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