1 /* $NetBSD: sym.c,v 1.3 2017/01/02 17:45:27 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.3 2017/01/02 17:45:27 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(char[], char *, int, hash_table, int); 66 static struct hash_entry *findsym (const char *sym, hash_table table, 67 int table_size); 68 static int hashfunct(const char *, int); 69 70 71 /* addsym - add symbol and definitions to symbol table 72 * 73 * -1 is returned if the symbol already exists, and the change not made. 74 */ 75 76 static int addsym (char sym[], char *str_def, int int_def, hash_table table, int table_size) 77 { 78 int hash_val = hashfunct (sym, table_size); 79 struct hash_entry *sym_entry = table[hash_val]; 80 struct hash_entry *new_entry; 81 struct hash_entry *successor; 82 83 while (sym_entry) { 84 if (!strcmp (sym, sym_entry->name)) { /* entry already exists */ 85 return -1; 86 } 87 88 sym_entry = sym_entry->next; 89 } 90 91 /* create new entry */ 92 new_entry = malloc(sizeof(struct hash_entry)); 93 94 if (new_entry == NULL) 95 flexfatal (_("symbol table memory allocation failed")); 96 97 if ((successor = table[hash_val]) != 0) { 98 new_entry->next = successor; 99 successor->prev = new_entry; 100 } 101 else 102 new_entry->next = NULL; 103 104 new_entry->prev = NULL; 105 new_entry->name = sym; 106 new_entry->str_val = str_def; 107 new_entry->int_val = int_def; 108 109 table[hash_val] = new_entry; 110 111 return 0; 112 } 113 114 115 /* cclinstal - save the text of a character class */ 116 117 void cclinstal (char ccltxt[], int cclnum) 118 { 119 /* We don't bother checking the return status because we are not 120 * called unless the symbol is new. 121 */ 122 123 (void) addsym (xstrdup(ccltxt), 124 (char *) 0, cclnum, ccltab, CCL_HASH_SIZE); 125 } 126 127 128 /* ccllookup - lookup the number associated with character class text 129 * 130 * Returns 0 if there's no CCL associated with the text. 131 */ 132 133 int ccllookup (char ccltxt[]) 134 { 135 return findsym (ccltxt, ccltab, CCL_HASH_SIZE)->int_val; 136 } 137 138 139 /* findsym - find symbol in symbol table */ 140 141 static struct hash_entry *findsym (const char *sym, hash_table table, int table_size) 142 { 143 static struct hash_entry empty_entry = { 144 NULL, NULL, NULL, NULL, 0, 145 }; 146 struct hash_entry *sym_entry = 147 148 table[hashfunct (sym, table_size)]; 149 150 while (sym_entry) { 151 if (!strcmp (sym, sym_entry->name)) 152 return sym_entry; 153 sym_entry = sym_entry->next; 154 } 155 156 return &empty_entry; 157 } 158 159 /* hashfunct - compute the hash value for "str" and hash size "hash_size" */ 160 161 static int hashfunct (const char *str, int hash_size) 162 { 163 int hashval; 164 int locstr; 165 166 hashval = 0; 167 locstr = 0; 168 169 while (str[locstr]) { 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 (const char *name, char definition[]) 181 { 182 183 if (addsym (xstrdup(name), 184 xstrdup(definition), 0, 185 ndtbl, NAME_TABLE_HASH_SIZE)) 186 synerr (_("name defined twice")); 187 } 188 189 190 /* ndlookup - lookup a name definition 191 * 192 * Returns a nil pointer if the name definition does not exist. 193 */ 194 195 char *ndlookup (const char *nd) 196 { 197 return findsym (nd, ndtbl, NAME_TABLE_HASH_SIZE)->str_val; 198 } 199 200 201 /* scextend - increase the maximum number of start conditions */ 202 203 void scextend (void) 204 { 205 current_max_scs += MAX_SCS_INCREMENT; 206 207 ++num_reallocs; 208 209 scset = reallocate_integer_array (scset, current_max_scs); 210 scbol = reallocate_integer_array (scbol, current_max_scs); 211 scxclu = reallocate_integer_array (scxclu, current_max_scs); 212 sceof = reallocate_integer_array (sceof, current_max_scs); 213 scname = reallocate_char_ptr_array (scname, current_max_scs); 214 } 215 216 217 /* scinstal - make a start condition 218 * 219 * NOTE 220 * The start condition is "exclusive" if xcluflg is true. 221 */ 222 223 void scinstal (const char *str, int xcluflg) 224 { 225 226 if (++lastsc >= current_max_scs) 227 scextend (); 228 229 scname[lastsc] = xstrdup(str); 230 231 if (addsym(scname[lastsc], NULL, lastsc, 232 sctbl, START_COND_HASH_SIZE)) 233 format_pinpoint_message (_ 234 ("start condition %s declared twice"), 235 str); 236 237 scset[lastsc] = mkstate (SYM_EPSILON); 238 scbol[lastsc] = mkstate (SYM_EPSILON); 239 scxclu[lastsc] = xcluflg; 240 sceof[lastsc] = false; 241 } 242 243 244 /* sclookup - lookup the number associated with a start condition 245 * 246 * Returns 0 if no such start condition. 247 */ 248 249 int sclookup (const char *str) 250 { 251 return findsym (str, sctbl, START_COND_HASH_SIZE)->int_val; 252 } 253