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