File:  [Research Unix] / researchv10no / cmd / usgmake / doname.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:21:35 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv10, HEAD
researchv10 Norman

/*      %W%     */
/*      @(#)/usr/src/cmd/make/doname.c  3.5     */

#include "defs"
#define	ONE	0


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 yet
p->done = 1   file in process of being updated
p->done = 2   file already exists in current state
p->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;

        if(p == 0)
        {
                *tval = 0;
                return(0);
        }

        if(ONE)
        {
                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 && ONE)
        {
                blprt(reclevel);
                printf("TIME(%s)=%ld\n", p->namep, 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("@", 0);
        }

/*
 *      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(ONE)
        {
                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(ONE)
                        {
                            blprt(reclevel);
                            printf("TIME(%s)=%ld\n", q->depname->namep, 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("@", 0);
                                        setvar("%", 0);
                                        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(ONE)
        {
                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(ONE)
                {
                        blprt(reclevel);
                        printf("archmem = %s\n", archmem);
                }
                if(ONE) 
                {
                        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(ONE) 
                        {
                                blprt(reclevel);
                                printf("right match = %s\n",p->namep);
                        }
                        found = 1;
                        if(savenamep)
                                pnamep = ".a";
searchdir:

                        copstr(temp, prefix);
                        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(is_sccs(sourcename) == NO)
                                                trysccs(sourcename);
                                }
                                if( (p2=srchname(sourcename)) == 0)
                                        continue;
                                if(equal(sourcename, p->namep))
                                        continue;
/*
 *      FOUND -- left and right match
 */

                                found = 2;
                                if(ONE)
                                {
                                  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(ONE)
                                {
                                        blprt(reclevel);
                                        printf("TIME(%s)=%ld\n",p2->namep,td);
                                }
                                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.
 */
                        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(ONE)
                {
                        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" (for botch).
 */
                        if(p1=srchname(".DEFAULT"))
                        {
                                if(ONE)
                                {
                                        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("@", 0);
                setvar("%", 0);
                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)
                exit(ndocoms>0 ? -1 : 0);

        p->done = (errstat ? 3 : 2);
        ptime = max(ptime1, ptime);
        p->modtime = ptime;
        *tval = ptime;
        setvar("<", 0);
        setvar("*", 0);
        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 && 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;

                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 50

ballbat(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;
        p = copstr(p, varptr("<")->varval);
        p = copstr(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;
                }
                p = copstr(p, npp->namep);
                p = copstr(p, " ");
        }
}

/*
 *      PRINT n BLANKS WHERE n IS THE CURRENT RECURSION LEVEL.
 */
blprt(n)
register int n;
{
        while(n--)
                printf("   ");
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.