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