2 * RCS rcsdiff operation
6 "$Header: /pub/NetBSD/misc/repositories/cvsroot/src/usr.bin/rcs/src/Attic/rcsdiff.c,v 1.1 1993/03/21 09:58:07 cgd Exp $ Purdue CS";
8 /*****************************************************************************
9 * generate difference between RCS revisions
10 *****************************************************************************
13 /* Copyright (C) 1982, 1988, 1989 Walter Tichy
14 * All rights reserved.
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
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.
26 * Report all problems and direct all questions to:
27 * rcs-bugs@cs.purdue.edu
41 /* $Log: rcsdiff.c,v $
42 * Revision 3.12 91/02/22 00:11:20 elan
43 * *** empty log message ***
45 * Revision 3.11 89/08/15 21:37:01 bostic
46 * Version 4 from Tom Narten at Purdue
48 * Revision 4.6 89/05/01 15:12:27 narten
49 * changed copyright header to reflect current distribution rules
51 * Revision 4.5 88/11/08 12:01:51 narten
52 * changes from eggert@sm.unisys.com (Paul Eggert)
54 * Revision 4.5 88/08/09 19:12:41 eggert
55 * Use execv(), not system(); yield exit status like diff(1)s; allow cc -R.
57 * Revision 4.4 87/12/18 11:37:46 narten
58 * changes Jay Lepreau made in the 4.3 BSD version, to add support for
59 * "-i", "-w", and "-t" flags and to permit flags to be bundled together,
62 * Revision 4.3 87/10/18 10:31:42 narten
63 * Updating version numbers. Changes relative to 1.1 actually
66 * Revision 1.3 87/09/24 13:59:21 narten
67 * Sources now pass through lint (if you ignore printf/sprintf/fprintf
70 * Revision 1.2 87/03/27 14:22:15 jenkins
73 * Revision 1.1 84/01/23 14:50:18 kcs
76 * Revision 4.1 83/05/03 22:13:19 wft
77 * Added default branch, option -q, exit status like diff.
78 * Added fterror() to replace faterror().
80 * Revision 3.6 83/01/15 17:52:40 wft
81 * Expanded mainprogram to handle multiple RCS files.
83 * Revision 3.5 83/01/06 09:33:45 wft
84 * Fixed passing of -c (context) option to diff.
86 * Revision 3.4 82/12/24 15:28:38 wft
87 * Added call to catchsig().
89 * Revision 3.3 82/12/10 16:08:17 wft
90 * Corrected checking of return code from diff; improved error msgs.
92 * Revision 3.2 82/12/04 13:20:09 wft
93 * replaced getdelta() with gettree(). Changed diagnostics.
95 * Revision 3.1 82/11/28 19:25:04 wft
101 #define ERRCODE 2 /*error code for exit status */
102 extern char *rindex();
104 static char rcsbaseid
[] = RCSBASE
;
106 static char co
[] = CO
;
108 extern int cleanup(); /* cleanup after signals */
109 extern char * mktempfile(); /*temporary file name generator */
110 extern int fterror(); /*forward for special fatal error func. */
111 extern struct hshentry
* genrevs(); /*generate delta numbers */
112 extern int nerror
; /*counter for errors */
113 extern int quietflag
; /*suppresses diagnostics */
114 extern FILE * finptr
; /* RCS input file */
118 char * temp1file
, * temp2file
;
124 int argc
; char **argv
;
127 char commarg
[revlength
+3];
128 int revnums
; /* counter for revision numbers given */
129 char * rev1
, * rev2
; /* revision numbers from command line */
130 char numericrev
[revlength
]; /* holds expanded revision number */
131 char * xrev1
, * xrev2
; /* expanded revision numbers */
132 struct hshentry
* gendeltas
[hshsize
];/*stores deltas to be generated*/
133 struct hshentry
* target
;
134 char * boption
, * otheroption
;
141 otheroption
= otherops
+ 2;
144 cmdusage
= "command format:\n rcsdiff [-biwt] [-q] [-cefhn] [-rrev1] [-rrev2] file";
145 diffs_found
=revnums
=0;
146 while (--argc
,++argv
, argc
>=1 && ((*argv
)[0] == '-')) {
147 argp
= &((*argv
)[1]);
148 while (c
= *argp
++) switch (c
) {
152 rev1
= argp
; revnums
=1;
153 } elif (revnums
==1) {
154 rev2
= argp
; revnums
=2;
156 fterror("too many revision numbers");
158 } /* do nothing for empty -r */
159 argp
+= strlen(argp
);
165 if (!rindex(bops
+ 2, c
))
176 if (otheroption
== otherops
+ 2) {
178 if (c
== 'c' && isdigit(*argp
)) {
179 while (isdigit(*argp
) && otheroption
< otherops
+sizeof(otherops
)-1)
180 *otheroption
++ = *argp
++;
182 faterror("-c: bad count");
186 fterror("Options c,e,f,h,n are mutually exclusive");
190 fterror("unknown option: %s\n%s", *argv
,cmdusage
);
192 } /* end of option processing */
194 if (boption
!= bops
+ 2) {
199 if (otheroption
!= otherops
+ 2) {
202 otheroption
= otherops
;
204 if (argc
<1) fterror("No input file\n%s",cmdusage
);
206 /* now handle all filenames */
210 if (pairfilenames(argc
,argv
,true,false)!=1) continue;
211 diagnose("===================================================================");
212 diagnose("RCS file: %s",RCSfilename
);
213 if (revnums
<2 && !(access(workfilename
,4)==0)) {
214 error("Can't open %s",workfilename
);
217 if (!trysema(RCSfilename
,false)) continue; /* give up */
220 gettree(); /* reads in the delta tree */
223 error("no revisions present");
227 rev1
=Dbranch
!=nil
?Dbranch
->num
:Head
->num
; /* default rev1 */
229 if (!expandsym(rev1
,numericrev
)) continue;
230 if (!(target
=genrevs(numericrev
,(char *)nil
,(char *)nil
,(char *)nil
,gendeltas
))) continue;
234 if (!expandsym(rev2
,numericrev
)) continue;
235 if (!(target
=genrevs(numericrev
,(char *)nil
,(char *)nil
,(char *)nil
,gendeltas
))) continue;
240 temp1file
=mktempfile("/tmp/",TMPFILE1
);
241 diagnose("retrieving revision %s",xrev1
);
242 VOID
sprintf(commarg
,"-p%s",xrev1
);
243 if (run((char*)nil
,temp1file
, co
,"-q",commarg
,RCSfilename
,(char*)nil
)){
248 temp2file
=workfilename
;
249 diagnose("diff%s%s -r%s %s",boption
,otheroption
,xrev1
,workfilename
);
251 temp2file
=mktempfile("/tmp/",TMPFILE2
);
252 diagnose("retrieving revision %s",xrev2
);
253 VOID
sprintf(commarg
,"-p%s",xrev2
);
254 if (run((char*)nil
,temp2file
, co
,"-q",commarg
,RCSfilename
,(char *)nil
)){
258 diagnose("diff%s%s -r%s -r%s",boption
,otheroption
,xrev1
,xrev2
);
264 ? run((char*)nil
,(char*)nil
, DIFF
, boption
+1, otheroption
+1, temp1file
,temp2file
,(char*)nil
)
265 : run((char*)nil
,(char*)nil
, DIFF
, boption
+1, temp1file
,temp2file
,(char*)nil
)
267 ? run((char*)nil
,(char*)nil
, DIFF
, otheroption
+1, temp1file
,temp2file
,(char*)nil
)
268 : run((char*)nil
,(char*)nil
, DIFF
, temp1file
,temp2file
,(char*)nil
);
270 if (exit_stats
== (1 << BYTESIZ
))
272 else if (exit_stats
!= 0) {
273 error ("diff failed");
280 exit(nerror
? ERRCODE
: diffs_found
);
286 char * e
, * e1
, * e2
;
287 /* prints error message and terminates program with ERRCODE */
289 VOID
fprintf(stderr
,"%s error: ",cmdid
);
290 VOID
fprintf(stderr
,e
, e1
, e2
);
291 VOID
fprintf(stderr
,"\n%s aborted\n",cmdid
);