xref: /csrg-svn/old/make/doname.c (revision 17682)
1*17682Smckusick static	char *sccsid = "@(#)doname.c	4.5 (Berkeley) 85/01/09";
22803Swnj #include "defs"
3*17682Smckusick #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];
30*17682Smckusick 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;
562803Swnj ptime = exists(p->namep);
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 		{
1262803Swnj 		srchdir( concat(prefix,"*",temp) , NO, (struct depblock *) NULL);
1272803Swnj 		for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock)
1282803Swnj 		    for(suffp1=lp1->depp ; suffp1 ; suffp1 = suffp1->nxtdepblock)
1292803Swnj 			{
1302803Swnj 			p1namep = suffp1->depname->namep;
1312803Swnj 			if( (p1=srchname(concat(p1namep, pnamep ,concsuff))) &&
1322803Swnj 			    (p2=srchname(concat(prefix, p1namep ,sourcename))) )
1332803Swnj 				{
1342803Swnj 				errstat += doname(p2, reclevel+1, &td);
1352803Swnj 				if(ptime < td)
1362803Swnj 					qchain = appendq(qchain, p2->namep);
1372803Swnj if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td);
1382803Swnj 				if(td > tdep) tdep = td;
1392803Swnj 				setvar("*", prefix);
1402803Swnj 				setvar("<", copys(sourcename));
1412803Swnj 				for(lp2=p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
1422803Swnj 					if(implcom = lp2->shp) break;
1432803Swnj 				goto endloop;
1442803Swnj 				}
1452803Swnj 			}
146*17682Smckusick 		cp = rindex(prefix, '/');
147*17682Smckusick 		if (cp++ == 0)
148*17682Smckusick 			cp = prefix;
149*17682Smckusick 		setvar("*", cp);
1502803Swnj 		}
1512803Swnj 	}
1522803Swnj 
1532803Swnj endloop:
1542803Swnj 
1552803Swnj 
1562803Swnj if(errstat==0 && (ptime<tdep || (ptime==0 && tdep==0) ) )
1572803Swnj 	{
1582803Swnj 	ptime = (tdep>0 ? tdep : prestime() );
1592803Swnj 	setvar("@", p->namep);
1602803Swnj 	setvar("?", mkqlist(qchain) );
1612803Swnj 	if(explcom)
1622803Swnj 		errstat += docom(explcom);
1632803Swnj 	else if(implcom)
1642803Swnj 		errstat += docom(implcom);
1652803Swnj 	else if(p->septype == 0)
1662803Swnj 		if(p1=srchname(".DEFAULT"))
1672803Swnj 			{
1682803Swnj 			setvar("<", p->namep);
1692803Swnj 			for(lp2 = p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
1702803Swnj 				if(implcom = lp2->shp)
1712803Swnj 					{
1722803Swnj 					errstat += docom(implcom);
1732803Swnj 					break;
1742803Swnj 					}
1752803Swnj 			}
1762803Swnj 		else if(keepgoing)
1772803Swnj 			{
1782803Swnj 			printf("Don't know how to make %s\n", p->namep);
1792803Swnj 			++errstat;
1802803Swnj 			}
1812803Swnj 		else
1822803Swnj 			fatal1(" Don't know how to make %s", p->namep);
1832803Swnj 
1842803Swnj 	setvar("@", (char *) NULL);
1852803Swnj 	if(noexflag || (ptime = exists(p->namep)) == 0)
1862803Swnj 		ptime = prestime();
1872803Swnj 	}
1882803Swnj 
1892803Swnj else if(errstat!=0 && reclevel==0)
1902803Swnj 	printf("`%s' not remade because of errors\n", p->namep);
1912803Swnj 
1922803Swnj else if(!questflag && reclevel==0  &&  didwork==NO)
1932803Swnj 	printf("`%s' is up to date.\n", p->namep);
1942803Swnj 
1952803Swnj if(questflag && reclevel==0)
1962803Swnj 	exit(ndocoms>0 ? -1 : 0);
1972803Swnj 
1982803Swnj p->done = (errstat ? 3 : 2);
1992803Swnj if(ptime1 > ptime) ptime = ptime1;
2002803Swnj p->modtime = ptime;
2012803Swnj *tval = ptime;
2022803Swnj return(errstat);
2032803Swnj }
2042803Swnj 
2052803Swnj docom(q)
2062803Swnj struct shblock *q;
2072803Swnj {
2082803Swnj char *s;
2092803Swnj struct varblock *varptr();
2102803Swnj int ign, nopr;
2112803Swnj char string[OUTMAX];
2122803Swnj 
2132803Swnj ++ndocoms;
2142803Swnj if(questflag)
2152803Swnj 	return(NO);
2162803Swnj 
2172803Swnj if(touchflag)
2182803Swnj 	{
2192803Swnj 	s = varptr("@")->varval;
2202803Swnj 	if(!silflag)
2212803Swnj 		printf("touch(%s)\n", s);
2222803Swnj 	if(!noexflag)
2232803Swnj 		touch(YES, s);
2242803Swnj 	}
2252803Swnj 
2262803Swnj else for( ; q ; q = q->nxtshblock )
2272803Swnj 	{
2282803Swnj 	subst(q->shbp,string);
2292803Swnj 
2302803Swnj 	ign = ignerr;
2312803Swnj 	nopr = NO;
2322803Swnj 	for(s = string ; *s=='-' || *s=='@' ; ++s)
2332803Swnj 		if(*s == '-')  ign = YES;
2342803Swnj 		else nopr = YES;
2352803Swnj 
2362803Swnj 	if( docom1(s, ign, nopr) && !ign)
2372803Swnj 		if(keepgoing)
2382803Swnj 			return(YES);
2392803Swnj 		else	fatal( (char *) NULL);
2402803Swnj 	}
2412803Swnj return(NO);
2422803Swnj }
2432803Swnj 
2442803Swnj 
2452803Swnj 
2462803Swnj docom1(comstring, nohalt, noprint)
2472803Swnj register char *comstring;
2482803Swnj int nohalt, noprint;
2492803Swnj {
2502803Swnj register int status;
2512803Swnj 
2522803Swnj if(comstring[0] == '\0') return(0);
2532803Swnj 
2542803Swnj if(!silflag && (!noprint || noexflag) )
2552803Swnj 	{
2562803Swnj 	printf("%s%s\n", (noexflag ? "" : prompt), comstring);
2572803Swnj 	fflush(stdout);
2582803Swnj 	}
2592803Swnj 
2602803Swnj if(noexflag) return(0);
2612803Swnj 
2622803Swnj if( status = dosys(comstring, nohalt) )
2632803Swnj 	{
2642803Swnj 	if( status>>8 )
2652803Swnj 		printf("*** Error code %d", status>>8 );
2662803Swnj 	else	printf("*** Termination code %d", status );
2672803Swnj 
2682803Swnj 	if(nohalt) printf(" (ignored)\n");
2692803Swnj 	else	printf("\n");
2702803Swnj 	fflush(stdout);
2712803Swnj 	}
2722803Swnj 
2732803Swnj return(status);
2742803Swnj }
2752803Swnj 
2762803Swnj 
2772803Swnj /*
2782803Swnj    If there are any Shell meta characters in the name,
2792803Swnj    expand into a list, after searching directory
2802803Swnj */
2812803Swnj 
2822803Swnj expand(q)
2832803Swnj register struct depblock *q;
2842803Swnj {
2852803Swnj register char *s;
2862803Swnj char *s1;
2872803Swnj struct depblock *p, *srchdir();
2882803Swnj 
28917585Ssam if (q->depname == NULL)
29017585Ssam 	return;
2912803Swnj s1 = q->depname->namep;
2922803Swnj for(s=s1 ; ;) switch(*s++)
2932803Swnj 	{
2942803Swnj 	case '\0':
2952803Swnj 		return;
2962803Swnj 
2972803Swnj 	case '*':
2982803Swnj 	case '?':
2992803Swnj 	case '[':
3002803Swnj 		if( p = srchdir(s1 , YES, q->nxtdepblock) )
3012803Swnj 			{
3022803Swnj 			q->nxtdepblock = p;
3032803Swnj 			q->depname = 0;
3042803Swnj 			}
3052803Swnj 		return;
3062803Swnj 	}
3072803Swnj }
308