svn commit: r317194 - in head/usr.bin/diff: . tests

Baptiste Daroussin bapt at FreeBSD.org
Thu Apr 20 14:22:35 UTC 2017


Author: bapt
Date: Thu Apr 20 14:22:33 2017
New Revision: 317194
URL: https://svnweb.freebsd.org/changeset/base/317194

Log:
  Implement a basic --changed-group-format
  
  etcupdate(8) requires that option, while GNU diff supports many more variation
  of that options, their behaviour beside the simple verion implemented here are
  quite inconsistent as such I do not plan to implement those.
  
  The only special keyword supported by this implementation are: %< and %>
  %= is not implemented as the documentation of GNU diff says: common lines, but
  it actually when tested print the changes from the first file

Added:
  head/usr.bin/diff/tests/group-format.out   (contents, props changed)
Modified:
  head/usr.bin/diff/diff.1
  head/usr.bin/diff/diff.c
  head/usr.bin/diff/diff.h
  head/usr.bin/diff/diffreg.c
  head/usr.bin/diff/tests/Makefile
  head/usr.bin/diff/tests/diff_test.sh

Modified: head/usr.bin/diff/diff.1
==============================================================================
--- head/usr.bin/diff/diff.1	Thu Apr 20 13:57:53 2017	(r317193)
+++ head/usr.bin/diff/diff.1	Thu Apr 20 14:22:33 2017	(r317194)
@@ -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:

Modified: head/usr.bin/diff/diff.c
==============================================================================
--- head/usr.bin/diff/diff.c	Thu Apr 20 13:57:53 2017	(r317193)
+++ head/usr.bin/diff/diff.c	Thu Apr 20 14:22:33 2017	(r317194)
@@ -41,6 +41,7 @@ int	 lflag, Nflag, Pflag, rflag, sflag, 
 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:

Modified: head/usr.bin/diff/diff.h
==============================================================================
--- head/usr.bin/diff/diff.h	Thu Apr 20 13:57:53 2017	(r317193)
+++ head/usr.bin/diff/diff.h	Thu Apr 20 14:22:33 2017	(r317194)
@@ -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, s
 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;

Modified: head/usr.bin/diff/diffreg.c
==============================================================================
--- head/usr.bin/diff/diffreg.c	Thu Apr 20 13:57:53 2017	(r317193)
+++ head/usr.bin/diff/diffreg.c	Thu Apr 20 14:22:33 2017	(r317194)
@@ -1008,7 +1008,7 @@ output(char *file1, FILE *f1, char *file
 	}
 	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 *file
     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, i
 	 * 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, i
 	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))

Modified: head/usr.bin/diff/tests/Makefile
==============================================================================
--- head/usr.bin/diff/tests/Makefile	Thu Apr 20 13:57:53 2017	(r317193)
+++ head/usr.bin/diff/tests/Makefile	Thu Apr 20 14:22:33 2017	(r317194)
@@ -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
 

Modified: head/usr.bin/diff/tests/diff_test.sh
==============================================================================
--- head/usr.bin/diff/tests/diff_test.sh	Thu Apr 20 13:57:53 2017	(r317193)
+++ head/usr.bin/diff/tests/diff_test.sh	Thu Apr 20 14:22:33 2017	(r317194)
@@ -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
 }

Added: head/usr.bin/diff/tests/group-format.out
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.bin/diff/tests/group-format.out	Thu Apr 20 14:22:33 2017	(r317194)
@@ -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);
+}


More information about the svn-src-head mailing list