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}