1 |
|
|
/* $OpenBSD: sym.c,v 1.9 2015/11/19 23:34:56 mmcc Exp $ */ |
2 |
|
|
|
3 |
|
|
/* sym - symbol table routines */ |
4 |
|
|
|
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. */ |
10 |
|
|
|
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. */ |
35 |
|
|
|
36 |
|
|
#include "flexdef.h" |
37 |
|
|
|
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 |
|
|
*/ |
43 |
|
|
|
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]; |
60 |
|
|
|
61 |
|
|
|
62 |
|
|
/* declare functions that have forward references */ |
63 |
|
|
|
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, |
67 |
|
|
|
68 |
|
|
int table_size)); |
69 |
|
|
static int hashfunct PROTO ((const char *, int)); |
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 |
|
|
|
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 |
|
6220 |
int hash_val = hashfunct (sym, table_size); |
85 |
|
3110 |
struct hash_entry *sym_entry = table[hash_val]; |
86 |
|
|
struct hash_entry *new_entry; |
87 |
|
|
struct hash_entry *successor; |
88 |
|
|
|
89 |
✓✓ |
6874 |
while (sym_entry) { |
90 |
✓✓ |
2782 |
if (!strcmp (sym, sym_entry->name)) { /* entry already exists */ |
91 |
|
2455 |
return -1; |
92 |
|
|
} |
93 |
|
|
|
94 |
|
327 |
sym_entry = sym_entry->next; |
95 |
|
|
} |
96 |
|
|
|
97 |
|
|
/* create new entry */ |
98 |
|
655 |
new_entry = (struct hash_entry *) |
99 |
|
655 |
malloc (sizeof (struct hash_entry)); |
100 |
|
|
|
101 |
✗✓ |
655 |
if (new_entry == NULL) |
102 |
|
|
flexfatal (_("symbol table memory allocation failed")); |
103 |
|
|
|
104 |
✓✓ |
655 |
if ((successor = table[hash_val]) != 0) { |
105 |
|
201 |
new_entry->next = successor; |
106 |
|
201 |
successor->prev = new_entry; |
107 |
|
201 |
} |
108 |
|
|
else |
109 |
|
454 |
new_entry->next = NULL; |
110 |
|
|
|
111 |
|
655 |
new_entry->prev = NULL; |
112 |
|
655 |
new_entry->name = sym; |
113 |
|
655 |
new_entry->str_val = str_def; |
114 |
|
655 |
new_entry->int_val = int_def; |
115 |
|
|
|
116 |
|
655 |
table[hash_val] = new_entry; |
117 |
|
|
|
118 |
|
655 |
return 0; |
119 |
|
3110 |
} |
120 |
|
|
|
121 |
|
|
|
122 |
|
|
/* cclinstal - save the text of a character class */ |
123 |
|
|
|
124 |
|
|
void cclinstal (ccltxt, cclnum) |
125 |
|
|
u_char ccltxt[]; |
126 |
|
|
int cclnum; |
127 |
|
|
{ |
128 |
|
|
/* We don't bother checking the return status because we are not |
129 |
|
|
* called unless the symbol is new. |
130 |
|
|
*/ |
131 |
|
|
|
132 |
|
5032 |
(void) addsym ((char *) copy_unsigned_string (ccltxt), |
133 |
|
|
(char *) 0, cclnum, ccltab, CCL_HASH_SIZE); |
134 |
|
2516 |
} |
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 |
|
|
|
142 |
|
|
int ccllookup (ccltxt) |
143 |
|
|
u_char ccltxt[]; |
144 |
|
|
{ |
145 |
|
|
return findsym ((char *) ccltxt, ccltab, CCL_HASH_SIZE)->int_val; |
146 |
|
|
} |
147 |
|
|
|
148 |
|
|
|
149 |
|
|
/* findsym - find symbol in symbol table */ |
150 |
|
|
|
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 = { |
157 |
|
|
(struct hash_entry *) 0, (struct hash_entry *) 0, |
158 |
|
|
(char *) 0, (char *) 0, 0, |
159 |
|
|
}; |
160 |
|
|
struct hash_entry *sym_entry = |
161 |
|
|
|
162 |
|
2174 |
table[hashfunct (sym, table_size)]; |
163 |
|
|
|
164 |
✓✗ |
2404 |
while (sym_entry) { |
165 |
✓✓ |
1202 |
if (!strcmp (sym, sym_entry->name)) |
166 |
|
1087 |
return sym_entry; |
167 |
|
115 |
sym_entry = sym_entry->next; |
168 |
|
|
} |
169 |
|
|
|
170 |
|
|
return &empty_entry; |
171 |
|
1087 |
} |
172 |
|
|
|
173 |
|
|
/* hashfunct - compute the hash value for "str" and hash size "hash_size" */ |
174 |
|
|
|
175 |
|
|
static int hashfunct (str, hash_size) |
176 |
|
|
const char *str; |
177 |
|
|
int hash_size; |
178 |
|
|
{ |
179 |
|
|
int hashval; |
180 |
|
|
int locstr; |
181 |
|
|
|
182 |
|
|
hashval = 0; |
183 |
|
|
locstr = 0; |
184 |
|
|
|
185 |
✓✓ |
73049 |
while (str[locstr]) { |
186 |
|
30229 |
hashval = (hashval << 1) + (unsigned char) str[locstr++]; |
187 |
|
30229 |
hashval %= hash_size; |
188 |
|
|
} |
189 |
|
|
|
190 |
|
4197 |
return hashval; |
191 |
|
|
} |
192 |
|
|
|
193 |
|
|
|
194 |
|
|
/* ndinstal - install a name definition */ |
195 |
|
|
|
196 |
|
|
void ndinstal (name, definition) |
197 |
|
|
const char *name; |
198 |
|
|
u_char definition[]; |
199 |
|
|
{ |
200 |
|
|
|
201 |
✗✓ |
1494 |
if (addsym (copy_string (name), |
202 |
|
498 |
(char *) copy_unsigned_string (definition), 0, |
203 |
|
|
ndtbl, NAME_TABLE_HASH_SIZE)) |
204 |
|
|
synerr (_("name defined twice")); |
205 |
|
498 |
} |
206 |
|
|
|
207 |
|
|
|
208 |
|
|
/* ndlookup - lookup a name definition |
209 |
|
|
* |
210 |
|
|
* Returns a nil pointer if the name definition does not exist. |
211 |
|
|
*/ |
212 |
|
|
|
213 |
|
|
u_char *ndlookup (nd) |
214 |
|
|
const char *nd; |
215 |
|
|
{ |
216 |
|
1950 |
return (u_char *) findsym (nd, ndtbl, NAME_TABLE_HASH_SIZE)->str_val; |
217 |
|
|
} |
218 |
|
|
|
219 |
|
|
|
220 |
|
|
/* scextend - increase the maximum number of start conditions */ |
221 |
|
|
|
222 |
|
|
void scextend () |
223 |
|
|
{ |
224 |
|
|
current_max_scs += MAX_SCS_INCREMENT; |
225 |
|
|
|
226 |
|
|
++num_reallocs; |
227 |
|
|
|
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 |
|
|
} |
234 |
|
|
|
235 |
|
|
|
236 |
|
|
/* scinstal - make a start condition |
237 |
|
|
* |
238 |
|
|
* NOTE |
239 |
|
|
* The start condition is "exclusive" if xcluflg is true. |
240 |
|
|
*/ |
241 |
|
|
|
242 |
|
|
void scinstal (str, xcluflg) |
243 |
|
|
const char *str; |
244 |
|
|
int xcluflg; |
245 |
|
|
{ |
246 |
|
|
|
247 |
✗✓ |
192 |
if (++lastsc >= current_max_scs) |
248 |
|
|
scextend (); |
249 |
|
|
|
250 |
|
96 |
scname[lastsc] = copy_string (str); |
251 |
|
|
|
252 |
✗✓ |
96 |
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); |
257 |
|
|
|
258 |
|
96 |
scset[lastsc] = mkstate (SYM_EPSILON); |
259 |
|
96 |
scbol[lastsc] = mkstate (SYM_EPSILON); |
260 |
|
96 |
scxclu[lastsc] = xcluflg; |
261 |
|
96 |
sceof[lastsc] = false; |
262 |
|
96 |
} |
263 |
|
|
|
264 |
|
|
|
265 |
|
|
/* sclookup - lookup the number associated with a start condition |
266 |
|
|
* |
267 |
|
|
* Returns 0 if no such start condition. |
268 |
|
|
*/ |
269 |
|
|
|
270 |
|
|
int sclookup (str) |
271 |
|
|
const char *str; |
272 |
|
|
{ |
273 |
|
224 |
return findsym (str, sctbl, START_COND_HASH_SIZE)->int_val; |
274 |
|
|
} |