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 + -
显示快捷键?