merger.c revision 9
1/* merger - three-way file merge internals */ 2 3/* Copyright 1991 by 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. If not, write to 20the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 21 22Report problems and direct all questions to: 23 24 rcs-bugs@cs.purdue.edu 25 26*/ 27 28#include "rcsbase.h" 29 30libId(mergerId, "$Id: merger.c,v 1.3 1991/08/20 23:05:00 eggert Exp $") 31 32 static char const * 33normalize_arg(s, b) 34 char const *s; 35 char **b; 36/* 37 * If S looks like an option, prepend ./ to it. Yield the result. 38 * Set *B to the address of any storage that was allocated.. 39 */ 40{ 41 char *t; 42 switch (*s) { 43 case '-': case '+': 44 *b = t = testalloc(strlen(s) + 3); 45 VOID sprintf(t, ".%c%s", SLASH, s); 46 return t; 47 default: 48 *b = 0; 49 return s; 50 } 51} 52 53 int 54merge(tostdout, label, argv) 55 int tostdout; 56 char const *const label[2]; 57 char const *const argv[3]; 58/* 59 * Do `merge [-p] -L l0 -L l1 a0 a1 a2', 60 * where TOSTDOUT specifies whether -p is present, 61 * LABEL gives l0 and l1, and ARGV gives a0, a1, and a2. 62 * Yield DIFF_SUCCESS or DIFF_FAILURE. 63 */ 64{ 65 register int i; 66 FILE *f; 67 RILE *rt; 68 char const *a[3], *t; 69 char *b[3]; 70 int s; 71#if !DIFF3_BIN 72 char const *d[2]; 73#endif 74 75 for (i=3; 0<=--i; ) 76 a[i] = normalize_arg(argv[i], &b[i]); 77 78#if DIFF3_BIN 79 t = 0; 80 if (!tostdout) 81 t = maketemp(0); 82 s = run( 83 (char*)0, t, 84 DIFF3, "-am", "-L", label[0], "-L", label[1], 85 a[0], a[1], a[2], (char*)0 86 ); 87 switch (s) { 88 case DIFF_SUCCESS: 89 break; 90 case DIFF_FAILURE: 91 if (!quietflag) 92 warn("overlaps during merge"); 93 break; 94 default: 95 exiterr(); 96 } 97 if (t) { 98 if (!(f = fopen(argv[0], FOPEN_W))) 99 efaterror(argv[0]); 100 if (!(rt = Iopen(t, FOPEN_R, (struct stat*)0))) 101 efaterror(t); 102 fastcopy(rt, f); 103 Ifclose(rt); 104 Ofclose(f); 105 } 106#else 107 for (i=0; i<2; i++) 108 switch (run( 109 (char*)0, d[i]=maketemp(i), 110 DIFF, a[i], a[2], (char*)0 111 )) { 112 case DIFF_FAILURE: case DIFF_SUCCESS: break; 113 default: exiterr(); 114 } 115 t = maketemp(2); 116 s = run( 117 (char*)0, t, 118 DIFF3, "-E", d[0], d[1], a[0], a[1], a[2], 119 label[0], label[1], (char*)0 120 ); 121 if (s != DIFF_SUCCESS) { 122 s = DIFF_FAILURE; 123 if (!quietflag) 124 warn("overlaps or other problems during merge"); 125 } 126 if (!(f = fopen(t, "a"))) 127 efaterror(t); 128 aputs(tostdout ? "1,$p\n" : "w\n", f); 129 Ofclose(f); 130 if (run(t, (char*)0, ED, "-", a[0], (char*)0)) 131 exiterr(); 132#endif 133 134 tempunlink(); 135 for (i=3; 0<=--i; ) 136 if (b[i]) 137 tfree(b[i]); 138 return s; 139} 140