Annotation of 43BSDTahoe/new/rcs/src/rcslex.c, revision 1.1

1.1     ! root        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

unix.superglobalmegacorp.com

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