FreeBSD Bugzilla – Attachment 211439 Details for
Bug 219933
bsddiff: Implement --suppress-common-lines // -y/--side-by-side // -W
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for diff.c diffreg.c diff.h diff.1
diff-side-by-side.patch (text/plain), 14.86 KB, created by
fehmi noyan isi
on 2020-02-07 09:59:00 UTC
(
hide
)
Description:
Patch for diff.c diffreg.c diff.h diff.1
Filename:
MIME Type:
Creator:
fehmi noyan isi
Created:
2020-02-07 09:59:00 UTC
Size:
14.86 KB
patch
obsolete
>Index: diff.1 >=================================================================== >--- diff.1 (revision 357647) >+++ diff.1 (working copy) >@@ -41,7 +41,7 @@ > .Op Fl aBbdipTtw > .Oo > .Fl c | e | f | >-.Fl n | q | u >+.Fl n | q | u | y > .Oc > .Op Fl -brief > .Op Fl -changed-group-format Ar GFMT >@@ -182,6 +182,21 @@ > .Op Fl x Ar pattern | Fl -exclude Ar pattern > .Ek > .Ar dir1 dir2 >+.Nm diff >+.Op Fl aBbditwW >+.Op --expand-tabs >+.Op --ignore-all-blanks >+.Op --ignore-blank-lines >+.Op --ignore-case >+.Op --minimal >+.Op --no-ignore-file-name-case >+.Op --strip-trailing-cr >+.Op --suppress-common-lines >+.Op --tabsize >+.Op --text >+.Op --width >+.Fl y | Fl -side-by-side >+.Ar file1 file2 > .Sh DESCRIPTION > The > .Nm >@@ -284,7 +299,21 @@ > .Fl c , > all lines to be changed (added and/or removed) are present in > a single section. >+.It Fl y Fl -side-by-side >+Output in two columns with a marker between them. The marker can be one >+of the following: >+.Pp >+.Bl -tag -width Ds -offset indent -compact >+.It space >+Corresponding lines are identical. >+.It '|' >+Corresponding lines are different. >+.It '<' >+Files differ and only the first file contains the line. >+.It '>' >+Files differ and only the second file contains the line. > .El >+.El > .Pp > Comparison options: > .Bl -tag -width Ds >@@ -362,6 +391,10 @@ > .Dq if (\ \&a == b \&) > will compare equal to > .Dq if(a==b) . >+.It Fl W Ar number Fl -width Ar number >+Output at most >+.Ar number >+columns when using side by side format. The default value is 130. > .It Fl -changed-group-format Ar GFMT > Format input groups in the provided > .Pp >@@ -382,7 +415,9 @@ > stub option for compatibility with GNU diff > .It Fl -strip-trailing-cr > strip carriage return on input files >-.It Fl tabsize Ar number >+.It Fl -suppress-common-lines >+Do not output common lines when using the side by side format >+.It Fl -tabsize Ar number > Number of spaces representing a tab (default 8) > .El > .Pp >Index: diff.c >=================================================================== >--- diff.c (revision 357647) >+++ diff.c (working copy) >@@ -37,9 +37,9 @@ > #include "diff.h" > #include "xmalloc.h" > >-int lflag, Nflag, Pflag, rflag, sflag, Tflag, cflag; >-int diff_format, diff_context, status, ignore_file_case; >-int tabsize = 8; >+int lflag, Nflag, Pflag, rflag, sflag, Tflag, cflag, Wflag; >+int diff_format, diff_context, status, ignore_file_case, suppress_common; >+int tabsize = 8, width = 130; > char *start, *ifdefname, *diffargs, *label[2], *ignore_pats; > char *group_format = NULL; > struct stat stb1, stb2; >@@ -46,7 +46,7 @@ > struct excludes *excludes_list; > regex_t ignore_re; > >-#define OPTIONS "0123456789aBbC:cdD:efHhI:iL:lnNPpqrS:sTtU:uwX:x:" >+#define OPTIONS "0123456789aBbC:cdD:efHhI:iL:lnNPpqrS:sTtU:uwW:X:x:y" > enum { > OPT_TSIZE = CHAR_MAX + 1, > OPT_STRIPCR, >@@ -55,6 +55,7 @@ > OPT_NORMAL, > OPT_HORIZON_LINES, > OPT_CHANGED_GROUP_FORMAT, >+ OPT_SUPPRESS_COMMON, > }; > > static struct option longopts[] = { >@@ -83,8 +84,10 @@ > { "initial-tab", no_argument, 0, 'T' }, > { "unified", optional_argument, 0, 'U' }, > { "ignore-all-space", no_argument, 0, 'w' }, >+ { "width", required_argument, 0, 'W' }, > { "exclude", required_argument, 0, 'x' }, > { "exclude-from", required_argument, 0, 'X' }, >+ { "side-by-side", no_argument, NULL, 'y' }, > { "ignore-file-name-case", no_argument, NULL, OPT_IGN_FN_CASE }, > { "horizon-lines", required_argument, NULL, OPT_HORIZON_LINES }, > { "no-ignore-file-name-case", no_argument, NULL, OPT_NO_IGN_FN_CASE }, >@@ -92,6 +95,7 @@ > { "strip-trailing-cr", no_argument, NULL, OPT_STRIPCR }, > { "tabsize", optional_argument, NULL, OPT_TSIZE }, > { "changed-group-format", required_argument, NULL, OPT_CHANGED_GROUP_FORMAT}, >+ { "suppress-common-lines", no_argument, NULL, OPT_SUPPRESS_COMMON }, > { NULL, 0, 0, '\0'} > }; > >@@ -230,6 +234,14 @@ > case 'w': > dflags |= D_IGNOREBLANKS; > break; >+ case 'W': >+ Wflag = 1; >+ width = (int) strtonum(optarg, 1, INT_MAX, &errstr); >+ if (errstr) { >+ warnx("Invalid argument for width"); >+ usage(); >+ } >+ break; > case 'X': > read_excludes_file(optarg); > break; >@@ -236,6 +248,9 @@ > case 'x': > push_excludes(optarg); > break; >+ case 'y': >+ diff_format = D_SIDEBYSIDE; >+ break; > case OPT_CHANGED_GROUP_FORMAT: > diff_format = D_GFORMAT; > group_format = optarg; >@@ -261,6 +276,9 @@ > case OPT_STRIPCR: > dflags |= D_STRIPCR; > break; >+ case OPT_SUPPRESS_COMMON: >+ suppress_common = 1; >+ break; > default: > usage(); > break; >@@ -464,7 +482,12 @@ > " -U number file1 file2\n" > " diff [-aBbdilNPprsTtw] [-c | -e | -f | -n | -q | -u] [--ignore-case]\n" > " [--no-ignore-case] [--normal] [--tabsize] [-I pattern] [-L label]\n" >- " [-S name] [-X file] [-x pattern] dir1 dir2\n"); >+ " [-S name] [-X file] [-x pattern] dir1 dir2\n" >+ " diff [-aBbditwW] [--expand-tabs] [--ignore-all-blanks]\n" >+ " [--ignore-blank-lines] [--ignore-case] [--minimal]\n" >+ " [--no-ignore-file-name-case] [--strip-trailing-cr]\n" >+ " [--suppress-common-lines] [--tabsize] [--text] [--width]\n" >+ " -y | --side-by-side file1 file2\n"); > > exit(2); > } >Index: diff.h >=================================================================== >--- diff.h (revision 357647) >+++ diff.h (working copy) >@@ -48,6 +48,7 @@ > lines and no trailing . */ > #define D_BRIEF 6 /* Say if the files differ */ > #define D_GFORMAT 7 /* Diff with defined changed group format */ >+#define D_SIDEBYSIDE 8 /* Side by side */ > > /* > * Output flags >@@ -85,9 +86,10 @@ > struct excludes *next; > }; > >-extern int lflag, Nflag, Pflag, rflag, sflag, Tflag, cflag; >+extern int lflag, Nflag, Pflag, rflag, sflag, Tflag, cflag, Wflag; > extern int diff_format, diff_context, status, ignore_file_case; >-extern int tabsize; >+extern int suppress_common; >+extern int tabsize, width; > extern char *start, *ifdefname, *diffargs, *label[2], *ignore_pats; > extern char *group_format; > extern struct stat stb1, stb2; >Index: diffreg.c >=================================================================== >--- diffreg.c (revision 357647) >+++ diffreg.c (working copy) >@@ -181,6 +181,7 @@ > }; > > #define diff_output printf >+#define MIN_PAD 1 > static FILE *opentemp(const char *); > static void output(char *, FILE *, char *, FILE *, int); > static void check(FILE *, FILE *, int); >@@ -196,6 +197,7 @@ > static void change(char *, FILE *, char *, FILE *, int, int, int, int, int *); > static void sort(struct line *, int); > static void print_header(const char *, const char *); >+static void print_space(int, int, int); > static bool ignoreline_pattern(char *); > static bool ignoreline(char *, bool); > static int asciifile(FILE *); >@@ -220,6 +222,8 @@ > static int pref, suff; /* length of prefix and suffix */ > static int slen[2]; > static int anychange; >+static int hw, padding; /* half width and padding */ >+static int edoffset; > static long *ixnew; /* will be overlaid on file[1] */ > static long *ixold; /* will be overlaid on klist */ > static struct cand *clist; /* merely a free storage pot for candidates */ >@@ -263,6 +267,22 @@ > lastline = 0; > lastmatchline = 0; > context_vec_ptr = context_vec_start - 1; >+ >+ /* >+ * hw excludes padding and make sure when -t is not used, >+ * the second column always starts from the closest tab stop >+ */ >+ if (diff_format == D_SIDEBYSIDE) { >+ hw = width >> 1; >+ padding = tabsize - (hw % tabsize); >+ if ((flags & D_EXPANDTABS) != 0 || (padding % tabsize == 0)) >+ padding = MIN_PAD; >+ >+ hw = (width >> 1) - >+ ((padding == MIN_PAD) ? (padding << 1) : padding) - 1; >+ } >+ >+ > if (flags & D_IGNORECASE) > chrtran = cup2low; > else >@@ -865,7 +885,7 @@ > static void > output(char *file1, FILE *f1, char *file2, FILE *f2, int flags) > { >- int m, i0, i1, j0, j1; >+ int i, j, m, i0, i1, j0, j1, nc; > > rewind(f1); > rewind(f2); >@@ -874,8 +894,20 @@ > J[m + 1] = len[1] + 1; > if (diff_format != D_EDIT) { > for (i0 = 1; i0 <= m; i0 = i1 + 1) { >- while (i0 <= m && J[i0] == J[i0 - 1] + 1) >+ while (i0 <= m && J[i0] == J[i0 - 1] + 1){ >+ if (diff_format == D_SIDEBYSIDE && >+ suppress_common != 1) { >+ nc = fetch(ixold, i0, i0, f1, '\0', >+ 1, flags); >+ print_space(nc, >+ (hw - nc) + (padding << 1) + 1, >+ flags); >+ fetch(ixnew, J[i0], J[i0], f2, '\0', >+ 0, flags); >+ diff_output("\n"); >+ } > i0++; >+ } > j0 = J[i0 - 1] + 1; > i1 = i0 - 1; > while (i1 < m && J[i1 + 1] == 0) >@@ -882,7 +914,35 @@ > i1++; > j1 = J[i1 + 1] - 1; > J[i1] = j1; >- change(file1, f1, file2, f2, i0, i1, j0, j1, &flags); >+ >+ /* >+ * When using side-by-side, lines from both of the >+ * files are printed. The algorithm used by diff(1) >+ * identifies the ranges in which two files differ. >+ * See the change() function below. >+ * The for loop below consumes the shorter range, >+ * whereas one of the while loops deals with the >+ * longer one. >+ */ >+ if (diff_format == D_SIDEBYSIDE) { >+ for (i=i0, j=j0; i<=i1 && j<=j1; i++, j++) >+ change(file1, f1, file2, f2, i, i, >+ j, j, &flags); >+ >+ while (i <= i1) { >+ change(file1, f1, file2, f2, >+ i, i, j+1, j, &flags); >+ i++; >+ } >+ >+ while (j <= j1) { >+ change(file1, f1, file2, f2, >+ i+1, i, j, j, &flags); >+ j++; >+ } >+ } else >+ change(file1, f1, file2, f2, i0, i1, j0, >+ j1, &flags); > } > } else { > for (i0 = m; i0 >= 1; i0 = i1 - 1) { >@@ -987,7 +1047,7 @@ > { > static size_t max_context = 64; > long curpos; >- int i, nc, f; >+ int i, nc; > const char *walk; > bool skip_blanks; > >@@ -1116,17 +1176,28 @@ > diff_output("%c", *walk); > } > } >+ if (diff_format == D_SIDEBYSIDE) { >+ if (a > b) { >+ print_space(0, hw + padding , *pflags); >+ } else { >+ nc = fetch(ixold, a, b, f1, '\0', 1, *pflags); >+ print_space(nc, hw - nc + padding, *pflags); >+ } >+ diff_output("%c", (a>b)? '>' : ((c>d)? '<' : '|')); >+ print_space(hw + padding + 1 , padding, *pflags); >+ fetch(ixnew, c, d, f2, '\0', 0, *pflags); >+ diff_output("\n"); >+ } > if (diff_format == D_NORMAL || diff_format == D_IFDEF) { > fetch(ixold, a, b, f1, '<', 1, *pflags); > if (a <= b && c <= d && diff_format == D_NORMAL) > diff_output("---\n"); > } >- f = 0; >- if (diff_format != D_GFORMAT) >- f = fetch(ixnew, c, d, f2, diff_format == D_NORMAL ? '>' : '\0', 0, *pflags); >- if (f != 0 && diff_format == D_EDIT) { >+ if (diff_format != D_GFORMAT && diff_format != D_SIDEBYSIDE) >+ fetch(ixnew, c, d, f2, diff_format == D_NORMAL ? '>' : '\0', 0, *pflags); >+ if (edoffset != 0 && diff_format == D_EDIT) { > /* >- * A non-zero return value for D_EDIT indicates that the >+ * A non-zero edoffset value for D_EDIT indicates that the > * last line printed was a bare dot (".") that has been > * escaped as ".." to prevent ed(1) from misinterpreting > * it. We have to add a substitute command to change this >@@ -1133,10 +1204,10 @@ > * back and restart where we left off. > */ > diff_output(".\n"); >- diff_output("%ds/.//\n", a + f - 1); >- b = a + f - 1; >+ diff_output("%ds/.//\n", a + edoffset - 1); >+ b = a + edoffset - 1; > a = b + 1; >- c += f; >+ c += edoffset; > goto restart; > } > if ((diff_format == D_EDIT || diff_format == D_REVERSE) && c <= d) >@@ -1150,9 +1221,10 @@ > static int > fetch(long *f, int a, int b, FILE *lb, int ch, int oldfile, int flags) > { >- int i, j, c, lastc, col, nc; >- int newcol; >+ int i, j, c, lastc, col, nc, newcol; > >+ edoffset = 0; >+ nc = 0; > /* > * When doing #ifdef's, copy down to current line > * if this is the first file, so that stuff makes it to output. >@@ -1180,12 +1252,15 @@ > } > for (i = a; i <= b; i++) { > fseek(lb, f[i - 1], SEEK_SET); >- nc = f[i] - f[i - 1]; >- if ((diff_format != D_IFDEF && diff_format != D_GFORMAT) && >+ nc = (f[i] - f[i - 1]); >+ if (diff_format == D_SIDEBYSIDE && hw < nc) >+ nc = hw; >+ if ((diff_format != D_IFDEF && diff_format != D_GFORMAT) && > ch != '\0') { > diff_output("%c", ch); >- if (Tflag && (diff_format == D_NORMAL || diff_format == D_CONTEXT >- || diff_format == D_UNIFIED)) >+ if (Tflag && (diff_format == D_NORMAL || >+ diff_format == D_CONTEXT || >+ diff_format == D_UNIFIED)) > diff_output("\t"); > else if (diff_format != D_UNIFIED) > diff_output(" "); >@@ -1193,19 +1268,43 @@ > col = 0; > for (j = 0, lastc = '\0'; j < nc; j++, lastc = c) { > if ((c = getc(lb)) == EOF) { >- if (diff_format == D_EDIT || diff_format == D_REVERSE || >+ if (diff_format == D_EDIT || >+ diff_format == D_REVERSE || > diff_format == D_NREVERSE) > warnx("No newline at end of file"); > else > diff_output("\n\\ No newline at end of " > "file\n"); >- return (0); >+ return col; > } >- if (c == '\t' && (flags & D_EXPANDTABS)) { >- newcol = ((col/tabsize)+1)*tabsize; >- do { >- diff_output(" "); >- } while (++col < newcol); >+ /* >+ * when using --side-by-side, col needs to be increased >+ * in any case to keep the columns aligned >+ */ >+ if (c == '\t') { >+ if (flags & D_EXPANDTABS) { >+ newcol = ((col/tabsize)+1)*tabsize; >+ do { >+ if (diff_format == D_SIDEBYSIDE) >+ j++; >+ diff_output(" "); >+ } while (++col < newcol && j < nc); >+ } else { >+ if (diff_format == D_SIDEBYSIDE) { >+ if ((j + tabsize) > nc) { >+ diff_output("%*s", >+ nc - j,""); >+ j = col = nc; >+ } else { >+ diff_output("\t"); >+ col += tabsize - 1; >+ j += tabsize - 1; >+ } >+ } else { >+ diff_output("\t"); >+ col++; >+ } >+ } > } else { > if (diff_format == D_EDIT && j == 1 && c == '\n' > && lastc == '.') { >@@ -1212,19 +1311,25 @@ > /* > * Don't print a bare "." line > * since that will confuse ed(1). >- * Print ".." instead and return, >- * giving the caller an offset >- * from which to restart. >+ * Print ".." instead and set the, >+ * global variable edoffset to an >+ * offset from which to restart. >+ * The caller must check the value >+ * of edoffset > */ > diff_output(".\n"); >- return (i - a + 1); >+ edoffset = i - a + 1; >+ return edoffset; > } >- diff_output("%c", c); >- col++; >+ /* when side-by-side, do not print a newline */ >+ if (diff_format != D_SIDEBYSIDE || c != '\n') { >+ diff_output("%c", c); >+ col++; >+ } > } > } > } >- return (0); >+ return col; > } > > /* >@@ -1578,3 +1683,25 @@ > diff_output("%s %s\t%s\n", diff_format == D_CONTEXT ? "---" : "+++", > file2, buf2); > } >+ >+/* >+ * Prints n number of space characters either by using tab >+ * or single space characters. >+ * nc is the preceding number of characters >+ */ >+static void >+print_space(int nc, int n, int flags) { >+ int i, col; >+ >+ col = n; >+ if ((flags & D_EXPANDTABS) == 0) { >+ /* first tabstop may be closer than tabsize */ >+ i = tabsize - (nc % tabsize); >+ while (col >= tabsize) { >+ diff_output("\t"); >+ col -= i; >+ i = tabsize; >+ } >+ } >+ diff_output("%*s", col, ""); >+} >\ No newline at end of file
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 219933
: 211439 |
211440