Commit | Line | Data |
---|---|---|
307749bd | 1 | static char *sccsid = "@(#)misc.c 4.2 (Berkeley) 82/10/19"; |
371ccbc6 BJ |
2 | #include "defs" |
3 | ||
4 | FSTATIC struct nameblock *hashtab[HASHSIZE]; | |
5 | FSTATIC int nhashed = 0; | |
6 | ||
7 | ||
8 | /* simple linear hash. hash function is sum of | |
9 | characters mod hash table size. | |
10 | */ | |
11 | hashloc(s) | |
12 | char *s; | |
13 | { | |
14 | register int i; | |
15 | register int hashval; | |
16 | register char *t; | |
17 | ||
18 | hashval = 0; | |
19 | ||
20 | for(t=s; *t!='\0' ; ++t) | |
21 | hashval += *t; | |
22 | ||
23 | hashval %= HASHSIZE; | |
24 | ||
25 | for(i=hashval; | |
26 | hashtab[i]!=0 && unequal(s,hashtab[i]->namep); | |
27 | i = (i+1)%HASHSIZE ) ; | |
28 | ||
29 | return(i); | |
30 | } | |
31 | ||
32 | ||
33 | struct nameblock *srchname(s) | |
34 | char *s; | |
35 | { | |
36 | return( hashtab[hashloc(s)] ); | |
37 | } | |
38 | ||
39 | ||
40 | ||
41 | struct nameblock *makename(s) | |
42 | char *s; | |
43 | { | |
44 | /* make a fresh copy of the string s */ | |
45 | ||
46 | char *copys(); | |
47 | register struct nameblock *p; | |
48 | ||
49 | if(nhashed++ > HASHSIZE-3) | |
50 | fatal("Hash table overflow"); | |
51 | ||
52 | p = ALLOC(nameblock); | |
53 | p->nxtnameblock = firstname; | |
54 | p->namep = copys(s); | |
55 | p->linep = 0; | |
56 | p->done = 0; | |
57 | p->septype = 0; | |
58 | p->modtime = 0; | |
59 | ||
60 | firstname = p; | |
61 | if(mainname == NULL) | |
62 | if(s[0]!='.' || hasslash(s) ) | |
63 | mainname = p; | |
64 | ||
65 | hashtab[hashloc(s)] = p; | |
66 | ||
67 | return(p); | |
68 | } | |
69 | ||
70 | ||
71 | ||
72 | hasslash(s) | |
73 | char *s; | |
74 | { | |
75 | for( ; *s ; ++s) | |
76 | if(*s == '/') | |
77 | return(YES); | |
78 | return(NO); | |
79 | } | |
80 | \f | |
81 | ||
82 | ||
83 | char *copys(s) | |
84 | register char *s; | |
85 | { | |
86 | char *calloc(); | |
87 | register char *t, *t0; | |
88 | ||
89 | if( (t = t0 = calloc( strlen(s)+1 , sizeof(char)) ) == NULL) | |
90 | fatal("out of memory"); | |
91 | while(*t++ = *s++) | |
92 | ; | |
93 | return(t0); | |
94 | } | |
95 | ||
96 | ||
97 | ||
98 | char *concat(a,b,c) /* c = concatenation of a and b */ | |
99 | register char *a,*b; | |
100 | char *c; | |
101 | { | |
102 | register char *t; | |
103 | t = c; | |
104 | ||
105 | while(*t = *a++) t++; | |
106 | while(*t++ = *b++); | |
107 | return(c); | |
108 | } | |
109 | ||
110 | ||
111 | ||
112 | suffix(a,b,p) /* is b the suffix of a? if so, set p = prefix */ | |
113 | register char *a,*b,*p; | |
114 | { | |
115 | char *a0,*b0; | |
116 | a0 = a; | |
117 | b0 = b; | |
118 | ||
119 | while(*a++); | |
120 | while(*b++); | |
121 | ||
122 | if( (a-a0) < (b-b0) ) return(0); | |
123 | ||
124 | while(b>b0) | |
125 | if(*--a != *--b) return(0); | |
126 | ||
127 | while(a0<a) *p++ = *a0++; | |
128 | *p = '\0'; | |
129 | ||
130 | return(1); | |
131 | } | |
132 | ||
133 | ||
134 | ||
135 | ||
136 | ||
137 | ||
138 | int *ckalloc(n) | |
139 | register int n; | |
140 | { | |
141 | register int *p; | |
142 | ||
143 | if( p = (int *) calloc(1,n) ) | |
144 | return(p); | |
145 | ||
146 | fatal("out of memory"); | |
147 | /* NOTREACHED */ | |
148 | } | |
149 | \f | |
150 | /* copy string a into b, substituting for arguments */ | |
151 | char *subst(a,b) | |
152 | register char *a,*b; | |
153 | { | |
154 | static depth = 0; | |
155 | register char *s; | |
156 | char vname[100]; | |
157 | struct varblock *varptr(), *vbp; | |
158 | char closer; | |
159 | ||
160 | if(++depth > 100) | |
161 | fatal("infinitely recursive macro?"); | |
162 | if(a!=0) while(*a) | |
163 | { | |
164 | if(*a != '$') *b++ = *a++; | |
165 | else if(*++a=='\0' || *a=='$') | |
166 | *b++ = *a++; | |
167 | else { | |
168 | s = vname; | |
169 | if( *a=='(' || *a=='{' ) | |
170 | { | |
171 | closer = ( *a=='(' ? ')' : '}'); | |
172 | ++a; | |
173 | while(*a == ' ') ++a; | |
174 | while(*a!=' ' && *a!=closer && *a!='\0') *s++ = *a++; | |
175 | while(*a!=closer && *a!='\0') ++a; | |
176 | if(*a == closer) ++a; | |
177 | } | |
178 | else *s++ = *a++; | |
179 | ||
180 | *s = '\0'; | |
181 | if( (vbp = varptr(vname)) ->varval != 0) | |
182 | { | |
183 | b = subst(vbp->varval, b); | |
184 | vbp->used = YES; | |
185 | } | |
186 | } | |
187 | } | |
188 | ||
189 | *b = '\0'; | |
190 | --depth; | |
191 | return(b); | |
192 | } | |
193 | ||
194 | ||
195 | setvar(v,s) | |
196 | char *v, *s; | |
197 | { | |
198 | struct varblock *varptr(), *p; | |
199 | ||
200 | p = varptr(v); | |
201 | if(p->noreset == 0) | |
202 | { | |
203 | p->varval = s; | |
204 | p->noreset = inarglist; | |
205 | if(p->used && unequal(v,"@") && unequal(v,"*") | |
206 | && unequal(v,"<") && unequal(v,"?") ) | |
207 | fprintf(stderr, "Warning: %s changed after being used\n",v); | |
208 | } | |
209 | } | |
210 | ||
211 | ||
212 | eqsign(a) /*look for arguments with equal signs but not colons */ | |
213 | char *a; | |
214 | { | |
215 | register char *s, *t; | |
216 | ||
217 | while(*a == ' ') ++a; | |
218 | for(s=a ; *s!='\0' && *s!=':' ; ++s) | |
219 | if(*s == '=') | |
220 | { | |
221 | for(t = a ; *t!='=' && *t!=' ' && *t!='\t' ; ++t ); | |
222 | *t = '\0'; | |
223 | ||
224 | for(++s; *s==' ' || *s=='\t' ; ++s); | |
225 | setvar(a, copys(s)); | |
226 | return(YES); | |
227 | } | |
228 | ||
229 | return(NO); | |
230 | } | |
231 | ||
232 | ||
233 | struct varblock *varptr(v) | |
234 | char *v; | |
235 | { | |
236 | register struct varblock *vp; | |
237 | ||
238 | for(vp = firstvar; vp ; vp = vp->nxtvarblock) | |
239 | if(! unequal(v , vp->varname)) | |
240 | return(vp); | |
241 | ||
242 | vp = ALLOC(varblock); | |
243 | vp->nxtvarblock = firstvar; | |
244 | firstvar = vp; | |
245 | vp->varname = copys(v); | |
246 | vp->varval = 0; | |
247 | return(vp); | |
248 | } | |
249 | ||
250 | ||
251 | fatal1(s, t) | |
252 | char *s, *t; | |
253 | { | |
307749bd | 254 | char buf[BUFSIZ]; |
371ccbc6 BJ |
255 | sprintf(buf, s, t); |
256 | fatal(buf); | |
257 | } | |
258 | ||
259 | ||
260 | ||
261 | fatal(s) | |
262 | char *s; | |
263 | { | |
264 | if(s) fprintf(stderr, "Make: %s. Stop.\n", s); | |
265 | else fprintf(stderr, "\nStop.\n"); | |
266 | #ifdef unix | |
267 | exit(1); | |
268 | #endif | |
269 | #ifdef gcos | |
270 | exit(0); | |
271 | #endif | |
272 | } | |
273 | ||
274 | ||
275 | ||
276 | yyerror(s) | |
277 | char *s; | |
278 | { | |
279 | char buf[50]; | |
280 | extern int yylineno; | |
281 | ||
282 | sprintf(buf, "line %d: %s", yylineno, s); | |
283 | fatal(buf); | |
284 | } | |
285 | ||
286 | ||
287 | ||
288 | struct chain *appendq(head, tail) | |
289 | struct chain *head; | |
290 | char *tail; | |
291 | { | |
292 | register struct chain *p, *q; | |
293 | ||
294 | p = ALLOC(chain); | |
295 | p->datap = tail; | |
296 | ||
297 | if(head) | |
298 | { | |
299 | for(q = head ; q->nextp ; q = q->nextp) | |
300 | ; | |
301 | q->nextp = p; | |
302 | return(head); | |
303 | } | |
304 | else | |
305 | return(p); | |
306 | } | |
307 | ||
308 | ||
309 | ||
310 | ||
311 | ||
312 | char *mkqlist(p) | |
313 | struct chain *p; | |
314 | { | |
315 | register char *qbufp, *s; | |
316 | static char qbuf[QBUFMAX]; | |
317 | ||
318 | if(p == NULL) | |
319 | { | |
320 | qbuf[0] = '\0'; | |
321 | return; | |
322 | } | |
323 | ||
324 | qbufp = qbuf; | |
325 | ||
326 | for( ; p ; p = p->nextp) | |
327 | { | |
328 | s = p->datap; | |
329 | if(qbufp+strlen(s) > &qbuf[QBUFMAX-3]) | |
330 | { | |
331 | fprintf(stderr, "$? list too long\n"); | |
332 | break; | |
333 | } | |
334 | while (*s) | |
335 | *qbufp++ = *s++; | |
336 | *qbufp++ = ' '; | |
337 | } | |
338 | *--qbufp = '\0'; | |
339 | return(qbuf); | |
340 | } |