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