diff options
| author | Baptiste Daroussin <bapt@FreeBSD.org> | 2026-02-13 16:10:44 +0000 |
|---|---|---|
| committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2026-03-22 02:04:58 +0000 |
| commit | a6f17dd2430b92b88a98f10ed35936e7e80f636b (patch) | |
| tree | 245ddd33bbcd52f68c007a6fca2464b7eadcf91c /usr.bin/diff3/diff3.c | |
| parent | 898db3e2978b154949fb64dee302cbfe4f10d497 (diff) | |
diff3: fix merge mode
Make the merge mode compatible with GNU diff3
Add tests for all the changes, those tests are extracted from the
etcupdate testsuite.
This version passes the etcupdate testsuite and the diffutils diff3
test suite.
MFC After: 1 week
(cherry picked from commit 2cfca8e710f260b8a1bb1ee5e1836a52e468ef4b)
Diffstat (limited to 'usr.bin/diff3/diff3.c')
| -rw-r--r-- | usr.bin/diff3/diff3.c | 51 |
1 files changed, 25 insertions, 26 deletions
diff --git a/usr.bin/diff3/diff3.c b/usr.bin/diff3/diff3.c index 4f3239b10625..9a01951e60ab 100644 --- a/usr.bin/diff3/diff3.c +++ b/usr.bin/diff3/diff3.c @@ -150,7 +150,7 @@ static void repos(int); static void separate(const char *); static void edscript(int) __dead2; static void Ascript(int) __dead2; -static void mergescript(int) __dead2; +static void mergescript(int, int) __dead2; static void increase(void); static void usage(void); static void printrange(FILE *, struct range *); @@ -361,12 +361,13 @@ merge(int m1, int m2) { struct diff *d1, *d2, *d3; int j, t1, t2; + int f1f3delta; bool dup = false; d1 = d13; d2 = d23; j = 0; - int f1f3delta = 0; + f1f3delta = 0; for (;;) { t1 = (d1 < d13 + m1); @@ -382,6 +383,12 @@ merge(int m1, int m2) change(1, &d1->old, false); keep(2, &d1->new); change(3, &d1->new, false); + } else if (mflag) { + j++; + de[j].type = DIFF_TYPE1; + de[j].old = d1->old; + de[j].new = d1->new; + overlap[j] = 0; } else if (eflag == EFLAG_OVERLAP) { j = edit(d2, dup, j, DIFF_TYPE1); } @@ -437,6 +444,14 @@ merge(int m1, int m2) change(2, &d2->old, false); d3 = d1->old.to > d1->old.from ? d1 : d2; change(3, &d3->new, false); + } else if (mflag) { + j++; + de[j].type = DIFF_TYPE3; + de[j].old = d1->old; + de[j].new = d1->new; + overlap[j] = !dup; + if (!dup) + overlapcnt++; } else { j = edit(d1, dup, j, DIFF_TYPE3); } @@ -468,7 +483,7 @@ merge(int m1, int m2) } if (mflag) - mergescript(j); + mergescript(j, f1f3delta); else if (Aflag) Ascript(j); else if (eflag) @@ -701,7 +716,7 @@ edscript(int n) if (iflag) printf("w\nq\n"); - exit(eflag == EFLAG_NONE ? overlapcnt : 0); + exit(oflag ? overlapcnt > 0 : 0); } /* @@ -795,11 +810,10 @@ Ascript(int n) * inbetween lines. */ static void -mergescript(int i) +mergescript(int i, int f1f3delta) { struct range r, *new, *old; int n; - bool delete = false; r.from = 1; r.to = 1; @@ -812,13 +826,9 @@ mergescript(int i) * Print any lines leading up to here. If we are merging don't * print deleted ranges. */ - delete = (new->from == new->to); - if (de[n].type == DIFF_TYPE1 && delete) - r.to = new->from - 1; - else if (de[n].type == DIFF_TYPE3 && (old->from == old->to)) { - r.from = old->from - 1; - r.to = new->from; - } else if (de[n].type == DIFF_TYPE2) + if (de[n].type == DIFF_TYPE1) + r.to = old->to; + else if (de[n].type == DIFF_TYPE2) r.to = new->from + de_delta[n]; else r.to = old->from; @@ -826,9 +836,7 @@ mergescript(int i) printrange(fp[0], &r); switch (de[n].type) { case DIFF_TYPE1: - /* If this isn't a delete print it */ - if (!delete) - printrange(fp[2], new); + /* Content included in "between" printing from fp[0] */ break; case DIFF_TYPE2: printf("%s %s\n", oldmark, f2mark); @@ -870,8 +878,6 @@ mergescript(int i) if (de[n].type == DIFF_TYPE2) r.from = new->to + de_delta[n]; - else if (old->from == old->to) - r.from = new->to; else r.from = old->to; } @@ -879,18 +885,11 @@ mergescript(int i) /* * Print from the final range to the end of 'myfile'. Any deletions or * additions to this file should have been handled by now. - * - * If the ranges are the same we need to rewind a line. - * If the new range is 0 length (from == to), we need to use the new - * range. */ new = &de[n-1].new; old = &de[n-1].old; - if (old->from == new->from && old->to == new->to) - r.from--; - else if (new->from == new->to) - r.from = new->from; + r.from -= f1f3delta; r.to = INT_MAX; printrange(fp[2], &r); |
