summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/rcs/Makefile10
-rw-r--r--usr.bin/rcs/diff.h3
-rw-r--r--usr.bin/rcs/diff3.c121
-rw-r--r--usr.bin/rcs/merge.c36
-rw-r--r--usr.bin/rcs/rcsprog.c3
-rw-r--r--usr.bin/rcs/rcsprog.h6
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);