19Sjkh/* merge - three-way file merge */
29Sjkh
311891Speter/* Copyright 1991, 1992, 1993, 1994, 1995 Paul Eggert
49Sjkh   Distributed under license by the Free Software Foundation, Inc.
59Sjkh
69SjkhThis file is part of RCS.
79Sjkh
89SjkhRCS is free software; you can redistribute it and/or modify
99Sjkhit under the terms of the GNU General Public License as published by
109Sjkhthe Free Software Foundation; either version 2, or (at your option)
119Sjkhany later version.
129Sjkh
139SjkhRCS is distributed in the hope that it will be useful,
149Sjkhbut WITHOUT ANY WARRANTY; without even the implied warranty of
159SjkhMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
169SjkhGNU General Public License for more details.
179Sjkh
189SjkhYou should have received a copy of the GNU General Public License
1911891Speteralong with RCS; see the file COPYING.
2011891SpeterIf not, write to the Free Software Foundation,
2111891Speter59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
229Sjkh
239SjkhReport problems and direct all questions to:
249Sjkh
259Sjkh    rcs-bugs@cs.purdue.edu
269Sjkh
279Sjkh*/
289Sjkh
299Sjkh#include "rcsbase.h"
309Sjkh
3111891Speterstatic void badoption P((char const*));
329Sjkh
339Sjkhstatic char const usage[] =
3411891Speter "\nmerge: usage: merge [-AeEpqxX3] [-L lab [-L lab [-L lab]]] file1 file2 file3";
359Sjkh
3611891Speter	static void
379Sjkhbadoption(a)
389Sjkh	char const *a;
399Sjkh{
4011891Speter	error("unknown option: %s%s", a, usage);
419Sjkh}
429Sjkh
439Sjkh
4450472SpetermainProg(mergeId, "merge", "$FreeBSD$")
459Sjkh{
469Sjkh	register char const *a;
4711891Speter	char const *arg[3], *label[3], *edarg = 0;
489Sjkh	int labels, tostdout;
499Sjkh
509Sjkh	labels = 0;
519Sjkh	tostdout = false;
529Sjkh
5311891Speter	for (;  (a = *++argv)  &&  *a++ == '-';  --argc) {
549Sjkh		switch (*a++) {
5511891Speter			case 'A': case 'E': case 'e':
5611891Speter				if (edarg  &&  edarg[1] != (*argv)[1])
5711891Speter					error("%s and %s are incompatible",
5811891Speter						edarg, *argv
5911891Speter					);
6011891Speter				edarg = *argv;
6111891Speter				break;
6211891Speter
639Sjkh			case 'p': tostdout = true; break;
649Sjkh			case 'q': quietflag = true; break;
6511891Speter
669Sjkh			case 'L':
6711891Speter				if (3 <= labels)
689Sjkh					faterror("too many -L options");
699Sjkh				if (!(label[labels++] = *++argv))
709Sjkh					faterror("-L needs following argument");
719Sjkh				--argc;
729Sjkh				break;
7311891Speter
7411891Speter			case 'V':
7511891Speter				printf("RCS version %s\n", RCS_version_string);
7611891Speter				exitmain(0);
7711891Speter
789Sjkh			default:
7911891Speter				badoption(a - 2);
8011891Speter				continue;
819Sjkh		}
829Sjkh		if (*a)
8311891Speter			badoption(a - 2);
849Sjkh	}
859Sjkh
869Sjkh	if (argc != 4)
879Sjkh		faterror("%s arguments%s",
889Sjkh			argc<4 ? "not enough" : "too many",  usage
899Sjkh		);
909Sjkh
919Sjkh	/* This copy keeps us `const'-clean.  */
929Sjkh	arg[0] = argv[0];
939Sjkh	arg[1] = argv[1];
949Sjkh	arg[2] = argv[2];
959Sjkh
9611891Speter	for (;  labels < 3;  labels++)
9711891Speter		label[labels] = arg[labels];
989Sjkh
9911891Speter	if (nerror)
10011891Speter		exiterr();
10111891Speter	exitmain(merge(tostdout, edarg, label, arg));
1029Sjkh}
1039Sjkh
1049Sjkh
10511891Speter#if RCS_lint
1069Sjkh#	define exiterr mergeExit
1079Sjkh#endif
10811891Speter	void
1099Sjkhexiterr()
1109Sjkh{
1119Sjkh	tempunlink();
1129Sjkh	_exit(DIFF_TROUBLE);
1139Sjkh}
114