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

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

unix.superglobalmegacorp.com

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