BSD 4_3 development
[unix-history] / usr / src / usr.bin / efl / symtab.c
CommitLineData
832026c6
C
1#include "defs"
2
3#ifdef HASHEDTABLE
4/* Basic symbol table maintainer. Action depends on t:
5t = -1 Remove name from table
6t = 0 Put name in table if not there. Copy name string
7t = 1 Find name in table if there, otherwise return 0.
8t = 2 Put name in table if not there. Do not copy name
9*/
10
11struct stentry *hashtab[MAXEFLNAMES+1];
12struct stentry **hashend = hashtab+MAXEFLNAMES+1;
13
14#define NEXT(x) (++x<hashend ? x : hashtab )
15
16struct stentry *name(s,t)
17char *s;
18int t;
19{
20int hash;
21register struct stentry *p, **hp;
22char *copys();
23
24hash = hashfunct(s);
25
26for(hp = hashtab + hash; (p = *hp) ; hp = NEXT(hp) )
27 if(hash==p->hashval && equals(s,p->namep))
28 switch(t)
29 {
30 case -1:
31 cfree(p->namep);
32 cfree(p);
33 delhash(hp);
34 --neflnames;
35 return(0);
36
37 case 0:
38 case 1:
39 case 2:
40 return(p);
41
42 default:
43 fatal("name: illegal argument");
44 }
45
46/* not in table */
47switch(t)
48 {
49 case -1:
50 fatal1("cannot delete nonexistent name %s from symbol table", s);
51
52 case 1:
53 return(0);
54
55 case 0:
56 case 2:
57 if(++neflnames >= MAXEFLNAMES)
58 fatal("hash table full");
59
60 *hp = p = ALLOC(stentry);
61 p->namep = (t==0 ? copys(s) : s);
62 p->hashval = hash;
63 return(p);
64
65 default:
66 fatal("illegal call to name");
67 }
68}
69
70
71
72hashfunct(s)
73register char *s;
74{
75register int h;
76
77h = 0;
78while(*s)
79 h += *s++;
80
81return( h % (MAXEFLNAMES+1) );
82}
83
84
85delhash(hp)
86struct stentry **hp;
87{
88struct stentry **hq, **hvp;
89
90for ( ; ; )
91 {
92 *hp = 0;
93 hq = hp;
94 for(hp = NEXT(hp) ; *hp &&
95 ( (hq < (hvp = hashtab + (*hp)->hashval) && hvp<=hp)
96 || (hp<hq && hq<hvp) || (hvp<=hp && hp<hq) ) ;
97 hp = NEXT(hp) )
98 ;
99 if(*hp == 0)
100 return;
101 *hq = *hp;
102 }
103}
104#endif
105\f
106#ifndef HASHEDTABLE
107/* Basic symbol table maintainer. Action depends on t:
108t = -1 Remove name from table
109t = 0 Put name in table if not there. Copy name string
110t = 1 Find name in table if there, otherwise return 0.
111t = 2 Put name in table if not there. Do not copy name
112*/
113
114struct stentry *hashtab[MAXEFLNAMES];
115struct stentry **hashend hashtab;
116
117name(s,t)
118char *s;
119int t;
120{
121int hash;
122register struct stentry *p, **hp;
123char *copys();
124
125hash = hashfunct(s);
126
127for(hp = hashtab ; hp<hashend ; ++hp)
128 if( (p = *hp) && hash==p->hashval && equals(s,p->namep))
129 switch(t)
130 {
131 case -1:
132 cfree(p->namep);
133 cfree(p);
134 *hp = 0;
135 return(0);
136
137 case 0:
138 case 1:
139 case 2:
140 return(p);
141
142 default:
143 fatal("name: illegal argument");
144 }
145
146/* not in table */
147switch(t)
148 {
149 case -1:
150 fatal1("cannot delete nonexistent name %s from symbol table", s);
151
152 case 1:
153 return(0);
154
155 case 0:
156 case 2:
157 /* look for an empty slot */
158 for(hp = hashtab ; hp<hashend && *hp!=0 ; ++hp)
159 ;
160
161 if(hp == hashend)
162 if(++neflnames >= MAXEFLNAMES)
163 fatal("hash table full");
164 else ++hashend;
165
166 *hp = p = ALLOC(stentry);
167 p->namep = (t==0 ? copys(s) : s);
168 p->hashval = hash;
169 return(p);
170
171 default:
172 fatal("illegal call to name");
173 }
174}
175
176
177
178hashfunct(s)
179register char *s;
180{
181register int h;
182
183h = 0;
184while(*s)
185 h = *s++;
186
187return(h);
188}
189#endif