From owner-p4-projects@FreeBSD.ORG Mon Aug 16 07:23:33 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 1761710656A3; Mon, 16 Aug 2010 07:23:33 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C6D391065694 for ; Mon, 16 Aug 2010 07:23:32 +0000 (UTC) (envelope-from bfiedler@FreeBSD.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id AA9DE8FC0A for ; Mon, 16 Aug 2010 07:23:32 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id o7G7NWij029226 for ; Mon, 16 Aug 2010 07:23:32 GMT (envelope-from bfiedler@FreeBSD.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id o7G7NWQU029223 for perforce@freebsd.org; Mon, 16 Aug 2010 07:23:32 GMT (envelope-from bfiedler@FreeBSD.org) Date: Mon, 16 Aug 2010 07:23:32 GMT Message-Id: <201008160723.o7G7NWQU029223@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to bfiedler@FreeBSD.org using -f From: Benjamin Fiedler To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 182457 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Aug 2010 07:23:33 -0000 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 #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