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