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