merger.c revision 9
19Sjkh/* merger - three-way file merge internals */ 29Sjkh 39Sjkh/* Copyright 1991 by 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 199Sjkhalong with RCS; see the file COPYING. If not, write to 209Sjkhthe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 219Sjkh 229SjkhReport problems and direct all questions to: 239Sjkh 249Sjkh rcs-bugs@cs.purdue.edu 259Sjkh 269Sjkh*/ 279Sjkh 289Sjkh#include "rcsbase.h" 299Sjkh 309SjkhlibId(mergerId, "$Id: merger.c,v 1.3 1991/08/20 23:05:00 eggert Exp $") 319Sjkh 329Sjkh static char const * 339Sjkhnormalize_arg(s, b) 349Sjkh char const *s; 359Sjkh char **b; 369Sjkh/* 379Sjkh * If S looks like an option, prepend ./ to it. Yield the result. 389Sjkh * Set *B to the address of any storage that was allocated.. 399Sjkh */ 409Sjkh{ 419Sjkh char *t; 429Sjkh switch (*s) { 439Sjkh case '-': case '+': 449Sjkh *b = t = testalloc(strlen(s) + 3); 459Sjkh VOID sprintf(t, ".%c%s", SLASH, s); 469Sjkh return t; 479Sjkh default: 489Sjkh *b = 0; 499Sjkh return s; 509Sjkh } 519Sjkh} 529Sjkh 539Sjkh int 549Sjkhmerge(tostdout, label, argv) 559Sjkh int tostdout; 569Sjkh char const *const label[2]; 579Sjkh char const *const argv[3]; 589Sjkh/* 599Sjkh * Do `merge [-p] -L l0 -L l1 a0 a1 a2', 609Sjkh * where TOSTDOUT specifies whether -p is present, 619Sjkh * LABEL gives l0 and l1, and ARGV gives a0, a1, and a2. 629Sjkh * Yield DIFF_SUCCESS or DIFF_FAILURE. 639Sjkh */ 649Sjkh{ 659Sjkh register int i; 669Sjkh FILE *f; 679Sjkh RILE *rt; 689Sjkh char const *a[3], *t; 699Sjkh char *b[3]; 709Sjkh int s; 719Sjkh#if !DIFF3_BIN 729Sjkh char const *d[2]; 739Sjkh#endif 749Sjkh 759Sjkh for (i=3; 0<=--i; ) 769Sjkh a[i] = normalize_arg(argv[i], &b[i]); 779Sjkh 789Sjkh#if DIFF3_BIN 799Sjkh t = 0; 809Sjkh if (!tostdout) 819Sjkh t = maketemp(0); 829Sjkh s = run( 839Sjkh (char*)0, t, 849Sjkh DIFF3, "-am", "-L", label[0], "-L", label[1], 859Sjkh a[0], a[1], a[2], (char*)0 869Sjkh ); 879Sjkh switch (s) { 889Sjkh case DIFF_SUCCESS: 899Sjkh break; 909Sjkh case DIFF_FAILURE: 919Sjkh if (!quietflag) 929Sjkh warn("overlaps during merge"); 939Sjkh break; 949Sjkh default: 959Sjkh exiterr(); 969Sjkh } 979Sjkh if (t) { 989Sjkh if (!(f = fopen(argv[0], FOPEN_W))) 999Sjkh efaterror(argv[0]); 1009Sjkh if (!(rt = Iopen(t, FOPEN_R, (struct stat*)0))) 1019Sjkh efaterror(t); 1029Sjkh fastcopy(rt, f); 1039Sjkh Ifclose(rt); 1049Sjkh Ofclose(f); 1059Sjkh } 1069Sjkh#else 1079Sjkh for (i=0; i<2; i++) 1089Sjkh switch (run( 1099Sjkh (char*)0, d[i]=maketemp(i), 1109Sjkh DIFF, a[i], a[2], (char*)0 1119Sjkh )) { 1129Sjkh case DIFF_FAILURE: case DIFF_SUCCESS: break; 1139Sjkh default: exiterr(); 1149Sjkh } 1159Sjkh t = maketemp(2); 1169Sjkh s = run( 1179Sjkh (char*)0, t, 1189Sjkh DIFF3, "-E", d[0], d[1], a[0], a[1], a[2], 1199Sjkh label[0], label[1], (char*)0 1209Sjkh ); 1219Sjkh if (s != DIFF_SUCCESS) { 1229Sjkh s = DIFF_FAILURE; 1239Sjkh if (!quietflag) 1249Sjkh warn("overlaps or other problems during merge"); 1259Sjkh } 1269Sjkh if (!(f = fopen(t, "a"))) 1279Sjkh efaterror(t); 1289Sjkh aputs(tostdout ? "1,$p\n" : "w\n", f); 1299Sjkh Ofclose(f); 1309Sjkh if (run(t, (char*)0, ED, "-", a[0], (char*)0)) 1319Sjkh exiterr(); 1329Sjkh#endif 1339Sjkh 1349Sjkh tempunlink(); 1359Sjkh for (i=3; 0<=--i; ) 1369Sjkh if (b[i]) 1379Sjkh tfree(b[i]); 1389Sjkh return s; 1399Sjkh} 140