|
|
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.