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