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