Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 16 Aug 2010 07:23:32 GMT
From:      Benjamin Fiedler <bfiedler@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 182457 for review
Message-ID:  <201008160723.o7G7NWQU029223@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@182457?ac=10

Change 182457 by bfiedler@freebsd-home on 2010/08/16 07:23:18

	Extend sdiff args; create a pipe between sdiff and diff when diff called first

Affected files ...

.. //depot/projects/soc2010/bsdtextproc/gabor_diff/diff.c#13 edit
.. //depot/projects/soc2010/bsdtextproc/gabor_diff/pathnames.h#3 edit
.. //depot/projects/soc2010/bsdtextproc/sdiff/sdiff.c#3 edit

Differences ...

==== //depot/projects/soc2010/bsdtextproc/gabor_diff/diff.c#13 (text+ko) ====

@@ -74,8 +74,7 @@
 	SUPCL_OPT,
 	LF_OPT,
 
-/* the following groupings must be in sequence
-*/
+/* the following groupings must be in sequence */
         OLDGF_OPT,
         NEWGF_OPT,
 	UNCGF_OPT,
@@ -84,8 +83,7 @@
         OLDLF_OPT,
         NEWLF_OPT,
         UNCLF_OPT,
-/* end order-sensitive enums
-*/
+/* end order-sensitive enums */
 
 	TSIZE_OPT,
 	HLINES_OPT,
@@ -94,7 +92,7 @@
 };
 
 
-#define	OPTIONS	"0123456789abBC:cdD:eEfhI:iL:lnNPpqrS:sTtU:uvwX:x:y"
+#define	OPTIONS	"0123456789abBC:cdD:eEfhI:iL:lnNPpqrS:sTtU:uvwW:X:x:y"
 static struct option longopts[] = {
 	{ "ignore-file-name-case",	no_argument,		NULL,	FCASE_IGNORE_OPT },
 	{ "no-ignore-file-name-case",	no_argument,		NULL,	FCASE_SENSITIVE_OPT },
@@ -138,7 +136,7 @@
 	
 /* options to be forwarded to sdiff */
 	{ "side-by-side",		no_argument,		NULL,	'y' },
-	{ "width",			optional_argument,	NULL,	'W' },
+	{ "width",			required_argument,		NULL,	'W' },
 	{ "left-column",		no_argument,		NULL,	LEFTC_OPT },
 	{ "suppress-common-lines",	no_argument,		NULL,	SUPCL_OPT },
 
@@ -181,7 +179,13 @@
 {
 	char	*ep, *fromfile = NULL, *tofile = NULL, **oargv, *src, *dst;
 	int	 ch, lastch, gotstdin, prevoptind, newarg, oargc, flags = 0;
+	char **sdiffargv; int sdiffargc=1; int width=-1;
 
+	/* sdiff gets at most 8 args if called*/
+	if (!(sdiffargv = calloc(argc, sizeof(char **) * 8)))
+		err(2, "main");
+	pid_t pid = getpid();
+	
 	setlocale(LC_ALL, "");
 
 	oargv = argv;
@@ -310,12 +314,29 @@
 		case 'x':
 			push_excludes(optarg);
 			break;
+		
 		case 'y':
-			oargv[0] = _PATH_SDIFF;
-			execv(_PATH_SDIFF, oargv);
-			_exit(127);
-
+			sdiffargv[0] = _PATH_SDIFF;
+			break;
+		case 'W':
+			sdiffargv[0] = _PATH_SDIFF;
+		
+			if (optarg != NULL) {
+				context = strtol(optarg, &ep, 10);
+                                if (*ep != '\0' || context < 0 || context >=ULLONG_MAX)
+                                        err(2, "context out of range\n");
+                                width = (int)context;
+			}
+			break;
+		case LEFTC_OPT:
+			sdiffargv[0] = _PATH_SDIFF;
+			sdiffargv[sdiffargc++] = "-l";
+			break;
+		case SUPCL_OPT:
+			sdiffargv[0] = _PATH_SDIFF;
+			sdiffargv[sdiffargc++] = "-s";
 			break;
+			
 		case FROMFILE_OPT:
 			if (tofile != NULL)
 				err(2, "--from-file and --to-file are both specified");
@@ -460,6 +481,42 @@
 			if (stat(dst, &stb2) < 0)
 				err(2, "%s", dst);
 		}
+		
+		if( strcmp(sdiffargv[0], _PATH_SDIFF) == 0 )
+		{
+			/* give sdiff the parent process to wait on */
+			asprintf( &sdiffargv[sdiffargc++], "--diff-pid=%d", pid);
+			sdiffargv[sdiffargc++]= src;
+			sdiffargv[sdiffargc++] = dst;
+			
+			int fd[2];
+			if (pipe(fd))
+				err(2, "pipe");
+			
+			pid_t newpid;
+			
+			switch(newpid = fork()) {
+				case 0:
+					/* child */
+					/* We don't write to the pipe. */
+					close(fd[1]);
+					if (dup2(fd[0], STDIN_FILENO) == -1)
+					err(2, "child could not duplicate descriptor");
+					/* Free unused descriptor. */
+					close(fd[0]);
+
+					execvp(_PATH_SDIFF, sdiffargv);
+					err(2, "could not execute sdiff: %s", _PATH_SDIFF);
+					break;
+				case -1:
+					err(2, "could not fork");
+					break;
+			}
+		
+			/* We don't read from the pipe. */
+			close(fd[0]); 
+			
+		}
 		print_status(diffreg(src, dst, flags), src, dst,
 		    NULL);
 	}

==== //depot/projects/soc2010/bsdtextproc/gabor_diff/pathnames.h#3 (text+ko) ====

@@ -23,4 +23,5 @@
 #include <paths.h>
 
 #define	_PATH_PR	"/usr/bin/pr"
-#define _PATH_SDIFF     "/usr/bin/sdiff"
+/*#define _PATH_SDIFF     "/usr/bin/sdiff" */
+#define _PATH_SDIFF 	"../sdiff/sdiff"

==== //depot/projects/soc2010/bsdtextproc/sdiff/sdiff.c#3 (text+ko) ====

@@ -75,26 +75,68 @@
 FILE	*outfp;		/* file to save changes to */
 const char *tmpdir;	/* TMPDIR or /tmp */
 
+enum {
+      HELP_OPT = CHAR_MAX + 1,
+      NORMAL_OPT,
+      FCASE_SENSITIVE_OPT,
+      FCASE_IGNORE_OPT,
+      FROMFILE_OPT,
+      TOFILE_OPT,
+      UNIDIR_OPT,
+      STRIPCR_OPT,
+      HORIZ_OPT,
+      LEFTC_OPT,
+      SUPCL_OPT,
+      LF_OPT,
+/* the following groupings must be in sequence */
+        OLDGF_OPT,
+        NEWGF_OPT,
+      UNCGF_OPT,
+        CHGF_OPT,
+        OLDLF_OPT,
+        NEWLF_OPT,
+        UNCLF_OPT,
+/* end order-sensitive enums */
+      TSIZE_OPT,
+      HLINES_OPT,
+      LFILES_OPT,
+      DIFFPROG_OPT,
+      
+/* pid from the diff parent (if applicable) */
+      DIFF_PID,
+      
+      NOOP_OPT,
+};
+
 static struct option longopts[] = {
-	{ "text",			no_argument,		NULL,	'a' },
-	{ "ignore-blank-lines",		no_argument,		NULL,	'B' },
-	{ "ignore-space-change",	no_argument,		NULL,	'b' },
-	{ "minimal",			no_argument,		NULL,	'd' },
-	{ "ignore-tab-expansion",	no_argument,		NULL,	'E' },
-	{ "diff-program",		required_argument,	NULL,	'F' },
-	{ "speed-large-files",		no_argument,		NULL,	'H' },
-	{ "ignore-matching-lines",	required_argument,	NULL,	'I' },
-	{ "ignore-case",		no_argument,		NULL,	'i' },
-	{ "left-column",		no_argument,		NULL,	'l' },
-	{ "output",			required_argument,	NULL,	'o' },
-	{ "strip-trailing-cr",		no_argument,		NULL,	'S' },
-	{ "suppress-common-lines",	no_argument,		NULL,	's' },
-	{ "expand-tabs",		no_argument,		NULL,	't' },
-	{ "ignore-all-space",		no_argument,		NULL,	'W' },
-	{ "width",			required_argument,	NULL,	'w' },
-	{ NULL,				0,			NULL,	 0  }
+	/* options only processed in sdiff */
+      { "left-column",                no_argument,            NULL,   LEFTC_OPT },
+      { "suppress-common-lines",      no_argument,            NULL,   's' },
+      { "width",                      required_argument,      NULL,   'w' },
+      { "ignore-all-space",           no_argument,            NULL,   'W' },
+      { "output",			required_argument,	NULL,	'o' },
+      { "diff-program",               required_argument,      NULL,   DIFFPROG_OPT },
+      
+      { "pipe-fd",                required_argument,            NULL,   PIPE_FD },
+      { "diff-pid",		required_argument,		NULL,	DIFF_PID },
+      
+      { "ignore-file-name-case",      no_argument,            NULL,   FCASE_IGNORE_OPT },
+      { "no-ignore-file-name-case",   no_argument,            NULL,   FCASE_SENSITIVE_OPT },
+      { "strip-trailing-cr",          no_argument,            NULL,   STRIPCR_OPT },
+      { "tabsize",                    required_argument,      NULL,   TSIZE_OPT },
+      { "help",                       no_argument,            NULL,   HELP_OPT },
+      { "text",                       no_argument,            NULL,   'a' },
+      { "ignore-blank-lines",         no_argument,            NULL,   'B' },
+      { "ignore-space-change",        no_argument,            NULL,   'b' },
+      { "minimal",                    no_argument,            NULL,   'd' },
+      { "ignore-tab-expansion",       no_argument,            NULL,   'E' },
+      { "ignore-matching-lines",      required_argument,      NULL,   'I' },
+      { "ignore-case",                no_argument,            NULL,   'i' },
+      { "expand-tabs",                no_argument,            NULL,   't' },
+      { "speed-large-files",          no_argument,            NULL,   'H' },
+      
+      { NULL,                         0,                      NULL,   '\0'}
 };
-
 /*
  * Create temporary file if source_file is not a regular file.
  * Returns temporary file name if one was malloced, NULL if unnecessary.
@@ -163,11 +205,12 @@
 int
 main(int argc, char **argv)
 {
-	FILE *diffpipe, *file1, *file2;
+	FILE *diffpipe=NULL, *file1, *file2;
 	size_t diffargc = 0, wflag = WIDTH;
-	int ch, fd[2], status;
-	pid_t pid;
+	int ch, fd[2] = {-1}, status;
+	pid_t pid=0; pid_t ppid =-1;
 	const char *outfile = NULL;
+	struct option *popt;
 	char **diffargv, *diffprog = "diff", *filename1, *filename2,
 	    *tmp1, *tmp2, *s1, *s2;
 
@@ -187,70 +230,97 @@
 
 	/* Add first argument, the program name. */
 	diffargv[diffargc++] = diffprog;
+	
+	/* create a dynamic string for merging single-switch options */
+	if ( asprintf(&diffargv[diffargc++], "-")  < 0 )
+		err(2, "main");
 
 	while ((ch = getopt_long(argc, argv, "aBbdEHI:ilo:stWw:",
 	    longopts, NULL)) != -1) {
 		const char *errstr;
 
 		switch (ch) {
+			
+		/* only compatible --long-name-form with diff */
+		case FCASE_IGNORE_OPT:
+		case FCASE_SENSITIVE_OPT:
+		case STRIPCR_OPT:
+		case TSIZE_OPT:
+		case 'S':
+		case 'W':
+			for(popt = longopts; ch != popt->val && popt->name != NULL; popt++);
+			asprintf(&diffargv[diffargc++], "%s", popt->name );
+		break;
+		
+		/* combine no-arg single switches */
 		case 'a':
-			diffargv[diffargc++] = "-a";
-			break;
 		case 'B':
-			diffargv[diffargc++] = "-B";
-			break;
 		case 'b':
-			diffargv[diffargc++] = "-b";
-			break;
 		case 'd':
-			diffargv[diffargc++] = "-d";
-			break;
 		case 'E':
-			diffargv[diffargc++] = "-E";
+		case 'i':
+		case 't':
+		case 'H':
+			for(popt = longopts; ch != popt->val && popt->name != NULL; popt++);
+			diffargv[1]  = realloc( diffargv[1], sizeof(char) * strlen(diffargv[1]) + 2 ); 
+			sprintf(diffargv[1], "%s%c", diffargv[1], ch);
 			break;
-		case 'F':
+		
+		case DIFFPROG_OPT:
 			diffargv[0] = diffprog = optarg;
 			break;
-		case 'H':
-			diffargv[diffargc++] = "-H";
-			break;
 		case 'I':
 			Iflag = 1;
 			diffargv[diffargc++] = "-I";
 			diffargv[diffargc++] = optarg;
 			break;
-		case 'i':
-			diffargv[diffargc++] = "-i";
-			break;
 		case 'l':
 			lflag = 1;
 			break;
 		case 'o':
 			outfile = optarg;
 			break;
-		case 'S':
-			diffargv[diffargc++] = "--strip-trailing-cr";
-			break;
 		case 's':
 			sflag = 1;
 			break;
-		case 't':
-			diffargv[diffargc++] = "-t";
-			break;
-		case 'W':
-			diffargv[diffargc++] = "-w";
-			break;
 		case 'w':
 			wflag = strtonum(optarg, WIDTH_MIN,
 			    INT_MAX, &errstr);
 			if (errstr)
 				errx(2, "width is %s: %s", errstr, optarg);
 			break;
+		
+		case DIFF_PID:
+			ppid = strtonum(optarg, 0, INT_MAX, &errstr);
+			if (errstr)
+				errx(2, "diff pid value is %s: %s", errstr, optarg);
+			break;
+			
+		case HELP_OPT:
+			usage();
+			break;
+		
 		default:
 			usage();
+			break;
 		}
+		
 
+
+	}
+	
+	/* no single switches were used */
+	if( strcmp( diffargv[1], "-" ) == 0 )
+	{
+		int i;
+		for(i=1; i<argc-1; i++)
+		{
+			diffargv[i] = diffargv[i+1];
+		}
+		diffargv[diffargc-1] = NULL;
+		diffargc--;
 	}
+	
 	argc -= optind;
 	argv += optind;
 
@@ -299,32 +369,38 @@
 		errx(2, "width is too large: %zu", width);
 	line_width = width * 2 + 3;
 
-	if (pipe(fd))
-		err(2, "pipe");
+	if( ppid == -1 )
+	{
+		if (pipe(fd))
+			err(2, "pipe");
+
+		switch(pid = fork()) {
+		case 0:
+			/* child */
+			/* We don't read from the pipe. */
+			close(fd[0]);
+			if (dup2(fd[1], STDOUT_FILENO) == -1)
+				err(2, "child could not duplicate descriptor");
+			/* Free unused descriptor. */
+			close(fd[1]);
+
+			execvp(diffprog, diffargv);
+			err(2, "could not execute diff: %s", diffprog);
+			break;
+		case -1:
+			err(2, "could not fork");
+			break;
+		}
 
-	switch(pid = fork()) {
-	case 0:
-		/* child */
-		/* We don't read from the pipe. */
-		close(fd[0]);
-		if (dup2(fd[1], STDOUT_FILENO) == -1)
-			err(2, "child could not duplicate descriptor");
-		/* Free unused descriptor. */
+		/* parent */
+		/* We don't write to the pipe. */
 		close(fd[1]);
 
-		execvp(diffprog, diffargv);
-		err(2, "could not execute diff: %s", diffprog);
-	case -1:
-		err(2, "could not fork");
+		/* Open pipe to diff command. */
+		if ((diffpipe = fdopen(fd[0], "r")) == NULL)
+			err(2, "could not open diff pipe");
 	}
-
-	/* parent */
-	/* We don't write to the pipe. */
-	close(fd[1]);
-
-	/* Open pipe to diff command. */
-	if ((diffpipe = fdopen(fd[0], "r")) == NULL)
-		err(2, "could not open diff pipe");
+	
 	if ((file1 = fopen(filename1, "r")) == NULL)
 		err(2, "could not open %s", filename1);
 	if ((file2 = fopen(filename2, "r")) == NULL)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201008160723.o7G7NWQU029223>