Coverage Report

Created: 2026-01-09 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/flex/src/sym.c
Line
Count
Source
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
42
struct hash_entry {
43
  struct hash_entry *next;
44
  char   *name;
45
  char   *str_val;
46
  int     int_val;
47
};
48
49
typedef struct hash_entry **hash_table;
50
51
0
#define NAME_TABLE_HASH_SIZE 101
52
0
#define START_COND_HASH_SIZE 101
53
0
#define CCL_HASH_SIZE 101
54
55
static struct hash_entry *ndtbl[NAME_TABLE_HASH_SIZE] = {NULL};
56
static struct hash_entry *sctbl[START_COND_HASH_SIZE] = {NULL};
57
static struct hash_entry *ccltab[CCL_HASH_SIZE] = {NULL};
58
59
60
/* declare functions that have forward references */
61
62
static int addsym(const char *, const char *, int, hash_table, size_t);
63
static struct hash_entry *findsym (const char *sym, hash_table table,
64
           size_t table_size);
65
static size_t hashfunct(const char *, size_t);
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
73
static int addsym (const char *sym, const char *str_def, int int_def, hash_table table, size_t table_size)
74
0
{
75
0
  size_t hash_val = hashfunct (sym, table_size);
76
0
  struct hash_entry *sym_entry = table[hash_val];
77
0
  struct hash_entry *new_entry;
78
79
0
  while (sym_entry) {
80
0
    if (!strcmp (sym, sym_entry->name)) { /* entry already exists */
81
0
      return -1;
82
0
    }
83
84
0
    sym_entry = sym_entry->next;
85
0
  }
86
87
  /* create new entry */
88
0
  new_entry = malloc(sizeof(struct hash_entry));
89
90
0
  if (new_entry == NULL)
91
0
    flexfatal (_("symbol table memory allocation failed"));
92
93
0
  new_entry->next = table[hash_val];
94
0
  new_entry->name = xstrdup(sym);
95
0
  if (str_def == NULL) {
96
0
    new_entry->str_val = NULL;
97
0
  } else {
98
0
    new_entry->str_val = xstrdup(str_def);
99
0
  }
100
0
  new_entry->int_val = int_def;
101
102
0
  table[hash_val] = new_entry;
103
104
0
  return 0;
105
0
}
106
107
108
/* cclinstal - save the text of a character class */
109
110
void    cclinstal (char ccltxt[], int cclnum)
111
0
{
112
  /* We don't bother checking the return status because we are not
113
   * called unless the symbol is new.
114
   */
115
116
0
  (void) addsym(ccltxt, NULL, cclnum, ccltab, CCL_HASH_SIZE);
117
0
}
118
119
120
/* ccllookup - lookup the number associated with character class text
121
 *
122
 * Returns 0 if there's no CCL associated with the text.
123
 */
124
125
int     ccllookup (char ccltxt[])
126
0
{
127
0
  return findsym (ccltxt, ccltab, CCL_HASH_SIZE)->int_val;
128
0
}
129
130
131
/* findsym - find symbol in symbol table */
132
133
static struct hash_entry *findsym (const char *sym, hash_table table, size_t table_size)
134
0
{
135
0
  static struct hash_entry empty_entry = {
136
0
    NULL, NULL, NULL, 0,
137
0
  };
138
0
  struct hash_entry *sym_entry =
139
140
0
    table[hashfunct (sym, table_size)];
141
142
0
  while (sym_entry) {
143
0
    if (!strcmp (sym, sym_entry->name))
144
0
      return sym_entry;
145
0
    sym_entry = sym_entry->next;
146
0
  }
147
148
0
  return &empty_entry;
149
0
}
150
151
/* hashfunct - compute the hash value for "str" and hash size "hash_size" */
152
153
static size_t hashfunct (const char *str, size_t hash_size)
154
0
{
155
0
  size_t hashval;
156
0
  size_t locstr;
157
158
0
  hashval = 0;
159
0
  locstr = 0;
160
161
0
  while (str[locstr] != '\0') {
162
0
    hashval = (hashval << 1) + (unsigned char) str[locstr++];
163
0
    hashval %= hash_size;
164
0
  }
165
166
0
  return hashval;
167
0
}
168
169
170
/* ndinstal - install a name definition */
171
172
void    ndinstal (const char *name, char definition[])
173
0
{
174
0
  if (addsym(name, definition, 0, ndtbl, NAME_TABLE_HASH_SIZE)) {
175
0
    synerr (_("name defined twice"));
176
0
  }
177
0
}
178
179
180
/* ndlookup - lookup a name definition
181
 *
182
 * Returns a nil pointer if the name definition does not exist.
183
 */
184
185
char   *ndlookup (const char *nd)
186
0
{
187
0
  return findsym (nd, ndtbl, NAME_TABLE_HASH_SIZE)->str_val;
188
0
}
189
190
191
/* scextend - increase the maximum number of start conditions */
192
193
void    scextend (void)
194
0
{
195
0
  current_max_scs += MAX_SCS_INCREMENT;
196
197
0
  ++num_reallocs;
198
199
0
  scset = reallocate_integer_array (scset, current_max_scs);
200
0
  scbol = reallocate_integer_array (scbol, current_max_scs);
201
0
  scxclu = reallocate_array(scxclu, current_max_scs,
202
0
    sizeof(char));
203
0
  sceof = reallocate_array(sceof, current_max_scs, sizeof(char));
204
0
  scname = reallocate_char_ptr_array (scname, current_max_scs);
205
0
}
206
207
208
/* scinstal - make a start condition */
209
210
void    scinstal (const char *str, bool sc_is_exclusive)
211
0
{
212
213
0
  if (++lastsc >= current_max_scs)
214
0
    scextend ();
215
216
0
  if (addsym(str, NULL, lastsc, sctbl, START_COND_HASH_SIZE)) {
217
0
    format_pinpoint_message (
218
0
      _("start condition %s declared twice"), str);
219
0
  }
220
0
  scname[lastsc] = sctbl[hashfunct(str, START_COND_HASH_SIZE)]->name;
221
222
0
  scset[lastsc] = mkstate (SYM_EPSILON);
223
0
  scbol[lastsc] = mkstate (SYM_EPSILON);
224
0
  scxclu[lastsc] = sc_is_exclusive ? 1 : 0;
225
0
  sceof[lastsc] = false;
226
0
}
227
228
229
/* sclookup - lookup the number associated with a start condition
230
 *
231
 * Returns 0 if no such start condition.
232
 */
233
234
int     sclookup (const char *str)
235
0
{
236
0
  return findsym (str, sctbl, START_COND_HASH_SIZE)->int_val;
237
0
}