1/*	$NetBSD: symtab.c,v 1.11 2018/12/23 20:27:23 jakllsch Exp $	*/
2
3/* Id: symtab.c,v 1.11 2014/03/26 00:17:09 Tom.Shields Exp  */
4
5#include "defs.h"
6
7#include <sys/cdefs.h>
8__RCSID("$NetBSD: symtab.c,v 1.11 2018/12/23 20:27:23 jakllsch Exp $");
9
10/* TABLE_SIZE is the number of entries in the symbol table. */
11/* TABLE_SIZE must be a power of two.			    */
12
13#define	TABLE_SIZE 1024
14
15static bucket **symbol_table = 0;
16bucket *first_symbol;
17bucket *last_symbol;
18
19static int
20hash(const char *name)
21{
22    const char *s;
23    int c, k;
24
25    assert(name && *name);
26    s = name;
27    k = *s;
28    while ((c = *++s) != 0)
29	k = (31 * k + c) & (TABLE_SIZE - 1);
30
31    return (k);
32}
33
34bucket *
35make_bucket(const char *name)
36{
37    bucket *bp;
38
39    assert(name != 0);
40
41    bp = TMALLOC(bucket, 1);
42    NO_SPACE(bp);
43
44    bp->link = 0;
45    bp->next = 0;
46
47    bp->name = TMALLOC(char, strlen(name) + 1);
48    NO_SPACE(bp->name);
49
50    bp->tag = 0;
51    bp->value = UNDEFINED;
52    bp->index = 0;
53    bp->prec = 0;
54    bp->class = UNKNOWN;
55    bp->assoc = TOKEN;
56#if defined(YYBTYACC)
57    bp->args = -1;
58    bp->argnames = 0;
59    bp->argtags = 0;
60    bp->destructor = 0;
61#endif
62    strcpy(bp->name, name);
63
64    return (bp);
65}
66
67bucket *
68lookup(const char *name)
69{
70    bucket *bp, **bpp;
71
72    bpp = symbol_table + hash(name);
73    bp = *bpp;
74
75    while (bp)
76    {
77	if (strcmp(name, bp->name) == 0)
78	    return (bp);
79	bpp = &bp->link;
80	bp = *bpp;
81    }
82
83    *bpp = bp = make_bucket(name);
84    last_symbol->next = bp;
85    last_symbol = bp;
86
87    return (bp);
88}
89
90void
91create_symbol_table(void)
92{
93    int i;
94    bucket *bp;
95
96    symbol_table = TMALLOC(bucket *, TABLE_SIZE);
97    NO_SPACE(symbol_table);
98
99    for (i = 0; i < TABLE_SIZE; i++)
100	symbol_table[i] = 0;
101
102    bp = make_bucket("error");
103    bp->index = 1;
104    bp->class = TERM;
105
106    first_symbol = bp;
107    last_symbol = bp;
108    symbol_table[hash("error")] = bp;
109}
110
111void
112free_symbol_table(void)
113{
114    FREE(symbol_table);
115    symbol_table = 0;
116}
117
118void
119free_symbols(void)
120{
121    bucket *p, *q;
122
123    for (p = first_symbol; p; p = q)
124    {
125	q = p->next;
126	FREE(p);
127    }
128}
129