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