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