1*17682Smckusick static char *sccsid = "@(#)doname.c 4.5 (Berkeley) 85/01/09"; 22803Swnj #include "defs" 3*17682Smckusick #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]; 30*17682Smckusick 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; 562803Swnj ptime = exists(p->namep); 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 { 1262803Swnj srchdir( concat(prefix,"*",temp) , NO, (struct depblock *) NULL); 1272803Swnj for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock) 1282803Swnj for(suffp1=lp1->depp ; suffp1 ; suffp1 = suffp1->nxtdepblock) 1292803Swnj { 1302803Swnj p1namep = suffp1->depname->namep; 1312803Swnj if( (p1=srchname(concat(p1namep, pnamep ,concsuff))) && 1322803Swnj (p2=srchname(concat(prefix, p1namep ,sourcename))) ) 1332803Swnj { 1342803Swnj errstat += doname(p2, reclevel+1, &td); 1352803Swnj if(ptime < td) 1362803Swnj qchain = appendq(qchain, p2->namep); 1372803Swnj if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td); 1382803Swnj if(td > tdep) tdep = td; 1392803Swnj setvar("*", prefix); 1402803Swnj setvar("<", copys(sourcename)); 1412803Swnj for(lp2=p1->linep ; lp2 ; lp2 = lp2->nxtlineblock) 1422803Swnj if(implcom = lp2->shp) break; 1432803Swnj goto endloop; 1442803Swnj } 1452803Swnj } 146*17682Smckusick cp = rindex(prefix, '/'); 147*17682Smckusick if (cp++ == 0) 148*17682Smckusick cp = prefix; 149*17682Smckusick setvar("*", cp); 1502803Swnj } 1512803Swnj } 1522803Swnj 1532803Swnj endloop: 1542803Swnj 1552803Swnj 1562803Swnj if(errstat==0 && (ptime<tdep || (ptime==0 && tdep==0) ) ) 1572803Swnj { 1582803Swnj ptime = (tdep>0 ? tdep : prestime() ); 1592803Swnj setvar("@", p->namep); 1602803Swnj setvar("?", mkqlist(qchain) ); 1612803Swnj if(explcom) 1622803Swnj errstat += docom(explcom); 1632803Swnj else if(implcom) 1642803Swnj errstat += docom(implcom); 1652803Swnj else if(p->septype == 0) 1662803Swnj if(p1=srchname(".DEFAULT")) 1672803Swnj { 1682803Swnj setvar("<", p->namep); 1692803Swnj for(lp2 = p1->linep ; lp2 ; lp2 = lp2->nxtlineblock) 1702803Swnj if(implcom = lp2->shp) 1712803Swnj { 1722803Swnj errstat += docom(implcom); 1732803Swnj break; 1742803Swnj } 1752803Swnj } 1762803Swnj else if(keepgoing) 1772803Swnj { 1782803Swnj printf("Don't know how to make %s\n", p->namep); 1792803Swnj ++errstat; 1802803Swnj } 1812803Swnj else 1822803Swnj fatal1(" Don't know how to make %s", p->namep); 1832803Swnj 1842803Swnj setvar("@", (char *) NULL); 1852803Swnj if(noexflag || (ptime = exists(p->namep)) == 0) 1862803Swnj ptime = prestime(); 1872803Swnj } 1882803Swnj 1892803Swnj else if(errstat!=0 && reclevel==0) 1902803Swnj printf("`%s' not remade because of errors\n", p->namep); 1912803Swnj 1922803Swnj else if(!questflag && reclevel==0 && didwork==NO) 1932803Swnj printf("`%s' is up to date.\n", p->namep); 1942803Swnj 1952803Swnj if(questflag && reclevel==0) 1962803Swnj exit(ndocoms>0 ? -1 : 0); 1972803Swnj 1982803Swnj p->done = (errstat ? 3 : 2); 1992803Swnj if(ptime1 > ptime) ptime = ptime1; 2002803Swnj p->modtime = ptime; 2012803Swnj *tval = ptime; 2022803Swnj return(errstat); 2032803Swnj } 2042803Swnj 2052803Swnj docom(q) 2062803Swnj struct shblock *q; 2072803Swnj { 2082803Swnj char *s; 2092803Swnj struct varblock *varptr(); 2102803Swnj int ign, nopr; 2112803Swnj char string[OUTMAX]; 2122803Swnj 2132803Swnj ++ndocoms; 2142803Swnj if(questflag) 2152803Swnj return(NO); 2162803Swnj 2172803Swnj if(touchflag) 2182803Swnj { 2192803Swnj s = varptr("@")->varval; 2202803Swnj if(!silflag) 2212803Swnj printf("touch(%s)\n", s); 2222803Swnj if(!noexflag) 2232803Swnj touch(YES, s); 2242803Swnj } 2252803Swnj 2262803Swnj else for( ; q ; q = q->nxtshblock ) 2272803Swnj { 2282803Swnj subst(q->shbp,string); 2292803Swnj 2302803Swnj ign = ignerr; 2312803Swnj nopr = NO; 2322803Swnj for(s = string ; *s=='-' || *s=='@' ; ++s) 2332803Swnj if(*s == '-') ign = YES; 2342803Swnj else nopr = YES; 2352803Swnj 2362803Swnj if( docom1(s, ign, nopr) && !ign) 2372803Swnj if(keepgoing) 2382803Swnj return(YES); 2392803Swnj else fatal( (char *) NULL); 2402803Swnj } 2412803Swnj return(NO); 2422803Swnj } 2432803Swnj 2442803Swnj 2452803Swnj 2462803Swnj docom1(comstring, nohalt, noprint) 2472803Swnj register char *comstring; 2482803Swnj int nohalt, noprint; 2492803Swnj { 2502803Swnj register int status; 2512803Swnj 2522803Swnj if(comstring[0] == '\0') return(0); 2532803Swnj 2542803Swnj if(!silflag && (!noprint || noexflag) ) 2552803Swnj { 2562803Swnj printf("%s%s\n", (noexflag ? "" : prompt), comstring); 2572803Swnj fflush(stdout); 2582803Swnj } 2592803Swnj 2602803Swnj if(noexflag) return(0); 2612803Swnj 2622803Swnj if( status = dosys(comstring, nohalt) ) 2632803Swnj { 2642803Swnj if( status>>8 ) 2652803Swnj printf("*** Error code %d", status>>8 ); 2662803Swnj else printf("*** Termination code %d", status ); 2672803Swnj 2682803Swnj if(nohalt) printf(" (ignored)\n"); 2692803Swnj else printf("\n"); 2702803Swnj fflush(stdout); 2712803Swnj } 2722803Swnj 2732803Swnj return(status); 2742803Swnj } 2752803Swnj 2762803Swnj 2772803Swnj /* 2782803Swnj If there are any Shell meta characters in the name, 2792803Swnj expand into a list, after searching directory 2802803Swnj */ 2812803Swnj 2822803Swnj expand(q) 2832803Swnj register struct depblock *q; 2842803Swnj { 2852803Swnj register char *s; 2862803Swnj char *s1; 2872803Swnj struct depblock *p, *srchdir(); 2882803Swnj 28917585Ssam if (q->depname == NULL) 29017585Ssam return; 2912803Swnj s1 = q->depname->namep; 2922803Swnj for(s=s1 ; ;) switch(*s++) 2932803Swnj { 2942803Swnj case '\0': 2952803Swnj return; 2962803Swnj 2972803Swnj case '*': 2982803Swnj case '?': 2992803Swnj case '[': 3002803Swnj if( p = srchdir(s1 , YES, q->nxtdepblock) ) 3012803Swnj { 3022803Swnj q->nxtdepblock = p; 3032803Swnj q->depname = 0; 3042803Swnj } 3052803Swnj return; 3062803Swnj } 3072803Swnj } 308