1 /*- 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Kenneth Almquist. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 static char sccsid[] = "@(#)parser.c 8.5 (Berkeley) 04/28/95"; 13 #endif /* not lint */ 14 15 #include "shell.h" 16 #include "parser.h" 17 #include "nodes.h" 18 #include "expand.h" /* defines rmescapes() */ 19 #include "redir.h" /* defines copyfd() */ 20 #include "syntax.h" 21 #include "options.h" 22 #include "input.h" 23 #include "output.h" 24 #include "var.h" 25 #include "error.h" 26 #include "memalloc.h" 27 #include "mystring.h" 28 #include "alias.h" 29 #include "myhistedit.h" 30 31 32 /* 33 * Shell command parser. 34 */ 35 36 #define EOFMARKLEN 79 37 38 /* values returned by readtoken */ 39 #include "token.def" 40 41 42 43 struct heredoc { 44 struct heredoc *next; /* next here document in list */ 45 union node *here; /* redirection node */ 46 char *eofmark; /* string indicating end of input */ 47 int striptabs; /* if set, strip leading tabs */ 48 }; 49 50 51 52 struct heredoc *heredoclist; /* list of here documents to read */ 53 int parsebackquote; /* nonzero if we are inside backquotes */ 54 int doprompt; /* if set, prompt the user */ 55 int needprompt; /* true if interactive and at start of line */ 56 int lasttoken; /* last token read */ 57 MKINIT int tokpushback; /* last token pushed back */ 58 char *wordtext; /* text of last word returned by readtoken */ 59 MKINIT int checkkwd; /* 1 == check for kwds, 2 == also eat newlines */ 60 struct nodelist *backquotelist; 61 union node *redirnode; 62 struct heredoc *heredoc; 63 int quoteflag; /* set if (part of) last token was quoted */ 64 int startlinno; /* line # where last token started */ 65 66 67 #define GDB_HACK 1 /* avoid local declarations which gdb can't handle */ 68 #ifdef GDB_HACK 69 static const char argvars[5] = {CTLVAR, VSNORMAL|VSQUOTE, '@', '=', '\0'}; 70 static const char types[] = "}-+?="; 71 #endif 72 73 74 STATIC union node *list __P((int)); 75 STATIC union node *andor __P((void)); 76 STATIC union node *pipeline __P((void)); 77 STATIC union node *command __P((void)); 78 STATIC union node *simplecmd __P((union node **, union node *)); 79 STATIC void parsefname __P((void)); 80 STATIC void parseheredoc __P((void)); 81 STATIC int readtoken __P((void)); 82 STATIC int readtoken1 __P((int, char const *, char *, int)); 83 STATIC void attyline __P((void)); 84 STATIC int noexpand __P((char *)); 85 STATIC void synexpect __P((int)); 86 STATIC void synerror __P((char *)); 87 STATIC void setprompt __P((int)); 88 89 /* 90 * Read and parse a command. Returns NEOF on end of file. (NULL is a 91 * valid parse tree indicating a blank line.) 92 */ 93 94 union node * 95 parsecmd(interact) { 96 int t; 97 98 doprompt = interact; 99 if (doprompt) 100 setprompt(1); 101 else 102 setprompt(0); 103 needprompt = 0; 104 t = readtoken(); 105 if (t == TEOF) 106 return NEOF; 107 if (t == TNL) 108 return NULL; 109 tokpushback++; 110 return list(1); 111 } 112 113 114 STATIC union node * 115 list(nlflag) { 116 union node *n1, *n2, *n3; 117 int tok; 118 119 checkkwd = 2; 120 if (nlflag == 0 && tokendlist[peektoken()]) 121 return NULL; 122 n1 = NULL; 123 for (;;) { 124 n2 = andor(); 125 tok = readtoken(); 126 if (tok == TBACKGND) { 127 if (n2->type == NCMD || n2->type == NPIPE) { 128 n2->ncmd.backgnd = 1; 129 } else if (n2->type == NREDIR) { 130 n2->type = NBACKGND; 131 } else { 132 n3 = (union node *)stalloc(sizeof (struct nredir)); 133 n3->type = NBACKGND; 134 n3->nredir.n = n2; 135 n3->nredir.redirect = NULL; 136 n2 = n3; 137 } 138 } 139 if (n1 == NULL) { 140 n1 = n2; 141 } 142 else { 143 n3 = (union node *)stalloc(sizeof (struct nbinary)); 144 n3->type = NSEMI; 145 n3->nbinary.ch1 = n1; 146 n3->nbinary.ch2 = n2; 147 n1 = n3; 148 } 149 switch (tok) { 150 case TBACKGND: 151 case TSEMI: 152 tok = readtoken(); 153 /* fall through */ 154 case TNL: 155 if (tok == TNL) { 156 parseheredoc(); 157 if (nlflag) 158 return n1; 159 } else { 160 tokpushback++; 161 } 162 checkkwd = 2; 163 if (tokendlist[peektoken()]) 164 return n1; 165 break; 166 case TEOF: 167 if (heredoclist) 168 parseheredoc(); 169 else 170 pungetc(); /* push back EOF on input */ 171 return n1; 172 default: 173 if (nlflag) 174 synexpect(-1); 175 tokpushback++; 176 return n1; 177 } 178 } 179 } 180 181 182 183 STATIC union node * 184 andor() { 185 union node *n1, *n2, *n3; 186 int t; 187 188 n1 = pipeline(); 189 for (;;) { 190 if ((t = readtoken()) == TAND) { 191 t = NAND; 192 } else if (t == TOR) { 193 t = NOR; 194 } else { 195 tokpushback++; 196 return n1; 197 } 198 n2 = pipeline(); 199 n3 = (union node *)stalloc(sizeof (struct nbinary)); 200 n3->type = t; 201 n3->nbinary.ch1 = n1; 202 n3->nbinary.ch2 = n2; 203 n1 = n3; 204 } 205 } 206 207 208 209 STATIC union node * 210 pipeline() { 211 union node *n1, *pipenode, *notnode; 212 struct nodelist *lp, *prev; 213 int negate = 0; 214 215 TRACE(("pipeline: entered\n")); 216 while (readtoken() == TNOT) { 217 TRACE(("pipeline: TNOT recognized\n")); 218 negate = !negate; 219 } 220 tokpushback++; 221 n1 = command(); 222 if (readtoken() == TPIPE) { 223 pipenode = (union node *)stalloc(sizeof (struct npipe)); 224 pipenode->type = NPIPE; 225 pipenode->npipe.backgnd = 0; 226 lp = (struct nodelist *)stalloc(sizeof (struct nodelist)); 227 pipenode->npipe.cmdlist = lp; 228 lp->n = n1; 229 do { 230 prev = lp; 231 lp = (struct nodelist *)stalloc(sizeof (struct nodelist)); 232 lp->n = command(); 233 prev->next = lp; 234 } while (readtoken() == TPIPE); 235 lp->next = NULL; 236 n1 = pipenode; 237 } 238 tokpushback++; 239 if (negate) { 240 notnode = (union node *)stalloc(sizeof (struct nnot)); 241 notnode->type = NNOT; 242 notnode->nnot.com = n1; 243 n1 = notnode; 244 } 245 return n1; 246 } 247 248 249 250 STATIC union node * 251 command() { 252 union node *n1, *n2; 253 union node *ap, **app; 254 union node *cp, **cpp; 255 union node *redir, **rpp; 256 int t; 257 258 checkkwd = 2; 259 redir = 0; 260 rpp = &redir; 261 /* Check for redirection which may precede command */ 262 while (readtoken() == TREDIR) { 263 *rpp = n2 = redirnode; 264 rpp = &n2->nfile.next; 265 parsefname(); 266 } 267 tokpushback++; 268 269 switch (readtoken()) { 270 case TIF: 271 n1 = (union node *)stalloc(sizeof (struct nif)); 272 n1->type = NIF; 273 n1->nif.test = list(0); 274 if (readtoken() != TTHEN) 275 synexpect(TTHEN); 276 n1->nif.ifpart = list(0); 277 n2 = n1; 278 while (readtoken() == TELIF) { 279 n2->nif.elsepart = (union node *)stalloc(sizeof (struct nif)); 280 n2 = n2->nif.elsepart; 281 n2->type = NIF; 282 n2->nif.test = list(0); 283 if (readtoken() != TTHEN) 284 synexpect(TTHEN); 285 n2->nif.ifpart = list(0); 286 } 287 if (lasttoken == TELSE) 288 n2->nif.elsepart = list(0); 289 else { 290 n2->nif.elsepart = NULL; 291 tokpushback++; 292 } 293 if (readtoken() != TFI) 294 synexpect(TFI); 295 checkkwd = 1; 296 break; 297 case TWHILE: 298 case TUNTIL: { 299 int got; 300 n1 = (union node *)stalloc(sizeof (struct nbinary)); 301 n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL; 302 n1->nbinary.ch1 = list(0); 303 if ((got=readtoken()) != TDO) { 304 TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : "")); 305 synexpect(TDO); 306 } 307 n1->nbinary.ch2 = list(0); 308 if (readtoken() != TDONE) 309 synexpect(TDONE); 310 checkkwd = 1; 311 break; 312 } 313 case TFOR: 314 if (readtoken() != TWORD || quoteflag || ! goodname(wordtext)) 315 synerror("Bad for loop variable"); 316 n1 = (union node *)stalloc(sizeof (struct nfor)); 317 n1->type = NFOR; 318 n1->nfor.var = wordtext; 319 if (readtoken() == TWORD && ! quoteflag && equal(wordtext, "in")) { 320 app = ≈ 321 while (readtoken() == TWORD) { 322 n2 = (union node *)stalloc(sizeof (struct narg)); 323 n2->type = NARG; 324 n2->narg.text = wordtext; 325 n2->narg.backquote = backquotelist; 326 *app = n2; 327 app = &n2->narg.next; 328 } 329 *app = NULL; 330 n1->nfor.args = ap; 331 if (lasttoken != TNL && lasttoken != TSEMI) 332 synexpect(-1); 333 } else { 334 #ifndef GDB_HACK 335 static const char argvars[5] = {CTLVAR, VSNORMAL|VSQUOTE, 336 '@', '=', '\0'}; 337 #endif 338 n2 = (union node *)stalloc(sizeof (struct narg)); 339 n2->type = NARG; 340 n2->narg.text = (char *)argvars; 341 n2->narg.backquote = NULL; 342 n2->narg.next = NULL; 343 n1->nfor.args = n2; 344 /* 345 * Newline or semicolon here is optional (but note 346 * that the original Bourne shell only allowed NL). 347 */ 348 if (lasttoken != TNL && lasttoken != TSEMI) 349 tokpushback++; 350 } 351 checkkwd = 2; 352 if ((t = readtoken()) == TDO) 353 t = TDONE; 354 else if (t == TBEGIN) 355 t = TEND; 356 else 357 synexpect(-1); 358 n1->nfor.body = list(0); 359 if (readtoken() != t) 360 synexpect(t); 361 checkkwd = 1; 362 break; 363 case TCASE: 364 n1 = (union node *)stalloc(sizeof (struct ncase)); 365 n1->type = NCASE; 366 if (readtoken() != TWORD) 367 synexpect(TWORD); 368 n1->ncase.expr = n2 = (union node *)stalloc(sizeof (struct narg)); 369 n2->type = NARG; 370 n2->narg.text = wordtext; 371 n2->narg.backquote = backquotelist; 372 n2->narg.next = NULL; 373 while (readtoken() == TNL); 374 if (lasttoken != TWORD || ! equal(wordtext, "in")) 375 synerror("expecting \"in\""); 376 cpp = &n1->ncase.cases; 377 while (checkkwd = 2, readtoken() == TWORD) { 378 *cpp = cp = (union node *)stalloc(sizeof (struct nclist)); 379 cp->type = NCLIST; 380 app = &cp->nclist.pattern; 381 for (;;) { 382 *app = ap = (union node *)stalloc(sizeof (struct narg)); 383 ap->type = NARG; 384 ap->narg.text = wordtext; 385 ap->narg.backquote = backquotelist; 386 if (readtoken() != TPIPE) 387 break; 388 app = &ap->narg.next; 389 if (readtoken() != TWORD) 390 synexpect(TWORD); 391 } 392 ap->narg.next = NULL; 393 if (lasttoken != TRP) 394 synexpect(TRP); 395 cp->nclist.body = list(0); 396 if ((t = readtoken()) == TESAC) 397 tokpushback++; 398 else if (t != TENDCASE) 399 synexpect(TENDCASE); 400 cpp = &cp->nclist.next; 401 } 402 *cpp = NULL; 403 if (lasttoken != TESAC) 404 synexpect(TESAC); 405 checkkwd = 1; 406 break; 407 case TLP: 408 n1 = (union node *)stalloc(sizeof (struct nredir)); 409 n1->type = NSUBSHELL; 410 n1->nredir.n = list(0); 411 n1->nredir.redirect = NULL; 412 if (readtoken() != TRP) 413 synexpect(TRP); 414 checkkwd = 1; 415 break; 416 case TBEGIN: 417 n1 = list(0); 418 if (readtoken() != TEND) 419 synexpect(TEND); 420 checkkwd = 1; 421 break; 422 /* Handle an empty command like other simple commands. */ 423 case TSEMI: 424 /* 425 * An empty command before a ; doesn't make much sense, and 426 * should certainly be disallowed in the case of `if ;'. 427 */ 428 if (!redir) 429 synexpect(-1); 430 case TNL: 431 case TWORD: 432 case TRP: 433 tokpushback++; 434 return simplecmd(rpp, redir); 435 default: 436 synexpect(-1); 437 } 438 439 /* Now check for redirection which may follow command */ 440 while (readtoken() == TREDIR) { 441 *rpp = n2 = redirnode; 442 rpp = &n2->nfile.next; 443 parsefname(); 444 } 445 tokpushback++; 446 *rpp = NULL; 447 if (redir) { 448 if (n1->type != NSUBSHELL) { 449 n2 = (union node *)stalloc(sizeof (struct nredir)); 450 n2->type = NREDIR; 451 n2->nredir.n = n1; 452 n1 = n2; 453 } 454 n1->nredir.redirect = redir; 455 } 456 return n1; 457 } 458 459 460 STATIC union node * 461 simplecmd(rpp, redir) 462 union node **rpp, *redir; 463 { 464 union node *args, **app; 465 union node **orig_rpp = rpp; 466 union node *n; 467 468 /* If we don't have any redirections already, then we must reset */ 469 /* rpp to be the address of the local redir variable. */ 470 if (redir == 0) 471 rpp = &redir; 472 473 args = NULL; 474 app = &args; 475 /* 476 * We save the incoming value, because we need this for shell 477 * functions. There can not be a redirect or an argument between 478 * the function name and the open parenthesis. 479 */ 480 orig_rpp = rpp; 481 482 for (;;) { 483 if (readtoken() == TWORD) { 484 n = (union node *)stalloc(sizeof (struct narg)); 485 n->type = NARG; 486 n->narg.text = wordtext; 487 n->narg.backquote = backquotelist; 488 *app = n; 489 app = &n->narg.next; 490 } else if (lasttoken == TREDIR) { 491 *rpp = n = redirnode; 492 rpp = &n->nfile.next; 493 parsefname(); /* read name of redirection file */ 494 } else if (lasttoken == TLP && app == &args->narg.next 495 && rpp == orig_rpp) { 496 /* We have a function */ 497 if (readtoken() != TRP) 498 synexpect(TRP); 499 #ifdef notdef 500 if (! goodname(n->narg.text)) 501 synerror("Bad function name"); 502 #endif 503 n->type = NDEFUN; 504 n->narg.next = command(); 505 return n; 506 } else { 507 tokpushback++; 508 break; 509 } 510 } 511 *app = NULL; 512 *rpp = NULL; 513 n = (union node *)stalloc(sizeof (struct ncmd)); 514 n->type = NCMD; 515 n->ncmd.backgnd = 0; 516 n->ncmd.args = args; 517 n->ncmd.redirect = redir; 518 return n; 519 } 520 521 522 STATIC void 523 parsefname() { 524 union node *n = redirnode; 525 526 if (readtoken() != TWORD) 527 synexpect(-1); 528 if (n->type == NHERE) { 529 struct heredoc *here = heredoc; 530 struct heredoc *p; 531 int i; 532 533 if (quoteflag == 0) 534 n->type = NXHERE; 535 TRACE(("Here document %d\n", n->type)); 536 if (here->striptabs) { 537 while (*wordtext == '\t') 538 wordtext++; 539 } 540 if (! noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN) 541 synerror("Illegal eof marker for << redirection"); 542 rmescapes(wordtext); 543 here->eofmark = wordtext; 544 here->next = NULL; 545 if (heredoclist == NULL) 546 heredoclist = here; 547 else { 548 for (p = heredoclist ; p->next ; p = p->next); 549 p->next = here; 550 } 551 } else if (n->type == NTOFD || n->type == NFROMFD) { 552 if (is_digit(wordtext[0])) 553 n->ndup.dupfd = digit_val(wordtext[0]); 554 else if (wordtext[0] == '-') 555 n->ndup.dupfd = -1; 556 else 557 goto bad; 558 if (wordtext[1] != '\0') { 559 bad: 560 synerror("Bad fd number"); 561 } 562 } else { 563 n->nfile.fname = (union node *)stalloc(sizeof (struct narg)); 564 n = n->nfile.fname; 565 n->type = NARG; 566 n->narg.next = NULL; 567 n->narg.text = wordtext; 568 n->narg.backquote = backquotelist; 569 } 570 } 571 572 573 /* 574 * Input any here documents. 575 */ 576 577 STATIC void 578 parseheredoc() { 579 struct heredoc *here; 580 union node *n; 581 582 while (heredoclist) { 583 here = heredoclist; 584 heredoclist = here->next; 585 if (needprompt) { 586 setprompt(2); 587 needprompt = 0; 588 } 589 readtoken1(pgetc(), here->here->type == NHERE? SQSYNTAX : DQSYNTAX, 590 here->eofmark, here->striptabs); 591 n = (union node *)stalloc(sizeof (struct narg)); 592 n->narg.type = NARG; 593 n->narg.next = NULL; 594 n->narg.text = wordtext; 595 n->narg.backquote = backquotelist; 596 here->here->nhere.doc = n; 597 } 598 } 599 600 STATIC int 601 peektoken() { 602 int t; 603 604 t = readtoken(); 605 tokpushback++; 606 return (t); 607 } 608 609 STATIC int xxreadtoken(); 610 611 STATIC int 612 readtoken() { 613 int t; 614 int savecheckkwd = checkkwd; 615 struct alias *ap; 616 #ifdef DEBUG 617 int alreadyseen = tokpushback; 618 #endif 619 620 top: 621 t = xxreadtoken(); 622 623 if (checkkwd) { 624 /* 625 * eat newlines 626 */ 627 if (checkkwd == 2) { 628 checkkwd = 0; 629 while (t == TNL) { 630 parseheredoc(); 631 t = xxreadtoken(); 632 } 633 } else 634 checkkwd = 0; 635 /* 636 * check for keywords and aliases 637 */ 638 if (t == TWORD && !quoteflag) { 639 register char * const *pp, *s; 640 641 for (pp = (char **)parsekwd; *pp; pp++) { 642 if (**pp == *wordtext && equal(*pp, wordtext)) { 643 lasttoken = t = pp - parsekwd + KWDOFFSET; 644 TRACE(("keyword %s recognized\n", tokname[t])); 645 goto out; 646 } 647 } 648 if (ap = lookupalias(wordtext, 1)) { 649 pushstring(ap->val, strlen(ap->val), ap); 650 checkkwd = savecheckkwd; 651 goto top; 652 } 653 } 654 out: 655 checkkwd = 0; 656 } 657 #ifdef DEBUG 658 if (!alreadyseen) 659 TRACE(("token %s %s\n", tokname[t], t == TWORD ? wordtext : "")); 660 else 661 TRACE(("reread token %s %s\n", tokname[t], t == TWORD ? wordtext : "")); 662 #endif 663 return (t); 664 } 665 666 667 /* 668 * Read the next input token. 669 * If the token is a word, we set backquotelist to the list of cmds in 670 * backquotes. We set quoteflag to true if any part of the word was 671 * quoted. 672 * If the token is TREDIR, then we set redirnode to a structure containing 673 * the redirection. 674 * In all cases, the variable startlinno is set to the number of the line 675 * on which the token starts. 676 * 677 * [Change comment: here documents and internal procedures] 678 * [Readtoken shouldn't have any arguments. Perhaps we should make the 679 * word parsing code into a separate routine. In this case, readtoken 680 * doesn't need to have any internal procedures, but parseword does. 681 * We could also make parseoperator in essence the main routine, and 682 * have parseword (readtoken1?) handle both words and redirection.] 683 */ 684 685 #define RETURN(token) return lasttoken = token 686 687 STATIC int 688 xxreadtoken() { 689 register c; 690 691 if (tokpushback) { 692 tokpushback = 0; 693 return lasttoken; 694 } 695 if (needprompt) { 696 setprompt(2); 697 needprompt = 0; 698 } 699 startlinno = plinno; 700 for (;;) { /* until token or start of word found */ 701 c = pgetc_macro(); 702 if (c == ' ' || c == '\t') 703 continue; /* quick check for white space first */ 704 switch (c) { 705 case ' ': case '\t': 706 continue; 707 case '#': 708 while ((c = pgetc()) != '\n' && c != PEOF); 709 pungetc(); 710 continue; 711 case '\\': 712 if (pgetc() == '\n') { 713 startlinno = ++plinno; 714 if (doprompt) 715 setprompt(2); 716 else 717 setprompt(0); 718 continue; 719 } 720 pungetc(); 721 goto breakloop; 722 case '\n': 723 plinno++; 724 needprompt = doprompt; 725 RETURN(TNL); 726 case PEOF: 727 RETURN(TEOF); 728 case '&': 729 if (pgetc() == '&') 730 RETURN(TAND); 731 pungetc(); 732 RETURN(TBACKGND); 733 case '|': 734 if (pgetc() == '|') 735 RETURN(TOR); 736 pungetc(); 737 RETURN(TPIPE); 738 case ';': 739 if (pgetc() == ';') 740 RETURN(TENDCASE); 741 pungetc(); 742 RETURN(TSEMI); 743 case '(': 744 RETURN(TLP); 745 case ')': 746 RETURN(TRP); 747 default: 748 goto breakloop; 749 } 750 } 751 breakloop: 752 return readtoken1(c, BASESYNTAX, (char *)NULL, 0); 753 #undef RETURN 754 } 755 756 757 758 /* 759 * If eofmark is NULL, read a word or a redirection symbol. If eofmark 760 * is not NULL, read a here document. In the latter case, eofmark is the 761 * word which marks the end of the document and striptabs is true if 762 * leading tabs should be stripped from the document. The argument firstc 763 * is the first character of the input token or document. 764 * 765 * Because C does not have internal subroutines, I have simulated them 766 * using goto's to implement the subroutine linkage. The following macros 767 * will run code that appears at the end of readtoken1. 768 */ 769 770 #define CHECKEND() {goto checkend; checkend_return:;} 771 #define PARSEREDIR() {goto parseredir; parseredir_return:;} 772 #define PARSESUB() {goto parsesub; parsesub_return:;} 773 #define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;} 774 #define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;} 775 #define PARSEARITH() {goto parsearith; parsearith_return:;} 776 777 STATIC int 778 readtoken1(firstc, syntax, eofmark, striptabs) 779 int firstc; 780 char const *syntax; 781 char *eofmark; 782 int striptabs; 783 { 784 register c = firstc; 785 register char *out; 786 int len; 787 char line[EOFMARKLEN + 1]; 788 struct nodelist *bqlist; 789 int quotef; 790 int dblquote; 791 int varnest; /* levels of variables expansion */ 792 int arinest; /* levels of arithmetic expansion */ 793 int parenlevel; /* levels of parens in arithmetic */ 794 int oldstyle; 795 char const *prevsyntax; /* syntax before arithmetic */ 796 797 startlinno = plinno; 798 dblquote = 0; 799 if (syntax == DQSYNTAX) 800 dblquote = 1; 801 quotef = 0; 802 bqlist = NULL; 803 varnest = 0; 804 arinest = 0; 805 parenlevel = 0; 806 807 STARTSTACKSTR(out); 808 loop: { /* for each line, until end of word */ 809 #if ATTY 810 if (c == '\034' && doprompt 811 && attyset() && ! equal(termval(), "emacs")) { 812 attyline(); 813 if (syntax == BASESYNTAX) 814 return readtoken(); 815 c = pgetc(); 816 goto loop; 817 } 818 #endif 819 CHECKEND(); /* set c to PEOF if at end of here document */ 820 for (;;) { /* until end of line or end of word */ 821 CHECKSTRSPACE(3, out); /* permit 3 calls to USTPUTC */ 822 if (parsebackquote && c == '\\') { 823 c = pgetc(); /* XXX - compat with old /bin/sh */ 824 if (c != '\\' && c != '`' && c != '$') { 825 pungetc(); 826 c = '\\'; 827 } 828 } 829 switch(syntax[c]) { 830 case CNL: /* '\n' */ 831 if (syntax == BASESYNTAX) 832 goto endword; /* exit outer loop */ 833 USTPUTC(c, out); 834 plinno++; 835 if (doprompt) 836 setprompt(2); 837 else 838 setprompt(0); 839 c = pgetc(); 840 goto loop; /* continue outer loop */ 841 case CWORD: 842 USTPUTC(c, out); 843 break; 844 case CCTL: 845 if (eofmark == NULL || dblquote) 846 USTPUTC(CTLESC, out); 847 USTPUTC(c, out); 848 break; 849 case CBACK: /* backslash */ 850 c = pgetc(); 851 if (c == PEOF) { 852 USTPUTC('\\', out); 853 pungetc(); 854 } else if (c == '\n') { 855 if (doprompt) 856 setprompt(2); 857 else 858 setprompt(0); 859 } else { 860 if (dblquote && c != '\\' && c != '`' && c != '$' 861 && (c != '"' || eofmark != NULL)) 862 USTPUTC('\\', out); 863 if (SQSYNTAX[c] == CCTL) 864 USTPUTC(CTLESC, out); 865 USTPUTC(c, out); 866 quotef++; 867 } 868 break; 869 case CSQUOTE: 870 syntax = SQSYNTAX; 871 break; 872 case CDQUOTE: 873 syntax = DQSYNTAX; 874 dblquote = 1; 875 break; 876 case CENDQUOTE: 877 if (eofmark) { 878 USTPUTC(c, out); 879 } else { 880 if (arinest) 881 syntax = ARISYNTAX; 882 else 883 syntax = BASESYNTAX; 884 quotef++; 885 dblquote = 0; 886 } 887 break; 888 case CVAR: /* '$' */ 889 PARSESUB(); /* parse substitution */ 890 break; 891 case CENDVAR: /* '}' */ 892 if (varnest > 0) { 893 varnest--; 894 USTPUTC(CTLENDVAR, out); 895 } else { 896 USTPUTC(c, out); 897 } 898 break; 899 case CLP: /* '(' in arithmetic */ 900 parenlevel++; 901 USTPUTC(c, out); 902 break; 903 case CRP: /* ')' in arithmetic */ 904 if (parenlevel > 0) { 905 USTPUTC(c, out); 906 --parenlevel; 907 } else { 908 if (pgetc() == ')') { 909 if (--arinest == 0) { 910 USTPUTC(CTLENDARI, out); 911 syntax = prevsyntax; 912 } else 913 USTPUTC(')', out); 914 } else { 915 /* 916 * unbalanced parens 917 * (don't 2nd guess - no error) 918 */ 919 pungetc(); 920 USTPUTC(')', out); 921 } 922 } 923 break; 924 case CBQUOTE: /* '`' */ 925 PARSEBACKQOLD(); 926 break; 927 case CEOF: 928 goto endword; /* exit outer loop */ 929 default: 930 if (varnest == 0) 931 goto endword; /* exit outer loop */ 932 USTPUTC(c, out); 933 } 934 c = pgetc_macro(); 935 } 936 } 937 endword: 938 if (syntax == ARISYNTAX) 939 synerror("Missing '))'"); 940 if (syntax != BASESYNTAX && ! parsebackquote && eofmark == NULL) 941 synerror("Unterminated quoted string"); 942 if (varnest != 0) { 943 startlinno = plinno; 944 synerror("Missing '}'"); 945 } 946 USTPUTC('\0', out); 947 len = out - stackblock(); 948 out = stackblock(); 949 if (eofmark == NULL) { 950 if ((c == '>' || c == '<') 951 && quotef == 0 952 && len <= 2 953 && (*out == '\0' || is_digit(*out))) { 954 PARSEREDIR(); 955 return lasttoken = TREDIR; 956 } else { 957 pungetc(); 958 } 959 } 960 quoteflag = quotef; 961 backquotelist = bqlist; 962 grabstackblock(len); 963 wordtext = out; 964 return lasttoken = TWORD; 965 /* end of readtoken routine */ 966 967 968 969 /* 970 * Check to see whether we are at the end of the here document. When this 971 * is called, c is set to the first character of the next input line. If 972 * we are at the end of the here document, this routine sets the c to PEOF. 973 */ 974 975 checkend: { 976 if (eofmark) { 977 if (striptabs) { 978 while (c == '\t') 979 c = pgetc(); 980 } 981 if (c == *eofmark) { 982 if (pfgets(line, sizeof line) != NULL) { 983 register char *p, *q; 984 985 p = line; 986 for (q = eofmark + 1 ; *q && *p == *q ; p++, q++); 987 if (*p == '\n' && *q == '\0') { 988 c = PEOF; 989 plinno++; 990 needprompt = doprompt; 991 } else { 992 pushstring(line, strlen(line), NULL); 993 } 994 } 995 } 996 } 997 goto checkend_return; 998 } 999 1000 1001 /* 1002 * Parse a redirection operator. The variable "out" points to a string 1003 * specifying the fd to be redirected. The variable "c" contains the 1004 * first character of the redirection operator. 1005 */ 1006 1007 parseredir: { 1008 char fd = *out; 1009 union node *np; 1010 1011 np = (union node *)stalloc(sizeof (struct nfile)); 1012 if (c == '>') { 1013 np->nfile.fd = 1; 1014 c = pgetc(); 1015 if (c == '>') 1016 np->type = NAPPEND; 1017 else if (c == '&') 1018 np->type = NTOFD; 1019 else { 1020 np->type = NTO; 1021 pungetc(); 1022 } 1023 } else { /* c == '<' */ 1024 np->nfile.fd = 0; 1025 c = pgetc(); 1026 if (c == '<') { 1027 if (sizeof (struct nfile) != sizeof (struct nhere)) { 1028 np = (union node *)stalloc(sizeof (struct nhere)); 1029 np->nfile.fd = 0; 1030 } 1031 np->type = NHERE; 1032 heredoc = (struct heredoc *)stalloc(sizeof (struct heredoc)); 1033 heredoc->here = np; 1034 if ((c = pgetc()) == '-') { 1035 heredoc->striptabs = 1; 1036 } else { 1037 heredoc->striptabs = 0; 1038 pungetc(); 1039 } 1040 } else if (c == '&') 1041 np->type = NFROMFD; 1042 else { 1043 np->type = NFROM; 1044 pungetc(); 1045 } 1046 } 1047 if (fd != '\0') 1048 np->nfile.fd = digit_val(fd); 1049 redirnode = np; 1050 goto parseredir_return; 1051 } 1052 1053 1054 /* 1055 * Parse a substitution. At this point, we have read the dollar sign 1056 * and nothing else. 1057 */ 1058 1059 parsesub: { 1060 int subtype; 1061 int typeloc; 1062 int flags; 1063 char *p; 1064 #ifndef GDB_HACK 1065 static const char types[] = "}-+?="; 1066 #endif 1067 1068 c = pgetc(); 1069 if (c != '(' && c != '{' && !is_name(c) && !is_special(c)) { 1070 USTPUTC('$', out); 1071 pungetc(); 1072 } else if (c == '(') { /* $(command) or $((arith)) */ 1073 if (pgetc() == '(') { 1074 PARSEARITH(); 1075 } else { 1076 pungetc(); 1077 PARSEBACKQNEW(); 1078 } 1079 } else { 1080 USTPUTC(CTLVAR, out); 1081 typeloc = out - stackblock(); 1082 USTPUTC(VSNORMAL, out); 1083 subtype = VSNORMAL; 1084 if (c == '{') { 1085 c = pgetc(); 1086 if (c == '#') { 1087 subtype = VSLENGTH; 1088 c = pgetc(); 1089 } 1090 else 1091 subtype = 0; 1092 } 1093 if (is_name(c)) { 1094 do { 1095 STPUTC(c, out); 1096 c = pgetc(); 1097 } while (is_in_name(c)); 1098 } else { 1099 if (! is_special(c)) 1100 badsub: synerror("Bad substitution"); 1101 USTPUTC(c, out); 1102 c = pgetc(); 1103 } 1104 STPUTC('=', out); 1105 flags = 0; 1106 if (subtype == 0) { 1107 switch (c) { 1108 case ':': 1109 flags = VSNUL; 1110 c = pgetc(); 1111 /*FALLTHROUGH*/ 1112 default: 1113 p = strchr(types, c); 1114 if (p == NULL) 1115 goto badsub; 1116 subtype = p - types + VSNORMAL; 1117 break; 1118 case '%': 1119 case '#': 1120 { 1121 int cc = c; 1122 subtype = c == '#' ? VSTRIMLEFT : 1123 VSTRIMRIGHT; 1124 c = pgetc(); 1125 if (c == cc) 1126 subtype++; 1127 else 1128 pungetc(); 1129 break; 1130 } 1131 } 1132 } else { 1133 pungetc(); 1134 } 1135 if (dblquote || arinest) 1136 flags |= VSQUOTE; 1137 *(stackblock() + typeloc) = subtype | flags; 1138 if (subtype != VSNORMAL) 1139 varnest++; 1140 } 1141 goto parsesub_return; 1142 } 1143 1144 1145 /* 1146 * Called to parse command substitutions. Newstyle is set if the command 1147 * is enclosed inside $(...); nlpp is a pointer to the head of the linked 1148 * list of commands (passed by reference), and savelen is the number of 1149 * characters on the top of the stack which must be preserved. 1150 */ 1151 1152 parsebackq: { 1153 struct nodelist **nlpp; 1154 int savepbq; 1155 union node *n; 1156 char *volatile str; 1157 struct jmploc jmploc; 1158 struct jmploc *volatile savehandler; 1159 int savelen; 1160 1161 savepbq = parsebackquote; 1162 if (setjmp(jmploc.loc)) { 1163 if (str) 1164 ckfree(str); 1165 parsebackquote = 0; 1166 handler = savehandler; 1167 longjmp(handler->loc, 1); 1168 } 1169 INTOFF; 1170 str = NULL; 1171 savelen = out - stackblock(); 1172 if (savelen > 0) { 1173 str = ckmalloc(savelen); 1174 memmove(str, stackblock(), savelen); 1175 } 1176 savehandler = handler; 1177 handler = &jmploc; 1178 INTON; 1179 if (oldstyle) { 1180 /* We must read until the closing backquote, giving special 1181 treatment to some slashes, and then push the string and 1182 reread it as input, interpreting it normally. */ 1183 register char *out; 1184 register c; 1185 int savelen; 1186 char *str; 1187 1188 STARTSTACKSTR(out); 1189 while ((c = pgetc ()) != '`') { 1190 if (c == '\\') { 1191 c = pgetc (); 1192 if (c != '\\' && c != '`' && c != '$' 1193 && (!dblquote || c != '"')) 1194 STPUTC('\\', out); 1195 } 1196 STPUTC(c, out); 1197 } 1198 STPUTC('\0', out); 1199 savelen = out - stackblock(); 1200 if (savelen > 0) { 1201 str = ckmalloc(savelen); 1202 memmove(str, stackblock(), savelen); 1203 } 1204 setinputstring(str, 1); 1205 } 1206 nlpp = &bqlist; 1207 while (*nlpp) 1208 nlpp = &(*nlpp)->next; 1209 *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist)); 1210 (*nlpp)->next = NULL; 1211 parsebackquote = oldstyle; 1212 n = list(0); 1213 if (!oldstyle && (readtoken() != TRP)) 1214 synexpect(TRP); 1215 (*nlpp)->n = n; 1216 /* Start reading from old file again. */ 1217 if (oldstyle) 1218 popfile(); 1219 while (stackblocksize() <= savelen) 1220 growstackblock(); 1221 STARTSTACKSTR(out); 1222 if (str) { 1223 memmove(out, str, savelen); 1224 STADJUST(savelen, out); 1225 INTOFF; 1226 ckfree(str); 1227 str = NULL; 1228 INTON; 1229 } 1230 parsebackquote = savepbq; 1231 handler = savehandler; 1232 if (arinest || dblquote) 1233 USTPUTC(CTLBACKQ | CTLQUOTE, out); 1234 else 1235 USTPUTC(CTLBACKQ, out); 1236 if (oldstyle) 1237 goto parsebackq_oldreturn; 1238 else 1239 goto parsebackq_newreturn; 1240 } 1241 1242 /* 1243 * Parse an arithmetic expansion (indicate start of one and set state) 1244 */ 1245 parsearith: { 1246 1247 if (++arinest == 1) { 1248 prevsyntax = syntax; 1249 syntax = ARISYNTAX; 1250 USTPUTC(CTLARI, out); 1251 } else { 1252 /* 1253 * we collapse embedded arithmetic expansion to 1254 * parenthesis, which should be equivalent 1255 */ 1256 USTPUTC('(', out); 1257 } 1258 goto parsearith_return; 1259 } 1260 1261 } /* end of readtoken */ 1262 1263 1264 1265 #ifdef mkinit 1266 RESET { 1267 tokpushback = 0; 1268 checkkwd = 0; 1269 } 1270 #endif 1271 1272 /* 1273 * Returns true if the text contains nothing to expand (no dollar signs 1274 * or backquotes). 1275 */ 1276 1277 STATIC int 1278 noexpand(text) 1279 char *text; 1280 { 1281 register char *p; 1282 register char c; 1283 1284 p = text; 1285 while ((c = *p++) != '\0') { 1286 if (c == CTLESC) 1287 p++; 1288 else if (BASESYNTAX[c] == CCTL) 1289 return 0; 1290 } 1291 return 1; 1292 } 1293 1294 1295 /* 1296 * Return true if the argument is a legal variable name (a letter or 1297 * underscore followed by zero or more letters, underscores, and digits). 1298 */ 1299 1300 int 1301 goodname(name) 1302 char *name; 1303 { 1304 register char *p; 1305 1306 p = name; 1307 if (! is_name(*p)) 1308 return 0; 1309 while (*++p) { 1310 if (! is_in_name(*p)) 1311 return 0; 1312 } 1313 return 1; 1314 } 1315 1316 1317 /* 1318 * Called when an unexpected token is read during the parse. The argument 1319 * is the token that is expected, or -1 if more than one type of token can 1320 * occur at this point. 1321 */ 1322 1323 STATIC void 1324 synexpect(token) { 1325 char msg[64]; 1326 1327 if (token >= 0) { 1328 fmtstr(msg, 64, "%s unexpected (expecting %s)", 1329 tokname[lasttoken], tokname[token]); 1330 } else { 1331 fmtstr(msg, 64, "%s unexpected", tokname[lasttoken]); 1332 } 1333 synerror(msg); 1334 } 1335 1336 1337 STATIC void 1338 synerror(msg) 1339 char *msg; 1340 { 1341 if (commandname) 1342 outfmt(&errout, "%s: %d: ", commandname, startlinno); 1343 outfmt(&errout, "Syntax error: %s\n", msg); 1344 error((char *)NULL); 1345 } 1346 1347 STATIC void 1348 setprompt(which) 1349 int which; 1350 { 1351 whichprompt = which; 1352 1353 if (!el) 1354 out2str(getprompt(NULL)); 1355 } 1356 1357 /* 1358 * called by editline -- any expansions to the prompt 1359 * should be added here. 1360 */ 1361 char * 1362 getprompt(unused) 1363 void *unused; 1364 { 1365 switch (whichprompt) { 1366 case 0: 1367 return ""; 1368 case 1: 1369 return ps1val(); 1370 case 2: 1371 return ps2val(); 1372 default: 1373 return "<internal prompt error>"; 1374 } 1375 } 1376