| File: | src/usr.bin/lex/sym.c |
| Warning: | line 109, column 19 Access to field 'next' results in a dereference of a null pointer (loaded from variable 'new_entry') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* $OpenBSD: sym.c,v 1.9 2015/11/19 23:34:56 mmcc 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 | ||||
| 36 | #include "flexdef.h" | |||
| 37 | ||||
| 38 | /* Variables for symbol tables: | |||
| 39 | * sctbl - start-condition symbol table | |||
| 40 | * ndtbl - name-definition symbol table | |||
| 41 | * ccltab - character class text symbol table | |||
| 42 | */ | |||
| 43 | ||||
| 44 | struct hash_entry { | |||
| 45 | struct hash_entry *prev, *next; | |||
| 46 | char *name; | |||
| 47 | char *str_val; | |||
| 48 | int int_val; | |||
| 49 | }; | |||
| 50 | ||||
| 51 | typedef struct hash_entry **hash_table; | |||
| 52 | ||||
| 53 | #define NAME_TABLE_HASH_SIZE101 101 | |||
| 54 | #define START_COND_HASH_SIZE101 101 | |||
| 55 | #define CCL_HASH_SIZE101 101 | |||
| 56 | ||||
| 57 | static struct hash_entry *ndtbl[NAME_TABLE_HASH_SIZE101]; | |||
| 58 | static struct hash_entry *sctbl[START_COND_HASH_SIZE101]; | |||
| 59 | static struct hash_entry *ccltab[CCL_HASH_SIZE101]; | |||
| 60 | ||||
| 61 | ||||
| 62 | /* declare functions that have forward references */ | |||
| 63 | ||||
| 64 | static int addsym PROTO ((char[], char *, int, hash_table, int))(char[], char *, int, hash_table, int); | |||
| 65 | static struct hash_entry *findsym PROTO ((const char *sym,(const char *sym, hash_table table, int table_size) | |||
| 66 | hash_table table,(const char *sym, hash_table table, int table_size) | |||
| 67 | ||||
| 68 | int table_size))(const char *sym, hash_table table, int table_size); | |||
| 69 | static int hashfunct PROTO ((const char *, int))(const char *, int); | |||
| 70 | ||||
| 71 | ||||
| 72 | /* addsym - add symbol and definitions to symbol table | |||
| 73 | * | |||
| 74 | * -1 is returned if the symbol already exists, and the change not made. | |||
| 75 | */ | |||
| 76 | ||||
| 77 | static int addsym (sym, str_def, int_def, table, table_size) | |||
| 78 | char sym[]; | |||
| 79 | char *str_def; | |||
| 80 | int int_def; | |||
| 81 | hash_table table; | |||
| 82 | int table_size; | |||
| 83 | { | |||
| 84 | int hash_val = hashfunct (sym, table_size); | |||
| 85 | struct hash_entry *sym_entry = table[hash_val]; | |||
| 86 | struct hash_entry *new_entry; | |||
| 87 | struct hash_entry *successor; | |||
| 88 | ||||
| 89 | while (sym_entry) { | |||
| 90 | if (!strcmp (sym, sym_entry->name)) { /* entry already exists */ | |||
| 91 | return -1; | |||
| 92 | } | |||
| 93 | ||||
| 94 | sym_entry = sym_entry->next; | |||
| 95 | } | |||
| 96 | ||||
| 97 | /* create new entry */ | |||
| 98 | new_entry = (struct hash_entry *) | |||
| 99 | malloc (sizeof (struct hash_entry)); | |||
| 100 | ||||
| 101 | if (new_entry == NULL((void *)0)) | |||
| 102 | flexfatal (_("symbol table memory allocation failed")"symbol table memory allocation failed"); | |||
| 103 | ||||
| 104 | if ((successor = table[hash_val]) != 0) { | |||
| 105 | new_entry->next = successor; | |||
| 106 | successor->prev = new_entry; | |||
| 107 | } | |||
| 108 | else | |||
| 109 | new_entry->next = NULL((void *)0); | |||
| ||||
| 110 | ||||
| 111 | new_entry->prev = NULL((void *)0); | |||
| 112 | new_entry->name = sym; | |||
| 113 | new_entry->str_val = str_def; | |||
| 114 | new_entry->int_val = int_def; | |||
| 115 | ||||
| 116 | table[hash_val] = new_entry; | |||
| 117 | ||||
| 118 | return 0; | |||
| 119 | } | |||
| 120 | ||||
| 121 | ||||
| 122 | /* cclinstal - save the text of a character class */ | |||
| 123 | ||||
| 124 | void cclinstal (ccltxt, cclnum) | |||
| 125 | u_char ccltxt[]; | |||
| 126 | int cclnum; | |||
| 127 | { | |||
| 128 | /* We don't bother checking the return status because we are not | |||
| 129 | * called unless the symbol is new. | |||
| 130 | */ | |||
| 131 | ||||
| 132 | (void) addsym ((char *) copy_unsigned_string (ccltxt), | |||
| 133 | (char *) 0, cclnum, ccltab, CCL_HASH_SIZE101); | |||
| 134 | } | |||
| 135 | ||||
| 136 | ||||
| 137 | /* ccllookup - lookup the number associated with character class text | |||
| 138 | * | |||
| 139 | * Returns 0 if there's no CCL associated with the text. | |||
| 140 | */ | |||
| 141 | ||||
| 142 | int ccllookup (ccltxt) | |||
| 143 | u_char ccltxt[]; | |||
| 144 | { | |||
| 145 | return findsym ((char *) ccltxt, ccltab, CCL_HASH_SIZE101)->int_val; | |||
| 146 | } | |||
| 147 | ||||
| 148 | ||||
| 149 | /* findsym - find symbol in symbol table */ | |||
| 150 | ||||
| 151 | static struct hash_entry *findsym (sym, table, table_size) | |||
| 152 | const char *sym; | |||
| 153 | hash_table table; | |||
| 154 | int table_size; | |||
| 155 | { | |||
| 156 | static struct hash_entry empty_entry = { | |||
| 157 | (struct hash_entry *) 0, (struct hash_entry *) 0, | |||
| 158 | (char *) 0, (char *) 0, 0, | |||
| 159 | }; | |||
| 160 | struct hash_entry *sym_entry = | |||
| 161 | ||||
| 162 | table[hashfunct (sym, table_size)]; | |||
| 163 | ||||
| 164 | while (sym_entry) { | |||
| 165 | if (!strcmp (sym, sym_entry->name)) | |||
| 166 | return sym_entry; | |||
| 167 | sym_entry = sym_entry->next; | |||
| 168 | } | |||
| 169 | ||||
| 170 | return &empty_entry; | |||
| 171 | } | |||
| 172 | ||||
| 173 | /* hashfunct - compute the hash value for "str" and hash size "hash_size" */ | |||
| 174 | ||||
| 175 | static int hashfunct (str, hash_size) | |||
| 176 | const char *str; | |||
| 177 | int hash_size; | |||
| 178 | { | |||
| 179 | int hashval; | |||
| 180 | int locstr; | |||
| 181 | ||||
| 182 | hashval = 0; | |||
| 183 | locstr = 0; | |||
| 184 | ||||
| 185 | while (str[locstr]) { | |||
| 186 | hashval = (hashval << 1) + (unsigned char) str[locstr++]; | |||
| 187 | hashval %= hash_size; | |||
| 188 | } | |||
| 189 | ||||
| 190 | return hashval; | |||
| 191 | } | |||
| 192 | ||||
| 193 | ||||
| 194 | /* ndinstal - install a name definition */ | |||
| 195 | ||||
| 196 | void ndinstal (name, definition) | |||
| 197 | const char *name; | |||
| 198 | u_char definition[]; | |||
| 199 | { | |||
| 200 | ||||
| 201 | if (addsym (copy_string (name), | |||
| 202 | (char *) copy_unsigned_string (definition), 0, | |||
| 203 | ndtbl, NAME_TABLE_HASH_SIZE101)) | |||
| 204 | synerr (_("name defined twice")"name defined twice"); | |||
| 205 | } | |||
| 206 | ||||
| 207 | ||||
| 208 | /* ndlookup - lookup a name definition | |||
| 209 | * | |||
| 210 | * Returns a nil pointer if the name definition does not exist. | |||
| 211 | */ | |||
| 212 | ||||
| 213 | u_char *ndlookup (nd) | |||
| 214 | const char *nd; | |||
| 215 | { | |||
| 216 | return (u_char *) findsym (nd, ndtbl, NAME_TABLE_HASH_SIZE101)->str_val; | |||
| 217 | } | |||
| 218 | ||||
| 219 | ||||
| 220 | /* scextend - increase the maximum number of start conditions */ | |||
| 221 | ||||
| 222 | void scextend () | |||
| 223 | { | |||
| 224 | current_max_scs += MAX_SCS_INCREMENT40; | |||
| 225 | ||||
| 226 | ++num_reallocs; | |||
| 227 | ||||
| 228 | scset = reallocate_integer_array (scset, current_max_scs)(int *) reallocate_array( (void *) scset, current_max_scs, sizeof ( int ) ); | |||
| 229 | scbol = reallocate_integer_array (scbol, current_max_scs)(int *) reallocate_array( (void *) scbol, current_max_scs, sizeof ( int ) ); | |||
| 230 | scxclu = reallocate_integer_array (scxclu, current_max_scs)(int *) reallocate_array( (void *) scxclu, current_max_scs, sizeof ( int ) ); | |||
| 231 | sceof = reallocate_integer_array (sceof, current_max_scs)(int *) reallocate_array( (void *) sceof, current_max_scs, sizeof ( int ) ); | |||
| 232 | scname = reallocate_char_ptr_array (scname, current_max_scs)(char **) reallocate_array( (void *) scname, current_max_scs, sizeof( char * ) ); | |||
| 233 | } | |||
| 234 | ||||
| 235 | ||||
| 236 | /* scinstal - make a start condition | |||
| 237 | * | |||
| 238 | * NOTE | |||
| 239 | * The start condition is "exclusive" if xcluflg is true. | |||
| 240 | */ | |||
| 241 | ||||
| 242 | void scinstal (str, xcluflg) | |||
| 243 | const char *str; | |||
| 244 | int xcluflg; | |||
| 245 | { | |||
| 246 | ||||
| 247 | if (++lastsc >= current_max_scs) | |||
| ||||
| 248 | scextend (); | |||
| 249 | ||||
| 250 | scname[lastsc] = copy_string (str); | |||
| 251 | ||||
| 252 | if (addsym (scname[lastsc], (char *) 0, lastsc, | |||
| 253 | sctbl, START_COND_HASH_SIZE101)) | |||
| 254 | format_pinpoint_message (_"start condition %s declared twice" | |||
| 255 | ("start condition %s declared twice")"start condition %s declared twice", | |||
| 256 | str); | |||
| 257 | ||||
| 258 | scset[lastsc] = mkstate (SYM_EPSILON(256 + 1)); | |||
| 259 | scbol[lastsc] = mkstate (SYM_EPSILON(256 + 1)); | |||
| 260 | scxclu[lastsc] = xcluflg; | |||
| 261 | sceof[lastsc] = false0; | |||
| 262 | } | |||
| 263 | ||||
| 264 | ||||
| 265 | /* sclookup - lookup the number associated with a start condition | |||
| 266 | * | |||
| 267 | * Returns 0 if no such start condition. | |||
| 268 | */ | |||
| 269 | ||||
| 270 | int sclookup (str) | |||
| 271 | const char *str; | |||
| 272 | { | |||
| 273 | return findsym (str, sctbl, START_COND_HASH_SIZE101)->int_val; | |||
| 274 | } |