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

  1. /*
  2.  *                     RCS revision generation
  3.  */
  4. #ifndef lint
  5. static char rcsid[]= "$Id: rcsgen.c,v 4.5 87/12/18 11:43:25 narten Exp $ Purdue CS";
  6. #endif
  7. /*********************************************************************************
  8.  *********************************************************************************
  9.  *
  10.  * Copyright (C) 1982 by Walter F. Tichy
  11.  *                       Purdue University
  12.  *                       Computer Science Department
  13.  *                       West Lafayette, IN 47907
  14.  *
  15.  * All rights reserved. No part of this software may be sold or distributed
  16.  * in any form or by any means without the prior written permission of the
  17.  * author.
  18.  * Report problems and direct all inquiries to Tichy@purdue (ARPA net).
  19.  */
  20.  
  21.  
  22. /* $Log:    rcsgen.c,v $
  23.  * Revision 4.5  87/12/18  11:43:25  narten
  24.  * additional lint cleanups, and a bug fix from the 4.3BSD version that
  25.  * keeps "ci" from sticking a '\377' into the description if you run it
  26.  * with a zero-length file as the description. (Guy Harris)
  27.  * 
  28.  * Revision 4.4  87/10/18  10:35:10  narten
  29.  * Updating version numbers. Changes relative to 1.1 actually relative to
  30.  * 4.2
  31.  * 
  32.  * Revision 1.3  87/09/24  13:59:51  narten
  33.  * Sources now pass through lint (if you ignore printf/sprintf/fprintf 
  34.  * warnings)
  35.  * 
  36.  * Revision 1.2  87/03/27  14:22:27  jenkins
  37.  * Port to suns
  38.  * 
  39.  * Revision 1.1  84/01/23  14:50:28  kcs
  40.  * Initial revision
  41.  * 
  42.  * Revision 4.2  83/12/02  23:01:39  wft
  43.  * merged 4.1 and 3.3.1.1 (clearerr(stdin)).
  44.  * 
  45.  * Revision 4.1  83/05/10  16:03:33  wft
  46.  * Changed putamin() to abort if trying to reread redirected stdin.
  47.  * Fixed getdesc() to output a prompt on initial newline.
  48.  * 
  49.  * Revision 3.3.1.1  83/10/19  04:21:51  lepreau
  50.  * Added clearerr(stdin) for re-reading description from stdin.
  51.  * 
  52.  * Revision 3.3  82/11/28  21:36:49  wft
  53.  * 4.2 prerelease
  54.  * 
  55.  * Revision 3.3  82/11/28  21:36:49  wft
  56.  * Replaced ferror() followed by fclose() with ffclose().
  57.  * Putdesc() now suppresses the prompts if stdin
  58.  * is not a terminal. A pointer to the current log message is now
  59.  * inserted into the corresponding delta, rather than leaving it in a
  60.  * global variable.
  61.  *
  62.  * Revision 3.2  82/10/18  21:11:26  wft
  63.  * I added checks for write errors during editing, and improved
  64.  * the prompt on putdesc().
  65.  *
  66.  * Revision 3.1  82/10/13  15:55:09  wft
  67.  * corrected type of variables assigned to by getc (char --> int)
  68.  */
  69.  
  70.  
  71.  
  72.  
  73. #include "rcsbase.h"
  74.  
  75. extern struct hshentry * getnum();
  76. extern char * mktemp();
  77. extern FILE * fopen();
  78. extern savestring();
  79. extern struct hshentry * genrevs();
  80. extern editstring();
  81.  
  82. extern int nextc;          /* next character from lexical analyzer          */
  83. extern char * RCSfilename, * workfilename;
  84. extern struct hshentry * targetdelta; /* delta to be generated              */
  85. extern char * Ktext;       /* keywords from syntax analyzer                 */
  86. extern char * Klog;        /* Keyword "log"                                 */
  87. extern char * Kdesc;       /* Keyword for description                       */
  88. extern FILE * finptr;      /* RCS input file                                */
  89. extern FILE * frewrite;    /* new RCS file                                  */
  90. extern FILE * fcopy;       /* result file during editing                    */
  91. extern FILE * fedit;       /* edit file                                     */
  92. extern char * resultfile, *editfile;/* file names for fcopy and fedit       */
  93. extern int    rewriteflag; /* indicates whether to rewrite the input file   */
  94.  
  95.  
  96. char    curlogmsg[logsize] /* buffer for current log message                */
  97.         = {'\0'};
  98.  
  99. enum stringwork {copy, edit, expand, edit_expand };
  100. /* parameter to scandeltatext() */
  101.  
  102.  
  103. extern    char    tmpdir[80];
  104.  
  105.  
  106. char * buildrevision(deltas, target, dir, expandflag)
  107. struct hshentry ** deltas, * target;
  108. char * dir; int expandflag;
  109. /* Function: Generates the revision given by target
  110.  * by retrieving all deltas given by parameter deltas and combining them.
  111.  * If dir==nil, the revision is printed on the standard output,
  112.  * otherwise written into a temporary file in directory dir.
  113.  * if expandflag==true, keyword expansion is performed.
  114.  * returns false on errors, the name of the file with the revision otherwise.
  115.  *
  116.  * Algorithm: Copy inital revision unchanged. Then edit all revisions but
  117.  * the last one into it, alternating input and output files (resultfile and
  118.  * editfile). The last revision is then edited in, performing simultaneous
  119.  * keyword substitution (this saves one extra pass).
  120.  * All this simplifies if only one revision needs to be generated,
  121.  * or no keyword expansion is necessary, or if output goes to stdout.
  122.  */
  123. {
  124.         int i;
  125.  
  126.         if (deltas[0]==target) {
  127.                 /* only latest revision to generate */
  128.                 if (dir==nil) {/* print directly to stdout */
  129.                         fcopy=stdout;
  130.                         scandeltatext(target,expand);
  131.                         return(char *) true;
  132.                 } else {
  133.                         initeditfiles(dir);
  134.                         scandeltatext(target,expandflag?expand:copy);
  135.                         ffclose(fcopy);
  136.                         return(resultfile);
  137.                 }
  138.         } else {
  139.                 /* several revisions to generate */
  140.                 initeditfiles(dir?dir:tmpdir);
  141.                 /* write initial revision into fcopy, no keyword expansion */
  142.                 scandeltatext(deltas[0],copy);
  143.                 i = 1;
  144.                 while (deltas[i+1] != nil) {
  145.                         /* do all deltas except last one */
  146.                         scandeltatext(deltas[i++],edit);
  147.                 }
  148.                 if (!expandflag) {
  149.                         /* no keyword expansion; only invoked from ci */
  150.                         scandeltatext(deltas[i],edit);
  151.                         finishedit((struct hshentry *)nil);
  152.                         ffclose(fcopy);
  153.                 } else {
  154.                         /* perform keyword expansion*/
  155.                         /* first, get to beginning of file*/
  156.                         finishedit((struct hshentry *)nil); swapeditfiles(dir==nil);
  157.                         scandeltatext(deltas[i],edit_expand);
  158.                         finishedit(deltas[i]);
  159.                         if (dir!=nil) ffclose(fcopy);
  160.                 }
  161.                 return(resultfile); /*doesn't matter for dir==nil*/
  162.         }
  163. }
  164.  
  165.  
  166.  
  167. scandeltatext(delta,func)
  168. struct hshentry * delta; enum stringwork func;
  169. /* Function: Scans delta text nodes up to and including the one given
  170.  * by delta. For the one given by delta, the log message is saved into
  171.  * curlogmsg and the text is processed according to parameter func.
  172.  * Assumes the initial lexeme must be read in first.
  173.  * Does not advance nexttok after it is finished.
  174.  */
  175. {       struct hshentry * nextdelta;
  176.  
  177.         do {
  178.                 nextlex();
  179.                 if (!(nextdelta=getnum())) {
  180.                         fatserror("Can't find delta for revision %s", delta->num);
  181.                 }
  182.                 if (!getkey(Klog) || nexttok!=STRING)
  183.                         serror("Missing log entry");
  184.                 elsif (delta==nextdelta) {
  185.                         VOID savestring(curlogmsg,logsize);
  186.                         delta->log=curlogmsg;
  187.                 } else {readstring();
  188.                         delta->log= "";
  189.                 }
  190.                 nextlex();
  191.                 if (!getkey(Ktext) || nexttok!=STRING)
  192.                         fatserror("Missing delta text");
  193.  
  194.                 if(delta==nextdelta)
  195.                         /* got the one we're looking for */
  196.                         switch (func) {
  197.                         case copy:      copystring();
  198.                                         break;
  199.                         case expand:    xpandstring(delta);
  200.                                         break;
  201.                         case edit:      editstring((struct hshentry *)nil);
  202.                                         break;
  203.                         case edit_expand: editstring(delta);
  204.                                         break;
  205.                         }
  206.                 else    readstring(); /* skip over it */
  207.  
  208.         } while (delta!=nextdelta);
  209. }
  210.  
  211.  
  212. int stdinread = 0; /* stdinread>0 if redirected stdin has been read once */
  213.  
  214. int putdesc(initflag,textflag,textfile,quietflag)
  215. int initflag,textflag; char * textfile; int quietflag;
  216. /* Function: puts the descriptive text into file frewrite.
  217.  * if !initflag && !textflag, the text is simply copied from finptr.
  218.  * Otherwise, if the textfile!=nil, the text is read from that
  219.  * file, or from stdin, if textfile==nil.
  220.  * Increments stdinread if text is read from redirected stdin.
  221.  * if initflag&&quietflag&&!textflag, an empty text is inserted.
  222.  * if !initflag, the old descriptive text is discarded.
  223.  * Returns true is successful, false otherwise.
  224.  */
  225. {       FILE * txt; register int c, old1, old2;
  226. #ifdef lint
  227.     if (quietflag ==  0) initflag = quietflag; /* silencelint */
  228. #endif    
  229.         if (!initflag && !textflag) {
  230.                 /* copy old description */
  231.                 VOID fprintf(frewrite,"\n\n%s%c",Kdesc,nextc);
  232.                 rewriteflag=true; getdesc(false);
  233.                 return true;
  234.         } else {
  235.                 /* get new description */
  236.                if (!initflag) {
  237.                         /*skip old description*/
  238.                         rewriteflag=false; getdesc(false);
  239.                 }
  240.                 VOID fprintf(frewrite,"\n\n%s\n%c",Kdesc,SDELIM);
  241.                 if (textfile) {
  242.                         old1='\n';
  243.                         /* copy textfile */
  244.                         if ((txt=fopen(textfile,"r"))!=NULL) {
  245.                                 while ((c=getc(txt))!=EOF) {
  246.                                         if (c==SDELIM) VOID putc(c,frewrite); /*double up*/
  247.                                         VOID putc(c,frewrite);
  248.                                         old1=c;
  249.                                 }
  250.                                 if (old1!='\n') VOID putc('\n',frewrite);
  251.                                 VOID fclose(txt);
  252.                                 VOID putc(SDELIM,frewrite);
  253.                 VOID fputs("\n\n", frewrite);
  254.                                 return true;
  255.                         } else {
  256.                                 error("Can't open file %s with description",textfile);
  257.                                 if (!isatty(fileno(stdin))) return false;
  258.                                 /* otherwise, get description from terminal */
  259.                         }
  260.                 }
  261.                 /* read text from stdin */
  262.                 if (isatty(fileno(stdin))) {
  263.                     VOID fputs("enter description, terminated with <eof> or '.':\n",stderr);
  264.                     VOID fputs("NOTE: This is NOT the log message!\n>> ",stderr);
  265.                     fflush(stderr);
  266.             if (feof(stdin))
  267.                     cleareof(stdin),clearerr(stdin);
  268.                 } else {  /* redirected stdin */
  269.                     if (stdinread>0)
  270.                         faterror("Can't reread redirected stdin for description; use -t<file>");
  271.                     stdinread++;
  272.                 }
  273.                 c = '\0'; old2= '\n';
  274.                 if ((old1=getchar())==EOF) {
  275.                         if (isatty(fileno(stdin))) {
  276.                              VOID putc('\n',stderr);
  277.                              cleareof(stdin),clearerr(stdin);
  278.             }
  279.         } else {
  280.              if (old1=='\n' && isatty(fileno(stdin)))
  281.              VOID fputs(">> ",stderr);
  282.              fflush(stderr);
  283.              for (;;) {
  284.                             c=getchar();
  285.                             if (c==EOF) {
  286.                                     if (isatty(fileno(stdin))) {
  287.                                             VOID putc('\n',stderr);
  288.                                             cleareof(stdin),clearerr(stdin);
  289.                     }
  290.                                     VOID putc(old1,frewrite);
  291.                                     if (old1!='\n') VOID putc('\n',frewrite);
  292.                                     break;
  293.                             }
  294.                             if (c=='\n' && old1=='.' && old2=='\n') {
  295.                                     break;
  296.                             }
  297.                             if (c=='\n' && isatty(fileno(stdin))) { VOID fputs(">> ",stderr); fflush(stderr); }
  298.                             if(old1==SDELIM) VOID putc(old1,frewrite); /* double up*/
  299.                             VOID putc(old1,frewrite);
  300.                             old2=old1;
  301.                             old1=c;
  302.                     } /* end for */
  303.         }
  304.                 VOID putc(SDELIM,frewrite);VOID fputs("\n\n",frewrite);
  305.                 return true;
  306.         }
  307. }
  308.