Annotation of 43BSDTahoe/bin/csh/sh.parse.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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