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

unix.superglobalmegacorp.com

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