Annotation of 41BSD/cmd/sh/cmd.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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