xref: /dflybsd-src/gnu/usr.bin/rcs/lib/merger.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
1*86d7f5d3SJohn Marino /* three-way file merge internals */
2*86d7f5d3SJohn Marino 
3*86d7f5d3SJohn Marino /* Copyright 1991, 1992, 1993, 1994, 1995 Paul Eggert
4*86d7f5d3SJohn Marino    Distributed under license by the Free Software Foundation, Inc.
5*86d7f5d3SJohn Marino 
6*86d7f5d3SJohn Marino This file is part of RCS.
7*86d7f5d3SJohn Marino 
8*86d7f5d3SJohn Marino RCS is free software; you can redistribute it and/or modify
9*86d7f5d3SJohn Marino it under the terms of the GNU General Public License as published by
10*86d7f5d3SJohn Marino the Free Software Foundation; either version 2, or (at your option)
11*86d7f5d3SJohn Marino any later version.
12*86d7f5d3SJohn Marino 
13*86d7f5d3SJohn Marino RCS is distributed in the hope that it will be useful,
14*86d7f5d3SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
15*86d7f5d3SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*86d7f5d3SJohn Marino GNU General Public License for more details.
17*86d7f5d3SJohn Marino 
18*86d7f5d3SJohn Marino You should have received a copy of the GNU General Public License
19*86d7f5d3SJohn Marino along with RCS; see the file COPYING.
20*86d7f5d3SJohn Marino If not, write to the Free Software Foundation,
21*86d7f5d3SJohn Marino 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22*86d7f5d3SJohn Marino 
23*86d7f5d3SJohn Marino Report problems and direct all questions to:
24*86d7f5d3SJohn Marino 
25*86d7f5d3SJohn Marino     rcs-bugs@cs.purdue.edu
26*86d7f5d3SJohn Marino 
27*86d7f5d3SJohn Marino */
28*86d7f5d3SJohn Marino /*
29*86d7f5d3SJohn Marino  * $FreeBSD: src/gnu/usr.bin/rcs/lib/merger.c,v 1.5 1999/08/27 23:36:44 peter Exp $
30*86d7f5d3SJohn Marino  * $DragonFly: src/gnu/usr.bin/rcs/lib/merger.c,v 1.2 2003/06/17 04:25:47 dillon Exp $
31*86d7f5d3SJohn Marino  */
32*86d7f5d3SJohn Marino 
33*86d7f5d3SJohn Marino #include "rcsbase.h"
34*86d7f5d3SJohn Marino 
35*86d7f5d3SJohn Marino libId(mergerId, "$DragonFly: src/gnu/usr.bin/rcs/lib/merger.c,v 1.2 2003/06/17 04:25:47 dillon Exp $")
36*86d7f5d3SJohn Marino 
37*86d7f5d3SJohn Marino 	static char const *normalize_arg P((char const*,char**));
38*86d7f5d3SJohn Marino 	static char const *
normalize_arg(s,b)39*86d7f5d3SJohn Marino normalize_arg(s, b)
40*86d7f5d3SJohn Marino 	char const *s;
41*86d7f5d3SJohn Marino 	char **b;
42*86d7f5d3SJohn Marino /*
43*86d7f5d3SJohn Marino  * If S looks like an option, prepend ./ to it.  Yield the result.
44*86d7f5d3SJohn Marino  * Set *B to the address of any storage that was allocated.
45*86d7f5d3SJohn Marino  */
46*86d7f5d3SJohn Marino {
47*86d7f5d3SJohn Marino 	char *t;
48*86d7f5d3SJohn Marino 	if (*s == '-') {
49*86d7f5d3SJohn Marino 		*b = t = testalloc(strlen(s) + 3);
50*86d7f5d3SJohn Marino 		VOID sprintf(t, ".%c%s", SLASH, s);
51*86d7f5d3SJohn Marino 		return t;
52*86d7f5d3SJohn Marino 	} else {
53*86d7f5d3SJohn Marino 		*b = 0;
54*86d7f5d3SJohn Marino 		return s;
55*86d7f5d3SJohn Marino 	}
56*86d7f5d3SJohn Marino }
57*86d7f5d3SJohn Marino 
58*86d7f5d3SJohn Marino 	int
merge(tostdout,edarg,label,argv)59*86d7f5d3SJohn Marino merge(tostdout, edarg, label, argv)
60*86d7f5d3SJohn Marino 	int tostdout;
61*86d7f5d3SJohn Marino 	char const *edarg;
62*86d7f5d3SJohn Marino 	char const *const label[3];
63*86d7f5d3SJohn Marino 	char const *const argv[3];
64*86d7f5d3SJohn Marino /*
65*86d7f5d3SJohn Marino  * Do `merge [-p] EDARG -L l0 -L l1 -L l2 a0 a1 a2',
66*86d7f5d3SJohn Marino  * where TOSTDOUT specifies whether -p is present,
67*86d7f5d3SJohn Marino  * EDARG gives the editing type (e.g. "-A", or null for the default),
68*86d7f5d3SJohn Marino  * LABEL gives l0, l1 and l2, and ARGV gives a0, a1 and a2.
69*86d7f5d3SJohn Marino  * Yield DIFF_SUCCESS or DIFF_FAILURE.
70*86d7f5d3SJohn Marino  */
71*86d7f5d3SJohn Marino {
72*86d7f5d3SJohn Marino 	register int i;
73*86d7f5d3SJohn Marino 	FILE *f;
74*86d7f5d3SJohn Marino 	RILE *rt;
75*86d7f5d3SJohn Marino 	char const *a[3], *t;
76*86d7f5d3SJohn Marino 	char *b[3];
77*86d7f5d3SJohn Marino 	int s;
78*86d7f5d3SJohn Marino #if !DIFF3_BIN
79*86d7f5d3SJohn Marino 	char const *d[2];
80*86d7f5d3SJohn Marino #endif
81*86d7f5d3SJohn Marino 
82*86d7f5d3SJohn Marino 	for (i=3; 0<=--i; )
83*86d7f5d3SJohn Marino 		a[i] = normalize_arg(argv[i], &b[i]);
84*86d7f5d3SJohn Marino 
85*86d7f5d3SJohn Marino 	if (!edarg)
86*86d7f5d3SJohn Marino 		edarg = "-E";
87*86d7f5d3SJohn Marino 
88*86d7f5d3SJohn Marino #if DIFF3_BIN
89*86d7f5d3SJohn Marino 	t = 0;
90*86d7f5d3SJohn Marino 	if (!tostdout)
91*86d7f5d3SJohn Marino 		t = maketemp(0);
92*86d7f5d3SJohn Marino 	s = run(
93*86d7f5d3SJohn Marino 		-1, t,
94*86d7f5d3SJohn Marino 		DIFF3, edarg, "-am",
95*86d7f5d3SJohn Marino 		"-L", label[0],
96*86d7f5d3SJohn Marino 		"-L", label[1],
97*86d7f5d3SJohn Marino 		"-L", label[2],
98*86d7f5d3SJohn Marino 		a[0], a[1], a[2], (char*)0
99*86d7f5d3SJohn Marino 	);
100*86d7f5d3SJohn Marino 	switch (s) {
101*86d7f5d3SJohn Marino 		case DIFF_SUCCESS:
102*86d7f5d3SJohn Marino 			break;
103*86d7f5d3SJohn Marino 		case DIFF_FAILURE:
104*86d7f5d3SJohn Marino 			warn("conflicts during merge");
105*86d7f5d3SJohn Marino 			break;
106*86d7f5d3SJohn Marino 		default:
107*86d7f5d3SJohn Marino 			exiterr();
108*86d7f5d3SJohn Marino 	}
109*86d7f5d3SJohn Marino 	if (t) {
110*86d7f5d3SJohn Marino 		if (!(f = fopenSafer(argv[0], "w")))
111*86d7f5d3SJohn Marino 			efaterror(argv[0]);
112*86d7f5d3SJohn Marino 		if (!(rt = Iopen(t, "r", (struct stat*)0)))
113*86d7f5d3SJohn Marino 			efaterror(t);
114*86d7f5d3SJohn Marino 		fastcopy(rt, f);
115*86d7f5d3SJohn Marino 		Ifclose(rt);
116*86d7f5d3SJohn Marino 		Ofclose(f);
117*86d7f5d3SJohn Marino 	}
118*86d7f5d3SJohn Marino #else
119*86d7f5d3SJohn Marino 	for (i=0; i<2; i++)
120*86d7f5d3SJohn Marino 		switch (run(
121*86d7f5d3SJohn Marino 			-1, d[i]=maketemp(i),
122*86d7f5d3SJohn Marino 			DIFF, a[i], a[2], (char*)0
123*86d7f5d3SJohn Marino 		)) {
124*86d7f5d3SJohn Marino 			case DIFF_FAILURE: case DIFF_SUCCESS: break;
125*86d7f5d3SJohn Marino 			default: faterror("diff failed");
126*86d7f5d3SJohn Marino 		}
127*86d7f5d3SJohn Marino 	t = maketemp(2);
128*86d7f5d3SJohn Marino 	s = run(
129*86d7f5d3SJohn Marino 		-1, t,
130*86d7f5d3SJohn Marino 		DIFF3, edarg, d[0], d[1], a[0], a[1], a[2],
131*86d7f5d3SJohn Marino 		label[0], label[2], (char*)0
132*86d7f5d3SJohn Marino 	);
133*86d7f5d3SJohn Marino 	if (s != DIFF_SUCCESS) {
134*86d7f5d3SJohn Marino 		s = DIFF_FAILURE;
135*86d7f5d3SJohn Marino 		warn("overlaps or other problems during merge");
136*86d7f5d3SJohn Marino 	}
137*86d7f5d3SJohn Marino 	if (!(f = fopenSafer(t, "a+")))
138*86d7f5d3SJohn Marino 		efaterror(t);
139*86d7f5d3SJohn Marino 	aputs(tostdout ? "1,$p\n" : "w\n",  f);
140*86d7f5d3SJohn Marino 	Orewind(f);
141*86d7f5d3SJohn Marino 	aflush(f);
142*86d7f5d3SJohn Marino 	if (run(fileno(f), (char*)0, ED, "-", a[0], (char*)0))
143*86d7f5d3SJohn Marino 		exiterr();
144*86d7f5d3SJohn Marino 	Ofclose(f);
145*86d7f5d3SJohn Marino #endif
146*86d7f5d3SJohn Marino 
147*86d7f5d3SJohn Marino 	tempunlink();
148*86d7f5d3SJohn Marino 	for (i=3; 0<=--i; )
149*86d7f5d3SJohn Marino 		if (b[i])
150*86d7f5d3SJohn Marino 			tfree(b[i]);
151*86d7f5d3SJohn Marino 	return s;
152*86d7f5d3SJohn Marino }
153