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