1/* $NetBSD: merger.c,v 1.1.1.2 1996/10/13 21:57:08 veego Exp $ */ 2 3/* three-way file merge internals */ 4 5/* Copyright 1991, 1992, 1993, 1994, 1995 Paul Eggert 6 Distributed under license by the Free Software Foundation, Inc. 7 8This file is part of RCS. 9 10RCS is free software; you can redistribute it and/or modify 11it under the terms of the GNU General Public License as published by 12the Free Software Foundation; either version 2, or (at your option) 13any later version. 14 15RCS is distributed in the hope that it will be useful, 16but WITHOUT ANY WARRANTY; without even the implied warranty of 17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18GNU General Public License for more details. 19 20You should have received a copy of the GNU General Public License 21along with RCS; see the file COPYING. 22If not, write to the Free Software Foundation, 2359 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 24 25Report problems and direct all questions to: 26 27 rcs-bugs@cs.purdue.edu 28 29*/ 30 31#include "rcsbase.h" 32 33libId(mergerId, "Id: merger.c,v 1.7 1995/06/16 06:19:24 eggert Exp") 34 35 static char const *normalize_arg P((char const*,char**)); 36 static char const * 37normalize_arg(s, b) 38 char const *s; 39 char **b; 40/* 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. 43 */ 44{ 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; 53 } 54} 55 56 int 57merge(tostdout, edarg, label, argv) 58 int tostdout; 59 char const *edarg; 60 char const *const label[3]; 61 char const *const argv[3]; 62/* 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. 68 */ 69{ 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 79 80 for (i=3; 0<=--i; ) 81 a[i] = normalize_arg(argv[i], &b[i]); 82 83 if (!edarg) 84 edarg = "-E"; 85 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 97 ); 98 switch (s) { 99 case DIFF_SUCCESS: 100 break; 101 case DIFF_FAILURE: 102 warn("conflicts during merge"); 103 break; 104 default: 105 exiterr(); 106 } 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); 115 } 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"); 124 } 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 130 ); 131 if (s != DIFF_SUCCESS) { 132 s = DIFF_FAILURE; 133 warn("overlaps or other problems during merge"); 134 } 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 144 145 tempunlink(); 146 for (i=3; 0<=--i; ) 147 if (b[i]) 148 tfree(b[i]); 149 return s; 150} 151