diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2006-09-21 15:30:08 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2006-09-21 15:30:08 +0000 |
commit | 8e2c082dd14cb4b99468f4650dfa95f87cae0acf (patch) | |
tree | 36ba221dd274fe71fb84a01f722bde186cafb111 /usr.bin | |
parent | a2ab53ec52316edf9ce164353dd0485d4a16b76b (diff) |
Add support to rcsdiff for all the other diff flags that
are pertinent to files (not directories) and that do not
conflict with rcsdiff-specific flags. OK xsa@
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/rcs/ci.c | 4 | ||||
-rw-r--r-- | usr.bin/rcs/diff.c | 178 | ||||
-rw-r--r-- | usr.bin/rcs/diff.h | 21 | ||||
-rw-r--r-- | usr.bin/rcs/diff3.c | 12 | ||||
-rw-r--r-- | usr.bin/rcs/rcs.c | 4 | ||||
-rw-r--r-- | usr.bin/rcs/rcsdiff.1 | 3 | ||||
-rw-r--r-- | usr.bin/rcs/rcsdiff.c | 147 |
7 files changed, 246 insertions, 123 deletions
diff --git a/usr.bin/rcs/ci.c b/usr.bin/rcs/ci.c index ecec047c827..392f724ca0d 100644 --- a/usr.bin/rcs/ci.c +++ b/usr.bin/rcs/ci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ci.c,v 1.186 2006/08/23 20:28:47 joris Exp $ */ +/* $OpenBSD: ci.c,v 1.187 2006/09/21 15:30:07 millert Exp $ */ /* * Copyright (c) 2005, 2006 Niall O'Higgins <niallo@openbsd.org> * All rights reserved. @@ -358,7 +358,7 @@ checkin_diff_file(struct checkin_params *pb) b2 = NULL; diff_format = D_RCSDIFF; - if (rcs_diffreg(path1, path2, b3) == D_ERROR) + if (rcs_diffreg(path1, path2, b3, 0) == D_ERROR) goto out; return (b3); diff --git a/usr.bin/rcs/diff.c b/usr.bin/rcs/diff.c index 12e67adcc93..8b837fb4ef9 100644 --- a/usr.bin/rcs/diff.c +++ b/usr.bin/rcs/diff.c @@ -1,4 +1,4 @@ -/* $OpenBSD: diff.c,v 1.8 2006/08/14 23:52:36 ray Exp $ */ +/* $OpenBSD: diff.c,v 1.9 2006/09/21 15:30:07 millert Exp $ */ /* * Copyright (C) Caldera International Inc. 2001-2002. * All rights reserved. @@ -162,43 +162,42 @@ struct diff_arg { char *date2; }; -static void output(FILE *, FILE *); -static void check(FILE *, FILE *); +static void output(FILE *, FILE *, int); +static void check(FILE *, FILE *, int); static void range(int, int, char *); static void uni_range(int, int); -static void dump_context_vec(FILE *, FILE *); -static void dump_unified_vec(FILE *, FILE *); -static int prepare(int, FILE *, off_t); +static void dump_context_vec(FILE *, FILE *, int); +static void dump_unified_vec(FILE *, FILE *, int); +static int prepare(int, FILE *, off_t, int); static void prune(void); static void equiv(struct line *, int, struct line *, int, int *); static void unravel(int); static void unsort(struct line *, int, int *); -static void change(FILE *, FILE *, int, int, int, int); +static void change(FILE *, FILE *, int, int, int, int, int); static void sort(struct line *, int); static int ignoreline(char *); static int asciifile(FILE *); -static void fetch(long *, int, int, FILE *, int, int); +static void fetch(long *, int, int, FILE *, int, int, int); static int newcand(int, int, int); static int search(int *, int, int); static int skipline(FILE *); static int isqrt(int); -static int stone(int *, int, int *, int *); -static int readhash(FILE *); +static int stone(int *, int, int *, int *, int); +static int readhash(FILE *, int); static int files_differ(FILE *, FILE *); static char *match_function(const long *, int, FILE *); static char *preadline(int, size_t, off_t); -static int aflag, bflag, dflag, iflag, pflag, tflag, Tflag, wflag; -static int context = 3; +int diff_context = 3; int diff_format = D_NORMAL; char *diff_file = NULL; RCSNUM *diff_rev1 = NULL; RCSNUM *diff_rev2 = NULL; -char diffargs[128]; +char diffargs[512]; /* XXX */ static struct stat stb1, stb2; -static char *ifdefname, *ignore_pats; -regex_t ignore_re; +static char *ifdefname; +regex_t *diff_ignore_re; static int *J; /* will be overlaid on class */ static int *class; /* will be overlaid on file[0] */ @@ -285,7 +284,7 @@ u_char cup2low[256] = { }; int -rcs_diffreg(const char *file1, const char *file2, BUF *out) +rcs_diffreg(const char *file1, const char *file2, BUF *out, int flags) { FILE *f1, *f2; int i, rval; @@ -297,7 +296,10 @@ rcs_diffreg(const char *file1, const char *file2, BUF *out) lastline = 0; lastmatchline = 0; context_vec_ptr = context_vec_start - 1; - chrtran = (iflag ? cup2low : clow2low); + if (flags & D_IGNORECASE) + chrtran = cup2low; + else + chrtran = clow2low; if (out != NULL) diffbuf = out; @@ -335,13 +337,14 @@ rcs_diffreg(const char *file1, const char *file2, BUF *out) errx(D_ERROR, "files_differ: invalid case"); } - if (!asciifile(f1) || !asciifile(f2)) { + if ((flags & D_FORCEASCII) == 0 && + (!asciifile(f1) || !asciifile(f2))) { rval = D_ERROR; goto closem; } - if (prepare(0, f1, stb1.st_size) < 0 || - prepare(1, f2, stb2.st_size) < 0) { + if (prepare(0, f1, stb1.st_size, flags) < 0 || + prepare(1, f2, stb2.st_size, flags) < 0) { goto closem; } @@ -364,7 +367,7 @@ rcs_diffreg(const char *file1, const char *file2, BUF *out) clistlen = 100; clist = xcalloc(clistlen, sizeof(*clist)); - if ((i = stone(class, slen[0], member, klist)) < 0) + if ((i = stone(class, slen[0], member, klist, flags)) < 0) goto closem; xfree(member); @@ -381,8 +384,8 @@ rcs_diffreg(const char *file1, const char *file2, BUF *out) tmp = xrealloc(ixnew, diff_len[1] + 2, sizeof(*ixnew)); ixnew = tmp; - check(f1, f2); - output(f1, f2); + check(f1, f2, flags); + output(f1, f2, flags); closem: if (anychange == 1) { @@ -426,7 +429,7 @@ files_differ(FILE *f1, FILE *f2) } static int -prepare(int i, FILE *fd, off_t filesize) +prepare(int i, FILE *fd, off_t filesize, int flags) { void *tmp; struct line *p; @@ -440,7 +443,7 @@ prepare(int i, FILE *fd, off_t filesize) sz = 100; p = xcalloc(sz + 3, sizeof(*p)); - for (j = 0; (h = readhash(fd));) { + for (j = 0; (h = readhash(fd, flags));) { if (j == (int)sz) { sz = sz * 3 / 2; tmp = xrealloc(p, sz + 3, sizeof(*p)); @@ -525,7 +528,7 @@ isqrt(int n) } static int -stone(int *a, int n, int *b, int *c) +stone(int *a, int n, int *b, int *c, int flags) { int ret; int i, k, y, j, l; @@ -533,7 +536,7 @@ stone(int *a, int n, int *b, int *c) u_int numtries; /* XXX move the isqrt() out of the macro to avoid multiple calls */ - const u_int bound = dflag ? UINT_MAX : MAX(256, (u_int)isqrt(n)); + const u_int bound = (flags & D_MINIMAL) ? UINT_MAX : MAX(256, isqrt(n)); k = 0; if ((ret = newcand(0, 0, 0)) < 0) @@ -638,7 +641,7 @@ unravel(int p) * 2. collect random access indexes to the two files */ static void -check(FILE *f1, FILE *f2) +check(FILE *f1, FILE *f2, int flags) { int i, j, jackpot, c, d; long ctold, ctnew; @@ -658,22 +661,23 @@ check(FILE *f1, FILE *f2) ixnew[j] = ctnew += skipline(f2); j++; } - if (bflag == 1 || wflag == 1 || iflag == 1) { + if (flags & (D_FOLDBLANKS|D_IGNOREBLANKS|D_IGNORECASE)) { for (;;) { c = getc(f1); d = getc(f2); /* * GNU diff ignores a missing newline - * in one file if bflag || wflag. + * in one file for -b or -w. */ - if ((bflag == 1 || wflag == 1) && + if ((flags & (D_FOLDBLANKS|D_IGNOREBLANKS)) && ((c == EOF && d == '\n') || (c == '\n' && d == EOF))) { break; } ctold++; ctnew++; - if (bflag == 1 && isspace(c) && isspace(d)) { + if ((flags & D_FOLDBLANKS) && isspace(c) && + isspace(d)) { do { if (c == '\n') break; @@ -684,7 +688,7 @@ check(FILE *f1, FILE *f2) break; ctnew++; } while (isspace(d = getc(f2))); - } else if (wflag == 1) { + } else if ((flags & D_IGNOREBLANKS)) { while (isspace(c) && c != '\n') { c = getc(f1); ctold++; @@ -792,7 +796,7 @@ skipline(FILE *f) } static void -output(FILE *f1, FILE *f2) +output(FILE *f1, FILE *f2, int flags) { int m, i0, i1, j0, j1; @@ -810,10 +814,10 @@ output(FILE *f1, FILE *f2) i1++; j1 = J[i1 + 1] - 1; J[i1] = j1; - change(f1, f2, i0, i1, j0, j1); + change(f1, f2, i0, i1, j0, j1, flags); } if (m == 0) - change(f1, f2, 1, 0, 1, diff_len[1]); + change(f1, f2, 1, 0, 1, diff_len[1], flags); if (diff_format == D_IFDEF) { for (;;) { #define c i0 @@ -825,9 +829,9 @@ output(FILE *f1, FILE *f2) } if (anychange != 0) { if (diff_format == D_CONTEXT) - dump_context_vec(f1, f2); + dump_context_vec(f1, f2, flags); else if (diff_format == D_UNIFIED) - dump_unified_vec(f1, f2); + dump_unified_vec(f1, f2, flags); } } @@ -870,7 +874,7 @@ ignoreline(char *line) { int ret; - ret = regexec(&ignore_re, line, 0, NULL, 0); + ret = regexec(diff_ignore_re, line, 0, NULL, 0); xfree(line); return (ret == 0); /* if it matched, it should be ignored. */ } @@ -883,7 +887,7 @@ ignoreline(char *line) * lines missing from the to file. */ static void -change(FILE *f1, FILE *f2, int a, int b, int c, int d) +change(FILE *f1, FILE *f2, int a, int b, int c, int d, int flags) { int i; static size_t max_context = 64; @@ -892,7 +896,7 @@ change(FILE *f1, FILE *f2, int a, int b, int c, int d) if (diff_format != D_IFDEF && a > b && c > d) return; - if (ignore_pats != NULL) { + if (diff_ignore_re != NULL) { char *line; /* * All lines in the change, insert, or delete must @@ -966,16 +970,16 @@ proceed: printf("\n"); anychange = 1; - } else if (a > context_vec_ptr->b + (2 * context) + 1 && - c > context_vec_ptr->d + (2 * context) + 1) { + } else if (a > context_vec_ptr->b + (2 * diff_context) + 1 && + c > context_vec_ptr->d + (2 * diff_context) + 1) { /* - * If this change is more than 'context' lines from the - * previous change, dump the record and reset it. + * If this change is more than 'diff_context' lines + * from the previous change, dump the record and reset it. */ if (diff_format == D_CONTEXT) - dump_context_vec(f1, f2); + dump_context_vec(f1, f2, flags); else - dump_unified_vec(f1, f2); + dump_unified_vec(f1, f2, flags); } context_vec_ptr++; context_vec_ptr->a = a; @@ -1008,11 +1012,11 @@ proceed: break; } if (diff_format == D_NORMAL || diff_format == D_IFDEF) { - fetch(ixold, a, b, f1, '<', 1); + fetch(ixold, a, b, f1, '<', 1, flags); if (a <= b && c <= d && diff_format == D_NORMAL) diff_output("---\n"); } - fetch(ixnew, c, d, f2, diff_format == D_NORMAL ? '>' : '\0', 0); + fetch(ixnew, c, d, f2, diff_format == D_NORMAL ? '>' : '\0', 0, flags); if (inifdef) { diff_output("#endif /* %s */\n", ifdefname); inifdef = 0; @@ -1020,7 +1024,7 @@ proceed: } static void -fetch(long *f, int a, int b, FILE *lb, int ch, int oldfile) +fetch(long *f, int a, int b, FILE *lb, int ch, int oldfile, int flags) { long j, nc; int i, c, col; @@ -1055,11 +1059,7 @@ fetch(long *f, int a, int b, FILE *lb, int ch, int oldfile) nc = f[i] - f[i - 1]; if (diff_format != D_IFDEF && ch != '\0') { diff_output("%c", ch); - if (Tflag == 1 && (diff_format == D_NORMAL || - diff_format == D_CONTEXT || - diff_format == D_UNIFIED)) - diff_output("\t"); - else if (diff_format != D_UNIFIED) + if (diff_format != D_UNIFIED) diff_output(" "); } col = 0; @@ -1072,7 +1072,7 @@ fetch(long *f, int a, int b, FILE *lb, int ch, int oldfile) "file"); return; } - if (c == '\t' && tflag == 1) { + if (c == '\t' && (flags & D_EXPANDTABS)) { do { diff_output(" "); } while (++col & 7); @@ -1088,15 +1088,15 @@ fetch(long *f, int a, int b, FILE *lb, int ch, int oldfile) * Hash function taken from Robert Sedgewick, Algorithms in C, 3d ed., p 578. */ static int -readhash(FILE *f) +readhash(FILE *f, int flags) { int i, t, space; int sum; sum = 1; space = 0; - if (bflag != 1 && wflag != 1) { - if (iflag == 1) + if ((flags & (D_FOLDBLANKS|D_IGNOREBLANKS)) == 0) { + if (flags & D_IGNORECASE) for (i = 0; (t = getc(f)) != '\n'; i++) { if (t == EOF) { if (i == 0) @@ -1122,7 +1122,7 @@ readhash(FILE *f) space++; continue; default: - if (space != 0 && wflag != 1) { + if (space && (flags & D_IGNOREBLANKS) == 0) { i++; space = 0; } @@ -1152,7 +1152,7 @@ asciifile(FILE *f) char buf[BUFSIZ]; size_t i, cnt; - if (aflag == 1 || f == NULL) + if (f == NULL) return (1); rewind(f); @@ -1199,7 +1199,7 @@ match_function(const long *f, int pos, FILE *fp) /* dump accumulated "context" diff changes */ static void -dump_context_vec(FILE *f1, FILE *f2) +dump_context_vec(FILE *f1, FILE *f2, int flags) { struct context_vec *cvp = context_vec_start; int lowa, upb, lowc, upd, do_output; @@ -1210,13 +1210,13 @@ dump_context_vec(FILE *f1, FILE *f2) return; b = d = 0; /* gcc */ - lowa = MAX(1, cvp->a - context); - upb = MIN(diff_len[0], context_vec_ptr->b + context); - lowc = MAX(1, cvp->c - context); - upd = MIN(diff_len[1], context_vec_ptr->d + context); + lowa = MAX(1, cvp->a - diff_context); + upb = MIN(diff_len[0], context_vec_ptr->b + diff_context); + lowc = MAX(1, cvp->c - diff_context); + upd = MIN(diff_len[1], context_vec_ptr->d + diff_context); diff_output("***************"); - if (pflag == 1) { + if ((flags & D_PROTOTYPE)) { f = match_function(ixold, lowa - 1, f1); if (f != NULL) { diff_output(" "); @@ -1252,16 +1252,16 @@ dump_context_vec(FILE *f1, FILE *f2) ch = (a <= b) ? 'd' : 'a'; if (ch == 'a') - fetch(ixold, lowa, b, f1, ' ', 0); + fetch(ixold, lowa, b, f1, ' ', 0, flags); else { - fetch(ixold, lowa, a - 1, f1, ' ', 0); + fetch(ixold, lowa, a - 1, f1, ' ', 0, flags); fetch(ixold, a, b, f1, - ch == 'c' ? '!' : '-', 0); + ch == 'c' ? '!' : '-', 0, flags); } lowa = b + 1; cvp++; } - fetch(ixold, b + 1, upb, f1, ' ', 0); + fetch(ixold, b + 1, upb, f1, ' ', 0, flags); } /* output changes to the "new" file */ diff_output("--- "); @@ -1288,23 +1288,23 @@ dump_context_vec(FILE *f1, FILE *f2) ch = (a <= b) ? 'd' : 'a'; if (ch == 'd') - fetch(ixnew, lowc, d, f2, ' ', 0); + fetch(ixnew, lowc, d, f2, ' ', 0, flags); else { - fetch(ixnew, lowc, c - 1, f2, ' ', 0); + fetch(ixnew, lowc, c - 1, f2, ' ', 0, flags); fetch(ixnew, c, d, f2, - ch == 'c' ? '!' : '+', 0); + ch == 'c' ? '!' : '+', 0, flags); } lowc = d + 1; cvp++; } - fetch(ixnew, d + 1, upd, f2, ' ', 0); + fetch(ixnew, d + 1, upd, f2, ' ', 0, flags); } context_vec_ptr = context_vec_start - 1; } /* dump accumulated "unified" diff changes */ static void -dump_unified_vec(FILE *f1, FILE *f2) +dump_unified_vec(FILE *f1, FILE *f2, int flags) { struct context_vec *cvp = context_vec_start; int lowa, upb, lowc, upd; @@ -1315,17 +1315,17 @@ dump_unified_vec(FILE *f1, FILE *f2) return; b = d = 0; /* gcc */ - lowa = MAX(1, cvp->a - context); - upb = MIN(diff_len[0], context_vec_ptr->b + context); - lowc = MAX(1, cvp->c - context); - upd = MIN(diff_len[1], context_vec_ptr->d + context); + lowa = MAX(1, cvp->a - diff_context); + upb = MIN(diff_len[0], context_vec_ptr->b + diff_context); + lowc = MAX(1, cvp->c - diff_context); + upd = MIN(diff_len[1], context_vec_ptr->d + diff_context); diff_output("@@ -"); uni_range(lowa, upb); diff_output(" +"); uni_range(lowc, upd); diff_output(" @@"); - if (pflag == 1) { + if ((flags & D_PROTOTYPE)) { f = match_function(ixold, lowa - 1, f1); if (f != NULL) { diff_output(" "); @@ -1356,23 +1356,23 @@ dump_unified_vec(FILE *f1, FILE *f2) switch (ch) { case 'c': - fetch(ixold, lowa, a - 1, f1, ' ', 0); - fetch(ixold, a, b, f1, '-', 0); - fetch(ixnew, c, d, f2, '+', 0); + fetch(ixold, lowa, a - 1, f1, ' ', 0, flags); + fetch(ixold, a, b, f1, '-', 0, flags); + fetch(ixnew, c, d, f2, '+', 0, flags); break; case 'd': - fetch(ixold, lowa, a - 1, f1, ' ', 0); - fetch(ixold, a, b, f1, '-', 0); + fetch(ixold, lowa, a - 1, f1, ' ', 0, flags); + fetch(ixold, a, b, f1, '-', 0, flags); break; case 'a': - fetch(ixnew, lowc, c - 1, f2, ' ', 0); - fetch(ixnew, c, d, f2, '+', 0); + fetch(ixnew, lowc, c - 1, f2, ' ', 0, flags); + fetch(ixnew, c, d, f2, '+', 0, flags); break; } lowa = b + 1; lowc = d + 1; } - fetch(ixnew, d + 1, upd, f2, ' ', 0); + fetch(ixnew, d + 1, upd, f2, ' ', 0, flags); context_vec_ptr = context_vec_start - 1; } diff --git a/usr.bin/rcs/diff.h b/usr.bin/rcs/diff.h index dfc46f85c05..ef349b9ae44 100644 --- a/usr.bin/rcs/diff.h +++ b/usr.bin/rcs/diff.h @@ -1,4 +1,4 @@ -/* $OpenBSD: diff.h,v 1.4 2006/05/15 06:58:03 xsa Exp $ */ +/* $OpenBSD: diff.h,v 1.5 2006/09/21 15:30:07 millert Exp $ */ /* * Copyright (C) Caldera International Inc. 2001-2002. * All rights reserved. @@ -81,6 +81,17 @@ #define D_RCSDIFF 5 /* Reverse editor output: RCS format */ /* + * Command line flags + */ +#define D_FORCEASCII 0x01 /* Treat file as ascii regardless of content */ +#define D_FOLDBLANKS 0x02 /* Treat all white space as equal */ +#define D_MINIMAL 0x04 /* Make diff as small as possible */ +#define D_IGNORECASE 0x08 /* Case-insensitive matching */ +#define D_PROTOTYPE 0x10 /* Display C function prototype */ +#define D_EXPANDTABS 0x20 /* Expand tabs to spaces */ +#define D_IGNOREBLANKS 0x40 /* Ignore white space changes */ + +/* * Status values for rcs_diffreg() return values */ #define D_SAME 0 /* Files are the same */ @@ -97,15 +108,17 @@ struct rcs_lines; BUF *rcs_diff3(RCSFILE *, char *, RCSNUM *, RCSNUM *, int); BUF *merge_diff3(char **, int); void diff_output(const char *, ...); -int rcs_diffreg(const char *, const char *, BUF *); +int rcs_diffreg(const char *, const char *, BUF *, int); int ed_patch_lines(struct rcs_lines *, struct rcs_lines *); +extern int diff_context; extern int diff_format; extern int diff3_conflicts; -extern char *diff_file; -extern char diffargs[128]; +extern char *diff_file, *diff_ignore_pats; +extern char diffargs[512]; /* XXX */ extern BUF *diffbuf; extern RCSNUM *diff_rev1; extern RCSNUM *diff_rev2; +extern regex_t *diff_ignore_re; #endif /* RCS_DIFF_H */ diff --git a/usr.bin/rcs/diff3.c b/usr.bin/rcs/diff3.c index d852a5286db..3ac29f5b6f8 100644 --- a/usr.bin/rcs/diff3.c +++ b/usr.bin/rcs/diff3.c @@ -1,4 +1,4 @@ -/* $OpenBSD: diff3.c,v 1.14 2006/08/11 08:18:19 xsa Exp $ */ +/* $OpenBSD: diff3.c,v 1.15 2006/09/21 15:30:07 millert Exp $ */ /* * Copyright (C) Caldera International Inc. 2001-2002. @@ -72,7 +72,7 @@ static const char copyright[] = #ifndef lint static const char rcsid[] = - "$OpenBSD: diff3.c,v 1.14 2006/08/11 08:18:19 xsa Exp $"; + "$OpenBSD: diff3.c,v 1.15 2006/09/21 15:30:07 millert Exp $"; #endif /* not lint */ #include "includes.h" @@ -191,8 +191,8 @@ merge_diff3(char **av, int flags) rcs_buf_free(b2); b2 = NULL; - if ((rcs_diffreg(path1, path3, d1) == D_ERROR) || - (rcs_diffreg(path2, path3, d2) == D_ERROR)) { + if ((rcs_diffreg(path1, path3, d1, 0) == D_ERROR) || + (rcs_diffreg(path2, path3, d2, 0) == D_ERROR)) { rcs_buf_free(diffb); diffb = NULL; goto out; @@ -309,8 +309,8 @@ rcs_diff3(RCSFILE *rf, char *workfile, RCSNUM *rev1, RCSNUM *rev2, int flags) rcs_buf_free(b2); b2 = NULL; - if ((rcs_diffreg(path1, path3, d1) == D_ERROR) || - (rcs_diffreg(path2, path3, d2) == D_ERROR)) { + if ((rcs_diffreg(path1, path3, d1, 0) == D_ERROR) || + (rcs_diffreg(path2, path3, d2, 0) == D_ERROR)) { rcs_buf_free(diffb); diffb = NULL; goto out; diff --git a/usr.bin/rcs/rcs.c b/usr.bin/rcs/rcs.c index 1c65239632a..7cd00bb0ce2 100644 --- a/usr.bin/rcs/rcs.c +++ b/usr.bin/rcs/rcs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rcs.c,v 1.32 2006/08/23 11:49:49 millert Exp $ */ +/* $OpenBSD: rcs.c,v 1.33 2006/09/21 15:30:07 millert Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -1401,7 +1401,7 @@ rcs_rev_remove(RCSFILE *rf, RCSNUM *rev) rcs_buf_free(prevbuf); diff_format = D_RCSDIFF; - if (rcs_diffreg(path_tmp1, path_tmp2, newdiff) == D_ERROR) + if (rcs_diffreg(path_tmp1, path_tmp2, newdiff, 0) == D_ERROR) errx(1, "rcs_diffreg failed"); newdeltatext = newdiff; diff --git a/usr.bin/rcs/rcsdiff.1 b/usr.bin/rcs/rcsdiff.1 index 3c8fdf370be..d59657161b7 100644 --- a/usr.bin/rcs/rcsdiff.1 +++ b/usr.bin/rcs/rcsdiff.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: rcsdiff.1,v 1.22 2006/05/05 15:47:36 xsa Exp $ +.\" $OpenBSD: rcsdiff.1,v 1.23 2006/09/21 15:30:07 millert Exp $ .\" .\" Copyright (c) 2005 Joris Vink <joris@openbsd.org> .\" All rights reserved. @@ -27,6 +27,7 @@ .Op Fl r Ns Ar rev .Op Fl x Ns Ar suffixes .Op Fl z Ns Ar tz +.Op Ar diff options .Ar .Sh DESCRIPTION The diff --git a/usr.bin/rcs/rcsdiff.c b/usr.bin/rcs/rcsdiff.c index 01774e8e7ab..c29498fcff9 100644 --- a/usr.bin/rcs/rcsdiff.c +++ b/usr.bin/rcs/rcsdiff.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rcsdiff.c,v 1.68 2006/07/31 06:51:55 ray Exp $ */ +/* $OpenBSD: rcsdiff.c,v 1.69 2006/09/21 15:30:07 millert Exp $ */ /* * Copyright (c) 2005 Joris Vink <joris@openbsd.org> * All rights reserved. @@ -29,35 +29,81 @@ #include "rcsprog.h" #include "diff.h" -static int rcsdiff_file(RCSFILE *, RCSNUM *, const char *); -static int rcsdiff_rev(RCSFILE *, RCSNUM *, RCSNUM *); +static int rcsdiff_file(RCSFILE *, RCSNUM *, const char *, int); +static int rcsdiff_rev(RCSFILE *, RCSNUM *, RCSNUM *, int); +static void push_ignore_pats(char *); -static int flags = 0; +static int quiet; static int kflag = RCS_KWEXP_ERR; +static char *diff_ignore_pats; int rcsdiff_main(int argc, char **argv) { - int fd, i, ch, status; + int fd, i, ch, dflags, status; RCSNUM *rev1, *rev2; RCSFILE *file; char fpath[MAXPATHLEN], *rev_str1, *rev_str2; + const char *errstr; rev1 = rev2 = NULL; rev_str1 = rev_str2 = NULL; status = D_SAME; + dflags = 0; if (strlcpy(diffargs, "diff", sizeof(diffargs)) >= sizeof(diffargs)) errx(D_ERROR, "diffargs too long"); - while ((ch = rcs_getopt(argc, argv, "ck:nqr:TuVx::z::")) != -1) { + while ((ch = rcs_getopt(argc, argv, "abC:cdI:ik:npqr:TtU:uVwx::z::")) != -1) { switch (ch) { + case 'a': + if (strlcat(diffargs, " -a", sizeof(diffargs)) >= + sizeof(diffargs)) + errx(D_ERROR, "diffargs too long"); + dflags |= D_FORCEASCII; + break; + case 'b': + if (strlcat(diffargs, " -b", sizeof(diffargs)) >= + sizeof(diffargs)) + errx(D_ERROR, "diffargs too long"); + dflags |= D_FOLDBLANKS; + break; + case 'C': + (void)strlcat(diffargs, " -C", sizeof(diffargs)); + if (strlcat(diffargs, rcs_optarg, sizeof(diffargs)) >= + sizeof(diffargs)) + errx(D_ERROR, "diffargs too long"); + diff_context = strtonum(rcs_optarg, 0, INT_MAX, &errstr); + if (errstr) + errx(D_ERROR, "context is %s: %s", + errstr, rcs_optarg); + diff_format = D_CONTEXT; + break; case 'c': if (strlcat(diffargs, " -c", sizeof(diffargs)) >= sizeof(diffargs)) errx(D_ERROR, "diffargs too long"); diff_format = D_CONTEXT; break; + case 'd': + if (strlcat(diffargs, " -d", sizeof(diffargs)) >= + sizeof(diffargs)) + errx(D_ERROR, "diffargs too long"); + dflags |= D_MINIMAL; + break; + case 'i': + if (strlcat(diffargs, " -i", sizeof(diffargs)) >= + sizeof(diffargs)) + errx(D_ERROR, "diffargs too long"); + dflags |= D_IGNORECASE; + break; + case 'I': + (void)strlcat(diffargs, " -I", sizeof(diffargs)); + if (strlcat(diffargs, rcs_optarg, sizeof(diffargs)) >= + sizeof(diffargs)) + errx(D_ERROR, "diffargs too long"); + push_ignore_pats(rcs_optarg); + break; case 'k': kflag = rcs_kflag_get(rcs_optarg); if (RCS_KWEXP_INVAL(kflag)) { @@ -72,8 +118,14 @@ rcsdiff_main(int argc, char **argv) errx(D_ERROR, "diffargs too long"); diff_format = D_RCSDIFF; break; + case 'p': + if (strlcat(diffargs, " -p", sizeof(diffargs)) >= + sizeof(diffargs)) + errx(D_ERROR, "diffargs too long"); + dflags |= D_PROTOTYPE; + break; case 'q': - flags |= QUIET; + quiet = 1; break; case 'r': rcs_setrevstr2(&rev_str1, &rev_str2, rcs_optarg); @@ -83,6 +135,23 @@ rcsdiff_main(int argc, char **argv) * kept for compatibility */ break; + case 't': + if (strlcat(diffargs, " -t", sizeof(diffargs)) >= + sizeof(diffargs)) + errx(D_ERROR, "diffargs too long"); + dflags |= D_EXPANDTABS; + break; + case 'U': + (void)strlcat(diffargs, " -U", sizeof(diffargs)); + if (strlcat(diffargs, rcs_optarg, sizeof(diffargs)) >= + sizeof(diffargs)) + errx(D_ERROR, "diffargs too long"); + diff_context = strtonum(rcs_optarg, 0, INT_MAX, &errstr); + if (errstr) + errx(D_ERROR, "context is %s: %s", + errstr, rcs_optarg); + diff_format = D_UNIFIED; + break; case 'u': if (strlcat(diffargs, " -u", sizeof(diffargs)) >= sizeof(diffargs)) @@ -92,6 +161,12 @@ rcsdiff_main(int argc, char **argv) case 'V': printf("%s\n", rcs_version); exit(0); + case 'w': + if (strlcat(diffargs, " -w", sizeof(diffargs)) >= + sizeof(diffargs)) + errx(D_ERROR, "diffargs too long"); + dflags |= D_IGNOREBLANKS; + break; case 'x': /* Use blank extension if none given. */ rcs_suffixes = rcs_optarg ? rcs_optarg : ""; @@ -114,6 +189,21 @@ rcsdiff_main(int argc, char **argv) exit(D_ERROR); } + if (diff_ignore_pats != NULL) { + char buf[BUFSIZ]; + int error; + + diff_ignore_re = xmalloc(sizeof(*diff_ignore_re)); + if ((error = regcomp(diff_ignore_re, diff_ignore_pats, + REG_NEWLINE | REG_EXTENDED)) != 0) { + regerror(error, diff_ignore_re, buf, sizeof(buf)); + if (*diff_ignore_pats != '\0') + errx(D_ERROR, "%s: %s", diff_ignore_pats, buf); + else + errx(D_ERROR, "%s", buf); + } + } + for (i = 0; i < argc; i++) { fd = rcs_choosefile(argv[i], fpath, sizeof(fpath)); if (fd < 0) { @@ -136,7 +226,7 @@ rcsdiff_main(int argc, char **argv) errx(D_ERROR, "bad revision number"); } - if (!(flags & QUIET)) { + if (!quiet) { fprintf(stderr, "%s\n", RCS_DIFF_DIV); fprintf(stderr, "RCS file: %s\n", fpath); } @@ -145,13 +235,14 @@ rcsdiff_main(int argc, char **argv) /* No revisions given. */ if (rev_str1 == NULL) - status = rcsdiff_file(file, file->rf_head, argv[i]); + status = rcsdiff_file(file, file->rf_head, argv[i], + dflags); /* One revision given. */ else if (rev_str2 == NULL) - status = rcsdiff_file(file, rev1, argv[i]); + status = rcsdiff_file(file, rev1, argv[i], dflags); /* Two revisions given. */ else - status = rcsdiff_rev(file, rev1, rev2); + status = rcsdiff_rev(file, rev1, rev2, dflags); rcs_close(file); @@ -177,7 +268,7 @@ rcsdiff_usage(void) } static int -rcsdiff_file(RCSFILE *file, RCSNUM *rev, const char *filename) +rcsdiff_file(RCSFILE *file, RCSNUM *rev, const char *filename, int dflags) { int ret, fd; time_t t; @@ -204,7 +295,7 @@ rcsdiff_file(RCSFILE *file, RCSNUM *rev, const char *filename) } rcsnum_tostr(rev, rbuf, sizeof(rbuf)); - if (!(flags & QUIET)) { + if (!quiet) { fprintf(stderr, "retrieving revision %s\n", rbuf); fprintf(stderr, "%s -r%s %s\n", diffargs, rbuf, filename); } @@ -251,7 +342,7 @@ rcsdiff_file(RCSFILE *file, RCSNUM *rev, const char *filename) if (utimes(path2, (const struct timeval *)&tv2) < 0) warn("utimes"); - ret = rcs_diffreg(path1, path2, NULL); + ret = rcs_diffreg(path1, path2, NULL, dflags); out: if (fd != -1) @@ -269,7 +360,7 @@ out: } static int -rcsdiff_rev(RCSFILE *file, RCSNUM *rev1, RCSNUM *rev2) +rcsdiff_rev(RCSFILE *file, RCSNUM *rev1, RCSNUM *rev2, int dflags) { struct timeval tv[2], tv2[2]; BUF *b1, *b2; @@ -286,7 +377,7 @@ rcsdiff_rev(RCSFILE *file, RCSNUM *rev1, RCSNUM *rev2) path1 = path2 = NULL; rcsnum_tostr(rev1, rbuf1, sizeof(rbuf1)); - if (!(flags & QUIET)) + if (!quiet) fprintf(stderr, "retrieving revision %s\n", rbuf1); if ((b1 = rcs_getrev(file, rev1)) == NULL) { @@ -299,7 +390,7 @@ rcsdiff_rev(RCSFILE *file, RCSNUM *rev1, RCSNUM *rev2) tv[1].tv_sec = tv[0].tv_sec; rcsnum_tostr(rev2, rbuf2, sizeof(rbuf2)); - if (!(flags & QUIET)) + if (!quiet) fprintf(stderr, "retrieving revision %s\n", rbuf2); if ((b2 = rcs_getrev(file, rev2)) == NULL) { @@ -311,7 +402,7 @@ rcsdiff_rev(RCSFILE *file, RCSNUM *rev1, RCSNUM *rev2) tv2[0].tv_sec = (long)rcs_rev_getdate(file, rev2); tv2[1].tv_sec = tv2[0].tv_sec; - if (!(flags & QUIET)) + if (!quiet) fprintf(stderr, "%s -r%s -r%s\n", diffargs, rbuf1, rbuf2); (void)xasprintf(&path1, "%s/diff1.XXXXXXXXXX", rcs_tmpdir); @@ -332,7 +423,7 @@ rcsdiff_rev(RCSFILE *file, RCSNUM *rev1, RCSNUM *rev2) if (utimes(path2, (const struct timeval *)&tv2) < 0) warn("utimes"); - ret = rcs_diffreg(path1, path2, NULL); + ret = rcs_diffreg(path1, path2, NULL, dflags); out: if (b1 != NULL) @@ -346,3 +437,21 @@ out: return (ret); } + +static void +push_ignore_pats(char *pattern) +{ + size_t len; + + if (diff_ignore_pats == NULL) { + len = strlen(pattern) + 1; + diff_ignore_pats = xmalloc(len); + strlcpy(diff_ignore_pats, pattern, len); + } else { + /* old + "|" + new + NUL */ + len = strlen(diff_ignore_pats) + strlen(pattern) + 2; + diff_ignore_pats = xrealloc(diff_ignore_pats, len, 1); + strlcat(diff_ignore_pats, "|", len); + strlcat(diff_ignore_pats, pattern, len); + } +} |