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