1*11539Smckusick static char *sccsid = "@(#)doname.c 4.3 (Berkeley) 83/03/11"; 22803Swnj #include "defs" 32803Swnj 42803Swnj /* BASIC PROCEDURE. RECURSIVE. */ 52803Swnj 62803Swnj /* 72803Swnj p->done = 0 don't know what to do yet 82803Swnj p->done = 1 file in process of being updated 92803Swnj p->done = 2 file already exists in current state 102803Swnj p->done = 3 file make failed 112803Swnj */ 122803Swnj 132803Swnj doname(p, reclevel, tval) 142803Swnj register struct nameblock *p; 152803Swnj int reclevel; 162803Swnj TIMETYPE *tval; 172803Swnj { 182803Swnj int errstat; 192803Swnj int okdel1; 202803Swnj int didwork; 212803Swnj TIMETYPE td, td1, tdep, ptime, ptime1, prestime(); 222803Swnj register struct depblock *q; 232803Swnj struct depblock *qtemp, *srchdir(), *suffp, *suffp1; 242803Swnj struct nameblock *p1, *p2; 252803Swnj struct shblock *implcom, *explcom; 262803Swnj register struct lineblock *lp; 272803Swnj struct lineblock *lp1, *lp2; 282803Swnj char sourcename[100], prefix[100], temp[100], concsuff[20]; 292803Swnj char *pnamep, *p1namep; 302803Swnj char *mkqlist(); 312803Swnj struct chain *qchain, *appendq(); 322803Swnj 332803Swnj if(p == 0) 342803Swnj { 352803Swnj *tval = 0; 362803Swnj return(0); 372803Swnj } 382803Swnj 392803Swnj if(dbgflag) 402803Swnj { 412803Swnj printf("doname(%s,%d)\n",p->namep,reclevel); 422803Swnj fflush(stdout); 432803Swnj } 442803Swnj 452803Swnj if(p->done > 0) 462803Swnj { 472803Swnj *tval = p->modtime; 482803Swnj return(p->done == 3); 492803Swnj } 502803Swnj 512803Swnj errstat = 0; 522803Swnj tdep = 0; 532803Swnj implcom = 0; 542803Swnj explcom = 0; 552803Swnj ptime = exists(p->namep); 562803Swnj ptime1 = 0; 572803Swnj didwork = NO; 582803Swnj p->done = 1; /* avoid infinite loops */ 592803Swnj 602803Swnj qchain = NULL; 612803Swnj 622803Swnj /* Expand any names that have embedded metacharaters */ 632803Swnj 642803Swnj for(lp = p->linep ; lp ; lp = lp->nxtlineblock) 652803Swnj for(q = lp->depp ; q ; q=qtemp ) 662803Swnj { 672803Swnj qtemp = q->nxtdepblock; 682803Swnj expand(q); 692803Swnj } 702803Swnj 712803Swnj /* make sure all dependents are up to date */ 722803Swnj 732803Swnj for(lp = p->linep ; lp ; lp = lp->nxtlineblock) 742803Swnj { 752803Swnj td = 0; 762803Swnj for(q = lp->depp ; q ; q = q->nxtdepblock) 772803Swnj { 782803Swnj errstat += doname(q->depname, reclevel+1, &td1); 792803Swnj if(dbgflag) 802803Swnj printf("TIME(%s)=%ld\n", q->depname->namep, td1); 812803Swnj if(td1 > td) td = td1; 822803Swnj if(ptime < td1) 832803Swnj qchain = appendq(qchain, q->depname->namep); 842803Swnj } 852803Swnj if(p->septype == SOMEDEPS) 862803Swnj { 872803Swnj if(lp->shp!=0) 882803Swnj if( ptime<td || (ptime==0 && td==0) || lp->depp==0) 892803Swnj { 902803Swnj okdel1 = okdel; 912803Swnj okdel = NO; 922803Swnj setvar("@", p->namep); 932803Swnj setvar("?", mkqlist(qchain) ); 942803Swnj qchain = NULL; 952803Swnj if( !questflag ) 962803Swnj errstat += docom(lp->shp); 972803Swnj setvar("@", (char *) NULL); 982803Swnj okdel = okdel1; 992803Swnj ptime1 = prestime(); 1002803Swnj didwork = YES; 1012803Swnj } 1022803Swnj } 1032803Swnj 1042803Swnj else { 1052803Swnj if(lp->shp != 0) 1062803Swnj { 1072803Swnj if(explcom) 1082803Swnj fprintf(stderr, "Too many command lines for `%s'\n", 1092803Swnj p->namep); 1102803Swnj else explcom = lp->shp; 1112803Swnj } 1122803Swnj 1132803Swnj if(td > tdep) tdep = td; 1142803Swnj } 1152803Swnj } 1162803Swnj 1172803Swnj /* Look for implicit dependents, using suffix rules */ 1182803Swnj 1192803Swnj for(lp = sufflist ; lp ; lp = lp->nxtlineblock) 1202803Swnj for(suffp = lp->depp ; suffp ; suffp = suffp->nxtdepblock) 1212803Swnj { 1222803Swnj pnamep = suffp->depname->namep; 1232803Swnj if(suffix(p->namep , pnamep , prefix)) 1242803Swnj { 1252803Swnj srchdir( concat(prefix,"*",temp) , NO, (struct depblock *) NULL); 1262803Swnj for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock) 1272803Swnj for(suffp1=lp1->depp ; suffp1 ; suffp1 = suffp1->nxtdepblock) 1282803Swnj { 1292803Swnj p1namep = suffp1->depname->namep; 1302803Swnj if( (p1=srchname(concat(p1namep, pnamep ,concsuff))) && 1312803Swnj (p2=srchname(concat(prefix, p1namep ,sourcename))) ) 1322803Swnj { 1332803Swnj errstat += doname(p2, reclevel+1, &td); 1342803Swnj if(ptime < td) 1352803Swnj qchain = appendq(qchain, p2->namep); 1362803Swnj if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td); 1372803Swnj if(td > tdep) tdep = td; 1382803Swnj setvar("*", prefix); 1392803Swnj setvar("<", copys(sourcename)); 1402803Swnj for(lp2=p1->linep ; lp2 ; lp2 = lp2->nxtlineblock) 1412803Swnj if(implcom = lp2->shp) break; 1422803Swnj goto endloop; 1432803Swnj } 1442803Swnj } 145*11539Smckusick setvar("*", rindex(prefix, '/') + 1); 1462803Swnj } 1472803Swnj } 1482803Swnj 1492803Swnj endloop: 1502803Swnj 1512803Swnj 1522803Swnj if(errstat==0 && (ptime<tdep || (ptime==0 && tdep==0) ) ) 1532803Swnj { 1542803Swnj ptime = (tdep>0 ? tdep : prestime() ); 1552803Swnj setvar("@", p->namep); 1562803Swnj setvar("?", mkqlist(qchain) ); 1572803Swnj if(explcom) 1582803Swnj errstat += docom(explcom); 1592803Swnj else if(implcom) 1602803Swnj errstat += docom(implcom); 1612803Swnj else if(p->septype == 0) 1622803Swnj if(p1=srchname(".DEFAULT")) 1632803Swnj { 1642803Swnj setvar("<", p->namep); 1652803Swnj for(lp2 = p1->linep ; lp2 ; lp2 = lp2->nxtlineblock) 1662803Swnj if(implcom = lp2->shp) 1672803Swnj { 1682803Swnj errstat += docom(implcom); 1692803Swnj break; 1702803Swnj } 1712803Swnj } 1722803Swnj else if(keepgoing) 1732803Swnj { 1742803Swnj printf("Don't know how to make %s\n", p->namep); 1752803Swnj ++errstat; 1762803Swnj } 1772803Swnj else 1782803Swnj fatal1(" Don't know how to make %s", p->namep); 1792803Swnj 1802803Swnj setvar("@", (char *) NULL); 1812803Swnj if(noexflag || (ptime = exists(p->namep)) == 0) 1822803Swnj ptime = prestime(); 1832803Swnj } 1842803Swnj 1852803Swnj else if(errstat!=0 && reclevel==0) 1862803Swnj printf("`%s' not remade because of errors\n", p->namep); 1872803Swnj 1882803Swnj else if(!questflag && reclevel==0 && didwork==NO) 1892803Swnj printf("`%s' is up to date.\n", p->namep); 1902803Swnj 1912803Swnj if(questflag && reclevel==0) 1922803Swnj exit(ndocoms>0 ? -1 : 0); 1932803Swnj 1942803Swnj p->done = (errstat ? 3 : 2); 1952803Swnj if(ptime1 > ptime) ptime = ptime1; 1962803Swnj p->modtime = ptime; 1972803Swnj *tval = ptime; 1982803Swnj return(errstat); 1992803Swnj } 2002803Swnj 2012803Swnj docom(q) 2022803Swnj struct shblock *q; 2032803Swnj { 2042803Swnj char *s; 2052803Swnj struct varblock *varptr(); 2062803Swnj int ign, nopr; 2072803Swnj char string[OUTMAX]; 2082803Swnj 2092803Swnj ++ndocoms; 2102803Swnj if(questflag) 2112803Swnj return(NO); 2122803Swnj 2132803Swnj if(touchflag) 2142803Swnj { 2152803Swnj s = varptr("@")->varval; 2162803Swnj if(!silflag) 2172803Swnj printf("touch(%s)\n", s); 2182803Swnj if(!noexflag) 2192803Swnj touch(YES, s); 2202803Swnj } 2212803Swnj 2222803Swnj else for( ; q ; q = q->nxtshblock ) 2232803Swnj { 2242803Swnj subst(q->shbp,string); 2252803Swnj 2262803Swnj ign = ignerr; 2272803Swnj nopr = NO; 2282803Swnj for(s = string ; *s=='-' || *s=='@' ; ++s) 2292803Swnj if(*s == '-') ign = YES; 2302803Swnj else nopr = YES; 2312803Swnj 2322803Swnj if( docom1(s, ign, nopr) && !ign) 2332803Swnj if(keepgoing) 2342803Swnj return(YES); 2352803Swnj else fatal( (char *) NULL); 2362803Swnj } 2372803Swnj return(NO); 2382803Swnj } 2392803Swnj 2402803Swnj 2412803Swnj 2422803Swnj docom1(comstring, nohalt, noprint) 2432803Swnj register char *comstring; 2442803Swnj int nohalt, noprint; 2452803Swnj { 2462803Swnj register int status; 2472803Swnj 2482803Swnj if(comstring[0] == '\0') return(0); 2492803Swnj 2502803Swnj if(!silflag && (!noprint || noexflag) ) 2512803Swnj { 2522803Swnj printf("%s%s\n", (noexflag ? "" : prompt), comstring); 2532803Swnj fflush(stdout); 2542803Swnj } 2552803Swnj 2562803Swnj if(noexflag) return(0); 2572803Swnj 2582803Swnj if( status = dosys(comstring, nohalt) ) 2592803Swnj { 2602803Swnj if( status>>8 ) 2612803Swnj printf("*** Error code %d", status>>8 ); 2622803Swnj else printf("*** Termination code %d", status ); 2632803Swnj 2642803Swnj if(nohalt) printf(" (ignored)\n"); 2652803Swnj else printf("\n"); 2662803Swnj fflush(stdout); 2672803Swnj } 2682803Swnj 2692803Swnj return(status); 2702803Swnj } 2712803Swnj 2722803Swnj 2732803Swnj /* 2742803Swnj If there are any Shell meta characters in the name, 2752803Swnj expand into a list, after searching directory 2762803Swnj */ 2772803Swnj 2782803Swnj expand(q) 2792803Swnj register struct depblock *q; 2802803Swnj { 2812803Swnj register char *s; 2822803Swnj char *s1; 2832803Swnj struct depblock *p, *srchdir(); 2842803Swnj 2852803Swnj s1 = q->depname->namep; 2862803Swnj for(s=s1 ; ;) switch(*s++) 2872803Swnj { 2882803Swnj case '\0': 2892803Swnj return; 2902803Swnj 2912803Swnj case '*': 2922803Swnj case '?': 2932803Swnj case '[': 2942803Swnj if( p = srchdir(s1 , YES, q->nxtdepblock) ) 2952803Swnj { 2962803Swnj q->nxtdepblock = p; 2972803Swnj q->depname = 0; 2982803Swnj } 2992803Swnj return; 3002803Swnj } 3012803Swnj } 302