xref: /csrg-svn/old/make/doname.c (revision 18644)
1*18644Smckusick static	char *sccsid = "@(#)doname.c	4.6 (Berkeley) 85/04/16";
22803Swnj #include "defs"
317682Smckusick #include <strings.h>
42803Swnj 
52803Swnj /*  BASIC PROCEDURE.  RECURSIVE.  */
62803Swnj 
72803Swnj /*
82803Swnj p->done = 0   don't know what to do yet
92803Swnj p->done = 1   file in process of being updated
102803Swnj p->done = 2   file already exists in current state
112803Swnj p->done = 3   file make failed
122803Swnj */
132803Swnj 
142803Swnj doname(p, reclevel, tval)
152803Swnj register struct nameblock *p;
162803Swnj int reclevel;
172803Swnj TIMETYPE *tval;
182803Swnj {
192803Swnj int errstat;
202803Swnj int okdel1;
212803Swnj int didwork;
222803Swnj TIMETYPE td, td1, tdep, ptime, ptime1, prestime();
232803Swnj register struct depblock *q;
242803Swnj struct depblock *qtemp, *srchdir(), *suffp, *suffp1;
252803Swnj struct nameblock *p1, *p2;
262803Swnj struct shblock *implcom, *explcom;
272803Swnj register struct lineblock *lp;
282803Swnj struct lineblock *lp1, *lp2;
292803Swnj char sourcename[100], prefix[100], temp[100], concsuff[20];
3017682Smckusick char *pnamep, *p1namep, *cp;
312803Swnj char *mkqlist();
322803Swnj struct chain *qchain, *appendq();
332803Swnj 
342803Swnj if(p == 0)
352803Swnj 	{
362803Swnj 	*tval = 0;
372803Swnj 	return(0);
382803Swnj 	}
392803Swnj 
402803Swnj if(dbgflag)
412803Swnj 	{
422803Swnj 	printf("doname(%s,%d)\n",p->namep,reclevel);
432803Swnj 	fflush(stdout);
442803Swnj 	}
452803Swnj 
462803Swnj if(p->done > 0)
472803Swnj 	{
482803Swnj 	*tval = p->modtime;
492803Swnj 	return(p->done == 3);
502803Swnj 	}
512803Swnj 
522803Swnj errstat = 0;
532803Swnj tdep = 0;
542803Swnj implcom = 0;
552803Swnj explcom = 0;
56*18644Smckusick ptime = exists(p);
572803Swnj ptime1 = 0;
582803Swnj didwork = NO;
592803Swnj p->done = 1;	/* avoid infinite loops */
602803Swnj 
612803Swnj qchain = NULL;
622803Swnj 
632803Swnj /* Expand any names that have embedded metacharaters */
642803Swnj 
652803Swnj for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
662803Swnj 	for(q = lp->depp ; q ; q=qtemp )
672803Swnj 		{
682803Swnj 		qtemp = q->nxtdepblock;
692803Swnj 		expand(q);
702803Swnj 		}
712803Swnj 
722803Swnj /* make sure all dependents are up to date */
732803Swnj 
742803Swnj for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
752803Swnj 	{
762803Swnj 	td = 0;
772803Swnj 	for(q = lp->depp ; q ; q = q->nxtdepblock)
782803Swnj 		{
792803Swnj 		errstat += doname(q->depname, reclevel+1, &td1);
802803Swnj 		if(dbgflag)
812803Swnj 		    printf("TIME(%s)=%ld\n", q->depname->namep, td1);
822803Swnj 		if(td1 > td) td = td1;
832803Swnj 		if(ptime < td1)
842803Swnj 			qchain = appendq(qchain, q->depname->namep);
852803Swnj 		}
862803Swnj 	if(p->septype == SOMEDEPS)
872803Swnj 		{
882803Swnj 		if(lp->shp!=0)
892803Swnj 		     if( ptime<td || (ptime==0 && td==0) || lp->depp==0)
902803Swnj 			{
912803Swnj 			okdel1 = okdel;
922803Swnj 			okdel = NO;
932803Swnj 			setvar("@", p->namep);
942803Swnj 			setvar("?", mkqlist(qchain) );
952803Swnj 			qchain = NULL;
962803Swnj 			if( !questflag )
972803Swnj 				errstat += docom(lp->shp);
982803Swnj 			setvar("@", (char *) NULL);
992803Swnj 			okdel = okdel1;
1002803Swnj 			ptime1 = prestime();
1012803Swnj 			didwork = YES;
1022803Swnj 			}
1032803Swnj 		}
1042803Swnj 
1052803Swnj 	else	{
1062803Swnj 		if(lp->shp != 0)
1072803Swnj 			{
1082803Swnj 			if(explcom)
1092803Swnj 				fprintf(stderr, "Too many command lines for `%s'\n",
1102803Swnj 					p->namep);
1112803Swnj 			else	explcom = lp->shp;
1122803Swnj 			}
1132803Swnj 
1142803Swnj 		if(td > tdep) tdep = td;
1152803Swnj 		}
1162803Swnj 	}
1172803Swnj 
1182803Swnj /* Look for implicit dependents, using suffix rules */
1192803Swnj 
1202803Swnj for(lp = sufflist ; lp ; lp = lp->nxtlineblock)
1212803Swnj     for(suffp = lp->depp ; suffp ; suffp = suffp->nxtdepblock)
1222803Swnj 	{
1232803Swnj 	pnamep = suffp->depname->namep;
1242803Swnj 	if(suffix(p->namep , pnamep , prefix))
1252803Swnj 		{
126*18644Smckusick 
1272803Swnj 		srchdir( concat(prefix,"*",temp) , NO, (struct depblock *) NULL);
1282803Swnj 		for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock)
1292803Swnj 		    for(suffp1=lp1->depp ; suffp1 ; suffp1 = suffp1->nxtdepblock)
1302803Swnj 			{
1312803Swnj 			p1namep = suffp1->depname->namep;
1322803Swnj 			if( (p1=srchname(concat(p1namep, pnamep ,concsuff))) &&
1332803Swnj 			    (p2=srchname(concat(prefix, p1namep ,sourcename))) )
1342803Swnj 				{
1352803Swnj 				errstat += doname(p2, reclevel+1, &td);
1362803Swnj 				if(ptime < td)
1372803Swnj 					qchain = appendq(qchain, p2->namep);
1382803Swnj if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td);
1392803Swnj 				if(td > tdep) tdep = td;
1402803Swnj 				setvar("*", prefix);
141*18644Smckusick 				if (p2->alias) setvar("<", copys(p2->alias));
142*18644Smckusick 				else setvar("<", copys(p2->namep));
1432803Swnj 				for(lp2=p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
1442803Swnj 					if(implcom = lp2->shp) break;
1452803Swnj 				goto endloop;
1462803Swnj 				}
1472803Swnj 			}
14817682Smckusick 		cp = rindex(prefix, '/');
14917682Smckusick 		if (cp++ == 0)
15017682Smckusick 			cp = prefix;
15117682Smckusick 		setvar("*", cp);
1522803Swnj 		}
1532803Swnj 	}
1542803Swnj 
1552803Swnj endloop:
1562803Swnj 
1572803Swnj 
1582803Swnj if(errstat==0 && (ptime<tdep || (ptime==0 && tdep==0) ) )
1592803Swnj 	{
1602803Swnj 	ptime = (tdep>0 ? tdep : prestime() );
1612803Swnj 	setvar("@", p->namep);
1622803Swnj 	setvar("?", mkqlist(qchain) );
1632803Swnj 	if(explcom)
1642803Swnj 		errstat += docom(explcom);
1652803Swnj 	else if(implcom)
1662803Swnj 		errstat += docom(implcom);
1672803Swnj 	else if(p->septype == 0)
1682803Swnj 		if(p1=srchname(".DEFAULT"))
1692803Swnj 			{
170*18644Smckusick 			if (p->alias) setvar("<", p->alias);
171*18644Smckusick 			else setvar("<", p->namep);
1722803Swnj 			for(lp2 = p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
1732803Swnj 				if(implcom = lp2->shp)
1742803Swnj 					{
1752803Swnj 					errstat += docom(implcom);
1762803Swnj 					break;
1772803Swnj 					}
1782803Swnj 			}
1792803Swnj 		else if(keepgoing)
1802803Swnj 			{
1812803Swnj 			printf("Don't know how to make %s\n", p->namep);
1822803Swnj 			++errstat;
1832803Swnj 			}
1842803Swnj 		else
1852803Swnj 			fatal1(" Don't know how to make %s", p->namep);
1862803Swnj 
1872803Swnj 	setvar("@", (char *) NULL);
188*18644Smckusick 	if(noexflag || (ptime = exists(p)) == 0)
1892803Swnj 		ptime = prestime();
1902803Swnj 	}
1912803Swnj 
1922803Swnj else if(errstat!=0 && reclevel==0)
1932803Swnj 	printf("`%s' not remade because of errors\n", p->namep);
1942803Swnj 
1952803Swnj else if(!questflag && reclevel==0  &&  didwork==NO)
1962803Swnj 	printf("`%s' is up to date.\n", p->namep);
1972803Swnj 
1982803Swnj if(questflag && reclevel==0)
1992803Swnj 	exit(ndocoms>0 ? -1 : 0);
2002803Swnj 
2012803Swnj p->done = (errstat ? 3 : 2);
2022803Swnj if(ptime1 > ptime) ptime = ptime1;
2032803Swnj p->modtime = ptime;
2042803Swnj *tval = ptime;
2052803Swnj return(errstat);
2062803Swnj }
2072803Swnj 
2082803Swnj docom(q)
2092803Swnj struct shblock *q;
2102803Swnj {
2112803Swnj char *s;
2122803Swnj struct varblock *varptr();
2132803Swnj int ign, nopr;
2142803Swnj char string[OUTMAX];
215*18644Smckusick char string2[OUTMAX];
2162803Swnj 
2172803Swnj ++ndocoms;
2182803Swnj if(questflag)
2192803Swnj 	return(NO);
2202803Swnj 
2212803Swnj if(touchflag)
2222803Swnj 	{
2232803Swnj 	s = varptr("@")->varval;
2242803Swnj 	if(!silflag)
2252803Swnj 		printf("touch(%s)\n", s);
2262803Swnj 	if(!noexflag)
2272803Swnj 		touch(YES, s);
2282803Swnj 	}
2292803Swnj 
2302803Swnj else for( ; q ; q = q->nxtshblock )
2312803Swnj 	{
232*18644Smckusick 	subst(q->shbp,string2);
233*18644Smckusick 	fixname(string2, string);
2342803Swnj 
2352803Swnj 	ign = ignerr;
2362803Swnj 	nopr = NO;
2372803Swnj 	for(s = string ; *s=='-' || *s=='@' ; ++s)
2382803Swnj 		if(*s == '-')  ign = YES;
2392803Swnj 		else nopr = YES;
2402803Swnj 
2412803Swnj 	if( docom1(s, ign, nopr) && !ign)
2422803Swnj 		if(keepgoing)
2432803Swnj 			return(YES);
2442803Swnj 		else	fatal( (char *) NULL);
2452803Swnj 	}
2462803Swnj return(NO);
2472803Swnj }
2482803Swnj 
2492803Swnj 
2502803Swnj 
2512803Swnj docom1(comstring, nohalt, noprint)
2522803Swnj register char *comstring;
2532803Swnj int nohalt, noprint;
2542803Swnj {
2552803Swnj register int status;
2562803Swnj 
2572803Swnj if(comstring[0] == '\0') return(0);
2582803Swnj 
2592803Swnj if(!silflag && (!noprint || noexflag) )
2602803Swnj 	{
2612803Swnj 	printf("%s%s\n", (noexflag ? "" : prompt), comstring);
2622803Swnj 	fflush(stdout);
2632803Swnj 	}
2642803Swnj 
2652803Swnj if(noexflag) return(0);
2662803Swnj 
2672803Swnj if( status = dosys(comstring, nohalt) )
2682803Swnj 	{
2692803Swnj 	if( status>>8 )
2702803Swnj 		printf("*** Error code %d", status>>8 );
2712803Swnj 	else	printf("*** Termination code %d", status );
2722803Swnj 
2732803Swnj 	if(nohalt) printf(" (ignored)\n");
2742803Swnj 	else	printf("\n");
2752803Swnj 	fflush(stdout);
2762803Swnj 	}
2772803Swnj 
2782803Swnj return(status);
2792803Swnj }
2802803Swnj 
2812803Swnj 
2822803Swnj /*
2832803Swnj    If there are any Shell meta characters in the name,
2842803Swnj    expand into a list, after searching directory
2852803Swnj */
2862803Swnj 
2872803Swnj expand(q)
2882803Swnj register struct depblock *q;
2892803Swnj {
2902803Swnj register char *s;
2912803Swnj char *s1;
2922803Swnj struct depblock *p, *srchdir();
2932803Swnj 
29417585Ssam if (q->depname == NULL)
29517585Ssam 	return;
2962803Swnj s1 = q->depname->namep;
2972803Swnj for(s=s1 ; ;) switch(*s++)
2982803Swnj 	{
2992803Swnj 	case '\0':
3002803Swnj 		return;
3012803Swnj 
3022803Swnj 	case '*':
3032803Swnj 	case '?':
3042803Swnj 	case '[':
3052803Swnj 		if( p = srchdir(s1 , YES, q->nxtdepblock) )
3062803Swnj 			{
3072803Swnj 			q->nxtdepblock = p;
3082803Swnj 			q->depname = 0;
3092803Swnj 			}
3102803Swnj 		return;
3112803Swnj 	}
3122803Swnj }
313