1*2803Swnj static char *sccsid = "@(#)doname.c 4.1 (Berkeley) 81/02/28"; 2*2803Swnj #include "defs" 3*2803Swnj 4*2803Swnj /* BASIC PROCEDURE. RECURSIVE. */ 5*2803Swnj 6*2803Swnj /* 7*2803Swnj p->done = 0 don't know what to do yet 8*2803Swnj p->done = 1 file in process of being updated 9*2803Swnj p->done = 2 file already exists in current state 10*2803Swnj p->done = 3 file make failed 11*2803Swnj */ 12*2803Swnj 13*2803Swnj doname(p, reclevel, tval) 14*2803Swnj register struct nameblock *p; 15*2803Swnj int reclevel; 16*2803Swnj TIMETYPE *tval; 17*2803Swnj { 18*2803Swnj int errstat; 19*2803Swnj int okdel1; 20*2803Swnj int didwork; 21*2803Swnj TIMETYPE td, td1, tdep, ptime, ptime1, prestime(); 22*2803Swnj register struct depblock *q; 23*2803Swnj struct depblock *qtemp, *srchdir(), *suffp, *suffp1; 24*2803Swnj struct nameblock *p1, *p2; 25*2803Swnj struct shblock *implcom, *explcom; 26*2803Swnj register struct lineblock *lp; 27*2803Swnj struct lineblock *lp1, *lp2; 28*2803Swnj char sourcename[100], prefix[100], temp[100], concsuff[20]; 29*2803Swnj char *pnamep, *p1namep; 30*2803Swnj char *mkqlist(); 31*2803Swnj struct chain *qchain, *appendq(); 32*2803Swnj 33*2803Swnj if(p == 0) 34*2803Swnj { 35*2803Swnj *tval = 0; 36*2803Swnj return(0); 37*2803Swnj } 38*2803Swnj 39*2803Swnj if(dbgflag) 40*2803Swnj { 41*2803Swnj printf("doname(%s,%d)\n",p->namep,reclevel); 42*2803Swnj fflush(stdout); 43*2803Swnj } 44*2803Swnj 45*2803Swnj if(p->done > 0) 46*2803Swnj { 47*2803Swnj *tval = p->modtime; 48*2803Swnj return(p->done == 3); 49*2803Swnj } 50*2803Swnj 51*2803Swnj errstat = 0; 52*2803Swnj tdep = 0; 53*2803Swnj implcom = 0; 54*2803Swnj explcom = 0; 55*2803Swnj ptime = exists(p->namep); 56*2803Swnj ptime1 = 0; 57*2803Swnj didwork = NO; 58*2803Swnj p->done = 1; /* avoid infinite loops */ 59*2803Swnj 60*2803Swnj qchain = NULL; 61*2803Swnj 62*2803Swnj /* Expand any names that have embedded metacharaters */ 63*2803Swnj 64*2803Swnj for(lp = p->linep ; lp ; lp = lp->nxtlineblock) 65*2803Swnj for(q = lp->depp ; q ; q=qtemp ) 66*2803Swnj { 67*2803Swnj qtemp = q->nxtdepblock; 68*2803Swnj expand(q); 69*2803Swnj } 70*2803Swnj 71*2803Swnj /* make sure all dependents are up to date */ 72*2803Swnj 73*2803Swnj for(lp = p->linep ; lp ; lp = lp->nxtlineblock) 74*2803Swnj { 75*2803Swnj td = 0; 76*2803Swnj for(q = lp->depp ; q ; q = q->nxtdepblock) 77*2803Swnj { 78*2803Swnj errstat += doname(q->depname, reclevel+1, &td1); 79*2803Swnj if(dbgflag) 80*2803Swnj printf("TIME(%s)=%ld\n", q->depname->namep, td1); 81*2803Swnj if(td1 > td) td = td1; 82*2803Swnj if(ptime < td1) 83*2803Swnj qchain = appendq(qchain, q->depname->namep); 84*2803Swnj } 85*2803Swnj if(p->septype == SOMEDEPS) 86*2803Swnj { 87*2803Swnj if(lp->shp!=0) 88*2803Swnj if( ptime<td || (ptime==0 && td==0) || lp->depp==0) 89*2803Swnj { 90*2803Swnj okdel1 = okdel; 91*2803Swnj okdel = NO; 92*2803Swnj setvar("@", p->namep); 93*2803Swnj setvar("?", mkqlist(qchain) ); 94*2803Swnj qchain = NULL; 95*2803Swnj if( !questflag ) 96*2803Swnj errstat += docom(lp->shp); 97*2803Swnj setvar("@", (char *) NULL); 98*2803Swnj okdel = okdel1; 99*2803Swnj ptime1 = prestime(); 100*2803Swnj didwork = YES; 101*2803Swnj } 102*2803Swnj } 103*2803Swnj 104*2803Swnj else { 105*2803Swnj if(lp->shp != 0) 106*2803Swnj { 107*2803Swnj if(explcom) 108*2803Swnj fprintf(stderr, "Too many command lines for `%s'\n", 109*2803Swnj p->namep); 110*2803Swnj else explcom = lp->shp; 111*2803Swnj } 112*2803Swnj 113*2803Swnj if(td > tdep) tdep = td; 114*2803Swnj } 115*2803Swnj } 116*2803Swnj 117*2803Swnj /* Look for implicit dependents, using suffix rules */ 118*2803Swnj 119*2803Swnj for(lp = sufflist ; lp ; lp = lp->nxtlineblock) 120*2803Swnj for(suffp = lp->depp ; suffp ; suffp = suffp->nxtdepblock) 121*2803Swnj { 122*2803Swnj pnamep = suffp->depname->namep; 123*2803Swnj if(suffix(p->namep , pnamep , prefix)) 124*2803Swnj { 125*2803Swnj srchdir( concat(prefix,"*",temp) , NO, (struct depblock *) NULL); 126*2803Swnj for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock) 127*2803Swnj for(suffp1=lp1->depp ; suffp1 ; suffp1 = suffp1->nxtdepblock) 128*2803Swnj { 129*2803Swnj p1namep = suffp1->depname->namep; 130*2803Swnj if( (p1=srchname(concat(p1namep, pnamep ,concsuff))) && 131*2803Swnj (p2=srchname(concat(prefix, p1namep ,sourcename))) ) 132*2803Swnj { 133*2803Swnj errstat += doname(p2, reclevel+1, &td); 134*2803Swnj if(ptime < td) 135*2803Swnj qchain = appendq(qchain, p2->namep); 136*2803Swnj if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td); 137*2803Swnj if(td > tdep) tdep = td; 138*2803Swnj setvar("*", prefix); 139*2803Swnj setvar("<", copys(sourcename)); 140*2803Swnj for(lp2=p1->linep ; lp2 ; lp2 = lp2->nxtlineblock) 141*2803Swnj if(implcom = lp2->shp) break; 142*2803Swnj goto endloop; 143*2803Swnj } 144*2803Swnj } 145*2803Swnj } 146*2803Swnj } 147*2803Swnj 148*2803Swnj endloop: 149*2803Swnj 150*2803Swnj 151*2803Swnj if(errstat==0 && (ptime<tdep || (ptime==0 && tdep==0) ) ) 152*2803Swnj { 153*2803Swnj ptime = (tdep>0 ? tdep : prestime() ); 154*2803Swnj setvar("@", p->namep); 155*2803Swnj setvar("?", mkqlist(qchain) ); 156*2803Swnj if(explcom) 157*2803Swnj errstat += docom(explcom); 158*2803Swnj else if(implcom) 159*2803Swnj errstat += docom(implcom); 160*2803Swnj else if(p->septype == 0) 161*2803Swnj if(p1=srchname(".DEFAULT")) 162*2803Swnj { 163*2803Swnj setvar("<", p->namep); 164*2803Swnj for(lp2 = p1->linep ; lp2 ; lp2 = lp2->nxtlineblock) 165*2803Swnj if(implcom = lp2->shp) 166*2803Swnj { 167*2803Swnj errstat += docom(implcom); 168*2803Swnj break; 169*2803Swnj } 170*2803Swnj } 171*2803Swnj else if(keepgoing) 172*2803Swnj { 173*2803Swnj printf("Don't know how to make %s\n", p->namep); 174*2803Swnj ++errstat; 175*2803Swnj } 176*2803Swnj else 177*2803Swnj fatal1(" Don't know how to make %s", p->namep); 178*2803Swnj 179*2803Swnj setvar("@", (char *) NULL); 180*2803Swnj if(noexflag || (ptime = exists(p->namep)) == 0) 181*2803Swnj ptime = prestime(); 182*2803Swnj } 183*2803Swnj 184*2803Swnj else if(errstat!=0 && reclevel==0) 185*2803Swnj printf("`%s' not remade because of errors\n", p->namep); 186*2803Swnj 187*2803Swnj else if(!questflag && reclevel==0 && didwork==NO) 188*2803Swnj printf("`%s' is up to date.\n", p->namep); 189*2803Swnj 190*2803Swnj if(questflag && reclevel==0) 191*2803Swnj exit(ndocoms>0 ? -1 : 0); 192*2803Swnj 193*2803Swnj p->done = (errstat ? 3 : 2); 194*2803Swnj if(ptime1 > ptime) ptime = ptime1; 195*2803Swnj p->modtime = ptime; 196*2803Swnj *tval = ptime; 197*2803Swnj return(errstat); 198*2803Swnj } 199*2803Swnj 200*2803Swnj docom(q) 201*2803Swnj struct shblock *q; 202*2803Swnj { 203*2803Swnj char *s; 204*2803Swnj struct varblock *varptr(); 205*2803Swnj int ign, nopr; 206*2803Swnj char string[OUTMAX]; 207*2803Swnj 208*2803Swnj ++ndocoms; 209*2803Swnj if(questflag) 210*2803Swnj return(NO); 211*2803Swnj 212*2803Swnj if(touchflag) 213*2803Swnj { 214*2803Swnj s = varptr("@")->varval; 215*2803Swnj if(!silflag) 216*2803Swnj printf("touch(%s)\n", s); 217*2803Swnj if(!noexflag) 218*2803Swnj touch(YES, s); 219*2803Swnj } 220*2803Swnj 221*2803Swnj else for( ; q ; q = q->nxtshblock ) 222*2803Swnj { 223*2803Swnj subst(q->shbp,string); 224*2803Swnj 225*2803Swnj ign = ignerr; 226*2803Swnj nopr = NO; 227*2803Swnj for(s = string ; *s=='-' || *s=='@' ; ++s) 228*2803Swnj if(*s == '-') ign = YES; 229*2803Swnj else nopr = YES; 230*2803Swnj 231*2803Swnj if( docom1(s, ign, nopr) && !ign) 232*2803Swnj if(keepgoing) 233*2803Swnj return(YES); 234*2803Swnj else fatal( (char *) NULL); 235*2803Swnj } 236*2803Swnj return(NO); 237*2803Swnj } 238*2803Swnj 239*2803Swnj 240*2803Swnj 241*2803Swnj docom1(comstring, nohalt, noprint) 242*2803Swnj register char *comstring; 243*2803Swnj int nohalt, noprint; 244*2803Swnj { 245*2803Swnj register int status; 246*2803Swnj 247*2803Swnj if(comstring[0] == '\0') return(0); 248*2803Swnj 249*2803Swnj if(!silflag && (!noprint || noexflag) ) 250*2803Swnj { 251*2803Swnj printf("%s%s\n", (noexflag ? "" : prompt), comstring); 252*2803Swnj fflush(stdout); 253*2803Swnj } 254*2803Swnj 255*2803Swnj if(noexflag) return(0); 256*2803Swnj 257*2803Swnj if( status = dosys(comstring, nohalt) ) 258*2803Swnj { 259*2803Swnj if( status>>8 ) 260*2803Swnj printf("*** Error code %d", status>>8 ); 261*2803Swnj else printf("*** Termination code %d", status ); 262*2803Swnj 263*2803Swnj if(nohalt) printf(" (ignored)\n"); 264*2803Swnj else printf("\n"); 265*2803Swnj fflush(stdout); 266*2803Swnj } 267*2803Swnj 268*2803Swnj return(status); 269*2803Swnj } 270*2803Swnj 271*2803Swnj 272*2803Swnj /* 273*2803Swnj If there are any Shell meta characters in the name, 274*2803Swnj expand into a list, after searching directory 275*2803Swnj */ 276*2803Swnj 277*2803Swnj expand(q) 278*2803Swnj register struct depblock *q; 279*2803Swnj { 280*2803Swnj register char *s; 281*2803Swnj char *s1; 282*2803Swnj struct depblock *p, *srchdir(); 283*2803Swnj 284*2803Swnj s1 = q->depname->namep; 285*2803Swnj for(s=s1 ; ;) switch(*s++) 286*2803Swnj { 287*2803Swnj case '\0': 288*2803Swnj return; 289*2803Swnj 290*2803Swnj case '*': 291*2803Swnj case '?': 292*2803Swnj case '[': 293*2803Swnj if( p = srchdir(s1 , YES, q->nxtdepblock) ) 294*2803Swnj { 295*2803Swnj q->nxtdepblock = p; 296*2803Swnj q->depname = 0; 297*2803Swnj } 298*2803Swnj return; 299*2803Swnj } 300*2803Swnj } 301