diff options
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/rcs/Makefile | 10 | ||||
-rw-r--r-- | usr.bin/rcs/diff.h | 3 | ||||
-rw-r--r-- | usr.bin/rcs/diff3.c | 121 | ||||
-rw-r--r-- | usr.bin/rcs/merge.c | 36 | ||||
-rw-r--r-- | usr.bin/rcs/rcsprog.c | 3 | ||||
-rw-r--r-- | usr.bin/rcs/rcsprog.h | 6 |
6 files changed, 165 insertions, 14 deletions
diff --git a/usr.bin/rcs/Makefile b/usr.bin/rcs/Makefile index 76df15f7071..d1b7e26f686 100644 --- a/usr.bin/rcs/Makefile +++ b/usr.bin/rcs/Makefile @@ -1,18 +1,18 @@ -# $OpenBSD: Makefile,v 1.34 2006/04/27 07:59:33 xsa Exp $ +# $OpenBSD: Makefile,v 1.35 2006/05/15 06:58:03 xsa Exp $ .PATH: ${.CURDIR}/.. PROG= rcs -MAN= ci.1 co.1 ident.1 rcs.1 rcsclean.1 rcsdiff.1 rcsmerge.1 rlog.1 +MAN= ci.1 co.1 ident.1 merge.1 rcs.1 rcsclean.1 rcsdiff.1 rcsmerge.1 rlog.1 -SRCS= ci.c co.c ident.c rcsclean.c rcsdiff.c rcsmerge.c rcsprog.c rlog.c \ - rcsutil.c buf.c date.y diff.c diff3.c rcs.c rcsnum.c \ +SRCS= ci.c co.c ident.c merge.c rcsclean.c rcsdiff.c rcsmerge.c rcsprog.c \ + rlog.c rcsutil.c buf.c date.y diff.c diff3.c rcs.c rcsnum.c \ rcstime.c worklist.c xmalloc.c LINKS= ${BINDIR}/rcs ${BINDIR}/ci ${BINDIR}/rcs ${BINDIR}/co \ + ${BINDIR}/rcs ${BINDIR}/ident ${BINDIR}/rcs ${BINDIR}/merge ${BINDIR}/rcs ${BINDIR}/rcsclean ${BINDIR}/rcs ${BINDIR}/rcsdiff \ ${BINDIR}/rcs ${BINDIR}/rcsmerge ${BINDIR}/rcs ${BINDIR}/rlog \ - ${BINDIR}/rcs ${BINDIR}/ident CPPFLAGS+=-I${.CURDIR} CFLAGS+=-Wall diff --git a/usr.bin/rcs/diff.h b/usr.bin/rcs/diff.h index f41171f1f41..dfc46f85c05 100644 --- a/usr.bin/rcs/diff.h +++ b/usr.bin/rcs/diff.h @@ -1,4 +1,4 @@ -/* $OpenBSD: diff.h,v 1.3 2006/05/08 18:36:04 xsa Exp $ */ +/* $OpenBSD: diff.h,v 1.4 2006/05/15 06:58:03 xsa Exp $ */ /* * Copyright (C) Caldera International Inc. 2001-2002. * All rights reserved. @@ -95,6 +95,7 @@ struct rcs_lines; BUF *rcs_diff3(RCSFILE *, char *, RCSNUM *, RCSNUM *, int); +BUF *merge_diff3(char **, int); void diff_output(const char *, ...); int rcs_diffreg(const char *, const char *, BUF *); int ed_patch_lines(struct rcs_lines *, struct rcs_lines *); diff --git a/usr.bin/rcs/diff3.c b/usr.bin/rcs/diff3.c index 42ba4ea9d79..8b9eb1ef887 100644 --- a/usr.bin/rcs/diff3.c +++ b/usr.bin/rcs/diff3.c @@ -1,4 +1,4 @@ -/* $OpenBSD: diff3.c,v 1.8 2006/05/10 01:10:23 ray Exp $ */ +/* $OpenBSD: diff3.c,v 1.9 2006/05/15 06:58:03 xsa 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.8 2006/05/10 01:10:23 ray Exp $"; + "$OpenBSD: diff3.c,v 1.9 2006/05/15 06:58:03 xsa Exp $"; #endif /* not lint */ #include "includes.h" @@ -153,6 +153,123 @@ static int diff3_internal(int, char **, const char *, const char *); int diff3_conflicts = 0; +/* + * For merge(1). + */ +BUF * +merge_diff3(char **av, int flags) +{ + int argc; + char *data, *patch; + char *argv[5], *dp13, *dp23, *path1, *path2, *path3; + BUF *b1, *b2, *b3, *d1, *d2, *diffb; + + b1 = b2 = b3 = d1 = d2 = diffb = NULL; + dp13 = dp23 = path1 = path2 = path3 = NULL; + + if ((b1 = rcs_buf_load(av[0], BUF_AUTOEXT)) == NULL) + goto out; + if ((b2 = rcs_buf_load(av[1], BUF_AUTOEXT)) == NULL) + goto out; + if ((b3 = rcs_buf_load(av[2], BUF_AUTOEXT)) == NULL) + goto out; + + d1 = rcs_buf_alloc(128, BUF_AUTOEXT); + d2 = rcs_buf_alloc(128, BUF_AUTOEXT); + diffb = rcs_buf_alloc(128, BUF_AUTOEXT); + + (void)xasprintf(&path1, "%s/diff1.XXXXXXXXXX", rcs_tmpdir); + (void)xasprintf(&path2, "%s/diff2.XXXXXXXXXX", rcs_tmpdir); + (void)xasprintf(&path3, "%s/diff3.XXXXXXXXXX", rcs_tmpdir); + + rcs_buf_write_stmp(b1, path1, 0600); + rcs_buf_write_stmp(b2, path2, 0600); + rcs_buf_write_stmp(b3, path3, 0600); + + rcs_buf_free(b2); + b2 = NULL; + + if ((rcs_diffreg(path1, path3, d1) == D_ERROR) || + (rcs_diffreg(path2, path3, d2) == D_ERROR)) { + rcs_buf_free(diffb); + diffb = NULL; + goto out; + } + + (void)xasprintf(&dp13, "%s/d13.XXXXXXXXXX", rcs_tmpdir); + rcs_buf_write_stmp(d1, dp13, 0600); + + rcs_buf_free(d1); + d1 = NULL; + + (void)xasprintf(&dp23, "%s/d23.XXXXXXXXXX", rcs_tmpdir); + rcs_buf_write_stmp(d2, dp23, 0600); + + rcs_buf_free(d2); + d2 = NULL; + + argc = 0; + diffbuf = diffb; + argv[argc++] = dp13; + argv[argc++] = dp23; + argv[argc++] = path1; + argv[argc++] = path2; + argv[argc++] = path3; + + diff3_conflicts = diff3_internal(argc, argv, av[0], av[2]); + if (diff3_conflicts < 0) { + rcs_buf_free(diffb); + diffb = NULL; + goto out; + } + + rcs_buf_putc(diffb, '\0'); + rcs_buf_putc(b1, '\0'); + + patch = rcs_buf_release(diffb); + data = rcs_buf_release(b1); + diffb = b1 = NULL; + + if ((diffb = rcs_patchfile(data, patch, ed_patch_lines)) == NULL) + goto out; + + if (!(flags & QUIET) && diff3_conflicts != 0) + warnx("warning: overlaps or other problems during merge"); + + xfree(data); + xfree(patch); +out: + if (b1 != NULL) + rcs_buf_free(b1); + if (b2 != NULL) + rcs_buf_free(b2); + if (b3 != NULL) + rcs_buf_free(b3); + if (d1 != NULL) + rcs_buf_free(d1); + if (d2 != NULL) + rcs_buf_free(d2); + + (void)unlink(path1); + (void)unlink(path2); + (void)unlink(path3); + (void)unlink(dp13); + (void)unlink(dp23); + + if (path1 != NULL) + xfree(path1); + if (path2 != NULL) + xfree(path2); + if (path3 != NULL) + xfree(path3); + if (dp13 != NULL) + xfree(dp13); + if (dp23 != NULL) + xfree(dp23); + + return (diffb); +} + BUF * rcs_diff3(RCSFILE *rf, char *workfile, RCSNUM *rev1, RCSNUM *rev2, int verbose) { diff --git a/usr.bin/rcs/merge.c b/usr.bin/rcs/merge.c index b879aacfc2b..7b449da3631 100644 --- a/usr.bin/rcs/merge.c +++ b/usr.bin/rcs/merge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: merge.c,v 1.1 2006/05/10 14:28:17 xsa Exp $ */ +/* $OpenBSD: merge.c,v 1.2 2006/05/15 06:58:03 xsa Exp $ */ /* * Copyright (c) 2006 Xavier Santolaria <xsa@openbsd.org> * All rights reserved. @@ -32,12 +32,15 @@ int merge_main(int argc, char **argv) { - int ch, flags, labels; - char *label[3]; + int ch, flags, labels, status; + char *fcont; + const char *label[3]; + BUF *bp; extern char *optarg; extern int optind; flags = labels = 0; + status = D_ERROR; /* * Using getopt(3) and not rcs_getopt() because merge(1) @@ -76,7 +79,32 @@ merge_main(int argc, char **argv) exit(D_ERROR); } - return (0); + for (; labels < 3; labels++) + label[labels] = argv[labels]; + + /* XXX handle labels */ + if ((bp = merge_diff3(argv, flags)) == NULL) + errx(D_ERROR, "failed to merge"); + + if (diff3_conflicts != 0) + status = D_OVERLAPS; + else + status = 0; + + if (flags & PIPEOUT) { + rcs_buf_putc(bp, '\0'); + fcont = rcs_buf_release(bp); + (void)printf("%s", fcont); + xfree(fcont); + } else { + /* XXX */ + if (rcs_buf_write(bp, argv[0], 0644) < 0) + warnx("rcs_buf_write failed"); + + rcs_buf_free(bp); + } + + return (status); } void diff --git a/usr.bin/rcs/rcsprog.c b/usr.bin/rcs/rcsprog.c index 40d65d1cf2c..c6f81881627 100644 --- a/usr.bin/rcs/rcsprog.c +++ b/usr.bin/rcs/rcsprog.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rcsprog.c,v 1.125 2006/05/11 09:43:19 xsa Exp $ */ +/* $OpenBSD: rcsprog.c,v 1.126 2006/05/15 06:58:03 xsa Exp $ */ /* * Copyright (c) 2005 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -52,6 +52,7 @@ struct rcs_prog { { "rcsmerge", rcsmerge_main, rcsmerge_usage }, { "rlog", rlog_main, rlog_usage }, { "ident", ident_main, ident_usage }, + { "merge", merge_main, merge_usage }, }; struct rcs_wklhead rcs_temp_files; diff --git a/usr.bin/rcs/rcsprog.h b/usr.bin/rcs/rcsprog.h index 9d00e5c1f7a..9f5bf22548b 100644 --- a/usr.bin/rcs/rcsprog.h +++ b/usr.bin/rcs/rcsprog.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rcsprog.h,v 1.57 2006/04/27 07:59:33 xsa Exp $ */ +/* $OpenBSD: rcsprog.h,v 1.58 2006/05/15 06:58:03 xsa Exp $ */ /* * Copyright (c) 2005 Joris Vink <joris@openbsd.org> * All rights reserved. @@ -92,6 +92,10 @@ void checkout_usage(void); int ident_main(int, char **); void ident_usage(void); +/* merge.c */ +int merge_main(int, char **); +void merge_usage(void); + /* rcsclean.c */ int rcsclean_main(int, char **); void rcsclean_usage(void); |