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