1 /* $OpenBSD: merge.c,v 1.10 2016/08/26 09:02:54 guenther 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 <time.h>
31 #include <unistd.h>
32
33 #include "rcsprog.h"
34 #include "diff.h"
35
36 int
merge_main(int argc,char ** argv)37 merge_main(int argc, char **argv)
38 {
39 int ch, flags, labels, status;
40 const char *label[3];
41 BUF *bp;
42
43 flags = labels = 0;
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 }
81 }
82 argc -= optind;
83 argv += optind;
84
85 if (argc != 3) {
86 warnx("%s arguments", (argc < 3) ? "not enough" : "too many");
87 (usage)();
88 }
89
90 for (; labels < 3; labels++)
91 label[labels] = argv[labels];
92
93 /* XXX handle labels */
94 if ((bp = merge_diff3(argv, flags)) == NULL)
95 errx(D_ERROR, "failed to merge");
96
97 if (diff3_conflicts != 0)
98 status = D_OVERLAPS;
99 else
100 status = 0;
101
102 if (flags & PIPEOUT)
103 buf_write_fd(bp, STDOUT_FILENO);
104 else {
105 /* XXX */
106 if (buf_write(bp, argv[0], 0644) < 0)
107 warnx("buf_write failed");
108 }
109 buf_free(bp);
110
111 return (status);
112 }
113
114 __dead void
merge_usage(void)115 merge_usage(void)
116 {
117 (void)fprintf(stderr,
118 "usage: merge [-EepqV] [-L label] file1 file2 file3\n");
119
120 exit(D_ERROR);
121 }
122