# 2.11BSD#431 - /usr/src/new/rcs/src/rcsgen.c

##### Functions

    buildrevision     X
    putdesc           X
    scandeltatext     X

##### Variables

    curlogmsg         X
    stdinread         X

##### enums's

    stringwork        X

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

#### Defined functions

buildrevision defined in line 110; used 5 times

- in /usr/src/new/rcs/src/ci.c line 124, 448, 464
- in /usr/src/new/rcs/src/co.c line 111, 323

putdesc defined in line 218; used 2 times

- in /usr/src/new/rcs/src/ci.c line 433
- in /usr/src/new/rcs/src/rcs.c line 538

scandeltatext defined in line 171; used 6 times

- in line 134-138(2), 146-154(3), 161

#### Defined variables

curlogmsg defined in line 102; used 6 times

- in line 189-190(2)
- in /usr/src/new/rcs/src/rcs.c line 834-835(2), 1479-1482(2)

rcsid defined in line 5; never used
stdinread defined in line 216; used 4 times

- in line 272-274(2)
- in /usr/src/new/rcs/src/ci.c line 906-908(2)

#### Defined enum's

stringwork defined in line 104; used 2 times

- in line 172(2)

Last modified: 1988-04-25 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1011 |