xref: /openbsd-src/usr.bin/rcs/merge.c (revision 099bc3622b4e1de69ecf60616221f4e660477a82)
1*099bc362Sguenther /*	$OpenBSD: merge.c,v 1.10 2016/08/26 09:02:54 guenther Exp $	*/
2d7823f4cSxsa /*
3d7823f4cSxsa  * Copyright (c) 2006 Xavier Santolaria <xsa@openbsd.org>
4d7823f4cSxsa  * All rights reserved.
5d7823f4cSxsa  *
6d7823f4cSxsa  * Redistribution and use in source and binary forms, with or without
7d7823f4cSxsa  * modification, are permitted provided that the following conditions
8d7823f4cSxsa  * are met:
9d7823f4cSxsa  *
10d7823f4cSxsa  * 1. Redistributions of source code must retain the above copyright
11d7823f4cSxsa  *    notice, this list of conditions and the following disclaimer.
12d7823f4cSxsa  * 2. The name of the author may not be used to endorse or promote products
13d7823f4cSxsa  *    derived from this software without specific prior written permission.
14d7823f4cSxsa  *
15d7823f4cSxsa  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16d7823f4cSxsa  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17d7823f4cSxsa  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18d7823f4cSxsa  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19d7823f4cSxsa  * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20d7823f4cSxsa  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21d7823f4cSxsa  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22d7823f4cSxsa  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23d7823f4cSxsa  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24d7823f4cSxsa  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25d7823f4cSxsa  */
26d7823f4cSxsa 
274781e2faSxsa #include <err.h>
284781e2faSxsa #include <stdio.h>
294781e2faSxsa #include <stdlib.h>
30*099bc362Sguenther #include <time.h>
314781e2faSxsa #include <unistd.h>
32d7823f4cSxsa 
33d7823f4cSxsa #include "rcsprog.h"
34d7823f4cSxsa #include "diff.h"
35d7823f4cSxsa 
36d7823f4cSxsa int
merge_main(int argc,char ** argv)37d7823f4cSxsa merge_main(int argc, char **argv)
38d7823f4cSxsa {
391bed6b5dSxsa 	int ch, flags, labels, status;
401bed6b5dSxsa 	const char *label[3];
411bed6b5dSxsa 	BUF *bp;
42d7823f4cSxsa 
43d7823f4cSxsa 	flags = labels = 0;
44d7823f4cSxsa 
45d7823f4cSxsa 	/*
46d7823f4cSxsa 	 * Using getopt(3) and not rcs_getopt() because merge(1)
47d7823f4cSxsa 	 * allows spaces between options and their arguments.
48d7823f4cSxsa 	 * Thus staying compatible with former implementation.
49d7823f4cSxsa 	 */
50d7823f4cSxsa 	while ((ch = getopt(argc, argv, "AEeL:pqV")) != -1) {
51d7823f4cSxsa 		switch(ch) {
52f91f651dSxsa 		case 'A':
53f91f651dSxsa 			/*
54f91f651dSxsa 			 * kept for compatibility
55f91f651dSxsa 			 */
56f91f651dSxsa 			break;
57f91f651dSxsa 		case 'E':
58f91f651dSxsa 			flags |= MERGE_EFLAG;
59f91f651dSxsa 			flags |= MERGE_OFLAG;
60f91f651dSxsa 			break;
61f91f651dSxsa 		case 'e':
62f91f651dSxsa 			flags |= MERGE_EFLAG;
63d7823f4cSxsa 			break;
64d7823f4cSxsa 		case 'L':
65d7823f4cSxsa 			if (3 <= labels)
66d7823f4cSxsa 				errx(D_ERROR, "too many -L options");
67d7823f4cSxsa 			label[labels++] = optarg;
68d7823f4cSxsa 			break;
69d7823f4cSxsa 		case 'p':
70d7823f4cSxsa 			flags |= PIPEOUT;
71d7823f4cSxsa 			break;
72d7823f4cSxsa 		case 'q':
73d7823f4cSxsa 			flags |= QUIET;
74d7823f4cSxsa 			break;
75d7823f4cSxsa 		case 'V':
76d7823f4cSxsa 			printf("%s\n", rcs_version);
77d7823f4cSxsa 			exit(0);
78d7823f4cSxsa 		default:
79d7823f4cSxsa 			(usage)();
80d7823f4cSxsa 		}
81d7823f4cSxsa 	}
82d7823f4cSxsa 	argc -= optind;
83d7823f4cSxsa 	argv += optind;
84d7823f4cSxsa 
85d7823f4cSxsa 	if (argc != 3) {
86d7823f4cSxsa 		warnx("%s arguments", (argc < 3) ? "not enough" : "too many");
87d7823f4cSxsa 		(usage)();
88d7823f4cSxsa 	}
89d7823f4cSxsa 
901bed6b5dSxsa 	for (; labels < 3; labels++)
911bed6b5dSxsa 		label[labels] = argv[labels];
921bed6b5dSxsa 
931bed6b5dSxsa 	/* XXX handle labels */
941bed6b5dSxsa 	if ((bp = merge_diff3(argv, flags)) == NULL)
951bed6b5dSxsa 		errx(D_ERROR, "failed to merge");
961bed6b5dSxsa 
971bed6b5dSxsa 	if (diff3_conflicts != 0)
981bed6b5dSxsa 		status = D_OVERLAPS;
991bed6b5dSxsa 	else
1001bed6b5dSxsa 		status = 0;
1011bed6b5dSxsa 
10251c4a85dSray 	if (flags & PIPEOUT)
1037bb3ddb0Sray 		buf_write_fd(bp, STDOUT_FILENO);
10451c4a85dSray 	else {
1051bed6b5dSxsa 		/* XXX */
1067bb3ddb0Sray 		if (buf_write(bp, argv[0], 0644) < 0)
1077bb3ddb0Sray 			warnx("buf_write failed");
1081bed6b5dSxsa 	}
1097bb3ddb0Sray 	buf_free(bp);
1101bed6b5dSxsa 
1111bed6b5dSxsa 	return (status);
112d7823f4cSxsa }
113d7823f4cSxsa 
114960e00beSotto __dead void
merge_usage(void)115d7823f4cSxsa merge_usage(void)
116d7823f4cSxsa {
117d7823f4cSxsa 	(void)fprintf(stderr,
118bf1eae80Ssobrado 	    "usage: merge [-EepqV] [-L label] file1 file2 file3\n");
119960e00beSotto 
120960e00beSotto 	exit(D_ERROR);
121d7823f4cSxsa }
122