Annotation of coherent/e/bin/ckermit/ckwart.c, revision 1.1

1.1     ! root        1: char *wartv = "Wart Version 2A(009) 14 Jan 92";
        !             2: 
        !             3: #ifdef MDEBUG
        !             4: /* Use the real ones in this module only */
        !             5: #ifdef malloc
        !             6: #undef malloc
        !             7: #endif /* malloc */
        !             8: #ifdef calloc
        !             9: #undef calloc
        !            10: #endif /* calloc */
        !            11: #ifdef realloc
        !            12: #undef realloc
        !            13: #endif /* realloc */
        !            14: #ifdef free
        !            15: #undef free
        !            16: #endif /* free */
        !            17: #endif /* MDEBUG */
        !            18: 
        !            19: #ifdef MAC
        !            20: #define VOID void
        !            21: #endif /* MAC */
        !            22: 
        !            23: /* W A R T */
        !            24: 
        !            25: /*
        !            26:   A small subset of "lex".
        !            27: 
        !            28:   Authors: Jeff Damens, Frank da Cruz
        !            29:   Columbia University Center for Computing Activites.
        !            30:   First released November 1984.
        !            31:   Copyright (C) 1984, 1992, Trustees of Columbia University in the City of New
        !            32:   York.  Permission is granted to any individual or institution to use this
        !            33:   software as long as it is not sold for profit.  This copyright notice must be
        !            34:   retained.  This software may not be included in commercial products without
        !            35:   written permission of Columbia University.
        !            36: */
        !            37: 
        !            38: /*
        !            39:  * input format is:
        !            40:  *  lines to be copied | %state <state names...>
        !            41:  *  %%
        !            42:  * <state> | <state,state,...> CHAR  { actions }
        !            43:  * ...
        !            44:  *  %%
        !            45:  *  more lines to be copied
        !            46:  */
        !            47: 
        !            48: #include "ckcdeb.h"                    /* Includes */
        !            49: 
        !            50: /*
        !            51:  The following "char" should be changed to "short", "int", or "long" if your
        !            52:  wart program will generate more than 127 states.  Since wart is used mainly
        !            53:  with C-Kermit, which has about 50 states, "char" is adequate.  This 
        !            54:  keeps the program about 3K-4K smaller.
        !            55: */
        !            56: 
        !            57: #define TBL_TYPE "char"                        /* C data type of state table */
        !            58: 
        !            59: #define C_L 014                                /* Formfeed */
        !            60: 
        !            61: #define SEP 1                          /* Token types */
        !            62: #define LBRACK 2
        !            63: #define RBRACK 3
        !            64: #define WORD 4
        !            65: #define COMMA 5
        !            66: 
        !            67: /* Storage sizes */
        !            68: 
        !            69: #define MAXSTATES 50                   /* max number of states */
        !            70: #define MAXWORD 50                     /* max # of chars/word */
        !            71: #define SBYTES ((MAXSTATES+6)/8)       /* # of bytes for state bitmask */
        !            72: 
        !            73: /* Name of wart function in generated program */
        !            74: 
        !            75: #ifndef FNAME
        !            76: #define FNAME "wart"
        !            77: #endif /* FNAME */
        !            78: 
        !            79: /* Structure for state information */
        !            80: 
        !            81: struct transx {
        !            82:     CHAR states[SBYTES];               /* included states */
        !            83:     int anyst;                         /* true if this good from any state */
        !            84:     CHAR inchr;                                /* input character */
        !            85:     int actno;                         /* associated action */
        !            86:     struct transx *nxt;
        !            87: };                                     /* next transition */
        !            88: typedef struct transx *trans;
        !            89: 
        !            90: /* Function prototypes */
        !            91: 
        !            92: _PROTOTYP( VOID setwstate, (int, trans) );
        !            93: _PROTOTYP( int teststate, (int, trans) );
        !            94: _PROTOTYP( trans rdinput, (FILE *, FILE *) );
        !            95: _PROTOTYP( VOID initial, (FILE *, FILE *) );
        !            96: _PROTOTYP( int isin, (char *, int) );
        !            97: _PROTOTYP( int isword, (int) );
        !            98: _PROTOTYP( VOID rdword, (FILE *, char *) );
        !            99: _PROTOTYP( VOID rdstates, (FILE *, FILE *) );
        !           100: _PROTOTYP( trans newtrans, (void) );
        !           101: _PROTOTYP( trans rdrules, (FILE *, FILE *) );
        !           102: _PROTOTYP( VOID statelist, (FILE *, trans) );
        !           103: _PROTOTYP( VOID copyact, (FILE *, FILE *, int) );
        !           104: _PROTOTYP( int faction, (trans, int, int) );
        !           105: _PROTOTYP( VOID emptytbl, (void) );
        !           106: _PROTOTYP( VOID addaction, (int, int, int) );
        !           107: _PROTOTYP( VOID writetbl, (FILE *) );
        !           108: _PROTOTYP( VOID warray, (FILE *, char *, int [], int, char *) );
        !           109: _PROTOTYP( VOID fatal, (char *) );
        !           110: _PROTOTYP( VOID prolog, (FILE *) );
        !           111: _PROTOTYP( VOID epilogue, (FILE *) );
        !           112: _PROTOTYP( VOID copyrest, (FILE *, FILE *) );
        !           113: _PROTOTYP( int gettoken, (FILE *) );
        !           114: _PROTOTYP( VOID rdcmnt, (FILE *) );
        !           115: _PROTOTYP( VOID clrhash, (void) );
        !           116: _PROTOTYP( int hash, (char *) );
        !           117: _PROTOTYP( VOID enter, (char *, int) );
        !           118: _PROTOTYP( int lkup, (char *) );
        !           119: _PROTOTYP( static char* copy, (char *s) );
        !           120: 
        !           121: /* Variables and tables */
        !           122: 
        !           123: /* lt 1992-10-08 Begin
        !           124:  * provide definition for deblog variable
        !           125:  * ckcdeb.h declares as extern. DECC AXP is strict about ref/def model
        !           126:  * Variable is unused herein, to the best of my knowledge.
        !           127:  */
        !           128: #ifdef VMS
        !           129: int deblog;
        !           130: #endif /* VMS */
        !           131: /* lt 1992-10-08 End
        !           132:  */
        !           133: 
        !           134: static int lines, nstates, nacts;
        !           135: 
        !           136: static char tokval[MAXWORD];
        !           137: 
        !           138: static int tbl[MAXSTATES*96];
        !           139: 
        !           140: char *tbl_type = TBL_TYPE;
        !           141: 
        !           142: char *txt1 = "\n#define BEGIN state =\n\nint state = 0;\n\nint\n";
        !           143: 
        !           144: char *fname = FNAME;                   /* Generated function name goes here */
        !           145: 
        !           146: /* rest of program... */
        !           147: 
        !           148: char *txt2 = "()\n\
        !           149: {\n\
        !           150:     int c,actno;\n\
        !           151:     extern ";
        !           152: 
        !           153: /* Data type of state table is inserted here (short or int) */
        !           154: 
        !           155: char *txt2a = " tbl[];\n    while (1) {\n      c = input() - 32;\n\
        !           156:         if (c < 0 || c > 95) c = 0;\n";
        !           157: 
        !           158: char *txt2b = "        if ((actno = tbl[c + state*96]) != -1)\n\
        !           159:            switch(actno) {\n";
        !           160: 
        !           161: /* this program's output goes here, followed by final text... */
        !           162: 
        !           163: char *txt3 = "\n           }\n    }\n}\n\n";
        !           164: 
        !           165: 
        !           166: /*
        !           167:  * turn on the bit associated with the given state
        !           168:  *
        !           169:  */
        !           170: VOID
        !           171: setwstate(state,t) int state; trans t; {
        !           172:     int idx,msk;
        !           173:     idx = state/8;                     /* byte associated with state */
        !           174:     msk = 0x80 >> (state % 8);         /* bit mask for state */
        !           175:     t->states[idx] |= msk;
        !           176: }
        !           177: 
        !           178: /*
        !           179:  * see if the state is involved in the transition
        !           180:  *
        !           181:  */
        !           182: int
        !           183: teststate(state,t) int state; trans t; {
        !           184:     int idx,msk;
        !           185:     idx = state/8;
        !           186:     msk = 0x80 >> (state % 8);
        !           187:     return(t->states[idx] & msk);
        !           188: }
        !           189: 
        !           190: 
        !           191: /*
        !           192:  * read input from here...
        !           193:  *
        !           194:  */
        !           195: 
        !           196: trans
        !           197: rdinput(infp,outfp) FILE *infp,*outfp; {
        !           198:     trans x,rdrules();
        !           199:     lines = 1;                         /* line counter */
        !           200:     nstates = 0;                       /* no states */
        !           201:     nacts = 0;                         /* no actions yet */
        !           202:     fprintf(outfp,"\n%c* WARNING -- This C source program generated by ",'/');
        !           203:     fprintf(outfp,"Wart preprocessor. */\n");
        !           204:     fprintf(outfp,"%c* Do not edit this file; edit the Wart-format ",'/');
        !           205:     fprintf(outfp,"source file instead, */\n");
        !           206:     fprintf(outfp,"%c* and then run it through Wart to produce a new ",'/');
        !           207:     fprintf(outfp,"C source file.     */\n\n");
        !           208:     fprintf(outfp,"%c* Wart Version Info: */\n",'/');
        !           209:     fprintf(outfp,"char *wartv = \"%s\";\n\n",wartv);
        !           210: 
        !           211:     initial(infp,outfp);               /* read state names, initial defs */
        !           212:     prolog(outfp);                     /* write out our initial code */
        !           213:     x = rdrules(infp,outfp);           /* read rules */
        !           214:     epilogue(outfp);                   /* write out epilogue code */
        !           215:     return(x);
        !           216: }
        !           217: 
        !           218: 
        !           219: /*
        !           220:  * initial - read initial definitions and state names.  Returns
        !           221:  * on EOF or %%.
        !           222:  *
        !           223:  */
        !           224: VOID
        !           225: initial(infp,outfp) FILE *infp, *outfp; {
        !           226:     int c;
        !           227:     char wordbuf[MAXWORD];
        !           228:     while ((c = getc(infp)) != EOF) {
        !           229:        if (c == '%') {
        !           230:            rdword(infp,wordbuf);
        !           231:            if (strcmp(wordbuf,"states") == 0)
        !           232:              rdstates(infp,outfp);
        !           233:            else if (strcmp(wordbuf,"%") == 0) return;
        !           234:            else fprintf(outfp,"%%%s",wordbuf);
        !           235:        }
        !           236:        else putc(c,outfp);
        !           237:        if (c == '\n') lines++;
        !           238:     }
        !           239: }
        !           240: 
        !           241: /*
        !           242:  * boolean function to tell if the given character can be part of
        !           243:  * a word.
        !           244:  *
        !           245:  */
        !           246: int
        !           247: isin(s,c) char *s; int c; {
        !           248:     for (; *s != '\0'; s++)
        !           249:       if (*s == (char) c) return(1);
        !           250:     return(0);
        !           251: }
        !           252: int
        !           253: isword(c) int c; {
        !           254:     static char special[] = ".%_-$@";  /* these are allowable */
        !           255:     return(isalnum(c) || isin(special,c));
        !           256: }
        !           257: 
        !           258: /*
        !           259:  * read the next word into the given buffer.
        !           260:  *
        !           261:  */
        !           262: VOID
        !           263: rdword(fp,buf) FILE *fp; char *buf; {
        !           264:     int len = 0,c;
        !           265:     while (isword(c = getc(fp)) && ++len < MAXWORD) *buf++ = (char) c;
        !           266:     *buf++ = '\0';                     /* tie off word */
        !           267:     ungetc(c,fp);                      /* put break char back */
        !           268: }
        !           269: 
        !           270: /*
        !           271:  * read state names, up to a newline.
        !           272:  *
        !           273:  */
        !           274: VOID
        !           275: rdstates(fp,ofp) FILE *fp,*ofp; {
        !           276:     int c;
        !           277:     char wordbuf[MAXWORD];
        !           278:     while ((c = getc(fp)) != EOF && c != '\n')   {
        !           279:        if (isspace(c) || c == C_L) continue;   /* skip whitespace */
        !           280:        ungetc(c,fp);                   /* put char back */
        !           281:        rdword(fp,wordbuf);             /* read the whole word */
        !           282:        enter(wordbuf,++nstates);       /* put into symbol tbl */
        !           283:        fprintf(ofp,"#define %s %d\n",wordbuf,nstates);
        !           284:     }
        !           285:     lines++;
        !           286: }
        !           287:                
        !           288: /*
        !           289:  * allocate a new, empty transition node
        !           290:  *
        !           291:  */
        !           292: trans
        !           293: newtrans() {
        !           294:     trans new;
        !           295:     int i;
        !           296:     new = (trans) malloc(sizeof (struct transx));
        !           297:     for (i=0; i<SBYTES; i++) new->states[i] = 0;
        !           298:     new->anyst = 0;
        !           299:     new->nxt = NULL;
        !           300:     return(new);
        !           301: }
        !           302: 
        !           303: 
        !           304: /*
        !           305:  * read all the rules.
        !           306:  *
        !           307:  */
        !           308: 
        !           309: trans
        !           310: rdrules(fp,out) FILE *fp,*out; {
        !           311:     trans head,cur,prev;
        !           312:     int curtok;
        !           313:     head = cur = prev = NULL;
        !           314:     while ((curtok = gettoken(fp)) != SEP) 
        !           315: 
        !           316:       switch(curtok) {
        !           317:        case LBRACK:
        !           318:          if (cur == NULL)
        !           319:            cur = newtrans();
        !           320:          else
        !           321:            fatal("duplicate state list");
        !           322:          statelist(fp,cur);            /* set states */
        !           323:          continue;                     /* prepare to read char */
        !           324:          
        !           325:        case WORD:
        !           326:          if ((int)strlen(tokval) != 1)
        !           327:            fatal("multiple chars in state");
        !           328:          if (cur == NULL) {
        !           329:              cur = newtrans();
        !           330:              cur->anyst = 1;
        !           331:          }
        !           332:          cur->actno = ++nacts;
        !           333:          cur->inchr = (char) (tokval[0] - 32);
        !           334:          if (head == NULL)
        !           335:            head = cur;
        !           336:          else
        !           337:            prev->nxt = cur;
        !           338:          prev = cur;
        !           339:          cur = NULL;
        !           340:          copyact(fp,out,nacts);
        !           341:          break; 
        !           342:        default: fatal("bad input format");
        !           343:       }
        !           344:     return(head);
        !           345: }
        !           346: 
        !           347: /*
        !           348:  * read a list of (comma-separated) states, set them in the
        !           349:  * given transition.
        !           350:  *
        !           351:  */
        !           352: VOID
        !           353: statelist(fp,t) FILE *fp; trans t; {
        !           354:     int curtok,sval;
        !           355:     curtok = COMMA;
        !           356:     while (curtok != RBRACK) {
        !           357:        if (curtok != COMMA) fatal("missing comma");
        !           358:        if ((curtok = gettoken(fp)) != WORD) fatal("missing state name");
        !           359:         if ((sval = lkup(tokval)) == -1) {
        !           360:            fprintf(stderr,"state %s undefined\n",tokval);
        !           361:            fatal("undefined state");
        !           362:        }
        !           363:         setwstate(sval,t);     
        !           364:        curtok = gettoken(fp);
        !           365:     }
        !           366: }
        !           367: 
        !           368: /*
        !           369:  * copy an action from the input to the output file
        !           370:  *
        !           371:  */
        !           372: VOID
        !           373: copyact(inp,outp,actno) FILE *inp,*outp; int actno; {
        !           374:     int c,bcnt;
        !           375:     fprintf(outp,"case %d:\n",actno);
        !           376:     while (c = getc(inp), (isspace(c) || c == C_L))
        !           377:       if (c == '\n') lines++;
        !           378:     if (c == '{') {
        !           379:        bcnt = 1;
        !           380:        fputs("    {",outp);
        !           381:        while (bcnt > 0 && (c = getc(inp)) != EOF) {
        !           382:            if (c == '{') bcnt++;
        !           383:            else if (c == '}') bcnt--;
        !           384:            else if (c == '\n') lines++;
        !           385:            putc(c,outp);
        !           386:        }
        !           387:        if (bcnt > 0) fatal("action doesn't end");
        !           388:     } else {
        !           389:        while (c != '\n' && c != EOF) {
        !           390:            putc(c,outp);
        !           391:            c = getc(inp);
        !           392:        }
        !           393:        lines++;
        !           394:     }
        !           395:     fprintf(outp,"\n    break;\n");
        !           396: }
        !           397: 
        !           398: /*
        !           399:  * find the action associated with a given character and state.
        !           400:  * returns -1 if one can't be found.
        !           401:  *
        !           402:  */
        !           403: int
        !           404: faction(hd,state,chr) trans hd; int state,chr; {
        !           405:     while (hd != NULL) {
        !           406:        if (hd->anyst || teststate(state,hd))
        !           407:          if (hd->inchr == ('.' - 32) || hd->inchr == (char) chr)
        !           408:            return(hd->actno);
        !           409:        hd = hd->nxt;
        !           410:     }
        !           411:     return(-1);
        !           412: }
        !           413: 
        !           414: /*
        !           415:  * empty the table...
        !           416:  *
        !           417:  */
        !           418: VOID
        !           419: emptytbl() {
        !           420:     int i;
        !           421:     for (i=0; i<nstates*96; i++) tbl[i] = -1;
        !           422: }
        !           423: 
        !           424: /*
        !           425:  * add the specified action to the output for the given state and chr.
        !           426:  *
        !           427:  */
        !           428: VOID
        !           429: addaction(act,state,chr) int act,state,chr; {
        !           430:     tbl[state*96 + chr] = act;
        !           431: }
        !           432: 
        !           433: VOID
        !           434: writetbl(fp) FILE *fp; {
        !           435:     warray(fp,"tbl",tbl,96*(nstates+1),TBL_TYPE);
        !           436: }
        !           437: 
        !           438: 
        !           439: /*
        !           440:  * write an array to the output file, given its name and size.
        !           441:  *
        !           442:  */
        !           443: VOID
        !           444: warray(fp,nam,cont,siz,typ) FILE *fp; char *nam; int cont[],siz; char *typ; {
        !           445:     int i;
        !           446:     fprintf(fp,"%s %s[] = {\n",typ,nam);
        !           447:     for (i = 0; i < siz - 1; ) {
        !           448:        fprintf(fp,"%2d, ",cont[i]);
        !           449:        if ((++i % 16) == 0) putc('\n',fp);
        !           450:     }
        !           451:     fprintf(fp,"%2d ",cont[siz-1]);
        !           452:     fprintf(fp,"};\n");
        !           453: }
        !           454: 
        !           455: VOID
        !           456: main(argc,argv) int argc; char *argv[]; {
        !           457:     trans head;
        !           458:     int state,c;
        !           459:     FILE *infile,*outfile;
        !           460: 
        !           461:     if (argc > 1) {
        !           462:        if ((infile = fopen(argv[1],"r")) == NULL) {
        !           463:            fprintf(stderr,"Can't open %s\n",argv[1]);
        !           464:            fatal("unreadable input file");
        !           465:        }
        !           466:     } else infile = stdin;
        !           467: 
        !           468:     if (argc > 2) {
        !           469:        if ((outfile = fopen(argv[2],"w")) == NULL) {
        !           470:            fprintf(stderr,"Can't write to %s\n",argv[2]);
        !           471:            fatal("bad output file");
        !           472:        }
        !           473:     } else outfile = stdout;
        !           474: 
        !           475:     clrhash();                         /* empty hash table */
        !           476:     head = rdinput(infile,outfile);    /* read input file */
        !           477:     emptytbl();                                /* empty our tables */
        !           478:     for (state = 0; state <= nstates; state++)
        !           479:       for (c = 1; c < 96; c++)         /* find actions, */
        !           480:        addaction(faction(head,state,c),state,c); /* add to tbl */
        !           481:     writetbl(outfile);
        !           482:     copyrest(infile,outfile);
        !           483:     printf("%d states, %d actions\n",nstates,nacts);
        !           484:     exit(GOOD_EXIT);
        !           485: }
        !           486: 
        !           487: 
        !           488: /*
        !           489:  * fatal error handler
        !           490:  *
        !           491:  */
        !           492: 
        !           493: VOID
        !           494: fatal(msg) char *msg; {
        !           495:     fprintf(stderr,"error in line %d: %s\n",lines,msg);
        !           496:     exit(BAD_EXIT);
        !           497: }
        !           498: 
        !           499: VOID
        !           500: prolog(outfp) FILE *outfp; {
        !           501:     int c;
        !           502:     while ((c = *txt1++)     != '\0') putc(c,outfp);
        !           503:     while ((c = *fname++)    != '\0') putc(c,outfp);
        !           504:     while ((c = *txt2++)     != '\0') putc(c,outfp);
        !           505:     while ((c = *tbl_type++) != '\0') putc(c,outfp);
        !           506:     while ((c = *txt2a++)    != '\0') putc(c,outfp);
        !           507:     while ((c = *txt2b++)    != '\0') putc(c,outfp);
        !           508: }
        !           509: 
        !           510: VOID
        !           511: epilogue(outfp) FILE *outfp; {
        !           512:     int c;
        !           513:     while ((c = *txt3++) != '\0') putc(c,outfp);
        !           514: }
        !           515: 
        !           516: VOID
        !           517: copyrest(in,out) FILE *in,*out; {
        !           518:     int c;
        !           519:     while ((c = getc(in)) != EOF) putc(c,out);
        !           520: }
        !           521: 
        !           522: /*
        !           523:  * gettoken - returns token type of next token, sets tokval
        !           524:  * to the string value of the token if appropriate.
        !           525:  *
        !           526:  */
        !           527: 
        !           528: int
        !           529: gettoken(fp) FILE *fp; {
        !           530:     int c;
        !           531:     while (1) {                                /* loop if reading comments... */
        !           532:        do {
        !           533:            c = getc(fp);
        !           534:            if (c == '\n') lines++;
        !           535:        } while ((isspace(c) || c == C_L)); /* skip whitespace */
        !           536:        switch(c) {
        !           537:          case EOF:
        !           538:            return(SEP);
        !           539:          case '%':
        !           540:            if ((c = getc(fp)) == '%') return(SEP);
        !           541:            tokval[0] = '%';
        !           542:            tokval[1] = (char) c;
        !           543:            rdword(fp,tokval+2);
        !           544:            return(WORD);
        !           545:          case '<':
        !           546:            return(LBRACK);
        !           547:          case '>':
        !           548:            return(RBRACK);
        !           549:          case ',':
        !           550:            return(COMMA);
        !           551:          case '/':
        !           552:            if ((c = getc(fp)) == '*') {
        !           553:                rdcmnt(fp);             /* skip over the comment */
        !           554:                continue;
        !           555:            } else {                    /* and keep looping */
        !           556:                ungetc(c,fp);           /* put this back into input */
        !           557:                c = '/';                /* put character back, fall thru */
        !           558:            }
        !           559: 
        !           560:          default:
        !           561:            if (isword(c)) {
        !           562:                ungetc(c,fp);
        !           563:                rdword(fp,tokval);
        !           564:                return(WORD);
        !           565:            } else fatal("Invalid character in input");
        !           566:        }
        !           567:     }
        !           568: }
        !           569: 
        !           570: /*
        !           571:  * skip over a comment
        !           572:  *
        !           573:  */
        !           574: 
        !           575: VOID
        !           576: rdcmnt(fp) FILE *fp; {
        !           577:     int c,star,prcnt;
        !           578:     prcnt = star = 0;                  /* no star seen yet */
        !           579:     while (!((c = getc(fp)) == '/' && star)) {
        !           580:        if (c == EOF || (prcnt && c == '%')) fatal("Unterminated comment");
        !           581:        prcnt = (c == '%');
        !           582:        star = (c == '*');
        !           583:        if (c == '\n') lines++;
        !           584:     }
        !           585: }
        !           586: 
        !           587: /*
        !           588:  * symbol table management for wart
        !           589:  *
        !           590:  * entry points:
        !           591:  *   clrhash - empty hash table.
        !           592:  *   enter - enter a name into the symbol table
        !           593:  *   lkup - find a name's value in the symbol table.
        !           594:  *
        !           595:  */
        !           596: 
        !           597: #define HASHSIZE 101                   /* # of entries in hash table */
        !           598: 
        !           599: struct sym {
        !           600:     char *name;                                /* symbol name */
        !           601:     int val;                           /* value */
        !           602:     struct sym *hnxt;                  /* next on collision chain */
        !           603: } *htab[HASHSIZE];                     /* the hash table */
        !           604: 
        !           605: /*
        !           606:  * empty the hash table before using it...
        !           607:  *
        !           608:  */
        !           609: VOID
        !           610: clrhash() {
        !           611:     int i;
        !           612:     for (i=0; i<HASHSIZE; i++) htab[i] = NULL;
        !           613: }
        !           614: 
        !           615: /*
        !           616:  * compute the value of the hash for a symbol
        !           617:  *
        !           618:  */
        !           619: int
        !           620: hash(name) char *name; {
        !           621:     int sum;
        !           622:     for (sum = 0; *name != '\0'; name++) sum += (sum + *name);
        !           623:     sum %= HASHSIZE;                   /* take sum mod hashsize */
        !           624:     if (sum < 0) sum += HASHSIZE;      /* disallow negative hash value */
        !           625:     return(sum);
        !           626: }
        !           627: 
        !           628: /*
        !           629:  * make a private copy of a string...
        !           630:  *
        !           631:  */
        !           632: static char*
        !           633: copy(s) char *s; {
        !           634:     char *new;
        !           635:     new = (char *) malloc((int)strlen(s) + 1);
        !           636:     strcpy(new,s);
        !           637:     return(new);
        !           638: }
        !           639: 
        !           640: /*
        !           641:  * enter state name into the hash table
        !           642:  *
        !           643:  */
        !           644: VOID
        !           645: enter(name,svalue) char *name; int svalue; {
        !           646:     int h;
        !           647:     struct sym *cur;
        !           648:     if (lkup(name) != -1) {
        !           649:        fprintf(stderr,"state \"%s\" appears twice...\n", name);
        !           650:        exit(BAD_EXIT);
        !           651:     }
        !           652:     h = hash(name);
        !           653:     cur = (struct sym *)malloc(sizeof (struct sym));
        !           654:     cur->name = copy(name);
        !           655:     cur->val = svalue;
        !           656:     cur->hnxt = htab[h];
        !           657:     htab[h] = cur;
        !           658: }
        !           659: 
        !           660: /*
        !           661:  * find name in the symbol table, return its value.  Returns -1
        !           662:  * if not found.
        !           663:  *
        !           664:  */
        !           665: int
        !           666: lkup(name) char *name; {
        !           667:     struct sym *cur;
        !           668:     for (cur = htab[hash(name)]; cur != NULL; cur = cur->hnxt)
        !           669:       if (strcmp(cur->name,name) == 0) return(cur->val);
        !           670:     return(-1);
        !           671: }
        !           672: 
        !           673: 

unix.superglobalmegacorp.com

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