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

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)cmd.c      4.3 4/24/88";
                      3: #endif
                      4: 
                      5: #
                      6: /*
                      7:  * UNIX shell
                      8:  *
                      9:  * S. R. Bourne
                     10:  * Bell Telephone Laboratories
                     11:  *
                     12:  */
                     13: 
                     14: #include       "defs.h"
                     15: #include       "sym.h"
                     16: 
                     17: PROC IOPTR     inout();
                     18: PROC VOID      chkword();
                     19: PROC VOID      chksym();
                     20: PROC TREPTR    term();
                     21: PROC TREPTR    makelist();
                     22: PROC TREPTR    list();
                     23: PROC REGPTR    syncase();
                     24: PROC TREPTR    item();
                     25: PROC VOID      skipnl();
                     26: PROC VOID      prsym();
                     27: PROC VOID      synbad();
                     28: 
                     29: 
                     30: /* ========    command line decoding   ========*/
                     31: 
                     32: 
                     33: 
                     34: 
                     35: TREPTR makefork(flgs, i)
                     36:        INT             flgs;
                     37:        TREPTR          i;
                     38: {
                     39:        REG TREPTR      t;
                     40: 
                     41:        t=getstak(FORKTYPE);
                     42:        t->forknod.forktyp=flgs|TFORK;
                     43:        t->forknod.forktre=i;
                     44:        t->forknod.forkio=0;
                     45:        return(t);
                     46: }
                     47: 
                     48: LOCAL TREPTR   makelist(type,i,r)
                     49:        INT             type;
                     50:        TREPTR          i, r;
                     51: {
                     52:        REG TREPTR      t;
                     53: 
                     54:        IF i==0 ORF r==0
                     55:        THEN    synbad();
                     56:        ELSE    t = getstak(LSTTYPE);
                     57:                t->lstnod.lsttyp = type;
                     58:                t->lstnod.lstlef = i;
                     59:                t->lstnod.lstrit = r;
                     60:        FI
                     61:        return(t);
                     62: }
                     63: 
                     64: /*
                     65:  * cmd
                     66:  *     empty
                     67:  *     list
                     68:  *     list & [ cmd ]
                     69:  *     list [ ; cmd ]
                     70:  */
                     71: 
                     72: TREPTR cmd(sym,flg)
                     73:        REG INT         sym;
                     74:        INT             flg;
                     75: {
                     76:        REG TREPTR      i, e;
                     77: 
                     78:        i = list(flg);
                     79: 
                     80:        IF wdval==NL
                     81:        THEN    IF flg&NLFLG
                     82:                THEN    wdval=';'; chkpr(NL);
                     83:                FI
                     84:        ELIF i==0 ANDF (flg&MTFLG)==0
                     85:        THEN    synbad();
                     86:        FI
                     87: 
                     88:        SWITCH wdval IN
                     89: 
                     90:            case '&':
                     91:                IF i
                     92:                THEN    i = makefork(FINT|FPRS|FAMP, i);
                     93:                ELSE    synbad();
                     94:                FI
                     95: 
                     96:            case ';':
                     97:                IF e=cmd(sym,flg|MTFLG)
                     98:                THEN    i=makelist(TLST, i, e);
                     99:                FI
                    100:                break;
                    101: 
                    102:            case EOFSYM:
                    103:                IF sym==NL
                    104:                THEN    break;
                    105:                FI
                    106: 
                    107:            default:
                    108:                IF sym
                    109:                THEN    chksym(sym);
                    110:                FI
                    111: 
                    112:        ENDSW
                    113:        return(i);
                    114: }
                    115: 
                    116: /*
                    117:  * list
                    118:  *     term
                    119:  *     list && term
                    120:  *     list || term
                    121:  */
                    122: 
                    123: LOCAL TREPTR   list(flg)
                    124: {
                    125:        REG TREPTR      r;
                    126:        REG INT         b;
                    127: 
                    128:        r = term(flg);
                    129:        WHILE r ANDF ((b=(wdval==ANDFSYM)) ORF wdval==ORFSYM)
                    130:        DO      r = makelist((b ? TAND : TORF), r, term(NLFLG));
                    131:        OD
                    132:        return(r);
                    133: }
                    134: 
                    135: /*
                    136:  * term
                    137:  *     item
                    138:  *     item |^ term
                    139:  */
                    140: 
                    141: LOCAL TREPTR   term(flg)
                    142: {
                    143:        REG TREPTR      t;
                    144: 
                    145:        reserv++;
                    146:        IF flg&NLFLG
                    147:        THEN    skipnl();
                    148:        ELSE    word();
                    149:        FI
                    150: 
                    151:        IF (t=item(TRUE)) ANDF (wdval=='^' ORF wdval=='|')
                    152:        THEN    return(makelist(TFIL, makefork(FPOU,t), makefork(FPIN|FPCL,term(NLFLG))));
                    153:        ELSE    return(t);
                    154:        FI
                    155: }
                    156: 
                    157: LOCAL REGPTR   syncase(esym)
                    158:        REG INT esym;
                    159: {
                    160:        skipnl();
                    161:        IF wdval==esym
                    162:        THEN    return(0);
                    163:        ELSE    REG REGPTR      r=getstak(REGTYPE);
                    164:                r->regptr=0;
                    165:                LOOP wdarg->argnxt=r->regptr;
                    166:                     r->regptr=wdarg;
                    167:                     IF wdval ORF ( word()!=')' ANDF wdval!='|' )
                    168:                     THEN synbad();
                    169:                     FI
                    170:                     IF wdval=='|'
                    171:                     THEN word();
                    172:                     ELSE break;
                    173:                     FI
                    174:                POOL
                    175:                r->regcom=cmd(0,NLFLG|MTFLG);
                    176:                IF wdval==ECSYM
                    177:                THEN    r->regnxt=syncase(esym);
                    178:                ELSE    chksym(esym);
                    179:                        r->regnxt=0;
                    180:                FI
                    181:                return(r);
                    182:        FI
                    183: }
                    184: 
                    185: /*
                    186:  * item
                    187:  *
                    188:  *     ( cmd ) [ < in  ] [ > out ]
                    189:  *     word word* [ < in ] [ > out ]
                    190:  *     if ... then ... else ... fi
                    191:  *     for ... while ... do ... done
                    192:  *     case ... in ... esac
                    193:  *     begin ... end
                    194:  */
                    195: 
                    196: LOCAL TREPTR   item(flag)
                    197:        BOOL            flag;
                    198: {
                    199:        REG TREPTR      t;
                    200:        REG IOPTR       io;
                    201: 
                    202:        IF flag
                    203:        THEN    io=inout((IOPTR)0);
                    204:        ELSE    io=0;
                    205:        FI
                    206: 
                    207:        SWITCH wdval IN
                    208: 
                    209:            case CASYM:
                    210:                BEGIN
                    211:                   t=getstak(SWTYPE);
                    212:                   chkword();
                    213:                   t->swnod.swarg=wdarg->argval;
                    214:                   skipnl(); chksym(INSYM|BRSYM);
                    215:                   t->swnod.swlst=syncase(wdval==INSYM?ESSYM:KTSYM);
                    216:                   t->swnod.swtyp=TSW;
                    217:                   break;
                    218:                END
                    219: 
                    220:            case IFSYM:
                    221:                BEGIN
                    222:                   REG INT      w;
                    223:                   t=getstak(IFTYPE);
                    224:                   t->ifnod.iftyp=TIF;
                    225:                   t->ifnod.iftre=cmd(THSYM,NLFLG);
                    226:                   t->ifnod.thtre=cmd(ELSYM|FISYM|EFSYM,NLFLG);
                    227:                   t->ifnod.eltre=((w=wdval)==ELSYM ? cmd(FISYM,NLFLG) : (w==EFSYM ? (wdval=IFSYM, item(0)) : 0));
                    228:                   IF w==EFSYM THEN return(t) FI
                    229:                   break;
                    230:                END
                    231: 
                    232:            case FORSYM:
                    233:                BEGIN
                    234:                   t=getstak(FORTYPE);
                    235:                   t->fornod.fortyp=TFOR;
                    236:                   t->fornod.forlst=0;
                    237:                   chkword();
                    238:                   t->fornod.fornam=wdarg->argval;
                    239:                   IF skipnl()==INSYM
                    240:                   THEN chkword();
                    241:                        t->fornod.forlst=item(0);
                    242:                        IF wdval!=NL ANDF wdval!=';'
                    243:                        THEN    synbad();
                    244:                        FI
                    245:                        chkpr(wdval); skipnl();
                    246:                   FI
                    247:                   chksym(DOSYM|BRSYM);
                    248:                   t->fornod.fortre=cmd(wdval==DOSYM?ODSYM:KTSYM,NLFLG);
                    249:                   break;
                    250:                END
                    251: 
                    252:            case WHSYM:
                    253:            case UNSYM:
                    254:                BEGIN
                    255:                   t=getstak(WHTYPE);
                    256:                   t->whnod.whtyp=(wdval==WHSYM ? TWH : TUN);
                    257:                   t->whnod.whtre = cmd(DOSYM,NLFLG);
                    258:                   t->whnod.dotre = cmd(ODSYM,NLFLG);
                    259:                   break;
                    260:                END
                    261: 
                    262:            case BRSYM:
                    263:                t=cmd(KTSYM,NLFLG);
                    264:                break;
                    265: 
                    266:            case '(':
                    267:                BEGIN
                    268:                   REG PARPTR    p;
                    269:                   p=getstak(PARTYPE);
                    270:                   p->partre=cmd(')',NLFLG);
                    271:                   p->partyp=TPAR;
                    272:                   t=makefork(0,p);
                    273:                   break;
                    274:                END
                    275: 
                    276:            default:
                    277:                IF io==0
                    278:                THEN    return(0);
                    279:                FI
                    280: 
                    281:            case 0:
                    282:                BEGIN
                    283:                   REG ARGPTR   argp;
                    284:                   REG ARGPTR   *argtail;
                    285:                   REG ARGPTR   *argset=0;
                    286:                   INT          keywd=1;
                    287:                   t=getstak(COMTYPE);
                    288:                   t->comnod.comio=io; /*initial io chain*/
                    289:                   argtail = &(t->comnod.comarg);
                    290:                   WHILE wdval==0
                    291:                   DO   argp = wdarg;
                    292:                        IF wdset ANDF keywd
                    293:                        THEN    argp->argnxt=argset; argset=argp;
                    294:                        ELSE    *argtail=argp; argtail = &(argp->argnxt); keywd=flags&keyflg;
                    295:                        FI
                    296:                        word();
                    297:                        IF flag
                    298:                        THEN t->comnod.comio=inout(t->comnod.comio);
                    299:                        FI
                    300:                   OD
                    301: 
                    302:                   t->comnod.comtyp=TCOM; t->comnod.comset=argset; *argtail=0;
                    303:                   return(t);
                    304:                END
                    305: 
                    306:        ENDSW
                    307:        reserv++; word();
                    308:        IF io=inout(io)
                    309:        THEN    t=makefork(0,t); t->treio.treio=io;
                    310:        FI
                    311:        return(t);
                    312: }
                    313: 
                    314: 
                    315: LOCAL VOID     skipnl()
                    316: {
                    317:        WHILE (reserv++, word()==NL) DO chkpr(NL) OD
                    318:        return(wdval);
                    319: }
                    320: 
                    321: LOCAL IOPTR    inout(lastio)
                    322:        IOPTR           lastio;
                    323: {
                    324:        REG INT         iof;
                    325:        REG IOPTR       iop;
                    326:        REG CHAR        c;
                    327: 
                    328:        iof=wdnum;
                    329: 
                    330:        SWITCH wdval IN
                    331: 
                    332:            case DOCSYM:
                    333:                iof |= IODOC; break;
                    334: 
                    335:            case APPSYM:
                    336:            case '>':
                    337:                IF wdnum==0 THEN iof |= 1 FI
                    338:                iof |= IOPUT;
                    339:                IF wdval==APPSYM
                    340:                THEN    iof |= IOAPP; break;
                    341:                FI
                    342: 
                    343:            case '<':
                    344:                IF (c=nextc(0))=='&'
                    345:                THEN    iof |= IOMOV;
                    346:                ELIF c=='>'
                    347:                THEN    iof |= IORDW;
                    348:                ELSE    peekc=c|MARK;
                    349:                FI
                    350:                break;
                    351: 
                    352:            default:
                    353:                return(lastio);
                    354:        ENDSW
                    355: 
                    356:        chkword();
                    357:        iop=getstak(IOTYPE); iop->ioname=wdarg->argval; iop->iofile=iof;
                    358:        IF iof&IODOC
                    359:        THEN iop->iolst=iopend; iopend=iop;
                    360:        FI
                    361:        word(); iop->ionxt=inout(lastio);
                    362:        return(iop);
                    363: }
                    364: 
                    365: LOCAL VOID     chkword()
                    366: {
                    367:        IF word()
                    368:        THEN    synbad();
                    369:        FI
                    370: }
                    371: 
                    372: LOCAL VOID     chksym(sym)
                    373: {
                    374:        REG INT         x = sym&wdval;
                    375:        IF ((x&SYMFLG) ? x : sym) != wdval
                    376:        THEN    synbad();
                    377:        FI
                    378: }
                    379: 
                    380: LOCAL VOID     prsym(sym)
                    381: {
                    382:        IF sym&SYMFLG
                    383:        THEN    REG SYSPTR      sp=reserved;
                    384:                WHILE sp->sysval
                    385:                        ANDF sp->sysval!=sym
                    386:                DO sp++ OD
                    387:                prs(sp->sysnam);
                    388:        ELIF sym==EOFSYM
                    389:        THEN    prs(endoffile);
                    390:        ELSE    IF sym&SYMREP THEN prc(sym) FI
                    391:                IF sym==NL
                    392:                THEN    prs("newline");
                    393:                ELSE    prc(sym);
                    394:                FI
                    395:        FI
                    396: }
                    397: 
                    398: LOCAL VOID     synbad()
                    399: {
                    400:        prp(); prs(synmsg);
                    401:        IF (flags&ttyflg)==0
                    402:        THEN    prs(atline); prn(standin->flin);
                    403:        FI
                    404:        prs(colon);
                    405:        prc(LQ);
                    406:        IF wdval
                    407:        THEN    prsym(wdval);
                    408:        ELSE    prs(wdarg->argval);
                    409:        FI
                    410:        prc(RQ); prs(unexpected);
                    411:        newline();
                    412:        exitsh(SYNBAD);
                    413: }

unix.superglobalmegacorp.com

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