home *** CD-ROM | disk | FTP | other *** search
- /*
- * RCS rcsdiff operation
- */
- #ifndef lint
- static char rcsid[]=
- "$Header: /site/tmp/dosrcs/src/RCS/rcsdiff.c,v 5.5 90/07/15 21:55:43 lfk Release $ Purdue CS";
- #endif
- /*****************************************************************************
- * generate difference between RCS revisions
- *****************************************************************************
- */
-
- /* Copyright (C) 1982, 1988, 1989 Walter Tichy
- Distributed under license by the Free Software Foundation, Inc.
-
- This file is part of RCS.
-
- RCS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, or (at your option)
- any later version.
-
- RCS is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with RCS; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
- */
-
-
-
-
- /* $Log: rcsdiff.c,v $
- * Revision 5.5 90/07/15 21:55:43 lfk
- * fixed incompatible arguments for MKS diff
- *
- * Revision 5.3 90/07/15 20:24:46 lfk
- * Most major fixes added between rev 5.1 and rev 5.5:
- * signals fixed so they work on MS-DOS
- * Added MKS arguments code so argv can be large
- * added code to handle slashes a'la Unix
- * added more file extensions to system from MS-DOS
- *
- * Revision 5.2 90/07/15 11:33:19 ROOT_DOS
- * DOS version of RCS 4.0 checked in for MODS
- * by lfk@athena.mit.edu
- * Also update to MSC 6.0
- *
- * Revision 4.6 89/05/01 15:12:27 narten
- * changed copyright header to reflect current distribution rules
- *
- * Revision 4.5 88/11/08 12:01:51 narten
- * changes from eggert@sm.unisys.com (Paul Eggert)
- *
- * Revision 4.5 88/08/09 19:12:41 eggert
- * Use execv(), not system(); yield exit status like diff(1)s; allow cc -R.
- *
- * Revision 4.4 87/12/18 11:37:46 narten
- * changes Jay Lepreau made in the 4.3 BSD version, to add support for
- * "-i", "-w", and "-t" flags and to permit flags to be bundled together,
- * merged in.
- *
- * Revision 4.3 87/10/18 10:31:42 narten
- * Updating version numbers. Changes relative to 1.1 actually
- * relative to 4.1
- *
- * Revision 1.3 87/09/24 13:59:21 narten
- * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- * warnings)
- *
- * Revision 1.2 87/03/27 14:22:15 jenkins
- * Port to suns
- *
- * Revision 1.1 84/01/23 14:50:18 kcs
- * Initial revision
- *
- * Revision 4.1 83/05/03 22:13:19 wft
- * Added default branch, option -q, exit status like diff.
- * Added fterror() to replace faterror().
- *
- * Revision 3.6 83/01/15 17:52:40 wft
- * Expanded mainprogram to handle multiple RCS files.
- *
- * Revision 3.5 83/01/06 09:33:45 wft
- * Fixed passing of -c (context) option to diff.
- *
- * Revision 3.4 82/12/24 15:28:38 wft
- * Added call to catchsig().
- *
- * Revision 3.3 82/12/10 16:08:17 wft
- * Corrected checking of return code from diff; improved error msgs.
- *
- * Revision 3.2 82/12/04 13:20:09 wft
- * replaced getdelta() with gettree(). Changed diagnostics.
- *
- * Revision 3.1 82/11/28 19:25:04 wft
- * Initial revision.
- *
- */
- #include <ctype.h>
- #include "rcsbase.h"
- #define ERRCODE 2 /*error code for exit status */
- extern char *rindex();
- #ifndef lint
- static char rcsbaseid[] = RCSBASE;
- #endif
- static char co[] = CO;
-
- extern int cleanup(); /* cleanup after signals */
- extern char * mktempfile(); /*temporary file name generator */
- extern int fterror(); /*forward for special fatal error func. */
- extern struct hshentry * genrevs(); /*generate delta numbers */
- extern int nerror; /*counter for errors */
- extern int quietflag; /*suppresses diagnostics */
- extern FILE * finptr; /* RCS input file */
-
- char *RCSfilename;
- char *workfilename;
- char * temp1file, * temp2file;
-
- #ifdef MSDOS
- int old_stdout;
- char *gettmpdir();
- char tmpdir[NCPPN];
- #endif /* MSDOS */
-
- char bops[10];
- char otherops[10];
-
-
- #ifdef MKS
- main(int argc, char *argv[], char *env[])
- #else
- main (argc, argv)
- int argc;
- char * argv[];
- #endif /* MKS */
- {
- char * cmdusage;
- char commarg[revlength+3];
- int revnums; /* counter for revision numbers given */
- char * rev1, * rev2; /* revision numbers from command line */
- char numericrev[revlength]; /* holds expanded revision number */
- char * xrev1, * xrev2; /* expanded revision numbers */
- struct hshentry * gendeltas[hshsize];/*stores deltas to be generated*/
- struct hshentry * target;
- char * boption, * otheroption;
- int exit_stats;
- int diffs_found;
- char *argp;
- register c;
- #ifdef MKS
- int z = 0;
- int ARGC = 0;
- char **tmp;
- char *env_name;
- # define MAXARGS 500 /* This means 500 items on the command line */
- if (!(tmp = (char **)malloc(sizeof(char *)*(MAXARGS+1)))) {
- fprintf(stderr, "%s: can't allocate space for arguments\n",argv[0]);
- exit(1);
- }
- for ( z = 0 ; env[z] != NULL; z++) { /* loop through environment */
- if (*env[z] == '~') { /* testing for entries begining with '~' */
- *++env[z]; /* increment pointer to delete '~' */
- tmp[ARGC++] = env[z]; /* add it to our new array */
- if (z >= MAXARGS) {
- fprintf(stderr, "%s: can't handle any more arguments\n", argv[0]);
- goto list;
- }
- }
- else if (*env[z] == '_') { /* testing for entries begining with _ */
- *++env[z] ; *++env[z]; /* move past the '_' and the '=' */
- env_name = env[z]; /* copy the name */
- }
- }
- list:
- if ( STREQ( (char *) argv[0] , env_name ) ) { /* test name against startup args */
- /* environment arguments meant for this program */
- # ifdef DEBUG
- printf("Using shell supplied args\n");
- # endif
- argc = ARGC;
- tmp[ARGC] = NULL; /* the terminal NULL */
- argv = tmp;
- }
- # ifdef DEBUG
- else
- printf("Using startup supplied args\n");
- # endif /* debug */
- #endif /* MKS */
-
- catchints();
- otheroption = otherops + 2;
- boption = bops + 2;
- cmdid = "rcsdiff";
- cmdusage = "command format:\n rcsdiff [-biwt] [-q] [-cefhn] [-rrev1] [-rrev2] file";
- diffs_found=revnums=0;
- while (--argc,++argv, argc>=1 && ((*argv)[0] == '-')) {
- argp = &((*argv)[1]);
- while (c = *argp++) switch (c) {
- case 'r':
- if (*argp!='\0') {
- if (revnums==0) {
- rev1= argp; revnums=1;
- } elif (revnums==1) {
- rev2= argp; revnums=2;
- } else {
- fterror("too many revision numbers");
- }
- } /* do nothing for empty -r */
- argp += strlen(argp);
- break;
- case 'b':
- case 'i':
- case 'w':
- case 't':
- if (!rindex(bops + 2, c))
- *boption++ = c;
- break;
- case 'q':
- quietflag=true;
- break;
- case 'c':
- case 'e':
- case 'f':
- case 'h':
- case 'n':
- if (otheroption == otherops + 2) {
- *otheroption++ = c;
- if (c == 'c' && isdigit(*argp)) {
- while (isdigit(*argp) && otheroption < otherops+sizeof(otherops)-1)
- *otheroption++ = *argp++;
- if (*argp)
- faterror("-c: bad count");
- argp = "";
- }
- } else {
- fterror("Options c,e,f,h,n are mutually exclusive");
- }
- break;
- default:
- fterror("unknown option: %s\n%s", *argv,cmdusage);
- };
- } /* end of option processing */
-
- if (boption != bops + 2) {
- bops[0] = ' ';
- bops[1] = '-';
- boption = bops;
- }
- if (otheroption != otherops + 2) {
- otherops[0] = ' ';
- otherops[1] = '-';
- otheroption = otherops;
- }
- if (argc<1) fterror("No input file\n%s",cmdusage);
-
- #ifdef MSDOS
- strcpy( tmpdir, gettmpdir() );
- old_stdout = dup(1);
- #endif /* MSDOS */
- /* now handle all filenames */
- do {
- finptr=NULL;
-
- if (pairfilenames(argc,argv,true,false)!=1) continue;
- diagnose("===================================================================");
- diagnose("RCS file: %s",RCSfilename);
- if (revnums<2 && !(access(workfilename,4)==0)) {
- error("Can't open %s",workfilename);
- continue;
- }
- if (!trysema(RCSfilename,false)) continue; /* give up */
-
-
- gettree(); /* reads in the delta tree */
-
- if (Head==nil) {
- error("no revisions present");
- continue;
- }
- if (revnums==0)
- rev1=Dbranch!=nil?Dbranch->num:Head->num; /* default rev1 */
-
- if (!expandsym(rev1,numericrev)) continue;
- if (!(target=genrevs(numericrev,(char *)nil,(char *)nil,(char *)nil,gendeltas))) continue;
- xrev1=target->num;
-
- if (revnums==2) {
- if (!expandsym(rev2,numericrev)) continue;
- if (!(target=genrevs(numericrev,(char *)nil,(char *)nil,(char *)nil,gendeltas))) continue;
- xrev2=target->num;
- }
-
-
- #ifdef MSDOS
- temp1file=mktempfile(tmpdir,TMPFILE1);
- #else
- temp1file=mktempfile("/tmp/",TMPFILE1);
- #endif /* MSDOS */
- diagnose("retrieving revision %s",xrev1);
- VOID sprintf(commarg,"-p%s",xrev1);
- if (run((char*)nil,temp1file, co,"-q",commarg,RCSfilename,(char*)nil)){
- error("co failed");
- continue;
- }
- if (revnums<=1) {
- temp2file=workfilename;
- diagnose("diff%s%s -r%s %s",boption,otheroption,xrev1,workfilename);
- } else {
- #ifdef MSDOS
- temp2file=mktempfile(tmpdir,TMPFILE2);
- #else
- temp2file=mktempfile("/tmp/",TMPFILE2);
- #endif /* MSDOS */
- diagnose("retrieving revision %s",xrev2);
- VOID sprintf(commarg,"-p%s",xrev2);
- if (run((char*)nil,temp2file, co,"-q",commarg,RCSfilename,(char *)nil)){
- error("co failed");
- continue;
- }
- diagnose("diff%s%s -r%s -r%s",boption,otheroption,xrev1,xrev2);
- }
- #ifdef MSDOS
- # ifdef MKS
- dup2( old_stdout, 1 );
- exit_stats =
- *boption
- ? *otheroption
- ? spawnlp( 0, DIFF, DIFF, boption+1, otheroption+1, temp1file,temp2file,NULL)
- : spawnlp( 0, DIFF, DIFF, boption+1, temp1file, temp2file, NULL)
- : *otheroption
- ? spawnlp( 0, DIFF, DIFF, otheroption+1, temp1file,temp2file, NULL)
- : spawnlp( 0, DIFF, DIFF, temp1file, temp2file, NULL);
- # else
- dup2( old_stdout, 1 );
- exit_stats =
- *boption
- ? *otheroption
- ? spawnlp( 0, DIFF, DIFF, "-a", boption+1, otheroption+1, temp1file,temp2file,NULL)
- : spawnlp( 0, DIFF, DIFF, "-a", boption+1, temp1file, temp2file, NULL)
- : *otheroption
- ? spawnlp( 0, DIFF, DIFF, "-a", otheroption+1, temp1file,temp2file, NULL)
- : spawnlp( 0, DIFF, DIFF, "-a", temp1file, temp2file, NULL);
- # endif
- #else
- exit_stats =
- *boption
- ? *otheroption
- ? run((char*)nil,(char*)nil, DIFF, boption+1, otheroption+1, temp1file,temp2file,(char*)nil)
- : run((char*)nil,(char*)nil, DIFF, boption+1, temp1file,temp2file,(char*)nil)
- : *otheroption
- ? run((char*)nil,(char*)nil, DIFF, otheroption+1, temp1file,temp2file,(char*)nil)
- : run((char*)nil,(char*)nil, DIFF, temp1file,temp2file,(char*)nil);
- #endif /* MSDOS */
-
- #ifdef MSDOS
- if (exit_stats == 1 )
- #else
- if (exit_stats == (1 << BYTESIZ))
- #endif /* MSDOS */
- diffs_found = 1;
- else if (exit_stats != 0) {
- error ("diff failed");
- continue;
- }
- } while ( cleanup(),
- ++argv, --argc >=1);
-
-
- exit(nerror ? ERRCODE : diffs_found);
- }
-
-
- /*VARARGS3*/
- fterror(e, e1, e2)
- char * e, * e1, * e2;
- /* prints error message and terminates program with ERRCODE */
- { nerror++;
- VOID fprintf(stderr,"%s error: ",cmdid);
- VOID fprintf(stderr,e, e1, e2);
- VOID fprintf(stderr,"\n%s aborted\n",cmdid);
- VOID cleanup();
- exit(ERRCODE);
- }
-
-