merger.c revision 11894
176612Stshiozak/* three-way file merge internals */ 276612Stshiozak 376612Stshiozak/* Copyright 1991, 1992, 1993, 1994, 1995 Paul Eggert 476612Stshiozak Distributed under license by the Free Software Foundation, Inc. 576612Stshiozak 676612StshiozakThis file is part of RCS. 776612Stshiozak 876612StshiozakRCS is free software; you can redistribute it and/or modify 976612Stshiozakit under the terms of the GNU General Public License as published by 1076612Stshiozakthe Free Software Foundation; either version 2, or (at your option) 1176612Stshiozakany later version. 1276612Stshiozak 1376612StshiozakRCS is distributed in the hope that it will be useful, 1476612Stshiozakbut WITHOUT ANY WARRANTY; without even the implied warranty of 1576612StshiozakMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1676612StshiozakGNU General Public License for more details. 1776612Stshiozak 1876612StshiozakYou should have received a copy of the GNU General Public License 1976612Stshiozakalong with RCS; see the file COPYING. 2076612StshiozakIf not, write to the Free Software Foundation, 2176612Stshiozak59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 2276612Stshiozak 2376612StshiozakReport problems and direct all questions to: 2476612Stshiozak 2576612Stshiozak rcs-bugs@cs.purdue.edu 2676612Stshiozak 2776612Stshiozak*/ 2876612Stshiozak 2976612Stshiozak#include "rcsbase.h" 3092986Sobrien 3176612StshiozaklibId(mergerId, "$Id: merger.c,v 1.7 1995/06/16 06:19:24 eggert Exp $") 3276612Stshiozak 3376612Stshiozak static char const *normalize_arg P((char const*,char**)); 3492986Sobrien static char const * 3586170Sobriennormalize_arg(s, b) 3676612Stshiozak char const *s; 3776612Stshiozak char **b; 3876612Stshiozak/* 3976612Stshiozak * If S looks like an option, prepend ./ to it. Yield the result. 4076612Stshiozak * Set *B to the address of any storage that was allocated. 4176612Stshiozak */ 4276612Stshiozak{ 4376612Stshiozak char *t; 4476612Stshiozak if (*s == '-') { 4576612Stshiozak *b = t = testalloc(strlen(s) + 3); 4676612Stshiozak VOID sprintf(t, ".%c%s", SLASH, s); 4776612Stshiozak return t; 4876612Stshiozak } else { 4976612Stshiozak *b = 0; 5076612Stshiozak return s; 5176612Stshiozak } 5276612Stshiozak} 5376612Stshiozak 5476612Stshiozak int 5576612Stshiozakmerge(tostdout, edarg, label, argv) 5676612Stshiozak int tostdout; 5776612Stshiozak char const *edarg; 5876612Stshiozak char const *const label[3]; 5976612Stshiozak char const *const argv[3]; 6076612Stshiozak/* 6176612Stshiozak * Do `merge [-p] EDARG -L l0 -L l1 -L l2 a0 a1 a2', 6276612Stshiozak * where TOSTDOUT specifies whether -p is present, 6376612Stshiozak * EDARG gives the editing type (e.g. "-A", or null for the default), 6476612Stshiozak * LABEL gives l0, l1 and l2, and ARGV gives a0, a1 and a2. 6576612Stshiozak * Yield DIFF_SUCCESS or DIFF_FAILURE. 6676612Stshiozak */ 6776612Stshiozak{ 6876612Stshiozak register int i; 6976612Stshiozak FILE *f; 7076612Stshiozak RILE *rt; 7176612Stshiozak char const *a[3], *t; 7276612Stshiozak char *b[3]; 7376612Stshiozak int s; 7476612Stshiozak#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