add EGP
[unix-history] / usr / src / old / make / doname.c
CommitLineData
393c84d8 1static char *sccsid = "@(#)doname.c 4.3 (Berkeley) 83/03/11";
6f8df2c3
BJ
2#include "defs"
3
4/* BASIC PROCEDURE. RECURSIVE. */
5
6/*
7p->done = 0 don't know what to do yet
8p->done = 1 file in process of being updated
9p->done = 2 file already exists in current state
10p->done = 3 file make failed
11*/
12
13doname(p, reclevel, tval)
14register struct nameblock *p;
15int reclevel;
16TIMETYPE *tval;
17{
18int errstat;
19int okdel1;
20int didwork;
21TIMETYPE td, td1, tdep, ptime, ptime1, prestime();
22register struct depblock *q;
23struct depblock *qtemp, *srchdir(), *suffp, *suffp1;
24struct nameblock *p1, *p2;
25struct shblock *implcom, *explcom;
26register struct lineblock *lp;
27struct lineblock *lp1, *lp2;
28char sourcename[100], prefix[100], temp[100], concsuff[20];
29char *pnamep, *p1namep;
30char *mkqlist();
31struct chain *qchain, *appendq();
32
33if(p == 0)
34 {
35 *tval = 0;
36 return(0);
37 }
38
39if(dbgflag)
40 {
41 printf("doname(%s,%d)\n",p->namep,reclevel);
42 fflush(stdout);
43 }
44
45if(p->done > 0)
46 {
47 *tval = p->modtime;
48 return(p->done == 3);
49 }
50
51errstat = 0;
52tdep = 0;
53implcom = 0;
54explcom = 0;
55ptime = exists(p->namep);
56ptime1 = 0;
57didwork = NO;
58p->done = 1; /* avoid infinite loops */
59
60qchain = NULL;
61
62/* Expand any names that have embedded metacharaters */
63
64for(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
73for(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
119for(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);
136if(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 }
393c84d8 145 setvar("*", rindex(prefix, '/') + 1);
6f8df2c3
BJ
146 }
147 }
148
149endloop:
150
151
152if(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
185else if(errstat!=0 && reclevel==0)
186 printf("`%s' not remade because of errors\n", p->namep);
187
188else if(!questflag && reclevel==0 && didwork==NO)
189 printf("`%s' is up to date.\n", p->namep);
190
191if(questflag && reclevel==0)
192 exit(ndocoms>0 ? -1 : 0);
193
194p->done = (errstat ? 3 : 2);
195if(ptime1 > ptime) ptime = ptime1;
196p->modtime = ptime;
197*tval = ptime;
198return(errstat);
199}
200\f
201docom(q)
202struct shblock *q;
203{
204char *s;
205struct varblock *varptr();
206int ign, nopr;
207char string[OUTMAX];
208
209++ndocoms;
210if(questflag)
211 return(NO);
212
213if(touchflag)
214 {
215 s = varptr("@")->varval;
216 if(!silflag)
217 printf("touch(%s)\n", s);
218 if(!noexflag)
219 touch(YES, s);
220 }
221
222else 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 }
237return(NO);
238}
239
240
241
242docom1(comstring, nohalt, noprint)
243register char *comstring;
244int nohalt, noprint;
245{
246register int status;
247
248if(comstring[0] == '\0') return(0);
249
250if(!silflag && (!noprint || noexflag) )
251 {
252 printf("%s%s\n", (noexflag ? "" : prompt), comstring);
253 fflush(stdout);
254 }
255
256if(noexflag) return(0);
257
258if( 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
269return(status);
270}
271\f
272
273/*
274 If there are any Shell meta characters in the name,
275 expand into a list, after searching directory
276*/
277
278expand(q)
279register struct depblock *q;
280{
281register char *s;
282char *s1;
283struct depblock *p, *srchdir();
284
285s1 = q->depname->namep;
286for(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}