xref: /original-bsd/old/make/misc.c (revision 9d44dd09)
1 static	char *sccsid = "@(#)misc.c	4.1 (Berkeley) 81/02/28";
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 
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 
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 {
254 char buf[100];
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 }
341