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: }