|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.