|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.