Annotation of 3BSD/cmd/sh/cmd.c, revision 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.