1: /* 2: * RCS rcsdiff operation 3: */ 4: static char rcsid[]= 5: "$Header: rcsdiff.c,v 3.7 86/05/19 02:36:16 lepreau Exp $ Purdue CS"; 6: /***************************************************************************** 7: * generate difference between RCS revisions 8: ***************************************************************************** 9: * 10: * Copyright (C) 1982 by Walter F. Tichy 11: * Purdue University 12: * Computer Science Department 13: * West Lafayette, IN 47907 14: * 15: * All rights reserved. No part of this software may be sold or distributed 16: * in any form or by any means without the prior written permission of the 17: * author. 18: * Report problems and direct all inquiries to Tichy@purdue (ARPA net). 19: */ 20: 21: 22: /* $Log: rcsdiff.c,v $ 23: * Revision 3.7 86/05/19 02:36:16 lepreau 24: * Pass on new diff options, and allow them to be clustered. 25: * 26: * Revision 3.6 83/01/15 17:52:40 wft 27: * Expanded mainprogram to handle multiple RCS files. 28: * 29: * Revision 3.5 83/01/06 09:33:45 wft 30: * Fixed passing of -c (context) option to diff. 31: * 32: * Revision 3.4 82/12/24 15:28:38 wft 33: * Added call to catchsig(). 34: * 35: * Revision 3.3 82/12/10 16:08:17 wft 36: * Corrected checking of return code from diff; improved error msgs. 37: * 38: * Revision 3.2 82/12/04 13:20:09 wft 39: * replaced getdelta() with gettree(). Changed diagnostics. 40: * 41: * Revision 3.1 82/11/28 19:25:04 wft 42: * Initial revision. 43: * 44: */ 45: #include "rcsbase.h" 46: static char rcsbaseid[] = RCSBASE; 47: 48: extern int cleanup(); /* cleanup after signals */ 49: extern char * mktempfile(); /*temporary file name generator */ 50: extern struct hshentry * genrevs(); /*generate delta numbers */ 51: extern int nerror; /*counter for errors */ 52: extern FILE * finptr; /* RCS input file */ 53: 54: char *RCSfilename; 55: char *workfilename; 56: char * temp1file, * temp2file; 57: 58: char bops[10] = "-"; 59: 60: main (argc, argv) 61: int argc; char **argv; 62: { 63: char * cmdusage; 64: char command[NCPPN+revlength+40]; 65: int revnums; /* counter for revision numbers given */ 66: char * rev1, * rev2; /* revision numbers from command line */ 67: char numericrev[revlength]; /* holds expanded revision number */ 68: char * xrev1, * xrev2; /* expanded revision numbers */ 69: struct hshentry * gendeltas[hshsize];/*stores deltas to be generated*/ 70: struct hshentry * target; 71: char * boption, * otheroption; 72: int exit_stats; 73: int filecounter; 74: char *argp; 75: register c; 76: 77: catchints(); 78: otheroption=""; 79: boption = bops + 1; 80: cmdid = "rcsdiff"; 81: cmdusage = "command format:\n rcsdiff [-biwt] [-cefhn] [-rrev1] [-rrev2] file"; 82: filecounter=revnums=0; 83: while (--argc,++argv, argc>=1 && argv[0][0] == '-') { 84: argp = &argv[0][1]; 85: while (c = *argp++) switch (c) { 86: case 'r': 87: if (*argp != '\0') { 88: if (revnums==0) { 89: rev1= argp; revnums=1; 90: } elif (revnums==1) { 91: rev2= argp; revnums=2; 92: } else { 93: faterror("too many revision numbers"); 94: } 95: } /* do nothing for empty -r */ 96: argp += strlen(argp); 97: break; 98: case 'b': 99: case 'i': 100: case 'w': 101: case 't': 102: *boption++ = c; 103: break; 104: case 'c': 105: case 'e': 106: case 'f': 107: case 'h': 108: case 'n': 109: if (*otheroption=='\0') { 110: otheroption= argp-2; 111: } else { 112: faterror("Options c,e,f,h,n are mutually exclusive"); 113: } 114: break; 115: default: 116: faterror("unknown option: %s\n%s", *argv,cmdusage); 117: }; 118: } /* end of option processing */ 119: if (boption != bops + 1) { 120: *boption = ' '; 121: boption = bops; 122: } 123: if (argc<1) faterror("No input file\n%s",cmdusage); 124: 125: /* now handle all filenames */ 126: do { 127: finptr=NULL; 128: 129: if (pairfilenames(argc,argv,true,false)!=1) continue; 130: if (++filecounter>1) 131: diagnose("==================================================================="); 132: diagnose("RCS file: %s",RCSfilename); 133: if (revnums<2 && !(access(workfilename,4)==0)) { 134: error("Can't open %s",workfilename); 135: continue; 136: } 137: if (!trysema(RCSfilename,false)) continue; /* give up */ 138: 139: 140: gettree(); /* reads in the delta tree */ 141: 142: if (Head==nil) { 143: error("no revisions present"); 144: continue; 145: } 146: if (revnums==0) rev1=Head->num; /* default rev1 */ 147: 148: if (!expandsym(rev1,numericrev)) continue; 149: if (!(target=genrevs(numericrev,nil,nil,nil,gendeltas))) continue; 150: xrev1=target->num; 151: 152: if (revnums==2) { 153: if (!expandsym(rev2,numericrev)) continue; 154: if (!(target=genrevs(numericrev,nil,nil,nil,gendeltas))) continue; 155: xrev2=target->num; 156: } 157: 158: 159: temp1file=mktempfile("/tmp/",TMPFILE1); 160: diagnose("retrieving revision %s",xrev1); 161: sprintf(command,"%s/co -q -p%s %s > %s\n", 162: TARGETDIR,xrev1,RCSfilename,temp1file); 163: if (system(command)){ 164: error("co failed"); 165: continue; 166: } 167: if (revnums<=1) { 168: temp2file=workfilename; 169: diagnose("diff %s%s -r%s %s",boption,otheroption,xrev1,workfilename); 170: } else { 171: temp2file=mktempfile("/tmp/",TMPFILE2); 172: diagnose("retrieving revision %s",xrev2); 173: sprintf(command,"%s/co -q -p%s %s > %s\n", 174: TARGETDIR,xrev2,RCSfilename,temp2file); 175: if (system(command)){ 176: error("co failed"); 177: continue; 178: } 179: diagnose("diff %s%s -r%s -r%s",boption,otheroption,xrev1,xrev2); 180: } 181: sprintf(command,"%s %s %s %s %s\n",DIFF,boption, 182: otheroption, temp1file, temp2file); 183: exit_stats = system (command); 184: if (exit_stats != 0 && exit_stats != (1 << BYTESIZ)) { 185: error ("diff failed"); 186: continue; 187: } 188: } while (cleanup(), 189: ++argv, --argc >=1); 190: 191: 192: exit(nerror!=0); 193: 194: }