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