Annotation of researchv9/cmd/sh/cmd.c, revision 1.1.1.1

1.1       root        1: /*     @(#)cmd.c       1.5     */
                      2: /*
                      3:  * UNIX shell
                      4:  *
                      5:  * Bell Telephone Laboratories
                      6:  *
                      7:  */
                      8: 
                      9: #include       "defs.h"
                     10: #include       "sym.h"
                     11: 
                     12: static struct ionod *  inout();
                     13: static int     chkword();
                     14: static int     chksym();
                     15: static struct trenod * term();
                     16: static struct trenod * makelist();
                     17: static struct trenod * list();
                     18: static struct regnod * syncase();
                     19: static struct trenod * item();
                     20: static int     skipnl();
                     21: static int     prsym();
                     22: static int     synbad();
                     23: 
                     24: 
                     25: /* ======== storage allocation for functions ======== */
                     26: 
                     27: char *
                     28: getstor(asize)
                     29:        int asize;
                     30: {
                     31:        if (fndef)
                     32:                return(shalloc(asize));
                     33:        else
                     34:                return(getstak(asize));
                     35: }
                     36: 
                     37: 
                     38: /* ========    command line decoding   ========*/
                     39: 
                     40: 
                     41: 
                     42: 
                     43: struct trenod *
                     44: makefork(flgs, i)
                     45:        int     flgs;
                     46:        struct trenod *i;
                     47: {
                     48:        register struct forknod *t;
                     49: 
                     50:        t = (struct forknod *)getstor(sizeof(struct forknod));
                     51:        t->forktyp = flgs|TFORK;
                     52:        t->forktre = i;
                     53:        t->forkio = 0;
                     54:        return((struct trenod *)t);
                     55: }
                     56: 
                     57: static struct trenod *
                     58: makelist(type, i, r)
                     59:        int     type;
                     60:        struct trenod *i, *r;
                     61: {
                     62:        register struct lstnod *t;
                     63: 
                     64:        if (i == 0 || r == 0)
                     65:                synbad();
                     66:        else
                     67:        {
                     68:                t = (struct lstnod *)getstor(sizeof(struct lstnod));
                     69:                t->lsttyp = type;
                     70:                t->lstlef = i;
                     71:                t->lstrit = r;
                     72:        }
                     73:        return((struct trenod *)t);
                     74: }
                     75: 
                     76: /*
                     77:  * cmd
                     78:  *     empty
                     79:  *     list
                     80:  *     list & [ cmd ]
                     81:  *     list [ ; cmd ]
                     82:  */
                     83: struct trenod *
                     84: cmd(sym, flg)
                     85:        register int    sym;
                     86:        int             flg;
                     87: {
                     88:        register struct trenod *i, *e;
                     89: 
                     90:        i = list(flg);
                     91:        if (wdval == NL)
                     92:        {
                     93:                if (flg & NLFLG)
                     94:                {
                     95:                        wdval = ';';
                     96:                        chkpr();
                     97:                }
                     98:        }
                     99:        else if (i == 0 && (flg & MTFLG) == 0)
                    100:                synbad();
                    101: 
                    102:        switch (wdval)
                    103:        {
                    104:        case '&':
                    105:                if (i)
                    106:                        i = makefork(FINT | FPRS | FAMP, i);
                    107:                else
                    108:                        synbad();
                    109: 
                    110:        case ';':
                    111:                if (e = cmd(sym, flg | MTFLG))
                    112:                        i = makelist(TLST, i, e);
                    113:                else if (i==0 && (flg & MTFLG) == 0)
                    114:                        synbad();
                    115:                break;
                    116: 
                    117:        case EOFSYM:
                    118:                if (sym == NL)
                    119:                        break;
                    120: 
                    121:        default:
                    122:                if (sym)
                    123:                        chksym(sym);
                    124:        }
                    125:        return(i);
                    126: }
                    127: 
                    128: /*
                    129:  * list
                    130:  *     term
                    131:  *     list && term
                    132:  *     list || term
                    133:  */
                    134: static struct trenod *
                    135: list(flg)
                    136: {
                    137:        register struct trenod *r;
                    138:        register int            b;
                    139: 
                    140:        r = term(flg);
                    141:        while (r && ((b = (wdval == ANDFSYM)) || wdval == ORFSYM))
                    142:                r = makelist((b ? TAND : TORF), r, term(NLFLG));
                    143:        return(r);
                    144: }
                    145: 
                    146: /*
                    147:  * term
                    148:  *     item
                    149:  *     item | term
                    150:  */
                    151: static struct trenod *
                    152: term(flg)
                    153: {
                    154:        register struct trenod *t;
                    155: 
                    156:        reserv++;
                    157:        if (flg & NLFLG)
                    158:                skipnl();
                    159:        else
                    160:                word();
                    161:        if ((t = item(TRUE)) && wdval == '|')
                    162:        {
                    163:                struct trenod   *left;
                    164:                struct trenod   *right;
                    165: 
                    166:                left = makefork(FPOU, t);
                    167:                right = makefork(FPIN | FPCL, term(NLFLG));
                    168:                return(makefork(0, makelist(TFIL, left, right)));
                    169:        }
                    170:        else
                    171:                return(t);
                    172: }
                    173: 
                    174: static struct regnod *
                    175: syncase(esym)
                    176: register int   esym;
                    177: {
                    178:        skipnl();
                    179:        if (wdval == esym)
                    180:                return(0);
                    181:        else
                    182:        {
                    183:                register struct regnod *r = (struct regnod *)getstor(sizeof(struct regnod));
                    184:                register struct argnod *argp;
                    185: 
                    186:                r->regptr = 0;
                    187:                for (;;)
                    188:                {
                    189:                        if (fndef)
                    190:                        {
                    191:                                argp= wdarg;
                    192:                                wdarg = (struct argnod *)shalloc(length(argp->argval) + BYTESPERWORD);
                    193:                                movstr(argp->argval, wdarg->argval);
                    194:                        }
                    195: 
                    196:                        wdarg->argnxt = r->regptr;
                    197:                        r->regptr = wdarg;
                    198:                        if (wdval || (word() != ')' && wdval != '|'))
                    199:                                synbad();
                    200:                        if (wdval == '|')
                    201:                                word();
                    202:                        else
                    203:                                break;
                    204:                }
                    205:                r->regcom = cmd(0, NLFLG | MTFLG);
                    206:                if (wdval == ECSYM)
                    207:                        r->regnxt = syncase(esym);
                    208:                else
                    209:                {
                    210:                        chksym(esym);
                    211:                        r->regnxt = 0;
                    212:                }
                    213:                return(r);
                    214:        }
                    215: }
                    216: 
                    217: /*
                    218:  * item
                    219:  *
                    220:  *     ( cmd ) [ < in  ] [ > out ]
                    221:  *     word word* [ < in ] [ > out ]
                    222:  *     if ... then ... else ... fi
                    223:  *     for ... while ... do ... done
                    224:  *     case ... in ... esac
                    225:  *     begin ... end
                    226:  */
                    227: static struct trenod *
                    228: item(flag)
                    229:        BOOL    flag;
                    230: {
                    231:        register struct trenod *r;
                    232:        register struct ionod *io;
                    233: 
                    234:        if (flag)
                    235:                io = inout((struct ionod *)0);
                    236:        else
                    237:                io = 0;
                    238:        switch (wdval)
                    239:        {
                    240:        case CASYM:
                    241:                {
                    242:                        register struct swnod *t;
                    243:                        
                    244:                        t = (struct swnod *)getstor(sizeof(struct swnod));
                    245:                        r = (struct trenod *)t;
                    246: 
                    247:                        chkword();
                    248:                        if (fndef)
                    249:                                t->swarg = make(wdarg->argval);
                    250:                        else
                    251:                                t->swarg = wdarg->argval;
                    252:                        skipnl();
                    253:                        chksym(INSYM);
                    254:                        t->swlst = syncase(ESSYM);
                    255:                        t->swtyp = TSW;
                    256:                        break;
                    257:                }
                    258: 
                    259:        case IFSYM:
                    260:                {
                    261:                        register int    w;
                    262:                        register struct ifnod *t;
                    263: 
                    264:                        t = (struct ifnod *)getstor(sizeof(struct ifnod));
                    265:                        r = (struct trenod *)t;
                    266: 
                    267:                        t->iftyp = TIF;
                    268:                        t->iftre = cmd(THSYM, NLFLG);
                    269:                        t->thtre = cmd(ELSYM | FISYM | EFSYM, NLFLG);
                    270:                        t->eltre = ((w = wdval) == ELSYM ? cmd(FISYM, NLFLG) : (w == EFSYM ? (wdval = IFSYM, item(0)) : 0));
                    271:                        if (w == EFSYM)
                    272:                                return(r);
                    273:                        break;
                    274:                }
                    275: 
                    276:        case FORSYM:
                    277:                {
                    278:                        register struct fornod *t;
                    279: 
                    280:                        t = (struct fornod *)getstor(sizeof(struct fornod));
                    281:                        r = (struct trenod *)t;
                    282: 
                    283:                        t->fortyp = TFOR;
                    284:                        t->forlst = 0;
                    285:                        chkword();
                    286:                        if (fndef)
                    287:                                t->fornam = make(wdarg->argval);
                    288:                        else
                    289:                                t->fornam = wdarg->argval;
                    290:                        if (skipnl() == INSYM)
                    291:                        {
                    292:                                chkword();
                    293: 
                    294:                                t->forlst = (struct comnod *)item(0);
                    295: 
                    296:                                if (wdval != NL && wdval != ';')
                    297:                                        synbad();
                    298:                                if (wdval == NL)
                    299:                                        chkpr();
                    300:                                skipnl();
                    301:                        }
                    302:                        else if (wdval == ';')
                    303:                                reserv++, word();       /* eat the ';' */
                    304:                        chksym(DOSYM);
                    305:                        t->fortre = cmd(ODSYM, NLFLG);
                    306:                        break;
                    307:                }
                    308: 
                    309:        case WHSYM:
                    310:        case UNSYM:
                    311:                {
                    312:                        register struct whnod *t;
                    313: 
                    314:                        t = (struct whnod *)getstor(sizeof(struct whnod));      
                    315:                        r = (struct trenod *)t;
                    316: 
                    317:                        t->whtyp = (wdval == WHSYM ? TWH : TUN);
                    318:                        t->whtre = cmd(DOSYM, NLFLG);
                    319:                        t->dotre = cmd(ODSYM, NLFLG);
                    320:                        break;
                    321:                }
                    322: 
                    323:        case '{':
                    324:                r = cmd('}', NLFLG);
                    325:                break;
                    326: 
                    327:        case '(':
                    328:                {
                    329:                        register struct parnod *p;
                    330: 
                    331:                        p = (struct parnod *)getstor(sizeof(struct parnod));
                    332:                        p->partre = cmd(')', NLFLG);
                    333:                        p->partyp = TPAR;
                    334:                        r = makefork(0, p);
                    335:                        break;
                    336:                }
                    337: 
                    338:        default:
                    339:                if (io == 0)
                    340:                        return(0);
                    341: 
                    342:        case 0:
                    343:                {
                    344:                        register struct comnod *t;
                    345:                        register struct argnod *argp;
                    346:                        register struct argnod **argtail;
                    347:                        register struct argnod **argset = 0;
                    348:                        int     keywd = 1;
                    349:                        char    *com;
                    350: 
                    351:                        if ((wdval != NL) && ((peekn = skipc()) == '('))
                    352:                        {
                    353:                                struct fndnod *f;
                    354:                                struct ionod  *saveio;
                    355: 
                    356:                                saveio = iotemp;
                    357:                                peekn = 0;
                    358:                                if (skipc() != ')')
                    359:                                        synbad();
                    360: 
                    361:                                f = (struct fndnod *)getstor(sizeof(struct fndnod));
                    362:                                r = (struct trenod *)f;
                    363: 
                    364:                                f->fndtyp = TFND;
                    365:                                if (fndef)
                    366:                                        f->fndnam = make(wdarg->argval);
                    367:                                else
                    368:                                        f->fndnam = wdarg->argval;
                    369:                                reserv++;
                    370:                                fndef++;
                    371:                                skipnl();
                    372:                                f->fndval = (struct trenod *)item(TRUE);
                    373:                                fndef--;
                    374: 
                    375:                                if (iotemp != saveio)
                    376:                                {
                    377:                                        struct ionod    *ioptr = iotemp;
                    378: 
                    379:                                        while (ioptr->iolst != saveio)
                    380:                                                ioptr = ioptr->iolst;
                    381: 
                    382:                                        ioptr->iolst = fiotemp;
                    383:                                        fiotemp = iotemp;
                    384:                                        iotemp = saveio;
                    385:                                }
                    386:                                return(r);
                    387:                        }
                    388:                        else
                    389:                        {
                    390:                                t = (struct comnod *)getstor(sizeof(struct comnod));
                    391:                                r = (struct trenod *)t;
                    392: 
                    393:                                t->comio = io; /*initial io chain*/
                    394:                                argtail = &(t->comarg);
                    395: 
                    396:                                while (wdval == 0)
                    397:                                {
                    398:                                        if (fndef)
                    399:                                        {
                    400:                                                argp = wdarg;
                    401:                                                wdarg = (struct argnod *)shalloc(length(argp->argval) + BYTESPERWORD);
                    402:                                                movstr(argp->argval, wdarg->argval);
                    403:                                        }
                    404: 
                    405:                                        argp = wdarg;
                    406:                                        if (wdset && keywd)
                    407:                                        {
                    408:                                                argp->argnxt = (struct argnod *)argset;
                    409:                                                argset = (struct argnod **)argp;
                    410:                                        }
                    411:                                        else
                    412:                                        {
                    413:                                                *argtail = argp;
                    414:                                                argtail = &(argp->argnxt);
                    415:                                                keywd = flags & keyflg;
                    416:                                        }
                    417:                                        word();
                    418:                                        if (flag)
                    419:                                                t->comio = inout(t->comio);
                    420:                                }
                    421: 
                    422:                                t->comtyp = TCOM;
                    423:                                t->comset = (struct argnod *)argset;
                    424:                                *argtail = 0;
                    425: 
                    426:                                return(r);
                    427:                        }
                    428:                }
                    429: 
                    430:        }
                    431:        reserv++;
                    432:        word();
                    433:        if (io = inout(io))
                    434:        {
                    435:                r = makefork(0,r);
                    436:                r->treio = io;
                    437:        }
                    438:        return(r);
                    439: }
                    440: 
                    441: 
                    442: static int
                    443: skipnl()
                    444: {
                    445:        while ((reserv++, word() == NL))
                    446:                chkpr();
                    447:        return(wdval);
                    448: }
                    449: 
                    450: static struct ionod *
                    451: inout(lastio)
                    452:        struct ionod *lastio;
                    453: {
                    454:        register int    iof;
                    455:        register struct ionod *iop;
                    456:        register char   c;
                    457: 
                    458:        iof = wdnum;
                    459:        switch (wdval)
                    460:        {
                    461:        case DOCSYM:    /*      <<      */
                    462:                iof |= IODOC;
                    463:                break;
                    464: 
                    465:        case APPSYM:    /*      >>      */
                    466:        case '>':
                    467:                if (wdnum == 0)
                    468:                        iof |= 1;
                    469:                iof |= IOPUT;
                    470:                if (wdval == APPSYM)
                    471:                {
                    472:                        iof |= IOAPP;
                    473:                        break;
                    474:                }
                    475: 
                    476:        case '<':
                    477:                if ((c = nextc(0)) == '&')
                    478:                        iof |= IOMOV;
                    479:                else if (c == '>')
                    480:                        iof |= IORDW;
                    481:                else
                    482:                        peekc = c | MARK;
                    483:                break;
                    484: 
                    485:        default:
                    486:                return(lastio);
                    487:        }
                    488: 
                    489:        chkword();
                    490:        iop = (struct ionod *)getstor(sizeof(struct ionod));
                    491: 
                    492:        if (fndef)
                    493:                iop->ioname = make(wdarg->argval);
                    494:        else
                    495:                iop->ioname = wdarg->argval;
                    496: 
                    497:        iop->iolink = 0;
                    498:        iop->iofile = iof;
                    499:        if (iof & IODOC)
                    500:        {
                    501:                iop->iolst = iopend;
                    502:                iopend = iop;
                    503:        }
                    504:        word();
                    505:        iop->ionxt = inout(lastio);
                    506:        return(iop);
                    507: }
                    508: 
                    509: static int
                    510: chkword()
                    511: {
                    512:        if (word())
                    513:                synbad();
                    514: }
                    515: 
                    516: static int
                    517: chksym(sym)
                    518: {
                    519:        register int    x = sym & wdval;
                    520: 
                    521:        if (((x & SYMFLG) ? x : sym) != wdval)
                    522:                synbad();
                    523: }
                    524: 
                    525: static int
                    526: prsym(sym)
                    527: {
                    528:        if (sym & SYMFLG)
                    529:        {
                    530:                register struct sysnod *sp = reserved;
                    531: 
                    532:                while (sp->sysval && sp->sysval != sym)
                    533:                        sp++;
                    534:                prs(sp->sysnam);
                    535:        }
                    536:        else if (sym == EOFSYM)
                    537:                prs(endoffile);
                    538:        else
                    539:        {
                    540:                if (sym & SYMREP)
                    541:                        prc(sym);
                    542:                if (sym == NL)
                    543:                        prs("newline or ;");
                    544:                else
                    545:                        prc(sym);
                    546:        }
                    547: }
                    548: 
                    549: static int
                    550: synbad()
                    551: {
                    552:        prp();
                    553:        prs(synmsg);
                    554:        if ((flags & ttyflg) == 0)
                    555:        {
                    556:                prs(atline);
                    557:                prn(standin->flin);
                    558:        }
                    559:        prs(colon);
                    560:        prc(LQ);
                    561:        if (wdval)
                    562:                prsym(wdval);
                    563:        else
                    564:                prs_cntl(wdarg->argval);
                    565:        prc(RQ);
                    566:        prs(unexpected);
                    567:        newline();
                    568:        exitsh(SYNBAD);
                    569: }

unix.superglobalmegacorp.com

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