xref: /original-bsd/usr.bin/struct/struct/1.hash.c (revision 25342562)
1 /*-
2  * %sccs.include.proprietary.c%
3  */
4 
5 #ifndef lint
6 static char sccsid[] = "@(#)1.hash.c	8.1 (Berkeley) 06/06/93";
7 #endif /* not lint */
8 
9 #include <stdio.h>
10 #include "1.incl.h"
11 #include "1.defs.h"
12 #include"def.h"
13 
14 extern int match[], symclass[],  action[], newstate[];
15 extern char symbol[];
16 long *hashtab;
17 int *value, *chain;
18 
19 extern FILE *infd;
20 
21 
22 parse()
23 	{int i,j,found,current, someread;
24 	char c;
25 
26 	hash_init();
27 	routinit();
28 	line_init();
29 
30 	someread = 0;			/* indicates haven't read part of a routine */
31 
32 	empseek(0);
33 	endbuf = getline(&endline, &endchar, &endcom, & comchar);
34 	if (progress && endbuf != -1) fprintf(stderr,"parsing\n");
35 	while(endbuf != -1)			/* getline returns -1 when no more input */
36 		{
37 		someread = 1;
38 		if (progress > 0)
39 			{
40 			for (i = begline; i <= endline; i++)
41 				if (!(i % progress)) fprintf(stderr,"parsing line %d\n",i);
42 			}
43 		current = 0;
44 		for (i = 0; i < endbuf; i++)
45 			{
46 
47 			c = buffer[i];
48 			if(c != '~')
49 				{
50 				found = 0;
51 				if ( (current < 0 || current >= snum) && current != ABORT)
52 					{
53 					strerr("in parsing:","","");
54 					fprintf(stderr,"line %d of file, parser in invalid state", current);
55 					fprintf(stderr,"treating it as straight line code\n");
56 					current = ABORT;
57 					}
58 				else
59 					for (j = match[current];  j < match[current + 1]; j++)
60 						{
61 						if ((symclass[j] == 0 && c == symbol[j]) ||
62 						    (symclass[j] != 0 && classmatch(c,symclass[j]) ))
63 							{found = 1;  break;
64 							}
65 						}
66 				if (!found)
67 					{
68 					error("in syntax:","","");
69 					fprintf(stderr,"between lines %d and %d of file\n",begline, endline);
70 					if (debug)
71 					fprintf(stderr,"symbol '%c' does not match entries for state %d\n",c,current);
72 					fprintf(stderr,"treating it as straight line code\n");
73 					current = ABORT;
74 					}
75 				else if (!action[j])
76 					current = newstate[j];
77 				else
78 					{
79 					current = act(action[j],c,i);
80 					if (current == nulls)  current = newstate[j];
81 					}
82 				if (current == ABORT)  break;
83 				if (current == endrt)
84 					{
85 					return(1);
86 					}
87 				}
88 			}
89 		line_init();
90 		endbuf = getline(&endline, &endchar, &endcom,&comchar);
91 		}
92 	if (someread) return(1);
93 	else return(0);
94 	}
95 
96 
97 hash_init()
98 	{
99 	int i;
100 	hashtab = challoc(sizeof(*hashtab) * maxhash);
101 	chain = challoc(sizeof(*chain) * maxhash);
102 	value = challoc(sizeof(*value) * maxhash);
103 	for (i = 0; i < maxhash; i++)
104 		{
105 		hashtab[i] = -1L;
106 		value[i] = -2;
107 		chain[i] = 0;
108 		}
109 	}
110 
111 
112 hash_check()
113 	{
114 	int i;
115 	for (i = 0; i < maxhash; ++i)
116 		if (value[i] == -2 && hashtab[i] != -1L)
117 			{
118 			error("in syntax; label used but does not appear as statement label:","","");
119 			fprintf(stderr,"%D\n",hashtab[i]);
120 			routerr = 1;
121 			}
122 	}
123 
124 hash_free()
125 	{
126 	chfree(hashtab,sizeof(*hashtab) * maxhash);
127 	hashtab = 0;
128 	chfree(chain,sizeof(*chain) * maxhash);
129 	chain = 0;
130 	chfree(value,sizeof(*value) * maxhash);
131 	value = 0;
132 	}
133 hash(x)
134 long x;
135 	{
136 	int quo, rem, hcount, temp;
137 
138 	ASSERT(x >= 0L, hash);
139 	quo = x/maxhash;
140 	rem = x - (quo * maxhash);
141 	if (quo == 0)  quo = 1;
142 
143 	temp = rem;
144 	for (hcount=0; (hashtab[temp] != -1L) && (hashtab[temp] != x) && (hcount<maxhash); hcount++)
145 		temp = (temp + quo)%maxhash;
146 	if(hcount>=maxhash) faterr("hash table overflow - too many labels","","");
147 	hashtab[temp] = x;
148 	return(temp);
149 	}
150 
151 addref(x,ptr)				/* put ptr in chain for x or assign value of x to *ptr */
152 long x;
153 int *ptr;
154 	{
155 	int index;
156 	index = hash(x);
157 
158 	if (value[index]  == -1)
159 		{			/* x already assigned value */
160 		*ptr = chain[index];
161 		return;
162 		}
163 
164 	/* add ptr to chain */
165 
166 	if (chain[index] == 0)
167 		*ptr = 0;
168 	else
169 		*ptr = chain[index];
170 	chain[index] = ptr;
171 	}
172 
173 fixvalue (x,ptr)
174 long x;
175 int ptr;
176 	{
177 	int *temp1, *temp2, index, temp0;
178 	index = hash(x);
179 
180 	while (index != -2)
181 		{			/* trace chain of linked labels */
182 
183 		if (value[index]  == -1)
184 			{
185 			error("in syntax:  ","","");
186 			fprintf(stderr,"attempt to redefine value of label %D between lines %d and %d\n",
187 				x,begline,endline);
188 			routerr = 1;
189 			return;
190 			}
191 
192 		temp1 = &chain[index];		/* trace chain for each label */
193 		while (temp1 != 0)
194 			{
195 			temp2 = *temp1;
196 			*temp1 = ptr;
197 			temp1 = temp2;
198 			}
199 		temp0 = index;
200 		index = value[index];
201 		value[temp0] = -1;
202 		}
203 	}
204 
205 connect(x,y)
206 long x,y;
207 	{
208 	int *temp, index, temp2;
209 	index = hash(x);
210 
211 	if (value[index] == -1)
212 		fixvalue(y, chain[index]);
213 	else
214 		{
215 		if (y == implicit)
216 		{		/* attach implicit chain to x chain */
217 		temp = &chain[index];
218 
219 		while (*temp != 0)
220 			temp = *temp;
221 
222 		*temp = chain[hash(y)];
223 		}
224 		temp2 = index;		/* attach y linked labels to x linked labels */
225 		while (value[temp2] >= 0)
226 			temp2 = value[temp2];
227 		if (y == implicit)
228 			value[temp2] = value[hash(y)];
229 		else
230 			value[temp2] = hash(y);
231 		}
232 	if (y == implicit)  clear(y);
233 	}
234 
235 
236 clear(x)
237 long x;
238 	{
239 	int index;
240 	index = hash(x);
241 	value[index] = -2;
242 	chain[index] = 0;
243 	hashtab[index] = -1L;
244 	}
245 
246 
247