From nobody Thu Sep 26 20:56:01 2024 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4XF5VF15dRz5Xltv; Thu, 26 Sep 2024 20:56:05 +0000 (UTC) (envelope-from bapt@freebsd.org) Received: from smtp.freebsd.org (smtp.freebsd.org [96.47.72.83]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "smtp.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4XF5VD5bTVz4Jv4; Thu, 26 Sep 2024 20:56:04 +0000 (UTC) (envelope-from bapt@freebsd.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1727384164; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=I3WBCbvr48rbEtut0OH6zcjmuTM5z6WyyYJzi+nQtrA=; b=lKVQdtSq3+dAAuzfB0qhZgN2ytrWNcLUDYqWmLITLvYenBwiT7nYAvXQkqtRxxFg9+GUAi aEMH8JQy9op9JED4NC7f42hQyfSaBvF224QiiLW8YqL0PJqKfTb+OjiY5nzmoIex1zvz4y B3X8qgLE2VIIOIMN5t3zy15by6bEhzGOqfb8EkV0yVl/+I0Wm/8HwRZ1kgiQmTOQjPhT7o sgCZpAbUhsCT8zu6Aabyi+KowC2Y7TxYKPtAVMo5pzvH+PE6RqqYjmeWmGbSv9sea1LL78 AnwCtEqGWyeTtO6ugCu0vRJoQHujN8AgWeb6DMF5cbid14DciSnWYgc2mZsfGA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1727384164; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=I3WBCbvr48rbEtut0OH6zcjmuTM5z6WyyYJzi+nQtrA=; b=LdER6LjdDnENrPe2wu2oMFSrbDDVspFx3kecllGDOqiDvb3BC7YdKlnuNTAoQrLhtuB/5J 8dZaVjUTHyNQQ0/+/n87TykiICIIwCrK4ByYwO3G0LzMZCwSYlUFIStvEyS+KNSXKYKJK6 S8+Mtqt5pSM8I+qtCjVvQlY0GWg6yzbwL+Sqiarom3RAxIL2yOWvh4ry6uedbUJTWLwdN7 sQVAiPwB2AHL75a3G3s1K2bI6kQ/SE1HqChyd9y6i1m59HNlKjj1kwStRmAPwlRlfuC/uy eYE1QQffFx0dNEiVuU6+K+mnSOGTjG8uDTlVxF14ZeUsS67KJ+CNFLzn199U4A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1727384164; a=rsa-sha256; cv=none; b=LJw8fU1g0A7Mn0Jzdtl27e+xfEwQNZKrDEuuOXWeSzCteE2A324OukldRlsNCstm48pbE3 gTxv+5exPp8QEzTchQVlZdjdZtnTEcpBj5okdOTMN70xeiqKfZxUhIegeZejzBsOSMkE/x FLIua2JbBgC0xJqeE/C8ODkpkYHVMxRIHWg8KVPRY+lTLvfWrUbXRYEYz3Gt4PUW38b69B OcDoZCqF/lbnCXlD3h//xuZ+L5ObnouHwmi8qjRZGoHZLuTg1X7nBHqDwglDKYadqtjTUi IZDv/3MqFxwqdXBNqOeM+eseP0maC4+yAP2VHcRXP1dzj/lUsrshfElN/F0iVA== Received: from aniel.nours.eu (nours.eu [IPv6:2001:41d0:8:3a4d::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: bapt) by smtp.freebsd.org (Postfix) with ESMTPSA id 4XF5VD3ZynzSlL; Thu, 26 Sep 2024 20:56:04 +0000 (UTC) (envelope-from bapt@freebsd.org) Received: by aniel.nours.eu (Postfix, from userid 1001) id 8F152120BDC; Thu, 26 Sep 2024 22:56:01 +0200 (CEST) Date: Thu, 26 Sep 2024 22:56:01 +0200 From: Baptiste Daroussin To: Dag-Erling =?utf-8?B?U23DuHJncmF2?= Cc: src-committers@freebsd.org, dev-commits-src-all@freebsd.org, dev-commits-src-main@freebsd.org Subject: Re: git: cf73401c4f7a - main - diff3: Fix merge mode. Message-ID: References: <202409251715.48PHFLuQ047265@gitrepo.freebsd.org> List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <202409251715.48PHFLuQ047265@gitrepo.freebsd.org> On Wed 25 Sep 17:15, Dag-Erling Smørgrav wrote: > The branch main has been updated by des: > > URL: https://cgit.FreeBSD.org/src/commit/?id=cf73401c4f7af063c91a0c8e4d5b46e08f06db87 > > commit cf73401c4f7af063c91a0c8e4d5b46e08f06db87 > Author: Dag-Erling Smørgrav > AuthorDate: 2024-09-25 17:14:32 +0000 > Commit: Dag-Erling Smørgrav > CommitDate: 2024-09-25 17:14:55 +0000 > > diff3: Fix merge mode. > > This is mostly thj@'s work, with some tweaks and cleanup by me. There > are still some cases where our output differs from GNU diff3, but it's > much better than before and I'd rather commit what I have now than let > it continue to languish in a metaphorical drawer. > > MFC after 3 weeks > Sponsored by: Klara, Inc. > Reviewed by: thj > Differential Revision: https://reviews.freebsd.org/D46762 > --- > usr.bin/diff3/diff3.c | 255 +++++++++++++++++++++++++++++++++++--------------- > 1 file changed, 179 insertions(+), 76 deletions(-) > > diff --git a/usr.bin/diff3/diff3.c b/usr.bin/diff3/diff3.c > index c72ea0747589..f20b1d74678d 100644 > --- a/usr.bin/diff3/diff3.c > +++ b/usr.bin/diff3/diff3.c > @@ -79,7 +79,6 @@ > #include > #include > > - > /* > * "from" is first in range of changed lines; "to" is last+1 > * from=to=line after point of insertion for added lines. > @@ -90,6 +89,7 @@ struct range { > }; > > struct diff { > +#define DIFF_TYPE1 1 > #define DIFF_TYPE2 2 > #define DIFF_TYPE3 3 > int type; > @@ -147,6 +147,7 @@ static void keep(int, struct range *); > static void merge(int, int); > static void prange(struct range *, bool); > static void repos(int); > +static void separate(const char *); > static void edscript(int) __dead2; > static void Ascript(int) __dead2; > static void mergescript(int) __dead2; > @@ -154,7 +155,7 @@ static void increase(void); > static void usage(void); > static void printrange(FILE *, struct range *); > > -static const char diff3_version[] = "FreeBSD diff3 20220517"; > +static const char diff3_version[] = "FreeBSD diff3 20240925"; > > enum { > DIFFPROG_OPT, > @@ -189,49 +190,110 @@ usage(void) > "[-L label3] file1 file2 file3\n"); > } > > +static int > +strtoi(char *str, char **end) > +{ > + intmax_t num; > + > + errno = 0; > + num = strtoimax(str, end, 10); > + if ((end != NULL && *end == str) || > + num < 0 || num > INT_MAX || > + errno == EINVAL || errno == ERANGE) > + err(1, "error in diff output"); > + return (int)num; > +} > + > +/* > + * Read diff hunks into the array pointed to by *dd. > + * > + * The output from `diff foo bar` consists of a series of hunks describing > + * an addition (lines in bar not present in foo), change (lines in bar > + * different from lines in foo), or deletion (lines in foo not present in > + * bar). Each record starts with a line of the form: > + * > + * a[,b]xc[,d] > + * > + * where a, b, c, and d are nonnegative integers (b and d are printed only > + * if they differ from a and c, respectively), and x is either 'a' for an > + * addition, 'c' for a change, or 'd' for a deletion. This is then > + * followed by a series of lines (which we ignore) giving the added, > + * changed, or deleted text. > + * > + * For an addition, a == b is the last line in 'foo' before the addition, > + * while c through d is the range of lines in 'bar' to be added to 'foo'. > + * > + * For a change, a through b is the range of lines in 'foo' to be replaced > + * and c through d is the range of lines in 'bar' to replace them with. > + * > + * For a deletion, a through b is the range of lines in 'foo' to remove > + * and c == d is the line in 'bar' which corresponds to the last line > + * before the deletion. > + * > + * The observant reader will have noticed that x is not really needed and > + * that we can fully describe any hunk using only a, b, c, and d: > + * > + * - an addition replaces a zero-length range in one file with a > + * non-zero-length range from the other > + * > + * - a change replaces a non-zero-length range in one file with a > + * non-zero-length range from the other > + * > + * - a deletion replaces a non-zero-length range in one file with a > + * zero-length range from the other > + */ > static int > readin(int fd, struct diff **dd) > { > int a, b, c, d; > - size_t i; > + int i; > char kind, *p; > FILE *f; > > f = fdopen(fd, "r"); > if (f == NULL) > err(2, "fdopen"); > - for (i = 0; (p = getchange(f)); i++) { > + for (i = 0; (p = getchange(f)) != NULL; i++) { > + if ((size_t)i >= szchanges - 1) > + increase(); > #if DEBUG > (*dd)[i].line = strdup(p); > #endif /* DEBUG */ > > - if (i >= szchanges - 1) > - increase(); > - a = b = (int)strtoimax(p, &p, 10); > - if (*p == ',') { > - p++; > - b = (int)strtoimax(p, &p, 10); > - } > + a = b = strtoi(p, &p); > + if (*p == ',') > + b = strtoi(p + 1, &p); > kind = *p++; > - c = d = (int)strtoimax(p, &p, 10); > - if (*p == ',') { > - p++; > - d = (int)strtoimax(p, &p, 10); > - } > + c = d = strtoi(p, &p); > + if (*p == ',') > + d = strtoi(p + 1, &p); > + if (*p != '\n') > + errx(1, "error in diff output"); > if (kind == 'a') > a++; > - if (kind == 'd') > + else if (kind == 'c') > + /* nothing */ ; > + else if (kind == 'd') > c++; > + else > + errx(1, "error in diff output"); > b++; > d++; > + if (b < a || d < c) > + errx(1, "error in diff output"); > (*dd)[i].old.from = a; > (*dd)[i].old.to = b; > (*dd)[i].new.from = c; > (*dd)[i].new.to = d; > + if (i > 0) { > + if ((*dd)[i].old.from < (*dd)[i - 1].old.to || > + (*dd)[i].new.from < (*dd)[i - 1].new.to) > + errx(1, "diff output out of order"); > + } > } > - if (i) { > - (*dd)[i].old.from = (*dd)[i - 1].old.to; > - (*dd)[i].new.from = (*dd)[i - 1].new.to; > + if (i > 0) { > + (*dd)[i].old.from = (*dd)[i].old.to = (*dd)[i - 1].old.to; > + (*dd)[i].new.from = (*dd)[i].new.to = (*dd)[i - 1].new.to; > } > fclose(f); > return (i); > @@ -264,7 +326,7 @@ getchange(FILE *b) > { > char *line; > > - while ((line = get_line(b, NULL))) { > + while ((line = get_line(b, NULL)) != NULL) { > if (isdigit((unsigned char)line[0])) > return (line); > } > @@ -305,15 +367,23 @@ merge(int m1, int m2) > d2 = d23; > j = 0; > > - while (t1 = d1 < d13 + m1, t2 = d2 < d23 + m2, t1 || t2) { > + for (;;) { > + t1 = (d1 < d13 + m1); > + t2 = (d2 < d23 + m2); > + if (!t1 && !t2) > + break; > + > /* first file is different from the others */ > if (!t2 || (t1 && d1->new.to < d2->new.from)) { > /* stuff peculiar to 1st file */ > if (eflag == EFLAG_NONE) { > - printf("====1\n"); > + separate("1"); > change(1, &d1->old, false); > keep(2, &d1->new); > change(3, &d1->new, false); > + } else if (eflag == EFLAG_OVERLAP) { > + j = edit(d2, dup, j, DIFF_TYPE1); > + printdiff(d2); This is defined nowhere, so the code does not build. Best regards, Bapt