|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include "efix.h" ! 3: #define Hlen 4091 ! 4: #define HGULP 1020 ! 5: #define SGULP 8092 ! 6: extern char *strcpy(); ! 7: ! 8: char * ! 9: alloc(x) ! 10: unsigned x; ! 11: { ! 12: extern char *malloc(); ! 13: char *s; ! 14: s = malloc(x); ! 15: if (!s) { ! 16: fprintf(stderr, "%s: malloc failure!\n", progname); ! 17: exit(1); ! 18: } ! 19: return s; ! 20: } ! 21: ! 22: struct HashHeader { ! 23: struct Hash *next, *prev; ! 24: } maintab[Hlen], memtab[Hlen]; ! 25: ! 26: struct Hash { ! 27: struct HashHeader hh; ! 28: char *name; ! 29: char *type; ! 30: struct Hash *dup; ! 31: int lev; ! 32: } *halloc_next, *halloc_last, *lasthash; ! 33: ! 34: /* type values: ! 35: * static, auto, extern, register: i ! 36: * char, double, float, int, long, short, unsigned, void: i ! 37: * enum: e ! 38: * struct, union: a ! 39: * typedef: t ! 40: * struct tag, union tag, typedefed name: T{type} ! 41: */ ! 42: ! 43: char *salloc_next, *salloc_last; ! 44: struct SALLOC { ! 45: struct SALLOC *next; ! 46: char *last; ! 47: char block[SGULP]; ! 48: } *Salloc_block; ! 49: struct HALLOC { ! 50: struct HALLOC *next, *prev; ! 51: struct Hash block[HGULP]; ! 52: } *Halloc_block; ! 53: ! 54: struct Context { ! 55: struct Context *next, *prev; ! 56: struct SALLOC *Sblock; ! 57: char *snext, *slast; ! 58: struct HALLOC *Hblock; ! 59: struct Hash *hnext; ! 60: } *context; ! 61: int levnow; ! 62: ! 63: new_context() ! 64: { ! 65: struct Context *C; ! 66: ++levnow; ! 67: if (!context || !(C = context->next)) { ! 68: C = (struct Context *)alloc(sizeof(struct Context)); ! 69: C->next = 0; ! 70: if (context) ! 71: context->next = C; ! 72: C->prev = context; ! 73: } ! 74: context = C; ! 75: C->Sblock = Salloc_block; ! 76: C->Hblock = Halloc_block; ! 77: C->snext = salloc_next; ! 78: C->slast = salloc_last; ! 79: C->hnext = halloc_next; ! 80: } ! 81: ! 82: end_context() ! 83: { ! 84: struct Hash *h, *h0, *h00, *h1; ! 85: struct HALLOC *H; ! 86: struct Context *C; ! 87: ! 88: --levnow; ! 89: C = context; ! 90: context = C->prev; ! 91: if (!C || levnow < 0) ! 92: scream("too many end_context's"); ! 93: Salloc_block = C->Sblock; ! 94: salloc_next = C->snext; ! 95: salloc_last = C->slast; ! 96: h00 = C->hnext; ! 97: if (H = Halloc_block) { ! 98: h0 = H->block; ! 99: h = halloc_next; ! 100: while(h != h00) { ! 101: if (--h == h0) { ! 102: H = H->prev; ! 103: h0 = H->block; ! 104: h = h0 + HGULP; ! 105: continue; ! 106: } ! 107: h1 = h->hh.next; ! 108: h1->hh.prev = h->hh.prev; ! 109: h->hh.prev->hh.next = h1; ! 110: } ! 111: } ! 112: Halloc_block = C->Hblock; ! 113: halloc_next = h00; ! 114: } ! 115: ! 116: struct Hash * ! 117: hash(s, ht) ! 118: register char *s; ! 119: struct HashHeader *ht; ! 120: { ! 121: register x = 0, c; ! 122: register struct Hash *h, *h0; ! 123: char *s0 = s; ! 124: ! 125: while(c = *s++) { ! 126: if (x & 1) ! 127: x = 0x40000000 | (x>>1) ^ c; ! 128: else ! 129: x = (x>>1) ^ c; ! 130: } ! 131: x %= Hlen; ! 132: lasthash = h0 = (struct Hash *) (ht + x); ! 133: s = s0; ! 134: for(h = h0->hh.next; h != h0; h = h->hh.next) ! 135: if (!strcmp(s,h->name)) ! 136: return h; ! 137: return 0; ! 138: } ! 139: ! 140: char * ! 141: salloc(s) ! 142: char *s; ! 143: { ! 144: unsigned x; ! 145: char *t; ! 146: struct SALLOC *S; ! 147: ! 148: x = strlen(s) + 1; ! 149: t = salloc_next; ! 150: if ((salloc_next += x) > salloc_last) { ! 151: if (Salloc_block && (S = Salloc_block->next)) { ! 152: if (S->last - S->block < x) ! 153: scream("Huge string in salloc"); ! 154: } ! 155: else { ! 156: S = (struct SALLOC *)alloc(x + sizeof(struct SALLOC)); ! 157: if (Salloc_block) ! 158: Salloc_block->next = S; ! 159: S->last = S->block + x + SGULP; ! 160: S->next = 0; ! 161: } ! 162: t = S->block; ! 163: salloc_next = t + x; ! 164: salloc_last = S->last; ! 165: Salloc_block = S; ! 166: } ! 167: return strcpy(t, s); ! 168: } ! 169: ! 170: struct Hash * ! 171: newhash(s,t) ! 172: char *s, *t; ! 173: { ! 174: struct Hash *h, *h1; ! 175: struct HALLOC *H; ! 176: ! 177: if ((h = halloc_next++) >= halloc_last) { ! 178: if (!Halloc_block || !(H = Halloc_block->next)) { ! 179: H = (struct HALLOC *) ! 180: alloc(sizeof(struct HALLOC)); ! 181: H->next = 0; ! 182: H->prev = Halloc_block; ! 183: } ! 184: Halloc_block = H; ! 185: h = H->block; ! 186: halloc_next = h + 1; ! 187: halloc_last = h + HGULP; ! 188: } ! 189: h->name = s; ! 190: h->type = t; ! 191: h->lev = levnow; ! 192: h->hh.next = h1 = lasthash->hh.next; ! 193: h1->hh.prev = h; ! 194: h->hh.prev = lasthash; ! 195: lasthash->hh.next = h; ! 196: return h; ! 197: } ! 198: ! 199: struct Tok Toks[3]; ! 200: char isdcl[128]; ! 201: ! 202: setup() ! 203: { ! 204: int i; ! 205: struct HashHeader *h; ! 206: static char *keywds[] = { ! 207: "auto", "i", ! 208: "char", "i", ! 209: "double", "i", ! 210: "enum", "e", ! 211: "extern", "i", ! 212: "float", "i", ! 213: "int", "i", ! 214: "long", "i", ! 215: "register", "i", ! 216: "short", "i", ! 217: "static", "i", ! 218: "struct", "a", ! 219: "typedef", "t", ! 220: "union", "a", ! 221: "unsigned", "i", ! 222: "void", "i", ! 223: 0, 0}; ! 224: char **k, *s; ! 225: ! 226: Toks[0].next = Toks + 1; Toks[0].prev = Toks + 2; ! 227: Toks[1].next = Toks + 2; Toks[1].prev = Toks; ! 228: Toks[2].next = Toks; Toks[2].prev = Toks + 1; ! 229: for(i = 0; i < 3; i++) Toks[i].inlevel = 1; ! 230: T = Toks; ! 231: for(h = maintab, i = 0; i < Hlen; ++i, ++h) ! 232: h->next = h->prev = (struct Hash *)h; ! 233: for(h = memtab, i = 0; i < Hlen; ++i, ++h) ! 234: h->next = h->prev = (struct Hash *)h; ! 235: ! 236: for(k = keywds; *k; k += 2) { ! 237: hash(*k, maintab); ! 238: newhash(k[0], k[1]); ! 239: } ! 240: for(s = "aeitT"; *s; ++s) ! 241: isdcl[*s] = 1; ! 242: } ! 243: ! 244: process() ! 245: { ! 246: int t; ! 247: struct Tok *T1; ! 248: ! 249: setup(); ! 250: ! 251: while((t = token(0)) != FEND) { ! 252: if (t == SYMBOL) ! 253: dcl(); ! 254: else if (t != ';') { ! 255: squawk("expected declaration"); ! 256: do token(2); ! 257: while(t != ';'); ! 258: } ! 259: } ! 260: done: ! 261: for(T1 = T;;) { ! 262: T1 = T1->next; ! 263: if (!T1->inlevel) ! 264: printf("%s%s", T1->white, T1->tok); ! 265: if (T1 == T) ! 266: break; ! 267: } ! 268: } ! 269: ! 270: char * ! 271: memname() ! 272: { ! 273: int pars = 0; ! 274: char *s; ! 275: int t; ! 276: ! 277: for(t = T->type; ; t = token(2)) { ! 278: switch(t) { ! 279: case '(': ++pars; ! 280: case '*': continue; ! 281: case ':': ! 282: if (pars) ! 283: scream("unexpected :"); ! 284: getexp(); ! 285: return 0; ! 286: default: break; ! 287: } ! 288: break; ! 289: } ! 290: if (t != SYMBOL) ! 291: scream("expected * ( : or symbol") /*)*/; ! 292: s = salloc(T->tok); ! 293: for(;;) { ! 294: switch(token(2)) { ! 295: case '(': ! 296: case '[': ! 297: ++pars; ! 298: continue; ! 299: case ')': ! 300: case ']': ! 301: --pars; ! 302: continue; ! 303: case ':': ! 304: if (!pars) { ! 305: getexp(); ! 306: break; ! 307: } ! 308: case ';': ! 309: break; ! 310: case ',': ! 311: if (pars <= 0) ! 312: break; ! 313: default: ! 314: continue; ! 315: } ! 316: break; ! 317: } ! 318: if (pars) ! 319: squawk("bad paren count in memname"); ! 320: return s; ! 321: } ! 322: ! 323: char * ! 324: sdcl(tag) ! 325: char *tag; ! 326: { ! 327: int t, typed; ! 328: char buf[256], *m, *s; ! 329: struct Hash *h, *h1; ! 330: static int anon; ! 331: char *b, *be = buf + sizeof(buf); ! 332: ! 333: b = adjoin(buf,be,tag); ! 334: *b++ = *T->tok; /* 's' or 'u' */ ! 335: t = token(2); ! 336: if (t == SYMBOL) { ! 337: adjoin(b,be,T->tok); ! 338: t = token(2); ! 339: } ! 340: else ! 341: sprintf(b, "#%d", ++anon); ! 342: s = salloc(buf); ! 343: if (t != '{') /*}*/ { ! 344: return s; ! 345: } ! 346: ! 347: /* struct foo {...} -- process the ... */ ! 348: ! 349: for(t = token(2); /*{*/ t != '}'; t = token(2)) { ! 350: for(typed = 0; t == SYMBOL; t = token(2), typed = 1) { ! 351: h = hash(T->tok, maintab); ! 352: if (h) switch(*h->type) { ! 353: case 'a': ! 354: case 'e': ! 355: t = token(2); ! 356: if (t != SYMBOL) ! 357: scream("expected tag"); ! 358: case 'i': ! 359: case 'T': ! 360: continue; ! 361: case 't': ! 362: scream("typedef within struct!"); ! 363: } ! 364: break; ! 365: } ! 366: if (!typed) ! 367: scream("no type!"); ! 368: if (t != ';') ! 369: for(; ; token(2)) { ! 370: if (m = memname()) { ! 371: h = hash(m, memtab); ! 372: h1 = newhash(m, s); ! 373: h1->dup = h; ! 374: } ! 375: switch(T->type) { ! 376: case ',': continue; ! 377: case ';': break; ! 378: default: ! 379: scream("expected ; or ,"); ! 380: } ! 381: break; ! 382: } ! 383: } ! 384: token(2); ! 385: return s; ! 386: } ! 387: ! 388: dcl() ! 389: { ! 390: struct Hash *h; ! 391: char buf[256], *sym; ! 392: int pars = 0, t, typed = 0; ! 393: char *b = buf, *buf1 = buf, *be = buf + sizeof(buf), *tag = ""; ! 394: ! 395: for(t = SYMBOL; t == SYMBOL; t = token(2)) { ! 396: h = hash(T->tok, maintab); ! 397: if (h) switch(*h->type) { ! 398: case 'T': ! 399: tag = h->type + 1; ! 400: typed = 1; ! 401: continue; ! 402: case 'a': /* aggregate -- struct or union */ ! 403: tag = sdcl(tag); ! 404: typed = 1; ! 405: t = T->type; ! 406: goto havetag; ! 407: case 'e': ! 408: do t = token(2); ! 409: while(t != ';'); ! 410: return; ! 411: case 'i': ! 412: typed = 1; ! 413: continue; ! 414: case 't': ! 415: typed = 0; ! 416: *buf = 'T'; ! 417: b = buf1 = buf + 1; ! 418: continue; ! 419: } ! 420: break; ! 421: } ! 422: havetag: ! 423: for(; t != ';'; t = token(2)) { ! 424: if (t != SYMBOL) ! 425: switch(t) { ! 426: case '(': ! 427: ++pars; ! 428: case '*': ! 429: *b++ = t; ! 430: continue; ! 431: default: ! 432: scream("expected symbol, ( or *" /*)*/); ! 433: } ! 434: sym = salloc(T->tok); ! 435: b = adjoin(b,be,tag); ! 436: while(pars > 0) { ! 437: switch(t = token(2)) { ! 438: case '(': ! 439: case '[': ! 440: ++pars; ! 441: break; ! 442: case ')': ! 443: case ']': ! 444: --pars; ! 445: break; ! 446: default: ! 447: scream("expected ( [ ] or )"); ! 448: } ! 449: *b++ = t; ! 450: } ! 451: if (pars < 0) ! 452: scream("negative paren count!"); ! 453: t = token(2); ! 454: if (t == '(' /*)*/) { ! 455: adjoin(b,be,"()"); ! 456: if ((h = hash(sym, maintab))) { ! 457: if (h->lev == levnow && strcmp(buf,h->type)) { ! 458: badtype: ! 459: squawk("wrong type!"); ! 460: fprintf(stderr, "expected %s, got %s\n", ! 461: h->type, buf); ! 462: exit(1); ! 463: } ! 464: } ! 465: else newhash(sym,salloc(buf)); ! 466: ! 467: /* start of a function body? */ ! 468: ! 469: switch(t = token(2)) { ! 470: case SYMBOL: ! 471: function(); ! 472: return; ! 473: case /*(*/ ')': ! 474: t = token(2); ! 475: if (t == '{'/*}*/) { ! 476: function(); ! 477: return; ! 478: } ! 479: break; ! 480: default: ! 481: scream(/*(*/"expected symbol or )"); ! 482: } ! 483: } ! 484: else { ! 485: if (!typed) ! 486: scream("expected type or function prologue"); ! 487: if (t == '['/*]*/) ! 488: for(; ; t = token(2)) { ! 489: switch(t) { ! 490: case '[': ! 491: if (!pars) ! 492: adjoin(b,be,"[]"); ! 493: case '(': ! 494: ++pars; ! 495: continue; ! 496: case ']': ! 497: case ')': ! 498: --pars; ! 499: continue; ! 500: default: ! 501: if (pars) ! 502: continue; ! 503: } ! 504: break; ! 505: } ! 506: if ((h = hash(sym, maintab))) { ! 507: if (h->lev == levnow && strcmp(buf,h->type)) ! 508: goto badtype; ! 509: } ! 510: else newhash(sym,salloc(buf)); ! 511: } ! 512: switch(t) { ! 513: case ',': ! 514: break; ! 515: case ';': ! 516: return; ! 517: case '=': ! 518: t = getexp(); ! 519: if (t == ';') ! 520: return; ! 521: break; ! 522: default: ! 523: scream("expected , ; or ="); ! 524: } ! 525: b = buf1; ! 526: } ! 527: } ! 528: ! 529: doarrow() ! 530: { ! 531: struct Tok *T0, *T1; ! 532: int t; ! 533: struct Hash *h, *h0; ! 534: char *s, *what; ! 535: ! 536: T0 = T->prev; ! 537: if (T0->type != SYMBOL || T0->inlevel) ! 538: return; ! 539: untok = t = token(2); ! 540: if (t != SYMBOL) ! 541: return; ! 542: T1 = T; ! 543: if (!(h = hash(T1->tok, memtab)) ! 544: || !(h0 = hash(T0->tok, maintab))) ! 545: return; ! 546: if (*h0->type == '*' && !strcmp(h0->type+1, h->type)) ! 547: return; ! 548: T0->inlevel = 1; ! 549: s = h->type; ! 550: what = *s++ == 's' ? "struct" : "union"; ! 551: if (!h->dup) ! 552: printf("%s((%s %s *)%s)", T0->white, what, s, T0->tok); ! 553: else { ! 554: printf("%s((%s %s /*"/*))*/, T0->white, what, s); ! 555: if (verbose) { ! 556: squawk("ambiguous tag"); ! 557: fprintf(stderr, "%s %s", what, s); ! 558: } ! 559: while(h = h->dup) { ! 560: s = h->type; ! 561: what = *s++ == 's' ? "struct" : "union"; ! 562: printf("|| %s %s", what, s); ! 563: if (verbose) ! 564: fprintf(stderr, " || %s %s", what, s); ! 565: } ! 566: printf(/*((*/" */ *)%s)", T0->tok); ! 567: } ! 568: } ! 569: ! 570: getexp() ! 571: { ! 572: int brcnt = 0, t; ! 573: ! 574: for(;;) switch(t = token(2)) { ! 575: case ';': ! 576: if (brcnt) ! 577: scream("unclosed braces!"); ! 578: /* no break */ ! 579: case ',': ! 580: if (!brcnt) ! 581: return t; ! 582: break; ! 583: case ARROW: ! 584: doarrow(); ! 585: break; ! 586: case '(': ! 587: case '{': ! 588: ++brcnt; ! 589: break; ! 590: case '}': ! 591: case ')': ! 592: --brcnt; ! 593: break; ! 594: } ! 595: } ! 596: ! 597: function() ! 598: { ! 599: int paren, t; ! 600: struct Hash *h; ! 601: /*debug*/static int zork; extern int lineno; ! 602: ! 603: if (levnow) ! 604: scream("inner function def!"); ! 605: new_context(); ! 606: if (T->type == SYMBOL) { ! 607: while((t = token(2)) != /*(*/ ')') { ! 608: if (t != ',') ! 609: scream(/*(*/"expected ) or ,"); ! 610: if (token(2) != SYMBOL) ! 611: scream("expected dummy arg"); ! 612: } ! 613: while((t = token(2)) == SYMBOL) ! 614: dcl(); ! 615: if (t != '{'/*}*/) ! 616: scream(/*{*/"expected }"); ! 617: } ! 618: new_context(); ! 619: paren = 0; ! 620: top: ! 621: for(;;) { ! 622: switch(t = token(2)) { ! 623: case ';': ! 624: continue; ! 625: case '{': ! 626: new_context(); ! 627: continue; ! 628: case '}': ! 629: end_context(); ! 630: if (levnow == 1) { ! 631: end_context(); ! 632: return; ! 633: } ! 634: continue; ! 635: case '(': /*)*/ ! 636: paren++; ! 637: break; ! 638: case SYMBOL: ! 639: if ((h = hash(T->tok,maintab)) ! 640: && isdcl[*h->type]) { ! 641: dcl(); ! 642: continue; ! 643: } ! 644: } ! 645: /* fall thru for non declaration stmt */ ! 646: for(;;) { ! 647: /*debug*/ if (lineno == zork) ! 648: /*debug*/ printf(""); ! 649: switch(t = token(2)) { ! 650: case ARROW: ! 651: doarrow(); ! 652: continue; ! 653: case ';': ! 654: if (!paren) ! 655: goto top; ! 656: continue; ! 657: case '(': ! 658: ++paren; ! 659: continue; ! 660: case ')': ! 661: if (--paren < 0) ! 662: scream("bad paren count"); ! 663: continue; ! 664: case '{': ! 665: if (paren) ! 666: scream("unexpected {"); ! 667: new_context(); ! 668: goto top; ! 669: case '}': ! 670: scream("unexpected }"); ! 671: } ! 672: } ! 673: } ! 674: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.