Annotation of researchv10dc/cmd/efl/efixsrc/process.c, revision 1.1.1.1

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:        }

unix.superglobalmegacorp.com

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