summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2006-09-21 15:30:08 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2006-09-21 15:30:08 +0000
commit8e2c082dd14cb4b99468f4650dfa95f87cae0acf (patch)
tree36ba221dd274fe71fb84a01f722bde186cafb111 /usr.bin
parenta2ab53ec52316edf9ce164353dd0485d4a16b76b (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.c4
-rw-r--r--usr.bin/rcs/diff.c178
-rw-r--r--usr.bin/rcs/diff.h21
-rw-r--r--usr.bin/rcs/diff3.c12
-rw-r--r--usr.bin/rcs/rcs.c4
-rw-r--r--usr.bin/rcs/rcsdiff.13
-rw-r--r--usr.bin/rcs/rcsdiff.c147
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);
+ }
+}