diff options
Diffstat (limited to 'usr.bin/cvs/diff3.c')
-rw-r--r-- | usr.bin/cvs/diff3.c | 67 |
1 files changed, 44 insertions, 23 deletions
diff --git a/usr.bin/cvs/diff3.c b/usr.bin/cvs/diff3.c index f98c55e4584..36aa0cff974 100644 --- a/usr.bin/cvs/diff3.c +++ b/usr.bin/cvs/diff3.c @@ -1,4 +1,4 @@ -/* $OpenBSD: diff3.c,v 1.46 2008/03/08 11:53:36 joris Exp $ */ +/* $OpenBSD: diff3.c,v 1.47 2008/03/08 20:26:34 joris Exp $ */ /* * Copyright (C) Caldera International Inc. 2001-2002. @@ -72,7 +72,7 @@ static const char copyright[] = #ifndef lint static const char rcsid[] = - "$OpenBSD: diff3.c,v 1.46 2008/03/08 11:53:36 joris Exp $"; + "$OpenBSD: diff3.c,v 1.47 2008/03/08 20:26:34 joris Exp $"; #endif /* not lint */ #include <ctype.h> @@ -115,8 +115,8 @@ struct diff { static size_t szchanges; -static struct diff *d13; -static struct diff *d23; +static struct diff *d13 = NULL; +static struct diff *d23 = NULL; /* * "de" is used to gather editing scripts. These are later spewed out in @@ -125,8 +125,8 @@ static struct diff *d23; * look (!?). Array overlap indicates which sections in "de" correspond to * lines that are different in all three files. */ -static struct diff *de; -static char *overlap; +static struct diff *de = NULL; +static char *overlap = NULL; static int overlapcnt = 0; static FILE *fp[3]; static int cline[3]; /* # of the last-read line in each file (0-2) */ @@ -159,6 +159,8 @@ static void increase(void); static int diff3_internal(int, char **, const char *, const char *); int diff3_conflicts = 0; +RCSNUM *d3rev1 = NULL; +RCSNUM *d3rev2 = NULL; static int fds[5]; @@ -176,8 +178,9 @@ cvs_merge_file(struct cvs_file *cf, int verbose) overlapcnt = 0; b1 = b2 = b3 = d1 = d2 = diffb = NULL; - rcsnum_tostr(cf->file_ent->ce_rev, r1, sizeof(r1)); - rcsnum_tostr(cf->file_rcsrev, r2, sizeof(r2)); + + rcsnum_tostr(d3rev1, r1, sizeof(r1)); + rcsnum_tostr(d3rev2, r2, sizeof(r2)); b1 = cvs_buf_load_fd(cf->fd); d1 = cvs_buf_alloc(128); @@ -191,11 +194,10 @@ cvs_merge_file(struct cvs_file *cf, int verbose) fds[2] = cvs_buf_write_stmp(b1, path1, NULL); if (verbose == 1) cvs_printf("Retrieving revision %s\n", r1); - fds[3] = rcs_rev_write_stmp(cf->file_rcs, cf->file_ent->ce_rev, - path2, 0); + fds[3] = rcs_rev_write_stmp(cf->file_rcs, d3rev1, path2, 0); if (verbose == 1) cvs_printf("Retrieving revision %s\n", r2); - fds[4] = rcs_rev_write_stmp(cf->file_rcs, cf->file_rcsrev, path3, 0); + fds[4] = rcs_rev_write_stmp(cf->file_rcs, d3rev2, path3, 0); cvs_diffreg(path1, path3, fds[2], fds[4], d1); cvs_diffreg(path2, path3, fds[3], fds[4], d2); @@ -232,11 +234,13 @@ cvs_merge_file(struct cvs_file *cf, int verbose) dlen = cvs_buf_len(b1); data = cvs_buf_release(b1); - cvs_printf("Merging differences between %s and %s into `%s'\n", - r1, r2, cf->file_path); + if (verbose == 1) + cvs_printf("Merging differences between %s and %s into `%s'\n", + r1, r2, cf->file_path); dlines = cvs_splitlines(data, dlen); plines = cvs_splitlines(patch, plen); + ed_patch_lines(dlines, plines); cvs_freelines(plines); @@ -271,11 +275,7 @@ cvs_merge_file(struct cvs_file *cf, int verbose) for (i = 0; i < 3; i++) fclose(fp[i]); - (void)unlink(path1); - (void)unlink(path2); - (void)unlink(path3); - (void)unlink(dp13); - (void)unlink(dp23); + cvs_worklist_run(&temp_files, cvs_worklist_unlink); xfree(path1); xfree(path2); @@ -290,7 +290,6 @@ diff3_internal(int argc, char **argv, const char *fmark, const char *rmark) size_t m, n; int i; - /* XXX */ eflag = 3; oflag = 1; @@ -300,6 +299,21 @@ diff3_internal(int argc, char **argv, const char *fmark, const char *rmark) (void)xsnprintf(f1mark, sizeof(f1mark), "<<<<<<< %s", fmark); (void)xsnprintf(f3mark, sizeof(f3mark), ">>>>>>> %s", rmark); + szchanges = 0; + memset(last, 0, sizeof(last)); + memset(cline, 0, sizeof(cline)); + if (d13 != NULL) + xfree(d13); + if (d23 != NULL) + xfree(d23); + if (overlap != NULL) + xfree(overlap); + if (de != NULL) + xfree(de); + + overlap = NULL; + de = d13 = d23 = NULL; + increase(); /* fds[0] and fds[1] are closed in readin() */ @@ -319,7 +333,7 @@ diff3_internal(int argc, char **argv, const char *fmark, const char *rmark) int ed_patch_lines(struct cvs_lines *dlines, struct cvs_lines *plines) { - char op, *ep; + char op, *ep, *p; struct cvs_line *sort, *lp, *dlp, *ndlp, *insert_after; int start, end, i, lineno; u_char tmp; @@ -333,18 +347,21 @@ ed_patch_lines(struct cvs_lines *dlines, struct cvs_lines *plines) /* Skip blank lines */ if (lp->l_len < 2) continue; + /* NUL-terminate line buffer for strtol() safety. */ tmp = lp->l_line[lp->l_len - 1]; lp->l_line[lp->l_len - 1] = '\0'; - /* len - 1 is NUL terminator so we use len - 2 for 'op' */ + op = lp->l_line[strlen(lp->l_line) - 1]; start = (int)strtol(lp->l_line, &ep, 10); + /* Restore the last byte of the buffer */ lp->l_line[lp->l_len - 1] = tmp; + if (op == 'a') { if (start > dlines->l_nblines || start < 0 || *ep != 'a') - fatal("ed_patch_lines"); + fatal("ed_patch_lines %d", start); } else if (op == 'c') { if (start > dlines->l_nblines || start < 0 || (*ep != ',' && *ep != 'c')) @@ -358,6 +375,8 @@ ed_patch_lines(struct cvs_lines *dlines, struct cvs_lines *plines) } else { end = start; } + } else { + fatal("invalid op %c found while merging", op); } @@ -397,7 +416,9 @@ ed_patch_lines(struct cvs_lines *dlines, struct cvs_lines *plines) if (lp == NULL) fatal("ed_patch_lines"); - if (!memcmp(lp->l_line, ".", 1)) + if (lp->l_len == 2 && + lp->l_line[0] == '.' && + lp->l_line[1] == '\n') break; TAILQ_REMOVE(&(plines->l_lines), lp, l_list); |