summaryrefslogtreecommitdiffstats
path: root/usr.bin/diff/diffreg.c
diff options
context:
space:
mode:
authorray <ray@openbsd.org>2009-06-06 15:00:27 +0000
committerray <ray@openbsd.org>2009-06-06 15:00:27 +0000
commitdba1d6ea0e7adc7407ba8b634ca533c869704ccd (patch)
treed1a4cfb9e472c0ad9ac6b51071e4e64c7887698a /usr.bin/diff/diffreg.c
parentSwedens National Day is today. ok jj@, halex@ and art@. -moj (diff)
downloadwireguard-openbsd-dba1d6ea0e7adc7407ba8b634ca533c869704ccd.tar.xz
wireguard-openbsd-dba1d6ea0e7adc7407ba8b634ca533c869704ccd.zip
Pull changes from rcsdiff, similar to what was pulled into cvsdiff.
OK millert
Diffstat (limited to 'usr.bin/diff/diffreg.c')
-rw-r--r--usr.bin/diff/diffreg.c154
1 files changed, 81 insertions, 73 deletions
diff --git a/usr.bin/diff/diffreg.c b/usr.bin/diff/diffreg.c
index 53209117025..74b6a72b066 100644
--- a/usr.bin/diff/diffreg.c
+++ b/usr.bin/diff/diffreg.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: diffreg.c,v 1.70 2007/09/11 15:47:17 gilles Exp $ */
+/* $OpenBSD: diffreg.c,v 1.71 2009/06/06 15:00:27 ray Exp $ */
/*
* Copyright (C) Caldera International Inc. 2001-2002.
@@ -65,7 +65,7 @@
*/
#ifndef lint
-static const char rcsid[] = "$OpenBSD: diffreg.c,v 1.70 2007/09/11 15:47:17 gilles Exp $";
+static const char rcsid[] = "$OpenBSD: diffreg.c,v 1.71 2009/06/06 15:00:27 ray Exp $";
#endif /* not lint */
#include <sys/param.h>
@@ -178,12 +178,12 @@ struct context_vec {
static FILE *opentemp(const char *);
static void output(char *, FILE *, char *, FILE *, int);
-static void check(char *, FILE *, char *, FILE *);
+static void check(char *, FILE *, char *, 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 void prepare(int, FILE *, off_t);
+static void dump_context_vec(FILE *, FILE *, int);
+static void dump_unified_vec(FILE *, FILE *, int);
+static void prepare(int, FILE *, off_t, int);
static void prune(void);
static void equiv(struct line *, int, struct line *, int, int *);
static void unravel(int);
@@ -193,13 +193,13 @@ static void sort(struct line *, int);
static void print_header(const char *, const char *);
static int ignoreline(char *);
static int asciifile(FILE *);
-static int fetch(long *, int, int, FILE *, int, int);
+static int 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 *, int);
static char *match_function(const long *, int, FILE *);
static char *preadline(int, size_t, off_t);
@@ -293,17 +293,20 @@ diffreg(char *ofile1, char *ofile2, int flags)
{
char *file1 = ofile1;
char *file2 = ofile2;
- FILE *f1 = NULL;
- FILE *f2 = NULL;
- int rval = D_SAME;
- int i, ostdout = -1;
+ FILE *f1, *f2;
+ int i, rval, ostdout = -1;
pid_t pid = -1;
+ f1 = f2 = NULL;
+ rval = D_SAME;
anychange = 0;
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 (S_ISDIR(stb1.st_mode) != S_ISDIR(stb2.st_mode))
return (S_ISDIR(stb1.st_mode) ? D_MISMATCH1 : D_MISMATCH2);
if (strcmp(file1, "-") == 0 && strcmp(file2, "-") == 0)
@@ -362,7 +365,8 @@ diffreg(char *ofile1, char *ofile2, int flags)
goto closem;
}
- if (!asciifile(f1) || !asciifile(f2)) {
+ if ((flags & D_FORCEASCII) == 0 &&
+ (!asciifile(f1) || !asciifile(f2))) {
rval = D_BINARY;
status |= 1;
goto closem;
@@ -405,8 +409,8 @@ diffreg(char *ofile1, char *ofile2, int flags)
xfree(header);
}
}
- prepare(0, f1, stb1.st_size);
- prepare(1, f2, stb2.st_size);
+ prepare(0, f1, stb1.st_size, flags);
+ prepare(1, f2, stb2.st_size, flags);
prune();
sort(sfile[0], slen[0]);
sort(sfile[1], slen[1]);
@@ -423,7 +427,7 @@ diffreg(char *ofile1, char *ofile2, int flags)
clen = 0;
clistlen = 100;
clist = xmalloc(clistlen * sizeof(*clist));
- i = stone(class, slen[0], member, klist);
+ i = stone(class, slen[0], member, klist, flags);
xfree(member);
xfree(class);
@@ -434,8 +438,8 @@ diffreg(char *ofile1, char *ofile2, int flags)
ixold = xrealloc(ixold, len[0] + 2, sizeof(*ixold));
ixnew = xrealloc(ixnew, len[1] + 2, sizeof(*ixnew));
- check(file1, f1, file2, f2);
- output(file1, f1, file2, f2, (flags & D_HEADER));
+ check(file1, f1, file2, f2, flags);
+ output(file1, f1, file2, f2, flags);
if (ostdout != -1) {
int wstatus;
@@ -463,6 +467,7 @@ closem:
xfree(file1);
if (file2 != ofile2)
xfree(file2);
+
return (rval);
}
@@ -547,7 +552,7 @@ splice(char *dir, char *file)
}
static void
-prepare(int i, FILE *fd, off_t filesize)
+prepare(int i, FILE *fd, off_t filesize, int flags)
{
struct line *p;
int j, h;
@@ -560,7 +565,7 @@ prepare(int i, FILE *fd, off_t filesize)
sz = 100;
p = xmalloc((sz + 3) * sizeof(*p));
- for (j = 0; (h = readhash(fd));) {
+ for (j = 0; (h = readhash(fd, flags));) {
if (j == sz) {
sz = sz * 3 / 2;
p = xrealloc(p, sz + 3, sizeof(*p));
@@ -640,13 +645,15 @@ 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 i, k, y, j, l;
int oldc, tc, oldl;
u_int numtries;
- const u_int bound = dflag ? UINT_MAX : MAX(256, isqrt(n));
+ /* XXX move the isqrt() out of the macro to avoid multiple calls */
+ const u_int bound = (flags & D_MINIMAL) ? UINT_MAX :
+ MAX(256, isqrt(n));
k = 0;
c[0] = newcand(0, 0, 0);
@@ -707,9 +714,9 @@ search(int *c, int k, int y)
return (k + 1);
i = 0;
j = k + 1;
- while (1) {
- l = i + j;
- if ((l >>= 1) <= i)
+ for (;;) {
+ l = (i + j) / 2;
+ if (l <= i)
break;
t = clist[c[l]].y;
if (t > y)
@@ -742,7 +749,7 @@ unravel(int p)
* 2. collect random access indexes to the two files
*/
static void
-check(char *file1, FILE *f1, char *file2, FILE *f2)
+check(char *file1, FILE *f1, char *file2, FILE *f2, int flags)
{
int i, j, jackpot, c, d;
long ctold, ctnew;
@@ -762,22 +769,23 @@ check(char *file1, FILE *f1, char *file2, FILE *f2)
ixnew[j] = ctnew += skipline(f2);
j++;
}
- if (bflag || wflag || iflag) {
+ 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 || wflag) &&
+ if ((flags & (D_FOLDBLANKS|D_IGNOREBLANKS)) &&
((c == EOF && d == '\n') ||
(c == '\n' && d == EOF))) {
break;
}
ctold++;
ctnew++;
- if (bflag && isspace(c) && isspace(d)) {
+ if ((flags & D_FOLDBLANKS) && isspace(c) &&
+ isspace(d)) {
do {
if (c == '\n')
break;
@@ -788,7 +796,7 @@ check(char *file1, FILE *f1, char *file2, FILE *f2)
break;
ctnew++;
} while (isspace(d = getc(f2)));
- } else if (wflag) {
+ } else if ((flags & D_IGNOREBLANKS)) {
while (isspace(c) && c != '\n') {
c = getc(f1);
ctold++;
@@ -943,9 +951,9 @@ output(char *file1, FILE *f1, char *file2, FILE *f2, int flags)
}
if (anychange != 0) {
if (format == D_CONTEXT)
- dump_context_vec(f1, f2);
+ dump_context_vec(f1, f2, flags);
else if (format == D_UNIFIED)
- dump_unified_vec(f1, f2);
+ dump_unified_vec(f1, f2, flags);
}
}
@@ -969,13 +977,13 @@ uni_range(int a, int b)
}
static char *
-preadline(int fd, size_t len, off_t off)
+preadline(int fd, size_t rlen, off_t off)
{
char *line;
ssize_t nr;
- line = xmalloc(len + 1);
- if ((nr = pread(fd, line, len, off)) < 0)
+ line = xmalloc(rlen + 1);
+ if ((nr = pread(fd, line, rlen, off)) < 0)
err(1, "preadline");
if (nr > 0 && line[nr-1] == '\n')
nr--;
@@ -1065,9 +1073,9 @@ proceed:
* previous change, dump the record and reset it.
*/
if (format == D_CONTEXT)
- dump_context_vec(f1, f2);
+ dump_context_vec(f1, f2, *pflags);
else
- dump_unified_vec(f1, f2);
+ dump_unified_vec(f1, f2, *pflags);
}
context_vec_ptr++;
context_vec_ptr->a = a;
@@ -1107,11 +1115,11 @@ proceed:
break;
}
if (format == D_NORMAL || format == D_IFDEF) {
- fetch(ixold, a, b, f1, '<', 1);
+ fetch(ixold, a, b, f1, '<', 1, *pflags);
if (a <= b && c <= d && format == D_NORMAL)
puts("---");
}
- i = fetch(ixnew, c, d, f2, format == D_NORMAL ? '>' : '\0', 0);
+ i = fetch(ixnew, c, d, f2, format == D_NORMAL ? '>' : '\0', 0, *pflags);
if (i != 0 && format == D_EDIT) {
/*
* A non-zero return value for D_EDIT indicates that the
@@ -1135,7 +1143,7 @@ proceed:
}
static int
-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)
{
int i, j, c, lastc, col, nc;
@@ -1185,7 +1193,7 @@ fetch(long *f, int a, int b, FILE *lb, int ch, int oldfile)
puts("\n\\ No newline at end of file");
return (0);
}
- if (c == '\t' && tflag) {
+ if (c == '\t' && (flags & D_EXPANDTABS)) {
do {
putchar(' ');
} while (++col & 7);
@@ -1214,15 +1222,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 && !wflag) {
- if (iflag)
+ 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)
@@ -1251,7 +1259,7 @@ readhash(FILE *f)
space++;
continue;
default:
- if (space && !wflag) {
+ if (space && (flags & D_IGNOREBLANKS) == 0) {
i++;
space = 0;
}
@@ -1279,9 +1287,9 @@ static int
asciifile(FILE *f)
{
unsigned char buf[BUFSIZ];
- int i, cnt;
+ size_t i, cnt;
- if (aflag || f == NULL)
+ if (f == NULL)
return (1);
rewind(f);
@@ -1295,7 +1303,7 @@ asciifile(FILE *f)
#define begins_with(s, pre) (strncmp(s, pre, sizeof(pre)-1) == 0)
static char *
-match_function(const long *f, int pos, FILE *file)
+match_function(const long *f, int pos, FILE *fp)
{
unsigned char buf[FUNCTION_CONTEXT_SIZE];
size_t nc;
@@ -1304,11 +1312,11 @@ match_function(const long *f, int pos, FILE *file)
lastline = pos;
while (pos > last) {
- fseek(file, f[pos - 1], SEEK_SET);
+ fseek(fp, f[pos - 1], SEEK_SET);
nc = f[pos] - f[pos - 1];
if (nc >= sizeof(buf))
nc = sizeof(buf) - 1;
- nc = fread(buf, 1, nc, file);
+ nc = fread(buf, 1, nc, fp);
if (nc > 0) {
buf[nc] = '\0';
buf[strcspn(buf, "\n")] = '\0';
@@ -1340,7 +1348,7 @@ match_function(const long *f, int pos, FILE *file)
/* 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;
@@ -1357,7 +1365,7 @@ dump_context_vec(FILE *f1, FILE *f2)
upd = MIN(len[1], context_vec_ptr->d + context);
printf("***************");
- if (pflag) {
+ if ((flags & D_PROTOTYPE)) {
f = match_function(ixold, lowa-1, f1);
if (f != NULL) {
putchar(' ');
@@ -1393,16 +1401,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 */
printf("--- ");
@@ -1429,23 +1437,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;
@@ -1466,7 +1474,7 @@ dump_unified_vec(FILE *f1, FILE *f2)
fputs(" +", stdout);
uni_range(lowc, upd);
fputs(" @@", stdout);
- if (pflag) {
+ if ((flags & D_PROTOTYPE)) {
f = match_function(ixold, lowa-1, f1);
if (f != NULL) {
putchar(' ');
@@ -1497,23 +1505,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;
}