|
|
1.1 root 1: static char *sccsid = "@(#)doname.c 4.2 (Berkeley) 83/02/03";
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("*", &prefix[rindex(prefix, '/')]);
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.