[BACK]Return to sym.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / lex

Annotation of src/usr.bin/lex/sym.c, Revision 1.7

1.7     ! tedu        1: /*     $OpenBSD: sym.c,v 1.6 2003/06/04 17:34:44 millert Exp $ */
1.2       deraadt     2:
1.1       deraadt     3: /* sym - symbol table routines */
                      4:
1.7     ! tedu        5: /*  Copyright (c) 1990 The Regents of the University of California. */
        !             6: /*  All rights reserved. */
        !             7:
        !             8: /*  This code is derived from software contributed to Berkeley by */
        !             9: /*  Vern Paxson. */
1.1       deraadt    10:
1.7     ! tedu       11: /*  The United States Government has rights in this work pursuant */
        !            12: /*  to contract no. DE-AC03-76SF00098 between the United States */
        !            13: /*  Department of Energy and the University of California. */
        !            14:
        !            15: /*  This file is part of flex. */
        !            16:
        !            17: /*  Redistribution and use in source and binary forms, with or without */
        !            18: /*  modification, are permitted provided that the following conditions */
        !            19: /*  are met: */
        !            20:
        !            21: /*  1. Redistributions of source code must retain the above copyright */
        !            22: /*     notice, this list of conditions and the following disclaimer. */
        !            23: /*  2. Redistributions in binary form must reproduce the above copyright */
        !            24: /*     notice, this list of conditions and the following disclaimer in the */
        !            25: /*     documentation and/or other materials provided with the distribution. */
        !            26:
        !            27: /*  Neither the name of the University nor the names of its contributors */
        !            28: /*  may be used to endorse or promote products derived from this software */
        !            29: /*  without specific prior written permission. */
        !            30:
        !            31: /*  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
        !            32: /*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
        !            33: /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
        !            34: /*  PURPOSE. */
1.1       deraadt    35:
                     36: #include "flexdef.h"
                     37:
1.7     ! tedu       38: /* Variables for symbol tables:
        !            39:  * sctbl - start-condition symbol table
        !            40:  * ndtbl - name-definition symbol table
        !            41:  * ccltab - character class text symbol table
        !            42:  */
1.1       deraadt    43:
1.7     ! tedu       44: struct hash_entry {
        !            45:        struct hash_entry *prev, *next;
        !            46:        char   *name;
        !            47:        char   *str_val;
        !            48:        int     int_val;
        !            49: };
        !            50:
        !            51: typedef struct hash_entry **hash_table;
        !            52:
        !            53: #define NAME_TABLE_HASH_SIZE 101
        !            54: #define START_COND_HASH_SIZE 101
        !            55: #define CCL_HASH_SIZE 101
        !            56:
        !            57: static struct hash_entry *ndtbl[NAME_TABLE_HASH_SIZE];
        !            58: static struct hash_entry *sctbl[START_COND_HASH_SIZE];
        !            59: static struct hash_entry *ccltab[CCL_HASH_SIZE];
1.1       deraadt    60:
                     61:
1.7     ! tedu       62: /* declare functions that have forward references */
1.1       deraadt    63:
1.7     ! tedu       64: static int addsym PROTO ((char[], char *, int, hash_table, int));
        !            65: static struct hash_entry *findsym PROTO ((const char *sym,
        !            66:                                          hash_table table,
1.1       deraadt    67:
1.7     ! tedu       68:                                          int table_size));
        !            69: static int hashfunct PROTO ((const char *, int));
1.1       deraadt    70:
                     71:
                     72: /* addsym - add symbol and definitions to symbol table
                     73:  *
                     74:  * -1 is returned if the symbol already exists, and the change not made.
                     75:  */
                     76:
1.7     ! tedu       77: static int addsym (sym, str_def, int_def, table, table_size)
        !            78:      char sym[];
        !            79:      char   *str_def;
        !            80:      int     int_def;
        !            81:      hash_table table;
        !            82:      int     table_size;
        !            83: {
        !            84:        int     hash_val = hashfunct (sym, table_size);
1.5       mpech      85:        struct hash_entry *sym_entry = table[hash_val];
                     86:        struct hash_entry *new_entry;
                     87:        struct hash_entry *successor;
1.1       deraadt    88:
1.7     ! tedu       89:        while (sym_entry) {
        !            90:                if (!strcmp (sym, sym_entry->name)) {   /* entry already exists */
1.1       deraadt    91:                        return -1;
1.7     ! tedu       92:                }
1.1       deraadt    93:
                     94:                sym_entry = sym_entry->next;
1.7     ! tedu       95:        }
1.1       deraadt    96:
                     97:        /* create new entry */
                     98:        new_entry = (struct hash_entry *)
1.7     ! tedu       99:                flex_alloc (sizeof (struct hash_entry));
1.1       deraadt   100:
1.7     ! tedu      101:        if (new_entry == NULL)
        !           102:                flexfatal (_("symbol table memory allocation failed"));
1.1       deraadt   103:
1.7     ! tedu      104:        if ((successor = table[hash_val]) != 0) {
1.1       deraadt   105:                new_entry->next = successor;
                    106:                successor->prev = new_entry;
1.7     ! tedu      107:        }
1.1       deraadt   108:        else
                    109:                new_entry->next = NULL;
                    110:
                    111:        new_entry->prev = NULL;
                    112:        new_entry->name = sym;
                    113:        new_entry->str_val = str_def;
                    114:        new_entry->int_val = int_def;
                    115:
                    116:        table[hash_val] = new_entry;
                    117:
                    118:        return 0;
1.7     ! tedu      119: }
1.1       deraadt   120:
                    121:
                    122: /* cclinstal - save the text of a character class */
                    123:
1.7     ! tedu      124: void    cclinstal (ccltxt, cclnum)
        !           125:      Char    ccltxt[];
        !           126:      int     cclnum;
        !           127: {
1.1       deraadt   128:        /* We don't bother checking the return status because we are not
                    129:         * called unless the symbol is new.
                    130:         */
                    131:
1.7     ! tedu      132:        (void) addsym ((char *) copy_unsigned_string (ccltxt),
        !           133:                       (char *) 0, cclnum, ccltab, CCL_HASH_SIZE);
        !           134: }
1.1       deraadt   135:
                    136:
                    137: /* ccllookup - lookup the number associated with character class text
                    138:  *
                    139:  * Returns 0 if there's no CCL associated with the text.
                    140:  */
                    141:
1.7     ! tedu      142: int     ccllookup (ccltxt)
        !           143:      Char    ccltxt[];
        !           144: {
        !           145:        return findsym ((char *) ccltxt, ccltab, CCL_HASH_SIZE)->int_val;
        !           146: }
1.1       deraadt   147:
                    148:
                    149: /* findsym - find symbol in symbol table */
                    150:
1.7     ! tedu      151: static struct hash_entry *findsym (sym, table, table_size)
        !           152:      const char *sym;
        !           153:      hash_table table;
        !           154:      int     table_size;
        !           155: {
        !           156:        static struct hash_entry empty_entry = {
1.1       deraadt   157:                (struct hash_entry *) 0, (struct hash_entry *) 0,
                    158:                (char *) 0, (char *) 0, 0,
1.7     ! tedu      159:        };
1.5       mpech     160:        struct hash_entry *sym_entry =
1.1       deraadt   161:
1.7     ! tedu      162:                table[hashfunct (sym, table_size)];
        !           163:
        !           164:        while (sym_entry) {
        !           165:                if (!strcmp (sym, sym_entry->name))
1.1       deraadt   166:                        return sym_entry;
                    167:                sym_entry = sym_entry->next;
1.7     ! tedu      168:        }
1.1       deraadt   169:
                    170:        return &empty_entry;
1.7     ! tedu      171: }
1.1       deraadt   172:
                    173: /* hashfunct - compute the hash value for "str" and hash size "hash_size" */
                    174:
1.7     ! tedu      175: static int hashfunct (str, hash_size)
        !           176:      const char *str;
        !           177:      int     hash_size;
        !           178: {
1.5       mpech     179:        int hashval;
                    180:        int locstr;
1.1       deraadt   181:
                    182:        hashval = 0;
                    183:        locstr = 0;
                    184:
1.7     ! tedu      185:        while (str[locstr]) {
1.1       deraadt   186:                hashval = (hashval << 1) + (unsigned char) str[locstr++];
                    187:                hashval %= hash_size;
1.7     ! tedu      188:        }
1.1       deraadt   189:
                    190:        return hashval;
1.7     ! tedu      191: }
1.1       deraadt   192:
                    193:
                    194: /* ndinstal - install a name definition */
                    195:
1.7     ! tedu      196: void    ndinstal (name, definition)
        !           197:      const char *name;
        !           198:      Char    definition[];
        !           199: {
        !           200:
        !           201:        if (addsym (copy_string (name),
        !           202:                    (char *) copy_unsigned_string (definition), 0,
        !           203:                    ndtbl, NAME_TABLE_HASH_SIZE))
        !           204:                        synerr (_("name defined twice"));
        !           205: }
1.1       deraadt   206:
                    207:
                    208: /* ndlookup - lookup a name definition
                    209:  *
                    210:  * Returns a nil pointer if the name definition does not exist.
                    211:  */
                    212:
1.7     ! tedu      213: Char   *ndlookup (nd)
        !           214:      const char *nd;
        !           215: {
        !           216:        return (Char *) findsym (nd, ndtbl, NAME_TABLE_HASH_SIZE)->str_val;
        !           217: }
1.1       deraadt   218:
                    219:
                    220: /* scextend - increase the maximum number of start conditions */
                    221:
1.7     ! tedu      222: void    scextend ()
        !           223: {
1.1       deraadt   224:        current_max_scs += MAX_SCS_INCREMENT;
                    225:
                    226:        ++num_reallocs;
                    227:
1.7     ! tedu      228:        scset = reallocate_integer_array (scset, current_max_scs);
        !           229:        scbol = reallocate_integer_array (scbol, current_max_scs);
        !           230:        scxclu = reallocate_integer_array (scxclu, current_max_scs);
        !           231:        sceof = reallocate_integer_array (sceof, current_max_scs);
        !           232:        scname = reallocate_char_ptr_array (scname, current_max_scs);
        !           233: }
1.1       deraadt   234:
                    235:
                    236: /* scinstal - make a start condition
                    237:  *
                    238:  * NOTE
                    239:  *    The start condition is "exclusive" if xcluflg is true.
                    240:  */
                    241:
1.7     ! tedu      242: void    scinstal (str, xcluflg)
        !           243:      const char *str;
        !           244:      int     xcluflg;
        !           245: {
        !           246:
        !           247:        if (++lastsc >= current_max_scs)
        !           248:                scextend ();
        !           249:
        !           250:        scname[lastsc] = copy_string (str);
        !           251:
        !           252:        if (addsym (scname[lastsc], (char *) 0, lastsc,
        !           253:                    sctbl, START_COND_HASH_SIZE))
        !           254:                        format_pinpoint_message (_
        !           255:                                                 ("start condition %s declared twice"),
        !           256: str);
1.1       deraadt   257:
1.7     ! tedu      258:        scset[lastsc] = mkstate (SYM_EPSILON);
        !           259:        scbol[lastsc] = mkstate (SYM_EPSILON);
1.1       deraadt   260:        scxclu[lastsc] = xcluflg;
                    261:        sceof[lastsc] = false;
1.7     ! tedu      262: }
1.1       deraadt   263:
                    264:
                    265: /* sclookup - lookup the number associated with a start condition
                    266:  *
                    267:  * Returns 0 if no such start condition.
                    268:  */
                    269:
1.7     ! tedu      270: int     sclookup (str)
        !           271:      const char *str;
        !           272: {
        !           273:        return findsym (str, sctbl, START_COND_HASH_SIZE)->int_val;
        !           274: }