]> git.neil.brown.name Git - wiggle.git/commitdiff
Add --output option to redirect output.
authorNeilBrown <neilb@suse.de>
Thu, 22 Aug 2013 07:54:42 +0000 (17:54 +1000)
committerNeilBrown <neilb@suse.de>
Thu, 22 Aug 2013 08:04:19 +0000 (18:04 +1000)
This is particularly useful for "git mergetool"

Signed-off-by: NeilBrown <neilb@suse.de>
ReadMe.c
parse.c
vpatch.c
wiggle.1
wiggle.c
wiggle.h

index 1db6f83f3eeb1acd0e5f0a5af5bbb7a78e7db47d..e8025a9def769cd3caecdc4c6455797761caf2f9 100644 (file)
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -38,7 +38,7 @@
 
 char Version[] = "wiggle " VERSION " " VERS_DATE " GPL-2+ http://neil.brown.name/wiggle/\n";
 
-char short_options[] = "xdmwlrhiW123p::VRvqBb";
+char short_options[] = "xdmwlrho:iW123p::VRvqBb";
 
 struct option long_options[] = {
        {"browse",      0, 0, 'B'},
@@ -55,6 +55,7 @@ struct option long_options[] = {
        {"verbose",     0, 0, 'v'},
        {"quiet",       0, 0, 'q'},
        {"strip",       1, 0, 'p'},
+       {"output",      1, 0, 'o'},
        {"no-ignore",   0, 0, 'i'},
        {"show-wiggles",0, 0, 'W'},
        {"ignore-blanks",0,0, 'b'},
diff --git a/parse.c b/parse.c
index 008fd043bbd6107eef93b3f8263a04cbe142974c..474152c01bab589618ac602abc9efeb3696c8e42 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -159,14 +159,13 @@ static struct plist *patch_add_file(struct plist *pl, int *np, char *file,
                }
                pl = npl;
        }
+       memset(&pl[n], 0, sizeof(pl[n]));
        pl[n].file = file;
        pl[n].start = start;
        pl[n].end = end;
        pl[n].last = pl[n].next = pl[n].prev = pl[n].parent = -1;
-       pl[n].chunks = pl[n].wiggles = 0; pl[n].conflicts = 100;
+       pl[n].conflicts = 100;
        pl[n].open = 1;
-       pl[n].calced = 0;
-       pl[n].is_merge = 0;
        *np = n+1;
        return pl;
 }
index 52c9d3f9a1d6d1f7738a3cf006f20fa2c0c1f6f0..a4475f68985a4da2a9356ca5dba209da31cc0e4e 100644 (file)
--- a/vpatch.c
+++ b/vpatch.c
@@ -1813,7 +1813,8 @@ static int merge_window(struct plist *p, FILE *f, int reverse, int replace,
                                        ci.merger, 0, &p->wiggles);
                                p->chunks = p->conflicts;
                                save_merge(fm, fb, fa, ci.merger,
-                                          p->file, !p->is_merge);
+                                          p->outfile ?: p->file,
+                                          p->outfile ? 0 : !p->is_merge);
                        }
                        if (!just_diff)
                                free(sm.body);
@@ -2402,12 +2403,15 @@ static int merge_window(struct plist *p, FILE *f, int reverse, int replace,
 
 static int show_merge(char *origname, FILE *patch, int reverse,
                      int is_merge, char *before, char *after,
-                     int replace, int selftest, int ignore_blanks,
+                     int replace, char *outfile,
+                     int selftest, int ignore_blanks,
                      int just_diff)
 {
-       struct plist p;
+       struct plist p = {0};
 
        p.file = origname;
+       if (replace)
+               p.outfile = outfile;
        if (patch) {
                p.start = 0;
                fseek(patch, 0, SEEK_END);
@@ -3068,7 +3072,8 @@ static void term_init(int doraw)
 }
 
 int vpatch(int argc, char *argv[], int patch, int strip,
-          int reverse, int replace, int selftest, int ignore_blanks)
+          int reverse, int replace, char *outfilename,
+          int selftest, int ignore_blanks)
 {
        /* NOTE argv[0] is first arg...
         * Behaviour depends on number of args and 'patch'.
@@ -3150,16 +3155,19 @@ int vpatch(int argc, char *argv[], int patch, int strip,
                        char *origname = strdup(argv[0]);
                        origname[strlen(origname) - 4] = '\0';
                        show_merge(origname, f, reverse, 0, NULL, NULL,
-                                  replace, selftest, ignore_blanks, just_diff);
+                                  replace, outfilename,
+                                  selftest, ignore_blanks, just_diff);
                } else
                        show_merge(argv[0], f, reverse, 1, NULL, NULL,
-                                  replace, selftest, ignore_blanks, just_diff);
+                                  replace, outfilename,
+                                  selftest, ignore_blanks, just_diff);
 
                break;
        case 2: /* an orig and a diff/.rej  or two files */
                if (just_diff) {
                        show_merge(NULL, NULL, reverse, 0, argv[0], argv[1],
-                                  replace, selftest, ignore_blanks, just_diff);
+                                  replace, outfilename,
+                                  selftest, ignore_blanks, just_diff);
                        break;
                }
                f = fopen(argv[1], "r");
@@ -3169,11 +3177,13 @@ int vpatch(int argc, char *argv[], int patch, int strip,
                        exit(1);
                }
                show_merge(argv[0], f, reverse, 0, NULL, NULL,
-                          replace, selftest, ignore_blanks, just_diff);
+                          replace, outfilename,
+                          selftest, ignore_blanks, just_diff);
                break;
        case 3: /* orig, before, after */
                show_merge(argv[0], NULL, reverse, 0, argv[1], argv[2],
-                          replace, selftest, ignore_blanks, just_diff);
+                          replace, outfilename,
+                          selftest, ignore_blanks, just_diff);
                break;
        }
 
index ebfeada91e3913a87833b50cb2844e5a91e6bfcd..4a4978c3cd01c08ad2a425aeed0cc763ab0224ee 100644 (file)
--- a/wiggle.1
+++ b/wiggle.1
@@ -221,6 +221,19 @@ mode, this instructs
 .I wiggle
 to always save the resulting merge when exiting.
 
+.TP
+.BR \-o ", " \-\-output=
+Rather than writing the result to stdout or to replace the original
+file, this requests that the output be written to the given file.
+This is only meaningful with
+.B \-\-merge
+or
+.B \-\-browse
+when given a single merge to browse.
+
+This option overrides
+.BR \-r .
+
 .TP
 .BR -R ", " \-\-reverse
 When used with the
@@ -636,7 +649,7 @@ in the user's home directory.
        tool = wiggle
 [mergetool "wiggle"]
        path = /usr/bin/wiggle
-       cmd = wiggle \-Br $LOCAL $BASE $REMOTE
+       cmd = wiggle \-B -o $MERGED $LOCAL $BASE $REMOTE
 .fi
 .RE
 
index fe71d495865b8bec8a1f7abb0c7f69a7f9abb13d..c1e94988c2288d44ff6e9c49e8d5242eb5b1b92d 100644 (file)
--- a/wiggle.c
+++ b/wiggle.c
@@ -459,7 +459,8 @@ static int do_diff(int argc, char *argv[], int obj, int ispatch,
 }
 
 static int do_merge(int argc, char *argv[], int obj, int blanks,
-                   int reverse, int replace, int ignore, int show_wiggles,
+                   int reverse, int replace, char *outfilename,
+                   int ignore, int show_wiggles,
                    int quiet)
 {
        /* merge three files, A B C, so changed between B and C get made to A
@@ -524,7 +525,14 @@ static int do_merge(int argc, char *argv[], int obj, int blanks,
                        return 2;
                }
        }
-       if (replace) {
+       if (outfilename) {
+               outfile = fopen(outfilename, "w");
+               if (!outfile) {
+                       fprintf(stderr, "%s: could not create %s\n",
+                               Cmd, outfilename);
+                       return 2;
+               }
+       } else if (replace) {
                int fd;
                replacename = xmalloc(strlen(argv[0]) + 20);
                orignew = xmalloc(strlen(argv[0]) + 20);
@@ -579,7 +587,9 @@ static int do_merge(int argc, char *argv[], int obj, int blanks,
                        ci.ignored,
                        ci.ignored == 1 ? "" : "s");
 
-       if (replace) {
+       if (outfilename)
+               fclose(outfile);
+       else if (replace) {
                fclose(outfile);
                if (rename(argv[0], orignew) == 0 &&
                    rename(replacename, argv[0]) == 0)
@@ -642,7 +652,7 @@ static int multi_merge(int argc, char *argv[], int obj, int blanks,
                         pl[i].start, pl[i].end, filename);
                av[0] = pl[i].file;
                av[1] = name;
-               rv |= do_merge(2, av, obj, blanks, reverse, 1, ignore,
+               rv |= do_merge(2, av, obj, blanks, reverse, 1, NULL, ignore,
                         show_wiggles, quiet);
        }
        return rv;
@@ -665,6 +675,7 @@ int main(int argc, char *argv[])
        int show_wiggles = 0;
        char *helpmsg;
        char *trace;
+       char *outfile = NULL;
        int selftest = 0;
        int ignore_blanks = 0;
 
@@ -735,6 +746,10 @@ int main(int argc, char *argv[])
                case 'r':
                        replace = 1;
                        continue;
+               case 'o':
+                       outfile = optarg;
+                       replace = 1;
+                       continue;
                case 'R':
                        reverse = 1;
                        continue;
@@ -787,7 +802,7 @@ int main(int argc, char *argv[])
 
        if (mode == 'B') {
                vpatch(argc-optind, argv+optind, ispatch,
-                      strip, reverse, replace, selftest,
+                      strip, reverse, replace, outfile, selftest,
                       ignore_blanks);
                /* should not return */
                exit(1);
@@ -801,9 +816,14 @@ int main(int argc, char *argv[])
        }
        if (mode != 'm' && !obj)
                obj = 'w';
+       if (ispatch && outfile) {
+               fprintf(stderr, "%s: --output incompatible with --patch\n",
+                       Cmd);
+               exit(2);
+       }
        if (replace && mode != 'm') {
                fprintf(stderr,
-                       "%s: --replace only allowed with --merge\n", Cmd);
+                       "%s: --replace or --output only allowed with --merge\n", Cmd);
                exit(2);
        }
        if (mode == 'x' && !which) {
@@ -847,6 +867,7 @@ int main(int argc, char *argv[])
                        exit_status = do_merge(
                                argc-optind, argv+optind,
                                obj, ignore_blanks, reverse, replace,
+                               outfile,
                                ignore, show_wiggles, quiet);
                break;
        }
index 1795c5a56ac5cdf07eab63e4dec102159e497e01..02fb568b0de57d350bcc4f86def33fe968bfe4a4 100644 (file)
--- a/wiggle.h
+++ b/wiggle.h
@@ -131,7 +131,7 @@ struct merge {
  * as a directory-tree.
  */
 struct plist {
-       char *file;
+       char *file, *outfile;
        unsigned int start, end;
        int parent;
        int next, prev, last;
@@ -190,7 +190,8 @@ extern void *xmalloc(int len);
 extern int do_trace;
 
 extern int vpatch(int argc, char *argv[], int patch, int strip,
-                 int reverse, int replace, int selftest,
+                 int reverse, int replace, char *outfile,
+                 int selftest,
                  int ignore_blanks);
 
 extern char *Cmd;