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

Defined functions

chksym defined in line 369; used 5 times
chkword defined in line 362; used 5 times
cmd defined in line 69; used 14 times
inout defined in line 318; used 5 times
item defined in line 193; used 4 times
list defined in line 120; used 2 times
makefork defined in line 35; used 7 times
makelist defined in line 46; used 4 times
prsym defined in line 377; used 2 times
skipnl defined in line 312; used 6 times
synbad defined in line 395; used 8 times
syncase defined in line 154; used 3 times
term defined in line 138; used 4 times

Defined variables

sccsid defined in line 2; never used
Last modified: 1983-08-12
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3119
Valid CSS Valid XHTML 1.0 Strict