This commit was manufactured by cvs2svn to create tag 'FreeBSD-release/1.0'.
[unix-history] / usr.bin / lex / sym.c
CommitLineData
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 30static 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
39int hashfunct PROTO((register char[], int));
40
41
42struct hash_entry *ndtbl[NAME_TABLE_HASH_SIZE];
43struct hash_entry *sctbl[START_COND_HASH_SIZE];
44struct hash_entry *ccltab[CCL_HASH_SIZE];
45
46struct 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
61int addsym( sym, str_def, int_def, table, table_size )
62register char sym[];
63char *str_def;
64int int_def;
65hash_table table;
66int 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
117void cclinstal( ccltxt, cclnum )
118Char ccltxt[];
119int 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
140int ccllookup( ccltxt )
141Char 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
158struct hash_entry *findsym( sym, table, table_size )
159register char sym[];
160hash_table table;
161int 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
189int hashfunct( str, hash_size )
190register char str[];
191int 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
215void ndinstal( nd, def )
216char nd[];
217Char 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
237Char *ndlookup( nd )
238char 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
256void scinstal( str, xcluflg )
257char str[];
258int 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
310int sclookup( str )
311char str[];
312
313 {
314 return ( findsym( str, sctbl, START_COND_HASH_SIZE )->int_val );
315 }