doname.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 645 行

C
645
字号
#ifndef lintstatic	char	*sccsid = "@(#)doname.c	4.2	(ULTRIX)	10/16/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1986 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//* * *   Modification History: * * */#include "defs"char Makecall;			/* flag which says whether to exec $(MAKE) */extern char archmem[];extern char archname[];/*  BASIC PROCEDURE.  RECURSIVE.  *//*p->done = 0   don't know what to do yetp->done = 1   file in process of being updatedp->done = 2   file already exists in current statep->done = 3   file make failed*/doname(p, reclevel, tval)register NAMEBLOCK p;int reclevel;TIMETYPE *tval;{	register DEPBLOCK q;	register LINEBLOCK lp;	int errstat;	int okdel1;	int didwork;	TIMETYPE td, td1, tdep, ptime, ptime1;	DEPBLOCK qtemp, suffp, suffp1;	NAMEBLOCK p1, p2;	SHBLOCK implcom, explcom;	LINEBLOCK lp1, lp2;	char sourcename[100],prefix[100],temp[100],concsuff[20];	CHARSTAR pnamep, p1namep;	CHAIN qchain;	int found, onetime;	CHARSTAR savenamep = NULL;	CHARSTAR pos, rindex();	if(p == 0)	{		*tval = 0;		return(0);	}	if(IS_ON(DBUG))	{		blprt(reclevel);		printf("doname(%s,%d)\n",p->namep,reclevel);		fflush(stdout);	}	if(p->done > 0)	{		*tval = p->modtime;		return(p->done == 3);	}	errstat = 0;	tdep = 0;	implcom = 0;	explcom = 0;	ptime = exists(p);	if(reclevel == 0 && IS_ON(DBUG))	{		blprt(reclevel);		printf("TIME1(%s)=%s\n", p->namep, ctime(&ptime));	}	ptime1 = 0;	didwork = NO;	p->done = 1;	/* avoid infinite loops */	qchain = NULL;/* *	Perform runtime dependency translations. */	if(p->rundep == 0)	{		setvar("@", p->namep);		dynamicdep(p);		setvar("@", Nullstr);	}/* *	Expand any names that have embedded metacharaters. Must be *	done after dynamic dependencies because the dyndep symbols *	($(*D)) may contain shell meta characters. */	expand(p);/* *	FIRST SECTION -- GO THROUGH DEPENDENCIES */	if(IS_ON(DBUG))	{		blprt(reclevel);		printf("look for explicit deps. %d \n", reclevel);	}	for(lp = p->linep ; lp!=0 ; lp = lp->nextline)	{		td = 0;		for(q = lp->depp ; q!=0 ; q=q->nextdep)		{			q->depname->backname = p;			errstat += doname(q->depname, reclevel+1, &td1);			if(IS_ON(DBUG))			{			    blprt(reclevel);			    printf("TIME2(%s)=%s", q->depname->namep, ctime(&td1));			}			td = max(td1,td);			if(ptime < td1)				appendq(&qchain, q->depname->namep);		}		if(p->septype == SOMEDEPS)		{			if(lp->shp!=0)				if(ptime<td||(ptime==0 && td==0) || lp->depp==0)				{					okdel1 = okdel;					okdel = NO;					setvar("@", p->namep);					if(savenamep)						setvar("%", archmem);					setvar("?", mkqlist(qchain) );					qchain = NULL;					if( IS_OFF(QUEST) )					{						ballbat(p, reclevel);						errstat += docom(lp->shp);					}					setvar("@", Nullstr);					setvar("%", Nullstr);					okdel = okdel1;					if( (ptime1 = exists(p)) == 0)						ptime1 = prestime();					didwork = YES;				}		}		else		{			if(lp->shp != 0)			{				if(explcom)					fprintf(stderr,					    "Too many command lines for `%s'\n",						p->namep);				else					explcom = lp->shp;			}			tdep = max(tdep, td);		}	}/* *	SECOND SECTION -- LOOK FOR IMPLICIT DEPENDENTS */	if(IS_ON(DBUG))	{		blprt(reclevel);		printf("look for implicit rules. %d \n", reclevel);	}	found = 0; onetime = 0;	if(any(p->namep, LPAREN))	{		savenamep = p->namep;		p->namep = copys(archmem);		if(IS_ON(DBUG))		{			blprt(reclevel);			printf("archmem = %s\n", archmem);		}		if(IS_ON(DBUG)) 		{			blprt(reclevel);			printf("archname = %s\n", archname);		}	}	else		savenamep = 0;	for(lp=sufflist ; lp!=0 ; lp = lp->nextline)	for(suffp = lp->depp ; suffp!=0 ; suffp = suffp->nextdep)	{		pnamep = suffp->depname->namep;		if(suffix(p->namep , pnamep , prefix))		{			if(IS_ON(DBUG)) 			{				blprt(reclevel);				printf("right match = %s\n",p->namep);			}			found = 1;			if(savenamep)				pnamep = ".a";searchdir:#if 0			{			  register char *p = temp, *q = prefix;			  while(*q) *p++ = *q++;			  *p = '\0';			}#else			copstr(temp, prefix);#endif 0			addstars(temp);			srchdir(temp, NO, NULL);			for(lp1 = sufflist ; lp1!=0 ; lp1 = lp1->nextline)			for(suffp1=lp1->depp;suffp1!=0;suffp1 = suffp1->nextdep)			{				p1namep = suffp1->depname->namep;				concat(p1namep, pnamep, concsuff);				if( (p1=srchname(concsuff)) == 0)					continue;				if(p1->linep == 0)					continue;				concat(prefix, p1namep, sourcename);				if(any(p1namep, WIGGLE))				{					sourcename[strlen(sourcename) - 1] =									CNULL;					if(!sdot(sourcename))						trysccs(sourcename);				}				if( (p2=srchname(sourcename)) == 0)					continue;				if(equal(sourcename, p->namep))					continue;/* *	FOUND -- left and right match */				found = 2;				if(IS_ON(DBUG))				{				  blprt(reclevel);				  printf("%s ---%s--- %s\n",					sourcename, concsuff, p->namep);				}				p2->backname = p;				errstat += doname(p2, reclevel+1, &td);				if(ptime < td)					appendq(&qchain, p2->namep);				if(IS_ON(DBUG))				{					TIMETYPE foo= exists(p);										blprt(reclevel);					printf("TIME3(%s)=%s",p->namep,ctime(&foo));					if(td > foo) {						blprt(reclevel);						printf("Building %s using inference rule %s, because it is out of date relative to %s\n", p->namep, concsuff, p2->namep);					}				}				tdep = max(tdep, td);				setvar("*", prefix);				setvar("<", sourcename);				for(lp2=p1->linep; lp2!=0 ; lp2 = lp2->nextline)					if(implcom = lp2->shp) break;				goto endloop;			}/* *	quit search for single suffix rule. */			pos = rindex(prefix, '/');			if(pos == NULL) setvar("*", copys(prefix));			else setvar("*", copys(pos + 1));			if(onetime == 1)				goto endloop;		}	}endloop:/* * look for a single suffix type rule. * only possible if no explicit dependents and no shell rules * are found, and nothing has been done so far. (previously, `make' * would exit with 'Don't know how to make ...' message. */	if(found == 0)	if(onetime == 0)	if(	  p->linep == 0 ||		( p->linep->depp == 0 && p->linep->shp == 0))	{		onetime = 1;		if(IS_ON(DBUG))		{			blprt(reclevel);			printf("Looking for Single suffix rule.\n");		}		concat(p->namep, "", prefix);		pnamep = "";		goto searchdir;	}/* *	THIRD SECTION -- LOOK FOR DEFAULT CONDITION OR DO COMMAND */	if(errstat==0 && (ptime<tdep || (ptime==0 && tdep==0) ) )	{		if(savenamep)		{			setvar("@", archname);			setvar("%", archmem);		}		else		{			setvar("@", p->namep);		}		setvar("?", mkqlist(qchain) );		ballbat(p, reclevel);		if(explcom)			errstat += docom(explcom);		else if(implcom)			errstat += docom(implcom);		else if( (p->septype != SOMEDEPS && IS_OFF(MH_DEP)) ||			 (p->septype == 0        && IS_ON(MH_DEP) )    )/* *	OLD WAY OF DOING TEST is *		else if(p->septype == 0) *	notice above, a flag has been put in to get the murray hill version. *	the flag is "-b". */			if(p1=srchname(".DEFAULT"))			{				if(IS_ON(DBUG))				{					blprt(reclevel);					printf("look for DEFAULT rule. %d \n",								reclevel);				}				setvar("<", p->namep);				for(lp2=p1->linep; lp2!=0 ; lp2 = lp2->nextline)					if(implcom = lp2->shp)					{						errstat += docom(implcom);					}			}			else if(IS_OFF(GET) ||				  !get(p->namep, NOCD, 0) )			{				fatal1(" Don't know how to make %s", p->namep);			}		setvar("@", Nullstr);		setvar("%", Nullstr);		if(IS_ON(NOEX) || (ptime = exists(p)) == 0)			ptime = prestime();	}	else if(errstat!=0 && reclevel==0)		printf("`%s' not remade because of errors\n", p->namep);	else if(IS_OFF(QUEST) && reclevel==0  &&  didwork==NO)		printf("`%s' is up to date.\n", p->namep);	if(IS_ON(QUEST) && reclevel==0)		mexit(ndocoms>0 ? -1 : 0);	p->done = (errstat ? 3 : 2);	ptime = max(ptime1, ptime);	p->modtime = ptime;	*tval = ptime;	setvar("<", Nullstr);	setvar("*", Nullstr);	return(errstat);}docom(q)SHBLOCK q;{	CHARSTAR s;	int status;	int ign, nopr;	char string[OUTMAX];	++ndocoms;	if(IS_ON(QUEST))		return(0);	if(IS_ON(TOUCH))	{		s = varptr("@")->varval;		if(IS_OFF(SIL))			printf("touch(%s)\n", s);		if(IS_OFF(NOEX))			touch(1,s);	}	else for( status = 0; q!=0 ; q = q->nextsh )	{/* *	Allow recursive makes to execute only if the NOEX flag set */		if((sindex(q->shbp, "$(MAKE)") != -1 ||				sindex(q->shbp, "${MAKE}") != -1 ||					q->shbp[0] == '+') && IS_ON(NOEX))		{			Makecall = YES;		} else {			Makecall = NO;		}		subst(q->shbp,string);		ign = IS_ON(IGNERR) ? YES : NO;		nopr = NO;		for(s = string ; *s==MINUS || *s==AT ; ++s)			if(*s == MINUS)  ign = YES;			else nopr = YES;		if( docom1(s, ign, nopr) && !ign)			if(IS_ON(KEEPGO))				return(1);			else	fatal(0);	}	return(0);}docom1(comstring, nohalt, noprint)register CHARSTAR comstring;int nohalt, noprint;{	register int status;	if(comstring[0] == '\0') return(0);	if(IS_OFF(SIL) && (!noprint || IS_ON(NOEX)) )	{		CHARSTAR p1, ps;		CHARSTAR pmt = prompt;		if (!sysvmode) pmt = "";		ps = p1 = comstring;		while(1)		{			while(*p1 && *p1 != NEWLINE) p1++;			if(*p1)			{				*p1 = 0;				printf("%s%s\n", pmt, ps);				*p1 = NEWLINE;				ps = p1 + 1;				p1 = ps;			}			else			{				printf("%s%s\n", pmt, ps);				break;			}		}		fflush(stdout);	}	if( status = dosys(comstring, nohalt) )	{		if( status>>8 )			printf("*** Error code %d", status>>8 );		else	printf("*** Termination code %d", status );		if(nohalt) printf(" (ignored)\n");		else	printf("\n");		fflush(stdout);	}	return(status);}/* *	If there are any Shell meta characters in the name, *	search the directory, and if the search finds something *	replace the dependency in "p"'s dependency chain. srchdir *	produces a DEPBLOCK chain whose last member has a null *	nextdep pointer or the NULL pointer if it finds nothing. *	The loops below do the following: for each dep in each line *	if the dep->depname has a shell metacharacter in it and *	if srchdir succeeds, replace the dep with the new one *	created by srchdir. The Nextdep variable is to skip over *	the new stuff inserted into the chain.*/expand(p)NAMEBLOCK p;{	register DEPBLOCK db;	register DEPBLOCK Nextdep;	register CHARSTAR s;	register DEPBLOCK srchdb;	register LINEBLOCK lp;	for(lp = p->linep ; lp!=0 ; lp = lp->nextline)		for(db=lp->depp ; db!=0 ; db=Nextdep )		{			Nextdep = db->nextdep;			if(any( (s=db->depname->namep), STAR) ||			   any(s, QUESTN) || any(s, LSQUAR) )				if( srchdb = srchdir(s , YES, NULL) )					dbreplace(p, db, srchdb);		}}/* *	Replace the odb depblock in np's dependency list with the *	dependency chain defined by ndb. This is just a linked list insert *	problem. dbreplace assumes the last "nextdep" pointer in *	"ndb" is null. */dbreplace(np, odb, ndb)register NAMEBLOCK np;register DEPBLOCK odb, ndb;{	register LINEBLOCK lp;	register DEPBLOCK  db;	register DEPBLOCK  enddb;	for(enddb = ndb; enddb->nextdep; enddb = enddb->nextdep);	for(lp = np->linep; lp; lp = lp->nextline)		if(lp->depp == odb)		{			enddb->nextdep	= lp->depp->nextdep;			lp->depp	= ndb;			return;		}		else		{			for(db = lp->depp; db; db = db->nextdep)				if(db->nextdep == odb)				{					enddb->nextdep	= odb->nextdep;					db->nextdep	= ndb;					return;				}		}}#define NPREDS 50ballbat(np, reclevel)NAMEBLOCK np;{	static char ballb[200];	register CHARSTAR p;	register NAMEBLOCK npp;	register int i;	VARBLOCK vp;	int npreds=0;	NAMEBLOCK circles[NPREDS];	if( *((vp=varptr("!"))->varval) == 0)		vp->varval = ballb;	p = ballb;	catstr(p, varptr("<")->varval);	*p++ = ' ';	for(npp = np; npp; npp = npp->backname)	{		for(i = 0; i < npreds; i++)		{			if(npp == circles[i])			{				fprintf(stderr,					"$! nulled, predecessor circle\n");				ballb[0] = CNULL;				return;			}		}		circles[npreds++] = npp;		if(npreds >= NPREDS)		{			fprintf(stderr, "$! nulled, too many predecessors\n");			ballb[0] = CNULL;			return;		}		catstr(p, npp->namep);		*p++ = ' ';	}}/* *	PRINT n BLANKS WHERE n IS THE CURRENT RECURSION LEVEL. */blprt(n)register int n;{	while(n--)		printf("   ");}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?