1*58336Storek static char *sccsid = "@(#)doname.c 4.10 (Berkeley) 93/03/01";
22803Swnj #include "defs"
317682Smckusick #include <strings.h>
424911Sserge #include <signal.h>
52803Swnj
62803Swnj /* BASIC PROCEDURE. RECURSIVE. */
72803Swnj
82803Swnj /*
92803Swnj p->done = 0 don't know what to do yet
102803Swnj p->done = 1 file in process of being updated
112803Swnj p->done = 2 file already exists in current state
122803Swnj p->done = 3 file make failed
132803Swnj */
142803Swnj
doname(p,reclevel,tval)152803Swnj doname(p, reclevel, tval)
162803Swnj register struct nameblock *p;
172803Swnj int reclevel;
182803Swnj TIMETYPE *tval;
192803Swnj {
202803Swnj int errstat;
212803Swnj int okdel1;
222803Swnj int didwork;
232803Swnj TIMETYPE td, td1, tdep, ptime, ptime1, prestime();
242803Swnj register struct depblock *q;
252803Swnj struct depblock *qtemp, *srchdir(), *suffp, *suffp1;
262803Swnj struct nameblock *p1, *p2;
272803Swnj struct shblock *implcom, *explcom;
282803Swnj register struct lineblock *lp;
292803Swnj struct lineblock *lp1, *lp2;
3024492Sbloom char sourcename[BUFSIZ], prefix[BUFSIZ], temp[BUFSIZ], concsuff[20];
3117682Smckusick char *pnamep, *p1namep, *cp;
322803Swnj char *mkqlist();
332803Swnj struct chain *qchain, *appendq();
342803Swnj
3531567Sbostic {
3631567Sbostic /*
3731567Sbostic * VPATH= ${PATH1}:${PATH2} didn't work. This fix is so ugly I don't
3831567Sbostic * even want to think about it. Basically it grabs VPATH and
3931567Sbostic * explicitly does macro expansion before resolving names. Why
4031567Sbostic * VPATH didn't get handled correctly I have no idea; the symptom
4131567Sbostic * was that, while macro expansion got done, the .c files in the
4231567Sbostic * non-local directories wouldn't be found.
4331567Sbostic */
4431567Sbostic struct varblock *vpath_cp, *varptr();
4531567Sbostic static int vpath_first;
4631567Sbostic char vpath_exp[INMAX];
4731567Sbostic
4831567Sbostic if (!vpath_first) {
4931567Sbostic vpath_first = 1;
5031567Sbostic vpath_cp = varptr("VPATH");
5131567Sbostic if (vpath_cp->varval) {
5231567Sbostic subst(vpath_cp->varval, vpath_exp);
5331567Sbostic setvar("VPATH",vpath_exp);
5431567Sbostic }
5531567Sbostic }
5631567Sbostic }
572803Swnj if(p == 0)
582803Swnj {
592803Swnj *tval = 0;
602803Swnj return(0);
612803Swnj }
622803Swnj
632803Swnj if(dbgflag)
642803Swnj {
652803Swnj printf("doname(%s,%d)\n",p->namep,reclevel);
662803Swnj fflush(stdout);
672803Swnj }
682803Swnj
692803Swnj if(p->done > 0)
702803Swnj {
712803Swnj *tval = p->modtime;
722803Swnj return(p->done == 3);
732803Swnj }
742803Swnj
752803Swnj errstat = 0;
762803Swnj tdep = 0;
772803Swnj implcom = 0;
782803Swnj explcom = 0;
7918644Smckusick ptime = exists(p);
802803Swnj ptime1 = 0;
812803Swnj didwork = NO;
822803Swnj p->done = 1; /* avoid infinite loops */
832803Swnj
842803Swnj qchain = NULL;
852803Swnj
862803Swnj /* Expand any names that have embedded metacharaters */
872803Swnj
882803Swnj for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
892803Swnj for(q = lp->depp ; q ; q=qtemp )
902803Swnj {
912803Swnj qtemp = q->nxtdepblock;
922803Swnj expand(q);
932803Swnj }
942803Swnj
952803Swnj /* make sure all dependents are up to date */
962803Swnj
972803Swnj for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
982803Swnj {
992803Swnj td = 0;
1002803Swnj for(q = lp->depp ; q ; q = q->nxtdepblock)
1012803Swnj {
1022803Swnj errstat += doname(q->depname, reclevel+1, &td1);
1032803Swnj if(dbgflag)
1042803Swnj printf("TIME(%s)=%ld\n", q->depname->namep, td1);
1052803Swnj if(td1 > td) td = td1;
1062803Swnj if(ptime < td1)
1072803Swnj qchain = appendq(qchain, q->depname->namep);
1082803Swnj }
1092803Swnj if(p->septype == SOMEDEPS)
1102803Swnj {
1112803Swnj if(lp->shp!=0)
1122803Swnj if( ptime<td || (ptime==0 && td==0) || lp->depp==0)
1132803Swnj {
1142803Swnj okdel1 = okdel;
1152803Swnj okdel = NO;
1162803Swnj setvar("@", p->namep);
1172803Swnj setvar("?", mkqlist(qchain) );
1182803Swnj qchain = NULL;
1192803Swnj if( !questflag )
1202803Swnj errstat += docom(lp->shp);
1212803Swnj setvar("@", (char *) NULL);
1222803Swnj okdel = okdel1;
1232803Swnj ptime1 = prestime();
1242803Swnj didwork = YES;
1252803Swnj }
1262803Swnj }
1272803Swnj
1282803Swnj else {
1292803Swnj if(lp->shp != 0)
1302803Swnj {
1312803Swnj if(explcom)
1322803Swnj fprintf(stderr, "Too many command lines for `%s'\n",
1332803Swnj p->namep);
1342803Swnj else explcom = lp->shp;
1352803Swnj }
1362803Swnj
1372803Swnj if(td > tdep) tdep = td;
1382803Swnj }
1392803Swnj }
1402803Swnj
1412803Swnj /* Look for implicit dependents, using suffix rules */
1422803Swnj
1432803Swnj for(lp = sufflist ; lp ; lp = lp->nxtlineblock)
1442803Swnj for(suffp = lp->depp ; suffp ; suffp = suffp->nxtdepblock)
1452803Swnj {
1462803Swnj pnamep = suffp->depname->namep;
1472803Swnj if(suffix(p->namep , pnamep , prefix))
1482803Swnj {
14918644Smckusick
1502803Swnj srchdir( concat(prefix,"*",temp) , NO, (struct depblock *) NULL);
1512803Swnj for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock)
1522803Swnj for(suffp1=lp1->depp ; suffp1 ; suffp1 = suffp1->nxtdepblock)
1532803Swnj {
1542803Swnj p1namep = suffp1->depname->namep;
1552803Swnj if( (p1=srchname(concat(p1namep, pnamep ,concsuff))) &&
1562803Swnj (p2=srchname(concat(prefix, p1namep ,sourcename))) )
1572803Swnj {
1582803Swnj errstat += doname(p2, reclevel+1, &td);
1592803Swnj if(ptime < td)
1602803Swnj qchain = appendq(qchain, p2->namep);
1612803Swnj if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td);
1622803Swnj if(td > tdep) tdep = td;
1632803Swnj setvar("*", prefix);
16418644Smckusick if (p2->alias) setvar("<", copys(p2->alias));
16518644Smckusick else setvar("<", copys(p2->namep));
1662803Swnj for(lp2=p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
1672803Swnj if(implcom = lp2->shp) break;
1682803Swnj goto endloop;
1692803Swnj }
1702803Swnj }
17117682Smckusick cp = rindex(prefix, '/');
17217682Smckusick if (cp++ == 0)
17317682Smckusick cp = prefix;
17417682Smckusick setvar("*", cp);
1752803Swnj }
1762803Swnj }
1772803Swnj
1782803Swnj endloop:
1792803Swnj
1802803Swnj
1812803Swnj if(errstat==0 && (ptime<tdep || (ptime==0 && tdep==0) ) )
1822803Swnj {
1832803Swnj ptime = (tdep>0 ? tdep : prestime() );
1842803Swnj setvar("@", p->namep);
1852803Swnj setvar("?", mkqlist(qchain) );
1862803Swnj if(explcom)
1872803Swnj errstat += docom(explcom);
1882803Swnj else if(implcom)
1892803Swnj errstat += docom(implcom);
1902803Swnj else if(p->septype == 0)
1912803Swnj if(p1=srchname(".DEFAULT"))
1922803Swnj {
19318644Smckusick if (p->alias) setvar("<", p->alias);
19418644Smckusick else setvar("<", p->namep);
1952803Swnj for(lp2 = p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
1962803Swnj if(implcom = lp2->shp)
1972803Swnj {
1982803Swnj errstat += docom(implcom);
1992803Swnj break;
2002803Swnj }
2012803Swnj }
2022803Swnj else if(keepgoing)
2032803Swnj {
2042803Swnj printf("Don't know how to make %s\n", p->namep);
2052803Swnj ++errstat;
2062803Swnj }
2072803Swnj else
2082803Swnj fatal1(" Don't know how to make %s", p->namep);
2092803Swnj
2102803Swnj setvar("@", (char *) NULL);
21118644Smckusick if(noexflag || (ptime = exists(p)) == 0)
2122803Swnj ptime = prestime();
2132803Swnj }
2142803Swnj
2152803Swnj else if(errstat!=0 && reclevel==0)
2162803Swnj printf("`%s' not remade because of errors\n", p->namep);
2172803Swnj
2182803Swnj else if(!questflag && reclevel==0 && didwork==NO)
2192803Swnj printf("`%s' is up to date.\n", p->namep);
2202803Swnj
2212803Swnj if(questflag && reclevel==0)
2222803Swnj exit(ndocoms>0 ? -1 : 0);
2232803Swnj
2242803Swnj p->done = (errstat ? 3 : 2);
2252803Swnj if(ptime1 > ptime) ptime = ptime1;
2262803Swnj p->modtime = ptime;
2272803Swnj *tval = ptime;
2282803Swnj return(errstat);
2292803Swnj }
2302803Swnj
2312803Swnj docom(q)
2322803Swnj struct shblock *q;
2332803Swnj {
2342803Swnj char *s;
2352803Swnj struct varblock *varptr();
2362803Swnj int ign, nopr;
2372803Swnj char string[OUTMAX];
23818644Smckusick char string2[OUTMAX];
2392803Swnj
2402803Swnj ++ndocoms;
2412803Swnj if(questflag)
2422803Swnj return(NO);
2432803Swnj
2442803Swnj if(touchflag)
2452803Swnj {
2462803Swnj s = varptr("@")->varval;
2472803Swnj if(!silflag)
2482803Swnj printf("touch(%s)\n", s);
2492803Swnj if(!noexflag)
2502803Swnj touch(YES, s);
2512803Swnj }
2522803Swnj
2532803Swnj else for( ; q ; q = q->nxtshblock )
2542803Swnj {
25518644Smckusick subst(q->shbp,string2);
25618644Smckusick fixname(string2, string);
2572803Swnj
2582803Swnj ign = ignerr;
2592803Swnj nopr = NO;
2602803Swnj for(s = string ; *s=='-' || *s=='@' ; ++s)
2612803Swnj if(*s == '-') ign = YES;
2622803Swnj else nopr = YES;
2632803Swnj
2642803Swnj if( docom1(s, ign, nopr) && !ign)
2652803Swnj if(keepgoing)
2662803Swnj return(YES);
2672803Swnj else fatal( (char *) NULL);
2682803Swnj }
2692803Swnj return(NO);
2702803Swnj }
2712803Swnj
2722803Swnj
2732803Swnj
docom1(comstring,nohalt,noprint)2742803Swnj docom1(comstring, nohalt, noprint)
2752803Swnj register char *comstring;
2762803Swnj int nohalt, noprint;
2772803Swnj {
2782803Swnj register int status;
2792803Swnj
2802803Swnj if(comstring[0] == '\0') return(0);
2812803Swnj
2822803Swnj if(!silflag && (!noprint || noexflag) )
2832803Swnj {
2842803Swnj printf("%s%s\n", (noexflag ? "" : prompt), comstring);
2852803Swnj fflush(stdout);
2862803Swnj }
2872803Swnj
2882803Swnj if(noexflag) return(0);
2892803Swnj
2902803Swnj if( status = dosys(comstring, nohalt) )
2912803Swnj {
29224911Sserge unsigned sig = status & 0177;
29324911Sserge if( sig ) {
29424911Sserge if (sig < NSIG && sys_siglist[sig] != NULL &&
29524911Sserge *sys_siglist[sig] != '\0')
29624911Sserge printf("*** %s", sys_siglist[sig]);
29724911Sserge else
29824911Sserge printf("*** Signal %d", sig);
29924911Sserge if (status & 0200)
30024911Sserge printf(" - core dumped");
30124911Sserge } else
30224911Sserge printf("*** Exit %d", status>>8 );
3032803Swnj
3042803Swnj if(nohalt) printf(" (ignored)\n");
3052803Swnj else printf("\n");
3062803Swnj fflush(stdout);
3072803Swnj }
3082803Swnj
3092803Swnj return(status);
3102803Swnj }
3112803Swnj
3122803Swnj
3132803Swnj /*
3142803Swnj If there are any Shell meta characters in the name,
3152803Swnj expand into a list, after searching directory
3162803Swnj */
3172803Swnj
expand(q)3182803Swnj expand(q)
3192803Swnj register struct depblock *q;
3202803Swnj {
3212803Swnj register char *s;
3222803Swnj char *s1;
3232803Swnj struct depblock *p, *srchdir();
3242803Swnj
32517585Ssam if (q->depname == NULL)
32617585Ssam return;
3272803Swnj s1 = q->depname->namep;
3282803Swnj for(s=s1 ; ;) switch(*s++)
3292803Swnj {
3302803Swnj case '\0':
3312803Swnj return;
3322803Swnj
3332803Swnj case '*':
3342803Swnj case '?':
3352803Swnj case '[':
3362803Swnj if( p = srchdir(s1 , YES, q->nxtdepblock) )
3372803Swnj {
3382803Swnj q->nxtdepblock = p;
3392803Swnj q->depname = 0;
3402803Swnj }
3412803Swnj return;
3422803Swnj }
3432803Swnj }
344