diff --git a/usr.bin/diff3/diff3.c b/usr.bin/diff3/diff3.c index c72ea0747589..3b07ced4705b 100644 --- a/usr.bin/diff3/diff3.c +++ b/usr.bin/diff3/diff3.c @@ -79,6 +79,7 @@ #include #include +#define DEBUG 1 /* * "from" is first in range of changed lines; "to" is last+1 @@ -90,6 +91,7 @@ struct range { }; struct diff { +#define DIFF_TYPE1 1 #define DIFF_TYPE2 2 #define DIFF_TYPE3 3 int type; @@ -182,6 +184,20 @@ static struct option longopts[] = { { "version", no_argument, NULL, VERSION_OPT} }; +#if DEBUG +static void +printdiff(struct diff *d) +{ + fprintf(stderr, "type %s old (%d->%d) new (%d->%d) line: %s", + d->type == DIFF_TYPE1 ? "TYPE1" : ( + d->type == DIFF_TYPE2 ? "TYPE2" : "TYPE3"), + d->old.from, d->old.to, + d->new.from, d->new.to, d->line); +} +#else +#define printdiff(unused) +#endif /* DEBUG */ + static void usage(void) { @@ -314,6 +330,9 @@ merge(int m1, int m2) 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); } d1++; continue; @@ -552,6 +571,9 @@ edit(struct diff *diff, bool dup, int j, int difftype) static void printrange(FILE *p, struct range *r) { +#if DEBUG + fprintf(stderr, "%s:\tfrom %d to %d\n", __func__, r->from, r->to); +#endif char *line = NULL; size_t len = 0; int i = 1; @@ -591,20 +613,31 @@ edscript(int n) old = &de[n].old; delete = (new->from == new->to); - if (!oflag || !overlap[n]) { - prange(old, delete); - } else { - printf("%da\n", old->to - 1); - printf("%s\n", divider); - } - printrange(fp[2], new); - if (!oflag || !overlap[n]) { - if (!delete) + if (de[n].type == DIFF_TYPE1) { + if (delete) + printf("%dd\n", new->from - 1); + else if (old->from == new->from && old->to == new->to) { + printf("%dc\n", old->from); + printrange(fp[2], old); printf(".\n"); + } + continue; } else { - printf("%s %s\n.\n", newmark, f3mark); - printf("%da\n%s %s\n.\n", old->from - 1, - oldmark, f1mark); + if (!oflag || !overlap[n]) { + prange(old, delete); + } else { + printf("%da\n", old->to - 1); + printf("%s\n", divider); + } + printrange(fp[2], new); + if (!oflag || !overlap[n]) { + if (!delete) + printf(".\n"); + } else { + printf("%s %s\n.\n", newmark, f3mark); + printf("%da\n%s %s\n.\n", old->from - 1, + oldmark, f1mark); + } } } if (iflag) @@ -709,27 +742,51 @@ Ascript(int n) static void mergescript(int i) { + struct range r, *new, *old; int n; + bool delete = false; r.from = 1; r.to = 1; for (n = 1; n < i+1; n++) { + printdiff(&de[n]); new = &de[n].new; old = &de[n].old; - /* print any lines leading up to here */ - r.to = old->from; - printrange(fp[0], &r); + /* + * 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 + r.to = old->from; - if (de[n].type == DIFF_TYPE2) { + printrange(fp[0], &r); +#if DEBUG +fprintf(stderr, "end of prologue\n"); +#endif + switch (de[n].type) { + case DIFF_TYPE1: + /* If this isn't a delete print it */ + if (!delete) { + printrange(fp[2], new); + } + break; + case DIFF_TYPE2: printf("%s %s\n", oldmark, f2mark); printrange(fp[1], old); printf("%s\n", divider); printrange(fp[2], new); printf("%s %s\n", newmark, f3mark); - } else if (de[n].type == DIFF_TYPE3) { + break; + case DIFF_TYPE3: if (!oflag || !overlap[n]) { printrange(fp[2], new); } else { @@ -737,20 +794,27 @@ mergescript(int i) printf("%s %s\n", oldmark, f1mark); printrange(fp[0], old); - printf("%s %s\n", orgmark, f2mark); - if (old->from == old->to) { - struct range or; - or.from = old->from - 1; - or.to = new->to; - printrange(fp[1], &or); - } else - printrange(fp[1], old); + if (eflag != EFLAG_OVERLAP) { + printf("%s %s\n", orgmark, f2mark); + if (old->from == old->to) { + struct range or; + or.from = old->from - 1; + or.to = new->to; + printrange(fp[1], &or); + } else { + printrange(fp[1], old); + } + } printf("%s\n", divider); printrange(fp[2], new); printf("%s %s\n", newmark, f3mark); } + break; + default: + printf("Error: Unhandled diff type - exiting\n"); + exit(EXIT_FAILURE); } if (old->from == old->to) @@ -758,6 +822,7 @@ mergescript(int i) else r.from = old->to; } + /* * Print from the final range to the end of 'myfile'. Any deletions or * additions to this file should have been handled by now. @@ -768,21 +833,15 @@ mergescript(int i) */ 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 = old->from; - /* - * If the range is a 3 way merge then we need to skip a line in the - * trailing output. - */ - if (de[n-1].type == DIFF_TYPE3) - r.from++; - r.to = INT_MAX; - printrange(fp[0], &r); + printrange(fp[2], &r); exit(overlapcnt > 0); }