home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OS9000 / APPS / rcs.lzh / rcs1 / rcsdiff.c < prev    next >
Text File  |  1996-04-20  |  12KB  |  363 lines

  1. /*
  2.  *                     Rcs rcsdiff operation
  3.  */
  4. #ifndef lint
  5. static char rcsid[]=
  6. "$Id: rcsdiff.c_v 1.2 93/04/27 01:50:50 hiro Exp $ Purdue CS";
  7. #endif
  8. /*****************************************************************************
  9.  *                       generate difference between RCS revisions
  10.  *****************************************************************************
  11.  */
  12.  
  13. /* Copyright (C) 1982, 1988, 1989 Walter Tichy
  14.    Distributed under license by the Free Software Foundation, Inc.
  15.  
  16. This file is part of RCS.
  17.  
  18. RCS is free software; you can redistribute it and/or modify
  19. it under the terms of the GNU General Public License as published by
  20. the Free Software Foundation; either version 1, or (at your option)
  21. any later version.
  22.  
  23. RCS is distributed in the hope that it will be useful,
  24. but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  26. GNU General Public License for more details.
  27.  
  28. You should have received a copy of the GNU General Public License
  29. along with RCS; see the file COPYING.  If not, write to
  30. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  31.  
  32. Report problems and direct all questions to:
  33.  
  34.     rcs-bugs@cs.purdue.edu
  35.  
  36. */
  37.  
  38.  
  39.  
  40.  
  41. /* $Log:    rcsdiff.c_v $
  42.  * Revision 1.2  93/04/27  01:50:50  hiro
  43.  * Prototype
  44.  * ================================================================
  45.  * Added remove with retry for temporary files.
  46.  * ================================================================
  47.  * 
  48.  * Revision 1.1  93/04/02  01:28:41  hiro
  49.  * Initial revision
  50.  * 
  51.  * Revision 1.1  90/07/19  15:21:04  momo
  52.  * Initial revision
  53.  * 
  54.  * Revision 4.6  89/05/01  15:12:27  narten
  55.  * changed copyright header to reflect current distribution rules
  56.  * 
  57.  * Revision 4.5  88/11/08  12:01:51  narten
  58.  * changes from  eggert@sm.unisys.com (Paul Eggert)
  59.  * 
  60.  * Revision 4.5  88/08/09  19:12:41  eggert
  61.  * Use execv(), not system(); yield exit status like diff(1)s; allow cc -R.
  62.  * 
  63.  * Revision 4.4  87/12/18  11:37:46  narten
  64.  * changes Jay Lepreau made in the 4.3 BSD version, to add support for
  65.  * "-i", "-w", and "-t" flags and to permit flags to be bundled together, 
  66.  * merged in.
  67.  * 
  68.  * Revision 4.3  87/10/18  10:31:42  narten
  69.  * Updating version numbers. Changes relative to 1.1 actually
  70.  * relative to 4.1
  71.  * 
  72.  * Revision 1.3  87/09/24  13:59:21  narten
  73.  * Sources now pass through lint (if you ignore printf/sprintf/fprintf 
  74.  * warnings)
  75.  * 
  76.  * Revision 1.2  87/03/27  14:22:15  jenkins
  77.  * Port to suns
  78.  * 
  79.  * Revision 1.1  84/01/23  14:50:18  kcs
  80.  * Initial revision
  81.  * 
  82.  * Revision 4.1  83/05/03  22:13:19  wft
  83.  * Added default branch, option -q, exit status like diff.
  84.  * Added fterror() to replace faterror().
  85.  * 
  86.  * Revision 3.6  83/01/15  17:52:40  wft
  87.  * Expanded mainprogram to handle multiple RCS files.
  88.  *
  89.  * Revision 3.5  83/01/06  09:33:45  wft
  90.  * Fixed passing of -c (context) option to diff.
  91.  *
  92.  * Revision 3.4  82/12/24  15:28:38  wft
  93.  * Added call to catchsig().
  94.  *
  95.  * Revision 3.3  82/12/10  16:08:17  wft
  96.  * Corrected checking of return code from diff; improved error msgs.
  97.  *
  98.  * Revision 3.2  82/12/04  13:20:09  wft
  99.  * replaced getdelta() with gettree(). Changed diagnostics.
  100.  *
  101.  * Revision 3.1  82/11/28  19:25:04  wft
  102.  * Initial revision.
  103.  *
  104.  */
  105. #include <ctype.h>
  106. #include <errno.h>
  107. #include "rcsbase.h"
  108. #define ERRCODE 2                   /*error code for exit status            */
  109. extern char *rindex();
  110. #ifndef lint
  111. static char rcsbaseid[] = RCSBASE;
  112. #endif
  113. static char co[] = CO;
  114.  
  115. extern int    cleanup();            /* cleanup after signals                */
  116. extern char * mktempfile();         /*temporary file name generator         */
  117. extern int    fterror();            /*forward for special fatal error func. */
  118. extern struct hshentry * genrevs(); /*generate delta numbers                */
  119. extern int    nerror;               /*counter for errors                    */
  120. extern int    quietflag;            /*suppresses diagnostics                */
  121. extern FILE * finptr;               /* RCS input file                       */
  122.  
  123. char *RCSfilename;
  124. char *workfilename;
  125. char * temp1file, * temp2file;
  126.  
  127. #if defined(MSDOS) || defined(OSK)
  128. int old_stdout;
  129. char *gettmpdir();
  130. char tmpdir[NCPPN];
  131. #endif /* MSDOS */
  132.  
  133. char bops[10];
  134. char otherops[10];
  135.  
  136. main (argc, argv)
  137. int argc; char **argv;
  138. {
  139.         char * cmdusage;
  140.     char commarg[revlength+3];
  141.         int  revnums;                 /* counter for revision numbers given */
  142.         char * rev1, * rev2;          /* revision numbers from command line */
  143.         char numericrev[revlength];   /* holds expanded revision number     */
  144.         char * xrev1, * xrev2;        /* expanded revision numbers          */
  145.         struct hshentry * gendeltas[hshsize];/*stores deltas to be generated*/
  146.         struct hshentry * target;
  147.     char * boption, * otheroption;
  148.         int  exit_stats;
  149.     int  diffs_found;
  150.     char *argp;
  151.     register c;
  152.  
  153.         catchints();
  154.         otheroption = otherops + 2;
  155.     boption = bops + 2;
  156.         cmdid = "rcsdiff";
  157.     cmdusage = "command format:\n    rcsdiff [-biwt] [-q] [-cefhn] [-rrev1] [-rrev2] file";
  158.     diffs_found=revnums=0;
  159.         while (--argc,++argv, argc>=1 && ((*argv)[0] == '-')) {
  160.         argp = &((*argv)[1]);
  161.         while (c = *argp++) switch (c) {
  162.                 case 'r':
  163.                 if (*argp!='\0') {
  164.                             if (revnums==0) {
  165.                                     rev1= argp; revnums=1;
  166.                             } elif (revnums==1) {
  167.                                     rev2= argp; revnums=2;
  168.                             } else {
  169.                     fterror("too many revision numbers");
  170.                             }
  171.                         } /* do nothing for empty -r */
  172.             argp += strlen(argp);
  173.                         break;
  174.                 case 'b':
  175.                 case 'i':
  176.                 case 'w':
  177.                 case 't':
  178.             if (!rindex(bops + 2, c))
  179.                 *boption++ = c;
  180.             break;
  181.         case 'q':
  182.             quietflag=true;
  183.             break;
  184.                 case 'c':
  185.                 case 'e':
  186.                 case 'f':
  187.                 case 'h':
  188.                 case 'n':
  189.                         if (otheroption == otherops + 2) {
  190.                 *otheroption++ = c;
  191.                 if (c == 'c' && isdigit(*argp)) {
  192.                     while (isdigit(*argp) && otheroption < otherops+sizeof(otherops)-1)
  193.                         *otheroption++ = *argp++;
  194.                     if (*argp)
  195.                         faterror("-c: bad count");
  196.                     argp = "";
  197.                 }
  198.                         } else {
  199.                 fterror("Options c,e,f,h,n are mutually exclusive");
  200.                         }
  201.             break;
  202.                 default:
  203.             fterror("unknown option: %s\n%s", *argv,cmdusage);
  204.                 };
  205.         } /* end of option processing */
  206.  
  207.     if (boption != bops + 2) {
  208.         bops[0] = ' ';
  209.         bops[1] = '-';
  210.         boption = bops;
  211.     }
  212.     if (otheroption != otherops + 2) {
  213.          otherops[0] = ' ';
  214.         otherops[1] = '-';
  215.         otheroption = otherops;
  216.     }
  217.     if (argc<1) fterror("No input file\n%s",cmdusage);
  218.  
  219. #if defined(MSDOS) || defined(OSK)
  220.     strcpy( tmpdir, gettmpdir() );
  221. #endif
  222. #ifdef MSDOS
  223.     old_stdout = dup(1);
  224. #endif /* MSDOS */        
  225. /* now handle all filenames */
  226.         do {
  227.                 finptr=NULL;
  228.  
  229.                 if (pairfilenames(argc,argv,true,false)!=1) continue;
  230.         diagnose("===================================================================");
  231.                 diagnose("RCS file: %s",RCSfilename);
  232. #ifdef OSK
  233.                 if (revnums<2 && !(access(workfilename,1)==0)) {
  234. #else
  235.                 if (revnums<2 && !(access(workfilename,4)==0)) {
  236. #endif
  237.  
  238.                         error("Can't open %s",workfilename);
  239.                         continue;
  240.                 }
  241.                 if (!trysema(RCSfilename,false)) continue; /* give up */
  242.  
  243.  
  244.                 gettree(); /* reads in the delta tree */
  245.  
  246.                 if (Head==nil) {
  247.                         error("no revisions present");
  248.                         continue;
  249.                 }
  250.  
  251.                 if (revnums==0)
  252.                         rev1=Dbranch!=nil?Dbranch->num:Head->num; /* default rev1 */
  253.  
  254.                 if (!expandsym(rev1,numericrev)) continue;
  255.                 if (!(target=genrevs(numericrev,(char *)nil,(char *)nil,(char *)nil,gendeltas))) continue;
  256.                 xrev1=target->num;
  257.  
  258.                 if (revnums==2) {
  259.                         if (!expandsym(rev2,numericrev)) continue;
  260.                         if (!(target=genrevs(numericrev,(char *)nil,(char *)nil,(char *)nil,gendeltas))) continue;
  261.                         xrev2=target->num;
  262.                 }
  263.  
  264. #if defined(MSDOS) || defined(OSK)
  265.                 temp1file=mktempfile(tmpdir,TMPFILE1);
  266. #else
  267.                 temp1file=mktempfile("/tmp/",TMPFILE1);
  268. #endif /* MSDOS */
  269.                 diagnose("retrieving revision %s",xrev1);
  270.                 VOID sprintf(commarg,"-p%s",xrev1);
  271.  
  272.                 if (run((char*)nil,temp1file, co,"-q",commarg,RCSfilename,(char*)nil)){
  273.                         error("co failed");
  274.                         continue;
  275.                 }
  276.                 if (revnums<=1) {
  277.                         temp2file=workfilename;
  278.                         diagnose("diff%s%s -r%s %s",boption,otheroption,xrev1,workfilename);
  279.                 } else {
  280. #if defined(MSDOS) || defined(OSK)
  281.                         temp2file=mktempfile(tmpdir,TMPFILE2);
  282. #else
  283.                         temp2file=mktempfile("/tmp/",TMPFILE2);
  284. #endif /* MSDOS */
  285.                         diagnose("retrieving revision %s",xrev2);
  286.             VOID sprintf(commarg,"-p%s",xrev2);
  287.                         if (run((char*)nil,temp2file, co,"-q",commarg,RCSfilename,(char *)nil)){
  288.                                 error("co failed");
  289.                                 continue;
  290.                         }
  291.                         diagnose("diff%s%s -r%s -r%s",boption,otheroption,xrev1,xrev2);
  292.                 }
  293. #ifdef MSDOS
  294.         dup2( old_stdout, 1 );
  295.                 exit_stats =
  296.             *boption
  297.             ? *otheroption
  298.               ? spawnlp( 0, DIFF, DIFF, "-a", boption+1, otheroption+1, temp1file,temp2file,NULL)
  299.               : spawnlp( 0, DIFF, DIFF, "-a", boption+1, temp1file, temp2file, NULL)
  300.             : *otheroption
  301.               ? spawnlp( 0, DIFF, DIFF, "-a", otheroption+1, temp1file,temp2file, NULL)
  302.               : spawnlp( 0, DIFF, DIFF, "-a", temp1file, temp2file, NULL);
  303. #else
  304. #ifdef OSK
  305.                 exit_stats =
  306.             *boption
  307.             ? *otheroption
  308.               ? run((char*)nil,(char*)nil, DIFF, "-a" , boption+1,    otheroption+1,    temp1file,temp2file,(char*)nil)
  309.               : run((char*)nil,(char*)nil, DIFF, "-a" , boption+1,            temp1file,temp2file,(char*)nil)
  310.             : *otheroption
  311.               ? run((char*)nil,(char*)nil, DIFF, "-a" ,        otheroption+1,    temp1file,temp2file,(char*)nil)
  312.               : run((char*)nil,(char*)nil, DIFF, "-a" ,                temp1file,temp2file,(char*)nil);
  313. #else
  314.                 exit_stats =
  315.             *boption
  316.             ? *otheroption
  317.               ? run((char*)nil,(char*)nil, DIFF, boption+1,    otheroption+1,    temp1file,temp2file,(char*)nil)
  318.               : run((char*)nil,(char*)nil, DIFF, boption+1,            temp1file,temp2file,(char*)nil)
  319.             : *otheroption
  320.               ? run((char*)nil,(char*)nil, DIFF,         otheroption+1,    temp1file,temp2file,(char*)nil)
  321.               : run((char*)nil,(char*)nil, DIFF,                 temp1file,temp2file,(char*)nil);
  322. #endif /* OSK */
  323. #endif /* MSDOS */
  324.  
  325. #ifdef OSK
  326. /**** Added by hiro ****/
  327.             while (remove(temp1file) == -1 && errno == EOS_SHARE)
  328.                 tsleep(10);
  329.             if (revnums>1)
  330.                 while (remove(temp2file) == -1 && errno == EOS_SHARE)
  331.                     tsleep(10);
  332. #endif
  333. #if  ( defined(MSDOS) || defined(OSK) ) && defined(GNUDIFF)
  334.                 if (exit_stats == 1 )
  335. #else
  336.                 if (exit_stats == (1 << BYTESIZ))
  337. #endif /* MSDOS && GNUDIFF */
  338.             diffs_found = 1;
  339.                 else if (exit_stats != 0) {
  340.                         error ("diff failed");
  341.                         continue;
  342.                 }
  343.         } while ( cleanup(),
  344.                  ++argv, --argc >=1);
  345.  
  346.  
  347.         exit(nerror ? ERRCODE : diffs_found);
  348. }
  349.  
  350.  
  351. /*VARARGS3*/
  352. fterror(e, e1, e2)
  353. char * e, * e1, * e2;
  354. /* prints error message and terminates program with ERRCODE */
  355. {       nerror++;
  356.         VOID fprintf(stderr,"%s error: ",cmdid);
  357.     VOID fprintf(stderr,e, e1, e2);
  358.         VOID fprintf(stderr,"\n%s aborted\n",cmdid);
  359.         VOID cleanup();
  360.     exit(ERRCODE);
  361. }
  362.  
  363.