diff options
-rw-r--r-- | usr.bin/diff/diff.1 | 17 | ||||
-rw-r--r-- | usr.bin/diff/diff.c | 7 | ||||
-rw-r--r-- | usr.bin/diff/diff.h | 2 | ||||
-rw-r--r-- | usr.bin/diff/diffreg.c | 42 | ||||
-rw-r--r-- | usr.bin/diff/tests/Makefile | 3 | ||||
-rwxr-xr-x | usr.bin/diff/tests/diff_test.sh | 11 | ||||
-rw-r--r-- | usr.bin/diff/tests/group-format.out | 27 |
7 files changed, 101 insertions, 8 deletions
diff --git a/usr.bin/diff/diff.1 b/usr.bin/diff/diff.1 index aeb4ee15df1a..a1f3edd1b8c5 100644 --- a/usr.bin/diff/diff.1 +++ b/usr.bin/diff/diff.1 @@ -30,7 +30,7 @@ .\" @(#)diff.1 8.1 (Berkeley) 6/30/93 .\" $FreeBSD$ .\" -.Dd April 8, 2017 +.Dd April 20, 2017 .Dt DIFF 1 .Os .Sh NAME @@ -44,6 +44,7 @@ .Fl n | q | u .Oc .Op Fl -brief +.Op Fl -changed-group-format Ar GFMT .Op Fl -ed .Op Fl -expand-tabs .Op Fl -forward-ed @@ -70,6 +71,7 @@ .Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern .Op Fl L Ar label | Fl -label Ar label .Op Fl -brief +.Op Fl -changed-group-format Ar GFMT .Op Fl -ed .Op Fl -expand-tabs .Op Fl -forward-ed @@ -94,6 +96,7 @@ .Op Fl abdiltw .Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern .Op Fl -brief +.Op Fl -changed-group-format Ar GFMT .Op Fl -ed .Op Fl -expand-tabs .Op Fl -forward-ed @@ -119,6 +122,7 @@ .Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern .Op Fl L Ar label | Fl -label Ar label .Op Fl -brief +.Op Fl -changed-group-format Ar GFMT .Op Fl -ed .Op Fl -expand-tabs .Op Fl -forward-ed @@ -146,6 +150,7 @@ .Fl n | q | u .Oc .Op Fl -brief +.Op Fl -changed-group-format Ar GFMT .Op Fl -context .Op Fl -ed .Op Fl -expand-tabs @@ -355,6 +360,16 @@ E.g., .Dq if (\ \&a == b \&) will compare equal to .Dq if(a==b) . +.It Fl -changed-group-format Ar GFMT +Format input groups in the provided +.Pp +the format is a string with special keywords: +.Bl -tag -width %< +.It %< +lines from FILE1 +.It %< +lines from FILE2 +.El .El .Pp Directory comparison options: diff --git a/usr.bin/diff/diff.c b/usr.bin/diff/diff.c index 9c20fa182d90..f314e9f76c3f 100644 --- a/usr.bin/diff/diff.c +++ b/usr.bin/diff/diff.c @@ -41,6 +41,7 @@ int lflag, Nflag, Pflag, rflag, sflag, Tflag, cflag; int diff_format, diff_context, status, ignore_file_case; int tabsize = 8; char *start, *ifdefname, *diffargs, *label[2], *ignore_pats; +char *group_format = NULL; struct stat stb1, stb2; struct excludes *excludes_list; regex_t ignore_re; @@ -54,6 +55,7 @@ enum { OPT_NORMAL, OPT_HORIZON_LINES, OPT_SPEED_LARGE_FILES, + OPT_CHANGED_GROUP_FORMAT, }; static struct option longopts[] = { @@ -89,6 +91,7 @@ static struct option longopts[] = { { "speed-large-files", no_argument, NULL, OPT_SPEED_LARGE_FILES}, { "strip-trailing-cr", no_argument, NULL, OPT_STRIPCR }, { "tabsize", optional_argument, NULL, OPT_TSIZE }, + { "changed-group-format", required_argument, NULL, OPT_CHANGED_GROUP_FORMAT}, { NULL, 0, 0, '\0'} }; @@ -227,6 +230,10 @@ main(int argc, char **argv) case 'x': push_excludes(optarg); break; + case OPT_CHANGED_GROUP_FORMAT: + diff_format = D_GFORMAT; + group_format = optarg; + break; case OPT_HORIZON_LINES: break; /* XXX TODO for compatibility with GNU diff3 */ case OPT_IGN_FN_CASE: diff --git a/usr.bin/diff/diff.h b/usr.bin/diff/diff.h index f70bb96102a4..87452058220f 100644 --- a/usr.bin/diff/diff.h +++ b/usr.bin/diff/diff.h @@ -47,6 +47,7 @@ #define D_NREVERSE 5 /* Reverse ed script with numbered lines and no trailing . */ #define D_BRIEF 6 /* Say if the files differ */ +#define D_GFORMAT 7 /* Diff with defined changed group format */ /* * Output flags @@ -87,6 +88,7 @@ extern int lflag, Nflag, Pflag, rflag, sflag, Tflag, cflag; extern int diff_format, diff_context, status, ignore_file_case; extern int tabsize; extern char *start, *ifdefname, *diffargs, *label[2], *ignore_pats; +extern char *group_format; extern struct stat stb1, stb2; extern struct excludes *excludes_list; extern regex_t ignore_re; diff --git a/usr.bin/diff/diffreg.c b/usr.bin/diff/diffreg.c index 6619837ba132..8f6d7ccd67c4 100644 --- a/usr.bin/diff/diffreg.c +++ b/usr.bin/diff/diffreg.c @@ -1008,7 +1008,7 @@ output(char *file1, FILE *f1, char *file2, FILE *f2, int flags) } if (m == 0) change(file1, f1, file2, f2, 1, 0, 1, len[1], &flags); - if (diff_format == D_IFDEF) { + if (diff_format == D_IFDEF || diff_format == D_GFORMAT) { for (;;) { #define c i0 if ((c = getc(f1)) == EOF) @@ -1081,10 +1081,13 @@ change(char *file1, FILE *f1, char *file2, FILE *f2, int a, int b, int c, int d, int *pflags) { static size_t max_context = 64; - int i; + long curpos; + int i, nc; + const char *walk; restart: - if (diff_format != D_IFDEF && a > b && c > d) + if ((diff_format != D_IFDEF || diff_format == D_GFORMAT) && + a > b && c > d) return; if (ignore_pats != NULL) { char *line; @@ -1181,12 +1184,38 @@ proceed: } break; } + if (diff_format == D_GFORMAT) { + curpos = ftell(f1); + /* print through if append (a>b), else to (nb: 0 vs 1 orig) */ + nc = ixold[a > b ? b : a - 1] - curpos; + for (i = 0; i < nc; i++) + diff_output("%c", getc(f1)); + for (walk = group_format; *walk != '\0'; walk++) { + if (*walk == '%') { + walk++; + switch (*walk) { + case '<': + fetch(ixold, a, b, f1, '<', 1, *pflags); + break; + case '>': + fetch(ixnew, c, d, f2, '>', 0, *pflags); + break; + default: + diff_output("%%%c", *walk); + break; + } + continue; + } + diff_output("%c", *walk); + } + } 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"); } - i = fetch(ixnew, c, d, f2, diff_format == D_NORMAL ? '>' : '\0', 0, *pflags); + if (diff_format != D_GFORMAT) + i = fetch(ixnew, c, d, f2, diff_format == D_NORMAL ? '>' : '\0', 0, *pflags); if (i != 0 && diff_format == D_EDIT) { /* * A non-zero return value for D_EDIT indicates that the @@ -1220,7 +1249,7 @@ fetch(long *f, int a, int b, FILE *lb, int ch, int oldfile, int flags) * When doing #ifdef's, copy down to current line * if this is the first file, so that stuff makes it to output. */ - if (diff_format == D_IFDEF && oldfile) { + if ((diff_format == D_IFDEF) && oldfile) { long curpos = ftell(lb); /* print through if append (a>b), else to (nb: 0 vs 1 orig) */ nc = f[a > b ? b : a - 1] - curpos; @@ -1244,7 +1273,8 @@ fetch(long *f, int a, int b, FILE *lb, int ch, int oldfile, int flags) for (i = a; i <= b; i++) { fseek(lb, f[i - 1], SEEK_SET); nc = f[i] - f[i - 1]; - if (diff_format != D_IFDEF && ch != '\0') { + 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)) diff --git a/usr.bin/diff/tests/Makefile b/usr.bin/diff/tests/Makefile index 295e3141f3d9..3fa234f3d515 100644 --- a/usr.bin/diff/tests/Makefile +++ b/usr.bin/diff/tests/Makefile @@ -22,7 +22,8 @@ ${PACKAGE}FILES+= \ unified_9999.out \ header.out \ header_ns.out \ - ifdef.out + ifdef.out \ + group-format.out NETBSD_ATF_TESTS_SH+= netbsd_diff_test diff --git a/usr.bin/diff/tests/diff_test.sh b/usr.bin/diff/tests/diff_test.sh index 589bc9a8603b..62ca8277c5f3 100755 --- a/usr.bin/diff/tests/diff_test.sh +++ b/usr.bin/diff/tests/diff_test.sh @@ -5,6 +5,7 @@ atf_test_case unified atf_test_case header atf_test_case header_ns atf_test_case ifdef +atf_test_case group_format simple_body() { @@ -78,6 +79,15 @@ ifdef_body() "$(atf_get_srcdir)/input_c2.in" } +group_format_body() +{ + atf_check -o file:$(atf_get_srcdir)/group-format.out -s eq:1 \ + diff --changed-group-format='<<<<<<< (local) +%<======= +%>>>>>>>> (stock) +' "$(atf_get_srcdir)/input_c1.in" "$(atf_get_srcdir)/input_c2.in" +} + atf_init_test_cases() { atf_add_test_case simple @@ -85,4 +95,5 @@ atf_init_test_cases() atf_add_test_case header atf_add_test_case header_ns atf_add_test_case ifdef + atf_add_test_case group_format } diff --git a/usr.bin/diff/tests/group-format.out b/usr.bin/diff/tests/group-format.out new file mode 100644 index 000000000000..4e1bf85fbba7 --- /dev/null +++ b/usr.bin/diff/tests/group-format.out @@ -0,0 +1,27 @@ +/* + * A comment + * +<<<<<<< (local) + * And another bla +======= + * And another bla +>>>>>>> (stock) + * +<<<<<<< (local) + * And yet another +======= + * and yet another +>>>>>>> (stock) + */ + +int +main(void) +{ +<<<<<<< (local) +======= + +>>>>>>> (stock) + printf("something"); + + return (0); +} |