summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2003-06-25 22:14:44 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2003-06-25 22:14:44 +0000
commit43dc572ab14f8ec484209993716b9bfd5f1252e4 (patch)
treea81d4f5a6d5af29caddbda6f8c09bde2ada1c5c7 /usr.bin
parentfff2546a7d7ebdf0345911dab6b38cb25328157f (diff)
Add unidiff support and try to pretty up usage() a bit
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/diff/diff.c24
-rw-r--r--usr.bin/diff/diffdir.c4
-rw-r--r--usr.bin/diff/diffreg.c101
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;
+}