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