xref: /netbsd-src/external/gpl2/rcs/dist/src/merger.c (revision fa28c6faa16e0b00edee7acdcaf4899797043def)
1*fa28c6faSchristos /*	$NetBSD: merger.c,v 1.2 2016/01/14 04:22:39 christos Exp $	*/
27bdc2678Schristos 
37bdc2678Schristos /* three-way file merge internals */
47bdc2678Schristos 
57bdc2678Schristos /* Copyright 1991, 1992, 1993, 1994, 1995 Paul Eggert
67bdc2678Schristos    Distributed under license by the Free Software Foundation, Inc.
77bdc2678Schristos 
87bdc2678Schristos This file is part of RCS.
97bdc2678Schristos 
107bdc2678Schristos RCS is free software; you can redistribute it and/or modify
117bdc2678Schristos it under the terms of the GNU General Public License as published by
127bdc2678Schristos the Free Software Foundation; either version 2, or (at your option)
137bdc2678Schristos any later version.
147bdc2678Schristos 
157bdc2678Schristos RCS is distributed in the hope that it will be useful,
167bdc2678Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
177bdc2678Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
187bdc2678Schristos GNU General Public License for more details.
197bdc2678Schristos 
207bdc2678Schristos You should have received a copy of the GNU General Public License
217bdc2678Schristos along with RCS; see the file COPYING.
227bdc2678Schristos If not, write to the Free Software Foundation,
237bdc2678Schristos 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
247bdc2678Schristos 
257bdc2678Schristos Report problems and direct all questions to:
267bdc2678Schristos 
277bdc2678Schristos     rcs-bugs@cs.purdue.edu
287bdc2678Schristos 
297bdc2678Schristos */
307bdc2678Schristos 
317bdc2678Schristos #include "rcsbase.h"
327bdc2678Schristos 
337bdc2678Schristos libId(mergerId, "Id: merger.c,v 1.7 1995/06/16 06:19:24 eggert Exp ")
347bdc2678Schristos 
357bdc2678Schristos 	static char const *normalize_arg P((char const*,char**));
367bdc2678Schristos 	static char const *
normalize_arg(s,b)377bdc2678Schristos normalize_arg(s, b)
387bdc2678Schristos 	char const *s;
397bdc2678Schristos 	char **b;
407bdc2678Schristos /*
417bdc2678Schristos  * If S looks like an option, prepend ./ to it.  Yield the result.
427bdc2678Schristos  * Set *B to the address of any storage that was allocated.
437bdc2678Schristos  */
447bdc2678Schristos {
457bdc2678Schristos 	char *t;
467bdc2678Schristos 	if (*s == '-') {
477bdc2678Schristos 		*b = t = testalloc(strlen(s) + 3);
487bdc2678Schristos 		VOID sprintf(t, ".%c%s", SLASH, s);
497bdc2678Schristos 		return t;
507bdc2678Schristos 	} else {
517bdc2678Schristos 		*b = 0;
527bdc2678Schristos 		return s;
537bdc2678Schristos 	}
547bdc2678Schristos }
557bdc2678Schristos 
567bdc2678Schristos 	int
merge(tostdout,edarg,label,argv)577bdc2678Schristos merge(tostdout, edarg, label, argv)
587bdc2678Schristos 	int tostdout;
597bdc2678Schristos 	char const *edarg;
607bdc2678Schristos 	char const *const label[3];
617bdc2678Schristos 	char const *const argv[3];
627bdc2678Schristos /*
637bdc2678Schristos  * Do `merge [-p] EDARG -L l0 -L l1 -L l2 a0 a1 a2',
647bdc2678Schristos  * where TOSTDOUT specifies whether -p is present,
657bdc2678Schristos  * EDARG gives the editing type (e.g. "-A", or null for the default),
667bdc2678Schristos  * LABEL gives l0, l1 and l2, and ARGV gives a0, a1 and a2.
677bdc2678Schristos  * Yield DIFF_SUCCESS or DIFF_FAILURE.
687bdc2678Schristos  */
697bdc2678Schristos {
707bdc2678Schristos 	register int i;
717bdc2678Schristos 	FILE *f;
727bdc2678Schristos 	RILE *rt;
737bdc2678Schristos 	char const *a[3], *t;
747bdc2678Schristos 	char *b[3];
757bdc2678Schristos 	int s;
767bdc2678Schristos #if !DIFF3_BIN
777bdc2678Schristos 	char const *d[2];
787bdc2678Schristos #endif
797bdc2678Schristos 
807bdc2678Schristos 	for (i=3; 0<=--i; )
817bdc2678Schristos 		a[i] = normalize_arg(argv[i], &b[i]);
827bdc2678Schristos 
837bdc2678Schristos 	if (!edarg)
847bdc2678Schristos 		edarg = "-E";
857bdc2678Schristos 
867bdc2678Schristos #if DIFF3_BIN
877bdc2678Schristos 	t = 0;
887bdc2678Schristos 	if (!tostdout)
897bdc2678Schristos 		t = maketemp(0);
907bdc2678Schristos 	s = run(
917bdc2678Schristos 		-1, t,
927bdc2678Schristos 		DIFF3, edarg, "-am",
937bdc2678Schristos 		"-L", label[0],
947bdc2678Schristos 		"-L", label[1],
957bdc2678Schristos 		"-L", label[2],
967bdc2678Schristos 		a[0], a[1], a[2], (char*)0
977bdc2678Schristos 	);
987bdc2678Schristos 	switch (s) {
997bdc2678Schristos 		case DIFF_SUCCESS:
1007bdc2678Schristos 			break;
1017bdc2678Schristos 		case DIFF_FAILURE:
1027bdc2678Schristos 			warn("conflicts during merge");
1037bdc2678Schristos 			break;
1047bdc2678Schristos 		default:
1057bdc2678Schristos 			exiterr();
1067bdc2678Schristos 	}
1077bdc2678Schristos 	if (t) {
1087bdc2678Schristos 		if (!(f = fopenSafer(argv[0], "w")))
1097bdc2678Schristos 			efaterror(argv[0]);
1107bdc2678Schristos 		if (!(rt = Iopen(t, "r", (struct stat*)0)))
1117bdc2678Schristos 			efaterror(t);
1127bdc2678Schristos 		fastcopy(rt, f);
1137bdc2678Schristos 		Ifclose(rt);
1147bdc2678Schristos 		Ofclose(f);
1157bdc2678Schristos 	}
1167bdc2678Schristos #else
1177bdc2678Schristos 	for (i=0; i<2; i++)
1187bdc2678Schristos 		switch (run(
1197bdc2678Schristos 			-1, d[i]=maketemp(i),
1207bdc2678Schristos 			DIFF, a[i], a[2], (char*)0
1217bdc2678Schristos 		)) {
1227bdc2678Schristos 			case DIFF_FAILURE: case DIFF_SUCCESS: break;
1237bdc2678Schristos 			default: faterror("diff failed");
1247bdc2678Schristos 		}
1257bdc2678Schristos 	t = maketemp(2);
1267bdc2678Schristos 	s = run(
1277bdc2678Schristos 		-1, t,
1287bdc2678Schristos 		DIFF3, edarg, d[0], d[1], a[0], a[1], a[2],
1297bdc2678Schristos 		label[0], label[2], (char*)0
1307bdc2678Schristos 	);
1317bdc2678Schristos 	if (s != DIFF_SUCCESS) {
1327bdc2678Schristos 		s = DIFF_FAILURE;
1337bdc2678Schristos 		warn("overlaps or other problems during merge");
1347bdc2678Schristos 	}
1357bdc2678Schristos 	if (!(f = fopenSafer(t, "a+")))
1367bdc2678Schristos 		efaterror(t);
1377bdc2678Schristos 	aputs(tostdout ? "1,$p\n" : "w\n",  f);
1387bdc2678Schristos 	Orewind(f);
1397bdc2678Schristos 	aflush(f);
1407bdc2678Schristos 	if (run(fileno(f), (char*)0, ED, "-", a[0], (char*)0))
1417bdc2678Schristos 		exiterr();
1427bdc2678Schristos 	Ofclose(f);
1437bdc2678Schristos #endif
1447bdc2678Schristos 
1457bdc2678Schristos 	tempunlink();
1467bdc2678Schristos 	for (i=3; 0<=--i; )
1477bdc2678Schristos 		if (b[i])
1487bdc2678Schristos 			tfree(b[i]);
1497bdc2678Schristos 	return s;
1507bdc2678Schristos }
151