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