xref: /original-bsd/old/make/doname.c (revision 0db3846e)
1 static	char *sccsid = "@(#)doname.c	4.9 (Berkeley) 87/06/18";
2 #include "defs"
3 #include <strings.h>
4 #include <signal.h>
5 
6 /*  BASIC PROCEDURE.  RECURSIVE.  */
7 
8 /*
9 p->done = 0   don't know what to do yet
10 p->done = 1   file in process of being updated
11 p->done = 2   file already exists in current state
12 p->done = 3   file make failed
13 */
14 
15 extern char *sys_siglist[];
16 
17 doname(p, reclevel, tval)
18 register struct nameblock *p;
19 int reclevel;
20 TIMETYPE *tval;
21 {
22 int errstat;
23 int okdel1;
24 int didwork;
25 TIMETYPE td, td1, tdep, ptime, ptime1, prestime();
26 register struct depblock *q;
27 struct depblock *qtemp, *srchdir(), *suffp, *suffp1;
28 struct nameblock *p1, *p2;
29 struct shblock *implcom, *explcom;
30 register struct lineblock *lp;
31 struct lineblock *lp1, *lp2;
32 char sourcename[BUFSIZ], prefix[BUFSIZ], temp[BUFSIZ], concsuff[20];
33 char *pnamep, *p1namep, *cp;
34 char *mkqlist();
35 struct chain *qchain, *appendq();
36 
37 {
38 	/*
39 	 * VPATH= ${PATH1}:${PATH2} didn't work.  This fix is so ugly I don't
40 	 * even want to think about it.  Basically it grabs VPATH and
41 	 * explicitly does macro expansion before resolving names.  Why
42 	 * VPATH didn't get handled correctly I have no idea; the symptom
43 	 * was that, while macro expansion got done, the .c files in the
44 	 * non-local directories wouldn't be found.
45 	 */
46 	struct varblock	*vpath_cp, *varptr();
47 	static int	vpath_first;
48 	char	vpath_exp[INMAX];
49 
50 	if (!vpath_first) {
51 		vpath_first = 1;
52 		vpath_cp = varptr("VPATH");
53 		if (vpath_cp->varval) {
54 			subst(vpath_cp->varval, vpath_exp);
55 			setvar("VPATH",vpath_exp);
56 		}
57 	}
58 }
59 if(p == 0)
60 	{
61 	*tval = 0;
62 	return(0);
63 	}
64 
65 if(dbgflag)
66 	{
67 	printf("doname(%s,%d)\n",p->namep,reclevel);
68 	fflush(stdout);
69 	}
70 
71 if(p->done > 0)
72 	{
73 	*tval = p->modtime;
74 	return(p->done == 3);
75 	}
76 
77 errstat = 0;
78 tdep = 0;
79 implcom = 0;
80 explcom = 0;
81 ptime = exists(p);
82 ptime1 = 0;
83 didwork = NO;
84 p->done = 1;	/* avoid infinite loops */
85 
86 qchain = NULL;
87 
88 /* Expand any names that have embedded metacharaters */
89 
90 for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
91 	for(q = lp->depp ; q ; q=qtemp )
92 		{
93 		qtemp = q->nxtdepblock;
94 		expand(q);
95 		}
96 
97 /* make sure all dependents are up to date */
98 
99 for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
100 	{
101 	td = 0;
102 	for(q = lp->depp ; q ; q = q->nxtdepblock)
103 		{
104 		errstat += doname(q->depname, reclevel+1, &td1);
105 		if(dbgflag)
106 		    printf("TIME(%s)=%ld\n", q->depname->namep, td1);
107 		if(td1 > td) td = td1;
108 		if(ptime < td1)
109 			qchain = appendq(qchain, q->depname->namep);
110 		}
111 	if(p->septype == SOMEDEPS)
112 		{
113 		if(lp->shp!=0)
114 		     if( ptime<td || (ptime==0 && td==0) || lp->depp==0)
115 			{
116 			okdel1 = okdel;
117 			okdel = NO;
118 			setvar("@", p->namep);
119 			setvar("?", mkqlist(qchain) );
120 			qchain = NULL;
121 			if( !questflag )
122 				errstat += docom(lp->shp);
123 			setvar("@", (char *) NULL);
124 			okdel = okdel1;
125 			ptime1 = prestime();
126 			didwork = YES;
127 			}
128 		}
129 
130 	else	{
131 		if(lp->shp != 0)
132 			{
133 			if(explcom)
134 				fprintf(stderr, "Too many command lines for `%s'\n",
135 					p->namep);
136 			else	explcom = lp->shp;
137 			}
138 
139 		if(td > tdep) tdep = td;
140 		}
141 	}
142 
143 /* Look for implicit dependents, using suffix rules */
144 
145 for(lp = sufflist ; lp ; lp = lp->nxtlineblock)
146     for(suffp = lp->depp ; suffp ; suffp = suffp->nxtdepblock)
147 	{
148 	pnamep = suffp->depname->namep;
149 	if(suffix(p->namep , pnamep , prefix))
150 		{
151 
152 		srchdir( concat(prefix,"*",temp) , NO, (struct depblock *) NULL);
153 		for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock)
154 		    for(suffp1=lp1->depp ; suffp1 ; suffp1 = suffp1->nxtdepblock)
155 			{
156 			p1namep = suffp1->depname->namep;
157 			if( (p1=srchname(concat(p1namep, pnamep ,concsuff))) &&
158 			    (p2=srchname(concat(prefix, p1namep ,sourcename))) )
159 				{
160 				errstat += doname(p2, reclevel+1, &td);
161 				if(ptime < td)
162 					qchain = appendq(qchain, p2->namep);
163 if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td);
164 				if(td > tdep) tdep = td;
165 				setvar("*", prefix);
166 				if (p2->alias) setvar("<", copys(p2->alias));
167 				else setvar("<", copys(p2->namep));
168 				for(lp2=p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
169 					if(implcom = lp2->shp) break;
170 				goto endloop;
171 				}
172 			}
173 		cp = rindex(prefix, '/');
174 		if (cp++ == 0)
175 			cp = prefix;
176 		setvar("*", cp);
177 		}
178 	}
179 
180 endloop:
181 
182 
183 if(errstat==0 && (ptime<tdep || (ptime==0 && tdep==0) ) )
184 	{
185 	ptime = (tdep>0 ? tdep : prestime() );
186 	setvar("@", p->namep);
187 	setvar("?", mkqlist(qchain) );
188 	if(explcom)
189 		errstat += docom(explcom);
190 	else if(implcom)
191 		errstat += docom(implcom);
192 	else if(p->septype == 0)
193 		if(p1=srchname(".DEFAULT"))
194 			{
195 			if (p->alias) setvar("<", p->alias);
196 			else setvar("<", p->namep);
197 			for(lp2 = p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
198 				if(implcom = lp2->shp)
199 					{
200 					errstat += docom(implcom);
201 					break;
202 					}
203 			}
204 		else if(keepgoing)
205 			{
206 			printf("Don't know how to make %s\n", p->namep);
207 			++errstat;
208 			}
209 		else
210 			fatal1(" Don't know how to make %s", p->namep);
211 
212 	setvar("@", (char *) NULL);
213 	if(noexflag || (ptime = exists(p)) == 0)
214 		ptime = prestime();
215 	}
216 
217 else if(errstat!=0 && reclevel==0)
218 	printf("`%s' not remade because of errors\n", p->namep);
219 
220 else if(!questflag && reclevel==0  &&  didwork==NO)
221 	printf("`%s' is up to date.\n", p->namep);
222 
223 if(questflag && reclevel==0)
224 	exit(ndocoms>0 ? -1 : 0);
225 
226 p->done = (errstat ? 3 : 2);
227 if(ptime1 > ptime) ptime = ptime1;
228 p->modtime = ptime;
229 *tval = ptime;
230 return(errstat);
231 }
232 
233 docom(q)
234 struct shblock *q;
235 {
236 char *s;
237 struct varblock *varptr();
238 int ign, nopr;
239 char string[OUTMAX];
240 char string2[OUTMAX];
241 
242 ++ndocoms;
243 if(questflag)
244 	return(NO);
245 
246 if(touchflag)
247 	{
248 	s = varptr("@")->varval;
249 	if(!silflag)
250 		printf("touch(%s)\n", s);
251 	if(!noexflag)
252 		touch(YES, s);
253 	}
254 
255 else for( ; q ; q = q->nxtshblock )
256 	{
257 	subst(q->shbp,string2);
258 	fixname(string2, string);
259 
260 	ign = ignerr;
261 	nopr = NO;
262 	for(s = string ; *s=='-' || *s=='@' ; ++s)
263 		if(*s == '-')  ign = YES;
264 		else nopr = YES;
265 
266 	if( docom1(s, ign, nopr) && !ign)
267 		if(keepgoing)
268 			return(YES);
269 		else	fatal( (char *) NULL);
270 	}
271 return(NO);
272 }
273 
274 
275 
276 docom1(comstring, nohalt, noprint)
277 register char *comstring;
278 int nohalt, noprint;
279 {
280 register int status;
281 
282 if(comstring[0] == '\0') return(0);
283 
284 if(!silflag && (!noprint || noexflag) )
285 	{
286 	printf("%s%s\n", (noexflag ? "" : prompt), comstring);
287 	fflush(stdout);
288 	}
289 
290 if(noexflag) return(0);
291 
292 if( status = dosys(comstring, nohalt) )
293 	{
294 	unsigned sig = status & 0177;
295 	if( sig ) {
296 		if (sig < NSIG && sys_siglist[sig] != NULL &&
297 		    *sys_siglist[sig] != '\0')
298 			printf("*** %s", sys_siglist[sig]);
299 		else
300 			printf("*** Signal %d", sig);
301 		if (status & 0200)
302 			printf(" - core dumped");
303 	} else
304 		printf("*** Exit %d", status>>8 );
305 
306 	if(nohalt) printf(" (ignored)\n");
307 	else	printf("\n");
308 	fflush(stdout);
309 	}
310 
311 return(status);
312 }
313 
314 
315 /*
316    If there are any Shell meta characters in the name,
317    expand into a list, after searching directory
318 */
319 
320 expand(q)
321 register struct depblock *q;
322 {
323 register char *s;
324 char *s1;
325 struct depblock *p, *srchdir();
326 
327 if (q->depname == NULL)
328 	return;
329 s1 = q->depname->namep;
330 for(s=s1 ; ;) switch(*s++)
331 	{
332 	case '\0':
333 		return;
334 
335 	case '*':
336 	case '?':
337 	case '[':
338 		if( p = srchdir(s1 , YES, q->nxtdepblock) )
339 			{
340 			q->nxtdepblock = p;
341 			q->depname = 0;
342 			}
343 		return;
344 	}
345 }
346