Annotation of 43BSDTahoe/new/rcs/src/rcsgen.c, revision 1.1.1.1

1.1       root        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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.