[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
diff -I support + fix
This patch is the same as the last with the addition of a fix from Otto
(thanks) in readline()'s parsing. Apologies for all the noise.
Comments?
Index: diff.1
===================================================================
RCS file: /cvs/src/usr.bin/diff/diff.1,v
retrieving revision 1.25
diff -u -r1.25 diff.1
--- diff.1 2004/03/16 00:40:34 1.25
+++ diff.1 2004/06/16 23:34:06
@@ -38,31 +38,36 @@
.Sh SYNOPSIS
.Nm diff
.Op Fl abdilpqtTw
+.Op Fl I Ar pattern
.Oo
-.Fl c | Fl e | Fl f |
-.Fl n | Fl u
+.Fl c | e | f |
+.Fl n | u
.Oc
.Op Fl L Ar label
.Ar file1 file2
.Nm diff
.Op Fl abdilpqtTw
+.Op Fl I Ar pattern
.Op Fl L Ar label
.Fl C Ar number
.Ar file1 file2
.Nm diff
.Op Fl abdilqtw
+.Op Fl I Ar pattern
.Fl D Ar string
.Ar file1 file2
.Nm diff
.Op Fl abdilpqtTw
+.Op Fl I Ar pattern
.Op Fl L Ar label
.Fl U Ar number
.Ar file1 file2
.Nm diff
.Op Fl abdilNPpqtTw
+.Op Fl I Ar pattern
.Oo
-.Fl c | Fl e | Fl f |
-.Fl n | Fl u
+.Fl c | e | f |
+.Fl n | u
.Oc
.Bk -words
.Op Fl L Ar label
@@ -97,7 +102,7 @@
The lines removed from
.Ar file1
are marked with
-.Sq \-\ \& ;
+.Sq \&-\ \& ;
those added to
.Ar file2
are marked
@@ -179,7 +184,8 @@
Comparison options:
.Bl -tag -width Ds
.It Fl a
-Treat all files as ASCII.
+Treat all files as
+.Tn ASCII .
.It Fl b
Causes trailing blanks (spaces and tabs) to be ignored, and other
strings of blanks to compare equal.
@@ -187,6 +193,18 @@
Try very hard to produce a diff as small as possible.
This may consume a lot of processing power and memory when processing
large files with many changes.
+.It Fl I Ar pattern
+Ignores changes, insertions, and deletions whose lines match the
+extended regular expression
+.Ar pattern .
+Multiple
+.Fl I
+patterns may be specified.
+All lines in the change must match some pattern for the change to be
+ignored.
+See
+.Xr re_format 7
+for more information on regular expression patterns.
.It Fl i
Ignores the case of letters.
E.g.,
@@ -285,8 +303,9 @@
common subdirectories, and files which appear in only one directory
are described as such.
In directory mode only regular files and directories are compared.
-If a non-regular file such as a device special file or FIFO is
-encountered, a diagnostic message is printed.
+If a non-regular file such as a device special file or
+.Tn FIFO
+is encountered, a diagnostic message is printed.
.Pp
If only one of
.Ar file1
@@ -372,11 +391,11 @@
.Va ZZ .
.It Li XX,YY Ns Ic c Ns Li ZZ,QQ
Replace the range
-.Va XX , Ns YY
+.Va XX , Ns Va YY
from
.Ar file1
with the range
-.Va ZZ , Ns QQ
+.Va ZZ , Ns Va QQ
from
.Ar file2 .
.El
@@ -418,7 +437,7 @@
.El
.Sh FILES
.Bl -tag -width /tmp/diff.XXXXXXXX -compact
-.It Pa /tmp/diff.XXXXXXXX
+.It Pa /tmp/diff. Ns Ar XXXXXXXX
Temporary file used when comparing a device or the standard input.
Note that the temporary file is unlinked as soon as it is created
so it will not show up in a directory listing.
@@ -442,7 +461,8 @@
.Xr diff3 1 ,
.Xr ed 1 ,
.Xr pr 1 ,
-.Xr fnmatch 3
+.Xr fnmatch 3 ,
+.Xr re_format 7
.Sh STANDARDS
The
.Nm
Index: diff.c
===================================================================
RCS file: /cvs/src/usr.bin/diff/diff.c,v
retrieving revision 1.45
diff -u -r1.45 diff.c
--- diff.c 2004/03/16 00:40:34 1.45
+++ diff.c 2004/06/16 23:34:07
@@ -43,11 +43,12 @@
int aflag, bflag, dflag, iflag, lflag, Nflag, Pflag, pflag, rflag;
int sflag, tflag, Tflag, wflag;
int format, context, status;
-char *start, *ifdefname, *diffargs, *label;
+char *start, *ifdefname, *diffargs, *label, *ignore_pats;
struct stat stb1, stb2;
struct excludes *excludes_list;
+regex_t ignore_re;
-#define OPTIONS "0123456789abC:cdD:efhiL:lnNPpqrS:sTtU:uwX:x:"
+#define OPTIONS "0123456789abC:cdD:efhI:iL:lnNPpqrS:sTtU:uwX:x:"
static struct option longopts[] = {
{ "text", no_argument, 0, 'a' },
{ "ignore-space-change", no_argument, 0, 'b' },
@@ -56,6 +57,7 @@
{ "minimal", no_argument, 0, 'd' },
{ "ed", no_argument, 0, 'e' },
{ "forward-ed", no_argument, 0, 'f' },
+ { "ignore-matching-lines", required_argument, 0, 'I' },
{ "ignore-case", no_argument, 0, 'i' },
{ "paginate", no_argument, 0, 'l' },
{ "label", required_argument, 0, 'L' },
@@ -78,6 +80,7 @@
__dead void usage(void);
void push_excludes(char *);
+void push_ignore_pats(char *);
void read_excludes_file(char *file);
void set_argstr(char **, char **);
@@ -139,6 +142,9 @@
case 'h':
/* silently ignore for backwards compatibility */
break;
+ case 'I':
+ push_ignore_pats(optarg);
+ break;
case 'i':
iflag = 1;
break;
@@ -216,6 +222,16 @@
*/
if (argc != 2)
usage();
+ if (ignore_pats) {
+ char buf[BUFSIZ];
+ int error;
+
+ if ((error = regcomp(&ignore_re, ignore_pats,
+ REG_EXTENDED)) != 0) {
+ regerror(error, &ignore_re, buf, sizeof(buf));
+ errx(2, "%s: %s", ignore_pats, buf);
+ }
+ }
if (strcmp(argv[0], "-") == 0) {
fstat(STDIN_FILENO, &stb1);
gotstdin = 1;
@@ -340,6 +356,25 @@
entry->pattern = pattern;
entry->next = excludes_list;
excludes_list = entry;
+}
+
+void
+push_ignore_pats(char *pattern)
+{
+ size_t len;
+
+ if (ignore_pats) {
+ /* old + "|" + new + NUL */
+ len = strlen(ignore_pats) + strlen(pattern) + 2;
+ ignore_pats = erealloc(ignore_pats, len);
+ strlcat(ignore_pats, "|", len);
+ strlcat(ignore_pats, pattern, len);
+ } else {
+ /* XXX: estrdup */
+ len = strlen(pattern) + 1;
+ ignore_pats = emalloc(len);
+ strlcpy(ignore_pats, pattern, len);
+ }
}
void
Index: diff.h
===================================================================
RCS file: /cvs/src/usr.bin/diff/diff.h,v
retrieving revision 1.27
diff -u -r1.27 diff.h
--- diff.h 2004/03/16 00:40:34 1.27
+++ diff.h 2004/06/16 23:34:07
@@ -31,6 +31,9 @@
* @(#)diff.h 8.1 (Berkeley) 6/6/93
*/
+#include <sys/types.h>
+#include <regex.h>
+
/*
* Output format options
*/
@@ -73,9 +76,10 @@
extern int aflag, bflag, dflag, iflag, lflag, Nflag, Pflag, pflag, rflag,
sflag, tflag, Tflag, wflag;
extern int format, context, status;
-extern char *start, *ifdefname, *diffargs, *label;
+extern char *start, *ifdefname, *diffargs, *label, *ignore_pats;
extern struct stat stb1, stb2;
extern struct excludes *excludes_list;
+extern regex_t ignore_re;
char *splice(char *, char *);
int diffreg(char *, char *, int);
Index: diffreg.c
===================================================================
RCS file: /cvs/src/usr.bin/diff/diffreg.c,v
retrieving revision 1.55
diff -u -r1.55 diffreg.c
--- diffreg.c 2004/01/07 17:18:32 1.55
+++ diffreg.c 2004/06/16 23:34:08
@@ -214,6 +214,8 @@
static void unsort(struct line *, int, int *);
static void change(char *, FILE *, char *, FILE *, int, int, int, int);
static void sort(struct line *, int);
+static void readline(FILE *, char **, long *, long);
+static int ignoreline(char **);
static int asciifile(FILE *);
static int fetch(long *, int, int, FILE *, int, int);
static int newcand(int, int, int);
@@ -965,6 +967,30 @@
printf("%d,0", b);
}
+static void
+readline(FILE *fp, char **line, long *f, long lineno)
+{
+ long len;
+
+ len = f[lineno] - f[lineno - 1];
+ *line = emalloc(len + 1);
+ len = fread(*line, sizeof(char), len, fp);
+ if (ferror(fp))
+ err(1, "readline");
+ (*line)[len] = '\0';
+}
+
+static int
+ignoreline(char **line)
+{
+ int ret;
+
+ ret = regexec(&ignore_re, *line, 0, NULL, 0);
+ free(*line);
+ /* If it matched, it should be ignored. */
+ return ret == 0;
+}
+
/*
* Indicate that there is a difference between lines a and b of the from file
* to get to lines c to d of the to file. If a is greater then b then there
@@ -981,6 +1007,34 @@
restart:
if (format != D_IFDEF && a > b && c > d)
return;
+ if (ignore_pats != NULL) {
+ char *line;
+ /*
+ * All lines in the change, insert, or delete must
+ * match an ignore pattern for the change to be
+ * ignored.
+ */
+ if (a <= b) { /* Changes and deletes. */
+ i = a;
+ fseek(f1, ixold[i - 1], SEEK_SET);
+ for (; i <= b; i++) {
+ readline(f1, &line, ixold, i);
+ if (!ignoreline(&line))
+ goto proceed;
+ }
+ }
+ if (a > b || c <= d) { /* Changes and inserts. */
+ i = c;
+ fseek(f2, ixnew[i - 1], SEEK_SET);
+ for (; i <= d; i++) {
+ readline(f2, &line, ixnew, i);
+ if (!ignoreline(&line))
+ goto proceed;
+ }
+ }
+ return;
+ }
+proceed:
if (format == D_CONTEXT || format == D_UNIFIED) {
/*
* Allocate change records as needed.