|
|
1.1 ! root 1: /* @(#)/usr/src/cmd/make/misc.c 3.4 */ ! 2: ! 3: /* @(#)misc.c 3.2 */ ! 4: ! 5: #include "defs" ! 6: #include "ctype.h" ! 7: ! 8: ! 9: ! 10: FSTATIC CHARSTAR nextchar=0; ! 11: FSTATIC CHARSTAR lastchar=0; ! 12: ! 13: FSTATIC int *nextint=0; ! 14: FSTATIC int *lastint=0; ! 15: ! 16: FSTATIC NAMEBLOCK hashtab[HASHSIZE]; ! 17: int nhashed=0; ! 18: ! 19: ! 20: /* simple linear hash. hash function is sum of ! 21: characters mod hash table size. ! 22: */ ! 23: hashloc(s) ! 24: CHARSTAR s; ! 25: { ! 26: register int i; ! 27: register int hashval; ! 28: register CHARSTAR t; ! 29: ! 30: hashval = 0; ! 31: ! 32: for(t=s; *t!=CNULL ; ++t) ! 33: hashval += *t; ! 34: ! 35: hashval %= HASHSIZE; ! 36: ! 37: for(i=hashval; ! 38: hashtab[i]!=0 && !equal(s,hashtab[i]->namep); ! 39: i = (i+1)%HASHSIZE ) ; ! 40: ! 41: return(i); ! 42: } ! 43: ! 44: ! 45: NAMEBLOCK srchname(s) ! 46: register CHARSTAR s; ! 47: { ! 48: return( hashtab[hashloc(s)] ); ! 49: } ! 50: ! 51: ! 52: ! 53: ! 54: NAMEBLOCK makename(s) ! 55: register CHARSTAR s; ! 56: { ! 57: /* make a name entry; `s' is presumed to already to have been saved */ ! 58: ! 59: register NAMEBLOCK p; ! 60: register CHARSTAR t; ! 61: ! 62: if(nhashed++ > HASHSIZE-3) ! 63: fatal("Hash table overflow"); ! 64: ! 65: p = ALLOC(nameblock); ! 66: p->nextname = firstname; ! 67: p->backname = NULL; ! 68: ! 69: p->namep = s; ! 70: p->linep = 0; ! 71: p->done = 0; ! 72: p->septype = 0; ! 73: p->rundep = 0; ! 74: p->modtime = 0; ! 75: ! 76: firstname = p; ! 77: ! 78: hashtab[hashloc(s)] = p; ! 79: ! 80: return(p); ! 81: } ! 82: ! 83: ! 84: ! 85: ! 86: ! 87: ! 88: ! 89: #define NOTSHORT sizeof (struct nameblock) ! 90: ! 91: extern CHARSTAR end; /* loader value of end of core */ ! 92: ! 93: CHARSTAR copys(s) ! 94: register CHARSTAR s; ! 95: { ! 96: register CHARSTAR t; ! 97: register struct ! 98: { ! 99: int i_i; ! 100: CHARSTAR i_s; ! 101: } i; ! 102: ! 103: i.i_i = strlen(s) + 1; ! 104: if(i.i_i > NOTSHORT) ! 105: { ! 106: i.i_i = (i.i_i + 1)&~1; ! 107: t = (CHARSTAR )calloc(i.i_i, sizeof (*s)); ! 108: if(t == NULL) ! 109: goto fat; ! 110: i.i_s = t; ! 111: while(*t++ = *s++); ! 112: return(i.i_s); ! 113: } ! 114: ! 115: if( i.i_i >= (lastchar-nextchar) ) ! 116: { ! 117: i.i_i = (i.i_i + 1)&~1; ! 118: if( (nextchar=(CHARSTAR )calloc(i.i_i, sizeof (*s) )) == NULL) ! 119: fat: ! 120: fatal("Cannot allocate memory"); ! 121: lastchar = nextchar + i.i_i; ! 122: } ! 123: ! 124: t = nextchar; ! 125: while(*nextchar++ = *s++); ! 126: return(t); ! 127: } ! 128: ! 129: ! 130: CHARSTAR concat(a,b,c) /* c = concatenation of a and b */ ! 131: register CHARSTAR a, b; ! 132: register CHARSTAR c; ! 133: { ! 134: register CHARSTAR t; ! 135: t = c; ! 136: ! 137: while(*t = *a++) t++; ! 138: while(*t++ = *b++); ! 139: return(c); ! 140: } ! 141: ! 142: suffix(a,b,p) /* is b the suffix of a? if so, set p = prefix */ ! 143: register CHARSTAR a, b, p; ! 144: { ! 145: CHARSTAR a0, b0; ! 146: a0 = a; ! 147: b0 = b; ! 148: ! 149: if(!a || !b) ! 150: return(0); ! 151: ! 152: while(*a++); ! 153: while(*b++); ! 154: ! 155: if( (a-a0) < (b-b0) ) ! 156: return(0); ! 157: ! 158: while(b>b0) ! 159: if(*--a != *--b) ! 160: return(0); ! 161: ! 162: while(a0<a) ! 163: *p++ = *a0++; ! 164: *p = CNULL; ! 165: ! 166: return(1); ! 167: } ! 168: ! 169: ! 170: ! 171: int *intalloc(n) ! 172: register int n; ! 173: { ! 174: register INTSTAR p; ! 175: ! 176: if( p = (int *) calloc(1,n) ) ! 177: return(p); ! 178: ! 179: fatal("out of memory"); ! 180: } ! 181: ! 182: /* copy string a into b, substituting for arguments */ ! 183: extern NAMEBLOCK cur_name; ! 184: ! 185: CHARSTAR subst(a,b) ! 186: register CHARSTAR a, b; ! 187: { ! 188: register CHARSTAR s; ! 189: register VARBLOCK vbp; ! 190: static depth=0; ! 191: char vname[100]; ! 192: char closer; ! 193: ! 194: if(++depth > 100) ! 195: fatal("infinitely recursive macro?"); ! 196: if(a!=0) ! 197: { ! 198: while(*a) ! 199: { ! 200: if(*a != DOLLAR) ! 201: *b++ = *a++; ! 202: else if(*++a==CNULL || *a==DOLLAR) ! 203: *b++ = *a++; ! 204: else ! 205: { ! 206: s = vname; ! 207: if( *a==LPAREN || *a==LCURLY ) ! 208: { ! 209: closer=(*a==LPAREN ? RPAREN : RCURLY); ! 210: ++a; ! 211: while(*a == BLANK) ! 212: ++a; ! 213: while( *a!=BLANK && ! 214: *a!=closer && ! 215: *a!=CNULL) ! 216: *s++ = *a++; ! 217: while(*a!=closer && *a!=CNULL) ! 218: ++a; ! 219: if(*a == closer) ! 220: ++a; ! 221: } ! 222: else ! 223: *s++ = *a++; ! 224: ! 225: *s = CNULL; ! 226: if(amatch(&vname[0], "*:*=*")) ! 227: { ! 228: b = colontrans(b, vname); ! 229: } ! 230: else if(amatch(vname, "[@*<%][DF]")) ! 231: { ! 232: b = dftrans(b, vname); ! 233: } ! 234: else ! 235: { ! 236: b = straightrans(b, vname); ! 237: } ! 238: } ! 239: } ! 240: } ! 241: ! 242: *b = CNULL; ! 243: --depth; ! 244: return(b); ! 245: } ! 246: ! 247: ! 248: /* ! 249: * Translate the $(name:*=*) type things. ! 250: */ ! 251: ! 252: CHARSTAR colontrans(b, vname) ! 253: register CHARSTAR b; ! 254: char vname[]; ! 255: { ! 256: register int i; ! 257: register CHARSTAR ps1; ! 258: int fromlen; ! 259: char from[30], to[70]; ! 260: char dftemp[128]; ! 261: char tmp, nextchr; ! 262: CHARSTAR psave, pcolon; ! 263: VARBLOCK vbp; ! 264: ! 265: /* ! 266: * Mark off the name (up to colon), the from expression (up to '='), ! 267: * and the to expresion (up to CNULL). ! 268: */ ! 269: i = 0; ! 270: for(ps1 = &vname[0]; *ps1 != KOLON; ps1++); ! 271: pcolon = ps1; ! 272: *pcolon = CNULL; ! 273: while(*++ps1 != EQUALS) ! 274: from[i++] = *ps1; ! 275: from[i] = CNULL; ! 276: fromlen = i; ! 277: i = 0; ! 278: while(*++ps1) ! 279: to[i++] = *ps1; ! 280: to[i] = CNULL; ! 281: ! 282: /* ! 283: * Now, tanslate. ! 284: */ ! 285: ! 286: if(amatch(vname, "[@*<%][DF]")) ! 287: { ! 288: dftrans(dftemp, vname); ! 289: ps1 = dftemp; ! 290: } ! 291: else ! 292: { ! 293: if((vbp = srchvar(vname)) == NULL) ! 294: { ! 295: return(b); ! 296: } ! 297: ps1 = vbp->varval; ! 298: } ! 299: if(ps1 != NULL && *ps1 != NULL) ! 300: { ! 301: psave = ps1; ! 302: while((i = sindex(ps1, from)) >= 0) ! 303: { ! 304: ps1 = &ps1[i]; ! 305: tmp = *ps1; ! 306: *ps1 = CNULL; ! 307: nextchr = *(ps1+fromlen); ! 308: if( nextchr == TAB || ! 309: nextchr == BLANK || ! 310: nextchr == CNULL) ! 311: { ! 312: b = copstr(b, psave); ! 313: b = copstr(b, to); ! 314: *ps1 = tmp; ! 315: ps1 += fromlen; ! 316: } ! 317: else ! 318: { ! 319: b = copstr(b, psave); ! 320: *b++ = tmp; ! 321: *ps1 = tmp; ! 322: ps1++; ! 323: } ! 324: psave = ps1; ! 325: } ! 326: b = copstr(b, ps1); ! 327: } ! 328: *pcolon = KOLON; ! 329: return(b); ! 330: } ! 331: ! 332: /* ! 333: * Do the $(@D) type translations. ! 334: */ ! 335: ! 336: CHARSTAR dftrans(b, vname) ! 337: register CHARSTAR b; ! 338: char vname[]; ! 339: { ! 340: char c, c1; ! 341: CHARSTAR p1, p2; ! 342: VARBLOCK vbp; ! 343: ! 344: c1 = vname[1]; ! 345: vname[1] = CNULL; ! 346: vbp = srchvar(vname); ! 347: if(vbp != 0 && vbp->varval != 0) ! 348: { ! 349: for(p1=p2=vbp->varval;*p1;p1++) ! 350: if(*p1 == SLASH) ! 351: p2 = p1; ! 352: if(*p2 == SLASH) ! 353: { ! 354: if(c1 == 'D') ! 355: { ! 356: if(p2 == vbp->varval) ! 357: p2++; ! 358: c = *p2; ! 359: *p2 = CNULL; ! 360: b = copstr(b,vbp->varval); ! 361: *p2 = c; ! 362: } ! 363: else ! 364: { ! 365: b = copstr(b, p2+1); ! 366: } ! 367: } ! 368: else ! 369: { ! 370: if(c1 == 'D') ! 371: b = copstr(b, "."); ! 372: else ! 373: b = copstr(b, p2); ! 374: } ! 375: } ! 376: vname[1] = c1; ! 377: return(b); ! 378: } ! 379: ! 380: ! 381: /* ! 382: * Standard trnaslation, nothing fancy. ! 383: */ ! 384: ! 385: CHARSTAR straightrans(b, vname) ! 386: register CHARSTAR b; ! 387: char vname[]; ! 388: { ! 389: register VARBLOCK vbp; ! 390: register CHAIN pchain; ! 391: register NAMEBLOCK pn; ! 392: ! 393: vbp = srchvar(vname); ! 394: if( vbp != 0 && vbp->varval != 0) ! 395: { ! 396: if(vbp->v_aflg == YES) ! 397: { ! 398: pchain = (CHAIN)vbp->varval; ! 399: for(; pchain; pchain = pchain->nextchain) ! 400: { ! 401: pn = (NAMEBLOCK)pchain->datap; ! 402: if(pn->alias) ! 403: b=copstr(b, pn->alias); ! 404: else ! 405: b=copstr(b,pn->namep); ! 406: *b++ = BLANK; ! 407: } ! 408: } ! 409: else ! 410: { ! 411: b = subst(vbp->varval, b); ! 412: } ! 413: vbp->used = YES; ! 414: } ! 415: return(b); ! 416: } ! 417: ! 418: ! 419: ! 420: /* copy s into t, return the location of the next free character in s */ ! 421: CHARSTAR copstr(s, t) ! 422: register CHARSTAR s, t; ! 423: { ! 424: if(t == 0) ! 425: return(s); ! 426: while (*t) ! 427: *s++ = *t++; ! 428: *s = CNULL; ! 429: return(s); ! 430: } ! 431: ! 432: setvar(v,s) ! 433: register CHARSTAR v, s; ! 434: { ! 435: register VARBLOCK p; ! 436: ! 437: p = srchvar(v); ! 438: if(p == 0) ! 439: { ! 440: p = varptr(v); ! 441: } ! 442: if (p->noreset == NO) ! 443: { ! 444: if(IS_ON(EXPORT)) ! 445: p->envflg = YES; ! 446: p->varval = s; ! 447: if(IS_ON(INARGS) || IS_ON(ENVOVER)) ! 448: p->noreset = YES; ! 449: else ! 450: p->noreset = NO; ! 451: if(IS_ON(DBUG))printf("setvar: %s = %s noreset = %d envflg = %d Mflags = 0%o\n", ! 452: v, p->varval, p->noreset, p->envflg, Mflags); ! 453: ! 454: if(p->used && !amatch(v, "[@*<?!%]") ) ! 455: if(IS_ON(DBUG)) ! 456: fprintf(stderr, "Warning: %s changed after being used\n",v); ! 457: } ! 458: } ! 459: ! 460: ! 461: eqsign(a) ! 462: register CHARSTAR a; ! 463: { ! 464: register CHARSTAR p; ! 465: ! 466: for(p = ":;=$\n\t"; *p; p++) ! 467: if(any(a, *p)) ! 468: { ! 469: callyacc(a); ! 470: return(YES); ! 471: } ! 472: return(NO); ! 473: } ! 474: ! 475: ! 476: VARBLOCK varptr(v) ! 477: register CHARSTAR v; ! 478: { ! 479: register VARBLOCK vp; ! 480: ! 481: if((vp = srchvar(v)) != 0) ! 482: return(vp); ! 483: ! 484: vp = ALLOC(varblock); ! 485: vp->nextvar = firstvar; ! 486: firstvar = vp; ! 487: vp->varname = copys(v); ! 488: vp->varval = 0; ! 489: return(vp); ! 490: } ! 491: ! 492: VARBLOCK srchvar(vname) ! 493: register CHARSTAR vname; ! 494: { ! 495: register VARBLOCK vp; ! 496: ! 497: for(vp=firstvar; vp != 0 ; vp = vp->nextvar) ! 498: if(equal(vname, vp->varname)) ! 499: return(vp); ! 500: return(NO); ! 501: } ! 502: ! 503: ! 504: fatal1(s,t) ! 505: CHARSTAR s, t; ! 506: { ! 507: char buf[100]; ! 508: sprintf(buf, s, t); ! 509: fatal(buf); ! 510: } ! 511: ! 512: ! 513: ! 514: fatal(s) ! 515: CHARSTAR s; ! 516: { ! 517: if(s) ! 518: fprintf(stderr, "Make: %s. Stop.\n", s); ! 519: else ! 520: fprintf(stderr, "\nStop.\n"); ! 521: #ifdef unix ! 522: exit(1); ! 523: #endif ! 524: #ifdef gcos ! 525: exit(0); ! 526: #endif ! 527: } ! 528: ! 529: ! 530: ! 531: yyerror(s) ! 532: CHARSTAR s; ! 533: { ! 534: char buf[50]; ! 535: extern int yylineno; ! 536: ! 537: sprintf(buf, "line %d: %s", yylineno, s); ! 538: fatal(buf); ! 539: } ! 540: ! 541: ! 542: ! 543: CHAIN appendq(head,tail) ! 544: register CHAIN head; ! 545: register CHARSTAR tail; ! 546: { ! 547: register CHAIN p; ! 548: ! 549: p = ALLOC(chain); ! 550: p->datap = tail; ! 551: while(head->nextchain) ! 552: head = head->nextchain; ! 553: head->nextchain = p; ! 554: } ! 555: ! 556: ! 557: ! 558: ! 559: ! 560: CHARSTAR mkqlist(p) ! 561: register CHAIN p; ! 562: { ! 563: register CHARSTAR qbufp, s; ! 564: static char qbuf[OUTMAX]; ! 565: ! 566: qbufp = qbuf; ! 567: ! 568: for( ; p ; p = p->nextchain) ! 569: { ! 570: s = p->datap; ! 571: if(qbufp != qbuf) ! 572: *qbufp++ = BLANK; ! 573: if(qbufp+strlen(s) > &qbuf[OUTMAX-3]) ! 574: { ! 575: fprintf(stderr, "$? list too long\n"); ! 576: break; ! 577: } ! 578: while (*s) ! 579: *qbufp++ = *s++; ! 580: } ! 581: *qbufp = CNULL; ! 582: return(qbuf); ! 583: } ! 584: ! 585: any(s,c) ! 586: register CHARSTAR s; ! 587: register char c; ! 588: { ! 589: register char d; ! 590: ! 591: while(d = *s++) ! 592: { ! 593: if(d==c) ! 594: return(1); ! 595: } ! 596: return(0); ! 597: } ! 598: ! 599: ! 600: sindex(s1,s2) ! 601: CHARSTAR s1; ! 602: CHARSTAR s2; ! 603: { ! 604: register CHARSTAR p1; ! 605: register CHARSTAR p2; ! 606: register int flag; ! 607: int ii; ! 608: ! 609: p1 = &s1[0]; ! 610: p2 = &s2[0]; ! 611: flag = -1; ! 612: for(ii = 0; ; ii++) ! 613: { ! 614: while(*p1 == *p2) ! 615: { ! 616: if(flag < 0) ! 617: flag = ii; ! 618: if(*p1++ == CNULL) ! 619: return(flag); ! 620: p2++; ! 621: } ! 622: if(*p2 == CNULL) ! 623: return(flag); ! 624: if(flag >= 0) ! 625: { ! 626: flag = -1; ! 627: p2 = &s2[0]; ! 628: } ! 629: if(*s1++ == CNULL) ! 630: return(flag); ! 631: p1 = s1; ! 632: } ! 633: } ! 634: ! 635: ! 636: #include "sys/types.h" ! 637: #include "sys/stat.h" ! 638: ! 639: /* ! 640: * findfl(name) (like execvp, but does path search and finds files) ! 641: */ ! 642: static char fname[128]; ! 643: ! 644: char *execat(); ! 645: ! 646: CHARSTAR findfl(name) ! 647: register CHARSTAR name; ! 648: { ! 649: register CHARSTAR p; ! 650: register VARBLOCK cp; ! 651: ! 652: if(name[0] == SLASH) ! 653: return(name); ! 654: cp = varptr("VPATH"); ! 655: if(cp->varval == 0) ! 656: p = ":"; ! 657: else ! 658: p = cp->varval; ! 659: ! 660: do ! 661: { ! 662: p = execat(p, name, fname); ! 663: if(access(fname, 4) == 0) ! 664: return(fname); ! 665: } while (p); ! 666: return((CHARSTAR )-1); ! 667: } ! 668: ! 669: CHARSTAR execat(s1, s2, si) ! 670: register CHARSTAR s1, s2; ! 671: CHARSTAR si; ! 672: { ! 673: register CHARSTAR s; ! 674: ! 675: s = si; ! 676: while (*s1 && *s1 != KOLON && *s1 != MINUS) ! 677: *s++ = *s1++; ! 678: if (si != s) ! 679: *s++ = SLASH; ! 680: while (*s2) ! 681: *s++ = *s2++; ! 682: *s = CNULL; ! 683: return(*s1? ++s1: 0); ! 684: } ! 685: ! 686: ! 687: /* ! 688: * change xx to s.xx or /x/y/z to /x/y/s.z ! 689: */ ! 690: CHARSTAR trysccs(str) ! 691: register CHARSTAR str; ! 692: { ! 693: register CHARSTAR sstr; ! 694: register int i = 2; ! 695: ! 696: sstr = str; ! 697: for(; *str; str++); ! 698: str[2] = CNULL; ! 699: str--; ! 700: for(;str >= sstr; str--) ! 701: { ! 702: if(*str == SLASH) ! 703: if(i == 2) ! 704: { ! 705: i = 0; ! 706: *(str+2) = DOT; ! 707: *(str+1) = 's'; ! 708: } ! 709: *(str+i) = *str; ! 710: } ! 711: if(i == 2) ! 712: { ! 713: *(str+2) = DOT; ! 714: *(str+1) = 's'; ! 715: } ! 716: return(sstr); ! 717: } ! 718: ! 719: ! 720: is_sccs(filename) ! 721: register CHARSTAR filename; ! 722: { ! 723: register CHARSTAR p; ! 724: ! 725: for(p = filename; *p; p++) ! 726: if(*p == 's') ! 727: if(p == filename && p[1] == DOT) ! 728: return(YES); ! 729: else if(p[-1] == SLASH && p[1] == DOT) ! 730: return(YES); ! 731: return(NO); ! 732: } ! 733: ! 734: /* ! 735: * change pfx to /xxx/yy/*zz.* or *zz.* ! 736: */ ! 737: CHARSTAR addstars(pfx) ! 738: register CHARSTAR pfx; ! 739: { ! 740: register CHARSTAR p1, p2; ! 741: ! 742: for(p1 = pfx; *p1; p1++); ! 743: p2 = p1 + 3; /* 3 characters, '*', '.', and '*'. */ ! 744: p1--; ! 745: ! 746: *p2-- = CNULL; ! 747: *p2-- = STAR; ! 748: *p2-- = DOT; ! 749: while(p1 >= pfx) ! 750: { ! 751: if(*p1 == SLASH) ! 752: { ! 753: *p2 = STAR; ! 754: return(pfx); ! 755: } ! 756: *p2-- = *p1--; ! 757: } ! 758: *p2 = STAR; ! 759: return(p2); ! 760: } ! 761: ! 762: ! 763: #define NENV 300 ! 764: extern CHARSTAR *environ; ! 765: ! 766: /* ! 767: * This routine is called just before and exec. ! 768: */ ! 769: ! 770: setenv() ! 771: { ! 772: register CHARSTAR *ea; ! 773: register int nenv = 0; ! 774: register CHARSTAR p; ! 775: CHARSTAR *es; ! 776: VARBLOCK vp; ! 777: int length; ! 778: ! 779: if(firstvar == 0) ! 780: return; ! 781: ! 782: es=ea=(CHARSTAR *)calloc(NENV, sizeof *ea); ! 783: if(es == (CHARSTAR *)-1) ! 784: fatal("Cannot alloc mem for envp."); ! 785: ! 786: for(vp=firstvar; vp != 0; vp=vp->nextvar) ! 787: if(vp->envflg) ! 788: { ! 789: if(++nenv >= NENV) ! 790: fatal("Too many env parameters."); ! 791: length = strlen(vp->varname) + strlen(vp->varval) + 2; ! 792: if((*ea = (CHARSTAR )calloc(length, sizeof **ea)) == (CHARSTAR )-1) ! 793: fatal("Cannot alloc mem for env."); ! 794: p = copstr(*ea++, vp->varname); ! 795: p = copstr(p, "="); ! 796: p = copstr(p, vp->varval); ! 797: } ! 798: *ea = 0; ! 799: if(nenv > 0) ! 800: environ=es; ! 801: if(IS_ON(DBUG)) ! 802: printf("nenv = %d\n", nenv); ! 803: } ! 804: ! 805: ! 806: /* ! 807: * Called in main ! 808: * If a string like "CC=" occurs then CC is not put in environment. ! 809: * This is because there is no good way to remove a variable ! 810: * from the environment within the shell. ! 811: */ ! 812: ! 813: readenv() ! 814: { ! 815: register CHARSTAR *ea; ! 816: register CHARSTAR p; ! 817: ! 818: ea=environ; ! 819: for(;*ea; ea++) ! 820: { ! 821: for(p = *ea; *p && *p != EQUALS; p++); ! 822: if(*p == EQUALS) ! 823: if(*(p+1)) ! 824: eqsign(*ea); ! 825: } ! 826: } ! 827: ! 828: ! 829: sccstrip(pstr) ! 830: register CHARSTAR pstr; ! 831: { ! 832: register CHARSTAR p2; ! 833: register CHARSTAR sstr; ! 834: ! 835: sstr = pstr; ! 836: for(; *pstr ; pstr++) ! 837: if(*pstr == RCURLY) ! 838: { ! 839: if(isdigit(pstr[1])) ! 840: if(pstr != sstr) ! 841: if(pstr[-1] != DOLLAR) ! 842: { ! 843: for(p2 = pstr; *p2 && (*p2 != LCURLY); p2++); ! 844: if(*p2 == CNULL) ! 845: break; ! 846: strshift(pstr, -(int)(p2-pstr+1) ); ! 847: } ! 848: } ! 849: } ! 850: ! 851: /* ! 852: * Shift a string `pstr' count places. negative is left, pos is right ! 853: * Negative shifts cause char's at front to be lost. ! 854: * Positive shifts assume enough space! ! 855: */ ! 856: CHARSTAR strshift(pstr, count) ! 857: register CHARSTAR pstr; ! 858: register int count; ! 859: { ! 860: register CHARSTAR sstr; ! 861: ! 862: sstr = pstr; ! 863: if(count < 0) ! 864: { ! 865: count = -count; ! 866: while(pstr[count]) ! 867: *pstr = pstr++[count]; ! 868: *pstr = 0; ! 869: return(sstr); ! 870: } ! 871: for(; *pstr; pstr++); ! 872: pstr--[count] = 0; ! 873: while(pstr != sstr) ! 874: pstr[count] = *pstr--; ! 875: pstr[count] = *pstr; ! 876: ! 877: return(sstr); ! 878: ! 879: } ! 880: ! 881: ! 882: /* ! 883: * execlp(name, arg,...,0) (like execl, but does path search) ! 884: * execvp(name, argv) (like execv, but does path search) ! 885: */ ! 886: #include <errno.h> ! 887: ! 888: CHARSTAR execat(); ! 889: extern errno; ! 890: ! 891: execlp(name, argv) ! 892: CHARSTAR name, argv; ! 893: { ! 894: return(execvp(name, &argv)); ! 895: } ! 896: ! 897: execvp(name, argv) ! 898: CHARSTAR name, *argv; ! 899: { ! 900: register etxtbsy = 1; ! 901: register eacces = 0; ! 902: register CHARSTAR cp; ! 903: CHARSTAR pathstr; ! 904: CHARSTAR shell; ! 905: char fname[128]; ! 906: ! 907: pathstr = varptr("PATH")->varval; ! 908: if(pathstr == 0 || *pathstr == CNULL) ! 909: pathstr = ":/bin:/usr/bin"; ! 910: shell = varptr("SHELL")->varval; ! 911: if(shell == 0 || *shell == CNULL) ! 912: shell = "/bin/sh"; ! 913: cp = strchr(name, SLASH)? "": pathstr; ! 914: ! 915: do ! 916: { ! 917: cp = execat(cp, name, fname); ! 918: retry: ! 919: execv(fname, argv); ! 920: switch(errno) ! 921: { ! 922: case ENOEXEC: ! 923: *argv = fname; ! 924: *--argv = "sh"; ! 925: execv(shell, argv); ! 926: return(-1); ! 927: case ETXTBSY: ! 928: if (++etxtbsy > 5) ! 929: return(-1); ! 930: sleep(etxtbsy); ! 931: goto retry; ! 932: case EACCES: ! 933: eacces++; ! 934: break; ! 935: case ENOMEM: ! 936: case E2BIG: ! 937: return(-1); ! 938: } ! 939: } while (cp); ! 940: if (eacces) ! 941: errno = EACCES; ! 942: return(-1); ! 943: } ! 944: ! 945: /* ! 946: * get() does an SCCS get on the file ssfile. ! 947: * For the get command, get() uses the value of the variable "GET". ! 948: * If ssfile has a slash in it, get() does a "chdir" to the appropriate ! 949: * directory if the cdflag is set to CD. This assures ! 950: * the program finds the ssfile where it belongs when necessary. ! 951: * If the rlse string variable is set, get() uses it in the ! 952: * get command sequence. ! 953: * Thus a possible sequence is: ! 954: * set -x; ! 955: * cd ../sys/head; ! 956: * get -r2.3.4.5 s.stdio.h ! 957: * ! 958: */ ! 959: ! 960: /* ! 961: * The gothead and gotf structures are used to remember ! 962: * the names of the files `make' automatically gets so ! 963: * `make' can remove them upon exit. ! 964: */ ! 965: GOTHEAD gotfiles; ! 966: ! 967: get(ssfile, cdflag, rlse) ! 968: register CHARSTAR ssfile; ! 969: int cdflag; ! 970: CHARSTAR rlse; ! 971: { ! 972: register CHARSTAR pr; ! 973: register CHARSTAR pr1; ! 974: char gbuf[128]; ! 975: char sfile[128]; ! 976: int retval; ! 977: GOTF gf; ! 978: ! 979: copstr(sfile, ssfile); ! 980: if(!is_sccs(sfile)) ! 981: trysccs(sfile); ! 982: if(access(sfile, 4) != 0 && IS_OFF(GET)) ! 983: return(NO); ! 984: ! 985: pr = gbuf; ! 986: if(IS_OFF(SIL)) ! 987: pr = copstr(pr, "set -x;\n"); ! 988: ! 989: if(cdflag == CD) ! 990: if(any(sfile, SLASH)) ! 991: { ! 992: pr = copstr(pr, "cd "); ! 993: for(pr1 = sfile; *pr1; pr1++); ! 994: while(*pr1 != SLASH) ! 995: pr1--; ! 996: *pr1 = CNULL; ! 997: pr = copstr(pr, sfile); ! 998: pr = copstr(pr, ";\n"); ! 999: *pr1 = SLASH; ! 1000: } ! 1001: ! 1002: pr = copstr(pr, varptr("GET")->varval); ! 1003: pr = copstr(pr, " "); ! 1004: pr = copstr(pr, varptr("GFLAGS")->varval); ! 1005: pr = copstr(pr, " "); ! 1006: ! 1007: pr1 = rlse; ! 1008: if(pr1 != NULL && pr1[0] != CNULL) ! 1009: { ! 1010: if(pr1[0] != MINUS) /* RELEASE doesn't have '-r' */ ! 1011: pr = copstr(pr, "-r"); ! 1012: pr = copstr(pr, pr1); ! 1013: pr = copstr(pr, " "); ! 1014: } ! 1015: ! 1016: pr = copstr(pr, sfile); ! 1017: /* ! 1018: * exit codes are opposite of error codes so do the following: ! 1019: */ ! 1020: retval = (system(gbuf) == 0) ? YES : NO ; ! 1021: if(retval == YES) ! 1022: { ! 1023: if(gotfiles == 0) ! 1024: { ! 1025: gotfiles = ALLOC(gothead); ! 1026: gf = (GOTF)gotfiles; ! 1027: gotfiles->gnextp = 0; ! 1028: gotfiles->endp = (GOTF)gotfiles; ! 1029: } ! 1030: else ! 1031: { ! 1032: gf = gotfiles->endp; ! 1033: gf->gnextp = ALLOC(gotf); ! 1034: gf = gf->gnextp; ! 1035: gf->gnextp = 0; ! 1036: } ! 1037: gf->gnamep = copys(sfile+2); /* `+2' skips `s.' */ ! 1038: gotfiles->endp = gf; ! 1039: } ! 1040: return(retval); ! 1041: } ! 1042: ! 1043: /* ! 1044: * subroutine to actually remove to gotten files. ! 1045: */ ! 1046: rm_gots() ! 1047: { ! 1048: register GOTF gf; ! 1049: ! 1050: if(IS_ON(GF_KEEP)) ! 1051: return; ! 1052: for(gf = (GOTF)gotfiles; gf ; gf=gf->gnextp) ! 1053: if(gf->gnamep) ! 1054: { ! 1055: if(IS_ON(DBUG))printf("rm_got: %s\n", gf->gnamep); ! 1056: unlink(gf->gnamep); ! 1057: } ! 1058: } ! 1059: callyacc(str) ! 1060: register CHARSTAR str; ! 1061: { ! 1062: CHARSTAR lines[2]; ! 1063: FILE *finsave; ! 1064: CHARSTAR *lpsave; ! 1065: ! 1066: finsave = fin; ! 1067: lpsave = linesptr; ! 1068: fin = 0; ! 1069: lines[0] = str; ! 1070: lines[1] = 0; ! 1071: linesptr = lines; ! 1072: yyparse(); ! 1073: fin = finsave; ! 1074: linesptr = lpsave; ! 1075: } ! 1076: ! 1077: /* ! 1078: * exit routine for removing the files `make' automatically ! 1079: * got. ! 1080: */ ! 1081: exit(arg) ! 1082: { ! 1083: rm_gots(); ! 1084: if(IS_ON(MEMMAP)) ! 1085: { ! 1086: prtmem(); ! 1087: } ! 1088: _cleanup(); ! 1089: _exit(arg); ! 1090: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.