Annotation of 43BSD/contrib/rcs/src/rcssyn.c, revision 1.1

1.1     ! root        1: 
        !             2: /*
        !             3:  *                     RCS file input
        !             4:  */
        !             5:  static char rcsid[]=
        !             6:  "$Header: /usr/wft/RCS/SRC/RCS/rcssyn.c,v 3.6 83/01/15 17:46:50 wft Exp $ Purdue CS";
        !             7: /*********************************************************************************
        !             8:  *                       Syntax Analysis.
        !             9:  *                       Keyword table
        !            10:  *                       Testprogram: define SYNDB
        !            11:  *                       Compatibility with Release 2: define COMPAT2
        !            12:  *********************************************************************************
        !            13:  *
        !            14:  * Copyright (C) 1982 by Walter F. Tichy
        !            15:  *                       Purdue University
        !            16:  *                       Computer Science Department
        !            17:  *                       West Lafayette, IN 47907
        !            18:  *
        !            19:  * All rights reserved. No part of this software may be sold or distributed
        !            20:  * in any form or by any means without the prior written permission of the
        !            21:  * author.
        !            22:  * Report problems and direct all inquiries to Tichy@purdue (ARPA net).
        !            23:  */
        !            24: 
        !            25: 
        !            26: /* $Log:       rcssyn.c,v $
        !            27:  * Revision 3.6  83/01/15  17:46:50  wft
        !            28:  * Changed readdelta() to initialize selector and log-pointer.
        !            29:  * Changed puttree to check for selector==DELETE; putdtext() uses DELNUMFORM.
        !            30:  * 
        !            31:  * Revision 3.5  82/12/08  21:58:58  wft
        !            32:  * renamed Commentleader to Commleader.
        !            33:  *
        !            34:  * Revision 3.4  82/12/04  13:24:40  wft
        !            35:  * Added routine gettree(), which updates keeplock after reading the
        !            36:  * delta tree.
        !            37:  *
        !            38:  * Revision 3.3  82/11/28  21:30:11  wft
        !            39:  * Reading and printing of Suffix removed; version COMPAT2 skips the
        !            40:  * Suffix for files of release 2 format. Fixed problems with printing nil.
        !            41:  *
        !            42:  * Revision 3.2  82/10/18  21:18:25  wft
        !            43:  * renamed putdeltatext to putdtext.
        !            44:  *
        !            45:  * Revision 3.1  82/10/11  19:45:11  wft
        !            46:  * made sure getc() returns into an integer.
        !            47:  */
        !            48: 
        !            49: 
        !            50: 
        !            51: /*
        !            52: #define COMPAT2
        !            53: /* version COMPAT2 reads files of the format of release 2 and 3, but
        !            54:  * generates files of release 3 format. Need not be defined if no
        !            55:  * old RCS files generated with release 2 exist.
        !            56:  */
        !            57: /*
        !            58: #define SYNDB
        !            59: /* version SYNDB is for debugging the syntax analysis for RCS files.
        !            60:  * SYNDB performs additional error checks.
        !            61:  */
        !            62: /*
        !            63: #define SYNTEST
        !            64: /* version SYNTEST inputs a RCS file and then prints out its internal
        !            65:  * data structures.
        !            66: */
        !            67: 
        !            68: #include "rcsbase.h"
        !            69: extern FILE * finptr;        /*RCS input file*/
        !            70: extern char * getid();
        !            71: extern struct hshentry * getnum();
        !            72: extern int    getkey();
        !            73: extern int    getlex();
        !            74: extern char * malloc();
        !            75: extern        readstring();
        !            76: extern int    savestring();
        !            77: 
        !            78: /* forward */
        !            79: char * getkeyval();
        !            80: int delta();
        !            81: 
        !            82: /* keyword table */
        !            83: 
        !            84: char * Kaccess     = "access";
        !            85: char * Kauthor     = "author";
        !            86: char * Kbranches   = "branches";
        !            87: char * Kcomment    = "comment";
        !            88: char * Kdate       = "date";
        !            89: char * Kdesc       = "desc";
        !            90: char * Khead       = "head";
        !            91: char * Klocks      = "locks";
        !            92: char * Klog        = "log";
        !            93: char * Knext       = "next";
        !            94: char * Kstate      = "state";
        !            95: char * Kstrict     = "strict";
        !            96: char * Ksuffix     = "suffix";
        !            97: char * Ksymbols    = "symbols";
        !            98: char * Ktext       = "text";
        !            99: 
        !           100: #define COMMLENGTH 20
        !           101: char              Commleader[COMMLENGTH];
        !           102: char            * Comment    = "";
        !           103: struct access   * AccessList =nil;
        !           104: struct access   * LastAccess =nil;
        !           105: struct assoc    * Symbols    =nil;
        !           106: struct assoc    * LastSymbol =nil;
        !           107: struct lock     * Locks      =nil;
        !           108: struct lock     * LastLock   =nil;
        !           109: int               StrictLocks=false;
        !           110: struct hshentry * Head       =nil;
        !           111: int               TotalDeltas=0;
        !           112: 
        !           113: 
        !           114: 
        !           115: getadmin()
        !           116: /* Function: Reads an <admin> and initializes the globals
        !           117:  * AccessList, LastAccess, Symbols, LastSymbol,
        !           118:  * Locks, LastLock, StrictLocks, Head, Comment, TotalDeltas;
        !           119:  */
        !           120: {
        !           121:         register char   * id;
        !           122:         struct access   * newaccess;
        !           123:         struct assoc    * newassoc;
        !           124:         struct lock     * newlock;
        !           125:         struct hshentry * delta;
        !           126: 
        !           127:         Comment="";
        !           128:         AccessList=LastAccess=nil;
        !           129:         Symbols=LastSymbol=nil;
        !           130:         Locks=LastLock=nil;
        !           131:         Head = nil;
        !           132:         TotalDeltas=0;
        !           133: 
        !           134:         if (!getkey(Khead)) fatserror("Missing head");
        !           135:         Head=getnum();
        !           136: #       ifdef SYNDB
        !           137:         if (Head&&((countnumflds(Head->num)%2)!=0))
        !           138:                 serror("Delta number required for head");
        !           139: #       endif
        !           140:         if (!getlex(SEMI)) serror("Missing ';' after head");
        !           141: 
        !           142: #ifdef COMPAT2
        !           143:         /* read suffix. Only in release 2 format */
        !           144:         if (getkey(Ksuffix)) {
        !           145:                 if (nexttok==STRING) {
        !           146:                         readstring(); nextlex(); /*through away the suffix*/
        !           147:                 } elsif(nexttok==ID) {
        !           148:                         nextlex();
        !           149:                 }
        !           150:                 if (!getlex(SEMI)) serror("Missing ';' after %s",Ksuffix);
        !           151:         }
        !           152: #endif
        !           153: 
        !           154:         if (!getkey(Kaccess)) fatserror("Missing access list");
        !           155:         while (id=getid()) {
        !           156:                 newaccess = (struct access *)malloc(sizeof(struct access));
        !           157:                 newaccess->login = id;
        !           158:                 newaccess->nextaccess = nil;
        !           159:                 if (AccessList == nil) {
        !           160:                         AccessList=LastAccess=newaccess;
        !           161:                 } else {
        !           162:                         LastAccess=LastAccess->nextaccess=newaccess;
        !           163:                 }
        !           164:         }
        !           165:         if (!getlex(SEMI)) serror("Missing ';' after access list");
        !           166: 
        !           167:         if (!getkey(Ksymbols)) fatserror("Missing symbols");
        !           168:         while (id = getid()) {
        !           169:                 if (!getlex(COLON))
        !           170:                         serror("Missing ':' in symbolic name definition");
        !           171:                 if (!(delta=getnum())) {
        !           172:                         serror("Missing number in symbolic name definition");
        !           173:                 } else { /*add new pair to association list*/
        !           174:                         newassoc=(struct assoc *)malloc(sizeof(struct assoc));
        !           175:                         newassoc->symbol=id;
        !           176:                         newassoc->delta=delta;
        !           177:                         newassoc->nextassoc=nil;
        !           178:                         if (Symbols == nil) {
        !           179:                                 Symbols=LastSymbol=newassoc;
        !           180:                         } else {
        !           181:                                 LastSymbol=LastSymbol->nextassoc=newassoc;
        !           182:                         }
        !           183:                 }
        !           184:         }
        !           185:         if (!getlex(SEMI)) serror("Missing ';' after symbolic names");
        !           186: 
        !           187:         if (!getkey(Klocks)) serror("Missing locks");
        !           188:         while (id = getid()) {
        !           189:                 if (!getlex(COLON))
        !           190:                         serror("Missing ':' in lock");
        !           191:                 if (!(delta=getnum())) {
        !           192:                         serror("Missing number in lock");
        !           193:                 } else { /*add new pair to lock list*/
        !           194: #                       ifdef SYNDB
        !           195:                         if ((countnumflds(delta->num)%2)!=0)
        !           196:                                 serror("Delta number required for lock");
        !           197: #                       endif
        !           198:                         newlock=(struct lock *)malloc(sizeof(struct lock));
        !           199:                         newlock->login=id;
        !           200:                         newlock->delta=delta;
        !           201:                         newlock->nextlock=nil;
        !           202:                         if (Locks == nil) {
        !           203:                                 Locks=LastLock=newlock;
        !           204:                         } else {
        !           205:                                 LastLock=LastLock->nextlock=newlock;
        !           206:                         }
        !           207:                 }
        !           208:         }
        !           209:         if (!getlex(SEMI)) serror("Missing ';' after locks");
        !           210:         if (!getkey(Kstrict)) {
        !           211:                 StrictLocks = false;
        !           212:         } else {
        !           213:                 StrictLocks = true;
        !           214:                 if (!getlex(SEMI)) serror("Missing ';' after keyword %s",Kstrict);
        !           215:         }
        !           216:         if (getkey(Kcomment) && (nexttok==STRING)) {
        !           217:                 savestring(Commleader,COMMLENGTH);nextlex();
        !           218:                 Comment=Commleader;
        !           219:                 if (!getlex(SEMI)) serror("Missing ';' after %s",Kcomment);
        !           220:         }
        !           221: }
        !           222: 
        !           223: 
        !           224: 
        !           225: getdelta()
        !           226: /* Function: reads a delta block.
        !           227:  * returns false if the current block does not start with a number.
        !           228:  */
        !           229: {
        !           230:         register struct hshentry * Delta, * num;
        !           231:         struct branchhead * LastBranch, * NewBranch;
        !           232: 
        !           233:         if (!(Delta=getnum())) return false;
        !           234: #       ifdef SYNDB
        !           235:         if ((countnumflds(Delta->num)%2)!=0)
        !           236:                 serror("Delta number required");
        !           237: #       endif
        !           238: 
        !           239:         hshenter = false; /*Don't enter dates into hashtable*/
        !           240:         Delta->date = getkeyval(Kdate, NUM, false);
        !           241:         hshenter=true;    /*reset hshenter for revision numbers.*/
        !           242: 
        !           243:         Delta->author = getkeyval(Kauthor, ID, false);
        !           244: 
        !           245:         Delta->state = getkeyval(Kstate, ID, true);
        !           246: 
        !           247:         if (!getkey(Kbranches)) fatserror("Missing branches");
        !           248:         Delta->branches = LastBranch=nil;
        !           249:         while (num=getnum()) {
        !           250: #               ifdef SYNDB
        !           251:                 if ((countnumflds(num->num)%2)!=0)
        !           252:                         serror("Delta number required");
        !           253: #               endif
        !           254:                 NewBranch = (struct branchhead *)malloc(sizeof(struct branchhead));
        !           255:                 NewBranch->hsh = num;
        !           256:                 NewBranch->nextbranch = nil;
        !           257:                 if (LastBranch == nil) {
        !           258:                         Delta->branches=LastBranch=NewBranch;
        !           259:                 } else {
        !           260:                         LastBranch=LastBranch->nextbranch=NewBranch;
        !           261:                 }
        !           262:         }
        !           263:         if (!getlex(SEMI)) serror("Missing ';' after branches");
        !           264: 
        !           265:         if (!getkey(Knext)) fatserror("Missing next");
        !           266:         Delta->next=num=getnum();
        !           267: #       ifdef SYNDB
        !           268:         if (num&&((countnumflds(num->num)%2)!=0))
        !           269:                 serror("Delta number required");
        !           270: #       endif
        !           271:         if (!getlex(SEMI)) serror("Missing ';' after next");
        !           272:         Delta->log=Delta->lockedby = nil;
        !           273:         Delta->selector = '\0';
        !           274:         TotalDeltas++;
        !           275:         return (true);
        !           276: }
        !           277: 
        !           278: 
        !           279: gettree()
        !           280: /* Function: Reads in the delta tree with getdelta(), then
        !           281:  * updates the lockedby fields. Returns the total number of deltas read.
        !           282:  */
        !           283: {       struct lock * currlock;
        !           284:         while (getdelta());
        !           285:         currlock=Locks;
        !           286:         while (currlock) {
        !           287:                 currlock->delta->lockedby = currlock->login;
        !           288:                 currlock = currlock->nextlock;
        !           289:         }
        !           290:         return TotalDeltas;
        !           291: }
        !           292: 
        !           293: 
        !           294: getdesc(prdesc)
        !           295: int  prdesc;
        !           296: /* Function: read in descriptive text
        !           297:  * nexttok is not advanced afterwards.
        !           298:  * if prdesc==true, the text is printed to stdout.
        !           299:  */
        !           300: {
        !           301: 
        !           302:         if (!getkey(Kdesc) || (nexttok!=STRING)) fatserror("Missing descriptive text");
        !           303:         if (prdesc)
        !           304:                 printstring();  /*echo string*/
        !           305:         else    readstring();   /*skip string*/
        !           306: }
        !           307: 
        !           308: 
        !           309: 
        !           310: 
        !           311: 
        !           312: 
        !           313: char * getkeyval(keyword, token, optional)
        !           314: enum tokens token; char * keyword; int optional;
        !           315: /* reads a pair of the form
        !           316:  * <keyword> <token> ;
        !           317:  * where token is one of <id> or <num>. optional indicates whether
        !           318:  * <token> is optional. A pointer to
        !           319:  * the acutal character string of <id> or <num) is returned.
        !           320:  * Getkeyval terminates the program on missing keyword or token, continues
        !           321:  * on missing ;.
        !           322:  */
        !           323: {
        !           324:         register char * val;
        !           325: 
        !           326:         if (!getkey(keyword)) {
        !           327:                 fatserror("Missing %s", keyword);
        !           328:         }
        !           329:         if (nexttok==token) {
        !           330:                 val = NextString;
        !           331:                 nextlex();
        !           332:         } else {
        !           333:                 if (!optional) {fatserror("Missing %s", keyword); }
        !           334:                 else val = nil;
        !           335:         }
        !           336:         if (!getlex(SEMI)) serror("Missing ';' after %s",keyword);
        !           337:         return(val);
        !           338: }
        !           339: 
        !           340: 
        !           341: 
        !           342: 
        !           343: putadmin(fout)
        !           344: register FILE * fout;
        !           345: /* Function: Print the <admin> node read with getadmin() to file fout.
        !           346:  * Assumption: Variables AccessList, Symbols, Locks, StrictLocks,
        !           347:  * and Head have been set.
        !           348:  */
        !           349: {       struct assoc  * curassoc;
        !           350:         struct lock   * curlock;
        !           351:         struct access * curaccess;
        !           352:         register char * sp;
        !           353: 
        !           354:         fputs(Khead,fout); fputs("     ",fout);
        !           355:         if (Head) fputs(Head->num,fout);
        !           356: 
        !           357:         fprintf(fout,";\n%s  ",Kaccess);
        !           358:         curaccess = AccessList;
        !           359:         if (curaccess==nil) putc(' ',fout);
        !           360:         while (curaccess) {
        !           361:                putc(' ',fout);
        !           362:                fputs(curaccess->login,fout);
        !           363:                curaccess = curaccess->nextaccess;
        !           364:         }
        !           365:         fprintf(fout,";\n%s ",Ksymbols);
        !           366:         curassoc = Symbols;
        !           367:         if (curassoc==nil) putc(' ',fout);
        !           368:         while (curassoc) {
        !           369:                fprintf(fout," %s:%s",curassoc->symbol, curassoc->delta->num);
        !           370:                curassoc = curassoc->nextassoc;
        !           371:         }
        !           372:         fprintf(fout,";\n%s   ",Klocks);
        !           373:         curlock = Locks;
        !           374:         if (curlock==nil) putc(' ',fout);
        !           375:         while (curlock) {
        !           376:                fprintf(fout," %s:%s",curlock->login, curlock->delta->num);
        !           377:                curlock = curlock->nextlock;
        !           378:         }
        !           379:         if (StrictLocks) fprintf(fout,"; %s",Kstrict);
        !           380:         fprintf(fout,";\n%s  %c",Kcomment,SDELIM);
        !           381:         if((sp=Comment)!=nil) {
        !           382:                while (*sp) if (putc(*sp++,fout)==SDELIM) putc(SDELIM,fout);
        !           383:         }
        !           384:         fprintf(fout,"%c;\n\n",SDELIM);
        !           385: }
        !           386: 
        !           387: 
        !           388: 
        !           389: 
        !           390: putdelta(node,fout)
        !           391: register struct hshentry * node;
        !           392: register FILE * fout;
        !           393: /* Function: prints a <delta> node to fout;
        !           394:  */
        !           395: {      struct branchhead * nextbranch;
        !           396: 
        !           397:         if (node == nil) return;
        !           398: 
        !           399:         fprintf(fout,"\n%s\n",node->num);
        !           400:         fprintf(fout,"%s     %s;  %s %s;  %s ",
        !           401:                 Kdate,node->date,Kauthor,node->author,Kstate);
        !           402:         if (node->state!=nil) fputs(node->state,fout);
        !           403:         fputs(";\nbranches",fout);
        !           404:         nextbranch = node->branches;
        !           405:         if (nextbranch==nil) putc(' ',fout);
        !           406:         while (nextbranch) {
        !           407:                putc(' ',fout);
        !           408:                fputs(nextbranch->hsh->num,fout);
        !           409:                nextbranch = nextbranch->nextbranch;
        !           410:         }
        !           411: 
        !           412:         fprintf(fout,";\n%s     ",Knext);
        !           413:         if (node->next!=nil) fputs(node->next->num,fout);
        !           414:         fputs(";\n",fout);
        !           415: 
        !           416: }
        !           417: 
        !           418: 
        !           419: 
        !           420: 
        !           421: puttree(root,fout)
        !           422: struct hshentry * root;
        !           423: register FILE * fout;
        !           424: /* Function: prints the delta tree in preorder to fout, starting with root.
        !           425:  */
        !           426: {       struct branchhead * nextbranch;
        !           427: 
        !           428:         if (root==nil) return;
        !           429: 
        !           430:         if (root->selector !=DELETE)putdelta(root,fout);
        !           431:         /* selector DELETE means deleted; set by rcs -o */
        !           432: 
        !           433:         puttree(root->next,fout);
        !           434: 
        !           435:         nextbranch = root->branches;
        !           436:         while (nextbranch) {
        !           437:              puttree(nextbranch->hsh,fout);
        !           438:              nextbranch = nextbranch->nextbranch;
        !           439:         }
        !           440: }
        !           441: 
        !           442: 
        !           443: 
        !           444: int putdtext(num,log,srcfilename,fout)
        !           445: char * num, * log, * srcfilename; FILE * fout;
        !           446: /* Function: write a deltatext-node to fout.
        !           447:  * num points to the deltanumber, log to the logmessage, and
        !           448:  * sourcefile contains the text. Doubles up all SDELIMs in both the
        !           449:  * log and the text; Makes sure the log message ends in \n.
        !           450:  * returns false on error.
        !           451:  */
        !           452: {
        !           453:         register char * sp;
        !           454:        register int c;
        !           455:         register FILE * fin;
        !           456: 
        !           457:         fprintf(fout,DELNUMFORM,num,Klog);
        !           458:         /* put log */
        !           459:         putc(SDELIM,fout);
        !           460:         sp=log;
        !           461:         while (*sp) if (putc(*sp++,fout)==SDELIM) putc(SDELIM,fout);
        !           462:         if (*(sp-1)!='\n') putc('\n', fout); /*append \n if necessary*/
        !           463:         /* put text */
        !           464:         fprintf(fout, "%c\n%s\n%c",SDELIM,Ktext,SDELIM);
        !           465:         if ((fin=fopen(srcfilename,"r"))==NULL) {
        !           466:                 error("Can't open source file %s",srcfilename);
        !           467:                 return false;
        !           468:         }
        !           469:         while ((c=fgetc(fin))!=EOF) {
        !           470:                 if (c==SDELIM) putc(SDELIM,fout);   /*double up SDELIM*/
        !           471:                 putc(c,fout);
        !           472:         }
        !           473:         putc(SDELIM,fout);putc('\n',fout);
        !           474:         fclose(fin);
        !           475:         return true;
        !           476: }
        !           477: 
        !           478: 
        !           479: 
        !           480: #ifdef SYNTEST
        !           481: 
        !           482: main(argc,argv)
        !           483: int argc; char * argv[];
        !           484: {
        !           485: 
        !           486:         cmdid = "syntest";
        !           487:         if (argc<2) {
        !           488:                 fputs("No input file\n",stderr);
        !           489:                 exit(-1);
        !           490:         }
        !           491:         if ((finptr=fopen(argv[1], "r")) == NULL) {
        !           492:                 faterror("Can't open input file %s\n",argv[1]);
        !           493:         }
        !           494:         Lexinit();
        !           495:         getadmin();
        !           496:         putadmin(stdout);
        !           497: 
        !           498:         gettree();
        !           499:         puttree(Head,stdout);
        !           500: 
        !           501:         getdesc(true);
        !           502: 
        !           503:         if (nextlex(),nexttok!=EOFILE) {
        !           504:                 fatserror("Syntax error");
        !           505:         }
        !           506:         exit(0);
        !           507: }
        !           508: 
        !           509: 
        !           510: cleanup(){}
        !           511: /*dummy*/
        !           512: 
        !           513: 
        !           514: #endif
        !           515: 

unix.superglobalmegacorp.com

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