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