merger.c revision 11894
176612Stshiozak/* three-way file merge internals */
276612Stshiozak
376612Stshiozak/* Copyright 1991, 1992, 1993, 1994, 1995 Paul Eggert
476612Stshiozak   Distributed under license by the Free Software Foundation, Inc.
576612Stshiozak
676612StshiozakThis file is part of RCS.
776612Stshiozak
876612StshiozakRCS is free software; you can redistribute it and/or modify
976612Stshiozakit under the terms of the GNU General Public License as published by
1076612Stshiozakthe Free Software Foundation; either version 2, or (at your option)
1176612Stshiozakany later version.
1276612Stshiozak
1376612StshiozakRCS is distributed in the hope that it will be useful,
1476612Stshiozakbut WITHOUT ANY WARRANTY; without even the implied warranty of
1576612StshiozakMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1676612StshiozakGNU General Public License for more details.
1776612Stshiozak
1876612StshiozakYou should have received a copy of the GNU General Public License
1976612Stshiozakalong with RCS; see the file COPYING.
2076612StshiozakIf not, write to the Free Software Foundation,
2176612Stshiozak59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2276612Stshiozak
2376612StshiozakReport problems and direct all questions to:
2476612Stshiozak
2576612Stshiozak    rcs-bugs@cs.purdue.edu
2676612Stshiozak
2776612Stshiozak*/
2876612Stshiozak
2976612Stshiozak#include "rcsbase.h"
3092986Sobrien
3176612StshiozaklibId(mergerId, "$Id: merger.c,v 1.7 1995/06/16 06:19:24 eggert Exp $")
3276612Stshiozak
3376612Stshiozak	static char const *normalize_arg P((char const*,char**));
3492986Sobrien	static char const *
3586170Sobriennormalize_arg(s, b)
3676612Stshiozak	char const *s;
3776612Stshiozak	char **b;
3876612Stshiozak/*
3976612Stshiozak * If S looks like an option, prepend ./ to it.  Yield the result.
4076612Stshiozak * Set *B to the address of any storage that was allocated.
4176612Stshiozak */
4276612Stshiozak{
4376612Stshiozak	char *t;
4476612Stshiozak	if (*s == '-') {
4576612Stshiozak		*b = t = testalloc(strlen(s) + 3);
4676612Stshiozak		VOID sprintf(t, ".%c%s", SLASH, s);
4776612Stshiozak		return t;
4876612Stshiozak	} else {
4976612Stshiozak		*b = 0;
5076612Stshiozak		return s;
5176612Stshiozak	}
5276612Stshiozak}
5376612Stshiozak
5476612Stshiozak	int
5576612Stshiozakmerge(tostdout, edarg, label, argv)
5676612Stshiozak	int tostdout;
5776612Stshiozak	char const *edarg;
5876612Stshiozak	char const *const label[3];
5976612Stshiozak	char const *const argv[3];
6076612Stshiozak/*
6176612Stshiozak * Do `merge [-p] EDARG -L l0 -L l1 -L l2 a0 a1 a2',
6276612Stshiozak * where TOSTDOUT specifies whether -p is present,
6376612Stshiozak * EDARG gives the editing type (e.g. "-A", or null for the default),
6476612Stshiozak * LABEL gives l0, l1 and l2, and ARGV gives a0, a1 and a2.
6576612Stshiozak * Yield DIFF_SUCCESS or DIFF_FAILURE.
6676612Stshiozak */
6776612Stshiozak{
6876612Stshiozak	register int i;
6976612Stshiozak	FILE *f;
7076612Stshiozak	RILE *rt;
7176612Stshiozak	char const *a[3], *t;
7276612Stshiozak	char *b[3];
7376612Stshiozak	int s;
7476612Stshiozak#if !DIFF3_BIN
75	char const *d[2];
76#endif
77
78	for (i=3; 0<=--i; )
79		a[i] = normalize_arg(argv[i], &b[i]);
80
81	if (!edarg)
82		edarg = "-E";
83
84#if DIFF3_BIN
85	t = 0;
86	if (!tostdout)
87		t = maketemp(0);
88	s = run(
89		-1, t,
90		DIFF3, edarg, "-am",
91		"-L", label[0],
92		"-L", label[1],
93		"-L", label[2],
94		a[0], a[1], a[2], (char*)0
95	);
96	switch (s) {
97		case DIFF_SUCCESS:
98			break;
99		case DIFF_FAILURE:
100			warn("conflicts during merge");
101			break;
102		default:
103			exiterr();
104	}
105	if (t) {
106		if (!(f = fopenSafer(argv[0], "w")))
107			efaterror(argv[0]);
108		if (!(rt = Iopen(t, "r", (struct stat*)0)))
109			efaterror(t);
110		fastcopy(rt, f);
111		Ifclose(rt);
112		Ofclose(f);
113	}
114#else
115	for (i=0; i<2; i++)
116		switch (run(
117			-1, d[i]=maketemp(i),
118			DIFF, a[i], a[2], (char*)0
119		)) {
120			case DIFF_FAILURE: case DIFF_SUCCESS: break;
121			default: faterror("diff failed");
122		}
123	t = maketemp(2);
124	s = run(
125		-1, t,
126		DIFF3, edarg, d[0], d[1], a[0], a[1], a[2],
127		label[0], label[2], (char*)0
128	);
129	if (s != DIFF_SUCCESS) {
130		s = DIFF_FAILURE;
131		warn("overlaps or other problems during merge");
132	}
133	if (!(f = fopenSafer(t, "a+")))
134		efaterror(t);
135	aputs(tostdout ? "1,$p\n" : "w\n",  f);
136	Orewind(f);
137	aflush(f);
138	if (run(fileno(f), (char*)0, ED, "-", a[0], (char*)0))
139		exiterr();
140	Ofclose(f);
141#endif
142
143	tempunlink();
144	for (i=3; 0<=--i; )
145		if (b[i])
146			tfree(b[i]);
147	return s;
148}
149