1*31567Sbostic static char *sccsid = "@(#)doname.c 4.9 (Berkeley) 87/06/18"; 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 1524911Sserge extern char *sys_siglist[]; 1624911Sserge 172803Swnj doname(p, reclevel, tval) 182803Swnj register struct nameblock *p; 192803Swnj int reclevel; 202803Swnj TIMETYPE *tval; 212803Swnj { 222803Swnj int errstat; 232803Swnj int okdel1; 242803Swnj int didwork; 252803Swnj TIMETYPE td, td1, tdep, ptime, ptime1, prestime(); 262803Swnj register struct depblock *q; 272803Swnj struct depblock *qtemp, *srchdir(), *suffp, *suffp1; 282803Swnj struct nameblock *p1, *p2; 292803Swnj struct shblock *implcom, *explcom; 302803Swnj register struct lineblock *lp; 312803Swnj struct lineblock *lp1, *lp2; 3224492Sbloom char sourcename[BUFSIZ], prefix[BUFSIZ], temp[BUFSIZ], concsuff[20]; 3317682Smckusick char *pnamep, *p1namep, *cp; 342803Swnj char *mkqlist(); 352803Swnj struct chain *qchain, *appendq(); 362803Swnj 37*31567Sbostic { 38*31567Sbostic /* 39*31567Sbostic * VPATH= ${PATH1}:${PATH2} didn't work. This fix is so ugly I don't 40*31567Sbostic * even want to think about it. Basically it grabs VPATH and 41*31567Sbostic * explicitly does macro expansion before resolving names. Why 42*31567Sbostic * VPATH didn't get handled correctly I have no idea; the symptom 43*31567Sbostic * was that, while macro expansion got done, the .c files in the 44*31567Sbostic * non-local directories wouldn't be found. 45*31567Sbostic */ 46*31567Sbostic struct varblock *vpath_cp, *varptr(); 47*31567Sbostic static int vpath_first; 48*31567Sbostic char vpath_exp[INMAX]; 49*31567Sbostic 50*31567Sbostic if (!vpath_first) { 51*31567Sbostic vpath_first = 1; 52*31567Sbostic vpath_cp = varptr("VPATH"); 53*31567Sbostic if (vpath_cp->varval) { 54*31567Sbostic subst(vpath_cp->varval, vpath_exp); 55*31567Sbostic setvar("VPATH",vpath_exp); 56*31567Sbostic } 57*31567Sbostic } 58*31567Sbostic } 592803Swnj if(p == 0) 602803Swnj { 612803Swnj *tval = 0; 622803Swnj return(0); 632803Swnj } 642803Swnj 652803Swnj if(dbgflag) 662803Swnj { 672803Swnj printf("doname(%s,%d)\n",p->namep,reclevel); 682803Swnj fflush(stdout); 692803Swnj } 702803Swnj 712803Swnj if(p->done > 0) 722803Swnj { 732803Swnj *tval = p->modtime; 742803Swnj return(p->done == 3); 752803Swnj } 762803Swnj 772803Swnj errstat = 0; 782803Swnj tdep = 0; 792803Swnj implcom = 0; 802803Swnj explcom = 0; 8118644Smckusick ptime = exists(p); 822803Swnj ptime1 = 0; 832803Swnj didwork = NO; 842803Swnj p->done = 1; /* avoid infinite loops */ 852803Swnj 862803Swnj qchain = NULL; 872803Swnj 882803Swnj /* Expand any names that have embedded metacharaters */ 892803Swnj 902803Swnj for(lp = p->linep ; lp ; lp = lp->nxtlineblock) 912803Swnj for(q = lp->depp ; q ; q=qtemp ) 922803Swnj { 932803Swnj qtemp = q->nxtdepblock; 942803Swnj expand(q); 952803Swnj } 962803Swnj 972803Swnj /* make sure all dependents are up to date */ 982803Swnj 992803Swnj for(lp = p->linep ; lp ; lp = lp->nxtlineblock) 1002803Swnj { 1012803Swnj td = 0; 1022803Swnj for(q = lp->depp ; q ; q = q->nxtdepblock) 1032803Swnj { 1042803Swnj errstat += doname(q->depname, reclevel+1, &td1); 1052803Swnj if(dbgflag) 1062803Swnj printf("TIME(%s)=%ld\n", q->depname->namep, td1); 1072803Swnj if(td1 > td) td = td1; 1082803Swnj if(ptime < td1) 1092803Swnj qchain = appendq(qchain, q->depname->namep); 1102803Swnj } 1112803Swnj if(p->septype == SOMEDEPS) 1122803Swnj { 1132803Swnj if(lp->shp!=0) 1142803Swnj if( ptime<td || (ptime==0 && td==0) || lp->depp==0) 1152803Swnj { 1162803Swnj okdel1 = okdel; 1172803Swnj okdel = NO; 1182803Swnj setvar("@", p->namep); 1192803Swnj setvar("?", mkqlist(qchain) ); 1202803Swnj qchain = NULL; 1212803Swnj if( !questflag ) 1222803Swnj errstat += docom(lp->shp); 1232803Swnj setvar("@", (char *) NULL); 1242803Swnj okdel = okdel1; 1252803Swnj ptime1 = prestime(); 1262803Swnj didwork = YES; 1272803Swnj } 1282803Swnj } 1292803Swnj 1302803Swnj else { 1312803Swnj if(lp->shp != 0) 1322803Swnj { 1332803Swnj if(explcom) 1342803Swnj fprintf(stderr, "Too many command lines for `%s'\n", 1352803Swnj p->namep); 1362803Swnj else explcom = lp->shp; 1372803Swnj } 1382803Swnj 1392803Swnj if(td > tdep) tdep = td; 1402803Swnj } 1412803Swnj } 1422803Swnj 1432803Swnj /* Look for implicit dependents, using suffix rules */ 1442803Swnj 1452803Swnj for(lp = sufflist ; lp ; lp = lp->nxtlineblock) 1462803Swnj for(suffp = lp->depp ; suffp ; suffp = suffp->nxtdepblock) 1472803Swnj { 1482803Swnj pnamep = suffp->depname->namep; 1492803Swnj if(suffix(p->namep , pnamep , prefix)) 1502803Swnj { 15118644Smckusick 1522803Swnj srchdir( concat(prefix,"*",temp) , NO, (struct depblock *) NULL); 1532803Swnj for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock) 1542803Swnj for(suffp1=lp1->depp ; suffp1 ; suffp1 = suffp1->nxtdepblock) 1552803Swnj { 1562803Swnj p1namep = suffp1->depname->namep; 1572803Swnj if( (p1=srchname(concat(p1namep, pnamep ,concsuff))) && 1582803Swnj (p2=srchname(concat(prefix, p1namep ,sourcename))) ) 1592803Swnj { 1602803Swnj errstat += doname(p2, reclevel+1, &td); 1612803Swnj if(ptime < td) 1622803Swnj qchain = appendq(qchain, p2->namep); 1632803Swnj if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td); 1642803Swnj if(td > tdep) tdep = td; 1652803Swnj setvar("*", prefix); 16618644Smckusick if (p2->alias) setvar("<", copys(p2->alias)); 16718644Smckusick else setvar("<", copys(p2->namep)); 1682803Swnj for(lp2=p1->linep ; lp2 ; lp2 = lp2->nxtlineblock) 1692803Swnj if(implcom = lp2->shp) break; 1702803Swnj goto endloop; 1712803Swnj } 1722803Swnj } 17317682Smckusick cp = rindex(prefix, '/'); 17417682Smckusick if (cp++ == 0) 17517682Smckusick cp = prefix; 17617682Smckusick setvar("*", cp); 1772803Swnj } 1782803Swnj } 1792803Swnj 1802803Swnj endloop: 1812803Swnj 1822803Swnj 1832803Swnj if(errstat==0 && (ptime<tdep || (ptime==0 && tdep==0) ) ) 1842803Swnj { 1852803Swnj ptime = (tdep>0 ? tdep : prestime() ); 1862803Swnj setvar("@", p->namep); 1872803Swnj setvar("?", mkqlist(qchain) ); 1882803Swnj if(explcom) 1892803Swnj errstat += docom(explcom); 1902803Swnj else if(implcom) 1912803Swnj errstat += docom(implcom); 1922803Swnj else if(p->septype == 0) 1932803Swnj if(p1=srchname(".DEFAULT")) 1942803Swnj { 19518644Smckusick if (p->alias) setvar("<", p->alias); 19618644Smckusick else setvar("<", p->namep); 1972803Swnj for(lp2 = p1->linep ; lp2 ; lp2 = lp2->nxtlineblock) 1982803Swnj if(implcom = lp2->shp) 1992803Swnj { 2002803Swnj errstat += docom(implcom); 2012803Swnj break; 2022803Swnj } 2032803Swnj } 2042803Swnj else if(keepgoing) 2052803Swnj { 2062803Swnj printf("Don't know how to make %s\n", p->namep); 2072803Swnj ++errstat; 2082803Swnj } 2092803Swnj else 2102803Swnj fatal1(" Don't know how to make %s", p->namep); 2112803Swnj 2122803Swnj setvar("@", (char *) NULL); 21318644Smckusick if(noexflag || (ptime = exists(p)) == 0) 2142803Swnj ptime = prestime(); 2152803Swnj } 2162803Swnj 2172803Swnj else if(errstat!=0 && reclevel==0) 2182803Swnj printf("`%s' not remade because of errors\n", p->namep); 2192803Swnj 2202803Swnj else if(!questflag && reclevel==0 && didwork==NO) 2212803Swnj printf("`%s' is up to date.\n", p->namep); 2222803Swnj 2232803Swnj if(questflag && reclevel==0) 2242803Swnj exit(ndocoms>0 ? -1 : 0); 2252803Swnj 2262803Swnj p->done = (errstat ? 3 : 2); 2272803Swnj if(ptime1 > ptime) ptime = ptime1; 2282803Swnj p->modtime = ptime; 2292803Swnj *tval = ptime; 2302803Swnj return(errstat); 2312803Swnj } 2322803Swnj 2332803Swnj docom(q) 2342803Swnj struct shblock *q; 2352803Swnj { 2362803Swnj char *s; 2372803Swnj struct varblock *varptr(); 2382803Swnj int ign, nopr; 2392803Swnj char string[OUTMAX]; 24018644Smckusick char string2[OUTMAX]; 2412803Swnj 2422803Swnj ++ndocoms; 2432803Swnj if(questflag) 2442803Swnj return(NO); 2452803Swnj 2462803Swnj if(touchflag) 2472803Swnj { 2482803Swnj s = varptr("@")->varval; 2492803Swnj if(!silflag) 2502803Swnj printf("touch(%s)\n", s); 2512803Swnj if(!noexflag) 2522803Swnj touch(YES, s); 2532803Swnj } 2542803Swnj 2552803Swnj else for( ; q ; q = q->nxtshblock ) 2562803Swnj { 25718644Smckusick subst(q->shbp,string2); 25818644Smckusick fixname(string2, string); 2592803Swnj 2602803Swnj ign = ignerr; 2612803Swnj nopr = NO; 2622803Swnj for(s = string ; *s=='-' || *s=='@' ; ++s) 2632803Swnj if(*s == '-') ign = YES; 2642803Swnj else nopr = YES; 2652803Swnj 2662803Swnj if( docom1(s, ign, nopr) && !ign) 2672803Swnj if(keepgoing) 2682803Swnj return(YES); 2692803Swnj else fatal( (char *) NULL); 2702803Swnj } 2712803Swnj return(NO); 2722803Swnj } 2732803Swnj 2742803Swnj 2752803Swnj 2762803Swnj docom1(comstring, nohalt, noprint) 2772803Swnj register char *comstring; 2782803Swnj int nohalt, noprint; 2792803Swnj { 2802803Swnj register int status; 2812803Swnj 2822803Swnj if(comstring[0] == '\0') return(0); 2832803Swnj 2842803Swnj if(!silflag && (!noprint || noexflag) ) 2852803Swnj { 2862803Swnj printf("%s%s\n", (noexflag ? "" : prompt), comstring); 2872803Swnj fflush(stdout); 2882803Swnj } 2892803Swnj 2902803Swnj if(noexflag) return(0); 2912803Swnj 2922803Swnj if( status = dosys(comstring, nohalt) ) 2932803Swnj { 29424911Sserge unsigned sig = status & 0177; 29524911Sserge if( sig ) { 29624911Sserge if (sig < NSIG && sys_siglist[sig] != NULL && 29724911Sserge *sys_siglist[sig] != '\0') 29824911Sserge printf("*** %s", sys_siglist[sig]); 29924911Sserge else 30024911Sserge printf("*** Signal %d", sig); 30124911Sserge if (status & 0200) 30224911Sserge printf(" - core dumped"); 30324911Sserge } else 30424911Sserge printf("*** Exit %d", status>>8 ); 3052803Swnj 3062803Swnj if(nohalt) printf(" (ignored)\n"); 3072803Swnj else printf("\n"); 3082803Swnj fflush(stdout); 3092803Swnj } 3102803Swnj 3112803Swnj return(status); 3122803Swnj } 3132803Swnj 3142803Swnj 3152803Swnj /* 3162803Swnj If there are any Shell meta characters in the name, 3172803Swnj expand into a list, after searching directory 3182803Swnj */ 3192803Swnj 3202803Swnj expand(q) 3212803Swnj register struct depblock *q; 3222803Swnj { 3232803Swnj register char *s; 3242803Swnj char *s1; 3252803Swnj struct depblock *p, *srchdir(); 3262803Swnj 32717585Ssam if (q->depname == NULL) 32817585Ssam return; 3292803Swnj s1 = q->depname->namep; 3302803Swnj for(s=s1 ; ;) switch(*s++) 3312803Swnj { 3322803Swnj case '\0': 3332803Swnj return; 3342803Swnj 3352803Swnj case '*': 3362803Swnj case '?': 3372803Swnj case '[': 3382803Swnj if( p = srchdir(s1 , YES, q->nxtdepblock) ) 3392803Swnj { 3402803Swnj q->nxtdepblock = p; 3412803Swnj q->depname = 0; 3422803Swnj } 3432803Swnj return; 3442803Swnj } 3452803Swnj } 346