From a2a4bd7cc4e451fc956ac7834ac3892fe11b08ce Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 14 Nov 2012 13:50:35 +1100 Subject: [PATCH] vpatch: support saving of files. 'S' will save the current file. If you try to enter it again, it will be loaded as a 'merge'. Signed-off-by: NeilBrown --- merge2.c | 31 +++++++++++++++++++++++++++++++ vpatch.c | 42 ++++++++++++++++++++++++++++++++++++++++++ wiggle.h | 2 ++ 3 files changed, 75 insertions(+) diff --git a/merge2.c b/merge2.c index 14f2cd4..4a6ffb6 100644 --- a/merge2.c +++ b/merge2.c @@ -653,3 +653,34 @@ void print_merge(FILE *out, struct file *a, struct file *b, struct file *c, } } } + +int save_merge(struct file a, struct file b, struct file c, + struct merge *merger, char *file) +{ + char *replacename = xmalloc(strlen(file) + 20); + char *orignew = xmalloc(strlen(file) + 20); + int fd; + FILE *outfile; + int err = 0; + strcpy(replacename, file); + strcat(replacename, "XXXXXX"); + strcpy(orignew, file); + strcat(orignew, ".porig"); + + fd = mkstemp(replacename); + if (fd < 0) { + err = 1; + goto out; + } + outfile = fdopen(fd, "w"); + print_merge(outfile, &a, &b, &c, 0, merger); + fclose(outfile); + if (rename(file, orignew) != 0 || + rename(replacename, file) != 0) + err = -2; + +out: + free(replacename); + free(orignew); + return err; +} diff --git a/vpatch.c b/vpatch.c index 39b9473..dc3f879 100644 --- a/vpatch.c +++ b/vpatch.c @@ -2214,6 +2214,7 @@ static void main_window(struct plist *pl, int *np, FILE *f, int reverse) * */ char *mesg = NULL; + char mesg_buf[1024]; int last_mesg_len = 0; int pos = 0; /* position in file */ int row = 1; /* position on screen */ @@ -2357,6 +2358,47 @@ static void main_window(struct plist *pl, int *np, FILE *f, int reverse) mesg = "Showing Conflicted files"; break; + case 'S': /* Save updated file */ + if (pl[pos].end == 0) { + /* directory */ + mesg = "Cannot save a folder."; + } else if (pl[pos].is_merge) { + /* Already saved */ + mesg = "File is already saved."; + } else { + struct stream sp, sa, sb, sm; + struct file fa, fb, fm; + struct csl *csl1, *csl2; + struct ci ci; + int chunks; + sp = load_segment(f, pl[pos].start, + pl[pos].end); + if (reverse) + chunks = split_patch(sp, &sa, &sb); + else + chunks = split_patch(sp, &sb, &sa); + fb = split_stream(sb, ByWord); + fa = split_stream(sa, ByWord); + sm = load_file(pl[pos].file); + fm = split_stream(sm, ByWord); + csl1 = pdiff(fm, fb, chunks); + csl2 = diff(fb, fa); + ci = make_merger(fm, fb, fa, csl1, csl2, 0, 1, 0); + if (save_merge(fm, fb, fa, ci.merger, + pl[pos].file) == 0) { + pl[pos].is_merge = 1; + snprintf(mesg_buf, cols, + "Saved file %s.", + pl[pos].file); + } else + snprintf(mesg_buf, cols, + "Failed to save file %s.", + pl[pos].file); + mesg = mesg_buf; + refresh = 1; + } + break; + case '?': help_window(main_help, NULL); refresh = 2; diff --git a/wiggle.h b/wiggle.h index a9b7bb6..32a68bc 100644 --- a/wiggle.h +++ b/wiggle.h @@ -171,6 +171,8 @@ extern void print_merge(FILE *out, struct file *a, struct file *b, struct file *c, int words, struct merge *merger); extern void printword(FILE *f, struct elmnt e); +extern int save_merge(struct file a, struct file b, struct file c, + struct merge *merger, char *file); extern int isolate_conflicts(struct file af, struct file bf, struct file cf, struct csl *csl1, struct csl *csl2, int words, -- 2.39.5