blob: 036431ac44c038b08e72c59fc60710171eb53173 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001#ifdef UEMF
2 #include "uemf.h"
3#else
4 #include "basic/basicInternal.h"
5#endif
6
7static int calcPrime(int size);
8
9typedef struct {
10 int inuse;
11 int hash_size;
12 sym_t **hash_table;
13} sym_tabent_t;
14
15static int symMax;
16static int hashIndex(sym_tabent_t *tp, char_t *name);
17static int htIndex;
18static sym_t *hash(sym_tabent_t *tp, char_t *name);
19static sym_t *next;
20static sym_tabent_t **sym;
21
22sym_fd_t symOpen(int hash_size)
23{
24 sym_fd_t sd;
25 sym_tabent_t *tp;
26
27 a_assert(hash_size > 2);
28
29 if ((sd = hAlloc((void***) &sym)) < 0) {
30 return -1;
31 }
32
33 if ((tp = (sym_tabent_t*) balloc(B_L, sizeof(sym_tabent_t))) == NULL) {
34 symMax = hFree((void***) &sym, sd);
35 return -1;
36 }
37 memset(tp, 0, sizeof(sym_tabent_t));
38 if (sd >= symMax) {
39 symMax = sd + 1;
40 }
41 a_assert(0 <= sd && sd < symMax);
42 sym[sd] = tp;
43
44 tp->hash_size = calcPrime(hash_size);
45 tp->hash_table = (sym_t**) balloc(B_L, tp->hash_size * sizeof(sym_t*));
46 a_assert(tp->hash_table);
47 if(tp->hash_table)
48 memset(tp->hash_table, 0, tp->hash_size * sizeof(sym_t*));
49
50 return sd;
51}
52
53void symClose(sym_fd_t sd)
54{
55 sym_tabent_t *tp;
56 sym_t *sp, *forw;
57 int i;
58
59 a_assert(0 <= sd && sd < symMax);
60 tp = sym[sd];
61 a_assert(tp);
62
63 for (i = 0; i < tp->hash_size; i++) {
64 for (sp = tp->hash_table[i]; sp; sp = forw) {
65 forw = sp->forw;
66 valueFree(&sp->name);
67 valueFree(&sp->content);
68 bfree(B_L, (void*) sp);
69 sp = forw;
70 }
71 }
72 bfree(B_L, (void*) tp->hash_table);
73
74 symMax = hFree((void***) &sym, sd);
75 bfree(B_L, (void*) tp);
76}
77
78sym_t* symFirst(sym_fd_t sd)
79{
80 sym_tabent_t *tp;
81 sym_t *sp, *forw;
82 int i;
83
84 a_assert(0 <= sd && sd < symMax);
85 tp = sym[sd];
86 a_assert(tp);
87
88 for (i = 0; i < tp->hash_size; i++) {
89
90#if 0 // KW 3 cov M
91 for (sp = tp->hash_table[i]; sp; sp = forw) {
92 forw = sp->forw;
93
94 if (forw == NULL) {
95 htIndex = i + 1;
96 next = tp->hash_table[htIndex];
97 } else {
98 htIndex = i;
99 next = forw;
100 }
101 return sp;
102 }
103#else
104 sp = tp->hash_table[i];
105 if(NULL != sp){
106 forw = sp->forw;
107
108 if (forw == NULL) {
109 htIndex = i + 1;
110 next = tp->hash_table[htIndex];
111 } else {
112 htIndex = i;
113 next = forw;
114 }
115 return sp;
116 }
117
118#endif
119 }
120 return NULL;
121}
122
123sym_t* symNext(sym_fd_t sd)
124{
125 sym_tabent_t *tp;
126 sym_t *sp, *forw;
127 int i;
128
129 a_assert(0 <= sd && sd < symMax);
130 tp = sym[sd];
131 a_assert(tp);
132
133 for (i = htIndex; i < tp->hash_size; i++) {
134
135#if 0 // kw 3 cov M
136 for (sp = next; sp; sp = forw) {
137 forw = sp->forw;
138
139 if (forw == NULL) {
140 htIndex = i + 1;
141 next = tp->hash_table[htIndex];
142 } else {
143 htIndex = i;
144 next = forw;
145 }
146 return sp;
147 }
148#else
149 sp = next;
150 if(NULL != sp) {
151 forw = sp->forw;
152
153 if (forw == NULL) {
154 htIndex = i + 1;
155 next = tp->hash_table[htIndex];
156 } else {
157 htIndex = i;
158 next = forw;
159 }
160 return sp;
161 }
162
163#endif
164 next = tp->hash_table[i + 1];
165 }
166 return NULL;
167}
168
169
170sym_t *symEnter(sym_fd_t sd, char_t *name, value_t v, int arg)
171{
172 sym_tabent_t *tp;
173 sym_t *sp, *last;
174 char_t *cp;
175 int hindex;
176
177 a_assert(name);
178 a_assert(0 <= sd && sd < symMax);
179 tp = sym[sd];
180 a_assert(tp);
181
182 last = NULL;
183 hindex = hashIndex(tp, name);
184 if ((sp = tp->hash_table[hindex]) != NULL) {
185 for (; sp; sp = sp->forw) {
186 cp = sp->name.value.string;
187 if (cp[0] == name[0] && gstrcmp(cp, name) == 0) {
188 break;
189 }
190 last = sp;
191 }
192 if (sp) {
193
194 if (sp->content.valid) {
195 valueFree(&sp->content);
196 }
197 sp->content = v;
198 sp->arg = arg;
199 return sp;
200 }
201
202 sp = (sym_t*) balloc(B_L, sizeof(sym_t));
203 if (sp == NULL) {
204 return NULL;
205 }
206 sp->content = v;
207 sp->forw = (sym_t*) NULL;
208 sp->name = valueString(name, VALUE_ALLOCATE);
209 sp->arg = arg;
210 last->forw = sp;
211
212 } else {
213 sp = (sym_t*) balloc(B_L, sizeof(sym_t));
214 if (sp == NULL) {
215 return NULL;
216 }
217 tp->hash_table[hindex] = sp;
218 tp->hash_table[hashIndex(tp, name)] = sp;
219
220 sp->arg = arg;
221 sp->content = v;
222 sp->name = valueString(name, VALUE_ALLOCATE);
223 sp->forw = (sym_t*) NULL;
224 }
225 return sp;
226}
227
228sym_t *symLookup(sym_fd_t sd, char_t *name)
229{
230 sym_tabent_t *tp;
231 sym_t *sp;
232 char_t *cp;
233
234 a_assert(0 <= sd && sd < symMax);
235 if ((tp = sym[sd]) == NULL) {
236 return NULL;
237 }
238
239 if (name == NULL || *name == '\0') {
240 return NULL;
241 }
242
243
244 for (sp = hash(tp, name); sp; sp = sp->forw) {
245 cp = sp->name.value.string;
246 if (cp[0] == name[0] && gstrcmp(cp, name) == 0) {
247 break;
248 }
249 }
250 return sp;
251}
252
253int symDelete(sym_fd_t sd, char_t *name)
254{
255 sym_t *last = NULL;
256 int hindex;
257 char_t *cp;
258 sym_t *sp;
259 sym_tabent_t *tp;
260
261 a_assert(name && *name);
262 a_assert(0 <= sd && sd < symMax);
263 tp = sym[sd];
264 a_assert(tp);
265
266 hindex = hashIndex(tp, name);
267 if ((sp = tp->hash_table[hindex]) != NULL) {
268 for ( ; sp; sp = sp->forw) {
269 cp = sp->name.value.string;
270 if (cp[0] == name[0] && gstrcmp(cp, name) == 0) {
271 break;
272 }
273 last = sp;
274 }
275 }
276 if (sp == (sym_t*) NULL) {
277 return -1;
278 }
279
280 if (last) {
281 last->forw = sp->forw;
282 } else {
283 tp->hash_table[hindex] = sp->forw;
284 }
285 valueFree(&sp->name);
286 valueFree(&sp->content);
287 bfree(B_L, (void*) sp);
288
289 return 0;
290}
291
292
293
294static int hashIndex(sym_tabent_t *tp, char_t *name)
295{
296 unsigned int sum;
297 int i;
298
299 a_assert(tp);
300
301 i = 0;
302 sum = 0;
303 while (*name) {
304 sum += (((int) *name++) << i);
305 i = (i + 7) % (BITS(int) - BITSPERBYTE);
306 }
307 return sum % tp->hash_size;
308}
309
310static int isPrime(int n)
311{
312 int i, max;
313
314 a_assert(n > 0);
315
316 max = n / 2;
317 for (i = 2; i <= max; i++) {
318 if (n % i == 0) {
319 return 0;
320 }
321 }
322 return 1;
323}
324
325static sym_t *hash(sym_tabent_t *tp, char_t *name)
326{
327 a_assert(tp);
328
329 return tp->hash_table[hashIndex(tp, name)];
330}
331
332static int calcPrime(int size)
333{
334 int count;
335
336 a_assert(size > 0);
337
338 for (count = size; count > 0; count--) {
339 if (isPrime(count)) {
340 return count;
341 }
342 }
343 return 1;
344}
345