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