1/* three-way file merge internals */ 2 3/* Copyright 1991, 1992, 1993, 1994, 1995 Paul Eggert 4 Distributed under license by the Free Software Foundation, Inc. 5 6This file is part of RCS. 7 8RCS is free software; you can redistribute it and/or modify 9it under the terms of the GNU General Public License as published by 10the Free Software Foundation; either version 2, or (at your option) 11any later version. 12 13RCS is distributed in the hope that it will be useful, 14but WITHOUT ANY WARRANTY; without even the implied warranty of 15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16GNU General Public License for more details. 17 18You should have received a copy of the GNU General Public License 19along with RCS; see the file COPYING. 20If not, write to the Free Software Foundation, 2159 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 23Report problems and direct all questions to: 24 25 rcs-bugs@cs.purdue.edu 26 27*/ 28 29#include "rcsbase.h" 30 31libId(mergerId, "$FreeBSD$") 32 33 static char const *normalize_arg P((char const*,char**)); 34 static char const * 35normalize_arg(s, b) 36 char const *s; 37 char **b; 38/* 39 * If S looks like an option, prepend ./ to it. Yield the result. 40 * Set *B to the address of any storage that was allocated. 41 */ 42{ 43 char *t; 44 if (*s == '-') { 45 *b = t = testalloc(strlen(s) + 3); 46 VOID sprintf(t, ".%c%s", SLASH, s); 47 return t; 48 } else { 49 *b = 0; 50 return s; 51 } 52} 53 54 int 55merge(tostdout, edarg, label, argv) 56 int tostdout; 57 char const *edarg; 58 char const *const label[3]; 59 char const *const argv[3]; 60/* 61 * Do `merge [-p] EDARG -L l0 -L l1 -L l2 a0 a1 a2', 62 * where TOSTDOUT specifies whether -p is present, 63 * EDARG gives the editing type (e.g. "-A", or null for the default), 64 * LABEL gives l0, l1 and l2, and ARGV gives a0, a1 and a2. 65 * Yield DIFF_SUCCESS or DIFF_FAILURE. 66 */ 67{ 68 register int i; 69 FILE *f; 70 RILE *rt; 71 char const *a[3], *t; 72 char *b[3]; 73 int s; 74#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