xref: /netbsd/external/bsd/flex/dist/src/sym.c (revision b806bde9)
1 /*	$NetBSD: sym.c,v 1.3 2017/01/02 17:45:27 christos 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 #include "flexdef.h"
36 __RCSID("$NetBSD: sym.c,v 1.3 2017/01/02 17:45:27 christos Exp $");
37 
38 
39 /* Variables for symbol tables:
40  * sctbl - start-condition symbol table
41  * ndtbl - name-definition symbol table
42  * ccltab - character class text symbol table
43  */
44 
45 struct hash_entry {
46 	struct hash_entry *prev, *next;
47 	char   *name;
48 	char   *str_val;
49 	int     int_val;
50 };
51 
52 typedef struct hash_entry **hash_table;
53 
54 #define NAME_TABLE_HASH_SIZE 101
55 #define START_COND_HASH_SIZE 101
56 #define CCL_HASH_SIZE 101
57 
58 static struct hash_entry *ndtbl[NAME_TABLE_HASH_SIZE];
59 static struct hash_entry *sctbl[START_COND_HASH_SIZE];
60 static struct hash_entry *ccltab[CCL_HASH_SIZE];
61 
62 
63 /* declare functions that have forward references */
64 
65 static int addsym(char[], char *, int, hash_table, int);
66 static struct hash_entry *findsym (const char *sym, hash_table table,
67 				   int table_size);
68 static int hashfunct(const char *, int);
69 
70 
71 /* addsym - add symbol and definitions to symbol table
72  *
73  * -1 is returned if the symbol already exists, and the change not made.
74  */
75 
addsym(char sym[],char * str_def,int int_def,hash_table table,int table_size)76 static int addsym (char sym[], char *str_def, int int_def, hash_table table, int table_size)
77 {
78 	int    hash_val = hashfunct (sym, table_size);
79 	struct hash_entry *sym_entry = table[hash_val];
80 	struct hash_entry *new_entry;
81 	struct hash_entry *successor;
82 
83 	while (sym_entry) {
84 		if (!strcmp (sym, sym_entry->name)) {	/* entry already exists */
85 			return -1;
86 		}
87 
88 		sym_entry = sym_entry->next;
89 	}
90 
91 	/* create new entry */
92 	new_entry = malloc(sizeof(struct hash_entry));
93 
94 	if (new_entry == NULL)
95 		flexfatal (_("symbol table memory allocation failed"));
96 
97 	if ((successor = table[hash_val]) != 0) {
98 		new_entry->next = successor;
99 		successor->prev = new_entry;
100 	}
101 	else
102 		new_entry->next = NULL;
103 
104 	new_entry->prev = NULL;
105 	new_entry->name = sym;
106 	new_entry->str_val = str_def;
107 	new_entry->int_val = int_def;
108 
109 	table[hash_val] = new_entry;
110 
111 	return 0;
112 }
113 
114 
115 /* cclinstal - save the text of a character class */
116 
cclinstal(char ccltxt[],int cclnum)117 void    cclinstal (char ccltxt[], int cclnum)
118 {
119 	/* We don't bother checking the return status because we are not
120 	 * called unless the symbol is new.
121 	 */
122 
123 	(void) addsym (xstrdup(ccltxt),
124 		       (char *) 0, cclnum, ccltab, CCL_HASH_SIZE);
125 }
126 
127 
128 /* ccllookup - lookup the number associated with character class text
129  *
130  * Returns 0 if there's no CCL associated with the text.
131  */
132 
ccllookup(char ccltxt[])133 int     ccllookup (char ccltxt[])
134 {
135 	return findsym (ccltxt, ccltab, CCL_HASH_SIZE)->int_val;
136 }
137 
138 
139 /* findsym - find symbol in symbol table */
140 
findsym(const char * sym,hash_table table,int table_size)141 static struct hash_entry *findsym (const char *sym, hash_table table, int table_size)
142 {
143 	static struct hash_entry empty_entry = {
144 		NULL, NULL, NULL, NULL, 0,
145 	};
146 	struct hash_entry *sym_entry =
147 
148 		table[hashfunct (sym, table_size)];
149 
150 	while (sym_entry) {
151 		if (!strcmp (sym, sym_entry->name))
152 			return sym_entry;
153 		sym_entry = sym_entry->next;
154 	}
155 
156 	return &empty_entry;
157 }
158 
159 /* hashfunct - compute the hash value for "str" and hash size "hash_size" */
160 
hashfunct(const char * str,int hash_size)161 static int hashfunct (const char *str, int hash_size)
162 {
163 	int hashval;
164 	int locstr;
165 
166 	hashval = 0;
167 	locstr = 0;
168 
169 	while (str[locstr]) {
170 		hashval = (hashval << 1) + (unsigned char) str[locstr++];
171 		hashval %= hash_size;
172 	}
173 
174 	return hashval;
175 }
176 
177 
178 /* ndinstal - install a name definition */
179 
ndinstal(const char * name,char definition[])180 void    ndinstal (const char *name, char definition[])
181 {
182 
183 	if (addsym (xstrdup(name),
184 		    xstrdup(definition), 0,
185 		    ndtbl, NAME_TABLE_HASH_SIZE))
186 			synerr (_("name defined twice"));
187 }
188 
189 
190 /* ndlookup - lookup a name definition
191  *
192  * Returns a nil pointer if the name definition does not exist.
193  */
194 
ndlookup(const char * nd)195 char   *ndlookup (const char *nd)
196 {
197 	return findsym (nd, ndtbl, NAME_TABLE_HASH_SIZE)->str_val;
198 }
199 
200 
201 /* scextend - increase the maximum number of start conditions */
202 
scextend(void)203 void    scextend (void)
204 {
205 	current_max_scs += MAX_SCS_INCREMENT;
206 
207 	++num_reallocs;
208 
209 	scset = reallocate_integer_array (scset, current_max_scs);
210 	scbol = reallocate_integer_array (scbol, current_max_scs);
211 	scxclu = reallocate_integer_array (scxclu, current_max_scs);
212 	sceof = reallocate_integer_array (sceof, current_max_scs);
213 	scname = reallocate_char_ptr_array (scname, current_max_scs);
214 }
215 
216 
217 /* scinstal - make a start condition
218  *
219  * NOTE
220  *    The start condition is "exclusive" if xcluflg is true.
221  */
222 
scinstal(const char * str,int xcluflg)223 void    scinstal (const char *str, int xcluflg)
224 {
225 
226 	if (++lastsc >= current_max_scs)
227 		scextend ();
228 
229 	scname[lastsc] = xstrdup(str);
230 
231 	if (addsym(scname[lastsc], NULL, lastsc,
232 		    sctbl, START_COND_HASH_SIZE))
233 			format_pinpoint_message (_
234 						 ("start condition %s declared twice"),
235 str);
236 
237 	scset[lastsc] = mkstate (SYM_EPSILON);
238 	scbol[lastsc] = mkstate (SYM_EPSILON);
239 	scxclu[lastsc] = xcluflg;
240 	sceof[lastsc] = false;
241 }
242 
243 
244 /* sclookup - lookup the number associated with a start condition
245  *
246  * Returns 0 if no such start condition.
247  */
248 
sclookup(const char * str)249 int     sclookup (const char *str)
250 {
251 	return findsym (str, sctbl, START_COND_HASH_SIZE)->int_val;
252 }
253