Commit | Line | Data |
---|---|---|
15637ed4 RG |
1 | /* sym - symbol table routines */ |
2 | ||
3 | /*- | |
4 | * Copyright (c) 1990 The Regents of the University of California. | |
5 | * All rights reserved. | |
6 | * | |
7 | * This code is derived from software contributed to Berkeley by | |
78ed81a3 | 8 | * Vern Paxson. |
15637ed4 RG |
9 | * |
10 | * The United States Government has rights in this work pursuant | |
11 | * to contract no. DE-AC03-76SF00098 between the United States | |
12 | * Department of Energy and the University of California. | |
13 | * | |
78ed81a3 | 14 | * Redistribution and use in source and binary forms are permitted provided |
15 | * that: (1) source distributions retain this entire copyright notice and | |
16 | * comment, and (2) distributions including binaries display the following | |
17 | * acknowledgement: ``This product includes software developed by the | |
18 | * University of California, Berkeley and its contributors'' in the | |
19 | * documentation or other materials provided with the distribution and in | |
20 | * all advertising materials mentioning features or use of this software. | |
21 | * Neither the name of the University nor the names of its contributors may | |
22 | * be used to endorse or promote products derived from this software without | |
23 | * specific prior written permission. | |
24 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED | |
25 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF | |
26 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
15637ed4 RG |
27 | */ |
28 | ||
29 | #ifndef lint | |
78ed81a3 | 30 | static char rcsid[] = |
31 | "@(#) $Header: /usr/fsys/odin/a/vern/flex/RCS/sym.c,v 2.4 90/06/27 23:48:36 vern Exp $ (LBL)"; | |
32 | #endif | |
15637ed4 RG |
33 | |
34 | #include "flexdef.h" | |
35 | ||
78ed81a3 | 36 | |
15637ed4 RG |
37 | /* declare functions that have forward references */ |
38 | ||
39 | int hashfunct PROTO((register char[], int)); | |
40 | ||
41 | ||
42 | struct hash_entry *ndtbl[NAME_TABLE_HASH_SIZE]; | |
43 | struct hash_entry *sctbl[START_COND_HASH_SIZE]; | |
44 | struct hash_entry *ccltab[CCL_HASH_SIZE]; | |
45 | ||
46 | struct hash_entry *findsym(); | |
47 | ||
48 | ||
49 | /* addsym - add symbol and definitions to symbol table | |
50 | * | |
51 | * synopsis | |
52 | * char sym[], *str_def; | |
53 | * int int_def; | |
54 | * hash_table table; | |
55 | * int table_size; | |
56 | * 0 / -1 = addsym( sym, def, int_def, table, table_size ); | |
57 | * | |
58 | * -1 is returned if the symbol already exists, and the change not made. | |
59 | */ | |
60 | ||
61 | int addsym( sym, str_def, int_def, table, table_size ) | |
62 | register char sym[]; | |
63 | char *str_def; | |
64 | int int_def; | |
65 | hash_table table; | |
66 | int table_size; | |
67 | ||
68 | { | |
69 | int hash_val = hashfunct( sym, table_size ); | |
70 | register struct hash_entry *sym_entry = table[hash_val]; | |
71 | register struct hash_entry *new_entry; | |
72 | register struct hash_entry *successor; | |
73 | ||
74 | while ( sym_entry ) | |
75 | { | |
76 | if ( ! strcmp( sym, sym_entry->name ) ) | |
77 | { /* entry already exists */ | |
78 | return ( -1 ); | |
79 | } | |
80 | ||
81 | sym_entry = sym_entry->next; | |
82 | } | |
83 | ||
84 | /* create new entry */ | |
85 | new_entry = (struct hash_entry *) malloc( sizeof( struct hash_entry ) ); | |
86 | ||
87 | if ( new_entry == NULL ) | |
88 | flexfatal( "symbol table memory allocation failed" ); | |
89 | ||
90 | if ( (successor = table[hash_val]) ) | |
91 | { | |
92 | new_entry->next = successor; | |
93 | successor->prev = new_entry; | |
94 | } | |
95 | else | |
96 | new_entry->next = NULL; | |
97 | ||
98 | new_entry->prev = NULL; | |
99 | new_entry->name = sym; | |
100 | new_entry->str_val = str_def; | |
101 | new_entry->int_val = int_def; | |
102 | ||
103 | table[hash_val] = new_entry; | |
104 | ||
105 | return ( 0 ); | |
106 | } | |
107 | ||
108 | ||
109 | /* cclinstal - save the text of a character class | |
110 | * | |
111 | * synopsis | |
112 | * Char ccltxt[]; | |
113 | * int cclnum; | |
114 | * cclinstal( ccltxt, cclnum ); | |
115 | */ | |
116 | ||
117 | void cclinstal( ccltxt, cclnum ) | |
118 | Char ccltxt[]; | |
119 | int cclnum; | |
120 | ||
121 | { | |
122 | /* we don't bother checking the return status because we are not called | |
123 | * unless the symbol is new | |
124 | */ | |
125 | Char *copy_unsigned_string(); | |
126 | ||
127 | (void) addsym( (char *) copy_unsigned_string( ccltxt ), (char *) 0, cclnum, | |
128 | ccltab, CCL_HASH_SIZE ); | |
129 | } | |
130 | ||
131 | ||
132 | /* ccllookup - lookup the number associated with character class text | |
133 | * | |
134 | * synopsis | |
135 | * Char ccltxt[]; | |
136 | * int ccllookup, cclval; | |
137 | * cclval/0 = ccllookup( ccltxt ); | |
138 | */ | |
139 | ||
140 | int ccllookup( ccltxt ) | |
141 | Char ccltxt[]; | |
142 | ||
143 | { | |
144 | return ( findsym( (char *) ccltxt, ccltab, CCL_HASH_SIZE )->int_val ); | |
145 | } | |
146 | ||
147 | ||
148 | /* findsym - find symbol in symbol table | |
149 | * | |
150 | * synopsis | |
151 | * char sym[]; | |
152 | * hash_table table; | |
153 | * int table_size; | |
154 | * struct hash_entry *sym_entry, *findsym(); | |
155 | * sym_entry = findsym( sym, table, table_size ); | |
156 | */ | |
157 | ||
158 | struct hash_entry *findsym( sym, table, table_size ) | |
159 | register char sym[]; | |
160 | hash_table table; | |
161 | int table_size; | |
162 | ||
163 | { | |
164 | register struct hash_entry *sym_entry = table[hashfunct( sym, table_size )]; | |
165 | static struct hash_entry empty_entry = | |
166 | { | |
167 | (struct hash_entry *) 0, (struct hash_entry *) 0, NULL, NULL, 0, | |
168 | } ; | |
169 | ||
170 | while ( sym_entry ) | |
171 | { | |
172 | if ( ! strcmp( sym, sym_entry->name ) ) | |
173 | return ( sym_entry ); | |
174 | sym_entry = sym_entry->next; | |
175 | } | |
176 | ||
177 | return ( &empty_entry ); | |
178 | } | |
179 | ||
180 | ||
181 | /* hashfunct - compute the hash value for "str" and hash size "hash_size" | |
182 | * | |
183 | * synopsis | |
184 | * char str[]; | |
185 | * int hash_size, hash_val; | |
186 | * hash_val = hashfunct( str, hash_size ); | |
187 | */ | |
188 | ||
189 | int hashfunct( str, hash_size ) | |
190 | register char str[]; | |
191 | int hash_size; | |
192 | ||
193 | { | |
194 | register int hashval; | |
195 | register int locstr; | |
196 | ||
197 | hashval = 0; | |
198 | locstr = 0; | |
199 | ||
200 | while ( str[locstr] ) | |
78ed81a3 | 201 | hashval = ((hashval << 1) + (unsigned char) str[locstr++]) % hash_size; |
15637ed4 RG |
202 | |
203 | return ( hashval ); | |
204 | } | |
205 | ||
206 | ||
207 | /* ndinstal - install a name definition | |
208 | * | |
209 | * synopsis | |
210 | * char nd[]; | |
211 | * Char def[]; | |
212 | * ndinstal( nd, def ); | |
213 | */ | |
214 | ||
215 | void ndinstal( nd, def ) | |
216 | char nd[]; | |
217 | Char def[]; | |
218 | ||
219 | { | |
220 | char *copy_string(); | |
221 | Char *copy_unsigned_string(); | |
222 | ||
223 | if ( addsym( copy_string( nd ), (char *) copy_unsigned_string( def ), 0, | |
224 | ndtbl, NAME_TABLE_HASH_SIZE ) ) | |
225 | synerr( "name defined twice" ); | |
226 | } | |
227 | ||
228 | ||
229 | /* ndlookup - lookup a name definition | |
230 | * | |
231 | * synopsis | |
232 | * char nd[], *def; | |
233 | * char *ndlookup(); | |
234 | * def/NULL = ndlookup( nd ); | |
235 | */ | |
236 | ||
237 | Char *ndlookup( nd ) | |
238 | char nd[]; | |
239 | ||
240 | { | |
241 | return ( (Char *) findsym( nd, ndtbl, NAME_TABLE_HASH_SIZE )->str_val ); | |
242 | } | |
243 | ||
244 | ||
245 | /* scinstal - make a start condition | |
246 | * | |
247 | * synopsis | |
248 | * char str[]; | |
249 | * int xcluflg; | |
250 | * scinstal( str, xcluflg ); | |
251 | * | |
252 | * NOTE | |
253 | * the start condition is Exclusive if xcluflg is true | |
254 | */ | |
255 | ||
256 | void scinstal( str, xcluflg ) | |
257 | char str[]; | |
258 | int xcluflg; | |
259 | ||
260 | { | |
261 | char *copy_string(); | |
262 | ||
263 | /* bit of a hack. We know how the default start-condition is | |
264 | * declared, and don't put out a define for it, because it | |
265 | * would come out as "#define 0 1" | |
266 | */ | |
267 | /* actually, this is no longer the case. The default start-condition | |
268 | * is now called "INITIAL". But we keep the following for the sake | |
269 | * of future robustness. | |
270 | */ | |
271 | ||
272 | if ( strcmp( str, "0" ) ) | |
273 | printf( "#define %s %d\n", str, lastsc ); | |
274 | ||
275 | if ( ++lastsc >= current_max_scs ) | |
276 | { | |
277 | current_max_scs += MAX_SCS_INCREMENT; | |
278 | ||
279 | ++num_reallocs; | |
280 | ||
281 | scset = reallocate_integer_array( scset, current_max_scs ); | |
282 | scbol = reallocate_integer_array( scbol, current_max_scs ); | |
283 | scxclu = reallocate_integer_array( scxclu, current_max_scs ); | |
284 | sceof = reallocate_integer_array( sceof, current_max_scs ); | |
285 | scname = reallocate_char_ptr_array( scname, current_max_scs ); | |
286 | actvsc = reallocate_integer_array( actvsc, current_max_scs ); | |
287 | } | |
288 | ||
289 | scname[lastsc] = copy_string( str ); | |
290 | ||
291 | if ( addsym( scname[lastsc], (char *) 0, lastsc, | |
292 | sctbl, START_COND_HASH_SIZE ) ) | |
293 | format_pinpoint_message( "start condition %s declared twice", str ); | |
294 | ||
295 | scset[lastsc] = mkstate( SYM_EPSILON ); | |
296 | scbol[lastsc] = mkstate( SYM_EPSILON ); | |
297 | scxclu[lastsc] = xcluflg; | |
298 | sceof[lastsc] = false; | |
299 | } | |
300 | ||
301 | ||
302 | /* sclookup - lookup the number associated with a start condition | |
303 | * | |
304 | * synopsis | |
305 | * char str[], scnum; | |
306 | * int sclookup; | |
307 | * scnum/0 = sclookup( str ); | |
308 | */ | |
309 | ||
310 | int sclookup( str ) | |
311 | char str[]; | |
312 | ||
313 | { | |
314 | return ( findsym( str, sctbl, START_COND_HASH_SIZE )->int_val ); | |
315 | } |