Annotation of researchv10no/lbin/csh/sh.parse.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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