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