|
|
1.1 ! root 1: /* ! 2: * Table processor for the ! 3: * new compiler, machine independent. ! 4: * Runs under Coherent. Uses ! 5: * two output files for compatability with ! 6: * the VAX cross compilers. ! 7: * Caches pattern flags, node flags, and type flags. ! 8: * Overlays common sequences before end of macros. ! 9: */ ! 10: char helpmessage[] = "\ ! 11: Usage: tabgen [-s] [-d define] [-p pfn] [-m mfn] file ...\n\ ! 12: "; ! 13: /* ! 14: * Options: ! 15: * -s report statistics ! 16: * -d define treat 'define' as defined in #ifdef and #ifndef ! 17: * NDEF is limit on number of -d define's ! 18: * -p pfn make 'pfn' the pattern file name ! 19: * -m mfn make 'mfn' the macro file name ! 20: * Arguments are concatenated into the tables with attention ! 21: * #ifdef's and #ifndef's. ! 22: */ ! 23: ! 24: #include <ctype.h> ! 25: #define YATC 1 ! 26: #ifdef vax ! 27: #include "INC$LIB:host.h" ! 28: #include "INC$LIB:cc1.h" ! 29: #else ! 30: #include "host.h" ! 31: #include "cc1.h" ! 32: #endif ! 33: ! 34: #define nel(x) (sizeof(x)/sizeof(x[0])) ! 35: ! 36: #define NCPS 8 /* Max identifier size */ ! 37: #define NDEF 32 /* Limit on number of -d defines */ ! 38: #define NHASH 512 /* Size of macro element hash */ ! 39: #define NMAC 256 /* Max number of elements in macro */ ! 40: ! 41: typedef struct cache { ! 42: struct cache *c_fp; ! 43: int c_type; ! 44: int c_sequence; ! 45: char c_data[]; ! 46: } CACHE; ! 47: ! 48: #define CPAT 0 ! 49: #define CTYPE 1 ! 50: #define CFLAG 2 ! 51: #define CICON 3 ! 52: #define CLCON 4 ! 53: #define CGID 5 ! 54: #define CFILE 6 ! 55: #define NCACHE 7 ! 56: ! 57: typedef struct hash { ! 58: char s_name[NCPS]; ! 59: } HASH; ! 60: ! 61: HASH hash[NHASH]; ! 62: HASH *macv[NMAC]; ! 63: HASH *m_end, *m_newl, *m_jmp, *m_gid, *m_icon, *m_lcon; ! 64: HASH *mlookup(); ! 65: int nmac = 0; ! 66: ! 67: typedef struct sort { ! 68: int t_boffs; ! 69: HASH *t_symb; ! 70: struct sort *t_diff, *t_same; ! 71: } SORT; ! 72: ! 73: SORT *root; ! 74: ! 75: FILE *ifp; ! 76: FILE *pfp; ! 77: FILE *mfp; ! 78: ! 79: int fnseq = 0; ! 80: char *fname = NULL; ! 81: int lineno = 0; ! 82: CACHE *cache = NULL; ! 83: int boffs = 0; ! 84: int bsave = 0; ! 85: int npats = 0; ! 86: int sflag = 0; ! 87: int nflag = 0; ! 88: int flevel = 0; ! 89: int tlevel = 0; ! 90: int getnc = 0; ! 91: int nbol = 0; ! 92: int ndef = 0; ! 93: int hiteof = 0; ! 94: int ungetc = -1; ! 95: int opseq = 1; ! 96: int fargc; ! 97: char **fargv; ! 98: ! 99: int cacheseq[NCACHE]; ! 100: char pbuf[128]; ! 101: char *def[NDEF]; ! 102: char *getcp; ! 103: char getbuf[128]; ! 104: ! 105: struct optable { ! 106: char o_id[NCPS]; /* Name */ ! 107: short o_value; /* Op value */ ! 108: short o_seq; /* Pattern sequence */ ! 109: short o_npat; /* # of patterns */ ! 110: } optable[] = { ! 111: { "ADD", ADD }, ! 112: { "SUB", SUB }, ! 113: { "MUL", MUL }, ! 114: { "DIV", DIV }, ! 115: { "REM", REM }, ! 116: { "AND", AND }, ! 117: { "OR", OR }, ! 118: { "XOR", XOR }, ! 119: { "SHL", SHL }, ! 120: { "SHR", SHR }, ! 121: { "AADD", AADD }, ! 122: { "ASUB", ASUB }, ! 123: { "AMUL", AMUL }, ! 124: { "ADIV", ADIV }, ! 125: { "AREM", AREM }, ! 126: { "AAND", AAND }, ! 127: { "AOR", AOR }, ! 128: { "AXOR", AXOR }, ! 129: { "ASHL", ASHL }, ! 130: { "ASHR", ASHR }, ! 131: { "EQ", EQ }, ! 132: { "NE", NE }, ! 133: { "GT", GT }, ! 134: { "GE", GE }, ! 135: { "LE", LE }, ! 136: { "LT", LT }, ! 137: { "UGT", UGT }, ! 138: { "UGE", UGE }, ! 139: { "ULE", ULE }, ! 140: { "ULT", ULT }, ! 141: { "STAR", STAR }, ! 142: { "ADDR", ADDR }, ! 143: { "NEG", NEG }, ! 144: { "COM", COM }, ! 145: { "NOT", NOT }, ! 146: { "QUEST", QUEST }, ! 147: { "COLON", COLON }, ! 148: { "INCBEF", INCBEF }, ! 149: { "DECBEF", DECBEF }, ! 150: { "INCAFT", INCAFT }, ! 151: { "DECAFT", DECAFT }, ! 152: { "COMMA", COMMA }, ! 153: { "CALL", CALL }, ! 154: { "ANDAND", ANDAND }, ! 155: { "OROR", OROR }, ! 156: { "CAST", CAST }, ! 157: { "CONVERT", CONVERT }, ! 158: { "FIELD", FIELD }, ! 159: { "SIZEOF", SIZEOF }, ! 160: { "ASSIGN", ASSIGN }, ! 161: { "NOP", NOP }, ! 162: { "INIT", INIT }, ! 163: { "ARGLST", ARGLST }, ! 164: { "LEAF", LEAF }, ! 165: { "FIXUP", FIXUP }, ! 166: { "BLKMOVE", BLKMOVE } ! 167: }; ! 168: ! 169: /* ! 170: * Only macros which must be recognized ! 171: * are listed, the rest are output symbolically. ! 172: */ ! 173: struct mtab { ! 174: char m_id[NCPS]; ! 175: short m_byte; ! 176: } mtab[] = { ! 177: { "IFR", M_IFR }, ! 178: { "IFE", M_IFE }, ! 179: { "IFV", M_IFV }, ! 180: { "CONST", M_ICON }, ! 181: { "LCONST", M_LCON }, ! 182: { "REGNO", M_REGNO }, ! 183: { "GID", M_GID } ! 184: }; ! 185: ! 186: #ifdef Z8001 ! 187: FILE *ofp; ! 188: char file[2]; ! 189: int line; ! 190: VARIANT variant; ! 191: #endif ! 192: ! 193: main(argc, argv) ! 194: char *argv[]; ! 195: { ! 196: char *pfn; ! 197: char *mfn; ! 198: char *p; ! 199: int c; ! 200: int i; ! 201: ! 202: pfn = "patern.c"; ! 203: mfn = "macros.c"; ! 204: for (i=1; i<argc; ++i) { ! 205: p = argv[i]; ! 206: if (*p == '-') { ! 207: while ((c = *++p) != 0) { ! 208: switch (c) { ! 209: ! 210: case 'p': ! 211: if (++i >= argc) ! 212: usage(); ! 213: pfn = argv[i]; ! 214: break; ! 215: ! 216: case 'm': ! 217: if (++i >= argc) ! 218: usage(); ! 219: mfn = argv[i]; ! 220: break; ! 221: ! 222: case 's': ! 223: sflag = 1; ! 224: break; ! 225: ! 226: case 'n': ! 227: nflag = 1; ! 228: break; ! 229: ! 230: case 'd': ! 231: if (++i >= argc) ! 232: usage(); ! 233: def[ndef++] = argv[i]; ! 234: break; ! 235: ! 236: default: ! 237: usage(); ! 238: } ! 239: } ! 240: } else ! 241: break; ! 242: } ! 243: fargc = argc - i; ! 244: fargv = argv + i; ! 245: if (fargc == 0) ! 246: usage(); ! 247: pinit(pfn); ! 248: minit(mfn); ! 249: if (sflag) ! 250: for (i=0; i<ndef; ++i) ! 251: fprintf(stderr, "def[%d] = \"%s\"\n", i, def[i]); ! 252: ncompile(); ! 253: pfinis(); ! 254: mfinis(); ! 255: if (sflag) { ! 256: fprintf(stderr, "%d patterns, %d bytes.\n", npats, boffs); ! 257: fprintf(stderr, "%d bytes saved by goto\n", bsave); ! 258: fprintf(stderr, "%d patflags\n", cacheseq[CPAT]); ! 259: fprintf(stderr, "%d types\n", cacheseq[CTYPE]); ! 260: fprintf(stderr, "%d flags\n", cacheseq[CFLAG]); ! 261: fprintf(stderr, "%d constants\n", cacheseq[CICON]); ! 262: fprintf(stderr, "%d long constants\n", cacheseq[CLCON]); ! 263: fprintf(stderr, "%d global identifiers\n", cacheseq[CGID]); ! 264: fprintf(stderr, "%d files\n", cacheseq[CFILE]); ! 265: } ! 266: exit (OK); ! 267: } ! 268: ! 269: usage() ! 270: { ! 271: fprintf(stderr, helpmessage); ! 272: exit(ABORT); ! 273: } ! 274: ! 275: ! 276: pinit(pfn) ! 277: char *pfn; ! 278: { ! 279: if ((pfp = fopen(pfn, "w")) == NULL) { ! 280: fprintf(stderr, "%s: cannot create\n", pfn); ! 281: exit(ABORT); ! 282: } ! 283: intro(pfp); ! 284: fprintf(pfp, "#if !TINY\n"); ! 285: fprintf(pfp, "#define fl(f,l) , f, l\n"); ! 286: fprintf(pfp, "#else\n"); ! 287: fprintf(pfp, "#define fl(f,l) /* f, l */\n"); ! 288: fprintf(pfp, "#endif\n"); ! 289: fprintf(pfp, "extern char macros[];\n"); ! 290: } ! 291: ! 292: minit(mfn) ! 293: char *mfn; ! 294: { ! 295: if ((mfp = fopen(mfn, "w")) == NULL) { ! 296: fprintf(stderr, "%s: cannot create\n", mfn); ! 297: exit(ABORT); ! 298: } ! 299: intro(mfp); ! 300: fprintf(mfp, "char macros[] = {\n"); ! 301: m_end = mlookup("M_END"); ! 302: m_newl = mlookup("\n"); ! 303: m_jmp = mlookup("M_JMP"); ! 304: m_gid = mlookup("M_GID"); ! 305: m_icon = mlookup("M_ICON"); ! 306: m_lcon = mlookup("M_LCON"); ! 307: } ! 308: ! 309: pfinis() ! 310: { ! 311: opindex(); ! 312: dumpcache("PATFLAG\tpatcache", CPAT); ! 313: fprintf(pfp, "int patcsize=sizeof(patcache)/sizeof(PATFLAG);\n"); ! 314: dumpcache("TYPESET\ttypecache", CTYPE); ! 315: dumpcache("FLAG\tflagcache", CFLAG); ! 316: dumpcache("ival_t\tivalcache", CICON); ! 317: dumpcache("lval_t\tlvalcache", CLCON); ! 318: dumpcache("char\t*gidcache", CGID); ! 319: fprintf(pfp, "#if !TINY\n"); ! 320: dumpcache("char\t*namecache", CFILE); ! 321: fprintf(pfp, "#endif\n"); ! 322: fclose(pfp); ! 323: } ! 324: ! 325: mfinis() ! 326: { ! 327: fprintf(mfp, " 0\n};\n"); ! 328: fclose(mfp); ! 329: } ! 330: ! 331: intro(fp) ! 332: FILE *fp; ! 333: { ! 334: fprintf(fp, "#ifdef vax\n"); ! 335: fprintf(fp, "#include \"INC$LIB:cc1.h\"\n"); ! 336: fprintf(fp, "#else\n"); ! 337: fprintf(fp, "#include \"cc1.h\"\n"); ! 338: fprintf(fp, "#endif\n"); ! 339: } ! 340: ! 341: ncompile() ! 342: { ! 343: extern char *rindex(); ! 344: for (fnseq = 0; fnseq < fargc; fnseq += 1) { ! 345: fname = fargv[fnseq]; ! 346: if ((ifp = fopen(fname, "r")) == NULL) { ! 347: fprintf(stderr, "%s: cannot open\n", fname); ! 348: exit(ABORT); ! 349: } ! 350: lineno = 0; ! 351: hiteof = 0; ! 352: fprintf(pfp, "/* %s */\n", fname); ! 353: fprintf(mfp, "/* %s */\n", fname); ! 354: if (rindex(fname, '/') != 0) ! 355: fname = rindex(fname, '/')+1; ! 356: findcache(fname, CFILE); ! 357: compile(); ! 358: if (tlevel!=0 || flevel!=0) ! 359: fatal("dangeling #if"); ! 360: fclose(ifp); ! 361: } ! 362: } ! 363: ! 364: compile() ! 365: { ! 366: register struct optable *opp; ! 367: register c; ! 368: struct optable *oplookup(); ! 369: char id[NCPS]; ! 370: int npat; ! 371: ! 372: c = getnb(); ! 373: while (c != EOF) { ! 374: if (!isalpha(c)) ! 375: fatal("missing op name"); ! 376: do { ! 377: getid(c, id); ! 378: opp = oplookup(id); ! 379: opp->o_seq = opseq; ! 380: if (getnb() != ':') ! 381: fatal("missing ':'"); ! 382: } while (isalpha(c = getnb())); ! 383: if (c != '%') ! 384: fatal("missing '%'"); ! 385: fprintf(pfp, "PAT p%d[] = {\n", opseq); ! 386: npat = 0; ! 387: do { ! 388: do { ! 389: pat(npat); ! 390: ++npat; ! 391: ++npats; ! 392: } while ((c = getnb()) == '%'); ! 393: if (c == EOF) ! 394: fatal("eof"); ! 395: unget(c); ! 396: c = body(); ! 397: } while (c == '%'); ! 398: fprintf(pfp, "\n};\n"); ! 399: for (opp = &optable[0]; opp < &optable[nel(optable)]; ++opp) ! 400: if (opp->o_seq == opseq) ! 401: opp->o_npat = npat; ! 402: ++opseq; ! 403: } ! 404: } ! 405: ! 406: pat(nth) ! 407: { ! 408: register char *cbp; ! 409: register int c; ! 410: register int i; ! 411: register int needtbar; ! 412: int pline; ! 413: /* ! 414: * Pattern fields requiring mapping with T_ prefixes ! 415: * and * translation. ! 416: */ ! 417: static int tbars[] = { ! 418: 0, ! 419: 0, 0, 0, 0, 0, ! 420: 1, 0, ! 421: 1, 0 ! 422: }; ! 423: static char none[] = " NONE"; ! 424: static char zero[] = " 0"; ! 425: static char *stars[] = { ! 426: zero, ! 427: zero, none, none, none, none, ! 428: zero, zero, ! 429: zero, zero ! 430: }; ! 431: ! 432: pline = lineno; ! 433: if (nth > 0) ! 434: fprintf(pfp, ",\n"); ! 435: fprintf(pfp, " {"); ! 436: for (i=0; i<10; ++i) { ! 437: cbp = pbuf; ! 438: if ((c = getnb()) == EOF) ! 439: fatal("eof"); ! 440: needtbar = tbars[i]; ! 441: do { ! 442: if (needtbar != 0) { ! 443: needtbar = 0; ! 444: if (c != '*') { ! 445: *cbp++ = 'T'; ! 446: *cbp++ = '_'; ! 447: } ! 448: } ! 449: *cbp++ = c; ! 450: if (c == '|') ! 451: needtbar = tbars[i]; ! 452: c = get(); ! 453: } while (c!=' ' && c!='\t' && c!='\n'); ! 454: *cbp++ = 0; ! 455: unget(c); ! 456: if (strcmp(pbuf, "*") == 0) ! 457: fprintf(pfp, stars[i]); ! 458: else { ! 459: switch (i) { ! 460: case 0: ! 461: fprintf(pfp, " %2d", findcache(pbuf, CPAT)); ! 462: break; ! 463: case 1: ! 464: case 7: ! 465: case 9: ! 466: fprintf(pfp, " %2d", findcache(pbuf, CTYPE)); ! 467: break; ! 468: case 6: ! 469: case 8: ! 470: fprintf(pfp, " %2d", findcache(pbuf, CFLAG)); ! 471: break; ! 472: default: ! 473: fprintf(pfp, " %4s", pbuf); ! 474: } ! 475: } ! 476: putc(',', pfp); ! 477: } ! 478: fprintf(pfp, " ¯os[%4d]", boffs); ! 479: fprintf(pfp, " fl(%d,%d)", fnseq, pline); ! 480: fprintf(pfp, " }"); ! 481: } ! 482: ! 483: findcache(p, t) ! 484: char *p; ! 485: { ! 486: register struct cache *cp; ! 487: ! 488: cp = cache; ! 489: while (cp != NULL) { ! 490: if (cp->c_type==t && strcmp(p, cp->c_data)==0) ! 491: return (cp->c_sequence); ! 492: cp = cp->c_fp; ! 493: } ! 494: cp = (struct cache *) malloc(sizeof(struct cache)+strlen(p)+1); ! 495: if (cp == NULL) ! 496: fatal("out of cache!"); ! 497: cp->c_fp = cache; ! 498: cache = cp; ! 499: cp->c_type = t; ! 500: cp->c_sequence = ++cacheseq[t]; ! 501: strcpy(cp->c_data, p); ! 502: return (cp->c_sequence); ! 503: } ! 504: ! 505: dumpcache(p, t) ! 506: char *p; ! 507: { ! 508: register struct cache *cp; ! 509: register int i; ! 510: ! 511: fprintf(pfp, "%s[] = {\n", p); ! 512: for (i=1; i<=cacheseq[t]; ++i) { ! 513: cp = cache; ! 514: while (cp != NULL) { ! 515: if (cp->c_type==t && cp->c_sequence==i) ! 516: break; ! 517: cp = cp->c_fp; ! 518: } ! 519: if (i > 1) ! 520: fprintf(pfp, ",\n\t"); ! 521: else ! 522: fprintf(pfp, "\t"); ! 523: if (t==CGID || t==CFILE) ! 524: fprintf(pfp, "\"%s\"", cp->c_data); ! 525: else ! 526: fprintf(pfp, "%s", cp->c_data); ! 527: } ! 528: if (i==1) ! 529: fprintf(pfp, "\t0"); ! 530: fprintf(pfp, "\n};\n"); ! 531: } ! 532: ! 533: struct optable * ! 534: oplookup(id) ! 535: register char *id; ! 536: { ! 537: register struct optable *opp; ! 538: ! 539: opp = &optable[0]; ! 540: while (opp < &optable[sizeof(optable)/sizeof(optable[0])]) { ! 541: if (strncmp(id, opp->o_id, NCPS) == 0) ! 542: return (opp); ! 543: ++opp; ! 544: } ! 545: fatal("operator not defined"); ! 546: } ! 547: ! 548: body() ! 549: { ! 550: int c; ! 551: ! 552: c = body1(); ! 553: body2(); ! 554: return (c); ! 555: } ! 556: ! 557: /* ! 558: * Parse body. ! 559: */ ! 560: body1() ! 561: { ! 562: register b, c; ! 563: static char id[NCPS]; ! 564: int iff; ! 565: ! 566: fprintf(mfp, "/* %4d */\n", boffs); ! 567: /* Read body and subsequent blank lines */ ! 568: for (;;) { ! 569: c = getnb(); ! 570: /* End of body reached */ ! 571: if (c==EOF || c=='%' || (c>='A' && c<='Z')) ! 572: break; ! 573: if (c == ';') ! 574: continue; /* Eat them */ ! 575: /* No conditional yet */ ! 576: iff = 0; ! 577: /* Parse line */ ! 578: do { ! 579: /* Eat intermediate spaces */ ! 580: while (c==' ' || c=='\t') ! 581: c = get(); ! 582: /* Catch trailing spaces */ ! 583: if (c == '\n') ! 584: break; ! 585: /* Read bracketed macros */ ! 586: if (c == '[') { ! 587: /* Until matching ] found */ ! 588: do { ! 589: /* No more tab spacing */ ! 590: while ((c = get()) == ' ') ! 591: ; ! 592: getid(c, id); ! 593: c = get(); ! 594: b = maclookup(id); ! 595: /* Output most macros */ ! 596: if (b != M_ICON && b != M_LCON) { ! 597: if (id[0] == 'Z') ! 598: mbyte(id); ! 599: else ! 600: mbar(id); ! 601: } ! 602: /* Output register name */ ! 603: if (b == M_REGNO) { ! 604: while (c == ' ') ! 605: c = get(); ! 606: getid(c, id); ! 607: mbyte(id); ! 608: c = get(); ! 609: } ! 610: /* Output identifier */ ! 611: if (b == M_GID) { ! 612: while (c == ' ') ! 613: c = get(); ! 614: getid(c, id); ! 615: mnum(findcache(id, CGID)); ! 616: c = get(); ! 617: } ! 618: /* Note conditional macros */ ! 619: if (b==M_IFR || b==M_IFV || b==M_IFE) ! 620: iff = 1; ! 621: /* Pack constants */ ! 622: if (b == M_ICON || b == M_LCON) ! 623: c = getcon(b, c); ! 624: } while (c == ' '); ! 625: if (c != ']') ! 626: fatal("missing ']' in macro"); ! 627: } ! 628: c = get(); ! 629: } while (c!=EOF && c!='\n'); ! 630: /* Terminate conditional */ ! 631: if (iff != 0) ! 632: mbyte("M_ENDIF"); ! 633: macv[nmac++] = m_newl; ! 634: if (nmac >= NMAC) ! 635: fatal("macro too big"); ! 636: } ! 637: /* Terminate macro */ ! 638: macv[nmac++] = m_end; ! 639: boffs += 1; ! 640: macv[nmac++] = m_newl; ! 641: return (c); ! 642: } ! 643: ! 644: maclookup(id) ! 645: register char *id; ! 646: { ! 647: register struct mtab *mtp; ! 648: ! 649: for (mtp = &mtab[0]; mtp < &mtab[sizeof(mtab)/sizeof(mtab[0])]; ++mtp) ! 650: if (strncmp(id, mtp->m_id, NCPS) == 0) { ! 651: return (mtp->m_byte); ! 652: } ! 653: return (-1); ! 654: } ! 655: ! 656: getcon(m, c) ! 657: int m; ! 658: register int c; ! 659: { ! 660: register long l; ! 661: register int b; ! 662: register char *p; ! 663: static char digita[] = "0123456789ABCDEF"; ! 664: static char digitb[] = "0123456789abcdef"; ! 665: static char nbuf[16]; ! 666: extern char *index(); ! 667: ! 668: while (c == ' ') ! 669: c = get(); ! 670: l = 0; ! 671: b = 10; ! 672: if (c == '0') { ! 673: b = 8; ! 674: c = get(); ! 675: if (c=='x' || c == 'X') { ! 676: b = 16; ! 677: c = get(); ! 678: } ! 679: } ! 680: for (;;) { ! 681: if ((p = index(digita, c)) && (p-digita) < b) ! 682: c = p - digita; ! 683: else if ((p = index(digitb, c)) && (p-digitb) < b) ! 684: c = p - digitb; ! 685: else ! 686: break; ! 687: l = b*l + c; ! 688: c = get(); ! 689: } ! 690: sprintf(nbuf, "0x%lx", l); ! 691: if (m == M_ICON) { ! 692: mbar("ICON"); ! 693: mnum(findcache(nbuf, CICON)); ! 694: } else { ! 695: strcat(nbuf, "L"); ! 696: mbar("LCON"); ! 697: mnum(findcache(nbuf, CLCON)); ! 698: } ! 699: return (c); ! 700: } ! 701: ! 702: mbyte(id) ! 703: char *id; ! 704: { ! 705: macv[nmac++] = mlookup(id); ! 706: boffs += 1; ! 707: } ! 708: ! 709: HASH * ! 710: mlookup(id) ! 711: char *id; ! 712: { ! 713: register HASH *sp; ! 714: register char *p; ! 715: register int i; ! 716: unsigned h; ! 717: ! 718: p = id; ! 719: h = 0; ! 720: i = NCPS; ! 721: while (--i >= 0) ! 722: if (*p) ! 723: h += *p++; ! 724: sp = &hash[h%NHASH]; ! 725: p = id; ! 726: i = NHASH; ! 727: while (--i >= 0) { ! 728: if (sp->s_name[0] == 0) { ! 729: strncpy(sp->s_name, p, NCPS); ! 730: return (sp); ! 731: } ! 732: if (strncmp(sp->s_name, p, NCPS) == 0) ! 733: return (sp); ! 734: if (++sp >= &hash[NHASH]) ! 735: sp = &hash[0]; ! 736: } ! 737: fatal("out of hash"); ! 738: } ! 739: ! 740: mbar(id) ! 741: register char *id; ! 742: { ! 743: static char t[NCPS] = "M_"; ! 744: ! 745: strncpy(t+2, id, NCPS-2); ! 746: mbyte(t); ! 747: } ! 748: ! 749: mnum(num) ! 750: int num; ! 751: { ! 752: static char t[] = "0x??"; ! 753: ! 754: mknum(t, num); ! 755: mbyte(t); ! 756: } ! 757: ! 758: mknum(id, n) ! 759: register char *id; ! 760: register int n; ! 761: { ! 762: static char d[] = "0123456789ABCDEF"; ! 763: ! 764: id[0] = '0'; ! 765: id[1] = 'x'; ! 766: id[3] = d[n&0xf]; ! 767: n >>= 4; ! 768: id[2] = d[n&0xf]; ! 769: id[4] = 0; ! 770: } ! 771: ! 772: /* ! 773: * Match body into reverse sorted tree, ! 774: * replace common ends with jumps, ! 775: * print body. ! 776: */ ! 777: body2() ! 778: { ! 779: int sboffs; /* Saved byte size of macro */ ! 780: int jto; /* Byte offset to jump to */ ! 781: int jfrom; /* Byte offset to jump from */ ! 782: int jnmac; /* The element which becomes M_JMP */ ! 783: int noto; /* We're in the middle of a macro, don't jump */ ! 784: register SORT **tpp; ! 785: register HASH *sp; ! 786: static char t1[] = "0x??"; ! 787: static char t2[] = "0x??"; ! 788: register int i; ! 789: ! 790: sboffs = boffs; ! 791: jto = -1; ! 792: tpp = &root; ! 793: i = nmac; ! 794: /* For each input macro element */ ! 795: while (--i >= 0) { ! 796: /* Avoid gotos from within two byte macros */ ! 797: noto = 0; ! 798: if (i > 0) { ! 799: sp = macv[i-1]; ! 800: if (sp==m_gid || sp==m_icon || sp==m_lcon) ! 801: noto += 1; ! 802: } ! 803: /* Count down the byte offset */ ! 804: if ((sp = macv[i]) != m_newl) ! 805: boffs -= 1; ! 806: /* Until match or new entry */ ! 807: for (;;) { ! 808: /* New entry */ ! 809: if (*tpp == NULL) { ! 810: if ((*tpp = malloc(sizeof(SORT))) == NULL) ! 811: fatal("out of trees"); ! 812: (*tpp)->t_boffs = boffs; ! 813: (*tpp)->t_symb = sp; ! 814: (*tpp)->t_diff = NULL; ! 815: (*tpp)->t_same = NULL; ! 816: break; ! 817: } ! 818: /* Match */ ! 819: if ((*tpp)->t_symb == sp) { ! 820: if (noto == 0) { ! 821: jto = (*tpp)->t_boffs; ! 822: jfrom = boffs; ! 823: jnmac = i; ! 824: } ! 825: break; ! 826: } ! 827: /* Search for match or empty */ ! 828: tpp = &(*tpp)->t_same; ! 829: } ! 830: /* Advance to next element in macro */ ! 831: tpp = &(*tpp)->t_diff; ! 832: } ! 833: /* Ignore any matches if nflag is set */ ! 834: if (nflag) ! 835: jto = -1; ! 836: /* See if we found a jump */ ! 837: if (jto >= 0) { ! 838: /* Make the offset strings for each form of jump */ ! 839: if (jto < 256) { ! 840: mknum(t1, jto); ! 841: i = 2; ! 842: } else if ((jfrom-jto) < 256) { ! 843: mknum(t1, jfrom-jto); ! 844: i = 2; ! 845: } else { ! 846: mknum(t1, jto); ! 847: mknum(t2, jto>>8); ! 848: i = 3; ! 849: } ! 850: /* If we save space, make the jump */ ! 851: if ((jfrom+i) < sboffs) { ! 852: nmac = jnmac; ! 853: if (nmac != 0 && macv[nmac-1] != m_newl) ! 854: macv[nmac++] = m_newl; ! 855: macv[nmac++] = m_jmp; ! 856: } ! 857: } ! 858: /* Print out the macro */ ! 859: for (i = 0; --nmac > 0; i += 1) ! 860: if ((sp = macv[i]) == m_newl) ! 861: putc('\n', mfp); ! 862: else { ! 863: if (i==0 || macv[i-1] == m_newl) ! 864: putc('\t', mfp); ! 865: else ! 866: putc(' ', mfp); ! 867: fprintf(mfp, "%.8s,", sp->s_name); ! 868: boffs += 1; ! 869: } ! 870: /* The last entry is m_jmp or a m_newl */ ! 871: if (macv[i] == m_jmp) { ! 872: if (jto < 256) { ! 873: fprintf(mfp, "\tM_JMP1, %s,\t\t", t1); ! 874: boffs += 2; ! 875: } else if ((jfrom-jto) < 256) { ! 876: fprintf(mfp, "\tM_JMPB, %s,\t\t", t1); ! 877: boffs += 2; ! 878: } else { ! 879: fprintf(mfp, "\tM_JMP2, %s, %s,\t", t1, t2); ! 880: boffs += 3; ! 881: } ! 882: /* Identify the destination */ ! 883: fprintf(mfp, "/* %d */\n", jto); ! 884: } else ! 885: putc('\n', mfp); ! 886: bsave += sboffs - boffs; ! 887: } ! 888: ! 889: getnb() ! 890: { ! 891: register int c; ! 892: ! 893: while ((c=get())==' ' || c=='\t' || c=='\n') ! 894: ; ! 895: return (c); ! 896: } ! 897: ! 898: get() ! 899: { ! 900: register char *p1; ! 901: register char *p2; ! 902: register int c; ! 903: register int hitslash; ! 904: register int isdef; ! 905: register int i; ! 906: ! 907: if ((c=ungetc) >= 0) { ! 908: ungetc = -1; ! 909: return (c); ! 910: } ! 911: if (hiteof != 0) ! 912: return (EOF); ! 913: while (getnc == 0) { ! 914: p1 = &getbuf[0]; ! 915: hitslash = 0; ! 916: while ((c=getc(ifp))!=EOF && c!='\n') { ! 917: if (hitslash == 0) { ! 918: if (c == '/') ! 919: hitslash = 1; ! 920: else ! 921: *p1++ = c; ! 922: } ! 923: } ! 924: if (c == EOF) { ! 925: hiteof = 1; ! 926: return (EOF); ! 927: } ! 928: *p1++ = '\n'; ! 929: ++lineno; ! 930: if (getbuf[0] == '#') { ! 931: static char endif[] = "endif"; ! 932: static char ifdef[] = "ifdef"; ! 933: static char ifndef[] = "ifndef"; ! 934: ! 935: p2 = &getbuf[1]; ! 936: if (match(p2, endif)) { ! 937: if (tlevel != 0) ! 938: --tlevel; ! 939: else if (flevel != 0) ! 940: --flevel; ! 941: else ! 942: fatal(endif); ! 943: if ((tlevel+flevel) == 0) ! 944: fprintf(pfp, "\n/* #%s */", endif); ! 945: continue; ! 946: } ! 947: if (match(p2, ifdef) || match(p2, ifndef)) { ! 948: if (flevel != 0) { ! 949: ++flevel; ! 950: continue; ! 951: } ! 952: while ((c = *p2)!=' ' && c!='\t' && c!='\n') ! 953: ++p2; ! 954: while ((c = *p2)==' ' || c=='\t') ! 955: ++p2; ! 956: if (c == '\n') ! 957: fatal("if name"); ! 958: p1 = p2; ! 959: while (*p2!=' ' && *p2!='\t' && *p2!='\n') ! 960: ++p2; ! 961: *p2 = 0; ! 962: isdef = 0; ! 963: for (i=0; i<ndef; ++i) { ! 964: if (strcmp(def[i], p1) == 0) { ! 965: isdef = 1; ! 966: break; ! 967: } ! 968: } ! 969: if (getbuf[3] == 'n') /* #ifndef */ ! 970: isdef = !isdef; ! 971: if (isdef != 0) ! 972: ++tlevel; ! 973: else ! 974: ++flevel; ! 975: fprintf(pfp, "\n/* %s */", getbuf); ! 976: continue; ! 977: } ! 978: if (flevel == 0) { ! 979: p2 = &getbuf[0]; ! 980: while (p2 < p1) ! 981: putc(*p2++, pfp); ! 982: } ! 983: continue; ! 984: } ! 985: if (flevel == 0) { ! 986: getnc = p1 - &getbuf[0]; ! 987: getcp = &getbuf[0]; ! 988: } ! 989: } ! 990: --getnc; ! 991: return (*getcp++); ! 992: } ! 993: ! 994: unget(c) ! 995: { ! 996: ungetc = c; ! 997: } ! 998: ! 999: getid(c, id) ! 1000: register c; ! 1001: char id[]; ! 1002: { ! 1003: register char *p; ! 1004: ! 1005: if (!isalpha(c) && c != '_') ! 1006: fatal("missing identifier"); ! 1007: p = id; ! 1008: do { ! 1009: if (p < &id[NCPS]) ! 1010: *p++ = c; ! 1011: c = get(); ! 1012: } while (isalnum(c)); ! 1013: while (p < &id[NCPS]) ! 1014: *p++ = 0; ! 1015: unget(c); ! 1016: } ! 1017: ! 1018: fatal(s) ! 1019: char *s; ! 1020: { ! 1021: fprintf(stderr, "%s: %d: %s\n", fname, lineno, s); ! 1022: exit(ABORT); ! 1023: } ! 1024: ! 1025: opindex() ! 1026: { ! 1027: register struct optable *opp; ! 1028: ! 1029: fprintf(pfp, "PATX patx[] = {\n"); ! 1030: opp = &optable[0]; ! 1031: while (opp < &optable[nel(optable)]) { ! 1032: fprintf(pfp, "\t"); ! 1033: if (opp->o_seq == 0) ! 1034: fprintf(pfp, "NULL,\t0"); ! 1035: else ! 1036: fprintf(pfp, "p%d,\t%d", opp->o_seq, opp->o_npat); ! 1037: if (opp != &optable[nel(optable)-1]) ! 1038: putc(',', pfp); ! 1039: putc('\n', pfp); ! 1040: ++opp; ! 1041: } ! 1042: fprintf(pfp, "};\n"); ! 1043: } ! 1044: ! 1045: match(p1, p2) ! 1046: register char *p1; ! 1047: register char *p2; ! 1048: { ! 1049: register int c; ! 1050: ! 1051: while ((c = *p2++) != 0) { ! 1052: if (*p1++ != c) ! 1053: return (0); ! 1054: } ! 1055: return (1); ! 1056: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.