111891Speter/* three-way file merge internals */ 29Sjkh 311891Speter/* Copyright 1991, 1992, 1993, 1994, 1995 Paul Eggert 49Sjkh Distributed under license by the Free Software Foundation, Inc. 59Sjkh 69SjkhThis file is part of RCS. 79Sjkh 89SjkhRCS is free software; you can redistribute it and/or modify 99Sjkhit under the terms of the GNU General Public License as published by 109Sjkhthe Free Software Foundation; either version 2, or (at your option) 119Sjkhany later version. 129Sjkh 139SjkhRCS is distributed in the hope that it will be useful, 149Sjkhbut WITHOUT ANY WARRANTY; without even the implied warranty of 159SjkhMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 169SjkhGNU General Public License for more details. 179Sjkh 189SjkhYou should have received a copy of the GNU General Public License 1911891Speteralong with RCS; see the file COPYING. 2011891SpeterIf not, write to the Free Software Foundation, 2111891Speter59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 229Sjkh 239SjkhReport problems and direct all questions to: 249Sjkh 259Sjkh rcs-bugs@cs.purdue.edu 269Sjkh 279Sjkh*/ 289Sjkh 299Sjkh#include "rcsbase.h" 309Sjkh 3150472SpeterlibId(mergerId, "$FreeBSD$") 329Sjkh 3311891Speter static char const *normalize_arg P((char const*,char**)); 349Sjkh static char const * 359Sjkhnormalize_arg(s, b) 369Sjkh char const *s; 379Sjkh char **b; 389Sjkh/* 399Sjkh * If S looks like an option, prepend ./ to it. Yield the result. 4011891Speter * Set *B to the address of any storage that was allocated. 419Sjkh */ 429Sjkh{ 439Sjkh char *t; 4411891Speter if (*s == '-') { 4511891Speter *b = t = testalloc(strlen(s) + 3); 4611891Speter VOID sprintf(t, ".%c%s", SLASH, s); 4711891Speter return t; 4811891Speter } else { 4911891Speter *b = 0; 5011891Speter return s; 519Sjkh } 529Sjkh} 539Sjkh 549Sjkh int 5511891Spetermerge(tostdout, edarg, label, argv) 569Sjkh int tostdout; 5711891Speter char const *edarg; 5811891Speter char const *const label[3]; 599Sjkh char const *const argv[3]; 609Sjkh/* 6111891Speter * Do `merge [-p] EDARG -L l0 -L l1 -L l2 a0 a1 a2', 629Sjkh * where TOSTDOUT specifies whether -p is present, 6311891Speter * EDARG gives the editing type (e.g. "-A", or null for the default), 6411891Speter * LABEL gives l0, l1 and l2, and ARGV gives a0, a1 and a2. 659Sjkh * Yield DIFF_SUCCESS or DIFF_FAILURE. 669Sjkh */ 679Sjkh{ 689Sjkh register int i; 699Sjkh FILE *f; 709Sjkh RILE *rt; 719Sjkh char const *a[3], *t; 729Sjkh char *b[3]; 739Sjkh int s; 749Sjkh#if !DIFF3_BIN 759Sjkh char const *d[2]; 769Sjkh#endif 779Sjkh 789Sjkh for (i=3; 0<=--i; ) 799Sjkh a[i] = normalize_arg(argv[i], &b[i]); 8011894Speter 8111891Speter if (!edarg) 8211891Speter edarg = "-E"; 839Sjkh 849Sjkh#if DIFF3_BIN 859Sjkh t = 0; 869Sjkh if (!tostdout) 879Sjkh t = maketemp(0); 889Sjkh s = run( 8911891Speter -1, t, 9011891Speter DIFF3, edarg, "-am", 9111891Speter "-L", label[0], 9211891Speter "-L", label[1], 9311891Speter "-L", label[2], 949Sjkh a[0], a[1], a[2], (char*)0 959Sjkh ); 969Sjkh switch (s) { 979Sjkh case DIFF_SUCCESS: 989Sjkh break; 999Sjkh case DIFF_FAILURE: 10011891Speter warn("conflicts during merge"); 1019Sjkh break; 1029Sjkh default: 1039Sjkh exiterr(); 1049Sjkh } 1059Sjkh if (t) { 10611891Speter if (!(f = fopenSafer(argv[0], "w"))) 1079Sjkh efaterror(argv[0]); 10811891Speter if (!(rt = Iopen(t, "r", (struct stat*)0))) 1099Sjkh efaterror(t); 1109Sjkh fastcopy(rt, f); 1119Sjkh Ifclose(rt); 1129Sjkh Ofclose(f); 1139Sjkh } 1149Sjkh#else 1159Sjkh for (i=0; i<2; i++) 1169Sjkh switch (run( 11711891Speter -1, d[i]=maketemp(i), 1189Sjkh DIFF, a[i], a[2], (char*)0 1199Sjkh )) { 1209Sjkh case DIFF_FAILURE: case DIFF_SUCCESS: break; 12111891Speter default: faterror("diff failed"); 1229Sjkh } 1239Sjkh t = maketemp(2); 1249Sjkh s = run( 12511891Speter -1, t, 12611891Speter DIFF3, edarg, d[0], d[1], a[0], a[1], a[2], 12711891Speter label[0], label[2], (char*)0 1289Sjkh ); 1299Sjkh if (s != DIFF_SUCCESS) { 1309Sjkh s = DIFF_FAILURE; 13111891Speter warn("overlaps or other problems during merge"); 1329Sjkh } 13311891Speter if (!(f = fopenSafer(t, "a+"))) 1349Sjkh efaterror(t); 1359Sjkh aputs(tostdout ? "1,$p\n" : "w\n", f); 13611891Speter Orewind(f); 13711891Speter aflush(f); 13811891Speter if (run(fileno(f), (char*)0, ED, "-", a[0], (char*)0)) 13911891Speter exiterr(); 1409Sjkh Ofclose(f); 1419Sjkh#endif 1429Sjkh 1439Sjkh tempunlink(); 1449Sjkh for (i=3; 0<=--i; ) 1459Sjkh if (b[i]) 1469Sjkh tfree(b[i]); 1479Sjkh return s; 1489Sjkh} 149