1*9c467b22Storek static char *sccsid = "@(#)doname.c 4.10 (Berkeley) 93/03/01";
2ae4128e1Swnj #include "defs"
3bd2409baSmckusick #include <strings.h>
44a24cb50Sserge #include <signal.h>
5ae4128e1Swnj
6ae4128e1Swnj /* BASIC PROCEDURE. RECURSIVE. */
7ae4128e1Swnj
8ae4128e1Swnj /*
9ae4128e1Swnj p->done = 0 don't know what to do yet
10ae4128e1Swnj p->done = 1 file in process of being updated
11ae4128e1Swnj p->done = 2 file already exists in current state
12ae4128e1Swnj p->done = 3 file make failed
13ae4128e1Swnj */
14ae4128e1Swnj
doname(p,reclevel,tval)15ae4128e1Swnj doname(p, reclevel, tval)
16ae4128e1Swnj register struct nameblock *p;
17ae4128e1Swnj int reclevel;
18ae4128e1Swnj TIMETYPE *tval;
19ae4128e1Swnj {
20ae4128e1Swnj int errstat;
21ae4128e1Swnj int okdel1;
22ae4128e1Swnj int didwork;
23ae4128e1Swnj TIMETYPE td, td1, tdep, ptime, ptime1, prestime();
24ae4128e1Swnj register struct depblock *q;
25ae4128e1Swnj struct depblock *qtemp, *srchdir(), *suffp, *suffp1;
26ae4128e1Swnj struct nameblock *p1, *p2;
27ae4128e1Swnj struct shblock *implcom, *explcom;
28ae4128e1Swnj register struct lineblock *lp;
29ae4128e1Swnj struct lineblock *lp1, *lp2;
30175799d7Sbloom char sourcename[BUFSIZ], prefix[BUFSIZ], temp[BUFSIZ], concsuff[20];
31bd2409baSmckusick char *pnamep, *p1namep, *cp;
32ae4128e1Swnj char *mkqlist();
33ae4128e1Swnj struct chain *qchain, *appendq();
34ae4128e1Swnj
357fae28c9Sbostic {
367fae28c9Sbostic /*
377fae28c9Sbostic * VPATH= ${PATH1}:${PATH2} didn't work. This fix is so ugly I don't
387fae28c9Sbostic * even want to think about it. Basically it grabs VPATH and
397fae28c9Sbostic * explicitly does macro expansion before resolving names. Why
407fae28c9Sbostic * VPATH didn't get handled correctly I have no idea; the symptom
417fae28c9Sbostic * was that, while macro expansion got done, the .c files in the
427fae28c9Sbostic * non-local directories wouldn't be found.
437fae28c9Sbostic */
447fae28c9Sbostic struct varblock *vpath_cp, *varptr();
457fae28c9Sbostic static int vpath_first;
467fae28c9Sbostic char vpath_exp[INMAX];
477fae28c9Sbostic
487fae28c9Sbostic if (!vpath_first) {
497fae28c9Sbostic vpath_first = 1;
507fae28c9Sbostic vpath_cp = varptr("VPATH");
517fae28c9Sbostic if (vpath_cp->varval) {
527fae28c9Sbostic subst(vpath_cp->varval, vpath_exp);
537fae28c9Sbostic setvar("VPATH",vpath_exp);
547fae28c9Sbostic }
557fae28c9Sbostic }
567fae28c9Sbostic }
57ae4128e1Swnj if(p == 0)
58ae4128e1Swnj {
59ae4128e1Swnj *tval = 0;
60ae4128e1Swnj return(0);
61ae4128e1Swnj }
62ae4128e1Swnj
63ae4128e1Swnj if(dbgflag)
64ae4128e1Swnj {
65ae4128e1Swnj printf("doname(%s,%d)\n",p->namep,reclevel);
66ae4128e1Swnj fflush(stdout);
67ae4128e1Swnj }
68ae4128e1Swnj
69ae4128e1Swnj if(p->done > 0)
70ae4128e1Swnj {
71ae4128e1Swnj *tval = p->modtime;
72ae4128e1Swnj return(p->done == 3);
73ae4128e1Swnj }
74ae4128e1Swnj
75ae4128e1Swnj errstat = 0;
76ae4128e1Swnj tdep = 0;
77ae4128e1Swnj implcom = 0;
78ae4128e1Swnj explcom = 0;
7924a9e40aSmckusick ptime = exists(p);
80ae4128e1Swnj ptime1 = 0;
81ae4128e1Swnj didwork = NO;
82ae4128e1Swnj p->done = 1; /* avoid infinite loops */
83ae4128e1Swnj
84ae4128e1Swnj qchain = NULL;
85ae4128e1Swnj
86ae4128e1Swnj /* Expand any names that have embedded metacharaters */
87ae4128e1Swnj
88ae4128e1Swnj for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
89ae4128e1Swnj for(q = lp->depp ; q ; q=qtemp )
90ae4128e1Swnj {
91ae4128e1Swnj qtemp = q->nxtdepblock;
92ae4128e1Swnj expand(q);
93ae4128e1Swnj }
94ae4128e1Swnj
95ae4128e1Swnj /* make sure all dependents are up to date */
96ae4128e1Swnj
97ae4128e1Swnj for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
98ae4128e1Swnj {
99ae4128e1Swnj td = 0;
100ae4128e1Swnj for(q = lp->depp ; q ; q = q->nxtdepblock)
101ae4128e1Swnj {
102ae4128e1Swnj errstat += doname(q->depname, reclevel+1, &td1);
103ae4128e1Swnj if(dbgflag)
104ae4128e1Swnj printf("TIME(%s)=%ld\n", q->depname->namep, td1);
105ae4128e1Swnj if(td1 > td) td = td1;
106ae4128e1Swnj if(ptime < td1)
107ae4128e1Swnj qchain = appendq(qchain, q->depname->namep);
108ae4128e1Swnj }
109ae4128e1Swnj if(p->septype == SOMEDEPS)
110ae4128e1Swnj {
111ae4128e1Swnj if(lp->shp!=0)
112ae4128e1Swnj if( ptime<td || (ptime==0 && td==0) || lp->depp==0)
113ae4128e1Swnj {
114ae4128e1Swnj okdel1 = okdel;
115ae4128e1Swnj okdel = NO;
116ae4128e1Swnj setvar("@", p->namep);
117ae4128e1Swnj setvar("?", mkqlist(qchain) );
118ae4128e1Swnj qchain = NULL;
119ae4128e1Swnj if( !questflag )
120ae4128e1Swnj errstat += docom(lp->shp);
121ae4128e1Swnj setvar("@", (char *) NULL);
122ae4128e1Swnj okdel = okdel1;
123ae4128e1Swnj ptime1 = prestime();
124ae4128e1Swnj didwork = YES;
125ae4128e1Swnj }
126ae4128e1Swnj }
127ae4128e1Swnj
128ae4128e1Swnj else {
129ae4128e1Swnj if(lp->shp != 0)
130ae4128e1Swnj {
131ae4128e1Swnj if(explcom)
132ae4128e1Swnj fprintf(stderr, "Too many command lines for `%s'\n",
133ae4128e1Swnj p->namep);
134ae4128e1Swnj else explcom = lp->shp;
135ae4128e1Swnj }
136ae4128e1Swnj
137ae4128e1Swnj if(td > tdep) tdep = td;
138ae4128e1Swnj }
139ae4128e1Swnj }
140ae4128e1Swnj
141ae4128e1Swnj /* Look for implicit dependents, using suffix rules */
142ae4128e1Swnj
143ae4128e1Swnj for(lp = sufflist ; lp ; lp = lp->nxtlineblock)
144ae4128e1Swnj for(suffp = lp->depp ; suffp ; suffp = suffp->nxtdepblock)
145ae4128e1Swnj {
146ae4128e1Swnj pnamep = suffp->depname->namep;
147ae4128e1Swnj if(suffix(p->namep , pnamep , prefix))
148ae4128e1Swnj {
14924a9e40aSmckusick
150ae4128e1Swnj srchdir( concat(prefix,"*",temp) , NO, (struct depblock *) NULL);
151ae4128e1Swnj for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock)
152ae4128e1Swnj for(suffp1=lp1->depp ; suffp1 ; suffp1 = suffp1->nxtdepblock)
153ae4128e1Swnj {
154ae4128e1Swnj p1namep = suffp1->depname->namep;
155ae4128e1Swnj if( (p1=srchname(concat(p1namep, pnamep ,concsuff))) &&
156ae4128e1Swnj (p2=srchname(concat(prefix, p1namep ,sourcename))) )
157ae4128e1Swnj {
158ae4128e1Swnj errstat += doname(p2, reclevel+1, &td);
159ae4128e1Swnj if(ptime < td)
160ae4128e1Swnj qchain = appendq(qchain, p2->namep);
161ae4128e1Swnj if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td);
162ae4128e1Swnj if(td > tdep) tdep = td;
163ae4128e1Swnj setvar("*", prefix);
16424a9e40aSmckusick if (p2->alias) setvar("<", copys(p2->alias));
16524a9e40aSmckusick else setvar("<", copys(p2->namep));
166ae4128e1Swnj for(lp2=p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
167ae4128e1Swnj if(implcom = lp2->shp) break;
168ae4128e1Swnj goto endloop;
169ae4128e1Swnj }
170ae4128e1Swnj }
171bd2409baSmckusick cp = rindex(prefix, '/');
172bd2409baSmckusick if (cp++ == 0)
173bd2409baSmckusick cp = prefix;
174bd2409baSmckusick setvar("*", cp);
175ae4128e1Swnj }
176ae4128e1Swnj }
177ae4128e1Swnj
178ae4128e1Swnj endloop:
179ae4128e1Swnj
180ae4128e1Swnj
181ae4128e1Swnj if(errstat==0 && (ptime<tdep || (ptime==0 && tdep==0) ) )
182ae4128e1Swnj {
183ae4128e1Swnj ptime = (tdep>0 ? tdep : prestime() );
184ae4128e1Swnj setvar("@", p->namep);
185ae4128e1Swnj setvar("?", mkqlist(qchain) );
186ae4128e1Swnj if(explcom)
187ae4128e1Swnj errstat += docom(explcom);
188ae4128e1Swnj else if(implcom)
189ae4128e1Swnj errstat += docom(implcom);
190ae4128e1Swnj else if(p->septype == 0)
191ae4128e1Swnj if(p1=srchname(".DEFAULT"))
192ae4128e1Swnj {
19324a9e40aSmckusick if (p->alias) setvar("<", p->alias);
19424a9e40aSmckusick else setvar("<", p->namep);
195ae4128e1Swnj for(lp2 = p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
196ae4128e1Swnj if(implcom = lp2->shp)
197ae4128e1Swnj {
198ae4128e1Swnj errstat += docom(implcom);
199ae4128e1Swnj break;
200ae4128e1Swnj }
201ae4128e1Swnj }
202ae4128e1Swnj else if(keepgoing)
203ae4128e1Swnj {
204ae4128e1Swnj printf("Don't know how to make %s\n", p->namep);
205ae4128e1Swnj ++errstat;
206ae4128e1Swnj }
207ae4128e1Swnj else
208ae4128e1Swnj fatal1(" Don't know how to make %s", p->namep);
209ae4128e1Swnj
210ae4128e1Swnj setvar("@", (char *) NULL);
21124a9e40aSmckusick if(noexflag || (ptime = exists(p)) == 0)
212ae4128e1Swnj ptime = prestime();
213ae4128e1Swnj }
214ae4128e1Swnj
215ae4128e1Swnj else if(errstat!=0 && reclevel==0)
216ae4128e1Swnj printf("`%s' not remade because of errors\n", p->namep);
217ae4128e1Swnj
218ae4128e1Swnj else if(!questflag && reclevel==0 && didwork==NO)
219ae4128e1Swnj printf("`%s' is up to date.\n", p->namep);
220ae4128e1Swnj
221ae4128e1Swnj if(questflag && reclevel==0)
222ae4128e1Swnj exit(ndocoms>0 ? -1 : 0);
223ae4128e1Swnj
224ae4128e1Swnj p->done = (errstat ? 3 : 2);
225ae4128e1Swnj if(ptime1 > ptime) ptime = ptime1;
226ae4128e1Swnj p->modtime = ptime;
227ae4128e1Swnj *tval = ptime;
228ae4128e1Swnj return(errstat);
229ae4128e1Swnj }
230ae4128e1Swnj
231ae4128e1Swnj docom(q)
232ae4128e1Swnj struct shblock *q;
233ae4128e1Swnj {
234ae4128e1Swnj char *s;
235ae4128e1Swnj struct varblock *varptr();
236ae4128e1Swnj int ign, nopr;
237ae4128e1Swnj char string[OUTMAX];
23824a9e40aSmckusick char string2[OUTMAX];
239ae4128e1Swnj
240ae4128e1Swnj ++ndocoms;
241ae4128e1Swnj if(questflag)
242ae4128e1Swnj return(NO);
243ae4128e1Swnj
244ae4128e1Swnj if(touchflag)
245ae4128e1Swnj {
246ae4128e1Swnj s = varptr("@")->varval;
247ae4128e1Swnj if(!silflag)
248ae4128e1Swnj printf("touch(%s)\n", s);
249ae4128e1Swnj if(!noexflag)
250ae4128e1Swnj touch(YES, s);
251ae4128e1Swnj }
252ae4128e1Swnj
253ae4128e1Swnj else for( ; q ; q = q->nxtshblock )
254ae4128e1Swnj {
25524a9e40aSmckusick subst(q->shbp,string2);
25624a9e40aSmckusick fixname(string2, string);
257ae4128e1Swnj
258ae4128e1Swnj ign = ignerr;
259ae4128e1Swnj nopr = NO;
260ae4128e1Swnj for(s = string ; *s=='-' || *s=='@' ; ++s)
261ae4128e1Swnj if(*s == '-') ign = YES;
262ae4128e1Swnj else nopr = YES;
263ae4128e1Swnj
264ae4128e1Swnj if( docom1(s, ign, nopr) && !ign)
265ae4128e1Swnj if(keepgoing)
266ae4128e1Swnj return(YES);
267ae4128e1Swnj else fatal( (char *) NULL);
268ae4128e1Swnj }
269ae4128e1Swnj return(NO);
270ae4128e1Swnj }
271ae4128e1Swnj
272ae4128e1Swnj
273ae4128e1Swnj
docom1(comstring,nohalt,noprint)274ae4128e1Swnj docom1(comstring, nohalt, noprint)
275ae4128e1Swnj register char *comstring;
276ae4128e1Swnj int nohalt, noprint;
277ae4128e1Swnj {
278ae4128e1Swnj register int status;
279ae4128e1Swnj
280ae4128e1Swnj if(comstring[0] == '\0') return(0);
281ae4128e1Swnj
282ae4128e1Swnj if(!silflag && (!noprint || noexflag) )
283ae4128e1Swnj {
284ae4128e1Swnj printf("%s%s\n", (noexflag ? "" : prompt), comstring);
285ae4128e1Swnj fflush(stdout);
286ae4128e1Swnj }
287ae4128e1Swnj
288ae4128e1Swnj if(noexflag) return(0);
289ae4128e1Swnj
290ae4128e1Swnj if( status = dosys(comstring, nohalt) )
291ae4128e1Swnj {
2924a24cb50Sserge unsigned sig = status & 0177;
2934a24cb50Sserge if( sig ) {
2944a24cb50Sserge if (sig < NSIG && sys_siglist[sig] != NULL &&
2954a24cb50Sserge *sys_siglist[sig] != '\0')
2964a24cb50Sserge printf("*** %s", sys_siglist[sig]);
2974a24cb50Sserge else
2984a24cb50Sserge printf("*** Signal %d", sig);
2994a24cb50Sserge if (status & 0200)
3004a24cb50Sserge printf(" - core dumped");
3014a24cb50Sserge } else
3024a24cb50Sserge printf("*** Exit %d", status>>8 );
303ae4128e1Swnj
304ae4128e1Swnj if(nohalt) printf(" (ignored)\n");
305ae4128e1Swnj else printf("\n");
306ae4128e1Swnj fflush(stdout);
307ae4128e1Swnj }
308ae4128e1Swnj
309ae4128e1Swnj return(status);
310ae4128e1Swnj }
311ae4128e1Swnj
312ae4128e1Swnj
313ae4128e1Swnj /*
314ae4128e1Swnj If there are any Shell meta characters in the name,
315ae4128e1Swnj expand into a list, after searching directory
316ae4128e1Swnj */
317ae4128e1Swnj
expand(q)318ae4128e1Swnj expand(q)
319ae4128e1Swnj register struct depblock *q;
320ae4128e1Swnj {
321ae4128e1Swnj register char *s;
322ae4128e1Swnj char *s1;
323ae4128e1Swnj struct depblock *p, *srchdir();
324ae4128e1Swnj
325a2760324Ssam if (q->depname == NULL)
326a2760324Ssam return;
327ae4128e1Swnj s1 = q->depname->namep;
328ae4128e1Swnj for(s=s1 ; ;) switch(*s++)
329ae4128e1Swnj {
330ae4128e1Swnj case '\0':
331ae4128e1Swnj return;
332ae4128e1Swnj
333ae4128e1Swnj case '*':
334ae4128e1Swnj case '?':
335ae4128e1Swnj case '[':
336ae4128e1Swnj if( p = srchdir(s1 , YES, q->nxtdepblock) )
337ae4128e1Swnj {
338ae4128e1Swnj q->nxtdepblock = p;
339ae4128e1Swnj q->depname = 0;
340ae4128e1Swnj }
341ae4128e1Swnj return;
342ae4128e1Swnj }
343ae4128e1Swnj }
344