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

Defined functions

buildrevision defined in line 78; used 5 times
putdesc defined in line 184; used 2 times
scandeltatext defined in line 139; used 6 times

Defined variables

curlogmsg defined in line 69; used 6 times
rcsid defined in line 4; never used

Defined enum's

stringwork defined in line 72; used 2 times
  • in line 140(2)
Last modified: 1986-05-15
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1214
Valid CSS Valid XHTML 1.0 Strict