Annotation of 41BSD/cmd/oldcsh/sh.parse.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1979 Regents of the University of California */
                      2: #include "sh.h"
                      3: 
                      4: /*
                      5:  * C shell
                      6:  */
                      7: 
                      8: /*
                      9:  * Perform aliasing on the word list lex
                     10:  * Do a (very rudimentary) parse to separate into commands.
                     11:  * If word 0 of a command has an alias, do it.
                     12:  * Repeat a maximum of 20 times.
                     13:  */
                     14: alias(lex)
                     15:        register struct wordent *lex;
                     16: {
                     17:        int aleft = 21;
                     18:        jmp_buf osetexit;
                     19: 
                     20:        getexit(osetexit);
                     21:        setexit();
                     22:        if (haderr) {
                     23:                resexit(osetexit);
                     24:                reset();
                     25:        }
                     26:        if (--aleft == 0)
                     27:                error("Alias loop");
                     28:        asyntax(lex->next, lex);
                     29:        resexit(osetexit);
                     30: }
                     31: 
                     32: asyntax(p1, p2)
                     33:        register struct wordent *p1, *p2;
                     34: {
                     35: 
                     36:        while (p1 != p2)
                     37:                if (any(p1->word[0], ";&\n"))
                     38:                        p1 = p1->next;
                     39:                else {
                     40:                        asyn0(p1, p2);
                     41:                        return;
                     42:                }
                     43: }
                     44: 
                     45: asyn0(p1, p2)
                     46:        struct wordent *p1;
                     47:        register struct wordent *p2;
                     48: {
                     49:        register struct wordent *p;
                     50:        register int l = 0;
                     51: 
                     52:        for (p = p1; p != p2; p = p->next)
                     53:                switch (p->word[0]) {
                     54: 
                     55:                case '(':
                     56:                        l++;
                     57:                        continue;
                     58: 
                     59:                case ')':
                     60:                        l--;
                     61:                        if (l < 0)
                     62:                                error("Too many )'s");
                     63:                        continue;
                     64: 
                     65:                case '>':
                     66:                        if (p->next != p2 && eq(p->next->word, "&"))
                     67:                                p = p->next;
                     68:                        continue;
                     69: 
                     70:                case '&':
                     71:                case '|':
                     72:                case ';':
                     73:                case '\n':
                     74:                        if (l != 0)
                     75:                                continue;
                     76:                        asyn3(p1, p);
                     77:                        asyntax(p->next, p2);
                     78:                        return;
                     79:                }
                     80:        if (l == 0)
                     81:                asyn3(p1, p2);
                     82: }
                     83: 
                     84: asyn3(p1, p2)
                     85:        struct wordent *p1;
                     86:        register struct wordent *p2;
                     87: {
                     88:        register struct varent *ap;
                     89:        struct wordent alout;
                     90:        register bool redid;
                     91: 
                     92:        if (p1 == p2)
                     93:                return;
                     94:        if (p1->word[0] == '(') {
                     95:                for (p2 = p2->prev; p2->word[0] != ')'; p2 = p2->prev)
                     96:                        if (p2 == p1)
                     97:                                return;
                     98:                if (p2 == p1->next)
                     99:                        return;
                    100:                asyn0(p1->next, p2);
                    101:                return;
                    102:        }
                    103:        ap = adrof1(p1->word, &aliases);
                    104:        if (ap == 0)
                    105:                return;
                    106:        alhistp = p1->prev;
                    107:        alhistt = p2;
                    108:        alvec = ap->vec;
                    109:        redid = lex(&alout);
                    110:        alhistp = alhistt = 0;
                    111:        alvec = 0;
                    112:        if (err) {
                    113:                freelex(&alout);
                    114:                error(err);
                    115:        }
                    116:        if (p1->word[0] && eq(p1->word, alout.next->word)) {
                    117:                char *cp = alout.next->word;
                    118: 
                    119:                alout.next->word = strspl("\200", cp);
                    120:                xfree(cp);
                    121:        }
                    122:        p1 = freenod(p1, redid ? p2 : p1->next);
                    123:        if (alout.next != &alout) {
                    124:                p1->next->prev = alout.prev->prev;
                    125:                alout.prev->prev->next = p1->next;
                    126:                alout.next->prev = p1;
                    127:                p1->next = alout.next;
                    128:                xfree(alout.prev->word);
                    129:                xfree(alout.prev);
                    130:        }
                    131:        reset();                /* throw! */
                    132: }
                    133: 
                    134: struct wordent *
                    135: freenod(p1, p2)
                    136:        register struct wordent *p1, *p2;
                    137: {
                    138:        register struct wordent *retp = p1->prev;
                    139: 
                    140:        while (p1 != p2) {
                    141:                xfree(p1->word);
                    142:                p1 = p1->next;
                    143:                xfree(p1->prev);
                    144:        }
                    145:        retp->next = p2;
                    146:        p2->prev = retp;
                    147:        return (retp);
                    148: }
                    149: 
                    150: #define        PHERE   1
                    151: #define        PIN     2
                    152: #define        POUT    4
                    153: #define        PDIAG   8
                    154: 
                    155: /*
                    156:  * syntax
                    157:  *     empty
                    158:  *     syn0
                    159:  */
                    160: struct command *
                    161: syntax(p1, p2, flags)
                    162:        register struct wordent *p1, *p2;
                    163:        int flags;
                    164: {
                    165: 
                    166:        while (p1 != p2)
                    167:                if (any(p1->word[0], ";&\n"))
                    168:                        p1 = p1->next;
                    169:                else
                    170:                        return (syn0(p1, p2, flags));
                    171:        return (0);
                    172: }
                    173: 
                    174: /*
                    175:  * syn0
                    176:  *     syn1
                    177:  *     syn1 & syntax
                    178:  */
                    179: struct command *
                    180: syn0(p1, p2, flags)
                    181:        struct wordent *p1, *p2;
                    182:        int flags;
                    183: {
                    184:        register struct wordent *p;
                    185:        register struct command *t, *t1;
                    186:        int l;
                    187: 
                    188:        l = 0;
                    189:        for (p = p1; p != p2; p = p->next)
                    190:                switch (p->word[0]) {
                    191: 
                    192:                case '(':
                    193:                        l++;
                    194:                        continue;
                    195: 
                    196:                case ')':
                    197:                        l--;
                    198:                        if (l < 0)
                    199:                                seterr("Too many )'s");
                    200:                        continue;
                    201: 
                    202:                case '|':
                    203:                        if (p->word[1] == '|')
                    204:                                continue;
                    205:                        /* fall into ... */
                    206: 
                    207:                case '>':
                    208:                        if (p->next != p2 && eq(p->next->word, "&"))
                    209:                                p = p->next;
                    210:                        continue;
                    211: 
                    212:                case '&':
                    213:                        if (l != 0)
                    214:                                break;
                    215:                        if (p->word[1] == '&')
                    216:                                continue;
                    217:                        t1 = syn1(p1, p, flags);
                    218:                        if (t1->t_dtyp == TLST) {
                    219:                                t = (struct command *) calloc(1, sizeof (*t));
                    220:                                t->t_dtyp = TPAR;
                    221:                                t->t_dflg = FAND|FPRS|FINT;
                    222:                                t->t_dspr = t1;
                    223:                                t1 = t;
                    224:                        } else
                    225:                                t1->t_dflg |= FAND|FPRS|FINT;
                    226:                        t = (struct command *) calloc(1, sizeof (*t));
                    227:                        t->t_dtyp = TLST;
                    228:                        t->t_dflg = 0;
                    229:                        t->t_dcar = t1;
                    230:                        t->t_dcdr = syntax(p, p2, flags);
                    231:                        return(t);
                    232:                }
                    233:        if (l == 0)
                    234:                return (syn1(p1, p2, flags));
                    235:        seterr("Too many ('s");
                    236:        return (0);
                    237: }
                    238: 
                    239: /*
                    240:  * syn1
                    241:  *     syn1a
                    242:  *     syn1a ; syntax
                    243:  */
                    244: struct command *
                    245: syn1(p1, p2, flags)
                    246:        struct wordent *p1, *p2;
                    247:        int flags;
                    248: {
                    249:        register struct wordent *p;
                    250:        register struct command *t;
                    251:        int l;
                    252: 
                    253:        l = 0;
                    254:        for (p = p1; p != p2; p = p->next)
                    255:                switch (p->word[0]) {
                    256: 
                    257:                case '(':
                    258:                        l++;
                    259:                        continue;
                    260: 
                    261:                case ')':
                    262:                        l--;
                    263:                        continue;
                    264: 
                    265:                case ';':
                    266:                case '\n':
                    267:                        if (l != 0)
                    268:                                break;
                    269:                        t = (struct command *) calloc(1, sizeof (*t));
                    270:                        t->t_dtyp = TLST;
                    271:                        t->t_dcar = syn1a(p1, p, flags);
                    272:                        t->t_dcdr = syntax(p->next, p2, flags);
                    273:                        if (t->t_dcdr == 0)
                    274:                                t->t_dcdr = t->t_dcar, t->t_dcar = 0;
                    275:                        return (t);
                    276:                }
                    277:        return (syn1a(p1, p2, flags));
                    278: }
                    279: 
                    280: /*
                    281:  * syn1a
                    282:  *     syn1b
                    283:  *     syn1b || syn1a
                    284:  */
                    285: struct command *
                    286: syn1a(p1, p2, flags)
                    287:        struct wordent *p1, *p2;
                    288:        int flags;
                    289: {
                    290:        register struct wordent *p;
                    291:        register struct command *t;
                    292:        register int l = 0;
                    293: 
                    294:        for (p = p1; p != p2; p = p->next)
                    295:                switch (p->word[0]) {
                    296: 
                    297:                case '(':
                    298:                        l++;
                    299:                        continue;
                    300: 
                    301:                case ')':
                    302:                        l--;
                    303:                        continue;
                    304: 
                    305:                case '|':
                    306:                        if (p->word[1] != '|')
                    307:                                continue;
                    308:                        if (l == 0) {
                    309:                                t = (struct command *) calloc(1, sizeof (*t));
                    310:                                t->t_dtyp = TOR;
                    311:                                t->t_dcar = syn1b(p1, p, flags);
                    312:                                t->t_dcdr = syn1a(p->next, p2, flags);
                    313:                                t->t_dflg = 0;
                    314:                                return (t);
                    315:                        }
                    316:                        continue;
                    317:                }
                    318:        return (syn1b(p1, p2, flags));
                    319: }
                    320: 
                    321: /*
                    322:  * syn1b
                    323:  *     syn2
                    324:  *     syn2 && syn1b
                    325:  */
                    326: struct command *
                    327: syn1b(p1, p2, flags)
                    328:        struct wordent *p1, *p2;
                    329:        int flags;
                    330: {
                    331:        register struct wordent *p;
                    332:        register struct command *t;
                    333:        register int l = 0;
                    334: 
                    335:        l = 0;
                    336:        for (p = p1; p != p2; p = p->next)
                    337:                switch (p->word[0]) {
                    338: 
                    339:                case '(':
                    340:                        l++;
                    341:                        continue;
                    342: 
                    343:                case ')':
                    344:                        l--;
                    345:                        continue;
                    346: 
                    347:                case '&':
                    348:                        if (p->word[1] == '&' && l == 0) {
                    349:                                t = (struct command *) calloc(1, sizeof (*t));
                    350:                                t->t_dtyp = TAND;
                    351:                                t->t_dcar = syn2(p1, p, flags);
                    352:                                t->t_dcdr = syn1b(p->next, p2, flags);
                    353:                                t->t_dflg = 0;
                    354:                                return (t);
                    355:                        }
                    356:                        continue;
                    357:                }
                    358:        return (syn2(p1, p2, flags));
                    359: }
                    360: 
                    361: /*
                    362:  * syn2
                    363:  *     syn3
                    364:  *     syn3 | syn2
                    365:  *     syn3 |& syn2
                    366:  */
                    367: struct command *
                    368: syn2(p1, p2, flags)
                    369:        struct wordent *p1, *p2;
                    370:        int flags;
                    371: {
                    372:        register struct wordent *p, *pn;
                    373:        register struct command *t;
                    374:        register int l = 0;
                    375:        int f;
                    376: 
                    377:        for (p = p1; p != p2; p = p->next)
                    378:                switch (p->word[0]) {
                    379: 
                    380:                case '(':
                    381:                        l++;
                    382:                        continue;
                    383: 
                    384:                case ')':
                    385:                        l--;
                    386:                        continue;
                    387: 
                    388:                case '|':
                    389:                        if (l != 0)
                    390:                                continue;
                    391:                        t = (struct command *) calloc(1, sizeof (*t));
                    392:                        f = flags | POUT;
                    393:                        pn = p->next;
                    394:                        if (pn != p2 && pn->word[0] == '&') {
                    395:                                f |= PDIAG;
                    396:                                t->t_dflg |= FDIAG;
                    397:                        }
                    398:                        t->t_dtyp = TFIL;
                    399:                        t->t_dcar = syn3(p1, p, f);
                    400:                        if (pn != p2 && pn->word[0] == '&')
                    401:                                p = pn;
                    402:                        t->t_dcdr = syn2(p->next, p2, flags | PIN);
                    403:                        return (t);
                    404:                }
                    405:        return (syn3(p1, p2, flags));
                    406: }
                    407: 
                    408: char   *RELPAR =       "<>()";
                    409: 
                    410: /*
                    411:  * syn3
                    412:  *     ( syn0 ) [ < in  ] [ > out ]
                    413:  *     word word* [ < in ] [ > out ]
                    414:  *     KEYWORD ( word* ) word* [ < in ] [ > out ]
                    415:  *
                    416:  *     KEYWORD = (@ exit foreach if set switch test while)
                    417:  */
                    418: struct command *
                    419: syn3(p1, p2, flags)
                    420:        struct wordent *p1, *p2;
                    421:        int flags;
                    422: {
                    423:        register struct wordent *p;
                    424:        struct wordent *lp, *rp;
                    425:        register struct command *t;
                    426:        register int l;
                    427:        char **av;
                    428:        int n, c;
                    429:        bool specp = 0;
                    430: 
                    431:        if (p1 != p2) {
                    432:                p = p1;
                    433: again:
                    434:                switch (srchx(p->word)) {
                    435: 
                    436:                case ZELSE:
                    437:                        p = p->next;
                    438:                        if (p != p2)
                    439:                                goto again;
                    440:                        break;
                    441: 
                    442:                case ZEXIT:
                    443:                case ZFOREACH:
                    444:                case ZIF:
                    445:                case ZLET:
                    446:                case ZSET:
                    447:                case ZSWITCH:
                    448:                case ZWHILE:
                    449:                        specp = 1;
                    450:                        break;
                    451:                }
                    452:        }
                    453:        n = 0;
                    454:        l = 0;
                    455:        for (p = p1; p != p2; p = p->next)
                    456:                switch (p->word[0]) {
                    457: 
                    458:                case '(':
                    459:                        if (specp)
                    460:                                n++;
                    461:                        l++;
                    462:                        continue;
                    463: 
                    464:                case ')':
                    465:                        if (specp)
                    466:                                n++;
                    467:                        l--;
                    468:                        continue;
                    469: 
                    470:                case '>':
                    471:                case '<':
                    472:                        if (l != 0) {
                    473:                                if (specp)
                    474:                                        n++;
                    475:                                continue;
                    476:                        }
                    477:                        if (p->next == p2)
                    478:                                continue;
                    479:                        if (any(p->next->word[0], RELPAR))
                    480:                                continue;
                    481:                        n--;
                    482:                        continue;
                    483: 
                    484:                default:
                    485:                        if (!specp && l != 0)
                    486:                                continue;
                    487:                        n++;
                    488:                        continue;
                    489:                }
                    490:        if (n < 0)
                    491:                n = 0;
                    492:        t = (struct command *) calloc(1, sizeof (*t));
                    493:        av = (char **) calloc(n + 1, sizeof (char **));
                    494:        t->t_dcom = av;
                    495:        n = 0;
                    496:        if (p2->word[0] == ')')
                    497:                t->t_dflg = FPAR;
                    498:        lp = 0;
                    499:        rp = 0;
                    500:        l = 0;
                    501:        for (p = p1; p != p2; p = p->next) {
                    502:                c = p->word[0];
                    503:                switch (c) {
                    504: 
                    505:                case '(':
                    506:                        if (l == 0) {
                    507:                                if (lp != 0 && !specp)
                    508:                                        seterr("Badly placed (");
                    509:                                lp = p->next;
                    510:                        }
                    511:                        l++;
                    512:                        goto savep;
                    513: 
                    514:                case ')':
                    515:                        l--;
                    516:                        if (l == 0)
                    517:                                rp = p;
                    518:                        goto savep;
                    519: 
                    520:                case '>':
                    521:                        if (l != 0)
                    522:                                goto savep;
                    523:                        if (p->word[1] == '>')
                    524:                                t->t_dflg |= FCAT;
                    525:                        if (p->next != p2 && eq(p->next->word, "&")) {
                    526:                                t->t_dflg |= FDIAG, p = p->next;
                    527:                                if (flags & (POUT|PDIAG))
                    528:                                        goto badout;
                    529:                        }
                    530:                        if (p->next != p2 && eq(p->next->word, "!"))
                    531:                                t->t_dflg |= FANY, p = p->next;
                    532:                        if (p->next == p2) {
                    533: missfile:
                    534:                                seterr("Missing name for redirect");
                    535:                                continue;
                    536:                        }
                    537:                        p = p->next;
                    538:                        if (any(p->word[0], RELPAR))
                    539:                                goto missfile;
                    540:                        if ((flags & POUT) && (flags & PDIAG) == 0 || t->t_drit)
                    541: badout:
                    542:                                seterr("Ambiguous output redirect");
                    543:                        else
                    544:                                t->t_drit = savestr(p->word);
                    545:                        continue;
                    546: 
                    547:                case '<':
                    548:                        if (l != 0)
                    549:                                goto savep;
                    550:                        if (p->word[1] == '<')
                    551:                                t->t_dflg |= FHERE;
                    552:                        if (p->next == p2)
                    553:                                goto missfile;
                    554:                        p = p->next;
                    555:                        if (any(p->word[0], RELPAR))
                    556:                                goto missfile;
                    557:                        if ((flags & PHERE) && (t->t_dflg & FHERE))
                    558:                                seterr("Can't << within ()'s");
                    559:                        else if ((flags & PIN) || t->t_dlef)
                    560:                                seterr("Ambiguous input redirect");
                    561:                        else
                    562:                                t->t_dlef = savestr(p->word);
                    563:                        continue;
                    564: 
                    565: savep:
                    566:                        if (!specp)
                    567:                                continue;
                    568:                default:
                    569:                        if (l != 0 && !specp)
                    570:                                continue;
                    571:                        if (err == 0)
                    572:                                av[n] = savestr(p->word);
                    573:                        n++;
                    574:                        continue;
                    575:                }
                    576:        }
                    577:        if (lp != 0 && !specp) {
                    578:                if (n != 0)
                    579:                        seterr("Badly placed ()'s");
                    580:                t->t_dtyp = TPAR;
                    581:                t->t_dspr = syn0(lp, rp, PHERE);
                    582:        } else {
                    583:                if (n == 0)
                    584:                        seterr("Invalid null command");
                    585:                t->t_dtyp = TCOM;
                    586:        }
                    587:        return (t);
                    588: }
                    589: 
                    590: freesyn(t)
                    591:        register struct command *t;
                    592: {
                    593:        register char **v;
                    594: 
                    595:        if (t == 0)
                    596:                return;
                    597:        switch (t->t_dtyp) {
                    598: 
                    599:        case TCOM:
                    600:                for (v = t->t_dcom; *v; v++)
                    601:                        xfree(*v);
                    602:                xfree(t->t_dcom);
                    603:                goto lr;
                    604: 
                    605:        case TPAR:
                    606:                freesyn(t->t_dspr);
                    607:                /* fall into ... */
                    608: 
                    609: lr:
                    610:                xfree(t->t_dlef), xfree(t->t_drit);
                    611:                break;
                    612: 
                    613:        case TAND:
                    614:        case TOR:
                    615:        case TFIL:
                    616:        case TLST:
                    617:                freesyn(t->t_dcar), freesyn(t->t_dcdr);
                    618:                break;
                    619:        }
                    620:        xfree(t);
                    621: }

unix.superglobalmegacorp.com

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