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