1219b2ee8SDavid du Colombier #include "defs.h"
2219b2ee8SDavid du Colombier
3219b2ee8SDavid du Colombier static int docom1(char *, int, int, int, int);
4219b2ee8SDavid du Colombier static void expand(depblkp);
5219b2ee8SDavid du Colombier
6219b2ee8SDavid du Colombier /* BASIC PROCEDURE. RECURSIVE. */
7219b2ee8SDavid du Colombier
8219b2ee8SDavid du Colombier /*
9219b2ee8SDavid du Colombier p->done = 0 don't know what to do yet
10219b2ee8SDavid du Colombier p->done = 1 file in process of being updated
11219b2ee8SDavid du Colombier p->done = 2 file already exists in current state
12219b2ee8SDavid du Colombier p->done = 3 file make failed
13219b2ee8SDavid du Colombier */
14219b2ee8SDavid du Colombier
15219b2ee8SDavid du Colombier int
doname(nameblkp p,int reclevel,time_t * tval,int nowait)16219b2ee8SDavid du Colombier doname(nameblkp p, int reclevel, time_t *tval, int nowait)
17219b2ee8SDavid du Colombier {
18219b2ee8SDavid du Colombier int errstat;
19219b2ee8SDavid du Colombier int okdel1;
20219b2ee8SDavid du Colombier int didwork;
21219b2ee8SDavid du Colombier int len;
22219b2ee8SDavid du Colombier time_t td, td1, tdep, ptime, ptime1;
23219b2ee8SDavid du Colombier depblkp q;
24219b2ee8SDavid du Colombier depblkp qtemp, suffp, suffp1;
25219b2ee8SDavid du Colombier nameblkp p1, p2;
26219b2ee8SDavid du Colombier struct shblock *implcom, *explcom;
27219b2ee8SDavid du Colombier lineblkp lp;
28219b2ee8SDavid du Colombier lineblkp lp1, lp2;
29219b2ee8SDavid du Colombier char sourcename[100], prefix[100], temp[100], concsuff[20];
30219b2ee8SDavid du Colombier char *stem;
31219b2ee8SDavid du Colombier char *pnamep, *p1namep;
32219b2ee8SDavid du Colombier chainp allchain, qchain;
33219b2ee8SDavid du Colombier char qbuf[QBUFMAX], tgsbuf[QBUFMAX];
34219b2ee8SDavid du Colombier wildp wp;
35219b2ee8SDavid du Colombier int nproc1;
36219b2ee8SDavid du Colombier char *lastslash, *s;
37219b2ee8SDavid du Colombier
38219b2ee8SDavid du Colombier if(p == 0)
39219b2ee8SDavid du Colombier {
40219b2ee8SDavid du Colombier *tval = 0;
41219b2ee8SDavid du Colombier return 0;
42219b2ee8SDavid du Colombier }
43219b2ee8SDavid du Colombier
44219b2ee8SDavid du Colombier if(dbgflag)
45219b2ee8SDavid du Colombier {
46219b2ee8SDavid du Colombier printf("doname(%s,%d)\n",p->namep,reclevel);
47219b2ee8SDavid du Colombier fflush(stdout);
48219b2ee8SDavid du Colombier }
49219b2ee8SDavid du Colombier
50219b2ee8SDavid du Colombier if(p->done > 0)
51219b2ee8SDavid du Colombier {
52219b2ee8SDavid du Colombier *tval = p->modtime;
53219b2ee8SDavid du Colombier return (p->done == 3);
54219b2ee8SDavid du Colombier }
55219b2ee8SDavid du Colombier
56219b2ee8SDavid du Colombier errstat = 0;
57219b2ee8SDavid du Colombier tdep = 0;
58219b2ee8SDavid du Colombier implcom = 0;
59219b2ee8SDavid du Colombier explcom = 0;
60219b2ee8SDavid du Colombier ptime = exists(p->namep);
61219b2ee8SDavid du Colombier ptime1 = 0;
62219b2ee8SDavid du Colombier didwork = NO;
63219b2ee8SDavid du Colombier p->done = 1; /* avoid infinite loops */
64219b2ee8SDavid du Colombier nproc1 = nproc; /* current depth of process stack */
65219b2ee8SDavid du Colombier
66219b2ee8SDavid du Colombier qchain = NULL;
67219b2ee8SDavid du Colombier allchain = NULL;
68219b2ee8SDavid du Colombier
69219b2ee8SDavid du Colombier /* define values of Bradford's $$@ and $$/ macros */
70219b2ee8SDavid du Colombier for(s = lastslash = p->namep; *s; ++s)
71219b2ee8SDavid du Colombier if(*s == '/')
72219b2ee8SDavid du Colombier lastslash = s;
73219b2ee8SDavid du Colombier setvar("$@", p->namep, YES);
74219b2ee8SDavid du Colombier setvar("$/", lastslash, YES);
75219b2ee8SDavid du Colombier
76219b2ee8SDavid du Colombier
77219b2ee8SDavid du Colombier /* expand any names that have embedded metacharacters */
78219b2ee8SDavid du Colombier
79219b2ee8SDavid du Colombier for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
80219b2ee8SDavid du Colombier for(q = lp->depp ; q ; q=qtemp )
81219b2ee8SDavid du Colombier {
82219b2ee8SDavid du Colombier qtemp = q->nxtdepblock;
83219b2ee8SDavid du Colombier expand(q);
84219b2ee8SDavid du Colombier }
85219b2ee8SDavid du Colombier
86219b2ee8SDavid du Colombier /* make sure all dependents are up to date */
87219b2ee8SDavid du Colombier
88219b2ee8SDavid du Colombier for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
89219b2ee8SDavid du Colombier {
90219b2ee8SDavid du Colombier td = 0;
91219b2ee8SDavid du Colombier for(q = lp->depp ; q ; q = q->nxtdepblock)
92219b2ee8SDavid du Colombier if(q->depname)
93219b2ee8SDavid du Colombier {
94219b2ee8SDavid du Colombier errstat += doname(q->depname, reclevel+1, &td1, q->nowait);
95219b2ee8SDavid du Colombier if(dbgflag)
96219b2ee8SDavid du Colombier printf("TIME(%s)=%ld\n",q->depname->namep, td1);
97219b2ee8SDavid du Colombier if(td1 > td)
98219b2ee8SDavid du Colombier td = td1;
99219b2ee8SDavid du Colombier if(ptime < td1)
100219b2ee8SDavid du Colombier qchain = appendq(qchain, q->depname->namep);
101219b2ee8SDavid du Colombier allchain = appendq(allchain, q->depname->namep);
102219b2ee8SDavid du Colombier }
103219b2ee8SDavid du Colombier if(p->septype == SOMEDEPS)
104219b2ee8SDavid du Colombier {
105219b2ee8SDavid du Colombier if(lp->shp)
106219b2ee8SDavid du Colombier if( ptime<td || (ptime==0 && td==0) || lp->depp==0)
107219b2ee8SDavid du Colombier {
108219b2ee8SDavid du Colombier okdel1 = okdel;
109219b2ee8SDavid du Colombier okdel = NO;
110219b2ee8SDavid du Colombier set3var("@", p->namep);
111219b2ee8SDavid du Colombier setvar("?", mkqlist(qchain,qbuf), YES);
112219b2ee8SDavid du Colombier setvar("^", mkqlist(allchain,tgsbuf), YES);
113219b2ee8SDavid du Colombier qchain = NULL;
114219b2ee8SDavid du Colombier if( !questflag )
115219b2ee8SDavid du Colombier errstat += docom(lp->shp, nowait, nproc1);
116219b2ee8SDavid du Colombier set3var("@", CHNULL);
117219b2ee8SDavid du Colombier okdel = okdel1;
118219b2ee8SDavid du Colombier ptime1 = prestime();
119219b2ee8SDavid du Colombier didwork = YES;
120219b2ee8SDavid du Colombier }
121219b2ee8SDavid du Colombier }
122219b2ee8SDavid du Colombier
123219b2ee8SDavid du Colombier else {
124219b2ee8SDavid du Colombier if(lp->shp != 0)
125219b2ee8SDavid du Colombier {
126219b2ee8SDavid du Colombier if(explcom)
127219b2ee8SDavid du Colombier fprintf(stderr, "Too many command lines for `%s'\n",
128219b2ee8SDavid du Colombier p->namep);
129219b2ee8SDavid du Colombier else explcom = lp->shp;
130219b2ee8SDavid du Colombier }
131219b2ee8SDavid du Colombier
132219b2ee8SDavid du Colombier if(td > tdep) tdep = td;
133219b2ee8SDavid du Colombier }
134219b2ee8SDavid du Colombier }
135219b2ee8SDavid du Colombier
136219b2ee8SDavid du Colombier
137219b2ee8SDavid du Colombier
138219b2ee8SDavid du Colombier /* Look for implicit dependents, using suffix rules */
139219b2ee8SDavid du Colombier
140219b2ee8SDavid du Colombier for(lp = sufflist ; lp ; lp = lp->nxtlineblock)
141219b2ee8SDavid du Colombier for(suffp = lp->depp ; suffp ; suffp = suffp->nxtdepblock)
142219b2ee8SDavid du Colombier {
143219b2ee8SDavid du Colombier pnamep = suffp->depname->namep;
144219b2ee8SDavid du Colombier if(suffix(p->namep , pnamep , prefix))
145219b2ee8SDavid du Colombier {
146219b2ee8SDavid du Colombier (void)srchdir(concat(prefix,"*",temp), NO, (depblkp) NULL);
147219b2ee8SDavid du Colombier for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock)
148219b2ee8SDavid du Colombier for(suffp1=lp1->depp; suffp1 ; suffp1 = suffp1->nxtdepblock)
149219b2ee8SDavid du Colombier {
150219b2ee8SDavid du Colombier p1namep = suffp1->depname->namep;
151219b2ee8SDavid du Colombier if( (p1=srchname(concat(p1namep, pnamep ,concsuff))) &&
152219b2ee8SDavid du Colombier (p2=srchname(concat(prefix, p1namep ,sourcename))) )
153219b2ee8SDavid du Colombier {
154219b2ee8SDavid du Colombier errstat += doname(p2, reclevel+1, &td, NO);
155219b2ee8SDavid du Colombier if(ptime < td)
156219b2ee8SDavid du Colombier qchain = appendq(qchain, p2->namep);
157219b2ee8SDavid du Colombier if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td);
158219b2ee8SDavid du Colombier if(td > tdep) tdep = td;
159219b2ee8SDavid du Colombier set3var("*", prefix);
160219b2ee8SDavid du Colombier set3var("<", copys(sourcename));
161219b2ee8SDavid du Colombier for(lp2=p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
162219b2ee8SDavid du Colombier if(implcom = lp2->shp) break;
163219b2ee8SDavid du Colombier goto endloop;
164219b2ee8SDavid du Colombier }
165219b2ee8SDavid du Colombier }
166219b2ee8SDavid du Colombier }
167219b2ee8SDavid du Colombier }
168219b2ee8SDavid du Colombier
169219b2ee8SDavid du Colombier /* Look for implicit dependents, using pattern matching rules */
170219b2ee8SDavid du Colombier
171219b2ee8SDavid du Colombier len = strlen(p->namep);
172219b2ee8SDavid du Colombier for(wp = firstwild ; wp ; wp = wp->next)
173219b2ee8SDavid du Colombier if(stem = wildmatch(wp, p->namep, len) )
174219b2ee8SDavid du Colombier {
175219b2ee8SDavid du Colombier lp = wp->linep;
176219b2ee8SDavid du Colombier for(q = lp->depp; q; q = q->nxtdepblock)
177219b2ee8SDavid du Colombier {
178219b2ee8SDavid du Colombier if(dbgflag>1 && q->depname)
179219b2ee8SDavid du Colombier fprintf(stderr,"check dep of %s on %s\n", p->namep,
180219b2ee8SDavid du Colombier wildsub(q->depname->namep,stem));
181219b2ee8SDavid du Colombier if(q->depname &&
182219b2ee8SDavid du Colombier ! chkname(wildsub(q->depname->namep,stem)))
183219b2ee8SDavid du Colombier break;
184219b2ee8SDavid du Colombier }
185219b2ee8SDavid du Colombier
186219b2ee8SDavid du Colombier if(q) /* some name not found, go to next line */
187219b2ee8SDavid du Colombier continue;
188219b2ee8SDavid du Colombier
189219b2ee8SDavid du Colombier for(q = lp->depp; q; q = q->nxtdepblock)
190219b2ee8SDavid du Colombier {
191219b2ee8SDavid du Colombier nameblkp tamep;
192219b2ee8SDavid du Colombier if(q->depname == NULL)
193219b2ee8SDavid du Colombier continue;
194219b2ee8SDavid du Colombier tamep = srchname( wildsub(q->depname->namep,stem));
195219b2ee8SDavid du Colombier /*TEMP fprintf(stderr,"check dep %s on %s =>%s\n",p->namep,q->depname->namep,tamep->namep);*/
196219b2ee8SDavid du Colombier /*TEMP*/if(dbgflag) printf("%s depends on %s. stem=%s\n", p->namep,tamep->namep, stem);
197219b2ee8SDavid du Colombier errstat += doname(tamep, reclevel+1, &td, q->nowait);
198219b2ee8SDavid du Colombier if(ptime < td)
199219b2ee8SDavid du Colombier qchain = appendq(qchain, tamep->namep);
200219b2ee8SDavid du Colombier allchain = appendq(allchain, tamep->namep);
201219b2ee8SDavid du Colombier if(dbgflag) printf("TIME(%s)=%ld\n", tamep->namep, td);
202219b2ee8SDavid du Colombier if(td > tdep)
203219b2ee8SDavid du Colombier tdep = td;
204219b2ee8SDavid du Colombier set3var("<", copys(tamep->namep) );
205219b2ee8SDavid du Colombier }
206219b2ee8SDavid du Colombier set3var("*", stem);
207219b2ee8SDavid du Colombier setvar("%", stem, YES);
208219b2ee8SDavid du Colombier implcom = lp->shp;
209219b2ee8SDavid du Colombier goto endloop;
210219b2ee8SDavid du Colombier }
211219b2ee8SDavid du Colombier
212219b2ee8SDavid du Colombier endloop:
213219b2ee8SDavid du Colombier
214219b2ee8SDavid du Colombier
215219b2ee8SDavid du Colombier if(errstat==0 && (ptime<tdep || (ptime==0 && tdep==0) ) )
216219b2ee8SDavid du Colombier {
217219b2ee8SDavid du Colombier ptime = (tdep>0 ? tdep : prestime() );
218219b2ee8SDavid du Colombier set3var("@", p->namep);
219219b2ee8SDavid du Colombier setvar("?", mkqlist(qchain,qbuf), YES);
220219b2ee8SDavid du Colombier setvar("^", mkqlist(allchain,tgsbuf), YES);
221219b2ee8SDavid du Colombier if(explcom)
222219b2ee8SDavid du Colombier errstat += docom(explcom, nowait, nproc1);
223219b2ee8SDavid du Colombier else if(implcom)
224219b2ee8SDavid du Colombier errstat += docom(implcom, nowait, nproc1);
225219b2ee8SDavid du Colombier else if(p->septype == 0)
226219b2ee8SDavid du Colombier if(p1=srchname(".DEFAULT"))
227219b2ee8SDavid du Colombier {
228219b2ee8SDavid du Colombier set3var("<", p->namep);
229219b2ee8SDavid du Colombier for(lp2 = p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
230219b2ee8SDavid du Colombier if(implcom = lp2->shp)
231219b2ee8SDavid du Colombier {
232219b2ee8SDavid du Colombier errstat += docom(implcom, nowait,nproc1);
233219b2ee8SDavid du Colombier break;
234219b2ee8SDavid du Colombier }
235219b2ee8SDavid du Colombier }
236219b2ee8SDavid du Colombier else if(keepgoing)
237219b2ee8SDavid du Colombier {
238219b2ee8SDavid du Colombier printf("Don't know how to make %s\n", p->namep);
239219b2ee8SDavid du Colombier ++errstat;
240219b2ee8SDavid du Colombier }
241219b2ee8SDavid du Colombier else
242219b2ee8SDavid du Colombier fatal1(" Don't know how to make %s", p->namep);
243219b2ee8SDavid du Colombier
244219b2ee8SDavid du Colombier set3var("@", CHNULL);
245219b2ee8SDavid du Colombier if(noexflag || nowait || (ptime = exists(p->namep)) == 0 )
246219b2ee8SDavid du Colombier ptime = prestime();
247219b2ee8SDavid du Colombier }
248219b2ee8SDavid du Colombier
249219b2ee8SDavid du Colombier else if(errstat!=0 && reclevel==0)
250219b2ee8SDavid du Colombier printf("`%s' not remade because of errors\n", p->namep);
251219b2ee8SDavid du Colombier
252219b2ee8SDavid du Colombier else if(!questflag && reclevel==0 && didwork==NO)
253219b2ee8SDavid du Colombier printf("`%s' is up to date.\n", p->namep);
254219b2ee8SDavid du Colombier
255219b2ee8SDavid du Colombier if(questflag && reclevel==0)
256219b2ee8SDavid du Colombier exit(ndocoms>0 ? -1 : 0);
257219b2ee8SDavid du Colombier
258219b2ee8SDavid du Colombier p->done = (errstat ? 3 : 2);
259219b2ee8SDavid du Colombier if(ptime1 > ptime)
260219b2ee8SDavid du Colombier ptime = ptime1;
261219b2ee8SDavid du Colombier p->modtime = ptime;
262219b2ee8SDavid du Colombier *tval = ptime;
263219b2ee8SDavid du Colombier return errstat;
264219b2ee8SDavid du Colombier }
265219b2ee8SDavid du Colombier
docom(struct shblock * q,int nowait,int nproc1)266219b2ee8SDavid du Colombier docom(struct shblock *q, int nowait, int nproc1)
267219b2ee8SDavid du Colombier {
268219b2ee8SDavid du Colombier char *s;
269219b2ee8SDavid du Colombier int ign, nopr, doit;
270219b2ee8SDavid du Colombier char string[OUTMAX];
271219b2ee8SDavid du Colombier
272219b2ee8SDavid du Colombier ++ndocoms;
273219b2ee8SDavid du Colombier if(questflag)
274219b2ee8SDavid du Colombier return NO;
275219b2ee8SDavid du Colombier
276219b2ee8SDavid du Colombier if(touchflag)
277219b2ee8SDavid du Colombier {
278219b2ee8SDavid du Colombier s = varptr("@")->varval;
279219b2ee8SDavid du Colombier if(!silflag)
280219b2ee8SDavid du Colombier printf("touch(%s)\n", s);
281219b2ee8SDavid du Colombier if(!noexflag)
282219b2ee8SDavid du Colombier touch(YES, s);
283219b2ee8SDavid du Colombier return NO;
284219b2ee8SDavid du Colombier }
285219b2ee8SDavid du Colombier
286219b2ee8SDavid du Colombier if(nproc1 < nproc)
287219b2ee8SDavid du Colombier waitstack(nproc1);
288219b2ee8SDavid du Colombier
289219b2ee8SDavid du Colombier for( ; q ; q = q->nxtshblock )
290219b2ee8SDavid du Colombier {
291*9b7bf7dfSDavid du Colombier subst(q->shbp, string, &string[sizeof string - 1]);
292219b2ee8SDavid du Colombier ign = ignerr;
293219b2ee8SDavid du Colombier nopr = NO;
294219b2ee8SDavid du Colombier doit = NO;
295219b2ee8SDavid du Colombier for(s = string ; ; ++s)
296219b2ee8SDavid du Colombier {
297219b2ee8SDavid du Colombier switch(*s)
298219b2ee8SDavid du Colombier {
299219b2ee8SDavid du Colombier case '-':
300219b2ee8SDavid du Colombier ign = YES;
301219b2ee8SDavid du Colombier continue;
302219b2ee8SDavid du Colombier case '@':
303219b2ee8SDavid du Colombier nopr = YES;
304219b2ee8SDavid du Colombier continue;
305219b2ee8SDavid du Colombier case '+':
306219b2ee8SDavid du Colombier doit = YES;
307219b2ee8SDavid du Colombier continue;
308219b2ee8SDavid du Colombier default:
309219b2ee8SDavid du Colombier break;
310219b2ee8SDavid du Colombier }
311219b2ee8SDavid du Colombier break;
312219b2ee8SDavid du Colombier }
313219b2ee8SDavid du Colombier
314219b2ee8SDavid du Colombier if( docom1(s, ign, nopr, doit||!noexflag, nowait&&!q->nxtshblock) && !ign)
315219b2ee8SDavid du Colombier return YES;
316219b2ee8SDavid du Colombier }
317219b2ee8SDavid du Colombier return NO;
318219b2ee8SDavid du Colombier }
319219b2ee8SDavid du Colombier
320219b2ee8SDavid du Colombier
321219b2ee8SDavid du Colombier static int
docom1(char * comstring,int nohalt,int noprint,int doit,int nowait)322219b2ee8SDavid du Colombier docom1(char *comstring, int nohalt, int noprint, int doit, int nowait)
323219b2ee8SDavid du Colombier {
324219b2ee8SDavid du Colombier int status;
325219b2ee8SDavid du Colombier char *prefix;
326219b2ee8SDavid du Colombier
327219b2ee8SDavid du Colombier if(comstring[0] == '\0')
328219b2ee8SDavid du Colombier return 0;
329219b2ee8SDavid du Colombier
330219b2ee8SDavid du Colombier if(!silflag && (!noprint || !doit) )
331219b2ee8SDavid du Colombier prefix = doit ? prompt : "" ;
332219b2ee8SDavid du Colombier else
333219b2ee8SDavid du Colombier prefix = CHNULL;
334219b2ee8SDavid du Colombier
335219b2ee8SDavid du Colombier if(dynmacro(comstring) || !doit)
336219b2ee8SDavid du Colombier {
337219b2ee8SDavid du Colombier if(prefix)
338219b2ee8SDavid du Colombier {
339219b2ee8SDavid du Colombier fputs(prefix, stdout);
340219b2ee8SDavid du Colombier puts(comstring); /* with a newline */
341219b2ee8SDavid du Colombier fflush(stdout);
342219b2ee8SDavid du Colombier }
343219b2ee8SDavid du Colombier return 0;
344219b2ee8SDavid du Colombier }
345219b2ee8SDavid du Colombier
346219b2ee8SDavid du Colombier status = dosys(comstring, nohalt, nowait, prefix);
347219b2ee8SDavid du Colombier baddirs(); /* directories may have changed */
348219b2ee8SDavid du Colombier return status;
349219b2ee8SDavid du Colombier }
350219b2ee8SDavid du Colombier
351219b2ee8SDavid du Colombier
352219b2ee8SDavid du Colombier /*
353219b2ee8SDavid du Colombier If there are any Shell meta characters in the name,
354219b2ee8SDavid du Colombier expand into a list, after searching directory
355219b2ee8SDavid du Colombier */
356219b2ee8SDavid du Colombier
357219b2ee8SDavid du Colombier static void
expand(depblkp q)358219b2ee8SDavid du Colombier expand(depblkp q)
359219b2ee8SDavid du Colombier {
360219b2ee8SDavid du Colombier char *s;
361219b2ee8SDavid du Colombier char *s1;
362219b2ee8SDavid du Colombier depblkp p;
363219b2ee8SDavid du Colombier
364219b2ee8SDavid du Colombier s1 = q->depname->namep;
365219b2ee8SDavid du Colombier for(s=s1 ; ;) switch(*s++)
366219b2ee8SDavid du Colombier {
367219b2ee8SDavid du Colombier case '\0':
368219b2ee8SDavid du Colombier return;
369219b2ee8SDavid du Colombier
370219b2ee8SDavid du Colombier case '*':
371219b2ee8SDavid du Colombier case '?':
372219b2ee8SDavid du Colombier case '[':
373219b2ee8SDavid du Colombier if( p = srchdir(s1 , YES, q->nxtdepblock) )
374219b2ee8SDavid du Colombier {
375219b2ee8SDavid du Colombier q->nxtdepblock = p;
376219b2ee8SDavid du Colombier q->depname = 0;
377219b2ee8SDavid du Colombier }
378219b2ee8SDavid du Colombier return;
379219b2ee8SDavid du Colombier }
380219b2ee8SDavid du Colombier }
381