main
doname.c
1#include "defs"
2
3void docom(struct shblock *);
4void expand(struct depblock *);
5
6/* BASIC PROCEDURE. RECURSIVE. */
7
8/*
9p->done = 0 don't know what to do yet
10p->done = 1 file in process of being updated
11p->done = 2 file already exists in current state
12*/
13
14TIMETYPE doname(p,reclevel)
15struct nameblock *p;
16int reclevel;
17{
18int okdel1;
19int didwork;
20TIMETYPE td, td1, tdep, ptime, ptime1, prestime(), exists();
21struct depblock *q, *qtemp, *srchdir(), *suffp, *suffp1;
22struct nameblock *p1, *p2, *srchname();
23struct shblock *implcom, *explcom;
24struct lineblock *lp, *lp1, *lp2;
25char *concat(),sourcename[100],prefix[100],temp[100],concsuff[20];
26char *pnamep, *p1namep;
27struct chain *qchain;
28
29if(p == 0) return(0);
30
31if(dbgflag)
32 {
33 printf("doname(%s,%d)\n",p->namep,reclevel);
34 fflush(stdout);
35 }
36
37if(p->done > 0) return(p->modtime);
38
39tdep = 0;
40implcom = 0;
41explcom = 0;
42ptime = exists(p->namep);
43ptime1 = 0;
44didwork = 0;
45p->done = 1; /* avoid infinite loops */
46
47qchain = 0;
48
49/* Expand any names that have embedded metacharaters */
50
51for(lp = p->linep ; lp!=0 ; lp = lp->nextp)
52 for(q=lp->depp ; q!=0 ; q=qtemp )
53 {
54 qtemp = q->nextp;
55 expand(q);
56 }
57
58/* make sure all dependents are up to date */
59
60for(lp = p->linep ; lp!=0 ; lp = lp->nextp)
61 {
62 td = 0;
63 for(q = lp->depp ; q!=0 ; q=q->nextp)
64 {
65 td1 = doname(q->depname,reclevel+1);
66 if(dbgflag)
67 printf("TIME(%s)=%ld\n", q->depname->namep, td1);
68 if(td1 > td) td = td1;
69 if(ptime < td1)
70 appendq(&qchain, q->depname->namep);
71 }
72 if(p->septype == SOMEDEPS)
73 {
74 if(lp->shp!=0)
75 if( ptime<td || (ptime==0 && td==0) )
76 {
77 okdel1 = okdel;
78 okdel = 0;
79 setvar("@", p->namep);
80 setvar("?", mkqlist(qchain) );
81 qchain = 0;
82 if( !questflag )
83 docom(lp->shp);
84 setvar("@", 0);
85 okdel = okdel1;
86 ptime1 = prestime();
87 ++didwork;
88 }
89 }
90
91 else {
92 if(lp->shp != 0)
93 if(explcom)
94 fprintf(stderr, "Too many command lines for `%s'\n",
95 p->namep);
96 else explcom = lp->shp;
97
98 if(td > tdep) tdep = td;
99 }
100 }
101
102/* Look for implicit dependents, using suffix rules */
103
104for(lp=sufflist ; lp!=0 ; lp = lp->nextp)
105 for(suffp = lp->depp ; suffp!=0 ; suffp = suffp->nextp)
106 {
107 pnamep = suffp->depname->namep;
108 if(suffix(p->namep , pnamep , prefix))
109 {
110 srchdir( concat(prefix,"*",temp) , 0,0);
111 for(lp1 = sufflist ; lp1!=0 ; lp1 = lp1->nextp)
112 for(suffp1=lp1->depp ; suffp1!=0 ; suffp1 = suffp1->nextp)
113 {
114 p1namep = suffp1->depname->namep;
115 if( (p1=srchname(concat(p1namep, pnamep ,concsuff))) &&
116 (p2=srchname(concat(prefix, p1namep ,sourcename))) )
117 {
118 td = doname(p2,reclevel+1);
119 if(ptime < td)
120 appendq(&qchain, p2->namep);
121if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td);
122 if(td > tdep) tdep = td;
123 setvar("*", prefix);
124 setvar("<", copys(sourcename));
125 for(lp2=p1->linep ; lp2!=0 ; lp2 = lp2->nextp)
126 if(implcom = lp2->shp) break;
127 goto endloop;
128 }
129 }
130 }
131 }
132
133endloop:
134
135
136if(ptime<tdep || (ptime==0 && tdep==0) )
137 {
138 ptime = (tdep>0 ? tdep : prestime() );
139 setvar("@", p->namep);
140 setvar("?", mkqlist(qchain) );
141 if(explcom) docom(explcom);
142 else if(implcom) docom(implcom);
143 else if(p->septype == 0)
144 if(p1=srchname(".DEFAULT"))
145 {
146 setvar("<", p->namep);
147 for(lp2=p1->linep ; lp2!=0 ; lp2 = lp2->nextp)
148 if(implcom = lp2->shp)
149 {
150 docom(implcom);
151 break;
152 }
153 }
154 else {
155 fprintf(stderr," Don't know how to make %s", p->namep);
156 fatal("");
157 }
158
159 setvar("@", 0);
160 if( (ptime = exists(p->namep)) == 0)
161 ptime = prestime();
162 }
163
164else if(!questflag && reclevel==0 && didwork==0)
165 printf("`%s' is up to date.\n", p->namep);
166
167if(questflag && reclevel==0)
168 exit(ndocoms>0 ? -1 : 0);
169
170p->done = 2;
171if(ptime1 > ptime) ptime = ptime1;
172p->modtime = ptime;
173return(ptime);
174}
175
176void docom(q)
177struct shblock *q;
178{
179char *s;
180struct varblock *varptr();
181int status;
182int ign, nopr;
183char string[400];
184
185++ndocoms;
186if(questflag)
187 return;
188
189if(touchflag)
190 {
191 s = varptr("@")->varval;
192 if(!silflag)
193 printf("touch(%s)\n", s);
194 if(!noexflag)
195 touch(s);
196 }
197
198else for( status = 0; q!=0 ; q = q->nextp )
199 {
200 subst(q->shbp,string);
201
202 ign = ignerr;
203 nopr = 0;
204 for(s = string ; *s=='-' || *s=='@' ; ++s)
205 if(*s == '-') ign = 1;
206 else nopr = 1;
207
208 status |= docom1(s, ign, nopr);
209
210 }
211}
212
213
214
215docom1(comstring, nohalt, noprint)
216char *comstring;
217int nohalt, noprint;
218{
219int status;
220
221if(comstring[0] == '\0') return(0);
222
223if(!silflag && (!noprint || noexflag) )
224 {
225 printf("%s%s\n", (noexflag ? "" : prompt), comstring);
226 fflush(stdout);
227 }
228
229if(noexflag) return(0);
230
231if( status = dosys(comstring, nohalt) )
232 if (!nohalt)
233 {
234 printf("*** Error code %d", status );
235 fatal(0);
236 }
237
238return(status);
239}
240
241
242/*
243 If there are any Shell meta characters in the name,
244 expand into a list, after searching directory
245*/
246
247void expand(q)
248struct depblock *q;
249{
250register char *s;
251char *s1;
252struct depblock *p, *srchdir();
253
254s1 = q->depname->namep;
255for(s=s1 ; ;) switch(*s++)
256 {
257 case '\0':
258 return;
259
260 case '*':
261 case '?':
262 case '[':
263 if(p = srchdir(s1 , 1 , q->nextp) )
264 {
265 q->nextp = p;
266 q->depname = 0;
267 }
268 return;
269 }
270}