diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2003-06-25 22:14:44 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2003-06-25 22:14:44 +0000 |
commit | 43dc572ab14f8ec484209993716b9bfd5f1252e4 (patch) | |
tree | a81d4f5a6d5af29caddbda6f8c09bde2ada1c5c7 /usr.bin | |
parent | fff2546a7d7ebdf0345911dab6b38cb25328157f (diff) |
Add unidiff support and try to pretty up usage() a bit
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/diff/diff.c | 24 | ||||
-rw-r--r-- | usr.bin/diff/diffdir.c | 4 | ||||
-rw-r--r-- | usr.bin/diff/diffreg.c | 101 |
3 files changed, 106 insertions, 23 deletions
diff --git a/usr.bin/diff/diff.c b/usr.bin/diff/diff.c index 3ae107214af..cf27d4c2516 100644 --- a/usr.bin/diff/diff.c +++ b/usr.bin/diff/diff.c @@ -1,4 +1,4 @@ -/* $OpenBSD: diff.c,v 1.8 2003/06/25 21:43:49 millert Exp $ */ +/* $OpenBSD: diff.c,v 1.9 2003/06/25 22:14:43 millert Exp $ */ /* * Copyright (C) Caldera International Inc. 2001-2002. @@ -65,7 +65,7 @@ main(int argc, char **argv) status = 2; diffargv = argv; - while ((ch = getopt(argc, argv, "bC:cD:efhilnrS:stw")) != -1) { + while ((ch = getopt(argc, argv, "bC:cD:efhilnrS:stU:uw")) != -1) { switch (ch) { case 'b': bflag++; @@ -117,6 +117,16 @@ main(int argc, char **argv) case 't': tflag++; break; + case 'U': + opt = D_UNIFIED; + if (!isdigit(*optarg)) + usage(); + context = atoi(optarg); /* XXX - use strtol */ + break; + case 'u': + opt = D_UNIFIED; + context = 3; + break; case 'w': wflag++; break; @@ -133,7 +143,7 @@ main(int argc, char **argv) file1 = argv[0]; file2 = argv[1]; if (hflag && opt) - errx(1, "-h doesn't support -D, -c, -C, -e, -f, -I or -n"); + errx(1, "-h doesn't support -D, -c, -C, -e, -f, -I, -n, -u or -U"); if (!strcmp(file1, "-")) stb1.st_mode = S_IFREG; else if (stat(file1, &stb1) < 0) @@ -203,9 +213,11 @@ noroom(void) __dead void usage(void) { - (void)fprintf(stderr, "usage: diff [-c | -C lines | -e | -f | -h | -n ] [-biwt] file1 file2\n" - "usage: diff [-Dstring] [-biw] file1 file2\n" - "usage: diff [-l] [-r] [-s] [-c | -C lines | -e | -f | -h | -n ] [-biwt]\n [-Sname] dir1 dir2\n"); + (void)fprintf(stderr, "usage: diff [-bitw] [-c | -e | -f | -h | -n | -u ] file1 file2\n" + " diff [-biw] -Dstring file1 file2\n" + " diff [-biwt] [-c | -e | -f | -h | -n | -u ] [-l] [-r] [-s] [-Sname]\n dir1 dir2\n" + " diff [-bitw] -Cnumber [file1 file2 | dir1 dir2]\n" + " diff [-bitw] -Unumber [file1 file2 | dir1 dir2]\n"); exit(1); } diff --git a/usr.bin/diff/diffdir.c b/usr.bin/diff/diffdir.c index 8c524b98bb4..d34638f1853 100644 --- a/usr.bin/diff/diffdir.c +++ b/usr.bin/diff/diffdir.c @@ -1,4 +1,4 @@ -/* $OpenBSD: diffdir.c,v 1.12 2003/06/25 21:43:49 millert Exp $ */ +/* $OpenBSD: diffdir.c,v 1.13 2003/06/25 22:14:43 millert Exp $ */ /* * Copyright (C) Caldera International Inc. 2001-2002. @@ -338,7 +338,7 @@ notsame: if (!ascii(f1) || !ascii(f2)) { if (lflag) dp->d_flags |= DIFFER; - else if (opt == D_NORMAL || opt == D_CONTEXT) + else if (opt == D_NORMAL || opt == D_CONTEXT || opt == D_UNIFIED) printf("Binary files %s and %s differ\n", file1, file2); goto closem; diff --git a/usr.bin/diff/diffreg.c b/usr.bin/diff/diffreg.c index 2b868776f77..ec86dfd9643 100644 --- a/usr.bin/diff/diffreg.c +++ b/usr.bin/diff/diffreg.c @@ -1,4 +1,4 @@ -/* $OpenBSD: diffreg.c,v 1.16 2003/06/25 21:43:49 millert Exp $ */ +/* $OpenBSD: diffreg.c,v 1.17 2003/06/25 22:14:43 millert Exp $ */ /* * Copyright (C) Caldera International Inc. 2001-2002. @@ -149,6 +149,7 @@ static void output(void); static void check(void); static void range(int, int, char *); static void dump_context_vec(void); +static void dump_unified_vec(void); static void prepare(int, FILE *); static void prune(void); static void equiv(struct line *, int, struct line *, int, int *); @@ -334,7 +335,7 @@ notsame: output(); status = anychange; same: - if (opt == D_CONTEXT && anychange == 0) + if (anychange == 0 && (opt == D_CONTEXT || opt == D_UNIFIED)) printf("No differences encountered\n"); done(0); } @@ -747,8 +748,12 @@ output(void) } #undef c } - if (anychange && opt == D_CONTEXT) - dump_context_vec(); + if (anychange != 0) { + if (opt == D_CONTEXT) + dump_context_vec(); + else if (opt == D_UNIFIED) + dump_unified_vec(); + } } /* @@ -783,21 +788,20 @@ change(int a, int b, int c, int d) return; if (anychange == 0) { anychange = 1; - if (opt == D_CONTEXT) { - printf("*** %s ", file1); + if (opt == D_CONTEXT || opt == D_UNIFIED) { stat(file1, &stbuf); - printf("%s--- %s ", - ctime(&stbuf.st_mtime), file2); + printf("%s %s %s", opt == D_CONTEXT ? "***" : "---", + file1, ctime(&stbuf.st_mtime)); stat(file2, &stbuf); - printf("%s", ctime(&stbuf.st_mtime)); - + printf("%s %s %s", opt == D_CONTEXT ? "---" : "+++", + file2, ctime(&stbuf.st_mtime)); context_vec_start = emalloc(MAX_CONTEXT * sizeof(struct context_vec)); context_vec_end = context_vec_start + MAX_CONTEXT; context_vec_ptr = context_vec_start - 1; } } - if (opt == D_CONTEXT) { + if (opt == D_CONTEXT || opt == D_UNIFIED) { /* * if this new change is within 'context' lines of * the previous change, just add it to the change @@ -807,10 +811,13 @@ change(int a, int b, int c, int d) */ if (context_vec_ptr >= context_vec_end || (context_vec_ptr >= context_vec_start && - a > (context_vec_ptr->b + 2 * context) && - c > (context_vec_ptr->d + 2 * context))) - dump_context_vec(); - + a > (context_vec_ptr->b + 2 * context) && + c > (context_vec_ptr->d + 2 * context))) { + if (opt == D_CONTEXT) + dump_context_vec(); + else + dump_unified_vec(); + } context_vec_ptr++; context_vec_ptr->a = a; context_vec_ptr->b = b; @@ -1114,3 +1121,67 @@ dump_context_vec(void) } context_vec_ptr = context_vec_start - 1; } + +/* dump accumulated "unified" diff changes */ +static void +dump_unified_vec(void) +{ + struct context_vec *cvp = context_vec_start; + int lowa, upb, lowc, upd; + int a, b, c, d; + char ch; + + if (cvp > context_vec_ptr) + return; + + b = d = 0; /* gcc */ + lowa = max(1, cvp->a - context); + upb = min(len[0], context_vec_ptr->b + context); + lowc = max(1, cvp->c - context); + upd = min(len[1], context_vec_ptr->d + context); + + printf("@@ -%d,%d +%d,%d @@\n", lowa, upb - lowa + 1, + lowc, upd - lowc + 1); + + /* + * Output changes in "unified" diff format--the old and new lines + * are printed together. + */ + for (; cvp <= context_vec_ptr; cvp++) { + a = cvp->a; + b = cvp->b; + c = cvp->c; + d = cvp->d; + + /* + * c: both new and old changes + * d: only changes in the old file + * a: only changes in the new file + */ + if (a <= b && c <= d) + ch = 'c'; + else + ch = (a <= b) ? 'd' : 'a'; + + switch (ch) { + case 'c': + fetch(ixold, lowa, a - 1, input[0], " ", 0); + fetch(ixold, a, b, input[0], "- ", 0); + fetch(ixnew, c, d, input[1], "+ ", 0); + break; + case 'd': + fetch(ixold, lowa, a - 1, input[0], " ", 0); + fetch(ixold, a, b, input[0], "- ", 0); + break; + case 'a': + fetch(ixnew, lowc, c - 1, input[1], " ", 0); + fetch(ixnew, c, d, input[1], "+ ", 0); + break; + } + lowa = b + 1; + lowc = d + 1; + } + fetch(ixnew, d + 1, upd, input[1], " ", 0); + + context_vec_ptr = context_vec_start - 1; +} |