home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / rcs4.lha / rcsdiff.c < prev    next >
Text File  |  1993-03-03  |  9KB  |  268 lines

  1. /*
  2.  *                     RCS rcsdiff operation
  3.  */
  4. #ifndef lint
  5. static char rcsid[]=
  6. "$Header: /usr/src/local/bin/rcs/src/RCS/rcsdiff.c,v 4.4 87/12/18 11:37:46 narten 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 4.4  87/12/18  11:37:46  narten
  26.  * changes Jay Lepreau made in the 4.3 BSD version, to add support for
  27.  * "-i", "-w", and "-t" flags and to permit flags to be bundled together, 
  28.  * merged in.
  29.  * 
  30.  * Revision 4.3  87/10/18  10:31:42  narten
  31.  * Updating version numbers. Changes relative to 1.1 actually
  32.  * relative to 4.1
  33.  * 
  34.  * Revision 1.3  87/09/24  13:59:21  narten
  35.  * Sources now pass through lint (if you ignore printf/sprintf/fprintf 
  36.  * warnings)
  37.  * 
  38.  * Revision 1.2  87/03/27  14:22:15  jenkins
  39.  * Port to suns
  40.  * 
  41.  * Revision 1.1  84/01/23  14:50:18  kcs
  42.  * Initial revision
  43.  * 
  44.  * Revision 4.1  83/05/03  22:13:19  wft
  45.  * Added default branch, option -q, exit status like diff.
  46.  * Added fterror() to replace faterror().
  47.  * 
  48.  * Revision 3.6  83/01/15  17:52:40  wft
  49.  * Expanded mainprogram to handle multiple RCS files.
  50.  *
  51.  * Revision 3.5  83/01/06  09:33:45  wft
  52.  * Fixed passing of -c (context) option to diff.
  53.  *
  54.  * Revision 3.4  82/12/24  15:28:38  wft
  55.  * Added call to catchsig().
  56.  *
  57.  * Revision 3.3  82/12/10  16:08:17  wft
  58.  * Corrected checking of return code from diff; improved error msgs.
  59.  *
  60.  * Revision 3.2  82/12/04  13:20:09  wft
  61.  * replaced getdelta() with gettree(). Changed diagnostics.
  62.  *
  63.  * Revision 3.1  82/11/28  19:25:04  wft
  64.  * Initial revision.
  65.  *
  66.  */
  67. #include <ctype.h>
  68. #include "rcsbase.h"
  69. #define ERRCODE 2                   /*error code for exit status            */
  70. #ifndef lint
  71. static char rcsbaseid[] = RCSBASE;
  72. #endif
  73.  
  74. extern int    cleanup();            /* cleanup after signals                */
  75. extern char * mktempfile();         /*temporary file name generator         */
  76. extern int    fterror();            /*forward for special fatal error func. */
  77. extern struct hshentry * genrevs(); /*generate delta numbers                */
  78. extern int    nerror;               /*counter for errors                    */
  79. extern int    quietflag;            /*suppresses diagnostics                */
  80. extern FILE * finptr;               /* RCS input file                       */
  81.  
  82. char *RCSfilename;
  83. char *workfilename;
  84. char * temp1file, * temp2file;
  85.  
  86. char bops[10] = "-";
  87. char otherops[10] = "-";
  88.  
  89. char    tmpdir[80];
  90.  
  91. main (argc, argv)
  92. int argc; char **argv;
  93. {
  94.         char * cmdusage;
  95.         char command[NCPPN+revlength+40];
  96.         int  revnums;                 /* counter for revision numbers given */
  97.         char * rev1, * rev2;          /* revision numbers from command line */
  98.         char numericrev[revlength];   /* holds expanded revision number     */
  99.         char * xrev1, * xrev2;        /* expanded revision numbers          */
  100.         struct hshentry * gendeltas[hshsize];/*stores deltas to be generated*/
  101.         struct hshentry * target;
  102.     char * boption, * otheroption;
  103.         int  exit_stats;
  104.         int  filecounter;
  105.     char *argp;
  106.     register c;
  107.  
  108.     cmdusage = getenv("TMPDIR");
  109.     if (cmdusage == NULL) {
  110.         cmdusage = "/dd/tmp";
  111.     }
  112.     strcpy(tmpdir,cmdusage);
  113.     strcat(tmpdir,"/");
  114.  
  115.         catchints();
  116.         otheroption = otherops + 1;
  117.     boption = bops + 1;
  118.         cmdid = "rcsdiff";
  119.     cmdusage = "command format:\n    rcsdiff [-biwt] [-q] [-cefhn] [-rrev1] [-rrev2] file";
  120.         filecounter=revnums=0;
  121.         while (--argc,++argv, argc>=1 && ((*argv)[0] == '-')) {
  122.         argp = &((*argv)[1]);
  123.         while (c = *argp++) switch (c) {
  124.                 case 'r':
  125.                 if (*argp!='\0') {
  126.                             if (revnums==0) {
  127.                                     rev1= argp; revnums=1;
  128.                             } elif (revnums==1) {
  129.                                     rev2= argp; revnums=2;
  130.                             } else {
  131.                     fterror("too many revision numbers");
  132.                             }
  133.                         } /* do nothing for empty -r */
  134.             argp += strlen(argp);
  135.                         break;
  136.                 case 'b':
  137.                 case 'i':
  138.                 case 'w':
  139.                 case 't':
  140.             *boption++ = c;
  141.             break;
  142.         case 'q':
  143.             quietflag=true;
  144.             break;
  145.                 case 'c':
  146.                 case 'e':
  147.                 case 'f':
  148.                 case 'h':
  149.                 case 'n':
  150.                         if (otheroption == otherops + 1) {
  151.                 *otheroption++ = c;
  152.                 if (c == 'c' && isdigit(*argp)) {
  153.                     while (isdigit(*argp))
  154.                         *otheroption++ = *argp++;
  155.                     if (*argp)
  156.                         faterror("-c: bad count");
  157.                     argp = "";
  158.                 }
  159.                         } else {
  160.                 fterror("Options c,e,f,h,n are mutually exclusive");
  161.                         }
  162.             break;
  163.                 default:
  164.             fterror("unknown option: %s\n%s", *argv,cmdusage);
  165.                 };
  166.         } /* end of option processing */
  167.  
  168.     if (boption != bops + 1) {
  169.          *boption = ' ';
  170.         boption = bops;
  171.     }
  172.     if (otheroption != otherops + 1) {
  173.          *otheroption = ' ';
  174.         otheroption = otherops;
  175.     }
  176.     if (argc<1) fterror("No input file\n%s",cmdusage);
  177.  
  178.         /* now handle all filenames */
  179.         do {
  180.                 finptr=NULL;
  181.  
  182.                 if (pairfilenames(argc,argv,true,false)!=1) continue;
  183.                 if (++filecounter>1)
  184.                         diagnose("===================================================================");
  185.                 diagnose("RCS file: %s",RCSfilename);
  186.                 if (revnums<2 && !(access(workfilename,1)==0)) {
  187.                         error("Can't open %s",workfilename);
  188.                         continue;
  189.                 }
  190.                 if (!trysema(RCSfilename,false)) continue; /* give up */
  191.  
  192.  
  193.                 gettree(); /* reads in the delta tree */
  194.  
  195.                 if (Head==nil) {
  196.                         error("no revisions present");
  197.                         continue;
  198.                 }
  199.                 if (revnums==0)
  200.                         rev1=Dbranch!=nil?Dbranch->num:Head->num; /* default rev1 */
  201.  
  202.                 if (!expandsym(rev1,numericrev)) continue;
  203.                 if (!(target=genrevs(numericrev,(char *)nil,(char *)nil,(char *)nil,gendeltas))) continue;
  204.                 xrev1=target->num;
  205.  
  206.                 if (revnums==2) {
  207.                         if (!expandsym(rev2,numericrev)) continue;
  208.                         if (!(target=genrevs(numericrev,(char *)nil,(char *)nil,(char *)nil,gendeltas))) continue;
  209.                         xrev2=target->num;
  210.                 }
  211.  
  212.  
  213.                 temp1file=mktempfile(tmpdir,TMPFILE1);
  214.                 diagnose("retrieving revision %s",xrev1);
  215.                 VOID sprintf(command,"%s/co -q -p%s %s >-%s\n",
  216.                         TARGETDIR,xrev1,RCSfilename,temp1file);
  217.                 if (system(command)){
  218.                         error("co failed");
  219.                         continue;
  220.                 }
  221.                 if (revnums<=1) {
  222.                         temp2file=workfilename;
  223.                         diagnose("diff %s%s-r%s %s",boption,otheroption,xrev1,workfilename);
  224.                 } else {
  225.                         temp2file=mktempfile(tmpdir,TMPFILE2);
  226.                         diagnose("retrieving revision %s",xrev2);
  227.                         VOID sprintf(command,"%s/co -q -p%s %s >-%s\n",
  228.                                 TARGETDIR,xrev2,RCSfilename,temp2file);
  229.                         if (system(command)){
  230.                                 error("co failed");
  231.                                 continue;
  232.                         }
  233.                         diagnose("diff %s%s-r%s -r%s",boption,otheroption,xrev1,xrev2);
  234.                 }
  235.                 VOID sprintf(command,"%s %s%s%s %s\n",DIFF,boption,
  236.                         otheroption, temp1file, temp2file);
  237.                 exit_stats = system (command);
  238.                 if (exit_stats != 0 && exit_stats != 1) {
  239.                         error ("diff failed");
  240.                         continue;
  241.                 }
  242.         } while (cleanup(),
  243.                  ++argv, --argc >=1);
  244.  
  245.  
  246.     if (nerror>0) {
  247.         exit(ERRCODE);
  248.     } else {
  249.         exit(exit_stats);
  250.         /* return exit status from diff */
  251.     }
  252.  
  253. }
  254.  
  255.  
  256. /*VARARGS3*/
  257. fterror(e, e1, e2)
  258. char * e, * e1, * e2;
  259. /* prints error message and terminates program with ERRCODE */
  260. {       nerror++;
  261.         VOID fprintf(stderr,"%s error: ",cmdid);
  262.     VOID fprintf(stderr,e, e1, e2);
  263.         VOID fprintf(stderr,"\n%s aborted\n",cmdid);
  264.         VOID cleanup();
  265.     exit(ERRCODE);
  266. }
  267.  
  268.