PERFORCE change 182457 for review
Benjamin Fiedler
bfiedler at FreeBSD.org
Mon Aug 16 07:23:33 UTC 2010
http://p4web.freebsd.org/@@182457?ac=10
Change 182457 by bfiedler at 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)
More information about the p4-projects
mailing list