Annotation of coherent/b/bin/c/coh/tabgen.c, revision 1.1.1.1

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, " &macros[%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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.