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: }

Defined functions

fterror defined in line 251; used 5 times
main defined in line 92; never used

Defined variables

RCSfilename defined in line 85; used 4 times
bops defined in line 89; used 3 times
otherops defined in line 90; used 4 times
rcsbaseid defined in line 74; never used
rcsid defined in line 5; never used
temp1file defined in line 87; used 3 times
temp2file defined in line 87; used 4 times
workfilename defined in line 86; used 4 times

Defined macros

ERRCODE defined in line 72; used 2 times
Last modified: 1988-02-19
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2829
Valid CSS Valid XHTML 1.0 Strict