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