111891Speter/* three-way file merge internals */
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
3150472SpeterlibId(mergerId, "$FreeBSD$")
329Sjkh
3311891Speter	static char const *normalize_arg P((char const*,char**));
349Sjkh	static char const *
359Sjkhnormalize_arg(s, b)
369Sjkh	char const *s;
379Sjkh	char **b;
389Sjkh/*
399Sjkh * If S looks like an option, prepend ./ to it.  Yield the result.
4011891Speter * Set *B to the address of any storage that was allocated.
419Sjkh */
429Sjkh{
439Sjkh	char *t;
4411891Speter	if (*s == '-') {
4511891Speter		*b = t = testalloc(strlen(s) + 3);
4611891Speter		VOID sprintf(t, ".%c%s", SLASH, s);
4711891Speter		return t;
4811891Speter	} else {
4911891Speter		*b = 0;
5011891Speter		return s;
519Sjkh	}
529Sjkh}
539Sjkh
549Sjkh	int
5511891Spetermerge(tostdout, edarg, label, argv)
569Sjkh	int tostdout;
5711891Speter	char const *edarg;
5811891Speter	char const *const label[3];
599Sjkh	char const *const argv[3];
609Sjkh/*
6111891Speter * Do `merge [-p] EDARG -L l0 -L l1 -L l2 a0 a1 a2',
629Sjkh * where TOSTDOUT specifies whether -p is present,
6311891Speter * EDARG gives the editing type (e.g. "-A", or null for the default),
6411891Speter * LABEL gives l0, l1 and l2, and ARGV gives a0, a1 and a2.
659Sjkh * Yield DIFF_SUCCESS or DIFF_FAILURE.
669Sjkh */
679Sjkh{
689Sjkh	register int i;
699Sjkh	FILE *f;
709Sjkh	RILE *rt;
719Sjkh	char const *a[3], *t;
729Sjkh	char *b[3];
739Sjkh	int s;
749Sjkh#if !DIFF3_BIN
759Sjkh	char const *d[2];
769Sjkh#endif
779Sjkh
789Sjkh	for (i=3; 0<=--i; )
799Sjkh		a[i] = normalize_arg(argv[i], &b[i]);
8011894Speter
8111891Speter	if (!edarg)
8211891Speter		edarg = "-E";
839Sjkh
849Sjkh#if DIFF3_BIN
859Sjkh	t = 0;
869Sjkh	if (!tostdout)
879Sjkh		t = maketemp(0);
889Sjkh	s = run(
8911891Speter		-1, t,
9011891Speter		DIFF3, edarg, "-am",
9111891Speter		"-L", label[0],
9211891Speter		"-L", label[1],
9311891Speter		"-L", label[2],
949Sjkh		a[0], a[1], a[2], (char*)0
959Sjkh	);
969Sjkh	switch (s) {
979Sjkh		case DIFF_SUCCESS:
989Sjkh			break;
999Sjkh		case DIFF_FAILURE:
10011891Speter			warn("conflicts during merge");
1019Sjkh			break;
1029Sjkh		default:
1039Sjkh			exiterr();
1049Sjkh	}
1059Sjkh	if (t) {
10611891Speter		if (!(f = fopenSafer(argv[0], "w")))
1079Sjkh			efaterror(argv[0]);
10811891Speter		if (!(rt = Iopen(t, "r", (struct stat*)0)))
1099Sjkh			efaterror(t);
1109Sjkh		fastcopy(rt, f);
1119Sjkh		Ifclose(rt);
1129Sjkh		Ofclose(f);
1139Sjkh	}
1149Sjkh#else
1159Sjkh	for (i=0; i<2; i++)
1169Sjkh		switch (run(
11711891Speter			-1, d[i]=maketemp(i),
1189Sjkh			DIFF, a[i], a[2], (char*)0
1199Sjkh		)) {
1209Sjkh			case DIFF_FAILURE: case DIFF_SUCCESS: break;
12111891Speter			default: faterror("diff failed");
1229Sjkh		}
1239Sjkh	t = maketemp(2);
1249Sjkh	s = run(
12511891Speter		-1, t,
12611891Speter		DIFF3, edarg, d[0], d[1], a[0], a[1], a[2],
12711891Speter		label[0], label[2], (char*)0
1289Sjkh	);
1299Sjkh	if (s != DIFF_SUCCESS) {
1309Sjkh		s = DIFF_FAILURE;
13111891Speter		warn("overlaps or other problems during merge");
1329Sjkh	}
13311891Speter	if (!(f = fopenSafer(t, "a+")))
1349Sjkh		efaterror(t);
1359Sjkh	aputs(tostdout ? "1,$p\n" : "w\n",  f);
13611891Speter	Orewind(f);
13711891Speter	aflush(f);
13811891Speter	if (run(fileno(f), (char*)0, ED, "-", a[0], (char*)0))
13911891Speter		exiterr();
1409Sjkh	Ofclose(f);
1419Sjkh#endif
1429Sjkh
1439Sjkh	tempunlink();
1449Sjkh	for (i=3; 0<=--i; )
1459Sjkh		if (b[i])
1469Sjkh			tfree(b[i]);
1479Sjkh	return s;
1489Sjkh}
149