# 2.11BSD#431 - /usr/src/new/rcs/src/rcslex.c

##### Functions

    Lexinit           X
    checkid           X
    cleanup           X
    diagnose          X
    error             X
    faterror          X
    fatserror         X
    fflsbuf           X
    fprintf           X
    fputs             X
    getid             X
    getkey            X
    getlex            X
    getnum            X
    lookup            X
    main              X
    nextlex           X
    printstring       X
    readstring        X
    savestring        X
    serror            X
    warn              X

##### Variables

    NextString        X
    StringTab         X
    Topchar           X
    cmdid             X
    eof               X
    hshenter          X
    hshtab            X
    line              X
    map               X
    nerror            X
    nextc             X
    nexthsh           X
    nexttok           X
    nwarn             X
    quietflag         X
    rewriteflag       X

       1: /*
       2:  *                     RCS file input
       3:  */
       4: #ifndef lint
       5: static char rcsid[]= "$Id: rcslex.c,v 4.4 87/12/18 11:44:47 narten Exp $ Purdue CS";
       6: #endif
       7: /*********************************************************************************
       8:  *                     Lexical Analysis.
       9:  *                     Character mapping table,
      10:  *                     hashtable, Lexinit, nextlex, getlex, getkey,
      11:  *                     getid, getnum, readstring, printstring, savestring,
      12:  *                     checkid, serror, fatserror, error, faterror, warn, diagnose
      13:  *                     fflsbuf, puts, fprintf
      14:  *                     Testprogram: define LEXDB
      15:  *********************************************************************************
      16:  *
      17:  * Copyright (C) 1982 by Walter F. Tichy
      18:  *                       Purdue University
      19:  *                       Computer Science Department
      20:  *                       West Lafayette, IN 47907
      21:  *
      22:  * All rights reserved. No part of this software may be sold or distributed
      23:  * in any form or by any means without the prior written permission of the
      24:  * author.
      25:  * Report problems and direct all inquiries to Tichy@purdue (ARPA net).
      26:  */
      27:
      28: /* $Log:	rcslex.c,v $
      29:  * Revision 4.4  87/12/18  11:44:47  narten
      30:  * fixed to use "varargs" in "fprintf"; this is required if it is to
      31:  * work on a SPARC machine such as a Sun-4
      32:  *
      33:  * Revision 4.3  87/10/18  10:37:18  narten
      34:  * Updating version numbers. Changes relative to 1.1 actually relative
      35:  * to version 4.1
      36:  *
      37:  * Revision 1.3  87/09/24  14:00:17  narten
      38:  * Sources now pass through lint (if you ignore printf/sprintf/fprintf
      39:  * warnings)
      40:  *
      41:  * Revision 1.2  87/03/27  14:22:33  jenkins
      42:  * Port to suns
      43:  *
      44:  * Revision 1.1  84/01/23  14:50:33  kcs
      45:  * Initial revision
      46:  *
      47:  * Revision 4.1  83/03/25  18:12:51  wft
      48:  * Only changed $Header to $Id.
      49:  *
      50:  * Revision 3.3  82/12/10  16:22:37  wft
      51:  * Improved error messages, changed exit status on error to 1.
      52:  *
      53:  * Revision 3.2  82/11/28  21:27:10  wft
      54:  * Renamed ctab to map and included EOFILE; ctab is now a macro in rcsbase.h.
      55:  * Added fflsbuf(), fputs(), and fprintf(), which abort the RCS operations
      56:  * properly in case there is an IO-error (e.g., file system full).
      57:  *
      58:  * Revision 3.1  82/10/11  19:43:56  wft
      59:  * removed unused label out:;
      60:  * made sure all calls to getc() return into an integer, not a char.
      61:  */
      62:
      63:
      64: /*
      65: #define LEXDB
      66: /* version LEXDB is for testing the lexical analyzer. The testprogram
      67:  * reads a stream of lexemes, enters the revision numbers into the
      68:  * hashtable, and prints the recognized tokens. Keywords are recognized
      69:  * as identifiers.
      70:  */
      71:
      72:
      73:
      74: #include "rcsbase.h"
      75: #include <varargs.h>
      76:
      77:
      78:
      79: /* character mapping table */
      80: enum tokens map[] = {
      81:         EOFILE,         /* this will end up at ctab[-1] */
      82:         UNKN,   INSERT, UNKN,   UNKN,   UNKN,   UNKN,   UNKN,   UNKN,
      83:         UNKN,   SPACE,  NEWLN,  UNKN,   SPACE,  UNKN,   UNKN,   UNKN,
      84:         UNKN,   UNKN,   UNKN,   UNKN,   UNKN,   UNKN,   UNKN,   UNKN,
      85:         UNKN,   UNKN,   UNKN,   UNKN,   UNKN,   UNKN,   UNKN,   UNKN,
      86:         SPACE,  EXCLA,  DQUOTE, HASH,   DOLLAR, PERCNT, AMPER,  SQUOTE,
      87:         LPARN,  RPARN,  TIMES,  PLUS,   COMMA,  MINUS,  PERIOD, DIVIDE,
      88:         DIGIT,  DIGIT,  DIGIT,  DIGIT,  DIGIT,  DIGIT,  DIGIT,  DIGIT,
      89:         DIGIT,  DIGIT,  COLON,  SEMI,   LESS,   EQUAL,  GREAT,  QUEST,
      90:         AT,     LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
      91:         LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
      92:         LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
      93:         LETTER, LETTER, LETTER, LBRACK, BACKSL, RBRACK, UPARR,  UNDER,
      94:         ACCENT, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
      95:         LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
      96:         LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
      97:         LETTER, LETTER, LETTER, LBRACE, BAR,    RBRACE, TILDE,  UNKN
      98: };
      99:
     100:
     101:
     102:
     103: struct hshentry * nexthsh;  /*pointer to next hashtable-entry, set by lookup*/
     104:
     105: enum tokens     nexttok;    /*next token, set by nextlex                    */
     106:
     107: int             hshenter    /*if true, next suitable lexeme will be entered */
     108:                 = true;     /*into the symbol table. Handle with care.      */
     109: int             nextc;      /*next input character, initialized by Lexinit  */
     110:
     111: int             eof         /*end-of-file indicator, set to >0 on end of file*/
     112:                 = 0;
     113: int             line        /*current line-number of input                  */
     114:                 = 1;
     115: int             nerror      /*counter for errors                            */
     116:                 = 0;
     117: int             nwarn       /*counter for warnings                          */
     118:                 = 0;
     119: char *          cmdid       /*command identification for error messages     */
     120:                 = nil;
     121: int             quietflag   /*indicates quiet mode                          */
     122:                 = false;
     123: FILE *          finptr;     /*input file descriptor                         */
     124:
     125: FILE *          frewrite;   /*file descriptor for echoing input             */
     126:
     127: int             rewriteflag;/*indicates whether to echo to frewrite         */
     128:
     129: char            StringTab[strtsize]; /* string table and heap               */
     130:
     131: char *          NextString          /*pointer to next identifier in StringTab*/
     132:                 = nil;
     133: char *          Topchar             /*pointer to next free byte in StringTab*/
     134:                 = &StringTab[0];    /*set by nextlex, lookup                */
     135: struct hshentry hshtab[hshsize];    /*hashtable                             */
     136:
     137:
     138:
     139:
     140:
     141: lookup() {
     142:
     143: /* Function: Looks up the character string pointed to by NextString in the
     144:  * hashtable. If the string is not present, a new entry for it is created.
     145:  * If the string is present, TopChar is moved back to save the space for
     146:  * the string, and NextString is set to point to the original string.
     147:  * In any case, the address of the corresponding hashtable entry is placed
     148:  * into nexthsh.
     149:  * Algorithm: Quadratic hash, covering all entries.
     150:  * Assumptions: NextString points at the first character of the string.
     151:  * Topchar points at the first empty byte after the string.
     152:  */
     153:
     154:         register int     ihash;      /* index into hashtable */
     155:         register char    * sp, * np;
     156:         int              c, delta, final, FirstScan; /*loop control*/
     157:
     158:         /* calculate hash code */
     159:         sp = NextString;
     160:         ihash = 0;
     161:         while (*sp) ihash += *sp++;
     162:
     163:         /* set up first search loop (c=0,step=1,until (hshsiz-1)/2 */
     164:         c=0;delta=1;final=(hshsize-1)/2;
     165:         FirstScan=true;   /*first loop */
     166:
     167:         for (;;) {
     168:                 ihash = (ihash+c)%hshsize;   /*next index*/
     169:
     170:                 if (hshtab[ihash].num == nil) {
     171:                         /*empty slot found*/
     172:                         hshtab[ihash].num = NextString;
     173:                         nexthsh= &hshtab[ihash];/*save hashtable address*/
     174: #                       ifdef LEXDB
     175:                         VOID printf("\nEntered: %s at %d ",nexthsh->num, ihash);
     176: #                       endif
     177:                         return;
     178:                 }
     179:                 /* compare strings */
     180:                 sp=NextString;np=hshtab[ihash].num;
     181:                 while (*sp == *np++) {
     182:                         if (*sp == 0) {
     183:                                 /* match found */
     184:                                 nexthsh= &hshtab[ihash];
     185:                                 Topchar = NextString;
     186:                                 NextString = nexthsh->num;
     187:                                 return;
     188:                         } else sp++;
     189:                 }
     190:
     191:                 /* neither empty slot nor string found */
     192:                 /* calculate next index and repeat */
     193:                 if (c != final)
     194:                         c += delta;
     195:                 else {
     196:                         if (FirstScan) {
     197:                                 /*set up second sweep*/
     198:                                 delta = -1; final = 1; FirstScan= false;
     199:                         } else {
     200:                                 fatserror("Hashtable overflow");
     201:                         }
     202:                 }
     203:         }
     204: };
     205:
     206:
     207:
     208:
     209:
     210:
     211: Lexinit()
     212: /* Function: Initialization of lexical analyzer:
     213:  * initializes the hastable,
     214:  * initializes nextc, nexttok if finptr != NULL
     215:  */
     216: {       register int            i;
     217:
     218:         for (i=hshsize-1; i>=0; i--) {
     219:                 hshtab[i].num = nil;
     220:         }
     221:
     222:         hshenter=true; eof=0; line=1; nerror=0; nwarn=0;
     223:         NextString=nil; Topchar = &StringTab[0];
     224:         if (finptr) {
     225:                 nextc = GETC(finptr,frewrite,rewriteflag); /*initial character*/
     226:                 nextlex();            /*initial token*/
     227:         } else {
     228:                 nextc = '\0';
     229:                 nexttok=EOFILE;
     230:         }
     231: }
     232:
     233:
     234:
     235:
     236:
     237:
     238:
     239: nextlex()
     240:
     241: /* Function: Reads the next token and sets nexttok to the next token code.
     242:  * Only if the hshenter==true, a revision number is entered into the
     243:  * hashtable and a pointer to it is placed into nexthsh.
     244:  * This is useful for avoiding that dates are placed into the hashtable.
     245:  * For ID's and NUM's, NextString is set to the character string in the
     246:  * string table. Assumption: nextc contains the next character.
     247:  */
     248: {       register c;
     249:         register char * sp;
     250:         register enum tokens d;
     251:
     252:         if (eof) {
     253:                 nexttok=EOFILE;
     254:                 return;
     255:         }
     256: loop:
     257:         switch(nexttok=ctab[nextc]) {
     258:
     259:         case UNKN:
     260:         case IDCHAR:
     261:         case PERIOD:
     262:                 serror("unknown Character: %c",nextc);
     263:                 nextc=GETC(finptr,frewrite,rewriteflag);
     264:                 goto loop;
     265:
     266:         case NEWLN:
     267:                 line++;
     268: #               ifdef LEXDB
     269:                 VOID putchar('\n');
     270: #               endif
     271:                 /* Note: falls into next case */
     272:
     273:         case SPACE:
     274:                 nextc=GETC(finptr,frewrite,rewriteflag);
     275:                 goto loop;
     276:
     277:         case EOFILE:
     278:                 eof++;
     279:                 nexttok=EOFILE;
     280:                 return;
     281:
     282:         case DIGIT:
     283:                 NextString = sp = Topchar;
     284:                 *sp++ = nextc;
     285:                 while ((d=ctab[c=GETC(finptr,frewrite,rewriteflag)])==DIGIT ||
     286:                         d==PERIOD) {
     287:                         *sp++ = c;         /* 1.2. and 1.2 are different */
     288:                 }
     289:                 *sp++ = '\0';
     290:                 if (sp >= StringTab+strtsize) {
     291:                         /*may have written outside stringtable already*/
     292:                         fatserror("Stringtable overflow");
     293:                 }
     294:                 Topchar = sp;
     295:                 nextc = c;
     296:                 if (hshenter == true)
     297:                         lookup();      /* lookup updates NextString, Topchar*/
     298:                 nexttok = NUM;
     299:                 return;
     300:
     301:
     302:         case LETTER:
     303:                 NextString = sp = Topchar;
     304:                 *sp++ = nextc;
     305:                 while ((d=ctab[c=GETC(finptr,frewrite,rewriteflag)])==LETTER ||
     306:                         d==DIGIT || d==IDCHAR) {
     307:                         *sp++ = c;
     308:                 }
     309:                 *sp++ = '\0';
     310:                 if (sp >= StringTab+strtsize) {
     311:                         /*may have written outside stringtable already*/
     312:                         fatserror("Stringtable overflow");
     313:                 }
     314:                 Topchar = sp;
     315:                 nextc = c;
     316:                 nexttok = ID;  /* may be ID or keyword */
     317:                 return;
     318:
     319:         case SBEGIN: /* long string */
     320:                 nexttok = STRING;
     321:                 /* note: only the initial SBEGIN has been read*/
     322:                 /* read the string, and reset nextc afterwards*/
     323:                 return;
     324:
     325:         default:
     326:                 nextc=GETC(finptr,frewrite,rewriteflag);
     327:                 return;
     328:         }
     329: }
     330:
     331:
     332: int getlex(token)
     333: enum tokens token;
     334: /* Function: Checks if nexttok is the same as token. If so,
     335:  * advances the input by calling nextlex and returns true.
     336:  * otherwise returns false.
     337:  * Doesn't work for strings and keywords; loses the character string for ids.
     338:  */
     339: {
     340:         if (nexttok==token) {
     341:                 nextlex();
     342:                 return(true);
     343:         } else  return(false);
     344: }
     345:
     346: int getkey (key)
     347: char * key;
     348: /* Function: If the current token is a keyword identical to key,
     349:  * getkey advances the input by calling nextlex and returns true;
     350:  * otherwise returns false.
     351:  */
     352: {
     353:         register char *s1,*s2;
     354:
     355:         if (nexttok==ID) {
     356:                 s1=key; s2=NextString;
     357:                 while(*s1 == *s2++)
     358:                      if (*s1++ == '\0') {
     359:                          /* match found */
     360:                          Topchar = NextString; /*reset Topchar */
     361:                          nextlex();
     362:                          return(true);
     363:                      }
     364:         }
     365:         return(false);
     366: }
     367:
     368:
     369:
     370: char * getid()
     371: /* Function: Checks if nexttok is an identifier. If so,
     372:  * advances the input by calling nextlex and returns a pointer
     373:  * to the identifier; otherwise returns nil.
     374:  * Treats keywords as identifiers.
     375:  */
     376: {
     377:         register char * name;
     378:         if (nexttok==ID) {
     379:                 name = NextString;
     380:                 nextlex();
     381:                 return name;
     382:         } else  return nil;
     383: }
     384:
     385:
     386: struct hshentry * getnum()
     387: /* Function: Checks if nexttok is a number. If so,
     388:  * advances the input by calling nextlex and returns a pointer
     389:  * to the hashtable entry. Otherwise returns nil.
     390:  * Doesn't work if hshenter is false.
     391:  */
     392: {
     393:         register struct hshentry * num;
     394:         if (nexttok==NUM) {
     395:                 num=nexthsh;
     396:                 nextlex();
     397:                 return num;
     398:         } else  return nil;
     399: }
     400:
     401:
     402: readstring()
     403: /* skip over characters until terminating single SDELIM        */
     404: /* if rewriteflag==true, copy every character read to frewrite.*/
     405: /* Does not advance nextlex at the end.                        */
     406: {       register c;
     407:         if (rewriteflag) {
     408:                 /* copy string verbatim to frewrite */
     409:                 while ((c=putc(getc(finptr),frewrite)) != EOF) {
     410:                         if (c==SDELIM) {
     411:                                 if ((c=putc(getc(finptr),frewrite)) != SDELIM) {
     412:                                         /* end of string */
     413:                                         nextc=c;
     414:                                         return;
     415:                                 }
     416:                         }
     417:                 }
     418:         } else {
     419:                 /* skip string */
     420:                 while ((c=getc(finptr)) != EOF) {
     421:                         if (c==SDELIM) {
     422:                                 if ((c=getc(finptr)) != SDELIM) {
     423:                                         /* end of string */
     424:                                         nextc=c;
     425:                                         return;
     426:                                 }
     427:                         }
     428:                 }
     429:         }
     430:         nextc = c;
     431:         error("Unterminated string");
     432: }
     433:
     434:
     435: printstring()
     436: /* Function: copy a string to stdout, until terminated with a single SDELIM.
     437:  * Does not advance nextlex at the end.
     438:  */
     439: {
     440:         register c;
     441:         while ((c=getc(finptr)) != EOF) {
     442:                 if (c==SDELIM) {
     443:                         if ((c=getc(finptr)) != SDELIM) {
     444:                                 /* end of string */
     445:                                 nextc=c;
     446:                                 return;
     447:                         }
     448:                 }
     449:                 VOID putchar(c);
     450:         }
     451:         nextc = c;
     452:         error("Unterminated string");
     453: }
     454:
     455:
     456:
     457: int savestring(target,length)
     458: char * target; int length;
     459: /* copies a string terminated with SDELIM from file finptr to buffer target,
     460:  * but not more than length bytes. If the string is longer than length,
     461:  * the extra characters are skipped. The string may be empty, in which
     462:  * case a '\0' is placed into target.
     463:  * Double SDELIM is replaced with SDELIM.
     464:  * If rewriteflag==true, the string is also copied unchanged to frewrite.
     465:  * Returns the length of the saved string.
     466:  * Does not advance nextlex at the end.
     467:  */
     468: {
     469:         register char * tp, * max;
     470:         register c;
     471:
     472:         tp=target; max= target+length; /*max is one too large*/
     473:         while ((c=GETC(finptr,frewrite,rewriteflag))!=EOF) {
     474:         *tp++ =c;
     475:                 if (c== SDELIM) {
     476:                         if ((c=GETC(finptr,frewrite,rewriteflag))!=SDELIM) {
     477:                                 /* end of string */
     478:                                 *(tp-1)='\0';
     479:                                 nextc=c;
     480:                                 return tp-target;
     481:                         }
     482:                 }
     483:                 if (tp >= max) {
     484:                         /* overflow */
     485:                         error("string buffer overflow -- truncating string");
     486:                         target[length-1]='\0';
     487:                         /* skip rest of string */
     488:                         while ((c=GETC(finptr,frewrite,rewriteflag))!=EOF) {
     489:                                 if ((c==SDELIM) && ((c=GETC(finptr,frewrite,rewriteflag))!=SDELIM)) {
     490:                                         /* end of string */
     491:                                         nextc=c;
     492:                                         return length;
     493:                                 }
     494:                         }
     495:                         nextc = c;
     496:                         error("Can't find %c to terminate string before end of file",SDELIM);
     497:                         return length;
     498:                 }
     499:         }
     500:         nextc = c;
     501:         error("Can't find %c to terminate string before end of file",SDELIM);
     502:         return length;
     503: }
     504:
     505:
     506: char  *checkid(id, delim)
     507: char    *id, delim;
     508: /*   Function:  check whether the string starting at id is an   */
     509: /*              identifier and return a pointer to the last char*/
     510: /*              of the identifer. White space, delim and '\0'   */
     511: /*              are legal delimeters. Aborts the program if not */
     512: /*              a legal identifier. Useful for checking commands*/
     513: {
     514:         register enum  tokens  d;
     515:         register char    *temp;
     516:         register char    c,tc;
     517:
     518:         temp = id;
     519:         if ( ctab[*id] == LETTER ) {
     520:             while( (d=ctab[c=(*++id)]) == LETTER || d==DIGIT || d==IDCHAR) ;
     521:             if ( c!=' ' && c!='\t' && c!='\n' && c!='\0' && c!=delim) {
     522:                 /* append \0 to end of id before error message */
     523:                 tc = c;
     524:                 while( (c=(*++id))!=' ' && c!='\t' && c!='\n' && c!='\0' && c!=delim) ;
     525:                 *id = '\0';
     526:                 faterror("Invalid character %c in identifier %s",tc,temp);
     527:                 return nil ;
     528:             } else
     529:                 return id;
     530:         } else {
     531:             /* append \0 to end of id before error message */
     532:             while( (c=(*++id))!=' ' && c!='\t' && c!='\n' && c!='\0' && c!=delim) ;
     533:             *id = '\0';
     534:             faterror("Identifier %s does not start with letter",temp);
     535:             return nil;
     536:         }
     537: }
     538:
     539:
     540: /*VARARGS1*/
     541: serror(e,e1,e2,e3,e4,e5)
     542: char * e, * e1, * e2, * e3, * e4, * e5;
     543: /* non-fatal syntax error */
     544: {       nerror++;
     545:         VOID fprintf(stderr,"%s error, line %d: ", cmdid, line);
     546:         VOID fprintf(stderr,e, e1, e2, e3, e4, e5);
     547:         VOID putc('\n',stderr);
     548: }
     549:
     550: /*VARARGS1*/
     551: error(e,e1,e2,e3,e4,e5)
     552: char * e, * e1, * e2, * e3, * e4, * e5;
     553: /* non-fatal error */
     554: {       nerror++;
     555:         VOID fprintf(stderr,"%s error: ",cmdid);
     556:         VOID fprintf(stderr,e, e1, e2, e3, e4, e5);
     557:         VOID putc('\n',stderr);
     558: }
     559:
     560: /*VARARGS1*/
     561: fatserror(e,e1,e2,e3,e4,e5)
     562: char * e, * e1, * e2, * e3, * e4, * e5;
     563: /* fatal syntax error */
     564: {       nerror++;
     565:         VOID fprintf(stderr,"%s error, line %d: ", cmdid,line);
     566:         VOID fprintf(stderr,e, e1, e2, e3, e4, e5);
     567:         VOID fprintf(stderr,"\n%s aborted\n",cmdid);
     568:         VOID cleanup();
     569:         exit(1);
     570: }
     571:
     572: /*VARARGS1*/
     573: faterror(e,e1,e2,e3,e4,e5)
     574: char * e, * e1, * e2, * e3, * e4, * e5;
     575: /* fatal error, terminates program after cleanup */
     576: {       nerror++;
     577:         VOID fprintf(stderr,"%s error: ",cmdid);
     578:         VOID fprintf(stderr,e, e1, e2, e3, e4, e5);
     579:         VOID fprintf(stderr,"\n%s aborted\n",cmdid);
     580:         VOID cleanup();
     581:         exit(1);
     582: }
     583:
     584: /*VARARGS1*/
     585: warn(e,e1,e2,e3,e4,e5)
     586: char * e, * e1, * e2, * e3, * e4, * e5;
     587: /* prints a warning message */
     588: {       nwarn++;
     589:         VOID fprintf(stderr,"%s warning: ",cmdid);
     590:         VOID fprintf(stderr,e, e1, e2, e3, e4, e5);
     591:         VOID putc('\n',stderr);
     592: }
     593:
     594:
     595: /*VARARGS1*/
     596: diagnose(e,e1,e2,e3,e4,e5)
     597: char * e, * e1, * e2, * e3, * e4, * e5;
     598: /* prints a diagnostic message */
     599: {
     600:         if (!quietflag) {
     601:                 VOID fprintf(stderr,e, e1, e2, e3, e4, e5);
     602:                 VOID putc('\n',stderr);
     603:         }
     604: }
     605:
     606:
     607:
     608: fflsbuf(c, iop)
     609: unsigned c; register FILE * iop;
     610: /* Function: Flush iop.
     611:  * Same routine as _flsbuf in stdio, but aborts program on error.
     612:  */
     613: {       register result;
     614:         if ((result=_flsbuf(c,iop))==EOF)
     615:                 faterror("write error");
     616:         return result;
     617: }
     618:
     619:
     620: fputs(s, iop)
     621: register char *s;
     622: register FILE *iop;
     623: /* Function: Put string s on file iop, abort on error.
     624:  * Same as puts in stdio, but with different putc macro.
     625:  */
     626: {
     627:     register r;
     628:     register c;
     629:
     630:     while (c = *s++)
     631:         r = putc(c, iop);
     632:     return(r);
     633: }
     634:
     635:
     636:
     637: fprintf(iop, fmt, va_alist)
     638: FILE *iop;
     639: char *fmt;
     640: va_dcl
     641: /* Function: formatted output. Same as fprintf in stdio,
     642:  * but aborts program on error
     643:  */
     644: {
     645:     register int value;
     646:     va_list ap;
     647:
     648:     va_start(ap);
     649: #ifdef VFPRINTF
     650:     VOID vfprintf(iop, fmt, ap);
     651: #else
     652:     _doprnt(fmt, ap, iop);
     653: #endif VFPRINTF
     654:         if (ferror(iop)) {
     655:                 faterror("write error");
     656:                 value = EOF;
     657:         } else value = 0;
     658:     va_end(ap);
     659:     return value;
     660: }
     661:
     662:
     663:
     664: #ifdef LEXDB
     665: /* test program reading a stream of lexems and printing the tokens.
     666:  */
     667:
     668:
     669:
     670: main(argc,argv)
     671: int argc; char * argv[];
     672: {
     673:         cmdid="lextest";
     674:         if (argc<2) {
     675:                 VOID fputs("No input file\n",stderr);
     676:                 exit(1);
     677:         }
     678:         if ((finptr=fopen(argv[1], "r")) == NULL) {
     679:                 faterror("Can't open input file %s\n",argv[1]);
     680:         }
     681:         Lexinit();
     682:         rewriteflag=false;
     683:         while (nexttok != EOFILE) {
     684:         switch (nexttok) {
     685:
     686:         case ID:
     687:                 VOID printf("ID: %s",NextString);
     688:                 break;
     689:
     690:         case NUM:
     691:                 if (hshenter==true)
     692:                    VOID printf("NUM: %s, index: %d",nexthsh->num, nexthsh-hshtab);
     693:                 else
     694:                    VOID printf("NUM, unentered: %s",NextString);
     695:                 hshenter = !hshenter; /*alternate between dates and numbers*/
     696:                 break;
     697:
     698:         case COLON:
     699:                 VOID printf("COLON"); break;
     700:
     701:         case SEMI:
     702:                 VOID printf("SEMI"); break;
     703:
     704:         case STRING:
     705:                 readstring();
     706:                 VOID printf("STRING"); break;
     707:
     708:         case UNKN:
     709:                 VOID printf("UNKN"); break;
     710:
     711:         default:
     712:                 VOID printf("DEFAULT"); break;
     713:         }
     714:         VOID printf(" | ");
     715:         nextlex();
     716:         }
     717:         VOID printf("\nEnd of lexical analyzer test\n");
     718: }
     719:
     720: cleanup()
     721: /* dummy */
     722: {}
     723:
     724:
     725: #endif

#### Defined functions

Lexinit defined in line 211; used 6 times

- in line 681
- in /usr/src/new/rcs/src/rcs.c line 717
- in /usr/src/new/rcs/src/rcsfnms.c line 332, 503
- in /usr/src/new/rcs/src/rcsrev.c line 659
- in /usr/src/new/rcs/src/rcssyn.c line 525

checkid defined in line 506; used 15 times

- in /usr/src/new/rcs/src/ci.c line 125, 253, 263, 272, 306
- in /usr/src/new/rcs/src/rcs.c line 130, 599, 650, 679
- in /usr/src/new/rcs/src/rcskeep.c line 60, 119, 138-140(2), 146, 166

cleanup defined in line 720; used 2 times

- in line 568, 580

diagnose defined in line 596; used 47 times

- in /usr/src/new/rcs/src/ci.c line 352, 388-389(2), 519, 824, 841
- in /usr/src/new/rcs/src/co.c line 256, 268, 299, 367, 591-601(3)
- in /usr/src/new/rcs/src/rcs.c line 410, 416, 450, 574-576(2), 1052, 1061, 1129, 1348, 1385, 1412, 1521
- in /usr/src/new/rcs/src/rcsclean.c line 105, 111, 128, 149, 158
- in /usr/src/new/rcs/src/rcsdiff.c line 178-179(2), 208, 217-220(2), 227
- in /usr/src/new/rcs/src/rcsfnms.c line 433, 500, 741-742(2), 750-755(2)
- in /usr/src/new/rcs/src/rcsmerge.c line 114, 137, 143, 149
- in /usr/src/new/rcs/src/rcsutil.c line 253

error defined in line 551; used 121 times

- in line 431, 452, 485, 496-501(2)
- in /usr/src/new/rcs/src/ci.c line 355, 368, 416, 428, 482, 510, 552, 588, 610, 631, 701, 743, 757, 797
- in /usr/src/new/rcs/src/co.c line 311, 333, 355, 405, 411, 458, 524, 545, 558, 564
- in /usr/src/new/rcs/src/rcs.c line 255, 269, 361, 369, 378, 386, 430, 531, 557, 604, 644, 689, 1067, 1113, 1120, 1160, 1175, 1227-1231(2), 1250, 1273, 1365, 1409, 1431
- in /usr/src/new/rcs/src/rcsclean.c line 118, 132-141(3), 151
- in /usr/src/new/rcs/src/rcsdiff.c line 181, 190, 212, 224, 233
- in /usr/src/new/rcs/src/rcsedit.c line 358
- in /usr/src/new/rcs/src/rcsfnms.c line 214-219(2), 237, 394, 411, 425, 444-448(2), 483-487(2), 569, 597, 609, 732, 748
- in /usr/src/new/rcs/src/rcsgen.c line 260
- in /usr/src/new/rcs/src/rcskeep.c line 98, 133, 157, 203, 209, 245
- in /usr/src/new/rcs/src/rcsrev.c line 299, 315, 321, 348, 364-365(2), 384, 407-411(2), 423-431(3), 466, 475-476(2), 490, 512, 524-537(4), 599, 611, 622-626(2)
- in /usr/src/new/rcs/src/rcssyn.c line 497
- in /usr/src/new/rcs/src/rcsutil.c line 165, 171, 205, 246
- in /usr/src/new/rcs/src/rlog.c line 874-879(2), 1083-1088(2), 1155

faterror defined in line 573; used 61 times

- in line 526, 534, 615, 655, 679
- in /usr/src/new/rcs/src/ci.c line 254, 264, 289-293(2), 314-322(3), 456, 472, 907
- in /usr/src/new/rcs/src/co.c line 205-207(2), 236-241(2), 428
- in /usr/src/new/rcs/src/rcs.c line 404-408(2), 715-720(2), 788, 824, 850, 983, 1456, 1478
- in /usr/src/new/rcs/src/rcsbase.h line 313
- in /usr/src/new/rcs/src/rcsdiff.c line 150
- in /usr/src/new/rcs/src/rcsedit.c line 130, 142, 150, 274, 283, 300, 325
- in /usr/src/new/rcs/src/rcsfcmp.c line 81
- in /usr/src/new/rcs/src/rcsfnms.c line 180, 536
- in /usr/src/new/rcs/src/rcsgen.c line 273
- in /usr/src/new/rcs/src/rcsmerge.c line 95, 101-106(3), 116, 122, 141, 147, 156
- in /usr/src/new/rcs/src/rcsrev.c line 657
- in /usr/src/new/rcs/src/rcssyn.c line 523
- in /usr/src/new/rcs/src/rcsutil.c line 305, 312
- in /usr/src/new/rcs/src/rlog.c line 238-243(2), 530, 537, 558

fatserror defined in line 561; used 20 times

- in line 200, 292, 312
- in /usr/src/new/rcs/src/rcs.c line 736, 841
- in /usr/src/new/rcs/src/rcsbase.h line 314
- in /usr/src/new/rcs/src/rcsgen.c line 184, 196
- in /usr/src/new/rcs/src/rcssyn.c line 157, 183, 196, 276, 294, 330, 355, 361, 535
- in /usr/src/new/rcs/src/rlog.c line 349, 496-501(2)

fflsbuf defined in line 608; used 1 times

- in /usr/src/new/rcs/src/rcsbase.h line 173

fprintf defined in line 637; used 102 times

- in line 545-546(2), 555-556(2), 565-567(3), 577-579(3), 589-590(2), 601
- in /usr/src/new/rcs/src/ci.c line 932
- in /usr/src/new/rcs/src/co.c line 316, 396
- in /usr/src/new/rcs/src/ident.c line 87, 93-98(2), 143
- in /usr/src/new/rcs/src/rcs.c line 829, 974-975(2), 986-988(3), 997, 1517
- in /usr/src/new/rcs/src/rcsbase.h line 111-112(2)
- in /usr/src/new/rcs/src/rcsclean.c line 178-180(3)
- in /usr/src/new/rcs/src/rcsdiff.c line 255-257(3)
- in /usr/src/new/rcs/src/rcsedit.c line 431, 444-459(6), 466-475(4)
- in /usr/src/new/rcs/src/rcsgen.c line 235, 244
- in /usr/src/new/rcs/src/rcsrev.c line 241, 669-680(9), 686-690(2)
- in /usr/src/new/rcs/src/rcssyn.c line 385-388(2), 396-415(7), 430-431(2), 443, 488, 495
- in /usr/src/new/rcs/src/rlog.c line 265-279(6), 297-305(3), 340, 443-446(3), 452-460(4), 471
- in /usr/src/new/rcs/src/sccstorcs.c line 80, 248-253(2), 302, 339, 421
- in /usr/src/new/rcs/src/snoop.c line 96, 104-105(2)

fputs defined in line 620; used 46 times

- in line 675
- in /usr/src/new/rcs/src/ci.c line 831, 892, 904, 933-938(2)
- in /usr/src/new/rcs/src/rcs.c line 989-990(2), 1005
- in /usr/src/new/rcs/src/rcsedit.c line 405, 442-443(2), 458-462(2)
- in /usr/src/new/rcs/src/rcsgen.c line 257, 267-268(2), 284, 299, 306
- in /usr/src/new/rcs/src/rcsrev.c line 653
- in /usr/src/new/rcs/src/rcssyn.c line 382-386(4), 393, 433-445(5), 519
- in /usr/src/new/rcs/src/rlog.c line 276, 284-294(5), 308-310(2), 342, 351, 449, 468, 477
- in /usr/src/new/rcs/src/snoop.c line 98

getid defined in line 370; used 7 times

- in /usr/src/new/rcs/src/rcs.c line 119, 738
- in /usr/src/new/rcs/src/rcsrev.c line 67
- in /usr/src/new/rcs/src/rcssyn.c line 90, 184, 197, 217

getkey defined in line 346; used 23 times

- in /usr/src/new/rcs/src/rcs.c line 720, 726, 736, 831, 840
- in /usr/src/new/rcs/src/rcsgen.c line 186, 195
- in /usr/src/new/rcs/src/rcsrev.c line 69
- in /usr/src/new/rcs/src/rcssyn.c line 92, 157, 165, 173, 183, 196, 216, 239, 245, 276, 294, 330, 354
- in /usr/src/new/rcs/src/rlog.c line 495-500(2)

getlex defined in line 332; used 18 times

- in /usr/src/new/rcs/src/rcs.c line 722, 732, 749
- in /usr/src/new/rcs/src/rcsrev.c line 70
- in /usr/src/new/rcs/src/rcssyn.c line 93, 163-167(2), 179, 194-198(2), 214-218(2), 238-248(3), 292, 300, 364

getnum defined in line 386; used 16 times

- in /usr/src/new/rcs/src/rcs.c line 117, 721, 822
- in /usr/src/new/rcs/src/rcsgen.c line 81, 183
- in /usr/src/new/rcs/src/rcsrev.c line 68
- in /usr/src/new/rcs/src/rcssyn.c line 91, 158, 166, 200, 220, 262, 278, 295
- in /usr/src/new/rcs/src/rlog.c line 103, 494

lookup defined in line 141; used 1 times

- in line 297

main defined in line 670; never used
nextlex defined in line 239; used 20 times

- in line 226, 341, 361, 380, 396, 715
- in /usr/src/new/rcs/src/rcs.c line 728-730(2), 821, 839
- in /usr/src/new/rcs/src/rcsgen.c line 182, 194
- in /usr/src/new/rcs/src/rcssyn.c line 175-177(2), 246, 359, 534
- in /usr/src/new/rcs/src/rlog.c line 348, 493, 499

printstring defined in line 435; used 1 times

- in /usr/src/new/rcs/src/rcssyn.c line 332

readstring defined in line 402; used 10 times

- in line 705
- in /usr/src/new/rcs/src/rcs.c line 728, 836, 852
- in /usr/src/new/rcs/src/rcsgen.c line 191, 210
- in /usr/src/new/rcs/src/rcssyn.c line 95, 175, 333
- in /usr/src/new/rcs/src/rlog.c line 506

savestring defined in line 457; used 6 times

- in /usr/src/new/rcs/src/rcs.c line 834
- in /usr/src/new/rcs/src/rcsgen.c line 84, 189
- in /usr/src/new/rcs/src/rcssyn.c line 96, 246
- in /usr/src/new/rcs/src/rlog.c line 498

serror defined in line 541; used 30 times

- in line 262
- in /usr/src/new/rcs/src/rcs.c line 722, 732, 749, 832
- in /usr/src/new/rcs/src/rcsbase.h line 312
- in /usr/src/new/rcs/src/rcsedit.c line 236, 315
- in /usr/src/new/rcs/src/rcsgen.c line 187
- in /usr/src/new/rcs/src/rcssyn.c line 161-167(3), 179, 194-201(3), 214-225(5), 238-248(3), 265, 281, 292, 298-300(2), 364

warn defined in line 585; used 55 times

- in /usr/src/new/rcs/src/ci.c line 203, 230-234(2), 245, 251-255(2), 261-273(4), 279, 286, 299-307(3), 372-376(3), 494, 516, 838, 928
- in /usr/src/new/rcs/src/co.c line 165, 177, 185, 200, 216, 223, 229, 341, 364, 401
- in /usr/src/new/rcs/src/rcs.c line 242, 248, 272, 345, 353, 376, 395, 504, 571, 931, 1316, 1351-1354(2), 1387
- in /usr/src/new/rcs/src/rcsclean.c line 108
- in /usr/src/new/rcs/src/rcsfnms.c line 513
- in /usr/src/new/rcs/src/rcskeep.c line 172
- in /usr/src/new/rcs/src/rcsmerge.c line 113
- in /usr/src/new/rcs/src/rlog.c line 227, 233, 674, 906, 1111

#### Defined variables

NextString defined in line 131; used 27 times

- in line 159, 172, 180-186(3), 223, 283, 303, 356-360(2), 379, 687, 694
- in /usr/src/new/rcs/src/rcslex.c line 159, 172, 180-186(3), 223, 283, 303, 356-360(2), 379, 687, 694
- in /usr/src/new/rcs/src/rcssyn.c line 358

StringTab defined in line 129; used 4 times

- in line 134, 223, 290, 310

Topchar defined in line 133; used 7 times

- in line 185, 223, 283, 294, 303, 314, 360

cmdid defined in line 119; used 29 times

- in line 545, 555, 565-567(2), 577-579(2), 589, 673
- in /usr/src/new/rcs/src/rcsclean.c line 72, 178-180(2)
- in /usr/src/new/rcs/src/rcsdiff.c line 112, 255-257(2)
- in /usr/src/new/rcs/src/rcsfcmp.c line 193
- in /usr/src/new/rcs/src/rcsfnms.c line 721
- in /usr/src/new/rcs/src/rcskeep.c line 274
- in /usr/src/new/rcs/src/rcslex.c line 545, 555, 565-567(2), 577-579(2), 589, 673
- in /usr/src/new/rcs/src/rcsmerge.c line 79
- in /usr/src/new/rcs/src/rcsrev.c line 651
- in /usr/src/new/rcs/src/rcssyn.c line 517
- in /usr/src/new/rcs/src/rlog.c line 172

eof defined in line 111; used 3 times

- in line 222, 252, 278

hshenter defined in line 107; used 12 times

- in line 222, 296, 691-695(3)
- in /usr/src/new/rcs/src/rcslex.c line 222, 296, 691-695(3)
- in /usr/src/new/rcs/src/rcssyn.c line 268-270(2)

hshtab defined in line 135; used 14 times

- in line 170-173(3), 180-184(2), 219, 692
- in /usr/src/new/rcs/src/rcslex.c line 170-173(3), 180-184(2), 219, 692

line defined in line 113; used 4 times

- in line 222, 267, 545, 565

map defined in line 80; used 1 times

- in /usr/src/new/rcs/src/rcsbase.h line 296

nerror defined in line 115; used 23 times

- in line 222, 544, 554, 564, 576
- in /usr/src/new/rcs/src/ci.c line 524
- in /usr/src/new/rcs/src/co.c line 327, 371, 594-599(2), 606
- in /usr/src/new/rcs/src/rcs.c line 214, 409, 415, 424, 554, 581
- in /usr/src/new/rcs/src/rcsclean.c line 165, 177
- in /usr/src/new/rcs/src/rcsdiff.c line 240, 254
- in /usr/src/new/rcs/src/rcsmerge.c line 162
- in /usr/src/new/rcs/src/rlog.c line 355

nextc defined in line 109; used 29 times

- in line 225-228(2), 257-263(3), 274, 284, 295, 304, 315, 326, 413, 424, 430, 445, 451, 479, 491-500(3)
- in /usr/src/new/rcs/src/co.c line 316
- in /usr/src/new/rcs/src/rcsedit.c line 212, 229, 235, 329, 359, 367
- in /usr/src/new/rcs/src/rcsgen.c line 235
- in /usr/src/new/rcs/src/rlog.c line 562

nexthsh defined in line 103; used 14 times

- in line 173-175(2), 184-186(2), 395, 692(2)
- in /usr/src/new/rcs/src/rcslex.c line 173-175(2), 184-186(2), 395, 692(2)

nexttok defined in line 105; used 38 times

- in line 229, 253-257(2), 279, 298, 316-320(2), 340, 355, 378, 394, 683-684(2)
- in /usr/src/new/rcs/src/rcsgen.c line 186, 195
- in /usr/src/new/rcs/src/rcslex.c line 229, 253-257(2), 279, 298, 316-320(2), 340, 355, 378, 394, 683-684(2)
- in /usr/src/new/rcs/src/rcssyn.c line 174-176(2), 245, 330, 357, 534
- in /usr/src/new/rcs/src/rlog.c line 344-348(2), 495-500(2)

nwarn defined in line 117; used 2 times

- in line 222, 588

quietflag defined in line 121; used 1 times

- in line 600

rcsid defined in line 5; never used
rewriteflag defined in line 127; used 27 times

- in line 225, 263, 274, 285, 305, 326, 407, 473-476(2), 488-489(2), 682
- in /usr/src/new/rcs/src/ci.c line 327, 446, 462
- in /usr/src/new/rcs/src/co.c line 245, 317
- in /usr/src/new/rcs/src/rcs.c line 422, 539, 820, 828
- in /usr/src/new/rcs/src/rcsedit.c line 211, 224, 263
- in /usr/src/new/rcs/src/rcsgen.c line 236, 242
- in /usr/src/new/rcs/src/rlog.c line 248

Last modified: 1988-02-18 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1710 |