|
|
1.1 root 1: static char *sccsid = "@(#)doname.c 8th edition (Bell Labs) 85/07/16";
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, nowait)
14: register nameblkp p;
15: int reclevel;
16: TIMETYPE *tval;
17: int nowait;
18: {
19: int errstat;
20: int okdel1;
21: int didwork;
22: int len;
23: TIMETYPE td, td1, tdep, ptime, ptime1, prestime();
24: register depblkp q;
25: depblkp qtemp, srchdir(), suffp, suffp1;
26: nameblkp p1, p2, chkname();
27: struct shblock *implcom, *explcom;
28: register lineblkp lp;
29: lineblkp lp1, lp2;
30: char sourcename[100], prefix[100], temp[100], concsuff[20];
31: char *wildsub(), *wildmatch(), *stem;
32: char *pnamep, *p1namep;
33: char *mkqlist();
34: chainp allchain, qchain, appendq();
35: char qbuf[QBUFMAX], tgsbuf[QBUFMAX];
36: wildp wp;
37: int nproc1;
38: char *lastslash, *s;
39:
40: if(p == 0)
41: {
42: *tval = 0;
43: return 0;
44: }
45:
46: if(dbgflag)
47: {
48: printf("doname(%s,%d)\n",p->namep,reclevel);
49: fflush(stdout);
50: }
51:
52: if(p->done > 0)
53: {
54: *tval = p->modtime;
55: return (p->done == 3);
56: }
57:
58: errstat = 0;
59: tdep = 0;
60: implcom = 0;
61: explcom = 0;
62: ptime = exists(p->namep);
63: ptime1 = 0;
64: didwork = NO;
65: p->done = 1; /* avoid infinite loops */
66: nproc1 = nproc; /* current depth of process stack */
67:
68: qchain = NULL;
69: allchain = NULL;
70:
71: /* define values of Bradford's $$@ and $$/ macros */
72: for(s = lastslash = p->namep; *s; ++s)
73: if(*s == '/')
74: lastslash = s;
75: setvar("$@", p->namep, YES);
76: setvar("$/", lastslash, YES);
77:
78:
79: /* expand any names that have embedded metacharacters */
80:
81: for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
82: for(q = lp->depp ; q ; q=qtemp )
83: {
84: qtemp = q->nxtdepblock;
85: expand(q);
86: }
87:
88: /* make sure all dependents are up to date */
89:
90: for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
91: {
92: td = 0;
93: for(q = lp->depp ; q ; q = q->nxtdepblock)
94: if(q->depname)
95: {
96: errstat += doname(q->depname, reclevel+1, &td1, q->nowait);
97: if(dbgflag)
98: printf("TIME(%s)=%ld\n",q->depname->namep, td1);
99: if(td1 > td)
100: td = td1;
101: if(ptime < td1)
102: qchain = appendq(qchain, q->depname->namep);
103: allchain = appendq(allchain, q->depname->namep);
104: }
105: if(p->septype == SOMEDEPS)
106: {
107: if(lp->shp)
108: if( ptime<td || (ptime==0 && td==0) || lp->depp==0)
109: {
110: okdel1 = okdel;
111: okdel = NO;
112: set3var("@", p->namep);
113: setvar("?", mkqlist(qchain,qbuf), YES);
114: setvar("^", mkqlist(allchain,tgsbuf), YES);
115: qchain = NULL;
116: if( !questflag )
117: errstat += docom(lp->shp, nowait, nproc1);
118: set3var("@", CHNULL);
119: okdel = okdel1;
120: ptime1 = prestime();
121: didwork = YES;
122: }
123: }
124:
125: else {
126: if(lp->shp != 0)
127: {
128: if(explcom)
129: fprintf(stderr, "Too many command lines for `%s'\n",
130: p->namep);
131: else explcom = lp->shp;
132: }
133:
134: if(td > tdep) tdep = td;
135: }
136: }
137:
138:
139:
140: /* Look for implicit dependents, using suffix rules */
141:
142: for(lp = sufflist ; lp ; lp = lp->nxtlineblock)
143: for(suffp = lp->depp ; suffp ; suffp = suffp->nxtdepblock)
144: {
145: pnamep = suffp->depname->namep;
146: if(suffix(p->namep , pnamep , prefix))
147: {
148: (void)srchdir(concat(prefix,"*",temp), NO, (depblkp) NULL);
149: for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock)
150: for(suffp1=lp1->depp; suffp1 ; suffp1 = suffp1->nxtdepblock)
151: {
152: p1namep = suffp1->depname->namep;
153: if( (p1=srchname(concat(p1namep, pnamep ,concsuff))) &&
154: (p2=srchname(concat(prefix, p1namep ,sourcename))) )
155: {
156: errstat += doname(p2, reclevel+1, &td, NO);
157: if(ptime < td)
158: qchain = appendq(qchain, p2->namep);
159: if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td);
160: if(td > tdep) tdep = td;
161: set3var("*", prefix);
162: set3var("<", copys(sourcename));
163: for(lp2=p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
164: if(implcom = lp2->shp) break;
165: goto endloop;
166: }
167: }
168: }
169: }
170:
171: /* Look for implicit dependents, using pattern matching rules */
172:
173: len = strlen(p->namep);
174: for(wp = firstwild ; wp ; wp = wp->next)
175: if(stem = wildmatch(wp, p->namep, len) )
176: {
177: lp = wp->linep;
178: for(q = lp->depp; q; q = q->nxtdepblock)
179: {
180: if(dbgflag>1 && q->depname)
181: fprintf(stderr,"check dep of %s on %s\n", p->namep,
182: wildsub(q->depname->namep,stem));
183: if(q->depname &&
184: ! chkname(wildsub(q->depname->namep,stem)))
185: break;
186: }
187:
188: if(q) /* some name not found, go to next line */
189: continue;
190:
191: for(q = lp->depp; q; q = q->nxtdepblock)
192: {
193: nameblkp tamep;
194: if(q->depname == NULL)
195: continue;
196: tamep = srchname( wildsub(q->depname->namep,stem));
197: /*TEMP fprintf(stderr,"check dep %s on %s =>%s\n",p->namep,q->depname->namep,tamep->namep);*/
198: /*TEMP*/if(dbgflag) printf("%s depends on %s. stem=%s\n", p->namep,tamep->namep, stem);
199: errstat += doname(tamep, reclevel+1, &td, q->nowait);
200: if(ptime < td)
201: qchain = appendq(qchain, tamep->namep);
202: allchain = appendq(allchain, tamep->namep);
203: if(dbgflag) printf("TIME(%s)=%ld\n", tamep->namep, td);
204: if(td > tdep)
205: tdep = td;
206: set3var("<", copys(tamep->namep) );
207: }
208: set3var("*", stem);
209: setvar("%", stem, YES);
210: implcom = lp->shp;
211: goto endloop;
212: }
213:
214: endloop:
215:
216:
217: if(errstat==0 && (ptime<tdep || (ptime==0 && tdep==0) ) )
218: {
219: ptime = (tdep>0 ? tdep : prestime() );
220: set3var("@", p->namep);
221: setvar("?", mkqlist(qchain,qbuf), YES);
222: setvar("^", mkqlist(allchain,tgsbuf), YES);
223: if(explcom)
224: errstat += docom(explcom, nowait, nproc1);
225: else if(implcom)
226: errstat += docom(implcom, nowait, nproc1);
227: else if(p->septype == 0)
228: if(p1=srchname(".DEFAULT"))
229: {
230: set3var("<", p->namep);
231: for(lp2 = p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
232: if(implcom = lp2->shp)
233: {
234: errstat += docom(implcom, nowait,nproc1);
235: break;
236: }
237: }
238: else if(keepgoing)
239: {
240: printf("Don't know how to make %s\n", p->namep);
241: ++errstat;
242: }
243: else
244: fatal1(" Don't know how to make %s", p->namep);
245:
246: set3var("@", CHNULL);
247: if(noexflag || nowait || (ptime = exists(p->namep)) == 0 )
248: ptime = prestime();
249: }
250:
251: else if(errstat!=0 && reclevel==0)
252: printf("`%s' not remade because of errors\n", p->namep);
253:
254: else if(!questflag && reclevel==0 && didwork==NO)
255: printf("`%s' is up to date.\n", p->namep);
256:
257: if(questflag && reclevel==0)
258: exit(ndocoms>0 ? -1 : 0);
259:
260: p->done = (errstat ? 3 : 2);
261: if(ptime1 > ptime)
262: ptime = ptime1;
263: p->modtime = ptime;
264: *tval = ptime;
265: return errstat;
266: }
267:
268: docom(q, nowait, nproc1)
269: struct shblock *q;
270: int nowait;
271: int nproc1;
272: {
273: char *s;
274: struct varblock *varptr();
275: int ign, nopr, doit;
276: char string[OUTMAX];
277:
278: ++ndocoms;
279: if(questflag)
280: return NO;
281:
282: if(touchflag)
283: {
284: s = varptr("@")->varval;
285: if(!silflag)
286: printf("touch(%s)\n", s);
287: if(!noexflag)
288: touch(YES, s);
289: return NO;
290: }
291:
292: if(nproc1 < nproc)
293: waitstack(nproc1);
294:
295: for( ; q ; q = q->nxtshblock )
296: {
297: subst(q->shbp,string);
298: ign = ignerr;
299: nopr = NO;
300: doit = NO;
301: for(s = string ; ; ++s)
302: {
303: switch(*s)
304: {
305: case '-':
306: ign = YES;
307: continue;
308: case '@':
309: nopr = YES;
310: continue;
311: case '+':
312: doit = YES;
313: continue;
314: default:
315: break;
316: }
317: break;
318: }
319:
320: if( docom1(s, ign, nopr, doit||!noexflag, nowait&&!q->nxtshblock) && !ign)
321: return YES;
322: }
323: return NO;
324: }
325:
326:
327:
328: docom1(comstring, nohalt, noprint, doit, nowait)
329: register char *comstring;
330: int nohalt, noprint, doit, nowait;
331: {
332: register int status;
333: char *prefix;
334:
335: if(comstring[0] == '\0')
336: return 0;
337:
338: if(!silflag && (!noprint || !doit) )
339: prefix = doit ? prompt : "" ;
340: else
341: prefix = CHNULL;
342:
343: if(dynmacro(comstring) || !doit)
344: {
345: if(prefix)
346: {
347: fputs(prefix, stdout);
348: puts(comstring); /* with a newline */
349: fflush(stdout);
350: }
351: return 0;
352: }
353:
354: status = dosys(comstring, nohalt, nowait, prefix);
355: baddirs(); /* directories may have changed */
356: return status;
357: }
358:
359:
360: /*
361: If there are any Shell meta characters in the name,
362: expand into a list, after searching directory
363: */
364:
365: expand(q)
366: register depblkp q;
367: {
368: register char *s;
369: char *s1;
370: depblkp p, srchdir();
371:
372: s1 = q->depname->namep;
373: for(s=s1 ; ;) switch(*s++)
374: {
375: case '\0':
376: return;
377:
378: case '*':
379: case '?':
380: case '[':
381: if( p = srchdir(s1 , YES, q->nxtdepblock) )
382: {
383: q->nxtdepblock = p;
384: q->depname = 0;
385: }
386: return;
387: }
388: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.