xref: /openbsd-src/usr.bin/rcs/merge.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /*	$OpenBSD: merge.c,v 1.6 2007/04/26 21:49:33 sobrado Exp $	*/
2 /*
3  * Copyright (c) 2006 Xavier Santolaria <xsa@openbsd.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. The name of the author may not be used to endorse or promote products
13  *    derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include <err.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 
32 #include "rcsprog.h"
33 #include "diff.h"
34 
35 int
36 merge_main(int argc, char **argv)
37 {
38 	int ch, flags, labels, status;
39 	const char *label[3];
40 	BUF *bp;
41 
42 	flags = labels = 0;
43 	status = D_ERROR;
44 
45 	/*
46 	 * Using getopt(3) and not rcs_getopt() because merge(1)
47 	 * allows spaces between options and their arguments.
48 	 * Thus staying compatible with former implementation.
49 	 */
50 	while ((ch = getopt(argc, argv, "AEeL:pqV")) != -1) {
51 		switch(ch) {
52 		case 'A':
53 			/*
54 			 * kept for compatibility
55 			 */
56 			break;
57 		case 'E':
58 			flags |= MERGE_EFLAG;
59 			flags |= MERGE_OFLAG;
60 			break;
61 		case 'e':
62 			flags |= MERGE_EFLAG;
63 			break;
64 		case 'L':
65 			if (3 <= labels)
66 				errx(D_ERROR, "too many -L options");
67 			label[labels++] = optarg;
68 			break;
69 		case 'p':
70 			flags |= PIPEOUT;
71 			break;
72 		case 'q':
73 			flags |= QUIET;
74 			break;
75 		case 'V':
76 			printf("%s\n", rcs_version);
77 			exit(0);
78 		default:
79 			(usage)();
80 			exit(D_ERROR);
81 		}
82 	}
83 	argc -= optind;
84 	argv += optind;
85 
86 	if (argc != 3) {
87 		warnx("%s arguments", (argc < 3) ? "not enough" : "too many");
88 		(usage)();
89 		exit(D_ERROR);
90 	}
91 
92 	for (; labels < 3; labels++)
93 		label[labels] = argv[labels];
94 
95 	/* XXX handle labels */
96 	if ((bp = merge_diff3(argv, flags)) == NULL)
97 		errx(D_ERROR, "failed to merge");
98 
99 	if (diff3_conflicts != 0)
100 		status = D_OVERLAPS;
101 	else
102 		status = 0;
103 
104 	if (flags & PIPEOUT)
105 		rcs_buf_write_fd(bp, STDOUT_FILENO);
106 	else {
107 		/* XXX */
108 		if (rcs_buf_write(bp, argv[0], 0644) < 0)
109 			warnx("rcs_buf_write failed");
110 	}
111 	rcs_buf_free(bp);
112 
113 	return (status);
114 }
115 
116 void
117 merge_usage(void)
118 {
119 	(void)fprintf(stderr,
120 	    "usage: merge [-EepqV] [-L label] file1 file2 file3\n");
121 }
122