|
|
1.1 ! root 1: /* %W% */ ! 2: /* @(#)/usr/src/cmd/make/doname.c 3.5 */ ! 3: ! 4: #include "defs" ! 5: #define ONE 0 ! 6: ! 7: ! 8: char Makecall; /* flag which says whether to exec $(MAKE) */ ! 9: extern char archmem[]; ! 10: extern char archname[]; ! 11: ! 12: /* BASIC PROCEDURE. RECURSIVE. */ ! 13: ! 14: /* ! 15: p->done = 0 don't know what to do yet ! 16: p->done = 1 file in process of being updated ! 17: p->done = 2 file already exists in current state ! 18: p->done = 3 file make failed ! 19: */ ! 20: ! 21: ! 22: doname(p, reclevel, tval) ! 23: register NAMEBLOCK p; ! 24: int reclevel; ! 25: TIMETYPE *tval; ! 26: { ! 27: register DEPBLOCK q; ! 28: register LINEBLOCK lp; ! 29: int errstat; ! 30: int okdel1; ! 31: int didwork; ! 32: TIMETYPE td, td1, tdep, ptime, ptime1; ! 33: DEPBLOCK qtemp, suffp, suffp1; ! 34: NAMEBLOCK p1, p2; ! 35: SHBLOCK implcom, explcom; ! 36: LINEBLOCK lp1, lp2; ! 37: char sourcename[100],prefix[100],temp[100],concsuff[20]; ! 38: CHARSTAR pnamep, p1namep; ! 39: CHAIN qchain; ! 40: int found, onetime; ! 41: CHARSTAR savenamep; ! 42: ! 43: if(p == 0) ! 44: { ! 45: *tval = 0; ! 46: return(0); ! 47: } ! 48: ! 49: if(ONE) ! 50: { ! 51: blprt(reclevel); ! 52: printf("doname(%s,%d)\n",p->namep,reclevel); ! 53: fflush(stdout); ! 54: } ! 55: ! 56: if(p->done > 0) ! 57: { ! 58: *tval = p->modtime; ! 59: return(p->done == 3); ! 60: } ! 61: ! 62: errstat = 0; ! 63: tdep = 0; ! 64: implcom = 0; ! 65: explcom = 0; ! 66: ptime = exists(p); ! 67: if(reclevel == 0 && ONE) ! 68: { ! 69: blprt(reclevel); ! 70: printf("TIME(%s)=%ld\n", p->namep, ptime); ! 71: } ! 72: ptime1 = 0; ! 73: didwork = NO; ! 74: p->done = 1; /* avoid infinite loops */ ! 75: ! 76: qchain = NULL; ! 77: ! 78: /* ! 79: * Perform runtime dependency translations. ! 80: */ ! 81: if(p->rundep == 0) ! 82: { ! 83: setvar("@", p->namep); ! 84: dynamicdep(p); ! 85: setvar("@", 0); ! 86: } ! 87: ! 88: /* ! 89: * Expand any names that have embedded metacharaters. Must be ! 90: * done after dynamic dependencies because the dyndep symbols ! 91: * ($(*D)) may contain shell meta characters. ! 92: */ ! 93: expand(p); ! 94: ! 95: ! 96: ! 97: /* ! 98: * FIRST SECTION -- GO THROUGH DEPENDENCIES ! 99: */ ! 100: ! 101: if(ONE) ! 102: { ! 103: blprt(reclevel); ! 104: printf("look for explicit deps. %d \n", reclevel); ! 105: } ! 106: for(lp = p->linep ; lp!=0 ; lp = lp->nextline) ! 107: { ! 108: td = 0; ! 109: for(q = lp->depp ; q!=0 ; q=q->nextdep) ! 110: { ! 111: q->depname->backname = p; ! 112: errstat += doname(q->depname, reclevel+1, &td1); ! 113: if(ONE) ! 114: { ! 115: blprt(reclevel); ! 116: printf("TIME(%s)=%ld\n", q->depname->namep, td1); ! 117: } ! 118: td = max(td1,td); ! 119: if(ptime < td1) ! 120: appendq(&qchain, q->depname->namep); ! 121: } ! 122: if(p->septype == SOMEDEPS) ! 123: { ! 124: if(lp->shp!=0) ! 125: if( ptime<td || (ptime==0 && td==0) || lp->depp==0) ! 126: { ! 127: okdel1 = okdel; ! 128: okdel = NO; ! 129: setvar("@", p->namep); ! 130: if(savenamep) ! 131: setvar("%", archmem); ! 132: setvar("?", mkqlist(qchain) ); ! 133: qchain = NULL; ! 134: if( IS_OFF(QUEST) ) ! 135: { ! 136: ballbat(p, reclevel); ! 137: errstat += docom(lp->shp); ! 138: } ! 139: setvar("@", 0); ! 140: setvar("%", 0); ! 141: okdel = okdel1; ! 142: if( (ptime1 = exists(p)) == 0) ! 143: ptime1 = prestime(); ! 144: didwork = YES; ! 145: } ! 146: } ! 147: ! 148: else ! 149: { ! 150: if(lp->shp != 0) ! 151: { ! 152: if(explcom) ! 153: fprintf(stderr, "Too many command lines for `%s'\n", ! 154: p->namep); ! 155: else ! 156: explcom = lp->shp; ! 157: } ! 158: ! 159: tdep = max(tdep, td); ! 160: } ! 161: } ! 162: ! 163: /* ! 164: * SECOND SECTION -- LOOK FOR IMPLICIT DEPENDENTS ! 165: */ ! 166: ! 167: if(ONE) ! 168: { ! 169: blprt(reclevel); ! 170: printf("look for implicit rules. %d \n", reclevel); ! 171: } ! 172: found = 0; onetime = 0; ! 173: if(any(p->namep, LPAREN)) ! 174: { ! 175: savenamep = p->namep; ! 176: p->namep = copys(archmem); ! 177: if(ONE) ! 178: { ! 179: blprt(reclevel); ! 180: printf("archmem = %s\n", archmem); ! 181: } ! 182: if(ONE) ! 183: { ! 184: blprt(reclevel); ! 185: printf("archname = %s\n", archname); ! 186: } ! 187: } ! 188: else ! 189: savenamep = 0; ! 190: ! 191: ! 192: for(lp=sufflist ; lp!=0 ; lp = lp->nextline) ! 193: for(suffp = lp->depp ; suffp!=0 ; suffp = suffp->nextdep) ! 194: { ! 195: pnamep = suffp->depname->namep; ! 196: if(suffix(p->namep , pnamep , prefix)) ! 197: { ! 198: if(ONE) ! 199: { ! 200: blprt(reclevel); ! 201: printf("right match = %s\n",p->namep); ! 202: } ! 203: found = 1; ! 204: if(savenamep) ! 205: pnamep = ".a"; ! 206: searchdir: ! 207: ! 208: copstr(temp, prefix); ! 209: addstars(temp); ! 210: srchdir( temp , NO, NULL); ! 211: for(lp1 = sufflist ; lp1!=0 ; lp1 = lp1->nextline) ! 212: for(suffp1=lp1->depp ; suffp1!=0 ; suffp1 = suffp1->nextdep) ! 213: { ! 214: p1namep = suffp1->depname->namep; ! 215: concat(p1namep, pnamep, concsuff); ! 216: if( (p1=srchname(concsuff)) == 0) ! 217: continue; ! 218: if(p1->linep == 0) ! 219: continue; ! 220: concat(prefix, p1namep, sourcename); ! 221: if(any(p1namep, WIGGLE)) ! 222: { ! 223: sourcename[strlen(sourcename) - 1] = CNULL; ! 224: if(is_sccs(sourcename) == NO) ! 225: trysccs(sourcename); ! 226: } ! 227: if( (p2=srchname(sourcename)) == 0) ! 228: continue; ! 229: if(equal(sourcename, p->namep)) ! 230: continue; ! 231: /* ! 232: * FOUND -- left and right match ! 233: */ ! 234: ! 235: found = 2; ! 236: if(ONE) ! 237: { ! 238: blprt(reclevel); ! 239: printf("%s ---%s--- %s\n", ! 240: sourcename, concsuff, p->namep); ! 241: } ! 242: p2->backname = p; ! 243: errstat += doname(p2, reclevel+1, &td); ! 244: if(ptime < td) ! 245: appendq(&qchain, p2->namep); ! 246: if(ONE) ! 247: { ! 248: blprt(reclevel); ! 249: printf("TIME(%s)=%ld\n",p2->namep,td); ! 250: } ! 251: tdep = max(tdep, td); ! 252: setvar("*", prefix); ! 253: setvar("<", sourcename); ! 254: for(lp2=p1->linep ; lp2!=0 ; lp2 = lp2->nextline) ! 255: if(implcom = lp2->shp) break; ! 256: goto endloop; ! 257: } ! 258: /* ! 259: * quit search for single suffix rule. ! 260: */ ! 261: if(onetime == 1) ! 262: goto endloop; ! 263: } ! 264: } ! 265: ! 266: endloop: ! 267: ! 268: ! 269: /* ! 270: * look for a single suffix type rule. ! 271: * only possible if no explicit dependents and no shell rules ! 272: * are found, and nothing has been done so far. (previously, `make' ! 273: * would exit with 'Don't know how to make ...' message. ! 274: */ ! 275: if(found == 0) ! 276: if(onetime == 0) ! 277: if( p->linep == 0 || ! 278: ( p->linep->depp == 0 && p->linep->shp == 0)) ! 279: { ! 280: onetime = 1; ! 281: if(ONE) ! 282: { ! 283: blprt(reclevel); ! 284: printf("Looking for Single suffix rule.\n"); ! 285: } ! 286: concat(p->namep, "", prefix); ! 287: pnamep = ""; ! 288: goto searchdir; ! 289: } ! 290: ! 291: ! 292: /* ! 293: * THIRD SECTION -- LOOK FOR DEFAULT CONDITION OR DO COMMAND ! 294: */ ! 295: if(errstat==0 && (ptime<tdep || (ptime==0 && tdep==0) ) ) ! 296: { ! 297: if(savenamep) ! 298: { ! 299: setvar("@", archname); ! 300: setvar("%", archmem); ! 301: } ! 302: else ! 303: { ! 304: setvar("@", p->namep); ! 305: } ! 306: setvar("?", mkqlist(qchain) ); ! 307: ballbat(p, reclevel); ! 308: if(explcom) ! 309: errstat += docom(explcom); ! 310: else if(implcom) ! 311: errstat += docom(implcom); ! 312: else if( (p->septype != SOMEDEPS && IS_OFF(MH_DEP)) || ! 313: (p->septype == 0 && IS_ON(MH_DEP) ) ) ! 314: /* ! 315: * OLD WAY OF DOING TEST is ! 316: * else if(p->septype == 0) ! 317: * notice above, a flag has been put in to get the murray hill version. ! 318: * the flag is "-b" (for botch). ! 319: */ ! 320: if(p1=srchname(".DEFAULT")) ! 321: { ! 322: if(ONE) ! 323: { ! 324: blprt(reclevel); ! 325: printf("look for DEFAULT rule. %d \n", reclevel); ! 326: } ! 327: setvar("<", p->namep); ! 328: for(lp2=p1->linep ; lp2!=0 ; lp2 = lp2->nextline) ! 329: if(implcom = lp2->shp) ! 330: { ! 331: errstat += docom(implcom); ! 332: } ! 333: } ! 334: else if(IS_OFF(GET) || ! 335: !get(p->namep, NOCD, 0) ) ! 336: { ! 337: fatal1(" Don't know how to make %s", p->namep); ! 338: } ! 339: ! 340: setvar("@", 0); ! 341: setvar("%", 0); ! 342: if(IS_ON(NOEX) || (ptime = exists(p)) == 0) ! 343: ptime = prestime(); ! 344: } ! 345: ! 346: else if(errstat!=0 && reclevel==0) ! 347: printf("`%s' not remade because of errors\n", p->namep); ! 348: ! 349: else if(IS_OFF(QUEST) && reclevel==0 && didwork==NO) ! 350: printf("`%s' is up to date.\n", p->namep); ! 351: ! 352: if(IS_ON(QUEST) && reclevel==0) ! 353: exit(ndocoms>0 ? -1 : 0); ! 354: ! 355: p->done = (errstat ? 3 : 2); ! 356: ptime = max(ptime1, ptime); ! 357: p->modtime = ptime; ! 358: *tval = ptime; ! 359: setvar("<", 0); ! 360: setvar("*", 0); ! 361: return(errstat); ! 362: } ! 363: ! 364: docom(q) ! 365: SHBLOCK q; ! 366: { ! 367: CHARSTAR s; ! 368: int status; ! 369: int ign, nopr; ! 370: char string[OUTMAX]; ! 371: ! 372: ++ndocoms; ! 373: if(IS_ON(QUEST)) ! 374: return(0); ! 375: ! 376: if(IS_ON(TOUCH)) ! 377: { ! 378: s = varptr("@")->varval; ! 379: if(IS_OFF(SIL)) ! 380: printf("touch(%s)\n", s); ! 381: if(IS_OFF(NOEX)) ! 382: touch(1,s); ! 383: } ! 384: ! 385: else for( status = 0; q!=0 ; q = q->nextsh ) ! 386: { ! 387: /* ! 388: * Allow recursive makes to execute only if the NOEX flag set ! 389: */ ! 390: if(sindex(q->shbp, "$(MAKE)") != -1 && IS_ON(NOEX)) ! 391: Makecall = YES; ! 392: else ! 393: Makecall = NO; ! 394: subst(q->shbp,string); ! 395: ! 396: ign = IS_ON(IGNERR) ? YES : NO; ! 397: nopr = NO; ! 398: for(s = string ; *s==MINUS || *s==AT ; ++s) ! 399: if(*s == MINUS) ign = YES; ! 400: else nopr = YES; ! 401: ! 402: if( docom1(s, ign, nopr) && !ign) ! 403: if(IS_ON(KEEPGO)) ! 404: return(1); ! 405: else fatal(0); ! 406: } ! 407: return(0); ! 408: } ! 409: ! 410: ! 411: ! 412: docom1(comstring, nohalt, noprint) ! 413: register CHARSTAR comstring; ! 414: int nohalt, noprint; ! 415: { ! 416: register int status; ! 417: ! 418: if(comstring[0] == '\0') return(0); ! 419: ! 420: if(IS_OFF(SIL) && (!noprint || IS_ON(NOEX)) ) ! 421: { ! 422: CHARSTAR p1, ps; ! 423: CHARSTAR pmt = prompt; ! 424: ! 425: ps = p1 = comstring; ! 426: while(1) ! 427: { ! 428: while(*p1 && *p1 != NEWLINE) p1++; ! 429: if(*p1) ! 430: { ! 431: *p1 = 0; ! 432: printf("%s%s\n", pmt, ps); ! 433: *p1 = NEWLINE; ! 434: ps = p1 + 1; ! 435: p1 = ps; ! 436: } ! 437: else ! 438: { ! 439: printf("%s%s\n", pmt, ps); ! 440: break; ! 441: } ! 442: } ! 443: ! 444: fflush(stdout); ! 445: } ! 446: ! 447: if( status = dosys(comstring, nohalt) ) ! 448: { ! 449: if( status>>8 ) ! 450: printf("*** Error code %d", status>>8 ); ! 451: else printf("*** Termination code %d", status ); ! 452: ! 453: if(nohalt) printf(" (ignored)\n"); ! 454: else printf("\n"); ! 455: fflush(stdout); ! 456: } ! 457: ! 458: return(status); ! 459: } ! 460: ! 461: ! 462: /* ! 463: * If there are any Shell meta characters in the name, ! 464: * search the directory, and if the search finds something ! 465: * replace the dependency in "p"'s dependency chain. srchdir ! 466: * produces a DEPBLOCK chain whose last member has a null ! 467: * nextdep pointer or the NULL pointer if it finds nothing. ! 468: * The loops below do the following: for each dep in each line ! 469: * if the dep->depname has a shell metacharacter in it and ! 470: * if srchdir succeeds, replace the dep with the new one ! 471: * created by srchdir. The Nextdep variable is to skip over ! 472: * the new stuff inserted into the chain. ! 473: */ ! 474: ! 475: expand(p) ! 476: NAMEBLOCK p; ! 477: { ! 478: register DEPBLOCK db; ! 479: register DEPBLOCK Nextdep; ! 480: register CHARSTAR s; ! 481: register DEPBLOCK srchdb; ! 482: register LINEBLOCK lp; ! 483: ! 484: ! 485: ! 486: for(lp = p->linep ; lp!=0 ; lp = lp->nextline) ! 487: for(db=lp->depp ; db!=0 ; db=Nextdep ) ! 488: { ! 489: Nextdep = db->nextdep; ! 490: if(any( (s=db->depname->namep), STAR) || ! 491: any(s, QUESTN) || any(s, LSQUAR) ) ! 492: if( srchdb = srchdir(s , YES, NULL) ) ! 493: dbreplace(p, db, srchdb); ! 494: } ! 495: } ! 496: /* ! 497: * Replace the odb depblock in np's dependency list with the ! 498: * dependency chain defined by ndb. This is just a linked list insert ! 499: * problem. dbreplace assumes the last "nextdep" pointer in ! 500: * "ndb" is null. ! 501: */ ! 502: dbreplace(np, odb, ndb) ! 503: register NAMEBLOCK np; ! 504: register DEPBLOCK odb, ndb; ! 505: { ! 506: register LINEBLOCK lp; ! 507: register DEPBLOCK db; ! 508: register DEPBLOCK enddb; ! 509: ! 510: for(enddb = ndb; enddb->nextdep; enddb = enddb->nextdep); ! 511: ! 512: for(lp = np->linep; lp; lp = lp->nextline) ! 513: if(lp->depp == odb) ! 514: { ! 515: enddb->nextdep = lp->depp->nextdep; ! 516: lp->depp = ndb; ! 517: return; ! 518: } ! 519: else ! 520: { ! 521: for(db = lp->depp; db; db = db->nextdep) ! 522: if(db->nextdep == odb) ! 523: { ! 524: enddb->nextdep = odb->nextdep; ! 525: db->nextdep = ndb; ! 526: return; ! 527: } ! 528: } ! 529: } ! 530: ! 531: ! 532: #define NPREDS 50 ! 533: ! 534: ballbat(np, reclevel) ! 535: NAMEBLOCK np; ! 536: { ! 537: static char ballb[200]; ! 538: register CHARSTAR p; ! 539: register NAMEBLOCK npp; ! 540: register int i; ! 541: VARBLOCK vp; ! 542: int npreds=0; ! 543: NAMEBLOCK circles[NPREDS]; ! 544: ! 545: ! 546: if( (vp=varptr("!"))->varval == 0) ! 547: vp->varval = ballb; ! 548: p = ballb; ! 549: p = copstr(p, varptr("<")->varval); ! 550: p = copstr(p, " "); ! 551: for(npp = np; npp; npp = npp->backname) ! 552: { ! 553: for(i = 0; i < npreds; i++) ! 554: { ! 555: if(npp == circles[i]) ! 556: { ! 557: fprintf(stderr,"$! nulled, predecessor circle\n"); ! 558: ballb[0] = CNULL; ! 559: return; ! 560: } ! 561: } ! 562: circles[npreds++] = npp; ! 563: if(npreds >= NPREDS) ! 564: { ! 565: fprintf(stderr, "$! nulled, too many predecessors\n"); ! 566: ballb[0] = CNULL; ! 567: return; ! 568: } ! 569: p = copstr(p, npp->namep); ! 570: p = copstr(p, " "); ! 571: } ! 572: } ! 573: ! 574: /* ! 575: * PRINT n BLANKS WHERE n IS THE CURRENT RECURSION LEVEL. ! 576: */ ! 577: blprt(n) ! 578: register int n; ! 579: { ! 580: while(n--) ! 581: printf(" "); ! 582: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.