Annotation of src/usr.bin/lex/sym.c, Revision 1.9
1.9 ! mmcc 1: /* $OpenBSD: sym.c,v 1.8 2015/11/19 23:20:34 tedu 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.8 tedu 99: malloc (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)
1.9 ! mmcc 125: u_char ccltxt[];
1.7 tedu 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)
1.9 ! mmcc 143: u_char ccltxt[];
1.7 tedu 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;
1.9 ! mmcc 198: u_char definition[];
1.7 tedu 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.9 ! mmcc 213: u_char *ndlookup (nd)
1.7 tedu 214: const char *nd;
215: {
1.9 ! mmcc 216: return (u_char *) findsym (nd, ndtbl, NAME_TABLE_HASH_SIZE)->str_val;
1.7 tedu 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: }