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