merger.c revision 22996
1128707Sru/* three-way file merge internals */ 2128707Sru 3128707Sru/* Copyright 1991, 1992, 1993, 1994, 1995 Paul Eggert 4128707Sru Distributed under license by the Free Software Foundation, Inc. 5128707Sru 6128707SruThis file is part of RCS. 7128707Sru 8128707SruRCS is free software; you can redistribute it and/or modify 9128707Sruit under the terms of the GNU General Public License as published by 10128707Sruthe Free Software Foundation; either version 2, or (at your option) 11128707Sruany later version. 12128707Sru 13128707SruRCS is distributed in the hope that it will be useful, 14128707Srubut WITHOUT ANY WARRANTY; without even the implied warranty of 15128707SruMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16128707SruGNU General Public License for more details. 17125932Sru 18129240SruYou should have received a copy of the GNU General Public License 19129240Srualong with RCS; see the file COPYING. 20125932SruIf not, write to the Free Software Foundation, 21125932Sru59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22125932Sru 23125932SruReport problems and direct all questions to: 24125932Sru 25125932Sru rcs-bugs@cs.purdue.edu 26125932Sru 27241301Savg*/ 28125932Sru 29220337Srdivacky#include "rcsbase.h" 30220337Srdivacky 31129240SrulibId(mergerId, "$Id$") 32129240Sru 33129240Sru static char const *normalize_arg P((char const*,char**)); 34220337Srdivacky static char const * 35129240Srunormalize_arg(s, b) 36220337Srdivacky char const *s; 37129240Sru char **b; 38129240Sru/* 39129240Sru * If S looks like an option, prepend ./ to it. Yield the result. 40129240Sru * Set *B to the address of any storage that was allocated. 41129240Sru */ 42129240Sru{ 43242804Sdim char *t; 44125932Sru if (*s == '-') { 45241301Savg *b = t = testalloc(strlen(s) + 3); 46125932Sru VOID sprintf(t, ".%c%s", SLASH, s); 47242804Sdim return t; 48241301Savg } else { 49241301Savg *b = 0; 50241301Savg return s; 51241301Savg } 52241301Savg} 53241301Savg 54125932Sru int 55128707Srumerge(tostdout, edarg, label, argv) 56125932Sru int tostdout; 57220337Srdivacky char const *edarg; 58220337Srdivacky char const *const label[3]; 59129240Sru char const *const argv[3]; 60129240Sru/* 61129240Sru * Do `merge [-p] EDARG -L l0 -L l1 -L l2 a0 a1 a2', 62129240Sru * where TOSTDOUT specifies whether -p is present, 63129240Sru * EDARG gives the editing type (e.g. "-A", or null for the default), 64129240Sru * LABEL gives l0, l1 and l2, and ARGV gives a0, a1 and a2. 65220337Srdivacky * Yield DIFF_SUCCESS or DIFF_FAILURE. 66129240Sru */ 67129240Sru{ 68220337Srdivacky register int i; 69125932Sru FILE *f; 70128707Sru RILE *rt; 71125932Sru char const *a[3], *t; 72129240Sru char *b[3]; 73129240Sru int s; 74129240Sru#if !DIFF3_BIN 75129240Sru char const *d[2]; 76129240Sru#endif 77125932Sru 78128707Sru for (i=3; 0<=--i; ) 79125932Sru a[i] = normalize_arg(argv[i], &b[i]); 80129240Sru 81129240Sru if (!edarg) 82129240Sru edarg = "-E"; 83129240Sru 84129240Sru#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