1: /* static char *sccsid = "@(#)doname.c 4.9.2 (2.11BSD) 2000/2/12"; */ 2: #include "defs" 3: #include <strings.h> 4: #include <signal.h> 5: 6: /* BASIC PROCEDURE. RECURSIVE. */ 7: 8: /* 9: p->done = 0 don't know what to do yet 10: p->done = 1 file in process of being updated 11: p->done = 2 file already exists in current state 12: p->done = 3 file make failed 13: */ 14: 15: extern char *sys_siglist[], arfile[], *arfname; 16: 17: doname(p, reclevel, tval) 18: register struct nameblock *p; 19: int reclevel; 20: TIMETYPE *tval; 21: { 22: int errstat; 23: u_char okdel1; 24: u_char didwork; 25: TIMETYPE td, td1, tdep, ptime, ptime1, prestime(); 26: register struct depblock *q; 27: struct depblock *qtemp, *srchdir(), *suffp, *suffp1; 28: struct nameblock *p1, *p2; 29: struct shblock *implcom, *explcom; 30: register struct lineblock *lp; 31: struct lineblock *lp1, *lp2; 32: #ifdef pdp11 33: /* temp and sourcename are mutually exclusive - save 254 bytes of stack by 34: * reusing sourcename's buffer 35: */ 36: char sourcename[256], prefix[256], *temp = sourcename, concsuff[20]; 37: #else 38: char sourcename[BUFSIZ], prefix[BUFSIZ], temp[BUFSIZ], concsuff[20]; 39: #endif 40: char *pnamep, *p1namep, *cp, *savenamep = NULL; 41: char *mkqlist(); 42: struct chain *qchain, *appendq(); 43: 44: { 45: /* 46: * VPATH= ${PATH1}:${PATH2} didn't work. This fix is so ugly I don't 47: * even want to think about it. Basically it grabs VPATH and 48: * explicitly does macro expansion before resolving names. Why 49: * VPATH didn't get handled correctly I have no idea; the symptom 50: * was that, while macro expansion got done, the .c files in the 51: * non-local directories wouldn't be found. 52: */ 53: static struct varblock *vpath_cp; 54: struct varblock *varptr(); 55: static char vpath_exp[256]; 56: 57: if (!vpath_cp) { 58: vpath_cp = varptr("VPATH"); 59: if (vpath_cp->varval) { 60: subst(vpath_cp->varval, vpath_exp); 61: setvar("VPATH", vpath_exp); 62: } 63: } 64: } 65: 66: if(p == 0) 67: { 68: *tval = 0; 69: return(0); 70: } 71: 72: if(dbgflag) 73: { 74: printf("doname(%s,%d)\n",p->namep,reclevel); 75: fflush(stdout); 76: } 77: 78: if(p->done > 0) 79: { 80: *tval = p->modtime; 81: return(p->done == 3); 82: } 83: 84: errstat = 0; 85: tdep = 0; 86: implcom = 0; 87: explcom = 0; 88: ptime = exists(p); 89: ptime1 = 0; 90: didwork = NO; 91: p->done = 1; /* avoid infinite loops */ 92: 93: qchain = NULL; 94: 95: /* Expand any names that have embedded metacharaters */ 96: 97: for(lp = p->linep ; lp ; lp = lp->nxtlineblock) 98: for(q = lp->depp ; q ; q=qtemp ) 99: { 100: qtemp = q->nxtdepblock; 101: expand(q); 102: } 103: 104: /* make sure all dependents are up to date */ 105: 106: for(lp = p->linep ; lp ; lp = lp->nxtlineblock) 107: { 108: td = 0; 109: for(q = lp->depp ; q ; q = q->nxtdepblock) 110: { 111: errstat += doname(q->depname, reclevel+1, &td1); 112: if(dbgflag) 113: printf("TIME(%s)=%ld\n", q->depname->namep, td1); 114: if(td1 > td) td = td1; 115: if(ptime < td1) 116: qchain = appendq(qchain, q->depname->namep); 117: } 118: if(p->septype == SOMEDEPS) 119: { 120: if(lp->shp!=0) 121: if( ptime<td || (ptime==0 && td==0) || lp->depp==0) 122: { 123: okdel1 = okdel; 124: okdel = NO; 125: setvar("@", p->namep); 126: setvar("?", mkqlist(qchain) ); 127: qchain = NULL; 128: if( !questflag ) 129: errstat += docom(lp->shp); 130: setvar("@", (char *) NULL); 131: okdel = okdel1; 132: ptime1 = prestime(); 133: didwork = YES; 134: } 135: } 136: 137: else { 138: if(lp->shp != 0) 139: { 140: if(explcom) 141: fprintf(stderr, "Too many command lines for `%s'\n", 142: p->namep); 143: else explcom = lp->shp; 144: } 145: 146: if(td > tdep) tdep = td; 147: } 148: } 149: 150: /* Look for implicit dependents, using suffix rules */ 151: 152: if (index(p->namep, '(')) { 153: savenamep = p->namep; 154: p->namep = arfname; 155: } 156: 157: for(lp = sufflist ; lp ; lp = lp->nxtlineblock) 158: for(suffp = lp->depp ; suffp ; suffp = suffp->nxtdepblock) 159: { 160: pnamep = suffp->depname->namep; 161: if(suffix(p->namep , pnamep , prefix)) 162: { 163: if (savenamep) 164: pnamep = ".a"; 165: 166: srchdir( concat(prefix,"*",temp), NO, (struct depblock *) NULL); 167: for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock) 168: for(suffp1=lp1->depp ; suffp1 ; suffp1 = suffp1->nxtdepblock) 169: { 170: p1namep = suffp1->depname->namep; 171: if( (p1=srchname(concat(p1namep, pnamep ,concsuff))) && 172: (p2=srchname(concat(prefix, p1namep ,sourcename))) ) 173: { 174: errstat += doname(p2, reclevel+1, &td); 175: if(ptime < td) 176: qchain = appendq(qchain, p2->namep); 177: if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td); 178: if(td > tdep) tdep = td; 179: setvar("*", prefix); 180: if (p2->alias) setvar("<", copys(p2->alias)); 181: else setvar("<", copys(p2->namep)); 182: for(lp2=p1->linep ; lp2 ; lp2 = lp2->nxtlineblock) 183: if(implcom = lp2->shp) break; 184: goto endloop; 185: } 186: } 187: cp = rindex(prefix, '/'); 188: if (cp++ == 0) 189: cp = prefix; 190: setvar("*", cp); 191: } 192: } 193: 194: endloop: 195: if (savenamep) 196: p->namep = savenamep; 197: 198: 199: if(errstat==0 && (ptime<tdep || (ptime==0 && tdep==0) ) ) 200: { 201: ptime = (tdep>0 ? tdep : prestime() ); 202: setvar("@", savenamep ? arfile : p->namep); 203: setvar("?", mkqlist(qchain) ); 204: if(explcom) 205: errstat += docom(explcom); 206: else if(implcom) 207: errstat += docom(implcom); 208: else if(p->septype == 0) 209: if(p1=srchname(".DEFAULT")) 210: { 211: if (p->alias) setvar("<", p->alias); 212: else setvar("<", p->namep); 213: for(lp2 = p1->linep ; lp2 ; lp2 = lp2->nxtlineblock) 214: if(implcom = lp2->shp) 215: { 216: errstat += docom(implcom); 217: break; 218: } 219: } 220: else if(keepgoing) 221: { 222: printf("Don't know how to make %s\n", p->namep); 223: ++errstat; 224: } 225: else 226: fatal1(" Don't know how to make %s", p->namep); 227: 228: setvar("@", (char *) NULL); 229: if(noexflag || (ptime = exists(p)) == 0) 230: ptime = prestime(); 231: } 232: 233: else if(errstat!=0 && reclevel==0) 234: printf("`%s' not remade because of errors\n", p->namep); 235: 236: else if(!questflag && reclevel==0 && didwork==NO) 237: printf("`%s' is up to date.\n", p->namep); 238: 239: if(questflag && reclevel==0) 240: exit(ndocoms>0 ? -1 : 0); 241: 242: p->done = (errstat ? 3 : 2); 243: if(ptime1 > ptime) ptime = ptime1; 244: p->modtime = ptime; 245: *tval = ptime; 246: return(errstat); 247: } 248: 249: docom(q) 250: struct shblock *q; 251: { 252: register char *s; 253: struct varblock *varptr(); 254: register int ign, nopr; 255: char string[OUTMAX]; 256: char string2[OUTMAX]; 257: 258: ++ndocoms; 259: if(questflag) 260: return(NO); 261: 262: if(touchflag) 263: { 264: s = varptr("@")->varval; 265: if(!silflag) 266: printf("touch(%s)\n", s); 267: if(!noexflag) 268: touch(YES, s); 269: } 270: 271: else for( ; q ; q = q->nxtshblock ) 272: { 273: subst(q->shbp,string2); 274: fixname(string2, string); 275: 276: ign = ignerr; 277: nopr = NO; 278: for(s = string ; *s=='-' || *s=='@' ; ++s) 279: if(*s == '-') ign = YES; 280: else nopr = YES; 281: 282: if( docom1(s, ign, nopr) && !ign) 283: if(keepgoing) 284: return(YES); 285: else fatal( (char *) NULL); 286: } 287: return(NO); 288: } 289: 290: 291: 292: docom1(comstring, nohalt, noprint) 293: register char *comstring; 294: int nohalt, noprint; 295: { 296: register int status; 297: 298: if(comstring[0] == '\0') return(0); 299: 300: if(!silflag && (!noprint || noexflag) ) 301: { 302: printf("%s%s\n", (noexflag ? "" : prompt), comstring); 303: fflush(stdout); 304: } 305: 306: if(noexflag) return(0); 307: 308: if( status = dosys(comstring, nohalt) ) 309: { 310: unsigned sig = status & 0177; 311: if( sig ) { 312: if (sig < NSIG && sys_siglist[sig] != NULL && 313: *sys_siglist[sig] != '\0') 314: printf("*** %s", sys_siglist[sig]); 315: else 316: printf("*** Signal %d", sig); 317: if (status & 0200) 318: printf(" - core dumped"); 319: } else 320: printf("*** Exit %d", (status>>8) & 0xff); 321: 322: if(nohalt) printf(" (ignored)\n"); 323: else printf("\n"); 324: fflush(stdout); 325: } 326: 327: return(status); 328: } 329: 330: 331: /* 332: If there are any Shell meta characters in the name, 333: expand into a list, after searching directory 334: */ 335: 336: expand(q) 337: register struct depblock *q; 338: { 339: register char *s; 340: char *s1; 341: struct depblock *p, *srchdir(); 342: 343: if (q->depname == NULL) 344: return; 345: s1 = q->depname->namep; 346: for(s=s1 ; ;) switch(*s++) 347: { 348: case '\0': 349: return; 350: 351: case '*': 352: case '?': 353: case '[': 354: if( p = srchdir(s1 , YES, q->nxtdepblock) ) 355: { 356: q->nxtdepblock = p; 357: q->depname = 0; 358: } 359: return; 360: } 361: }