xref: /csrg-svn/old/make/doname.c (revision 58336)
1*58336Storek static	char *sccsid = "@(#)doname.c	4.10 (Berkeley) 93/03/01";
22803Swnj #include "defs"
317682Smckusick #include <strings.h>
424911Sserge #include <signal.h>
52803Swnj 
62803Swnj /*  BASIC PROCEDURE.  RECURSIVE.  */
72803Swnj 
82803Swnj /*
92803Swnj p->done = 0   don't know what to do yet
102803Swnj p->done = 1   file in process of being updated
112803Swnj p->done = 2   file already exists in current state
122803Swnj p->done = 3   file make failed
132803Swnj */
142803Swnj 
doname(p,reclevel,tval)152803Swnj doname(p, reclevel, tval)
162803Swnj register struct nameblock *p;
172803Swnj int reclevel;
182803Swnj TIMETYPE *tval;
192803Swnj {
202803Swnj int errstat;
212803Swnj int okdel1;
222803Swnj int didwork;
232803Swnj TIMETYPE td, td1, tdep, ptime, ptime1, prestime();
242803Swnj register struct depblock *q;
252803Swnj struct depblock *qtemp, *srchdir(), *suffp, *suffp1;
262803Swnj struct nameblock *p1, *p2;
272803Swnj struct shblock *implcom, *explcom;
282803Swnj register struct lineblock *lp;
292803Swnj struct lineblock *lp1, *lp2;
3024492Sbloom char sourcename[BUFSIZ], prefix[BUFSIZ], temp[BUFSIZ], concsuff[20];
3117682Smckusick char *pnamep, *p1namep, *cp;
322803Swnj char *mkqlist();
332803Swnj struct chain *qchain, *appendq();
342803Swnj 
3531567Sbostic {
3631567Sbostic 	/*
3731567Sbostic 	 * VPATH= ${PATH1}:${PATH2} didn't work.  This fix is so ugly I don't
3831567Sbostic 	 * even want to think about it.  Basically it grabs VPATH and
3931567Sbostic 	 * explicitly does macro expansion before resolving names.  Why
4031567Sbostic 	 * VPATH didn't get handled correctly I have no idea; the symptom
4131567Sbostic 	 * was that, while macro expansion got done, the .c files in the
4231567Sbostic 	 * non-local directories wouldn't be found.
4331567Sbostic 	 */
4431567Sbostic 	struct varblock	*vpath_cp, *varptr();
4531567Sbostic 	static int	vpath_first;
4631567Sbostic 	char	vpath_exp[INMAX];
4731567Sbostic 
4831567Sbostic 	if (!vpath_first) {
4931567Sbostic 		vpath_first = 1;
5031567Sbostic 		vpath_cp = varptr("VPATH");
5131567Sbostic 		if (vpath_cp->varval) {
5231567Sbostic 			subst(vpath_cp->varval, vpath_exp);
5331567Sbostic 			setvar("VPATH",vpath_exp);
5431567Sbostic 		}
5531567Sbostic 	}
5631567Sbostic }
572803Swnj if(p == 0)
582803Swnj 	{
592803Swnj 	*tval = 0;
602803Swnj 	return(0);
612803Swnj 	}
622803Swnj 
632803Swnj if(dbgflag)
642803Swnj 	{
652803Swnj 	printf("doname(%s,%d)\n",p->namep,reclevel);
662803Swnj 	fflush(stdout);
672803Swnj 	}
682803Swnj 
692803Swnj if(p->done > 0)
702803Swnj 	{
712803Swnj 	*tval = p->modtime;
722803Swnj 	return(p->done == 3);
732803Swnj 	}
742803Swnj 
752803Swnj errstat = 0;
762803Swnj tdep = 0;
772803Swnj implcom = 0;
782803Swnj explcom = 0;
7918644Smckusick ptime = exists(p);
802803Swnj ptime1 = 0;
812803Swnj didwork = NO;
822803Swnj p->done = 1;	/* avoid infinite loops */
832803Swnj 
842803Swnj qchain = NULL;
852803Swnj 
862803Swnj /* Expand any names that have embedded metacharaters */
872803Swnj 
882803Swnj for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
892803Swnj 	for(q = lp->depp ; q ; q=qtemp )
902803Swnj 		{
912803Swnj 		qtemp = q->nxtdepblock;
922803Swnj 		expand(q);
932803Swnj 		}
942803Swnj 
952803Swnj /* make sure all dependents are up to date */
962803Swnj 
972803Swnj for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
982803Swnj 	{
992803Swnj 	td = 0;
1002803Swnj 	for(q = lp->depp ; q ; q = q->nxtdepblock)
1012803Swnj 		{
1022803Swnj 		errstat += doname(q->depname, reclevel+1, &td1);
1032803Swnj 		if(dbgflag)
1042803Swnj 		    printf("TIME(%s)=%ld\n", q->depname->namep, td1);
1052803Swnj 		if(td1 > td) td = td1;
1062803Swnj 		if(ptime < td1)
1072803Swnj 			qchain = appendq(qchain, q->depname->namep);
1082803Swnj 		}
1092803Swnj 	if(p->septype == SOMEDEPS)
1102803Swnj 		{
1112803Swnj 		if(lp->shp!=0)
1122803Swnj 		     if( ptime<td || (ptime==0 && td==0) || lp->depp==0)
1132803Swnj 			{
1142803Swnj 			okdel1 = okdel;
1152803Swnj 			okdel = NO;
1162803Swnj 			setvar("@", p->namep);
1172803Swnj 			setvar("?", mkqlist(qchain) );
1182803Swnj 			qchain = NULL;
1192803Swnj 			if( !questflag )
1202803Swnj 				errstat += docom(lp->shp);
1212803Swnj 			setvar("@", (char *) NULL);
1222803Swnj 			okdel = okdel1;
1232803Swnj 			ptime1 = prestime();
1242803Swnj 			didwork = YES;
1252803Swnj 			}
1262803Swnj 		}
1272803Swnj 
1282803Swnj 	else	{
1292803Swnj 		if(lp->shp != 0)
1302803Swnj 			{
1312803Swnj 			if(explcom)
1322803Swnj 				fprintf(stderr, "Too many command lines for `%s'\n",
1332803Swnj 					p->namep);
1342803Swnj 			else	explcom = lp->shp;
1352803Swnj 			}
1362803Swnj 
1372803Swnj 		if(td > tdep) tdep = td;
1382803Swnj 		}
1392803Swnj 	}
1402803Swnj 
1412803Swnj /* Look for implicit dependents, using suffix rules */
1422803Swnj 
1432803Swnj for(lp = sufflist ; lp ; lp = lp->nxtlineblock)
1442803Swnj     for(suffp = lp->depp ; suffp ; suffp = suffp->nxtdepblock)
1452803Swnj 	{
1462803Swnj 	pnamep = suffp->depname->namep;
1472803Swnj 	if(suffix(p->namep , pnamep , prefix))
1482803Swnj 		{
14918644Smckusick 
1502803Swnj 		srchdir( concat(prefix,"*",temp) , NO, (struct depblock *) NULL);
1512803Swnj 		for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock)
1522803Swnj 		    for(suffp1=lp1->depp ; suffp1 ; suffp1 = suffp1->nxtdepblock)
1532803Swnj 			{
1542803Swnj 			p1namep = suffp1->depname->namep;
1552803Swnj 			if( (p1=srchname(concat(p1namep, pnamep ,concsuff))) &&
1562803Swnj 			    (p2=srchname(concat(prefix, p1namep ,sourcename))) )
1572803Swnj 				{
1582803Swnj 				errstat += doname(p2, reclevel+1, &td);
1592803Swnj 				if(ptime < td)
1602803Swnj 					qchain = appendq(qchain, p2->namep);
1612803Swnj if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td);
1622803Swnj 				if(td > tdep) tdep = td;
1632803Swnj 				setvar("*", prefix);
16418644Smckusick 				if (p2->alias) setvar("<", copys(p2->alias));
16518644Smckusick 				else setvar("<", copys(p2->namep));
1662803Swnj 				for(lp2=p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
1672803Swnj 					if(implcom = lp2->shp) break;
1682803Swnj 				goto endloop;
1692803Swnj 				}
1702803Swnj 			}
17117682Smckusick 		cp = rindex(prefix, '/');
17217682Smckusick 		if (cp++ == 0)
17317682Smckusick 			cp = prefix;
17417682Smckusick 		setvar("*", cp);
1752803Swnj 		}
1762803Swnj 	}
1772803Swnj 
1782803Swnj endloop:
1792803Swnj 
1802803Swnj 
1812803Swnj if(errstat==0 && (ptime<tdep || (ptime==0 && tdep==0) ) )
1822803Swnj 	{
1832803Swnj 	ptime = (tdep>0 ? tdep : prestime() );
1842803Swnj 	setvar("@", p->namep);
1852803Swnj 	setvar("?", mkqlist(qchain) );
1862803Swnj 	if(explcom)
1872803Swnj 		errstat += docom(explcom);
1882803Swnj 	else if(implcom)
1892803Swnj 		errstat += docom(implcom);
1902803Swnj 	else if(p->septype == 0)
1912803Swnj 		if(p1=srchname(".DEFAULT"))
1922803Swnj 			{
19318644Smckusick 			if (p->alias) setvar("<", p->alias);
19418644Smckusick 			else setvar("<", p->namep);
1952803Swnj 			for(lp2 = p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
1962803Swnj 				if(implcom = lp2->shp)
1972803Swnj 					{
1982803Swnj 					errstat += docom(implcom);
1992803Swnj 					break;
2002803Swnj 					}
2012803Swnj 			}
2022803Swnj 		else if(keepgoing)
2032803Swnj 			{
2042803Swnj 			printf("Don't know how to make %s\n", p->namep);
2052803Swnj 			++errstat;
2062803Swnj 			}
2072803Swnj 		else
2082803Swnj 			fatal1(" Don't know how to make %s", p->namep);
2092803Swnj 
2102803Swnj 	setvar("@", (char *) NULL);
21118644Smckusick 	if(noexflag || (ptime = exists(p)) == 0)
2122803Swnj 		ptime = prestime();
2132803Swnj 	}
2142803Swnj 
2152803Swnj else if(errstat!=0 && reclevel==0)
2162803Swnj 	printf("`%s' not remade because of errors\n", p->namep);
2172803Swnj 
2182803Swnj else if(!questflag && reclevel==0  &&  didwork==NO)
2192803Swnj 	printf("`%s' is up to date.\n", p->namep);
2202803Swnj 
2212803Swnj if(questflag && reclevel==0)
2222803Swnj 	exit(ndocoms>0 ? -1 : 0);
2232803Swnj 
2242803Swnj p->done = (errstat ? 3 : 2);
2252803Swnj if(ptime1 > ptime) ptime = ptime1;
2262803Swnj p->modtime = ptime;
2272803Swnj *tval = ptime;
2282803Swnj return(errstat);
2292803Swnj }
2302803Swnj 
2312803Swnj docom(q)
2322803Swnj struct shblock *q;
2332803Swnj {
2342803Swnj char *s;
2352803Swnj struct varblock *varptr();
2362803Swnj int ign, nopr;
2372803Swnj char string[OUTMAX];
23818644Smckusick char string2[OUTMAX];
2392803Swnj 
2402803Swnj ++ndocoms;
2412803Swnj if(questflag)
2422803Swnj 	return(NO);
2432803Swnj 
2442803Swnj if(touchflag)
2452803Swnj 	{
2462803Swnj 	s = varptr("@")->varval;
2472803Swnj 	if(!silflag)
2482803Swnj 		printf("touch(%s)\n", s);
2492803Swnj 	if(!noexflag)
2502803Swnj 		touch(YES, s);
2512803Swnj 	}
2522803Swnj 
2532803Swnj else for( ; q ; q = q->nxtshblock )
2542803Swnj 	{
25518644Smckusick 	subst(q->shbp,string2);
25618644Smckusick 	fixname(string2, string);
2572803Swnj 
2582803Swnj 	ign = ignerr;
2592803Swnj 	nopr = NO;
2602803Swnj 	for(s = string ; *s=='-' || *s=='@' ; ++s)
2612803Swnj 		if(*s == '-')  ign = YES;
2622803Swnj 		else nopr = YES;
2632803Swnj 
2642803Swnj 	if( docom1(s, ign, nopr) && !ign)
2652803Swnj 		if(keepgoing)
2662803Swnj 			return(YES);
2672803Swnj 		else	fatal( (char *) NULL);
2682803Swnj 	}
2692803Swnj return(NO);
2702803Swnj }
2712803Swnj 
2722803Swnj 
2732803Swnj 
docom1(comstring,nohalt,noprint)2742803Swnj docom1(comstring, nohalt, noprint)
2752803Swnj register char *comstring;
2762803Swnj int nohalt, noprint;
2772803Swnj {
2782803Swnj register int status;
2792803Swnj 
2802803Swnj if(comstring[0] == '\0') return(0);
2812803Swnj 
2822803Swnj if(!silflag && (!noprint || noexflag) )
2832803Swnj 	{
2842803Swnj 	printf("%s%s\n", (noexflag ? "" : prompt), comstring);
2852803Swnj 	fflush(stdout);
2862803Swnj 	}
2872803Swnj 
2882803Swnj if(noexflag) return(0);
2892803Swnj 
2902803Swnj if( status = dosys(comstring, nohalt) )
2912803Swnj 	{
29224911Sserge 	unsigned sig = status & 0177;
29324911Sserge 	if( sig ) {
29424911Sserge 		if (sig < NSIG && sys_siglist[sig] != NULL &&
29524911Sserge 		    *sys_siglist[sig] != '\0')
29624911Sserge 			printf("*** %s", sys_siglist[sig]);
29724911Sserge 		else
29824911Sserge 			printf("*** Signal %d", sig);
29924911Sserge 		if (status & 0200)
30024911Sserge 			printf(" - core dumped");
30124911Sserge 	} else
30224911Sserge 		printf("*** Exit %d", status>>8 );
3032803Swnj 
3042803Swnj 	if(nohalt) printf(" (ignored)\n");
3052803Swnj 	else	printf("\n");
3062803Swnj 	fflush(stdout);
3072803Swnj 	}
3082803Swnj 
3092803Swnj return(status);
3102803Swnj }
3112803Swnj 
3122803Swnj 
3132803Swnj /*
3142803Swnj    If there are any Shell meta characters in the name,
3152803Swnj    expand into a list, after searching directory
3162803Swnj */
3172803Swnj 
expand(q)3182803Swnj expand(q)
3192803Swnj register struct depblock *q;
3202803Swnj {
3212803Swnj register char *s;
3222803Swnj char *s1;
3232803Swnj struct depblock *p, *srchdir();
3242803Swnj 
32517585Ssam if (q->depname == NULL)
32617585Ssam 	return;
3272803Swnj s1 = q->depname->namep;
3282803Swnj for(s=s1 ; ;) switch(*s++)
3292803Swnj 	{
3302803Swnj 	case '\0':
3312803Swnj 		return;
3322803Swnj 
3332803Swnj 	case '*':
3342803Swnj 	case '?':
3352803Swnj 	case '[':
3362803Swnj 		if( p = srchdir(s1 , YES, q->nxtdepblock) )
3372803Swnj 			{
3382803Swnj 			q->nxtdepblock = p;
3392803Swnj 			q->depname = 0;
3402803Swnj 			}
3412803Swnj 		return;
3422803Swnj 	}
3432803Swnj }
344