|
|
1.1 ! root 1: static char *sccsid = "@(#)misc.c 8th Edition (Bell Labs) 85/05/25"; ! 2: #include "defs" ! 3: #include <ctype.h> ! 4: ! 5: ! 6: ! 7: /* simple linear hash. hash function is sum of ! 8: characters mod hash table size. ! 9: */ ! 10: hashloc(s) ! 11: char *s; ! 12: { ! 13: register int i; ! 14: register int hashval; ! 15: register char *t; ! 16: ! 17: hashval = 0; ! 18: ! 19: for(t=s; *t!='\0' ; ++t) ! 20: hashval += *t; ! 21: ! 22: hashval %= hashsize; ! 23: ! 24: for(i=hashval; ! 25: hashtab[i]!=0 && !equal(s,hashtab[i]->namep); ! 26: i = i >= hashsize-1 ? 0 : i+1) ; ! 27: ! 28: return i; ! 29: } ! 30: ! 31: ! 32: nameblkp srchname(s) ! 33: char *s; ! 34: { ! 35: return hashtab[hashloc(s)] ; ! 36: } ! 37: ! 38: ! 39: ! 40: nameblkp makename(s) ! 41: char *s; ! 42: { ! 43: register nameblkp p; ! 44: ! 45: if(nhashed > hashthresh) ! 46: rehash(); ! 47: ! 48: ++nhashed; ! 49: hashtab[hashloc(s)] = p = ALLOC(nameblock); ! 50: p->nxtnameblock = firstname; ! 51: p->namep = copys(s); /* make a fresh copy of the string s */ ! 52: /* p->linep = 0; p->done = 0; p->septype = 0; p->modtime = 0; */ ! 53: ! 54: firstname = p; ! 55: if(mainname==NULL && !haspercent(s) && (*s!='.' || hasslash(s)) ) ! 56: mainname = p; ! 57: ! 58: return p; ! 59: } ! 60: ! 61: ! 62: ! 63: hasslash(s) ! 64: register char *s; ! 65: { ! 66: for( ; *s ; ++s) ! 67: if(*s == '/') ! 68: return YES; ! 69: return NO; ! 70: } ! 71: ! 72: ! 73: haspercent(s) ! 74: register char *s; ! 75: { ! 76: for( ; *s ; ++s) ! 77: if(*s == '%') ! 78: return YES; ! 79: return NO; ! 80: } ! 81: ! 82: ! 83: hasparen(s) ! 84: register char *s; ! 85: { ! 86: for( ; *s ; ++s) ! 87: if(*s == '(') ! 88: return YES; ! 89: return NO; ! 90: } ! 91: ! 92: ! 93: rehash() ! 94: { ! 95: nameblkp *ohash; ! 96: register nameblkp p, *hp, *endohash; ! 97: hp = ohash = hashtab; ! 98: endohash = hashtab + hashsize; ! 99: ! 100: newhash(2*hashsize); ! 101: ! 102: while( hp<endohash ) ! 103: if(p = *hp++) ! 104: hashtab[hashloc(p->namep)] = p; ! 105: ! 106: free( (char *) ohash); ! 107: } ! 108: ! 109: ! 110: ! 111: newhash(newsize) ! 112: int newsize; ! 113: { ! 114: hashsize = newsize; ! 115: hashtab = (nameblkp *) ckalloc(hashsize * sizeof(nameblkp)); ! 116: hashthresh = (2*hashsize)/3; ! 117: } ! 118: ! 119: ! 120: ! 121: nameblkp chkname(s) ! 122: char *s; ! 123: { ! 124: nameblkp p; ! 125: TIMETYPE k; ! 126: /*TEMP NEW */ ! 127: if(hasparen(s)) ! 128: { ! 129: k = lookarch(s); ! 130: /*TEMP fprintf(stderr, "chkname(%s): look=%d\n", s, k); */ ! 131: if(k == 0) ! 132: return NULL; ! 133: } ! 134: if(p = srchname(s)) ! 135: return p; ! 136: dirsrch(s); ! 137: return srchname(s); ! 138: } ! 139: ! 140: ! 141: ! 142: char *copys(s) ! 143: register char *s; ! 144: { ! 145: char *malloc(); ! 146: register char *t, *t0; ! 147: ! 148: if( (t = t0 = malloc( strlen(s)+1 ) ) == NULL) ! 149: fatal("out of memory"); ! 150: while(*t++ = *s++) ! 151: ; ! 152: return t0; ! 153: } ! 154: ! 155: ! 156: ! 157: char *concat(a,b,c) /* c = concatenation of a and b */ ! 158: register char *a,*b; ! 159: char *c; ! 160: { ! 161: register char *t; ! 162: t = c; ! 163: ! 164: while(*t = *a++) t++; ! 165: while(*t++ = *b++); ! 166: return c; ! 167: } ! 168: ! 169: ! 170: ! 171: suffix(a,b,p) /* is b the suffix of a? if so, set p = prefix */ ! 172: register char *a,*b,*p; ! 173: { ! 174: char *a0,*b0; ! 175: a0 = a; ! 176: b0 = b; ! 177: ! 178: while(*a++); ! 179: while(*b++); ! 180: ! 181: if( (a-a0) < (b-b0) ) return 0; ! 182: ! 183: while(b>b0) ! 184: if(*--a != *--b) return 0; ! 185: ! 186: while(a0<a) *p++ = *a0++; ! 187: *p = '\0'; ! 188: ! 189: return 1; ! 190: } ! 191: ! 192: ! 193: ! 194: ! 195: ! 196: ! 197: int *ckalloc(n) ! 198: register int n; ! 199: { ! 200: register int *p; ! 201: ! 202: if( p = (int *) calloc(1,n) ) ! 203: return p; ! 204: ! 205: fatal("out of memory"); ! 206: /* NOTREACHED */ ! 207: } ! 208: ! 209: /* copy string a into b, substituting for arguments */ ! 210: char *subst(a,b) ! 211: register char *a,*b; ! 212: { ! 213: static depth = 0; ! 214: register char *s; ! 215: char vname[100]; ! 216: struct varblock *varptr(), *vbp; ! 217: char closer; ! 218: ! 219: if(++depth > 100) ! 220: fatal("infinitely recursive macro?"); ! 221: if(a) while(*a) ! 222: { ! 223: if(*a!='$' || a[1]=='\0' || *++a=='$') ! 224: /* if a non-macro character copy it. if $$ or $\0, copy $ */ ! 225: *b++ = *a++; ! 226: else { ! 227: s = vname; ! 228: if( *a=='(' || *a=='{' ) ! 229: { ! 230: closer = ( *a=='(' ? ')' : '}'); ! 231: ++a; ! 232: while(*a == ' ') ++a; ! 233: while(*a!=' ' && *a!=closer && *a!='\0') *s++ = *a++; ! 234: while(*a!=closer && *a!='\0') ++a; ! 235: if(*a == closer) ++a; ! 236: } ! 237: else *s++ = *a++; ! 238: ! 239: *s = '\0'; ! 240: if( (vbp = varptr(vname)) ->varval != 0) ! 241: { ! 242: b = subst(vbp->varval, b); ! 243: vbp->used = YES; ! 244: } ! 245: } ! 246: } ! 247: ! 248: *b = '\0'; ! 249: --depth; ! 250: return b; ! 251: } ! 252: ! 253: ! 254: setvar(v, s, dyn) ! 255: char *v, *s; ! 256: int dyn; /* 1 if dynamic macro */ ! 257: { ! 258: struct varblock *varptr(); ! 259: register struct varblock *p; ! 260: ! 261: p = varptr(v); ! 262: if( ! p->noreset ) ! 263: { ! 264: p->varval = s; ! 265: p->noreset = inarglist; ! 266: if(p->used && !dyn) ! 267: fprintf(stderr, "Warning: %s changed after being used\n",v); ! 268: if(p->export) ! 269: { ! 270: /* change string pointed to by environment to new v=s */ ! 271: register char *t; ! 272: int lenv; ! 273: lenv = strlen(v); ! 274: *(p->export) = t = (char *) ckalloc(lenv + strlen(s) + 2); ! 275: strcpy(t,v); ! 276: t[lenv] = '='; ! 277: strcpy(t+lenv+1, s); ! 278: } ! 279: else ! 280: p->export = envpp; ! 281: } ! 282: } ! 283: ! 284: ! 285: /* for setting Bradford's *D and *F family of macros whens setting * etc */ ! 286: set3var(macro, value) ! 287: char *macro, *value; ! 288: { ! 289: register char *s; ! 290: char macjunk[8], *lastslash, *dirpart, *filepart; ! 291: ! 292: setvar(macro, value, YES); ! 293: if(value == CHNULL) ! 294: dirpart = filepart = CHNULL; ! 295: else ! 296: { ! 297: lastslash = CHNULL; ! 298: for(s = value; *s; ++s) ! 299: if(*s == '/') ! 300: lastslash = s; ! 301: if(lastslash) ! 302: { ! 303: dirpart = copys(value); ! 304: filepart = dirpart + (lastslash-value); ! 305: filepart[-1] = '\0'; ! 306: } ! 307: else ! 308: { ! 309: dirpart = ""; ! 310: filepart = value; ! 311: } ! 312: } ! 313: setvar(concat(macro, "D", macjunk), dirpart, YES); ! 314: setvar(concat(macro, "F", macjunk), filepart, YES); ! 315: } ! 316: ! 317: ! 318: ! 319: eqsign(a) /*look for arguments with equal signs but not colons */ ! 320: char *a; ! 321: { ! 322: register char *s, *t; ! 323: char c; ! 324: ! 325: while(*a == ' ') ++a; ! 326: for(s=a ; *s!='\0' && *s!=':' ; ++s) ! 327: if(*s == '=') ! 328: { ! 329: for(t = a ; *t!='=' && *t!=' ' && *t!='\t' ; ++t ); ! 330: c = *t; ! 331: *t = '\0'; ! 332: ! 333: for(++s; *s==' ' || *s=='\t' ; ++s); ! 334: setvar(a, copys(s), NO); ! 335: *t = c; ! 336: return YES; ! 337: } ! 338: ! 339: return NO; ! 340: } ! 341: ! 342: ! 343: struct varblock *varptr(v) ! 344: char *v; ! 345: { ! 346: register struct varblock *vp; ! 347: ! 348: /* for compatibility, $(TGS) = $^ */ ! 349: if(equal(v, "TGS") ) ! 350: v = "^"; ! 351: for(vp = firstvar; vp ; vp = vp->nxtvarblock) ! 352: if(equal(v , vp->varname)) ! 353: return vp; ! 354: ! 355: vp = ALLOC(varblock); ! 356: vp->nxtvarblock = firstvar; ! 357: firstvar = vp; ! 358: vp->varname = copys(v); ! 359: vp->varval = 0; ! 360: return vp; ! 361: } ! 362: ! 363: ! 364: dynmacro(line) ! 365: char *line; ! 366: { ! 367: register char *s; ! 368: char endc, *endp; ! 369: if(!isalpha(line[0])) ! 370: return NO; ! 371: for(s=line+1 ; *s && (isalpha(*s) | isdigit(*s)) ; ++s) ! 372: ; ! 373: endp = s; ! 374: while( isspace(*s) ) ! 375: ++s; ! 376: if(s[0]!=':' || s[1]!='=') ! 377: return NO; ! 378: ! 379: endc = *endp; ! 380: *endp = '\0'; ! 381: setvar(line, copys(s+2), YES); ! 382: *endp = endc; ! 383: ! 384: return YES; ! 385: } ! 386: ! 387: ! 388: ! 389: fatal1(s, t) ! 390: char *s, *t; ! 391: { ! 392: char buf[100]; ! 393: sprintf(buf, s, t); ! 394: fatal(buf); ! 395: } ! 396: ! 397: ! 398: ! 399: fatal(s) ! 400: char *s; ! 401: { ! 402: fflush(stdout); ! 403: if(s) ! 404: fprintf(stderr, "Make: %s. Stop.\n", s); ! 405: else ! 406: fprintf(stderr, "\nStop.\n"); ! 407: ! 408: waitstack(0); ! 409: exit(1); ! 410: } ! 411: ! 412: ! 413: ! 414: /* appends to the chain for $? and $^ */ ! 415: chainp appendq(head, tail) ! 416: chainp head; ! 417: char *tail; ! 418: { ! 419: register chainp p, q; ! 420: ! 421: p = ALLOC(chain); ! 422: p->datap = tail; ! 423: ! 424: if(head) ! 425: { ! 426: for(q = head ; q->nextp ; q = q->nextp) ! 427: ; ! 428: q->nextp = p; ! 429: return head; ! 430: } ! 431: else ! 432: return p; ! 433: } ! 434: ! 435: ! 436: ! 437: ! 438: ! 439: /* builds the value for $? and $^ */ ! 440: char *mkqlist(p,qbuf) ! 441: struct chain *p; ! 442: char *qbuf; ! 443: { ! 444: register char *qbufp, *s; ! 445: ! 446: if(p == NULL) ! 447: return ""; ! 448: ! 449: qbufp = qbuf; ! 450: ! 451: for( ; p ; p = p->nextp) ! 452: { ! 453: s = p->datap; ! 454: if(qbufp+strlen(s) > &qbuf[QBUFMAX-3]) ! 455: { ! 456: fprintf(stderr, "$? list too long\n"); ! 457: break; ! 458: } ! 459: while (*s) ! 460: *qbufp++ = *s++; ! 461: *qbufp++ = ' '; ! 462: } ! 463: *--qbufp = '\0'; ! 464: return qbuf; ! 465: } ! 466: ! 467: wildp iswild(name) ! 468: char *name; ! 469: { ! 470: register char *s; ! 471: register wildp p; ! 472: ! 473: for(s=name; *s; ++s) ! 474: if(*s == '%') ! 475: { ! 476: p = ALLOC(wild); ! 477: *s = '\0'; ! 478: p->left = copys(name); ! 479: *s = '%'; ! 480: p->right = copys(s+1); ! 481: p->llen = strlen(p->left); ! 482: p->rlen = strlen(p->right); ! 483: p->totlen = p->llen + p->rlen; ! 484: return p; ! 485: } ! 486: return NULL; ! 487: } ! 488: ! 489: ! 490: char *wildmatch(p, name, len) ! 491: register wildp p; ! 492: char *name; ! 493: int len; ! 494: { ! 495: char *stem; ! 496: register char *s; ! 497: char c; ! 498: ! 499: if(len < p->totlen || ! 500: strncmp(name, p->left, p->llen) || ! 501: strncmp(s = name+len-p->rlen, p->right, p->rlen) ) ! 502: return CHNULL; ! 503: ! 504: /*TEMP fprintf(stderr, "wildmatch(%s)=%s%%%s)\n", name,p->left,p->right); */ ! 505: c = *s; ! 506: *s = '\0'; ! 507: stem = copys(name + p->llen); ! 508: *s = c; ! 509: return stem; ! 510: } ! 511: ! 512: ! 513: ! 514: /* substitute stem for any % marks */ ! 515: char *wildsub(pat, stem) ! 516: char *pat, *stem; ! 517: { ! 518: static char temp[100]; ! 519: register char *s, *t; ! 520: ! 521: s = temp; ! 522: for(; *pat; ++pat) ! 523: if(*pat == '%') ! 524: for(t = stem ; *t; ) ! 525: *s++ = *t++; ! 526: else ! 527: *s++ = *pat; ! 528: *s = '\0'; ! 529: return temp; ! 530: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.