xref: /csrg-svn/old/make/doname.c (revision 31567)
1*31567Sbostic static	char *sccsid = "@(#)doname.c	4.9 (Berkeley) 87/06/18";
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 
1524911Sserge extern char *sys_siglist[];
1624911Sserge 
172803Swnj doname(p, reclevel, tval)
182803Swnj register struct nameblock *p;
192803Swnj int reclevel;
202803Swnj TIMETYPE *tval;
212803Swnj {
222803Swnj int errstat;
232803Swnj int okdel1;
242803Swnj int didwork;
252803Swnj TIMETYPE td, td1, tdep, ptime, ptime1, prestime();
262803Swnj register struct depblock *q;
272803Swnj struct depblock *qtemp, *srchdir(), *suffp, *suffp1;
282803Swnj struct nameblock *p1, *p2;
292803Swnj struct shblock *implcom, *explcom;
302803Swnj register struct lineblock *lp;
312803Swnj struct lineblock *lp1, *lp2;
3224492Sbloom char sourcename[BUFSIZ], prefix[BUFSIZ], temp[BUFSIZ], concsuff[20];
3317682Smckusick char *pnamep, *p1namep, *cp;
342803Swnj char *mkqlist();
352803Swnj struct chain *qchain, *appendq();
362803Swnj 
37*31567Sbostic {
38*31567Sbostic 	/*
39*31567Sbostic 	 * VPATH= ${PATH1}:${PATH2} didn't work.  This fix is so ugly I don't
40*31567Sbostic 	 * even want to think about it.  Basically it grabs VPATH and
41*31567Sbostic 	 * explicitly does macro expansion before resolving names.  Why
42*31567Sbostic 	 * VPATH didn't get handled correctly I have no idea; the symptom
43*31567Sbostic 	 * was that, while macro expansion got done, the .c files in the
44*31567Sbostic 	 * non-local directories wouldn't be found.
45*31567Sbostic 	 */
46*31567Sbostic 	struct varblock	*vpath_cp, *varptr();
47*31567Sbostic 	static int	vpath_first;
48*31567Sbostic 	char	vpath_exp[INMAX];
49*31567Sbostic 
50*31567Sbostic 	if (!vpath_first) {
51*31567Sbostic 		vpath_first = 1;
52*31567Sbostic 		vpath_cp = varptr("VPATH");
53*31567Sbostic 		if (vpath_cp->varval) {
54*31567Sbostic 			subst(vpath_cp->varval, vpath_exp);
55*31567Sbostic 			setvar("VPATH",vpath_exp);
56*31567Sbostic 		}
57*31567Sbostic 	}
58*31567Sbostic }
592803Swnj if(p == 0)
602803Swnj 	{
612803Swnj 	*tval = 0;
622803Swnj 	return(0);
632803Swnj 	}
642803Swnj 
652803Swnj if(dbgflag)
662803Swnj 	{
672803Swnj 	printf("doname(%s,%d)\n",p->namep,reclevel);
682803Swnj 	fflush(stdout);
692803Swnj 	}
702803Swnj 
712803Swnj if(p->done > 0)
722803Swnj 	{
732803Swnj 	*tval = p->modtime;
742803Swnj 	return(p->done == 3);
752803Swnj 	}
762803Swnj 
772803Swnj errstat = 0;
782803Swnj tdep = 0;
792803Swnj implcom = 0;
802803Swnj explcom = 0;
8118644Smckusick ptime = exists(p);
822803Swnj ptime1 = 0;
832803Swnj didwork = NO;
842803Swnj p->done = 1;	/* avoid infinite loops */
852803Swnj 
862803Swnj qchain = NULL;
872803Swnj 
882803Swnj /* Expand any names that have embedded metacharaters */
892803Swnj 
902803Swnj for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
912803Swnj 	for(q = lp->depp ; q ; q=qtemp )
922803Swnj 		{
932803Swnj 		qtemp = q->nxtdepblock;
942803Swnj 		expand(q);
952803Swnj 		}
962803Swnj 
972803Swnj /* make sure all dependents are up to date */
982803Swnj 
992803Swnj for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
1002803Swnj 	{
1012803Swnj 	td = 0;
1022803Swnj 	for(q = lp->depp ; q ; q = q->nxtdepblock)
1032803Swnj 		{
1042803Swnj 		errstat += doname(q->depname, reclevel+1, &td1);
1052803Swnj 		if(dbgflag)
1062803Swnj 		    printf("TIME(%s)=%ld\n", q->depname->namep, td1);
1072803Swnj 		if(td1 > td) td = td1;
1082803Swnj 		if(ptime < td1)
1092803Swnj 			qchain = appendq(qchain, q->depname->namep);
1102803Swnj 		}
1112803Swnj 	if(p->septype == SOMEDEPS)
1122803Swnj 		{
1132803Swnj 		if(lp->shp!=0)
1142803Swnj 		     if( ptime<td || (ptime==0 && td==0) || lp->depp==0)
1152803Swnj 			{
1162803Swnj 			okdel1 = okdel;
1172803Swnj 			okdel = NO;
1182803Swnj 			setvar("@", p->namep);
1192803Swnj 			setvar("?", mkqlist(qchain) );
1202803Swnj 			qchain = NULL;
1212803Swnj 			if( !questflag )
1222803Swnj 				errstat += docom(lp->shp);
1232803Swnj 			setvar("@", (char *) NULL);
1242803Swnj 			okdel = okdel1;
1252803Swnj 			ptime1 = prestime();
1262803Swnj 			didwork = YES;
1272803Swnj 			}
1282803Swnj 		}
1292803Swnj 
1302803Swnj 	else	{
1312803Swnj 		if(lp->shp != 0)
1322803Swnj 			{
1332803Swnj 			if(explcom)
1342803Swnj 				fprintf(stderr, "Too many command lines for `%s'\n",
1352803Swnj 					p->namep);
1362803Swnj 			else	explcom = lp->shp;
1372803Swnj 			}
1382803Swnj 
1392803Swnj 		if(td > tdep) tdep = td;
1402803Swnj 		}
1412803Swnj 	}
1422803Swnj 
1432803Swnj /* Look for implicit dependents, using suffix rules */
1442803Swnj 
1452803Swnj for(lp = sufflist ; lp ; lp = lp->nxtlineblock)
1462803Swnj     for(suffp = lp->depp ; suffp ; suffp = suffp->nxtdepblock)
1472803Swnj 	{
1482803Swnj 	pnamep = suffp->depname->namep;
1492803Swnj 	if(suffix(p->namep , pnamep , prefix))
1502803Swnj 		{
15118644Smckusick 
1522803Swnj 		srchdir( concat(prefix,"*",temp) , NO, (struct depblock *) NULL);
1532803Swnj 		for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock)
1542803Swnj 		    for(suffp1=lp1->depp ; suffp1 ; suffp1 = suffp1->nxtdepblock)
1552803Swnj 			{
1562803Swnj 			p1namep = suffp1->depname->namep;
1572803Swnj 			if( (p1=srchname(concat(p1namep, pnamep ,concsuff))) &&
1582803Swnj 			    (p2=srchname(concat(prefix, p1namep ,sourcename))) )
1592803Swnj 				{
1602803Swnj 				errstat += doname(p2, reclevel+1, &td);
1612803Swnj 				if(ptime < td)
1622803Swnj 					qchain = appendq(qchain, p2->namep);
1632803Swnj if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td);
1642803Swnj 				if(td > tdep) tdep = td;
1652803Swnj 				setvar("*", prefix);
16618644Smckusick 				if (p2->alias) setvar("<", copys(p2->alias));
16718644Smckusick 				else setvar("<", copys(p2->namep));
1682803Swnj 				for(lp2=p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
1692803Swnj 					if(implcom = lp2->shp) break;
1702803Swnj 				goto endloop;
1712803Swnj 				}
1722803Swnj 			}
17317682Smckusick 		cp = rindex(prefix, '/');
17417682Smckusick 		if (cp++ == 0)
17517682Smckusick 			cp = prefix;
17617682Smckusick 		setvar("*", cp);
1772803Swnj 		}
1782803Swnj 	}
1792803Swnj 
1802803Swnj endloop:
1812803Swnj 
1822803Swnj 
1832803Swnj if(errstat==0 && (ptime<tdep || (ptime==0 && tdep==0) ) )
1842803Swnj 	{
1852803Swnj 	ptime = (tdep>0 ? tdep : prestime() );
1862803Swnj 	setvar("@", p->namep);
1872803Swnj 	setvar("?", mkqlist(qchain) );
1882803Swnj 	if(explcom)
1892803Swnj 		errstat += docom(explcom);
1902803Swnj 	else if(implcom)
1912803Swnj 		errstat += docom(implcom);
1922803Swnj 	else if(p->septype == 0)
1932803Swnj 		if(p1=srchname(".DEFAULT"))
1942803Swnj 			{
19518644Smckusick 			if (p->alias) setvar("<", p->alias);
19618644Smckusick 			else setvar("<", p->namep);
1972803Swnj 			for(lp2 = p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
1982803Swnj 				if(implcom = lp2->shp)
1992803Swnj 					{
2002803Swnj 					errstat += docom(implcom);
2012803Swnj 					break;
2022803Swnj 					}
2032803Swnj 			}
2042803Swnj 		else if(keepgoing)
2052803Swnj 			{
2062803Swnj 			printf("Don't know how to make %s\n", p->namep);
2072803Swnj 			++errstat;
2082803Swnj 			}
2092803Swnj 		else
2102803Swnj 			fatal1(" Don't know how to make %s", p->namep);
2112803Swnj 
2122803Swnj 	setvar("@", (char *) NULL);
21318644Smckusick 	if(noexflag || (ptime = exists(p)) == 0)
2142803Swnj 		ptime = prestime();
2152803Swnj 	}
2162803Swnj 
2172803Swnj else if(errstat!=0 && reclevel==0)
2182803Swnj 	printf("`%s' not remade because of errors\n", p->namep);
2192803Swnj 
2202803Swnj else if(!questflag && reclevel==0  &&  didwork==NO)
2212803Swnj 	printf("`%s' is up to date.\n", p->namep);
2222803Swnj 
2232803Swnj if(questflag && reclevel==0)
2242803Swnj 	exit(ndocoms>0 ? -1 : 0);
2252803Swnj 
2262803Swnj p->done = (errstat ? 3 : 2);
2272803Swnj if(ptime1 > ptime) ptime = ptime1;
2282803Swnj p->modtime = ptime;
2292803Swnj *tval = ptime;
2302803Swnj return(errstat);
2312803Swnj }
2322803Swnj 
2332803Swnj docom(q)
2342803Swnj struct shblock *q;
2352803Swnj {
2362803Swnj char *s;
2372803Swnj struct varblock *varptr();
2382803Swnj int ign, nopr;
2392803Swnj char string[OUTMAX];
24018644Smckusick char string2[OUTMAX];
2412803Swnj 
2422803Swnj ++ndocoms;
2432803Swnj if(questflag)
2442803Swnj 	return(NO);
2452803Swnj 
2462803Swnj if(touchflag)
2472803Swnj 	{
2482803Swnj 	s = varptr("@")->varval;
2492803Swnj 	if(!silflag)
2502803Swnj 		printf("touch(%s)\n", s);
2512803Swnj 	if(!noexflag)
2522803Swnj 		touch(YES, s);
2532803Swnj 	}
2542803Swnj 
2552803Swnj else for( ; q ; q = q->nxtshblock )
2562803Swnj 	{
25718644Smckusick 	subst(q->shbp,string2);
25818644Smckusick 	fixname(string2, string);
2592803Swnj 
2602803Swnj 	ign = ignerr;
2612803Swnj 	nopr = NO;
2622803Swnj 	for(s = string ; *s=='-' || *s=='@' ; ++s)
2632803Swnj 		if(*s == '-')  ign = YES;
2642803Swnj 		else nopr = YES;
2652803Swnj 
2662803Swnj 	if( docom1(s, ign, nopr) && !ign)
2672803Swnj 		if(keepgoing)
2682803Swnj 			return(YES);
2692803Swnj 		else	fatal( (char *) NULL);
2702803Swnj 	}
2712803Swnj return(NO);
2722803Swnj }
2732803Swnj 
2742803Swnj 
2752803Swnj 
2762803Swnj docom1(comstring, nohalt, noprint)
2772803Swnj register char *comstring;
2782803Swnj int nohalt, noprint;
2792803Swnj {
2802803Swnj register int status;
2812803Swnj 
2822803Swnj if(comstring[0] == '\0') return(0);
2832803Swnj 
2842803Swnj if(!silflag && (!noprint || noexflag) )
2852803Swnj 	{
2862803Swnj 	printf("%s%s\n", (noexflag ? "" : prompt), comstring);
2872803Swnj 	fflush(stdout);
2882803Swnj 	}
2892803Swnj 
2902803Swnj if(noexflag) return(0);
2912803Swnj 
2922803Swnj if( status = dosys(comstring, nohalt) )
2932803Swnj 	{
29424911Sserge 	unsigned sig = status & 0177;
29524911Sserge 	if( sig ) {
29624911Sserge 		if (sig < NSIG && sys_siglist[sig] != NULL &&
29724911Sserge 		    *sys_siglist[sig] != '\0')
29824911Sserge 			printf("*** %s", sys_siglist[sig]);
29924911Sserge 		else
30024911Sserge 			printf("*** Signal %d", sig);
30124911Sserge 		if (status & 0200)
30224911Sserge 			printf(" - core dumped");
30324911Sserge 	} else
30424911Sserge 		printf("*** Exit %d", status>>8 );
3052803Swnj 
3062803Swnj 	if(nohalt) printf(" (ignored)\n");
3072803Swnj 	else	printf("\n");
3082803Swnj 	fflush(stdout);
3092803Swnj 	}
3102803Swnj 
3112803Swnj return(status);
3122803Swnj }
3132803Swnj 
3142803Swnj 
3152803Swnj /*
3162803Swnj    If there are any Shell meta characters in the name,
3172803Swnj    expand into a list, after searching directory
3182803Swnj */
3192803Swnj 
3202803Swnj expand(q)
3212803Swnj register struct depblock *q;
3222803Swnj {
3232803Swnj register char *s;
3242803Swnj char *s1;
3252803Swnj struct depblock *p, *srchdir();
3262803Swnj 
32717585Ssam if (q->depname == NULL)
32817585Ssam 	return;
3292803Swnj s1 = q->depname->namep;
3302803Swnj for(s=s1 ; ;) switch(*s++)
3312803Swnj 	{
3322803Swnj 	case '\0':
3332803Swnj 		return;
3342803Swnj 
3352803Swnj 	case '*':
3362803Swnj 	case '?':
3372803Swnj 	case '[':
3382803Swnj 		if( p = srchdir(s1 , YES, q->nxtdepblock) )
3392803Swnj 			{
3402803Swnj 			q->nxtdepblock = p;
3412803Swnj 			q->depname = 0;
3422803Swnj 			}
3432803Swnj 		return;
3442803Swnj 	}
3452803Swnj }
346