|
|
1.1 ! root 1: /* ! 2: * RCS rcsdiff operation ! 3: */ ! 4: #ifndef lint ! 5: static char rcsid[]= ! 6: "$Header: /usr/src/contrib/rcs/src/RCS/rcsdiff.c,v 3.11 89/08/15 21:37:01 bostic Exp $ Purdue CS"; ! 7: #endif ! 8: /***************************************************************************** ! 9: * generate difference between RCS revisions ! 10: ***************************************************************************** ! 11: */ ! 12: ! 13: /* Copyright (C) 1982, 1988, 1989 Walter Tichy ! 14: * All rights reserved. ! 15: * ! 16: * Redistribution and use in source and binary forms are permitted ! 17: * provided that the above copyright notice and this paragraph are ! 18: * duplicated in all such forms and that any documentation, ! 19: * advertising materials, and other materials related to such ! 20: * distribution and use acknowledge that the software was developed ! 21: * by Walter Tichy. ! 22: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 23: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 24: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 25: * ! 26: * Report all problems and direct all questions to: ! 27: * [email protected] ! 28: * ! 29: ! 30: ! 31: ! 32: ! 33: ! 34: ! 35: ! 36: */ ! 37: ! 38: ! 39: ! 40: ! 41: /* $Log: rcsdiff.c,v $ ! 42: * Revision 3.11 89/08/15 21:37:01 bostic ! 43: * Version 4 from Tom Narten at Purdue ! 44: * ! 45: * Revision 4.6 89/05/01 15:12:27 narten ! 46: * changed copyright header to reflect current distribution rules ! 47: * ! 48: * Revision 4.5 88/11/08 12:01:51 narten ! 49: * changes from [email protected] (Paul Eggert) ! 50: * ! 51: * Revision 4.5 88/08/09 19:12:41 eggert ! 52: * Use execv(), not system(); yield exit status like diff(1)s; allow cc -R. ! 53: * ! 54: * Revision 4.4 87/12/18 11:37:46 narten ! 55: * changes Jay Lepreau made in the 4.3 BSD version, to add support for ! 56: * "-i", "-w", and "-t" flags and to permit flags to be bundled together, ! 57: * merged in. ! 58: * ! 59: * Revision 4.3 87/10/18 10:31:42 narten ! 60: * Updating version numbers. Changes relative to 1.1 actually ! 61: * relative to 4.1 ! 62: * ! 63: * Revision 1.3 87/09/24 13:59:21 narten ! 64: * Sources now pass through lint (if you ignore printf/sprintf/fprintf ! 65: * warnings) ! 66: * ! 67: * Revision 1.2 87/03/27 14:22:15 jenkins ! 68: * Port to suns ! 69: * ! 70: * Revision 1.1 84/01/23 14:50:18 kcs ! 71: * Initial revision ! 72: * ! 73: * Revision 4.1 83/05/03 22:13:19 wft ! 74: * Added default branch, option -q, exit status like diff. ! 75: * Added fterror() to replace faterror(). ! 76: * ! 77: * Revision 3.6 83/01/15 17:52:40 wft ! 78: * Expanded mainprogram to handle multiple RCS files. ! 79: * ! 80: * Revision 3.5 83/01/06 09:33:45 wft ! 81: * Fixed passing of -c (context) option to diff. ! 82: * ! 83: * Revision 3.4 82/12/24 15:28:38 wft ! 84: * Added call to catchsig(). ! 85: * ! 86: * Revision 3.3 82/12/10 16:08:17 wft ! 87: * Corrected checking of return code from diff; improved error msgs. ! 88: * ! 89: * Revision 3.2 82/12/04 13:20:09 wft ! 90: * replaced getdelta() with gettree(). Changed diagnostics. ! 91: * ! 92: * Revision 3.1 82/11/28 19:25:04 wft ! 93: * Initial revision. ! 94: * ! 95: */ ! 96: #include <ctype.h> ! 97: #include "rcsbase.h" ! 98: #define ERRCODE 2 /*error code for exit status */ ! 99: extern char *rindex(); ! 100: #ifndef lint ! 101: static char rcsbaseid[] = RCSBASE; ! 102: #endif ! 103: static char co[] = CO; ! 104: ! 105: extern int cleanup(); /* cleanup after signals */ ! 106: extern char * mktempfile(); /*temporary file name generator */ ! 107: extern int fterror(); /*forward for special fatal error func. */ ! 108: extern struct hshentry * genrevs(); /*generate delta numbers */ ! 109: extern int nerror; /*counter for errors */ ! 110: extern int quietflag; /*suppresses diagnostics */ ! 111: extern FILE * finptr; /* RCS input file */ ! 112: ! 113: char *RCSfilename; ! 114: char *workfilename; ! 115: char * temp1file, * temp2file; ! 116: ! 117: char bops[10]; ! 118: char otherops[10]; ! 119: ! 120: main (argc, argv) ! 121: int argc; char **argv; ! 122: { ! 123: char * cmdusage; ! 124: char commarg[revlength+3]; ! 125: int revnums; /* counter for revision numbers given */ ! 126: char * rev1, * rev2; /* revision numbers from command line */ ! 127: char numericrev[revlength]; /* holds expanded revision number */ ! 128: char * xrev1, * xrev2; /* expanded revision numbers */ ! 129: struct hshentry * gendeltas[hshsize];/*stores deltas to be generated*/ ! 130: struct hshentry * target; ! 131: char * boption, * otheroption; ! 132: int exit_stats; ! 133: int diffs_found; ! 134: char *argp; ! 135: register c; ! 136: ! 137: catchints(); ! 138: otheroption = otherops + 2; ! 139: boption = bops + 2; ! 140: cmdid = "rcsdiff"; ! 141: cmdusage = "command format:\n rcsdiff [-biwt] [-q] [-cefhn] [-rrev1] [-rrev2] file"; ! 142: diffs_found=revnums=0; ! 143: while (--argc,++argv, argc>=1 && ((*argv)[0] == '-')) { ! 144: argp = &((*argv)[1]); ! 145: while (c = *argp++) switch (c) { ! 146: case 'r': ! 147: if (*argp!='\0') { ! 148: if (revnums==0) { ! 149: rev1= argp; revnums=1; ! 150: } elif (revnums==1) { ! 151: rev2= argp; revnums=2; ! 152: } else { ! 153: fterror("too many revision numbers"); ! 154: } ! 155: } /* do nothing for empty -r */ ! 156: argp += strlen(argp); ! 157: break; ! 158: case 'b': ! 159: case 'i': ! 160: case 'w': ! 161: case 't': ! 162: if (!rindex(bops + 2, c)) ! 163: *boption++ = c; ! 164: break; ! 165: case 'q': ! 166: quietflag=true; ! 167: break; ! 168: case 'c': ! 169: case 'e': ! 170: case 'f': ! 171: case 'h': ! 172: case 'n': ! 173: if (otheroption == otherops + 2) { ! 174: *otheroption++ = c; ! 175: if (c == 'c' && isdigit(*argp)) { ! 176: while (isdigit(*argp) && otheroption < otherops+sizeof(otherops)-1) ! 177: *otheroption++ = *argp++; ! 178: if (*argp) ! 179: faterror("-c: bad count"); ! 180: argp = ""; ! 181: } ! 182: } else { ! 183: fterror("Options c,e,f,h,n are mutually exclusive"); ! 184: } ! 185: break; ! 186: default: ! 187: fterror("unknown option: %s\n%s", *argv,cmdusage); ! 188: }; ! 189: } /* end of option processing */ ! 190: ! 191: if (boption != bops + 2) { ! 192: bops[0] = ' '; ! 193: bops[1] = '-'; ! 194: boption = bops; ! 195: } ! 196: if (otheroption != otherops + 2) { ! 197: otherops[0] = ' '; ! 198: otherops[1] = '-'; ! 199: otheroption = otherops; ! 200: } ! 201: if (argc<1) fterror("No input file\n%s",cmdusage); ! 202: ! 203: /* now handle all filenames */ ! 204: do { ! 205: finptr=NULL; ! 206: ! 207: if (pairfilenames(argc,argv,true,false)!=1) continue; ! 208: diagnose("==================================================================="); ! 209: diagnose("RCS file: %s",RCSfilename); ! 210: if (revnums<2 && !(access(workfilename,4)==0)) { ! 211: error("Can't open %s",workfilename); ! 212: continue; ! 213: } ! 214: if (!trysema(RCSfilename,false)) continue; /* give up */ ! 215: ! 216: ! 217: gettree(); /* reads in the delta tree */ ! 218: ! 219: if (Head==nil) { ! 220: error("no revisions present"); ! 221: continue; ! 222: } ! 223: if (revnums==0) ! 224: rev1=Dbranch!=nil?Dbranch->num:Head->num; /* default rev1 */ ! 225: ! 226: if (!expandsym(rev1,numericrev)) continue; ! 227: if (!(target=genrevs(numericrev,(char *)nil,(char *)nil,(char *)nil,gendeltas))) continue; ! 228: xrev1=target->num; ! 229: ! 230: if (revnums==2) { ! 231: if (!expandsym(rev2,numericrev)) continue; ! 232: if (!(target=genrevs(numericrev,(char *)nil,(char *)nil,(char *)nil,gendeltas))) continue; ! 233: xrev2=target->num; ! 234: } ! 235: ! 236: ! 237: temp1file=mktempfile("/tmp/",TMPFILE1); ! 238: diagnose("retrieving revision %s",xrev1); ! 239: VOID sprintf(commarg,"-p%s",xrev1); ! 240: if (run((char*)nil,temp1file, co,"-q",commarg,RCSfilename,(char*)nil)){ ! 241: error("co failed"); ! 242: continue; ! 243: } ! 244: if (revnums<=1) { ! 245: temp2file=workfilename; ! 246: diagnose("diff%s%s -r%s %s",boption,otheroption,xrev1,workfilename); ! 247: } else { ! 248: temp2file=mktempfile("/tmp/",TMPFILE2); ! 249: diagnose("retrieving revision %s",xrev2); ! 250: VOID sprintf(commarg,"-p%s",xrev2); ! 251: if (run((char*)nil,temp2file, co,"-q",commarg,RCSfilename,(char *)nil)){ ! 252: error("co failed"); ! 253: continue; ! 254: } ! 255: diagnose("diff%s%s -r%s -r%s",boption,otheroption,xrev1,xrev2); ! 256: } ! 257: ! 258: exit_stats = ! 259: *boption ! 260: ? *otheroption ! 261: ? run((char*)nil,(char*)nil, DIFF, boption+1, otheroption+1, temp1file,temp2file,(char*)nil) ! 262: : run((char*)nil,(char*)nil, DIFF, boption+1, temp1file,temp2file,(char*)nil) ! 263: : *otheroption ! 264: ? run((char*)nil,(char*)nil, DIFF, otheroption+1, temp1file,temp2file,(char*)nil) ! 265: : run((char*)nil,(char*)nil, DIFF, temp1file,temp2file,(char*)nil); ! 266: ! 267: if (exit_stats == (1 << BYTESIZ)) ! 268: diffs_found = 1; ! 269: else if (exit_stats != 0) { ! 270: error ("diff failed"); ! 271: continue; ! 272: } ! 273: } while (cleanup(), ! 274: ++argv, --argc >=1); ! 275: ! 276: ! 277: exit(nerror ? ERRCODE : diffs_found); ! 278: } ! 279: ! 280: ! 281: /*VARARGS3*/ ! 282: fterror(e, e1, e2) ! 283: char * e, * e1, * e2; ! 284: /* prints error message and terminates program with ERRCODE */ ! 285: { nerror++; ! 286: VOID fprintf(stderr,"%s error: ",cmdid); ! 287: VOID fprintf(stderr,e, e1, e2); ! 288: VOID fprintf(stderr,"\n%s aborted\n",cmdid); ! 289: VOID cleanup(); ! 290: exit(ERRCODE); ! 291: } ! 292:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.