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: }

Defined functions

chksym defined in line 365; used 5 times
chkword defined in line 358; used 5 times
cmd defined in line 65; used 14 times
inout defined in line 314; used 5 times
item defined in line 189; used 4 times
list defined in line 116; used 2 times
makefork defined in line 31; used 7 times
makelist defined in line 42; used 4 times
prsym defined in line 373; used 2 times
skipnl defined in line 308; used 6 times
synbad defined in line 391; used 8 times
syncase defined in line 150; used 3 times
term defined in line 134; used 4 times
Last modified: 1981-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1280
Valid CSS Valid XHTML 1.0 Strict