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