/bin/sh/parser.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 2080 lines · 1844 code · 104 blank · 132 comment · 361 complexity · 5c3435391c19382f0f15de4322b344af MD5 · raw file

  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. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. * 4. Neither the name of the University nor the names of its contributors
  17. * may be used to endorse or promote products derived from this software
  18. * without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  21. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  24. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  26. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. */
  32. #ifndef lint
  33. #if 0
  34. static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95";
  35. #endif
  36. #endif /* not lint */
  37. #include <sys/cdefs.h>
  38. __FBSDID("$FreeBSD$");
  39. #include <stdlib.h>
  40. #include <unistd.h>
  41. #include <stdio.h>
  42. #include "shell.h"
  43. #include "parser.h"
  44. #include "nodes.h"
  45. #include "expand.h" /* defines rmescapes() */
  46. #include "syntax.h"
  47. #include "options.h"
  48. #include "input.h"
  49. #include "output.h"
  50. #include "var.h"
  51. #include "error.h"
  52. #include "memalloc.h"
  53. #include "mystring.h"
  54. #include "alias.h"
  55. #include "show.h"
  56. #include "eval.h"
  57. #include "exec.h" /* to check for special builtins */
  58. #ifndef NO_HISTORY
  59. #include "myhistedit.h"
  60. #endif
  61. /*
  62. * Shell command parser.
  63. */
  64. #define EOFMARKLEN 79
  65. #define PROMPTLEN 128
  66. /* values of checkkwd variable */
  67. #define CHKALIAS 0x1
  68. #define CHKKWD 0x2
  69. #define CHKNL 0x4
  70. /* values returned by readtoken */
  71. #include "token.h"
  72. struct heredoc {
  73. struct heredoc *next; /* next here document in list */
  74. union node *here; /* redirection node */
  75. char *eofmark; /* string indicating end of input */
  76. int striptabs; /* if set, strip leading tabs */
  77. };
  78. struct parser_temp {
  79. struct parser_temp *next;
  80. void *data;
  81. };
  82. static struct heredoc *heredoclist; /* list of here documents to read */
  83. static int doprompt; /* if set, prompt the user */
  84. static int needprompt; /* true if interactive and at start of line */
  85. static int lasttoken; /* last token read */
  86. MKINIT int tokpushback; /* last token pushed back */
  87. static char *wordtext; /* text of last word returned by readtoken */
  88. MKINIT int checkkwd; /* 1 == check for kwds, 2 == also eat newlines */
  89. static struct nodelist *backquotelist;
  90. static union node *redirnode;
  91. static struct heredoc *heredoc;
  92. static int quoteflag; /* set if (part of) last token was quoted */
  93. static int startlinno; /* line # where last token started */
  94. static int funclinno; /* line # where the current function started */
  95. static struct parser_temp *parser_temp;
  96. static union node *list(int, int);
  97. static union node *andor(void);
  98. static union node *pipeline(void);
  99. static union node *command(void);
  100. static union node *simplecmd(union node **, union node *);
  101. static union node *makename(void);
  102. static void parsefname(void);
  103. static void parseheredoc(void);
  104. static int peektoken(void);
  105. static int readtoken(void);
  106. static int xxreadtoken(void);
  107. static int readtoken1(int, char const *, char *, int);
  108. static int noexpand(char *);
  109. static void synexpect(int) __dead2;
  110. static void synerror(const char *) __dead2;
  111. static void setprompt(int);
  112. static void *
  113. parser_temp_alloc(size_t len)
  114. {
  115. struct parser_temp *t;
  116. INTOFF;
  117. t = ckmalloc(sizeof(*t));
  118. t->data = NULL;
  119. t->next = parser_temp;
  120. parser_temp = t;
  121. t->data = ckmalloc(len);
  122. INTON;
  123. return t->data;
  124. }
  125. static void *
  126. parser_temp_realloc(void *ptr, size_t len)
  127. {
  128. struct parser_temp *t;
  129. INTOFF;
  130. t = parser_temp;
  131. if (ptr != t->data)
  132. error("bug: parser_temp_realloc misused");
  133. t->data = ckrealloc(t->data, len);
  134. INTON;
  135. return t->data;
  136. }
  137. static void
  138. parser_temp_free_upto(void *ptr)
  139. {
  140. struct parser_temp *t;
  141. int done = 0;
  142. INTOFF;
  143. while (parser_temp != NULL && !done) {
  144. t = parser_temp;
  145. parser_temp = t->next;
  146. done = t->data == ptr;
  147. ckfree(t->data);
  148. ckfree(t);
  149. }
  150. INTON;
  151. if (!done)
  152. error("bug: parser_temp_free_upto misused");
  153. }
  154. static void
  155. parser_temp_free_all(void)
  156. {
  157. struct parser_temp *t;
  158. INTOFF;
  159. while (parser_temp != NULL) {
  160. t = parser_temp;
  161. parser_temp = t->next;
  162. ckfree(t->data);
  163. ckfree(t);
  164. }
  165. INTON;
  166. }
  167. /*
  168. * Read and parse a command. Returns NEOF on end of file. (NULL is a
  169. * valid parse tree indicating a blank line.)
  170. */
  171. union node *
  172. parsecmd(int interact)
  173. {
  174. int t;
  175. /* This assumes the parser is not re-entered,
  176. * which could happen if we add command substitution on PS1/PS2.
  177. */
  178. parser_temp_free_all();
  179. heredoclist = NULL;
  180. tokpushback = 0;
  181. doprompt = interact;
  182. if (doprompt)
  183. setprompt(1);
  184. else
  185. setprompt(0);
  186. needprompt = 0;
  187. t = readtoken();
  188. if (t == TEOF)
  189. return NEOF;
  190. if (t == TNL)
  191. return NULL;
  192. tokpushback++;
  193. return list(1, 1);
  194. }
  195. static union node *
  196. list(int nlflag, int erflag)
  197. {
  198. union node *ntop, *n1, *n2, *n3;
  199. int tok;
  200. checkkwd = CHKNL | CHKKWD | CHKALIAS;
  201. if (!nlflag && !erflag && tokendlist[peektoken()])
  202. return NULL;
  203. ntop = n1 = NULL;
  204. for (;;) {
  205. n2 = andor();
  206. tok = readtoken();
  207. if (tok == TBACKGND) {
  208. if (n2->type == NPIPE) {
  209. n2->npipe.backgnd = 1;
  210. } else if (n2->type == NREDIR) {
  211. n2->type = NBACKGND;
  212. } else {
  213. n3 = (union node *)stalloc(sizeof (struct nredir));
  214. n3->type = NBACKGND;
  215. n3->nredir.n = n2;
  216. n3->nredir.redirect = NULL;
  217. n2 = n3;
  218. }
  219. }
  220. if (ntop == NULL)
  221. ntop = n2;
  222. else if (n1 == NULL) {
  223. n1 = (union node *)stalloc(sizeof (struct nbinary));
  224. n1->type = NSEMI;
  225. n1->nbinary.ch1 = ntop;
  226. n1->nbinary.ch2 = n2;
  227. ntop = n1;
  228. }
  229. else {
  230. n3 = (union node *)stalloc(sizeof (struct nbinary));
  231. n3->type = NSEMI;
  232. n3->nbinary.ch1 = n1->nbinary.ch2;
  233. n3->nbinary.ch2 = n2;
  234. n1->nbinary.ch2 = n3;
  235. n1 = n3;
  236. }
  237. switch (tok) {
  238. case TBACKGND:
  239. case TSEMI:
  240. tok = readtoken();
  241. /* FALLTHROUGH */
  242. case TNL:
  243. if (tok == TNL) {
  244. parseheredoc();
  245. if (nlflag)
  246. return ntop;
  247. } else if (tok == TEOF && nlflag) {
  248. parseheredoc();
  249. return ntop;
  250. } else {
  251. tokpushback++;
  252. }
  253. checkkwd = CHKNL | CHKKWD | CHKALIAS;
  254. if (!nlflag && !erflag && tokendlist[peektoken()])
  255. return ntop;
  256. break;
  257. case TEOF:
  258. if (heredoclist)
  259. parseheredoc();
  260. else
  261. pungetc(); /* push back EOF on input */
  262. return ntop;
  263. default:
  264. if (nlflag || erflag)
  265. synexpect(-1);
  266. tokpushback++;
  267. return ntop;
  268. }
  269. }
  270. }
  271. static union node *
  272. andor(void)
  273. {
  274. union node *n1, *n2, *n3;
  275. int t;
  276. n1 = pipeline();
  277. for (;;) {
  278. if ((t = readtoken()) == TAND) {
  279. t = NAND;
  280. } else if (t == TOR) {
  281. t = NOR;
  282. } else {
  283. tokpushback++;
  284. return n1;
  285. }
  286. n2 = pipeline();
  287. n3 = (union node *)stalloc(sizeof (struct nbinary));
  288. n3->type = t;
  289. n3->nbinary.ch1 = n1;
  290. n3->nbinary.ch2 = n2;
  291. n1 = n3;
  292. }
  293. }
  294. static union node *
  295. pipeline(void)
  296. {
  297. union node *n1, *n2, *pipenode;
  298. struct nodelist *lp, *prev;
  299. int negate, t;
  300. negate = 0;
  301. checkkwd = CHKNL | CHKKWD | CHKALIAS;
  302. TRACE(("pipeline: entered\n"));
  303. while (readtoken() == TNOT)
  304. negate = !negate;
  305. tokpushback++;
  306. n1 = command();
  307. if (readtoken() == TPIPE) {
  308. pipenode = (union node *)stalloc(sizeof (struct npipe));
  309. pipenode->type = NPIPE;
  310. pipenode->npipe.backgnd = 0;
  311. lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
  312. pipenode->npipe.cmdlist = lp;
  313. lp->n = n1;
  314. do {
  315. prev = lp;
  316. lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
  317. checkkwd = CHKNL | CHKKWD | CHKALIAS;
  318. t = readtoken();
  319. tokpushback++;
  320. if (t == TNOT)
  321. lp->n = pipeline();
  322. else
  323. lp->n = command();
  324. prev->next = lp;
  325. } while (readtoken() == TPIPE);
  326. lp->next = NULL;
  327. n1 = pipenode;
  328. }
  329. tokpushback++;
  330. if (negate) {
  331. n2 = (union node *)stalloc(sizeof (struct nnot));
  332. n2->type = NNOT;
  333. n2->nnot.com = n1;
  334. return n2;
  335. } else
  336. return n1;
  337. }
  338. static union node *
  339. command(void)
  340. {
  341. union node *n1, *n2;
  342. union node *ap, **app;
  343. union node *cp, **cpp;
  344. union node *redir, **rpp;
  345. int t;
  346. int is_subshell;
  347. checkkwd = CHKNL | CHKKWD | CHKALIAS;
  348. is_subshell = 0;
  349. redir = NULL;
  350. n1 = NULL;
  351. rpp = &redir;
  352. /* Check for redirection which may precede command */
  353. while (readtoken() == TREDIR) {
  354. *rpp = n2 = redirnode;
  355. rpp = &n2->nfile.next;
  356. parsefname();
  357. }
  358. tokpushback++;
  359. switch (readtoken()) {
  360. case TIF:
  361. n1 = (union node *)stalloc(sizeof (struct nif));
  362. n1->type = NIF;
  363. if ((n1->nif.test = list(0, 0)) == NULL)
  364. synexpect(-1);
  365. if (readtoken() != TTHEN)
  366. synexpect(TTHEN);
  367. n1->nif.ifpart = list(0, 0);
  368. n2 = n1;
  369. while (readtoken() == TELIF) {
  370. n2->nif.elsepart = (union node *)stalloc(sizeof (struct nif));
  371. n2 = n2->nif.elsepart;
  372. n2->type = NIF;
  373. if ((n2->nif.test = list(0, 0)) == NULL)
  374. synexpect(-1);
  375. if (readtoken() != TTHEN)
  376. synexpect(TTHEN);
  377. n2->nif.ifpart = list(0, 0);
  378. }
  379. if (lasttoken == TELSE)
  380. n2->nif.elsepart = list(0, 0);
  381. else {
  382. n2->nif.elsepart = NULL;
  383. tokpushback++;
  384. }
  385. if (readtoken() != TFI)
  386. synexpect(TFI);
  387. checkkwd = CHKKWD | CHKALIAS;
  388. break;
  389. case TWHILE:
  390. case TUNTIL: {
  391. int got;
  392. n1 = (union node *)stalloc(sizeof (struct nbinary));
  393. n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL;
  394. if ((n1->nbinary.ch1 = list(0, 0)) == NULL)
  395. synexpect(-1);
  396. if ((got=readtoken()) != TDO) {
  397. TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
  398. synexpect(TDO);
  399. }
  400. n1->nbinary.ch2 = list(0, 0);
  401. if (readtoken() != TDONE)
  402. synexpect(TDONE);
  403. checkkwd = CHKKWD | CHKALIAS;
  404. break;
  405. }
  406. case TFOR:
  407. if (readtoken() != TWORD || quoteflag || ! goodname(wordtext))
  408. synerror("Bad for loop variable");
  409. n1 = (union node *)stalloc(sizeof (struct nfor));
  410. n1->type = NFOR;
  411. n1->nfor.var = wordtext;
  412. while (readtoken() == TNL)
  413. ;
  414. if (lasttoken == TWORD && ! quoteflag && equal(wordtext, "in")) {
  415. app = &ap;
  416. while (readtoken() == TWORD) {
  417. n2 = (union node *)stalloc(sizeof (struct narg));
  418. n2->type = NARG;
  419. n2->narg.text = wordtext;
  420. n2->narg.backquote = backquotelist;
  421. *app = n2;
  422. app = &n2->narg.next;
  423. }
  424. *app = NULL;
  425. n1->nfor.args = ap;
  426. if (lasttoken != TNL && lasttoken != TSEMI)
  427. synexpect(-1);
  428. } else {
  429. static char argvars[5] = {
  430. CTLVAR, VSNORMAL|VSQUOTE, '@', '=', '\0'
  431. };
  432. n2 = (union node *)stalloc(sizeof (struct narg));
  433. n2->type = NARG;
  434. n2->narg.text = argvars;
  435. n2->narg.backquote = NULL;
  436. n2->narg.next = NULL;
  437. n1->nfor.args = n2;
  438. /*
  439. * Newline or semicolon here is optional (but note
  440. * that the original Bourne shell only allowed NL).
  441. */
  442. if (lasttoken != TNL && lasttoken != TSEMI)
  443. tokpushback++;
  444. }
  445. checkkwd = CHKNL | CHKKWD | CHKALIAS;
  446. if ((t = readtoken()) == TDO)
  447. t = TDONE;
  448. else if (t == TBEGIN)
  449. t = TEND;
  450. else
  451. synexpect(-1);
  452. n1->nfor.body = list(0, 0);
  453. if (readtoken() != t)
  454. synexpect(t);
  455. checkkwd = CHKKWD | CHKALIAS;
  456. break;
  457. case TCASE:
  458. n1 = (union node *)stalloc(sizeof (struct ncase));
  459. n1->type = NCASE;
  460. if (readtoken() != TWORD)
  461. synexpect(TWORD);
  462. n1->ncase.expr = n2 = (union node *)stalloc(sizeof (struct narg));
  463. n2->type = NARG;
  464. n2->narg.text = wordtext;
  465. n2->narg.backquote = backquotelist;
  466. n2->narg.next = NULL;
  467. while (readtoken() == TNL);
  468. if (lasttoken != TWORD || ! equal(wordtext, "in"))
  469. synerror("expecting \"in\"");
  470. cpp = &n1->ncase.cases;
  471. checkkwd = CHKNL | CHKKWD, readtoken();
  472. while (lasttoken != TESAC) {
  473. *cpp = cp = (union node *)stalloc(sizeof (struct nclist));
  474. cp->type = NCLIST;
  475. app = &cp->nclist.pattern;
  476. if (lasttoken == TLP)
  477. readtoken();
  478. for (;;) {
  479. *app = ap = (union node *)stalloc(sizeof (struct narg));
  480. ap->type = NARG;
  481. ap->narg.text = wordtext;
  482. ap->narg.backquote = backquotelist;
  483. checkkwd = CHKNL | CHKKWD;
  484. if (readtoken() != TPIPE)
  485. break;
  486. app = &ap->narg.next;
  487. readtoken();
  488. }
  489. ap->narg.next = NULL;
  490. if (lasttoken != TRP)
  491. synexpect(TRP);
  492. cp->nclist.body = list(0, 0);
  493. checkkwd = CHKNL | CHKKWD | CHKALIAS;
  494. if ((t = readtoken()) != TESAC) {
  495. if (t == TENDCASE)
  496. ;
  497. else if (t == TFALLTHRU)
  498. cp->type = NCLISTFALLTHRU;
  499. else
  500. synexpect(TENDCASE);
  501. checkkwd = CHKNL | CHKKWD, readtoken();
  502. }
  503. cpp = &cp->nclist.next;
  504. }
  505. *cpp = NULL;
  506. checkkwd = CHKKWD | CHKALIAS;
  507. break;
  508. case TLP:
  509. n1 = (union node *)stalloc(sizeof (struct nredir));
  510. n1->type = NSUBSHELL;
  511. n1->nredir.n = list(0, 0);
  512. n1->nredir.redirect = NULL;
  513. if (readtoken() != TRP)
  514. synexpect(TRP);
  515. checkkwd = CHKKWD | CHKALIAS;
  516. is_subshell = 1;
  517. break;
  518. case TBEGIN:
  519. n1 = list(0, 0);
  520. if (readtoken() != TEND)
  521. synexpect(TEND);
  522. checkkwd = CHKKWD | CHKALIAS;
  523. break;
  524. /* Handle an empty command like other simple commands. */
  525. case TBACKGND:
  526. case TSEMI:
  527. case TAND:
  528. case TOR:
  529. /*
  530. * An empty command before a ; doesn't make much sense, and
  531. * should certainly be disallowed in the case of `if ;'.
  532. */
  533. if (!redir)
  534. synexpect(-1);
  535. case TNL:
  536. case TEOF:
  537. case TWORD:
  538. case TRP:
  539. tokpushback++;
  540. n1 = simplecmd(rpp, redir);
  541. return n1;
  542. default:
  543. synexpect(-1);
  544. }
  545. /* Now check for redirection which may follow command */
  546. while (readtoken() == TREDIR) {
  547. *rpp = n2 = redirnode;
  548. rpp = &n2->nfile.next;
  549. parsefname();
  550. }
  551. tokpushback++;
  552. *rpp = NULL;
  553. if (redir) {
  554. if (!is_subshell) {
  555. n2 = (union node *)stalloc(sizeof (struct nredir));
  556. n2->type = NREDIR;
  557. n2->nredir.n = n1;
  558. n1 = n2;
  559. }
  560. n1->nredir.redirect = redir;
  561. }
  562. return n1;
  563. }
  564. static union node *
  565. simplecmd(union node **rpp, union node *redir)
  566. {
  567. union node *args, **app;
  568. union node **orig_rpp = rpp;
  569. union node *n = NULL;
  570. int special;
  571. int savecheckkwd;
  572. /* If we don't have any redirections already, then we must reset */
  573. /* rpp to be the address of the local redir variable. */
  574. if (redir == 0)
  575. rpp = &redir;
  576. args = NULL;
  577. app = &args;
  578. /*
  579. * We save the incoming value, because we need this for shell
  580. * functions. There can not be a redirect or an argument between
  581. * the function name and the open parenthesis.
  582. */
  583. orig_rpp = rpp;
  584. savecheckkwd = CHKALIAS;
  585. for (;;) {
  586. checkkwd = savecheckkwd;
  587. if (readtoken() == TWORD) {
  588. n = (union node *)stalloc(sizeof (struct narg));
  589. n->type = NARG;
  590. n->narg.text = wordtext;
  591. n->narg.backquote = backquotelist;
  592. *app = n;
  593. app = &n->narg.next;
  594. if (savecheckkwd != 0 && !isassignment(wordtext))
  595. savecheckkwd = 0;
  596. } else if (lasttoken == TREDIR) {
  597. *rpp = n = redirnode;
  598. rpp = &n->nfile.next;
  599. parsefname(); /* read name of redirection file */
  600. } else if (lasttoken == TLP && app == &args->narg.next
  601. && rpp == orig_rpp) {
  602. /* We have a function */
  603. if (readtoken() != TRP)
  604. synexpect(TRP);
  605. funclinno = plinno;
  606. /*
  607. * - Require plain text.
  608. * - Functions with '/' cannot be called.
  609. * - Reject name=().
  610. * - Reject ksh extended glob patterns.
  611. */
  612. if (!noexpand(n->narg.text) || quoteflag ||
  613. strchr(n->narg.text, '/') ||
  614. strchr("!%*+-=?@}~",
  615. n->narg.text[strlen(n->narg.text) - 1]))
  616. synerror("Bad function name");
  617. rmescapes(n->narg.text);
  618. if (find_builtin(n->narg.text, &special) >= 0 &&
  619. special)
  620. synerror("Cannot override a special builtin with a function");
  621. n->type = NDEFUN;
  622. n->narg.next = command();
  623. funclinno = 0;
  624. return n;
  625. } else {
  626. tokpushback++;
  627. break;
  628. }
  629. }
  630. *app = NULL;
  631. *rpp = NULL;
  632. n = (union node *)stalloc(sizeof (struct ncmd));
  633. n->type = NCMD;
  634. n->ncmd.args = args;
  635. n->ncmd.redirect = redir;
  636. return n;
  637. }
  638. static union node *
  639. makename(void)
  640. {
  641. union node *n;
  642. n = (union node *)stalloc(sizeof (struct narg));
  643. n->type = NARG;
  644. n->narg.next = NULL;
  645. n->narg.text = wordtext;
  646. n->narg.backquote = backquotelist;
  647. return n;
  648. }
  649. void
  650. fixredir(union node *n, const char *text, int err)
  651. {
  652. TRACE(("Fix redir %s %d\n", text, err));
  653. if (!err)
  654. n->ndup.vname = NULL;
  655. if (is_digit(text[0]) && text[1] == '\0')
  656. n->ndup.dupfd = digit_val(text[0]);
  657. else if (text[0] == '-' && text[1] == '\0')
  658. n->ndup.dupfd = -1;
  659. else {
  660. if (err)
  661. synerror("Bad fd number");
  662. else
  663. n->ndup.vname = makename();
  664. }
  665. }
  666. static void
  667. parsefname(void)
  668. {
  669. union node *n = redirnode;
  670. if (readtoken() != TWORD)
  671. synexpect(-1);
  672. if (n->type == NHERE) {
  673. struct heredoc *here = heredoc;
  674. struct heredoc *p;
  675. int i;
  676. if (quoteflag == 0)
  677. n->type = NXHERE;
  678. TRACE(("Here document %d\n", n->type));
  679. if (here->striptabs) {
  680. while (*wordtext == '\t')
  681. wordtext++;
  682. }
  683. if (! noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN)
  684. synerror("Illegal eof marker for << redirection");
  685. rmescapes(wordtext);
  686. here->eofmark = wordtext;
  687. here->next = NULL;
  688. if (heredoclist == NULL)
  689. heredoclist = here;
  690. else {
  691. for (p = heredoclist ; p->next ; p = p->next);
  692. p->next = here;
  693. }
  694. } else if (n->type == NTOFD || n->type == NFROMFD) {
  695. fixredir(n, wordtext, 0);
  696. } else {
  697. n->nfile.fname = makename();
  698. }
  699. }
  700. /*
  701. * Input any here documents.
  702. */
  703. static void
  704. parseheredoc(void)
  705. {
  706. struct heredoc *here;
  707. union node *n;
  708. while (heredoclist) {
  709. here = heredoclist;
  710. heredoclist = here->next;
  711. if (needprompt) {
  712. setprompt(2);
  713. needprompt = 0;
  714. }
  715. readtoken1(pgetc(), here->here->type == NHERE? SQSYNTAX : DQSYNTAX,
  716. here->eofmark, here->striptabs);
  717. n = (union node *)stalloc(sizeof (struct narg));
  718. n->narg.type = NARG;
  719. n->narg.next = NULL;
  720. n->narg.text = wordtext;
  721. n->narg.backquote = backquotelist;
  722. here->here->nhere.doc = n;
  723. }
  724. }
  725. static int
  726. peektoken(void)
  727. {
  728. int t;
  729. t = readtoken();
  730. tokpushback++;
  731. return (t);
  732. }
  733. static int
  734. readtoken(void)
  735. {
  736. int t;
  737. struct alias *ap;
  738. #ifdef DEBUG
  739. int alreadyseen = tokpushback;
  740. #endif
  741. top:
  742. t = xxreadtoken();
  743. /*
  744. * eat newlines
  745. */
  746. if (checkkwd & CHKNL) {
  747. while (t == TNL) {
  748. parseheredoc();
  749. t = xxreadtoken();
  750. }
  751. }
  752. /*
  753. * check for keywords and aliases
  754. */
  755. if (t == TWORD && !quoteflag)
  756. {
  757. const char * const *pp;
  758. if (checkkwd & CHKKWD)
  759. for (pp = parsekwd; *pp; pp++) {
  760. if (**pp == *wordtext && equal(*pp, wordtext))
  761. {
  762. lasttoken = t = pp - parsekwd + KWDOFFSET;
  763. TRACE(("keyword %s recognized\n", tokname[t]));
  764. goto out;
  765. }
  766. }
  767. if (checkkwd & CHKALIAS &&
  768. (ap = lookupalias(wordtext, 1)) != NULL) {
  769. pushstring(ap->val, strlen(ap->val), ap);
  770. goto top;
  771. }
  772. }
  773. out:
  774. if (t != TNOT)
  775. checkkwd = 0;
  776. #ifdef DEBUG
  777. if (!alreadyseen)
  778. TRACE(("token %s %s\n", tokname[t], t == TWORD ? wordtext : ""));
  779. else
  780. TRACE(("reread token %s %s\n", tokname[t], t == TWORD ? wordtext : ""));
  781. #endif
  782. return (t);
  783. }
  784. /*
  785. * Read the next input token.
  786. * If the token is a word, we set backquotelist to the list of cmds in
  787. * backquotes. We set quoteflag to true if any part of the word was
  788. * quoted.
  789. * If the token is TREDIR, then we set redirnode to a structure containing
  790. * the redirection.
  791. * In all cases, the variable startlinno is set to the number of the line
  792. * on which the token starts.
  793. *
  794. * [Change comment: here documents and internal procedures]
  795. * [Readtoken shouldn't have any arguments. Perhaps we should make the
  796. * word parsing code into a separate routine. In this case, readtoken
  797. * doesn't need to have any internal procedures, but parseword does.
  798. * We could also make parseoperator in essence the main routine, and
  799. * have parseword (readtoken1?) handle both words and redirection.]
  800. */
  801. #define RETURN(token) return lasttoken = token
  802. static int
  803. xxreadtoken(void)
  804. {
  805. int c;
  806. if (tokpushback) {
  807. tokpushback = 0;
  808. return lasttoken;
  809. }
  810. if (needprompt) {
  811. setprompt(2);
  812. needprompt = 0;
  813. }
  814. startlinno = plinno;
  815. for (;;) { /* until token or start of word found */
  816. c = pgetc_macro();
  817. switch (c) {
  818. case ' ': case '\t':
  819. continue;
  820. case '#':
  821. while ((c = pgetc()) != '\n' && c != PEOF);
  822. pungetc();
  823. continue;
  824. case '\\':
  825. if (pgetc() == '\n') {
  826. startlinno = ++plinno;
  827. if (doprompt)
  828. setprompt(2);
  829. else
  830. setprompt(0);
  831. continue;
  832. }
  833. pungetc();
  834. goto breakloop;
  835. case '\n':
  836. plinno++;
  837. needprompt = doprompt;
  838. RETURN(TNL);
  839. case PEOF:
  840. RETURN(TEOF);
  841. case '&':
  842. if (pgetc() == '&')
  843. RETURN(TAND);
  844. pungetc();
  845. RETURN(TBACKGND);
  846. case '|':
  847. if (pgetc() == '|')
  848. RETURN(TOR);
  849. pungetc();
  850. RETURN(TPIPE);
  851. case ';':
  852. c = pgetc();
  853. if (c == ';')
  854. RETURN(TENDCASE);
  855. else if (c == '&')
  856. RETURN(TFALLTHRU);
  857. pungetc();
  858. RETURN(TSEMI);
  859. case '(':
  860. RETURN(TLP);
  861. case ')':
  862. RETURN(TRP);
  863. default:
  864. goto breakloop;
  865. }
  866. }
  867. breakloop:
  868. return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
  869. #undef RETURN
  870. }
  871. #define MAXNEST_static 8
  872. struct tokenstate
  873. {
  874. const char *syntax; /* *SYNTAX */
  875. int parenlevel; /* levels of parentheses in arithmetic */
  876. enum tokenstate_category
  877. {
  878. TSTATE_TOP,
  879. TSTATE_VAR_OLD, /* ${var+-=?}, inherits dquotes */
  880. TSTATE_VAR_NEW, /* other ${var...}, own dquote state */
  881. TSTATE_ARITH
  882. } category;
  883. };
  884. /*
  885. * Called to parse command substitutions.
  886. */
  887. static char *
  888. parsebackq(char *out, struct nodelist **pbqlist,
  889. int oldstyle, int dblquote, int quoted)
  890. {
  891. struct nodelist **nlpp;
  892. union node *n;
  893. char *volatile str;
  894. struct jmploc jmploc;
  895. struct jmploc *const savehandler = handler;
  896. int savelen;
  897. int saveprompt;
  898. const int bq_startlinno = plinno;
  899. char *volatile ostr = NULL;
  900. struct parsefile *const savetopfile = getcurrentfile();
  901. struct heredoc *const saveheredoclist = heredoclist;
  902. struct heredoc *here;
  903. str = NULL;
  904. if (setjmp(jmploc.loc)) {
  905. popfilesupto(savetopfile);
  906. if (str)
  907. ckfree(str);
  908. if (ostr)
  909. ckfree(ostr);
  910. heredoclist = saveheredoclist;
  911. handler = savehandler;
  912. if (exception == EXERROR) {
  913. startlinno = bq_startlinno;
  914. synerror("Error in command substitution");
  915. }
  916. longjmp(handler->loc, 1);
  917. }
  918. INTOFF;
  919. savelen = out - stackblock();
  920. if (savelen > 0) {
  921. str = ckmalloc(savelen);
  922. memcpy(str, stackblock(), savelen);
  923. }
  924. handler = &jmploc;
  925. heredoclist = NULL;
  926. INTON;
  927. if (oldstyle) {
  928. /* We must read until the closing backquote, giving special
  929. treatment to some slashes, and then push the string and
  930. reread it as input, interpreting it normally. */
  931. char *oout;
  932. int c;
  933. int olen;
  934. STARTSTACKSTR(oout);
  935. for (;;) {
  936. if (needprompt) {
  937. setprompt(2);
  938. needprompt = 0;
  939. }
  940. CHECKSTRSPACE(2, oout);
  941. switch (c = pgetc()) {
  942. case '`':
  943. goto done;
  944. case '\\':
  945. if ((c = pgetc()) == '\n') {
  946. plinno++;
  947. if (doprompt)
  948. setprompt(2);
  949. else
  950. setprompt(0);
  951. /*
  952. * If eating a newline, avoid putting
  953. * the newline into the new character
  954. * stream (via the USTPUTC after the
  955. * switch).
  956. */
  957. continue;
  958. }
  959. if (c != '\\' && c != '`' && c != '$'
  960. && (!dblquote || c != '"'))
  961. USTPUTC('\\', oout);
  962. break;
  963. case '\n':
  964. plinno++;
  965. needprompt = doprompt;
  966. break;
  967. case PEOF:
  968. startlinno = plinno;
  969. synerror("EOF in backquote substitution");
  970. break;
  971. default:
  972. break;
  973. }
  974. USTPUTC(c, oout);
  975. }
  976. done:
  977. USTPUTC('\0', oout);
  978. olen = oout - stackblock();
  979. INTOFF;
  980. ostr = ckmalloc(olen);
  981. memcpy(ostr, stackblock(), olen);
  982. setinputstring(ostr, 1);
  983. INTON;
  984. }
  985. nlpp = pbqlist;
  986. while (*nlpp)
  987. nlpp = &(*nlpp)->next;
  988. *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist));
  989. (*nlpp)->next = NULL;
  990. if (oldstyle) {
  991. saveprompt = doprompt;
  992. doprompt = 0;
  993. }
  994. n = list(0, oldstyle);
  995. if (oldstyle)
  996. doprompt = saveprompt;
  997. else {
  998. if (readtoken() != TRP)
  999. synexpect(TRP);
  1000. }
  1001. (*nlpp)->n = n;
  1002. if (oldstyle) {
  1003. /*
  1004. * Start reading from old file again, ignoring any pushed back
  1005. * tokens left from the backquote parsing
  1006. */
  1007. popfile();
  1008. tokpushback = 0;
  1009. }
  1010. STARTSTACKSTR(out);
  1011. CHECKSTRSPACE(savelen + 1, out);
  1012. INTOFF;
  1013. if (str) {
  1014. memcpy(out, str, savelen);
  1015. STADJUST(savelen, out);
  1016. ckfree(str);
  1017. str = NULL;
  1018. }
  1019. if (ostr) {
  1020. ckfree(ostr);
  1021. ostr = NULL;
  1022. }
  1023. here = saveheredoclist;
  1024. if (here != NULL) {
  1025. while (here->next != NULL)
  1026. here = here->next;
  1027. here->next = heredoclist;
  1028. heredoclist = saveheredoclist;
  1029. }
  1030. handler = savehandler;
  1031. INTON;
  1032. if (quoted)
  1033. USTPUTC(CTLBACKQ | CTLQUOTE, out);
  1034. else
  1035. USTPUTC(CTLBACKQ, out);
  1036. return out;
  1037. }
  1038. /*
  1039. * Called to parse a backslash escape sequence inside $'...'.
  1040. * The backslash has already been read.
  1041. */
  1042. static char *
  1043. readcstyleesc(char *out)
  1044. {
  1045. int c, v, i, n;
  1046. c = pgetc();
  1047. switch (c) {
  1048. case '\0':
  1049. synerror("Unterminated quoted string");
  1050. case '\n':
  1051. plinno++;
  1052. if (doprompt)
  1053. setprompt(2);
  1054. else
  1055. setprompt(0);
  1056. return out;
  1057. case '\\':
  1058. case '\'':
  1059. case '"':
  1060. v = c;
  1061. break;
  1062. case 'a': v = '\a'; break;
  1063. case 'b': v = '\b'; break;
  1064. case 'e': v = '\033'; break;
  1065. case 'f': v = '\f'; break;
  1066. case 'n': v = '\n'; break;
  1067. case 'r': v = '\r'; break;
  1068. case 't': v = '\t'; break;
  1069. case 'v': v = '\v'; break;
  1070. case 'x':
  1071. v = 0;
  1072. for (;;) {
  1073. c = pgetc();
  1074. if (c >= '0' && c <= '9')
  1075. v = (v << 4) + c - '0';
  1076. else if (c >= 'A' && c <= 'F')
  1077. v = (v << 4) + c - 'A' + 10;
  1078. else if (c >= 'a' && c <= 'f')
  1079. v = (v << 4) + c - 'a' + 10;
  1080. else
  1081. break;
  1082. }
  1083. pungetc();
  1084. break;
  1085. case '0': case '1': case '2': case '3':
  1086. case '4': case '5': case '6': case '7':
  1087. v = c - '0';
  1088. c = pgetc();
  1089. if (c >= '0' && c <= '7') {
  1090. v <<= 3;
  1091. v += c - '0';
  1092. c = pgetc();
  1093. if (c >= '0' && c <= '7') {
  1094. v <<= 3;
  1095. v += c - '0';
  1096. } else
  1097. pungetc();
  1098. } else
  1099. pungetc();
  1100. break;
  1101. case 'c':
  1102. c = pgetc();
  1103. if (c < 0x3f || c > 0x7a || c == 0x60)
  1104. synerror("Bad escape sequence");
  1105. if (c == '\\' && pgetc() != '\\')
  1106. synerror("Bad escape sequence");
  1107. if (c == '?')
  1108. v = 127;
  1109. else
  1110. v = c & 0x1f;
  1111. break;
  1112. case 'u':
  1113. case 'U':
  1114. n = c == 'U' ? 8 : 4;
  1115. v = 0;
  1116. for (i = 0; i < n; i++) {
  1117. c = pgetc();
  1118. if (c >= '0' && c <= '9')
  1119. v = (v << 4) + c - '0';
  1120. else if (c >= 'A' && c <= 'F')
  1121. v = (v << 4) + c - 'A' + 10;
  1122. else if (c >= 'a' && c <= 'f')
  1123. v = (v << 4) + c - 'a' + 10;
  1124. else
  1125. synerror("Bad escape sequence");
  1126. }
  1127. if (v == 0 || (v >= 0xd800 && v <= 0xdfff))
  1128. synerror("Bad escape sequence");
  1129. /* We really need iconv here. */
  1130. if (initial_localeisutf8 && v > 127) {
  1131. CHECKSTRSPACE(4, out);
  1132. /*
  1133. * We cannot use wctomb() as the locale may have
  1134. * changed.
  1135. */
  1136. if (v <= 0x7ff) {
  1137. USTPUTC(0xc0 | v >> 6, out);
  1138. USTPUTC(0x80 | (v & 0x3f), out);
  1139. return out;
  1140. } else if (v <= 0xffff) {
  1141. USTPUTC(0xe0 | v >> 12, out);
  1142. USTPUTC(0x80 | ((v >> 6) & 0x3f), out);
  1143. USTPUTC(0x80 | (v & 0x3f), out);
  1144. return out;
  1145. } else if (v <= 0x10ffff) {
  1146. USTPUTC(0xf0 | v >> 18, out);
  1147. USTPUTC(0x80 | ((v >> 12) & 0x3f), out);
  1148. USTPUTC(0x80 | ((v >> 6) & 0x3f), out);
  1149. USTPUTC(0x80 | (v & 0x3f), out);
  1150. return out;
  1151. }
  1152. }
  1153. if (v > 127)
  1154. v = '?';
  1155. break;
  1156. default:
  1157. synerror("Bad escape sequence");
  1158. }
  1159. v = (char)v;
  1160. /*
  1161. * We can't handle NUL bytes.
  1162. * POSIX says we should skip till the closing quote.
  1163. */
  1164. if (v == '\0') {
  1165. while ((c = pgetc()) != '\'') {
  1166. if (c == '\\')
  1167. c = pgetc();
  1168. if (c == PEOF)
  1169. synerror("Unterminated quoted string");
  1170. }
  1171. pungetc();
  1172. return out;
  1173. }
  1174. if (SQSYNTAX[v] == CCTL)
  1175. USTPUTC(CTLESC, out);
  1176. USTPUTC(v, out);
  1177. return out;
  1178. }
  1179. /*
  1180. * If eofmark is NULL, read a word or a redirection symbol. If eofmark
  1181. * is not NULL, read a here document. In the latter case, eofmark is the
  1182. * word which marks the end of the document and striptabs is true if
  1183. * leading tabs should be stripped from the document. The argument firstc
  1184. * is the first character of the input token or document.
  1185. *
  1186. * Because C does not have internal subroutines, I have simulated them
  1187. * using goto's to implement the subroutine linkage. The following macros
  1188. * will run code that appears at the end of readtoken1.
  1189. */
  1190. #define CHECKEND() {goto checkend; checkend_return:;}
  1191. #define PARSEREDIR() {goto parseredir; parseredir_return:;}
  1192. #define PARSESUB() {goto parsesub; parsesub_return:;}
  1193. #define PARSEARITH() {goto parsearith; parsearith_return:;}
  1194. static int
  1195. readtoken1(int firstc, char const *initialsyntax, char *eofmark, int striptabs)
  1196. {
  1197. int c = firstc;
  1198. char *out;
  1199. int len;
  1200. char line[EOFMARKLEN + 1];
  1201. struct nodelist *bqlist;
  1202. int quotef;
  1203. int newvarnest;
  1204. int level;
  1205. int synentry;
  1206. struct tokenstate state_static[MAXNEST_static];
  1207. int maxnest = MAXNEST_static;
  1208. struct tokenstate *state = state_static;
  1209. int sqiscstyle = 0;
  1210. startlinno = plinno;
  1211. quotef = 0;
  1212. bqlist = NULL;
  1213. newvarnest = 0;
  1214. level = 0;
  1215. state[level].syntax = initialsyntax;
  1216. state[level].parenlevel = 0;
  1217. state[level].category = TSTATE_TOP;
  1218. STARTSTACKSTR(out);
  1219. loop: { /* for each line, until end of word */
  1220. CHECKEND(); /* set c to PEOF if at end of here document */
  1221. for (;;) { /* until end of line or end of word */
  1222. CHECKSTRSPACE(4, out); /* permit 4 calls to USTPUTC */
  1223. synentry = state[level].syntax[c];
  1224. switch(synentry) {
  1225. case CNL: /* '\n' */
  1226. if (state[level].syntax == BASESYNTAX)
  1227. goto endword; /* exit outer loop */
  1228. USTPUTC(c, out);
  1229. plinno++;
  1230. if (doprompt)
  1231. setprompt(2);
  1232. else
  1233. setprompt(0);
  1234. c = pgetc();
  1235. goto loop; /* continue outer loop */
  1236. case CSBACK:
  1237. if (sqiscstyle) {
  1238. out = readcstyleesc(out);
  1239. break;
  1240. }
  1241. /* FALLTHROUGH */
  1242. case CWORD:
  1243. USTPUTC(c, out);
  1244. break;
  1245. case CCTL:
  1246. if (eofmark == NULL || initialsyntax != SQSYNTAX)
  1247. USTPUTC(CTLESC, out);
  1248. USTPUTC(c, out);
  1249. break;
  1250. case CBACK: /* backslash */
  1251. c = pgetc();
  1252. if (c == PEOF) {
  1253. USTPUTC('\\', out);
  1254. pungetc();
  1255. } else if (c == '\n') {
  1256. plinno++;
  1257. if (doprompt)
  1258. setprompt(2);
  1259. else
  1260. setprompt(0);
  1261. } else {
  1262. if (state[level].syntax == DQSYNTAX &&
  1263. c != '\\' && c != '`' && c != '$' &&
  1264. (c != '"' || (eofmark != NULL &&
  1265. newvarnest == 0)) &&
  1266. (c != '}' || state[level].category != TSTATE_VAR_OLD))
  1267. USTPUTC('\\', out);
  1268. if ((eofmark == NULL ||
  1269. newvarnest > 0) &&
  1270. state[level].syntax == BASESYNTAX)
  1271. USTPUTC(CTLQUOTEMARK, out);
  1272. if (SQSYNTAX[c] == CCTL)
  1273. USTPUTC(CTLESC, out);
  1274. USTPUTC(c, out);
  1275. if ((eofmark == NULL ||
  1276. newvarnest > 0) &&
  1277. state[level].syntax == BASESYNTAX &&
  1278. state[level].category == TSTATE_VAR_OLD)
  1279. USTPUTC(CTLQUOTEEND, out);
  1280. quotef++;
  1281. }
  1282. break;
  1283. case CSQUOTE:
  1284. USTPUTC(CTLQUOTEMARK, out);
  1285. state[level].syntax = SQSYNTAX;
  1286. sqiscstyle = 0;
  1287. break;
  1288. case CDQUOTE:
  1289. USTPUTC(CTLQUOTEMARK, out);
  1290. state[level].syntax = DQSYNTAX;
  1291. break;
  1292. case CENDQUOTE:
  1293. if (eofmark != NULL && newvarnest == 0)
  1294. USTPUTC(c, out);
  1295. else {
  1296. if (state[level].category == TSTATE_VAR_OLD)
  1297. USTPUTC(CTLQUOTEEND, out);
  1298. state[level].syntax = BASESYNTAX;
  1299. quotef++;
  1300. }
  1301. break;
  1302. case CVAR: /* '$' */
  1303. PARSESUB(); /* parse substitution */
  1304. break;
  1305. case CENDVAR: /* '}' */
  1306. if (level > 0 &&
  1307. ((state[level].category == TSTATE_VAR_OLD &&
  1308. state[level].syntax ==
  1309. state[level - 1].syntax) ||
  1310. (state[level].category == TSTATE_VAR_NEW &&
  1311. state[level].syntax == BASESYNTAX))) {
  1312. if (state[level].category == TSTATE_VAR_NEW)
  1313. newvarnest--;
  1314. level--;
  1315. USTPUTC(CTLENDVAR, out);
  1316. } else {
  1317. USTPUTC(c, out);
  1318. }
  1319. break;
  1320. case CLP: /* '(' in arithmetic */
  1321. state[level].parenlevel++;
  1322. USTPUTC(c, out);
  1323. break;
  1324. case CRP: /* ')' in arithmetic */
  1325. if (state[level].parenlevel > 0) {
  1326. USTPUTC(c, out);
  1327. --state[level].parenlevel;
  1328. } else {
  1329. if (pgetc() == ')') {
  1330. if (level > 0 &&
  1331. state[level].category == TSTATE_ARITH) {
  1332. level--;
  1333. USTPUTC(CTLENDARI, out);
  1334. } else
  1335. USTPUTC(')', out);
  1336. } else {
  1337. /*
  1338. * unbalanced parens
  1339. * (don't 2nd guess - no error)
  1340. */
  1341. pungetc();
  1342. USTPUTC(')', out);
  1343. }
  1344. }
  1345. break;
  1346. case CBQUOTE: /* '`' */
  1347. out = parsebackq(out, &bqlist, 1,
  1348. state[level].syntax == DQSYNTAX &&
  1349. (eofmark == NULL || newvarnest > 0),
  1350. state[level].syntax == DQSYNTAX || state[level].syntax == ARISYNTAX);
  1351. break;
  1352. case CEOF:
  1353. goto endword; /* exit outer loop */
  1354. case CIGN:
  1355. break;
  1356. default:
  1357. if (level == 0)
  1358. goto endword; /* exit outer loop */
  1359. USTPUTC(c, out);
  1360. }
  1361. c = pgetc_macro();
  1362. }
  1363. }
  1364. endword:
  1365. if (state[level].syntax == ARISYNTAX)
  1366. synerror("Missing '))'");
  1367. if (state[level].syntax != BASESYNTAX && eofmark == NULL)
  1368. synerror("Unterminated quoted string");
  1369. if (state[level].category == TSTATE_VAR_OLD ||
  1370. state[level].category == TSTATE_VAR_NEW) {
  1371. startlinno = plinno;
  1372. synerror("Missing '}'");
  1373. }
  1374. if (state != state_static)
  1375. parser_temp_free_upto(state);
  1376. USTPUTC('\0', out);
  1377. len = out - stackblock();
  1378. out = stackblock();
  1379. if (eofmark == NULL) {
  1380. if ((c == '>' || c == '<')
  1381. && quotef == 0
  1382. && len <= 2
  1383. && (*out == '\0' || is_digit(*out))) {
  1384. PARSEREDIR();
  1385. return lasttoken = TREDIR;
  1386. } else {
  1387. pungetc();
  1388. }
  1389. }
  1390. quoteflag = quotef;
  1391. backquotelist = bqlist;
  1392. grabstackblock(len);
  1393. wordtext = out;
  1394. return lasttoken = TWORD;
  1395. /* end of readtoken routine */
  1396. /*
  1397. * Check to see whether we are at the end of the here document. When this
  1398. * is called, c is set to the first character of the next input line. If
  1399. * we are at the end of the here document, this routine sets the c to PEOF.
  1400. */
  1401. checkend: {
  1402. if (eofmark) {
  1403. if (striptabs) {
  1404. while (c == '\t')
  1405. c = pgetc();
  1406. }
  1407. if (c == *eofmark) {
  1408. if (pfgets(line, sizeof line) != NULL) {
  1409. char *p, *q;
  1410. p = line;
  1411. for (q = eofmark + 1 ; *q && *p == *q ; p++, q++);
  1412. if ((*p == '\0' || *p == '\n') && *q == '\0') {
  1413. c = PEOF;
  1414. if (*p == '\n') {
  1415. plinno++;
  1416. needprompt = doprompt;
  1417. }
  1418. } else {
  1419. pushstring(line, strlen(line), NULL);
  1420. }
  1421. }
  1422. }
  1423. }
  1424. goto checkend_return;
  1425. }
  1426. /*
  1427. * Parse a redirection operator. The variable "out" points to a string
  1428. * specifying the fd to be redirected. The variable "c" contains the
  1429. * first character of the redirection operator.
  1430. */
  1431. parseredir: {
  1432. char fd = *out;
  1433. union node *np;
  1434. np = (union node *)stalloc(sizeof (struct nfile));
  1435. if (c == '>') {
  1436. np->nfile.fd = 1;
  1437. c = pgetc();
  1438. if (c == '>')
  1439. np->type = NAPPEND;
  1440. else if (c == '&')
  1441. np->type = NTOFD;
  1442. else if (c == '|')
  1443. np->type = NCLOBBER;
  1444. else {
  1445. np->type = NTO;
  1446. pungetc();
  1447. }
  1448. } else { /* c == '<' */
  1449. np->nfile.fd = 0;
  1450. c = pgetc();
  1451. if (c == '<') {
  1452. if (sizeof (struct nfile) != sizeof (struct nhere)) {
  1453. np = (union node *)stalloc(sizeof (struct nhere));
  1454. np->nfile.fd = 0;
  1455. }
  1456. np->type = NHERE;
  1457. heredoc = (struct heredoc *)stalloc(sizeof (struct heredoc));
  1458. heredoc->here = np;
  1459. if ((c = pgetc()) == '-') {
  1460. heredoc->striptabs = 1;
  1461. } else {
  1462. heredoc->striptabs = 0;
  1463. pungetc();
  1464. }
  1465. } else if (c == '&')
  1466. np->type = NFROMFD;
  1467. else if (c == '>')
  1468. np->type = NFROMTO;
  1469. else {
  1470. np->type = NFROM;
  1471. pungetc();
  1472. }
  1473. }
  1474. if (fd != '\0')
  1475. np->nfile.fd = digit_val(fd);
  1476. redirnode = np;
  1477. goto parseredir_return;
  1478. }
  1479. /*
  1480. * Parse a substitution. At this point, we have read the dollar sign
  1481. * and nothing else.
  1482. */
  1483. parsesub: {
  1484. char buf[10];
  1485. int subtype;
  1486. int typeloc;
  1487. int flags;
  1488. char *p;
  1489. static const char types[] = "}-+?=";
  1490. int bracketed_name = 0; /* used to handle ${[0-9]*} variables */
  1491. int linno;
  1492. int length;
  1493. int c1;
  1494. c = pgetc();
  1495. if (c == '(') { /* $(command) or $((arith)) */
  1496. if (pgetc() == '(') {
  1497. PARSEARITH();
  1498. } else {
  1499. pungetc();
  1500. out = parsebackq(out, &bqlist, 0,
  1501. state[level].syntax == DQSYNTAX &&
  1502. (eofmark == NULL || newvarnest > 0),
  1503. state[level].syntax == DQSYNTAX ||
  1504. state[level].syntax == ARISYNTAX);
  1505. }
  1506. } else if (c == '{' || is_name(c) || is_special(c)) {
  1507. USTPUTC(CTLVAR, out);
  1508. typeloc = out - stackblock();
  1509. USTPUTC(VSNORMAL, out);
  1510. subtype = VSNORMAL;
  1511. flags = 0;
  1512. if (c == '{') {
  1513. bracketed_name = 1;
  1514. c = pgetc();
  1515. subtype = 0;
  1516. }
  1517. varname:
  1518. if (!is_eof(c) && is_name(c)) {
  1519. length = 0;
  1520. do {
  1521. STPUTC(c, out);
  1522. c = pgetc();
  1523. length++;
  1524. } while (!is_eof(c) && is_in_name(c));
  1525. if (length == 6 &&
  1526. strncmp(out - length, "LINENO", length) == 0) {
  1527. /* Replace the variable name with the
  1528. * current line number. */
  1529. linno = plinno;
  1530. if (funclinno != 0)
  1531. linno -= funclinno - 1;
  1532. snprintf(buf, sizeof(buf), "%d", linno);
  1533. STADJUST(-6, out);
  1534. STPUTS(buf, out);
  1535. flags |= VSLINENO;
  1536. }
  1537. } else if (is_digit(c)) {
  1538. if (bracketed_name) {
  1539. do {
  1540. STPUTC(c, out);
  1541. c = pgetc();
  1542. } while (is_digit(c));
  1543. } else {
  1544. STPUTC(c, out);
  1545. c = pgetc();
  1546. }
  1547. } else if (is_special(c)) {
  1548. c1 = c;
  1549. c = pgetc();
  1550. if (subtype == 0 && c1 == '#') {
  1551. subtype = VSLENGTH;
  1552. if (strchr(types, c) == NULL && c != ':' &&
  1553. c != '#' && c != '%')
  1554. goto varname;
  1555. c1 = c;
  1556. c = pgetc();
  1557. if (c1 != '}' && c == '}') {
  1558. pungetc();
  1559. c = c1;
  1560. goto varname;
  1561. }
  1562. pungetc();
  1563. c = c1;
  1564. c1 = '#';
  1565. subtype = 0;
  1566. }
  1567. USTPUTC(c1, out);
  1568. } else {
  1569. subtype = VSERROR;
  1570. if (c == '}')
  1571. pungetc();
  1572. else if (c == '\n' || c == PEOF)
  1573. synerror("Unexpected end of line in substitution");
  1574. else
  1575. USTPUTC(c, out);
  1576. }
  1577. if (subtype == 0) {
  1578. switch (c) {
  1579. case ':':
  1580. flags |= VSNUL;
  1581. c = pgetc();
  1582. /*FALLTHROUGH*/
  1583. default:
  1584. p = strchr(types, c);
  1585. if (p == NULL) {
  1586. if (c == '\n' || c == PEOF)
  1587. synerror("Unexpected end of line in substitution");
  1588. if (flags == VSNUL)
  1589. STPUTC(':', out);
  1590. STPUTC(c, out);
  1591. subtype = VSERROR;
  1592. } else
  1593. subtype = p - types + VSNORMAL;
  1594. break;
  1595. case '%':
  1596. case '#':
  1597. {
  1598. int cc = c;
  1599. subtype = c == '#' ? VSTRIMLEFT :
  1600. VSTRIMRIGHT;
  1601. c = pgetc();
  1602. if (c == cc)
  1603. subtype++;
  1604. else
  1605. pungetc();
  1606. break;
  1607. }
  1608. }
  1609. } else if (subtype != VSERROR) {
  1610. if (subtype == VSLENGTH && c != '}')
  1611. subtype = VSERROR;
  1612. pungetc();
  1613. }
  1614. STPUTC('=', out);
  1615. if (state[level].syntax == DQSYNTAX ||
  1616. state[level].syntax == ARISYNTAX)
  1617. flags |= VSQUOTE;
  1618. *(stackblock() + typeloc) = subtype | flags;
  1619. if (subtype != VSNORMAL) {
  1620. if (level + 1 >= maxnest) {
  1621. maxnest *= 2;
  1622. if (state == state_static) {
  1623. state = parser_temp_alloc(
  1624. maxnest * sizeof(*state));
  1625. memcpy(state, state_static,
  1626. MAXNEST_static * sizeof(*state));
  1627. } else
  1628. state = parser_temp_realloc(state,
  1629. maxnest * sizeof(*state));
  1630. }
  1631. level++;
  1632. state[level].parenlevel = 0;
  1633. if (subtype == VSMINUS || subtype == VSPLUS ||
  1634. subtype == VSQUESTION || subtype == VSASSIGN) {
  1635. /*
  1636. * For operators that were in the Bourne shell,
  1637. * inherit the double-quote state.
  1638. */
  1639. state[level].syntax = state[level - 1].syntax;
  1640. state[level].category = TSTATE_VAR_OLD;
  1641. } else {
  1642. /*
  1643. * The other operators take a pattern,
  1644. * so go to BASESYNTAX.
  1645. * Also, ' and " are now special, even
  1646. * in here documents.
  1647. */
  1648. state[level].syntax = BASESYNTAX;
  1649. state[level].category = TSTATE_VAR_NEW;
  1650. newvarnest++;
  1651. }
  1652. }
  1653. } else if (c == '\'' && state[level].syntax == BASESYNTAX) {
  1654. /* $'cstylequotes' */
  1655. USTPUTC(CTLQUOTEMARK, out);
  1656. state[level].syntax = SQSYNTAX;
  1657. sqiscstyle = 1;
  1658. } else {
  1659. USTPUTC('$', out);
  1660. pungetc();
  1661. }
  1662. goto parsesub_return;
  1663. }
  1664. /*
  1665. * Parse an arithmetic expansion (indicate start of one and set state)
  1666. */
  1667. parsearith: {
  1668. if (level + 1 >= maxnest) {
  1669. maxnest *= 2;
  1670. if (state == state_static) {
  1671. state = parser_temp_alloc(
  1672. maxnest * sizeof(*state));
  1673. memcpy(state, state_static,
  1674. MAXNEST_static * sizeof(*state));
  1675. } else
  1676. state = parser_temp_realloc(state,
  1677. maxnest * sizeof(*state));
  1678. }
  1679. level++;
  1680. state[level].syntax = ARISYNTAX;
  1681. state[level].parenlevel = 0;
  1682. state[level].category = TSTATE_ARITH;
  1683. USTPUTC(CTLARI, out);
  1684. if (state[level - 1].syntax == DQSYNTAX)
  1685. USTPUTC('"',out);
  1686. else
  1687. USTPUTC(' ',out);
  1688. goto parsearith_return;
  1689. }
  1690. } /* end of readtoken */
  1691. #ifdef mkinit
  1692. RESET {
  1693. tokpushback = 0;
  1694. checkkwd = 0;
  1695. }
  1696. #endif
  1697. /*
  1698. * Returns true if the text contains nothing to expand (no dollar signs
  1699. * or backquotes).
  1700. */
  1701. static int
  1702. noexpand(char *text)
  1703. {
  1704. char *p;
  1705. char c;
  1706. p = text;
  1707. while ((c = *p++) != '\0') {
  1708. if ( c == CTLQUOTEMARK)
  1709. continue;
  1710. if (c == CTLESC)
  1711. p++;
  1712. else if (BASESYNTAX[(int)c] == CCTL)
  1713. return 0;
  1714. }
  1715. return 1;
  1716. }
  1717. /*
  1718. * Return true if the argument is a legal variable name (a letter or
  1719. * underscore followed by zero or more letters, underscores, and digits).
  1720. */
  1721. int
  1722. goodname(const char *name)
  1723. {
  1724. const char *p;
  1725. p = name;
  1726. if (! is_name(*p))
  1727. return 0;
  1728. while (*++p) {
  1729. if (! is_in_name(*p))
  1730. return 0;
  1731. }
  1732. return 1;
  1733. }
  1734. int
  1735. isassignment(const char *p)
  1736. {
  1737. if (!is_name(*p))
  1738. return 0;
  1739. p++;
  1740. for (;;) {
  1741. if (*p == '=')
  1742. return 1;
  1743. else if (!is_in_name(*p))
  1744. return 0;
  1745. p++;
  1746. }
  1747. }
  1748. /*
  1749. * Called when an unexpected token is read during the parse. The argument
  1750. * is the token that is expected, or -1 if more than one type of token can
  1751. * occur at this point.
  1752. */
  1753. static void
  1754. synexpect(int token)
  1755. {
  1756. char msg[64];
  1757. if (token >= 0) {
  1758. fmtstr(msg, 64, "%s unexpected (expecting %s)",
  1759. tokname[lasttoken], tokname[token]);
  1760. } else {
  1761. fmtstr(msg, 64, "%s unexpected", tokname[lasttoken]);
  1762. }
  1763. synerror(msg);
  1764. }
  1765. static void
  1766. synerror(const char *msg)
  1767. {
  1768. if (commandname)
  1769. outfmt(out2, "%s: %d: ", commandname, startlinno);
  1770. outfmt(out2, "Syntax error: %s\n", msg);
  1771. error((char *)NULL);
  1772. }
  1773. static void
  1774. setprompt(int which)
  1775. {
  1776. whichprompt = which;
  1777. #ifndef NO_HISTORY
  1778. if (!el)
  1779. #endif
  1780. {
  1781. out2str(getprompt(NULL));
  1782. flushout(out2);
  1783. }
  1784. }
  1785. /*
  1786. * called by editline -- any expansions to the prompt
  1787. * should be added here.
  1788. */
  1789. char *
  1790. getprompt(void *unused __unused)
  1791. {
  1792. static char ps[PROMPTLEN];
  1793. char *fmt;
  1794. const char *pwd;
  1795. int i, trim;
  1796. static char internal_error[] = "??";
  1797. /*
  1798. * Select prompt format.
  1799. */
  1800. switch (whichprompt) {
  1801. case 0:
  1802. fmt = nullstr;
  1803. break;
  1804. case 1:
  1805. fmt = ps1val();
  1806. break;
  1807. case 2:
  1808. fmt = ps2val();
  1809. break;
  1810. default:
  1811. return internal_error;
  1812. }
  1813. /*
  1814. * Format prompt string.
  1815. */
  1816. for (i = 0; (i < 127) && (*fmt != '\0'); i++, fmt++)
  1817. if (*fmt == '\\')
  1818. switch (*++fmt) {
  1819. /*
  1820. * Hostname.
  1821. *
  1822. * \h specifies just the local hostname,
  1823. * \H specifies fully-qualified hostname.
  1824. */
  1825. case 'h':
  1826. case 'H':
  1827. ps[i] = '\0';
  1828. gethostname(&ps[i], PROMPTLEN - i);
  1829. /* Skip to end of hostname. */
  1830. trim = (*fmt == 'h') ? '.' : '\0';
  1831. while ((ps[i+1] != '\0') && (ps[i+1] != trim))
  1832. i++;
  1833. break;
  1834. /*
  1835. * Working directory.
  1836. *
  1837. * \W specifies just the final component,
  1838. * \w specifies the entire path.
  1839. */
  1840. case 'W':
  1841. case 'w':
  1842. pwd = lookupvar("PWD");
  1843. if (pwd == NULL)
  1844. pwd = "?";
  1845. if (*fmt == 'W' &&
  1846. *pwd == '/' && pwd[1] != '\0')
  1847. strlcpy(&ps[i], strrchr(pwd, '/') + 1,
  1848. PROMPTLEN - i);
  1849. else
  1850. strlcpy(&ps[i], pwd, PROMPTLEN - i);
  1851. /* Skip to end of path. */
  1852. while (ps[i + 1] != '\0')
  1853. i++;
  1854. break;
  1855. /*
  1856. * Superuser status.
  1857. *
  1858. * '$' for normal users, '#' for root.
  1859. */
  1860. case '$':
  1861. ps[i] = (geteuid() != 0) ? '$' : '#';
  1862. break;
  1863. /*
  1864. * A literal \.
  1865. */
  1866. case '\\':
  1867. ps[i] = '\\';
  1868. break;
  1869. /*
  1870. * Emit unrecognized formats verbatim.
  1871. */
  1872. default:
  1873. ps[i++] = '\\';
  1874. ps[i] = *fmt;
  1875. break;
  1876. }
  1877. else
  1878. ps[i] = *fmt;
  1879. ps[i] = '\0';
  1880. return (ps);
  1881. }
  1882. const char *
  1883. expandstr(char *ps)
  1884. {
  1885. union node n;
  1886. struct jmploc jmploc;
  1887. struct jmploc *const savehandler = handler;
  1888. const int saveprompt = doprompt;
  1889. struct parsefile *const savetopfile = getcurrentfile();
  1890. struct parser_temp *const saveparser_temp = parser_temp;
  1891. const char *result = NULL;
  1892. if (!setjmp(jmploc.loc)) {
  1893. handler = &jmploc;
  1894. parser_temp = NULL;
  1895. setinputstring(ps, 1);
  1896. doprompt = 0;
  1897. readtoken1(pgetc(), DQSYNTAX, "\n\n", 0);
  1898. if (backquotelist != NULL)
  1899. error("Command substitution not allowed here");
  1900. n.narg.type = NARG;
  1901. n.narg.next = NULL;
  1902. n.narg.text = wordtext;
  1903. n.narg.backquote = backquotelist;
  1904. expandarg(&n, NULL, 0);
  1905. result = stackblock();
  1906. INTOFF;
  1907. }
  1908. handler = savehandler;
  1909. doprompt = saveprompt;
  1910. popfilesupto(savetopfile);
  1911. if (parser_temp != saveparser_temp) {
  1912. parser_temp_free_all();
  1913. parser_temp = saveparser_temp;
  1914. }
  1915. if (result != NULL) {
  1916. INTON;
  1917. } else if (exception == EXINT)
  1918. raise(SIGINT);
  1919. return result;
  1920. }