sym.c (6214B)
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: /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 }