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
36int
37merge_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
115merge_usage(void)
116{
117	(void)fprintf(stderr,
118	    "usage: merge [-EepqV] [-L label] file1 file2 file3\n");
119
120	exit(D_ERROR);
121}
122