Annotation of researchv10dc/cmd/osh/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: 
                    350:                        if ((wdval != NL) && ((peekn = skipc()) == '('))
                    351:                        {
                    352:                                struct fndnod *f;
                    353:                                struct ionod  *saveio;
                    354: 
                    355:                                saveio = iotemp;
                    356:                                peekn = 0;
                    357:                                if (skipc() != ')')
                    358:                                        synbad();
                    359: 
                    360:                                f = (struct fndnod *)getstor(sizeof(struct fndnod));
                    361:                                r = (struct trenod *)f;
                    362: 
                    363:                                f->fndtyp = TFND;
                    364:                                if (fndef)
                    365:                                        f->fndnam = make(wdarg->argval);
                    366:                                else
                    367:                                        f->fndnam = wdarg->argval;
                    368:                                reserv++;
                    369:                                fndef++;
                    370:                                skipnl();
                    371:                                f->fndval = (struct trenod *)item(TRUE);
                    372:                                fndef--;
                    373: 
                    374:                                if (iotemp != saveio)
                    375:                                {
                    376:                                        struct ionod    *ioptr = iotemp;
                    377: 
                    378:                                        while (ioptr->iolst != saveio)
                    379:                                                ioptr = ioptr->iolst;
                    380: 
                    381:                                        ioptr->iolst = fiotemp;
                    382:                                        fiotemp = iotemp;
                    383:                                        iotemp = saveio;
                    384:                                }
                    385:                                return(r);
                    386:                        }
                    387:                        else
                    388:                        {
                    389:                                t = (struct comnod *)getstor(sizeof(struct comnod));
                    390:                                r = (struct trenod *)t;
                    391: 
                    392:                                t->comio = io; /*initial io chain*/
                    393:                                argtail = &(t->comarg);
                    394: 
                    395:                                while (wdval == 0)
                    396:                                {
                    397:                                        if (fndef)
                    398:                                        {
                    399:                                                argp = wdarg;
                    400:                                                wdarg = (struct argnod *)shalloc(length(argp->argval) + BYTESPERWORD);
                    401:                                                movstr(argp->argval, wdarg->argval);
                    402:                                        }
                    403: 
                    404:                                        argp = wdarg;
                    405:                                        if (wdset && keywd)
                    406:                                        {
                    407:                                                argp->argnxt = (struct argnod *)argset;
                    408:                                                argset = (struct argnod **)argp;
                    409:                                        }
                    410:                                        else
                    411:                                        {
                    412:                                                *argtail = argp;
                    413:                                                argtail = &(argp->argnxt);
                    414:                                                keywd = flags & keyflg;
                    415:                                        }
                    416:                                        word();
                    417:                                        if (flag)
                    418:                                                t->comio = inout(t->comio);
                    419:                                }
                    420: 
                    421:                                t->comtyp = TCOM;
                    422:                                t->comset = (struct argnod *)argset;
                    423:                                *argtail = 0;
                    424: 
                    425:                                return(r);
                    426:                        }
                    427:                }
                    428: 
                    429:        }
                    430:        reserv++;
                    431:        word();
                    432:        if (io = inout(io))
                    433:        {
                    434:                r = makefork(0,r);
                    435:                r->treio = io;
                    436:        }
                    437:        return(r);
                    438: }
                    439: 
                    440: 
                    441: static int
                    442: skipnl()
                    443: {
                    444:        while ((reserv++, word() == NL))
                    445:                chkpr();
                    446:        return(wdval);
                    447: }
                    448: 
                    449: static struct ionod *
                    450: inout(lastio)
                    451:        struct ionod *lastio;
                    452: {
                    453:        register int    iof;
                    454:        register struct ionod *iop;
                    455:        register char   c;
                    456: 
                    457:        iof = wdnum;
                    458:        switch (wdval)
                    459:        {
                    460:        case DOCSYM:    /*      <<      */
                    461:                iof |= IODOC;
                    462:                break;
                    463: 
                    464:        case APPSYM:    /*      >>      */
                    465:        case '>':
                    466:                if (wdnum == 0)
                    467:                        iof |= 1;
                    468:                iof |= IOPUT;
                    469:                if (wdval == APPSYM)
                    470:                {
                    471:                        iof |= IOAPP;
                    472:                        break;
                    473:                }
                    474: 
                    475:        case '<':
                    476:                if ((c = nextc(0)) == '&')
                    477:                        iof |= IOMOV;
                    478:                else if (c == '>')
                    479:                        iof |= IORDW;
                    480:                else
                    481:                        peekc = c | MARK;
                    482:                break;
                    483: 
                    484:        default:
                    485:                return(lastio);
                    486:        }
                    487: 
                    488:        chkword();
                    489:        iop = (struct ionod *)getstor(sizeof(struct ionod));
                    490: 
                    491:        if (fndef)
                    492:                iop->ioname = make(wdarg->argval);
                    493:        else
                    494:                iop->ioname = wdarg->argval;
                    495: 
                    496:        iop->iolink = 0;
                    497:        iop->iofile = iof;
                    498:        if (iof & IODOC)
                    499:        {
                    500:                iop->iolst = iopend;
                    501:                iopend = iop;
                    502:        }
                    503:        word();
                    504:        iop->ionxt = inout(lastio);
                    505:        return(iop);
                    506: }
                    507: 
                    508: static int
                    509: chkword()
                    510: {
                    511:        if (word())
                    512:                synbad();
                    513: }
                    514: 
                    515: static int
                    516: chksym(sym)
                    517: {
                    518:        register int    x = sym & wdval;
                    519: 
                    520:        if (((x & SYMFLG) ? x : sym) != wdval)
                    521:                synbad();
                    522: }
                    523: 
                    524: static int
                    525: prsym(sym)
                    526: {
                    527:        if (sym & SYMFLG)
                    528:        {
                    529:                register struct sysnod *sp = reserved;
                    530: 
                    531:                while (sp->sysval && sp->sysval != sym)
                    532:                        sp++;
                    533:                prs(sp->sysnam);
                    534:        }
                    535:        else if (sym == EOFSYM)
                    536:                prs(endoffile);
                    537:        else
                    538:        {
                    539:                if (sym & SYMREP)
                    540:                        prc(sym);
                    541:                if (sym == NL)
                    542:                        prs("newline or ;");
                    543:                else
                    544:                        prc(sym);
                    545:        }
                    546: }
                    547: 
                    548: static int
                    549: synbad()
                    550: {
                    551:        prp();
                    552:        prs(synmsg);
                    553:        if ((flags & ttyflg) == 0)
                    554:        {
                    555:                prs(atline);
                    556:                prn(standin->flin);
                    557:        }
                    558:        prs(colon);
                    559:        prc(LQ);
                    560:        if (wdval)
                    561:                prsym(wdval);
                    562:        else
                    563:                prs_cntl(wdarg->argval);
                    564:        prc(RQ);
                    565:        prs(unexpected);
                    566:        newline();
                    567:        exitsh(SYNBAD);
                    568: }

unix.superglobalmegacorp.com

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