Annotation of 43BSDReno/contrib/rcs/src/rcsgen.c, revision 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.