|
|
1.1 ! root 1: /* @(#)cmd.c 1.5 */ ! 2: /* ! 3: * UNIX shell ! 4: * ! 5: * Bell Telephone Laboratories ! 6: * ! 7: */ ! 8: ! 9: #include "defs.h" ! 10: #include "sym.h" ! 11: ! 12: static struct ionod * inout(); ! 13: static int chkword(); ! 14: static int chksym(); ! 15: static struct trenod * term(); ! 16: static struct trenod * makelist(); ! 17: static struct trenod * list(); ! 18: static struct regnod * syncase(); ! 19: static struct trenod * item(); ! 20: static int skipnl(); ! 21: static int prsym(); ! 22: static int synbad(); ! 23: ! 24: ! 25: /* ======== storage allocation for functions ======== */ ! 26: ! 27: char * ! 28: getstor(asize) ! 29: int asize; ! 30: { ! 31: if (fndef) ! 32: return(shalloc(asize)); ! 33: else ! 34: return(getstak(asize)); ! 35: } ! 36: ! 37: ! 38: /* ======== command line decoding ========*/ ! 39: ! 40: ! 41: ! 42: ! 43: struct trenod * ! 44: makefork(flgs, i) ! 45: int flgs; ! 46: struct trenod *i; ! 47: { ! 48: register struct forknod *t; ! 49: ! 50: t = (struct forknod *)getstor(sizeof(struct forknod)); ! 51: t->forktyp = flgs|TFORK; ! 52: t->forktre = i; ! 53: t->forkio = 0; ! 54: return((struct trenod *)t); ! 55: } ! 56: ! 57: static struct trenod * ! 58: makelist(type, i, r) ! 59: int type; ! 60: struct trenod *i, *r; ! 61: { ! 62: register struct lstnod *t; ! 63: ! 64: if (i == 0 || r == 0) ! 65: synbad(); ! 66: else ! 67: { ! 68: t = (struct lstnod *)getstor(sizeof(struct lstnod)); ! 69: t->lsttyp = type; ! 70: t->lstlef = i; ! 71: t->lstrit = r; ! 72: } ! 73: return((struct trenod *)t); ! 74: } ! 75: ! 76: /* ! 77: * cmd ! 78: * empty ! 79: * list ! 80: * list & [ cmd ] ! 81: * list [ ; cmd ] ! 82: */ ! 83: struct trenod * ! 84: cmd(sym, flg) ! 85: register int sym; ! 86: int flg; ! 87: { ! 88: register struct trenod *i, *e; ! 89: ! 90: i = list(flg); ! 91: if (wdval == NL) ! 92: { ! 93: if (flg & NLFLG) ! 94: { ! 95: wdval = ';'; ! 96: chkpr(); ! 97: } ! 98: } ! 99: else if (i == 0 && (flg & MTFLG) == 0) ! 100: synbad(); ! 101: ! 102: switch (wdval) ! 103: { ! 104: case '&': ! 105: if (i) ! 106: i = makefork(FINT | FPRS | FAMP, i); ! 107: else ! 108: synbad(); ! 109: ! 110: case ';': ! 111: if (e = cmd(sym, flg | MTFLG)) ! 112: i = makelist(TLST, i, e); ! 113: else if (i==0 && (flg & MTFLG) == 0) ! 114: synbad(); ! 115: break; ! 116: ! 117: case EOFSYM: ! 118: if (sym == NL) ! 119: break; ! 120: ! 121: default: ! 122: if (sym) ! 123: chksym(sym); ! 124: } ! 125: return(i); ! 126: } ! 127: ! 128: /* ! 129: * list ! 130: * term ! 131: * list && term ! 132: * list || term ! 133: */ ! 134: static struct trenod * ! 135: list(flg) ! 136: { ! 137: register struct trenod *r; ! 138: register int b; ! 139: ! 140: r = term(flg); ! 141: while (r && ((b = (wdval == ANDFSYM)) || wdval == ORFSYM)) ! 142: r = makelist((b ? TAND : TORF), r, term(NLFLG)); ! 143: return(r); ! 144: } ! 145: ! 146: /* ! 147: * term ! 148: * item ! 149: * item | term ! 150: */ ! 151: static struct trenod * ! 152: term(flg) ! 153: { ! 154: register struct trenod *t; ! 155: ! 156: reserv++; ! 157: if (flg & NLFLG) ! 158: skipnl(); ! 159: else ! 160: word(); ! 161: if ((t = item(TRUE)) && wdval == '|') ! 162: { ! 163: struct trenod *left; ! 164: struct trenod *right; ! 165: ! 166: left = makefork(FPOU, t); ! 167: right = makefork(FPIN | FPCL, term(NLFLG)); ! 168: return(makefork(0, makelist(TFIL, left, right))); ! 169: } ! 170: else ! 171: return(t); ! 172: } ! 173: ! 174: static struct regnod * ! 175: syncase(esym) ! 176: register int esym; ! 177: { ! 178: skipnl(); ! 179: if (wdval == esym) ! 180: return(0); ! 181: else ! 182: { ! 183: register struct regnod *r = (struct regnod *)getstor(sizeof(struct regnod)); ! 184: register struct argnod *argp; ! 185: ! 186: r->regptr = 0; ! 187: for (;;) ! 188: { ! 189: if (fndef) ! 190: { ! 191: argp= wdarg; ! 192: wdarg = (struct argnod *)shalloc(length(argp->argval) + BYTESPERWORD); ! 193: movstr(argp->argval, wdarg->argval); ! 194: } ! 195: ! 196: wdarg->argnxt = r->regptr; ! 197: r->regptr = wdarg; ! 198: if (wdval || (word() != ')' && wdval != '|')) ! 199: synbad(); ! 200: if (wdval == '|') ! 201: word(); ! 202: else ! 203: break; ! 204: } ! 205: r->regcom = cmd(0, NLFLG | MTFLG); ! 206: if (wdval == ECSYM) ! 207: r->regnxt = syncase(esym); ! 208: else ! 209: { ! 210: chksym(esym); ! 211: r->regnxt = 0; ! 212: } ! 213: return(r); ! 214: } ! 215: } ! 216: ! 217: /* ! 218: * item ! 219: * ! 220: * ( cmd ) [ < in ] [ > out ] ! 221: * word word* [ < in ] [ > out ] ! 222: * if ... then ... else ... fi ! 223: * for ... while ... do ... done ! 224: * case ... in ... esac ! 225: * begin ... end ! 226: */ ! 227: static struct trenod * ! 228: item(flag) ! 229: BOOL flag; ! 230: { ! 231: register struct trenod *r; ! 232: register struct ionod *io; ! 233: ! 234: if (flag) ! 235: io = inout((struct ionod *)0); ! 236: else ! 237: io = 0; ! 238: switch (wdval) ! 239: { ! 240: case CASYM: ! 241: { ! 242: register struct swnod *t; ! 243: ! 244: t = (struct swnod *)getstor(sizeof(struct swnod)); ! 245: r = (struct trenod *)t; ! 246: ! 247: chkword(); ! 248: if (fndef) ! 249: t->swarg = make(wdarg->argval); ! 250: else ! 251: t->swarg = wdarg->argval; ! 252: skipnl(); ! 253: chksym(INSYM); ! 254: t->swlst = syncase(ESSYM); ! 255: t->swtyp = TSW; ! 256: break; ! 257: } ! 258: ! 259: case IFSYM: ! 260: { ! 261: register int w; ! 262: register struct ifnod *t; ! 263: ! 264: t = (struct ifnod *)getstor(sizeof(struct ifnod)); ! 265: r = (struct trenod *)t; ! 266: ! 267: t->iftyp = TIF; ! 268: t->iftre = cmd(THSYM, NLFLG); ! 269: t->thtre = cmd(ELSYM | FISYM | EFSYM, NLFLG); ! 270: t->eltre = ((w = wdval) == ELSYM ? cmd(FISYM, NLFLG) : (w == EFSYM ? (wdval = IFSYM, item(0)) : 0)); ! 271: if (w == EFSYM) ! 272: return(r); ! 273: break; ! 274: } ! 275: ! 276: case FORSYM: ! 277: { ! 278: register struct fornod *t; ! 279: ! 280: t = (struct fornod *)getstor(sizeof(struct fornod)); ! 281: r = (struct trenod *)t; ! 282: ! 283: t->fortyp = TFOR; ! 284: t->forlst = 0; ! 285: chkword(); ! 286: if (fndef) ! 287: t->fornam = make(wdarg->argval); ! 288: else ! 289: t->fornam = wdarg->argval; ! 290: if (skipnl() == INSYM) ! 291: { ! 292: chkword(); ! 293: ! 294: t->forlst = (struct comnod *)item(0); ! 295: ! 296: if (wdval != NL && wdval != ';') ! 297: synbad(); ! 298: if (wdval == NL) ! 299: chkpr(); ! 300: skipnl(); ! 301: } ! 302: else if (wdval == ';') ! 303: reserv++, word(); /* eat the ';' */ ! 304: chksym(DOSYM); ! 305: t->fortre = cmd(ODSYM, NLFLG); ! 306: break; ! 307: } ! 308: ! 309: case WHSYM: ! 310: case UNSYM: ! 311: { ! 312: register struct whnod *t; ! 313: ! 314: t = (struct whnod *)getstor(sizeof(struct whnod)); ! 315: r = (struct trenod *)t; ! 316: ! 317: t->whtyp = (wdval == WHSYM ? TWH : TUN); ! 318: t->whtre = cmd(DOSYM, NLFLG); ! 319: t->dotre = cmd(ODSYM, NLFLG); ! 320: break; ! 321: } ! 322: ! 323: case '{': ! 324: r = cmd('}', NLFLG); ! 325: break; ! 326: ! 327: case '(': ! 328: { ! 329: register struct parnod *p; ! 330: ! 331: p = (struct parnod *)getstor(sizeof(struct parnod)); ! 332: p->partre = cmd(')', NLFLG); ! 333: p->partyp = TPAR; ! 334: r = makefork(0, p); ! 335: break; ! 336: } ! 337: ! 338: default: ! 339: if (io == 0) ! 340: return(0); ! 341: ! 342: case 0: ! 343: { ! 344: register struct comnod *t; ! 345: register struct argnod *argp; ! 346: register struct argnod **argtail; ! 347: register struct argnod **argset = 0; ! 348: int keywd = 1; ! 349: char *com; ! 350: ! 351: if ((wdval != NL) && ((peekn = skipc()) == '(')) ! 352: { ! 353: struct fndnod *f; ! 354: struct ionod *saveio; ! 355: ! 356: saveio = iotemp; ! 357: peekn = 0; ! 358: if (skipc() != ')') ! 359: synbad(); ! 360: ! 361: f = (struct fndnod *)getstor(sizeof(struct fndnod)); ! 362: r = (struct trenod *)f; ! 363: ! 364: f->fndtyp = TFND; ! 365: if (fndef) ! 366: f->fndnam = make(wdarg->argval); ! 367: else ! 368: f->fndnam = wdarg->argval; ! 369: reserv++; ! 370: fndef++; ! 371: skipnl(); ! 372: f->fndval = (struct trenod *)item(TRUE); ! 373: fndef--; ! 374: ! 375: if (iotemp != saveio) ! 376: { ! 377: struct ionod *ioptr = iotemp; ! 378: ! 379: while (ioptr->iolst != saveio) ! 380: ioptr = ioptr->iolst; ! 381: ! 382: ioptr->iolst = fiotemp; ! 383: fiotemp = iotemp; ! 384: iotemp = saveio; ! 385: } ! 386: return(r); ! 387: } ! 388: else ! 389: { ! 390: t = (struct comnod *)getstor(sizeof(struct comnod)); ! 391: r = (struct trenod *)t; ! 392: ! 393: t->comio = io; /*initial io chain*/ ! 394: argtail = &(t->comarg); ! 395: ! 396: while (wdval == 0) ! 397: { ! 398: if (fndef) ! 399: { ! 400: argp = wdarg; ! 401: wdarg = (struct argnod *)shalloc(length(argp->argval) + BYTESPERWORD); ! 402: movstr(argp->argval, wdarg->argval); ! 403: } ! 404: ! 405: argp = wdarg; ! 406: if (wdset && keywd) ! 407: { ! 408: argp->argnxt = (struct argnod *)argset; ! 409: argset = (struct argnod **)argp; ! 410: } ! 411: else ! 412: { ! 413: *argtail = argp; ! 414: argtail = &(argp->argnxt); ! 415: keywd = flags & keyflg; ! 416: } ! 417: word(); ! 418: if (flag) ! 419: t->comio = inout(t->comio); ! 420: } ! 421: ! 422: t->comtyp = TCOM; ! 423: t->comset = (struct argnod *)argset; ! 424: *argtail = 0; ! 425: ! 426: return(r); ! 427: } ! 428: } ! 429: ! 430: } ! 431: reserv++; ! 432: word(); ! 433: if (io = inout(io)) ! 434: { ! 435: r = makefork(0,r); ! 436: r->treio = io; ! 437: } ! 438: return(r); ! 439: } ! 440: ! 441: ! 442: static int ! 443: skipnl() ! 444: { ! 445: while ((reserv++, word() == NL)) ! 446: chkpr(); ! 447: return(wdval); ! 448: } ! 449: ! 450: static struct ionod * ! 451: inout(lastio) ! 452: struct ionod *lastio; ! 453: { ! 454: register int iof; ! 455: register struct ionod *iop; ! 456: register char c; ! 457: ! 458: iof = wdnum; ! 459: switch (wdval) ! 460: { ! 461: case DOCSYM: /* << */ ! 462: iof |= IODOC; ! 463: break; ! 464: ! 465: case APPSYM: /* >> */ ! 466: case '>': ! 467: if (wdnum == 0) ! 468: iof |= 1; ! 469: iof |= IOPUT; ! 470: if (wdval == APPSYM) ! 471: { ! 472: iof |= IOAPP; ! 473: break; ! 474: } ! 475: ! 476: case '<': ! 477: if ((c = nextc(0)) == '&') ! 478: iof |= IOMOV; ! 479: else if (c == '>') ! 480: iof |= IORDW; ! 481: else ! 482: peekc = c | MARK; ! 483: break; ! 484: ! 485: default: ! 486: return(lastio); ! 487: } ! 488: ! 489: chkword(); ! 490: iop = (struct ionod *)getstor(sizeof(struct ionod)); ! 491: ! 492: if (fndef) ! 493: iop->ioname = make(wdarg->argval); ! 494: else ! 495: iop->ioname = wdarg->argval; ! 496: ! 497: iop->iolink = 0; ! 498: iop->iofile = iof; ! 499: if (iof & IODOC) ! 500: { ! 501: iop->iolst = iopend; ! 502: iopend = iop; ! 503: } ! 504: word(); ! 505: iop->ionxt = inout(lastio); ! 506: return(iop); ! 507: } ! 508: ! 509: static int ! 510: chkword() ! 511: { ! 512: if (word()) ! 513: synbad(); ! 514: } ! 515: ! 516: static int ! 517: chksym(sym) ! 518: { ! 519: register int x = sym & wdval; ! 520: ! 521: if (((x & SYMFLG) ? x : sym) != wdval) ! 522: synbad(); ! 523: } ! 524: ! 525: static int ! 526: prsym(sym) ! 527: { ! 528: if (sym & SYMFLG) ! 529: { ! 530: register struct sysnod *sp = reserved; ! 531: ! 532: while (sp->sysval && sp->sysval != sym) ! 533: sp++; ! 534: prs(sp->sysnam); ! 535: } ! 536: else if (sym == EOFSYM) ! 537: prs(endoffile); ! 538: else ! 539: { ! 540: if (sym & SYMREP) ! 541: prc(sym); ! 542: if (sym == NL) ! 543: prs("newline or ;"); ! 544: else ! 545: prc(sym); ! 546: } ! 547: } ! 548: ! 549: static int ! 550: synbad() ! 551: { ! 552: prp(); ! 553: prs(synmsg); ! 554: if ((flags & ttyflg) == 0) ! 555: { ! 556: prs(atline); ! 557: prn(standin->flin); ! 558: } ! 559: prs(colon); ! 560: prc(LQ); ! 561: if (wdval) ! 562: prsym(wdval); ! 563: else ! 564: prs_cntl(wdarg->argval); ! 565: prc(RQ); ! 566: prs(unexpected); ! 567: newline(); ! 568: exitsh(SYNBAD); ! 569: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.