xref: /openbsd-src/usr.bin/lex/sym.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
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: /home/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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
265 int sclookup( str )
266 char str[];
267 	{
268 	return findsym( str, sctbl, START_COND_HASH_SIZE )->int_val;
269 	}
270