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