jobs: Preserve parent jobs for simple commands
[dash.git] / src / parser.c
blob27611f08d7cf8f8dc960e7fe9c0c46852f715fed
1 /*-
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1997-2005
5 * Herbert Xu <herbert@gondor.apana.org.au>. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
8 * Kenneth Almquist.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
35 #if HAVE_ALLOCA_H
36 #include <alloca.h>
37 #endif
39 #include <stdlib.h>
41 #include "shell.h"
42 #include "parser.h"
43 #include "nodes.h"
44 #include "expand.h" /* defines rmescapes() */
45 #include "exec.h" /* defines find_builtin() */
46 #include "syntax.h"
47 #include "options.h"
48 #include "input.h"
49 #include "jobs.h"
50 #include "output.h"
51 #include "var.h"
52 #include "error.h"
53 #include "memalloc.h"
54 #include "mystring.h"
55 #include "alias.h"
56 #include "show.h"
57 #include "builtins.h"
58 #include "system.h"
59 #ifndef SMALL
60 #include "myhistedit.h"
61 #endif
64 * Shell command parser.
67 /* values returned by readtoken */
68 #include "token_vars.h"
72 /* Used by expandstr to get here-doc like behaviour. */
73 #define FAKEEOFMARK (char *)1
77 struct heredoc {
78 struct heredoc *next; /* next here document in list */
79 union node *here; /* redirection node */
80 char *eofmark; /* string indicating end of input */
81 int striptabs; /* if set, strip leading tabs */
84 struct synstack {
85 const char *syntax;
86 struct synstack *prev;
87 struct synstack *next;
88 int innerdq;
89 int varpushed;
90 int dblquote;
91 int varnest; /* levels of variables expansion */
92 int parenlevel; /* levels of parens in arithmetic */
93 int dqvarnest; /* levels of variables expansion within double quotes */
98 struct heredoc *heredoclist; /* list of here documents to read */
99 int doprompt; /* if set, prompt the user */
100 int needprompt; /* true if interactive and at start of line */
101 int lasttoken; /* last token read */
102 int tokpushback; /* last token pushed back */
103 char *wordtext; /* text of last word returned by readtoken */
104 int checkkwd;
105 struct nodelist *backquotelist;
106 union node *redirnode;
107 struct heredoc *heredoc;
108 int quoteflag; /* set if (part of) last token was quoted */
111 STATIC union node *list(int);
112 STATIC union node *andor(void);
113 STATIC union node *pipeline(void);
114 STATIC union node *command(void);
115 STATIC union node *simplecmd(void);
116 STATIC union node *makename(void);
117 STATIC void parsefname(void);
118 STATIC void parseheredoc(void);
119 STATIC int readtoken(void);
120 STATIC int xxreadtoken(void);
121 STATIC int pgetc_eatbnl();
122 STATIC int readtoken1(int, char const *, char *, int);
123 STATIC void synexpect(int) __attribute__((__noreturn__));
124 STATIC void synerror(const char *) __attribute__((__noreturn__));
125 STATIC void setprompt(int);
128 int isassignment(const char *p)
130 const char *q = endofname(p);
131 if (p == q)
132 return 0;
133 return *q == '=';
136 int issimplecmd(union node *n, const char *name)
138 return n && n->type == NCMD && n->ncmd.args &&
139 equal(n->ncmd.args->narg.text, name);
142 static inline int realeofmark(const char *eofmark)
144 return eofmark && eofmark != FAKEEOFMARK;
149 * Read and parse a command. Returns NEOF on end of file. (NULL is a
150 * valid parse tree indicating a blank line.)
153 union node *
154 parsecmd(int interact)
156 tokpushback = 0;
157 checkkwd = 0;
158 heredoclist = 0;
159 doprompt = interact;
160 if (doprompt)
161 setprompt(doprompt);
162 needprompt = 0;
163 return list(1);
167 STATIC union node *
168 list(int nlflag)
170 int chknl = nlflag & 1 ? 0 : CHKNL;
171 union node *n1, *n2, *n3;
172 int tok;
174 n1 = NULL;
175 for (;;) {
176 checkkwd = chknl | CHKKWD | CHKALIAS;
177 tok = readtoken();
178 switch (tok) {
179 case TNL:
180 parseheredoc();
181 return n1;
183 case TEOF:
184 if (!n1 && !chknl)
185 n1 = NEOF;
186 out_eof:
187 parseheredoc();
188 tokpushback++;
189 lasttoken = TEOF;
190 return n1;
193 tokpushback++;
194 if (nlflag == 2 && tokendlist[tok])
195 return n1;
196 nlflag |= 2;
198 n2 = andor();
199 tok = readtoken();
200 if (tok == TBACKGND) {
201 if (n2->type == NPIPE) {
202 n2->npipe.backgnd = 1;
203 } else {
204 if (n2->type != NREDIR) {
205 n3 = stalloc(sizeof(struct nredir));
206 n3->nredir.n = n2;
207 n3->nredir.redirect = NULL;
208 n2 = n3;
210 n2->type = NBACKGND;
213 if (n1 == NULL) {
214 n1 = n2;
216 else {
217 n3 = (union node *)stalloc(sizeof (struct nbinary));
218 n3->type = NSEMI;
219 n3->nbinary.ch1 = n1;
220 n3->nbinary.ch2 = n2;
221 n1 = n3;
223 switch (tok) {
224 case TEOF:
225 goto out_eof;
226 case TNL:
227 tokpushback++;
228 /* fall through */
229 case TBACKGND:
230 case TSEMI:
231 break;
232 default:
233 if (!chknl)
234 synexpect(-1);
235 tokpushback++;
236 return n1;
243 STATIC union node *
244 andor(void)
246 union node *n1, *n2, *n3;
247 int t;
249 n1 = pipeline();
250 for (;;) {
251 if ((t = readtoken()) == TAND) {
252 t = NAND;
253 } else if (t == TOR) {
254 t = NOR;
255 } else {
256 tokpushback++;
257 return n1;
259 checkkwd = CHKNL | CHKKWD | CHKALIAS;
260 n2 = pipeline();
261 n3 = (union node *)stalloc(sizeof (struct nbinary));
262 n3->type = t;
263 n3->nbinary.ch1 = n1;
264 n3->nbinary.ch2 = n2;
265 n1 = n3;
271 STATIC union node *
272 pipeline(void)
274 union node *n1, *n2, *pipenode;
275 struct nodelist *lp, *prev;
276 int negate;
278 negate = 0;
279 TRACE(("pipeline: entered\n"));
280 if (readtoken() == TNOT) {
281 negate = !negate;
282 checkkwd = CHKKWD | CHKALIAS;
283 } else
284 tokpushback++;
285 n1 = command();
286 if (readtoken() == TPIPE) {
287 pipenode = (union node *)stalloc(sizeof (struct npipe));
288 pipenode->type = NPIPE;
289 pipenode->npipe.backgnd = 0;
290 lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
291 pipenode->npipe.cmdlist = lp;
292 lp->n = n1;
293 do {
294 prev = lp;
295 lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
296 checkkwd = CHKNL | CHKKWD | CHKALIAS;
297 lp->n = command();
298 prev->next = lp;
299 } while (readtoken() == TPIPE);
300 lp->next = NULL;
301 n1 = pipenode;
303 tokpushback++;
304 if (negate) {
305 n2 = (union node *)stalloc(sizeof (struct nnot));
306 n2->type = NNOT;
307 n2->nnot.com = n1;
308 return n2;
309 } else
310 return n1;
315 STATIC union node *
316 command(void)
318 union node *n1, *n2;
319 union node *ap, **app;
320 union node *cp, **cpp;
321 union node *redir, **rpp;
322 union node **rpp2;
323 int t;
324 int savelinno;
326 redir = NULL;
327 rpp2 = &redir;
329 savelinno = plinno;
331 switch (readtoken()) {
332 default:
333 synexpect(-1);
334 /* NOTREACHED */
335 case TIF:
336 n1 = (union node *)stalloc(sizeof (struct nif));
337 n1->type = NIF;
338 n1->nif.test = list(0);
339 if (readtoken() != TTHEN)
340 synexpect(TTHEN);
341 n1->nif.ifpart = list(0);
342 n2 = n1;
343 while (readtoken() == TELIF) {
344 n2->nif.elsepart = (union node *)stalloc(sizeof (struct nif));
345 n2 = n2->nif.elsepart;
346 n2->type = NIF;
347 n2->nif.test = list(0);
348 if (readtoken() != TTHEN)
349 synexpect(TTHEN);
350 n2->nif.ifpart = list(0);
352 if (lasttoken == TELSE)
353 n2->nif.elsepart = list(0);
354 else {
355 n2->nif.elsepart = NULL;
356 tokpushback++;
358 t = TFI;
359 break;
360 case TWHILE:
361 case TUNTIL: {
362 int got;
363 n1 = (union node *)stalloc(sizeof (struct nbinary));
364 n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL;
365 n1->nbinary.ch1 = list(0);
366 if ((got=readtoken()) != TDO) {
367 TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
368 synexpect(TDO);
370 n1->nbinary.ch2 = list(0);
371 t = TDONE;
372 break;
374 case TFOR:
375 if (readtoken() != TWORD || quoteflag || ! goodname(wordtext))
376 synerror("Bad for loop variable");
377 n1 = (union node *)stalloc(sizeof (struct nfor));
378 n1->type = NFOR;
379 n1->nfor.linno = savelinno;
380 n1->nfor.var = wordtext;
381 checkkwd = CHKNL | CHKKWD | CHKALIAS;
382 if (readtoken() == TIN) {
383 app = &ap;
384 while (readtoken() == TWORD) {
385 n2 = (union node *)stalloc(sizeof (struct narg));
386 n2->type = NARG;
387 n2->narg.text = wordtext;
388 n2->narg.backquote = backquotelist;
389 *app = n2;
390 app = &n2->narg.next;
392 *app = NULL;
393 n1->nfor.args = ap;
394 if (lasttoken != TNL && lasttoken != TSEMI)
395 synexpect(-1);
396 } else {
397 n2 = (union node *)stalloc(sizeof (struct narg));
398 n2->type = NARG;
399 n2->narg.text = (char *)dolatstr;
400 n2->narg.backquote = NULL;
401 n2->narg.next = NULL;
402 n1->nfor.args = n2;
404 * Newline or semicolon here is optional (but note
405 * that the original Bourne shell only allowed NL).
407 if (lasttoken != TSEMI)
408 tokpushback++;
410 checkkwd = CHKNL | CHKKWD | CHKALIAS;
411 if (readtoken() != TDO)
412 synexpect(TDO);
413 n1->nfor.body = list(0);
414 t = TDONE;
415 break;
416 case TCASE:
417 n1 = (union node *)stalloc(sizeof (struct ncase));
418 n1->type = NCASE;
419 n1->ncase.linno = savelinno;
420 if (readtoken() != TWORD)
421 synexpect(TWORD);
422 n1->ncase.expr = n2 = (union node *)stalloc(sizeof (struct narg));
423 n2->type = NARG;
424 n2->narg.text = wordtext;
425 n2->narg.backquote = backquotelist;
426 n2->narg.next = NULL;
427 checkkwd = CHKNL | CHKKWD | CHKALIAS;
428 if (readtoken() != TIN)
429 synexpect(TIN);
430 cpp = &n1->ncase.cases;
431 next_case:
432 checkkwd = CHKNL | CHKKWD;
433 t = readtoken();
434 while(t != TESAC) {
435 if (lasttoken == TLP)
436 readtoken();
437 *cpp = cp = (union node *)stalloc(sizeof (struct nclist));
438 cp->type = NCLIST;
439 app = &cp->nclist.pattern;
440 for (;;) {
441 *app = ap = (union node *)stalloc(sizeof (struct narg));
442 ap->type = NARG;
443 ap->narg.text = wordtext;
444 ap->narg.backquote = backquotelist;
445 if (readtoken() != TPIPE)
446 break;
447 app = &ap->narg.next;
448 readtoken();
450 ap->narg.next = NULL;
451 if (lasttoken != TRP)
452 synexpect(TRP);
453 cp->nclist.body = list(2);
455 cpp = &cp->nclist.next;
457 checkkwd = CHKNL | CHKKWD;
458 if ((t = readtoken()) != TESAC) {
459 if (t != TENDCASE)
460 synexpect(TENDCASE);
461 else
462 goto next_case;
465 *cpp = NULL;
466 goto redir;
467 case TLP:
468 n1 = (union node *)stalloc(sizeof (struct nredir));
469 n1->type = NSUBSHELL;
470 n1->nredir.linno = savelinno;
471 n1->nredir.n = list(0);
472 n1->nredir.redirect = NULL;
473 t = TRP;
474 break;
475 case TBEGIN:
476 n1 = list(0);
477 t = TEND;
478 break;
479 case TWORD:
480 case TREDIR:
481 tokpushback++;
482 return simplecmd();
485 if (readtoken() != t)
486 synexpect(t);
488 redir:
489 /* Now check for redirection which may follow command */
490 checkkwd = CHKKWD | CHKALIAS;
491 rpp = rpp2;
492 while (readtoken() == TREDIR) {
493 *rpp = n2 = redirnode;
494 rpp = &n2->nfile.next;
495 parsefname();
497 tokpushback++;
498 *rpp = NULL;
499 if (redir) {
500 if (n1->type != NSUBSHELL) {
501 n2 = (union node *)stalloc(sizeof (struct nredir));
502 n2->type = NREDIR;
503 n2->nredir.linno = savelinno;
504 n2->nredir.n = n1;
505 n1 = n2;
507 n1->nredir.redirect = redir;
510 return n1;
514 STATIC union node *
515 simplecmd(void) {
516 union node *args, **app;
517 union node *n = NULL;
518 union node *vars, **vpp;
519 union node **rpp, *redir;
520 int savecheckkwd;
521 int savelinno;
523 args = NULL;
524 app = &args;
525 vars = NULL;
526 vpp = &vars;
527 redir = NULL;
528 rpp = &redir;
530 savecheckkwd = CHKALIAS;
531 savelinno = plinno;
532 for (;;) {
533 checkkwd = savecheckkwd;
534 switch (readtoken()) {
535 case TWORD:
536 n = (union node *)stalloc(sizeof (struct narg));
537 n->type = NARG;
538 n->narg.text = wordtext;
539 n->narg.backquote = backquotelist;
540 if (savecheckkwd && isassignment(wordtext)) {
541 *vpp = n;
542 vpp = &n->narg.next;
543 } else {
544 *app = n;
545 app = &n->narg.next;
546 savecheckkwd = 0;
548 break;
549 case TREDIR:
550 *rpp = n = redirnode;
551 rpp = &n->nfile.next;
552 parsefname(); /* read name of redirection file */
553 break;
554 case TLP:
555 if (
556 args && app == &args->narg.next &&
557 !vars && !redir
559 struct builtincmd *bcmd;
560 const char *name;
562 /* We have a function */
563 if (readtoken() != TRP)
564 synexpect(TRP);
565 name = n->narg.text;
566 if (
567 !goodname(name) || (
568 (bcmd = find_builtin(name)) &&
569 bcmd->flags & BUILTIN_SPECIAL
572 synerror("Bad function name");
573 n->type = NDEFUN;
574 checkkwd = CHKNL | CHKKWD | CHKALIAS;
575 n->ndefun.text = n->narg.text;
576 n->ndefun.linno = plinno;
577 n->ndefun.body = command();
578 return n;
580 /* fall through */
581 default:
582 tokpushback++;
583 goto out;
586 out:
587 *app = NULL;
588 *vpp = NULL;
589 *rpp = NULL;
590 n = (union node *)stalloc(sizeof (struct ncmd));
591 n->type = NCMD;
592 n->ncmd.linno = savelinno;
593 n->ncmd.args = args;
594 n->ncmd.assign = vars;
595 n->ncmd.redirect = redir;
596 return n;
599 STATIC union node *
600 makename(void)
602 union node *n;
604 n = (union node *)stalloc(sizeof (struct narg));
605 n->type = NARG;
606 n->narg.next = NULL;
607 n->narg.text = wordtext;
608 n->narg.backquote = backquotelist;
609 return n;
612 void fixredir(union node *n, const char *text, int err)
614 TRACE(("Fix redir %s %d\n", text, err));
615 if (!err)
616 n->ndup.vname = NULL;
618 if (is_digit(text[0]) && text[1] == '\0')
619 n->ndup.dupfd = digit_val(text[0]);
620 else if (text[0] == '-' && text[1] == '\0')
621 n->ndup.dupfd = -1;
622 else {
624 if (err)
625 sh_error("Bad fd number: %s", text);
626 else
627 n->ndup.vname = makename();
632 STATIC void
633 parsefname(void)
635 union node *n = redirnode;
637 if (n->type == NHERE)
638 checkkwd |= CHKEOFMARK;
639 if (readtoken() != TWORD)
640 synexpect(-1);
641 checkkwd &= ~CHKEOFMARK;
642 if (n->type == NHERE) {
643 struct heredoc *here = heredoc;
644 struct heredoc *p;
646 if (quoteflag == 0)
647 n->type = NXHERE;
648 TRACE(("Here document %d\n", n->type));
649 rmescapes(wordtext);
650 here->eofmark = wordtext;
651 here->next = NULL;
652 if (heredoclist == NULL)
653 heredoclist = here;
654 else {
655 for (p = heredoclist ; p->next ; p = p->next);
656 p->next = here;
658 } else if (n->type == NTOFD || n->type == NFROMFD) {
659 fixredir(n, wordtext, 0);
660 } else {
661 n->nfile.fname = makename();
667 * Input any here documents.
670 STATIC void
671 parseheredoc(void)
673 struct heredoc *here;
674 union node *n;
676 here = heredoclist;
677 heredoclist = 0;
679 while (here) {
680 if (needprompt) {
681 setprompt(2);
683 if (here->here->type == NHERE)
684 readtoken1(pgetc(), SQSYNTAX, here->eofmark, here->striptabs);
685 else
686 readtoken1(pgetc_eatbnl(), DQSYNTAX, here->eofmark, here->striptabs);
687 n = (union node *)stalloc(sizeof (struct narg));
688 n->narg.type = NARG;
689 n->narg.next = NULL;
690 n->narg.text = wordtext;
691 n->narg.backquote = backquotelist;
692 here->here->nhere.doc = n;
693 here = here->next;
697 STATIC int
698 readtoken(void)
700 int t;
701 int kwd = checkkwd;
702 #ifdef DEBUG
703 int alreadyseen = tokpushback;
704 #endif
706 top:
707 t = xxreadtoken();
710 * eat newlines
712 if (kwd & CHKNL) {
713 while (t == TNL) {
714 parseheredoc();
715 checkkwd = 0;
716 t = xxreadtoken();
720 kwd |= checkkwd;
721 checkkwd = 0;
723 if (t != TWORD || quoteflag) {
724 goto out;
728 * check for keywords
730 if (kwd & CHKKWD) {
731 const char *const *pp;
733 if ((pp = findkwd(wordtext))) {
734 lasttoken = t = pp - parsekwd + KWDOFFSET;
735 TRACE(("keyword %s recognized\n", tokname[t]));
736 goto out;
740 if (kwd & CHKALIAS) {
741 struct alias *ap;
742 if ((ap = lookupalias(wordtext, 1)) != NULL) {
743 if (*ap->val) {
744 pushstring(ap->val, ap);
746 goto top;
749 out:
750 #ifdef DEBUG
751 if (!alreadyseen)
752 TRACE(("token %s %s\n", tokname[t], t == TWORD ? wordtext : ""));
753 else
754 TRACE(("reread token %s %s\n", tokname[t], t == TWORD ? wordtext : ""));
755 #endif
756 return (t);
759 static void nlprompt(void)
761 plinno++;
762 if (doprompt)
763 setprompt(2);
766 static void nlnoprompt(void)
768 plinno++;
769 needprompt = doprompt;
774 * Read the next input token.
775 * If the token is a word, we set backquotelist to the list of cmds in
776 * backquotes. We set quoteflag to true if any part of the word was
777 * quoted.
778 * If the token is TREDIR, then we set redirnode to a structure containing
779 * the redirection.
781 * [Change comment: here documents and internal procedures]
782 * [Readtoken shouldn't have any arguments. Perhaps we should make the
783 * word parsing code into a separate routine. In this case, readtoken
784 * doesn't need to have any internal procedures, but parseword does.
785 * We could also make parseoperator in essence the main routine, and
786 * have parseword (readtoken1?) handle both words and redirection.]
789 #define RETURN(token) return lasttoken = token
791 STATIC int
792 xxreadtoken(void)
794 int c;
796 if (tokpushback) {
797 tokpushback = 0;
798 return lasttoken;
800 if (needprompt) {
801 setprompt(2);
803 for (;;) { /* until token or start of word found */
804 c = pgetc_eatbnl();
805 switch (c) {
806 case ' ': case '\t':
807 continue;
808 case '#':
809 while ((c = pgetc()) != '\n' && c != PEOF);
810 pungetc();
811 continue;
812 case '\n':
813 nlnoprompt();
814 RETURN(TNL);
815 case PEOF:
816 RETURN(TEOF);
817 case '&':
818 if (pgetc_eatbnl() == '&')
819 RETURN(TAND);
820 pungetc();
821 RETURN(TBACKGND);
822 case '|':
823 if (pgetc_eatbnl() == '|')
824 RETURN(TOR);
825 pungetc();
826 RETURN(TPIPE);
827 case ';':
828 if (pgetc_eatbnl() == ';')
829 RETURN(TENDCASE);
830 pungetc();
831 RETURN(TSEMI);
832 case '(':
833 RETURN(TLP);
834 case ')':
835 RETURN(TRP);
837 break;
839 return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
840 #undef RETURN
843 static int pgetc_eatbnl(void)
845 int c;
847 while ((c = pgetc()) == '\\') {
848 if (pgetc() != '\n') {
849 pungetc();
850 break;
853 nlprompt();
856 return c;
859 static int pgetc_top(struct synstack *stack)
861 return stack->syntax == SQSYNTAX ? pgetc() : pgetc_eatbnl();
864 static void synstack_push(struct synstack **stack, struct synstack *next,
865 const char *syntax)
867 memset(next, 0, sizeof(*next));
868 next->syntax = syntax;
869 next->next = *stack;
870 (*stack)->prev = next;
871 *stack = next;
874 static void synstack_pop(struct synstack **stack)
876 *stack = (*stack)->next;
882 * If eofmark is NULL, read a word or a redirection symbol. If eofmark
883 * is not NULL, read a here document. In the latter case, eofmark is the
884 * word which marks the end of the document and striptabs is true if
885 * leading tabs should be stripped from the document. The argument firstc
886 * is the first character of the input token or document.
888 * Because C does not have internal subroutines, I have simulated them
889 * using goto's to implement the subroutine linkage. The following macros
890 * will run code that appears at the end of readtoken1.
893 #define CHECKEND() {goto checkend; checkend_return:;}
894 #define PARSEREDIR() {goto parseredir; parseredir_return:;}
895 #define PARSESUB() {goto parsesub; parsesub_return:;}
896 #define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;}
897 #define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;}
898 #define PARSEARITH() {goto parsearith; parsearith_return:;}
900 STATIC int
901 readtoken1(int firstc, char const *syntax, char *eofmark, int striptabs)
903 int c = firstc;
904 char *out;
905 size_t len;
906 struct nodelist *bqlist;
907 int quotef;
908 int oldstyle;
909 /* syntax stack */
910 struct synstack synbase = { .syntax = syntax };
911 struct synstack *synstack = &synbase;
912 int chkeofmark = checkkwd & CHKEOFMARK;
914 if (syntax == DQSYNTAX)
915 synstack->dblquote = 1;
916 quotef = 0;
917 bqlist = NULL;
919 STARTSTACKSTR(out);
920 loop: { /* for each line, until end of word */
921 #if ATTY
922 if (c == '\034' && doprompt
923 && attyset() && ! equal(termval(), "emacs")) {
924 attyline();
925 if (synstack->syntax == BASESYNTAX)
926 return readtoken();
927 c = pgetc_top(synstack);
928 goto loop;
930 #endif
931 CHECKEND(); /* set c to PEOF if at end of here document */
932 for (;;) { /* until end of line or end of word */
933 CHECKSTRSPACE(4, out); /* permit 4 calls to USTPUTC */
934 switch(synstack->syntax[c]) {
935 case CNL: /* '\n' */
936 if (synstack->syntax == BASESYNTAX &&
937 !synstack->varnest)
938 goto endword; /* exit outer loop */
939 USTPUTC(c, out);
940 nlprompt();
941 c = pgetc_top(synstack);
942 goto loop; /* continue outer loop */
943 case CWORD:
944 USTPUTC(c, out);
945 break;
946 case CCTL:
947 if ((!eofmark) | synstack->dblquote |
948 synstack->varnest)
949 USTPUTC(CTLESC, out);
950 USTPUTC(c, out);
951 break;
952 /* backslash */
953 case CBACK:
954 c = pgetc();
955 if (c == PEOF) {
956 USTPUTC(CTLESC, out);
957 USTPUTC('\\', out);
958 pungetc();
959 } else {
960 if (
961 synstack->dblquote &&
962 c != '\\' && c != '`' &&
963 c != '$' && (
964 c != '"' ||
965 (eofmark != NULL &&
966 !synstack->varnest)
967 ) && (
968 c != '}' ||
969 !synstack->varnest
972 USTPUTC(CTLESC, out);
973 USTPUTC('\\', out);
975 USTPUTC(CTLESC, out);
976 USTPUTC(c, out);
977 quotef++;
979 break;
980 case CSQUOTE:
981 synstack->syntax = SQSYNTAX;
982 quotemark:
983 if (eofmark == NULL) {
984 USTPUTC(CTLQUOTEMARK, out);
986 break;
987 case CDQUOTE:
988 synstack->syntax = DQSYNTAX;
989 synstack->dblquote = 1;
990 toggledq:
991 if (synstack->varnest)
992 synstack->innerdq ^= 1;
993 goto quotemark;
994 case CENDQUOTE:
995 if (eofmark && !synstack->varnest) {
996 USTPUTC(c, out);
997 break;
1000 if (synstack->dqvarnest == 0) {
1001 synstack->syntax = BASESYNTAX;
1002 synstack->dblquote = 0;
1005 quotef++;
1007 if (c == '"')
1008 goto toggledq;
1010 goto quotemark;
1011 case CVAR: /* '$' */
1012 PARSESUB(); /* parse substitution */
1013 break;
1014 case CENDVAR: /* '}' */
1015 if (!synstack->innerdq &&
1016 synstack->varnest > 0) {
1017 if (!--synstack->varnest &&
1018 synstack->varpushed)
1019 synstack_pop(&synstack);
1020 else if (synstack->dqvarnest > 0)
1021 synstack->dqvarnest--;
1022 if (!chkeofmark)
1023 c = CTLENDVAR;
1025 USTPUTC(c, out);
1026 break;
1027 case CLP: /* '(' in arithmetic */
1028 synstack->parenlevel++;
1029 USTPUTC(c, out);
1030 break;
1031 case CRP: /* ')' in arithmetic */
1032 if (synstack->parenlevel > 0)
1033 --synstack->parenlevel;
1034 else if (pgetc_eatbnl() == ')') {
1035 synstack_pop(&synstack);
1036 if (chkeofmark)
1037 USTPUTC(c, out);
1038 else
1039 c = CTLENDARI;
1040 } else {
1042 * unbalanced parens
1043 * (don't 2nd guess - no error)
1045 pungetc();
1047 USTPUTC(c, out);
1048 break;
1049 case CBQUOTE: /* '`' */
1050 USTPUTC('`', out);
1051 PARSEBACKQOLD();
1052 break;
1053 case CEOF:
1054 goto endword; /* exit outer loop */
1055 default:
1056 if (synstack->varnest == 0)
1057 goto endword; /* exit outer loop */
1058 USTPUTC(c, out);
1060 c = pgetc_top(synstack);
1063 endword:
1064 if (synstack->syntax == ARISYNTAX)
1065 synerror("Missing '))'");
1066 if (synstack->syntax != BASESYNTAX && eofmark == NULL)
1067 synerror("Unterminated quoted string");
1068 if (synstack->varnest != 0) {
1069 /* { */
1070 synerror("Missing '}'");
1072 USTPUTC('\0', out);
1073 len = out - (char *)stackblock();
1074 out = stackblock();
1075 if (eofmark == NULL) {
1076 if ((c == '>' || c == '<')
1077 && quotef == 0
1078 && len <= 2
1079 && (*out == '\0' || is_digit(*out))) {
1080 PARSEREDIR();
1081 return lasttoken = TREDIR;
1082 } else {
1083 pungetc();
1086 quoteflag = quotef;
1087 backquotelist = bqlist;
1088 grabstackblock(len);
1089 wordtext = out;
1090 return lasttoken = TWORD;
1091 /* end of readtoken routine */
1096 * Check to see whether we are at the end of the here document. When this
1097 * is called, c is set to the first character of the next input line. If
1098 * we are at the end of the here document, this routine sets the c to PEOF.
1101 checkend: {
1102 if (realeofmark(eofmark)) {
1103 int markloc;
1104 char *p;
1106 if (striptabs) {
1107 while (c == '\t')
1108 c = pgetc();
1111 markloc = out - (char *)stackblock();
1112 for (p = eofmark; STPUTC(c, out), *p; p++) {
1113 if (c != *p)
1114 goto more_heredoc;
1116 c = pgetc();
1119 if (c == '\n' || c == PEOF) {
1120 c = PEOF;
1121 nlnoprompt();
1122 } else {
1123 int len;
1125 more_heredoc:
1126 p = (char *)stackblock() + markloc + 1;
1127 len = out - p;
1129 if (len) {
1130 len -= c < 0;
1131 c = p[-1];
1133 if (len) {
1134 char *str;
1136 str = alloca(len + 1);
1137 *(char *)mempcpy(str, p, len) = 0;
1139 pushstring(str, NULL);
1144 STADJUST((char *)stackblock() + markloc - out, out);
1146 goto checkend_return;
1151 * Parse a redirection operator. The variable "out" points to a string
1152 * specifying the fd to be redirected. The variable "c" contains the
1153 * first character of the redirection operator.
1156 parseredir: {
1157 char fd = *out;
1158 union node *np;
1160 np = (union node *)stalloc(sizeof (struct nfile));
1161 if (c == '>') {
1162 np->nfile.fd = 1;
1163 c = pgetc_eatbnl();
1164 if (c == '>')
1165 np->type = NAPPEND;
1166 else if (c == '|')
1167 np->type = NCLOBBER;
1168 else if (c == '&')
1169 np->type = NTOFD;
1170 else {
1171 np->type = NTO;
1172 pungetc();
1174 } else { /* c == '<' */
1175 np->nfile.fd = 0;
1176 switch (c = pgetc_eatbnl()) {
1177 case '<':
1178 if (sizeof (struct nfile) != sizeof (struct nhere)) {
1179 np = (union node *)stalloc(sizeof (struct nhere));
1180 np->nfile.fd = 0;
1182 np->type = NHERE;
1183 heredoc = (struct heredoc *)stalloc(sizeof (struct heredoc));
1184 heredoc->here = np;
1185 if ((c = pgetc_eatbnl()) == '-') {
1186 heredoc->striptabs = 1;
1187 } else {
1188 heredoc->striptabs = 0;
1189 pungetc();
1191 break;
1193 case '&':
1194 np->type = NFROMFD;
1195 break;
1197 case '>':
1198 np->type = NFROMTO;
1199 break;
1201 default:
1202 np->type = NFROM;
1203 pungetc();
1204 break;
1207 if (fd != '\0')
1208 np->nfile.fd = digit_val(fd);
1209 redirnode = np;
1210 goto parseredir_return;
1215 * Parse a substitution. At this point, we have read the dollar sign
1216 * and nothing else.
1219 parsesub: {
1220 int subtype;
1221 int typeloc;
1222 char *p;
1223 static const char types[] = "}-+?=";
1225 c = pgetc_eatbnl();
1226 if (c != '(' && c != '{' && !is_name(c) && !is_special(c)) {
1227 USTPUTC('$', out);
1228 pungetc();
1229 goto parsesub_return;
1232 USTPUTC('$', out);
1234 if (c == '(') { /* $(command) or $((arith)) */
1235 USTPUTC(c, out);
1236 if (pgetc_eatbnl() == '(') {
1237 PARSEARITH();
1238 } else {
1239 pungetc();
1240 PARSEBACKQNEW();
1242 } else {
1243 const char *newsyn = synstack->syntax;
1245 typeloc = out - (char *)stackblock();
1246 if (!chkeofmark) {
1247 out[-1] = CTLVAR;
1248 STADJUST(1, out);
1250 subtype = VSNORMAL;
1251 if (likely(c == '{')) {
1252 if (chkeofmark)
1253 USTPUTC('{', out);
1254 c = pgetc_eatbnl();
1255 subtype = 0;
1257 varname:
1258 if (is_name(c)) {
1259 do {
1260 STPUTC(c, out);
1261 c = pgetc_eatbnl();
1262 } while (is_in_name(c));
1263 } else if (is_digit(c)) {
1264 do {
1265 STPUTC(c, out);
1266 c = pgetc_eatbnl();
1267 } while ((subtype <= 0 || subtype >= VSLENGTH) &&
1268 is_digit(c));
1269 } else if (c != '}') {
1270 int cc = c;
1272 c = pgetc_eatbnl();
1274 if (!subtype && cc == '#') {
1275 subtype = VSLENGTH;
1277 if (c == '_' || isalnum(c)) {
1278 if (chkeofmark)
1279 USTPUTC('#', out);
1280 goto varname;
1283 cc = c;
1284 c = pgetc_eatbnl();
1285 if (cc == '}' || c != '}') {
1286 pungetc();
1287 subtype = 0;
1288 c = cc;
1289 cc = '#';
1290 } else if (chkeofmark)
1291 USTPUTC('#', out);
1294 if (!is_special(cc)) {
1295 if (subtype == VSLENGTH)
1296 subtype = 0;
1297 goto badsub;
1300 USTPUTC(cc, out);
1301 } else
1302 goto badsub;
1304 if (subtype == 0) {
1305 int cc = c;
1307 if (chkeofmark)
1308 STPUTC(c, out);
1310 switch (c) {
1311 case ':':
1312 subtype = VSNUL;
1313 c = pgetc_eatbnl();
1314 if (chkeofmark)
1315 STPUTC(c, out);
1316 /*FALLTHROUGH*/
1317 default:
1318 p = strchr(types, c);
1319 if (p == NULL)
1320 break;
1321 subtype |= p - types + VSNORMAL;
1322 break;
1323 case '%':
1324 case '#':
1325 subtype = c == '#' ? VSTRIMLEFT :
1326 VSTRIMRIGHT;
1327 c = pgetc_eatbnl();
1328 if (c == cc) {
1329 if (chkeofmark)
1330 STPUTC(c, out);
1331 subtype++;
1332 } else
1333 pungetc();
1335 newsyn = BASESYNTAX;
1336 break;
1338 } else {
1339 if (subtype == VSLENGTH && c != '}')
1340 subtype = 0;
1341 badsub:
1342 pungetc();
1345 if (newsyn == ARISYNTAX)
1346 newsyn = DQSYNTAX;
1348 if ((newsyn != synstack->syntax || synstack->innerdq) &&
1349 subtype != VSNORMAL) {
1350 synstack_push(&synstack,
1351 synstack->prev ?:
1352 alloca(sizeof(*synstack)),
1353 newsyn);
1355 synstack->varpushed++;
1356 synstack->dblquote = newsyn != BASESYNTAX;
1359 if (subtype != VSNORMAL) {
1360 synstack->varnest++;
1361 if (synstack->dblquote)
1362 synstack->dqvarnest++;
1364 if (!chkeofmark) {
1365 *((char *)stackblock() + typeloc) = subtype | VSBIT;
1366 STPUTC('=', out);
1369 goto parsesub_return;
1374 * Called to parse command substitutions. Newstyle is set if the command
1375 * is enclosed inside $(...); nlpp is a pointer to the head of the linked
1376 * list of commands (passed by reference), and savelen is the number of
1377 * characters on the top of the stack which must be preserved.
1380 parsebackq: {
1381 int uninitialized_var(saveprompt);
1382 struct heredoc *saveheredoclist;
1383 struct nodelist **nlpp;
1384 size_t psavelen;
1385 size_t savelen;
1386 union node *n;
1387 char *pstr;
1388 char *str;
1390 if (!chkeofmark) {
1391 STADJUST(oldstyle - 1, out);
1392 out[-1] = CTLBACKQ;
1394 str = stackblock();
1395 savelen = out - (char *)stackblock();
1396 grabstackblock(savelen);
1397 if (oldstyle) {
1398 /* We must read until the closing backquote, giving special
1399 treatment to some slashes, and then push the string and
1400 reread it as input, interpreting it normally. */
1401 char *pout;
1402 int pc;
1404 STARTSTACKSTR(pout);
1405 for (;;) {
1406 if (needprompt) {
1407 setprompt(2);
1409 switch (pc = pgetc_eatbnl()) {
1410 case '`':
1411 goto done;
1413 case '\\':
1414 pc = pgetc();
1415 if (pc != '\\' && pc != '`' && pc != '$'
1416 && (!synstack->dblquote || pc != '"'))
1417 STPUTC('\\', pout);
1418 break;
1420 case PEOF:
1421 synerror("EOF in backquote substitution");
1423 case '\n':
1424 nlnoprompt();
1425 break;
1427 default:
1428 break;
1430 STPUTC(pc, pout);
1432 done:
1433 STPUTC('\0', pout);
1434 psavelen = pout - (char *)stackblock();
1435 pstr = grabstackstr(pout);
1436 setinputstring(pstr);
1438 nlpp = &bqlist;
1439 while (*nlpp)
1440 nlpp = &(*nlpp)->next;
1441 *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist));
1442 (*nlpp)->next = NULL;
1444 saveheredoclist = heredoclist;
1445 heredoclist = NULL;
1447 if (oldstyle) {
1448 saveprompt = doprompt;
1449 doprompt = 0;
1452 n = list(2);
1454 if (oldstyle)
1455 doprompt = saveprompt;
1456 else {
1457 if (readtoken() != TRP)
1458 synexpect(TRP);
1459 setinputstring(nullstr);
1462 parseheredoc();
1463 heredoclist = saveheredoclist;
1465 (*nlpp)->n = n;
1466 /* Start reading from old file again. */
1467 popfile();
1469 out = stnputs(str, savelen, stackblock());
1471 if (oldstyle) {
1472 /* Ignore any pushed back tokens left from the backquote
1473 * parsing.
1475 tokpushback = 0;
1476 if (chkeofmark) {
1477 pstr[psavelen - 1] = '`';
1478 out = stnputs(pstr, psavelen, out);
1480 goto parsebackq_oldreturn;
1481 } else {
1482 if (chkeofmark) {
1483 out = commandtextcont(n, out);
1484 USTPUTC(')', out);
1486 goto parsebackq_newreturn;
1491 * Parse an arithmetic expansion (indicate start of one and set state)
1493 parsearith: {
1495 synstack_push(&synstack,
1496 synstack->prev ?: alloca(sizeof(*synstack)),
1497 ARISYNTAX);
1498 synstack->dblquote = 1;
1499 if (chkeofmark)
1500 USTPUTC(c, out);
1501 else {
1502 STADJUST(-1, out);
1503 out[-1] = CTLARI;
1505 goto parsearith_return;
1508 } /* end of readtoken */
1512 #ifdef mkinit
1513 INCLUDE "parser.h"
1514 #endif
1518 * Return of a legal variable name (a letter or underscore followed by zero or
1519 * more letters, underscores, and digits).
1522 char *
1523 endofname(const char *name)
1525 char *p;
1527 p = (char *) name;
1528 if (! is_name(*p))
1529 return p;
1530 while (*++p) {
1531 if (! is_in_name(*p))
1532 break;
1534 return p;
1539 * Called when an unexpected token is read during the parse. The argument
1540 * is the token that is expected, or -1 if more than one type of token can
1541 * occur at this point.
1544 STATIC void
1545 synexpect(int token)
1547 char msg[64];
1549 if (token >= 0) {
1550 fmtstr(msg, 64, "%s unexpected (expecting %s)",
1551 tokname[lasttoken], tokname[token]);
1552 } else {
1553 fmtstr(msg, 64, "%s unexpected", tokname[lasttoken]);
1555 synerror(msg);
1556 /* NOTREACHED */
1560 STATIC void
1561 synerror(const char *msg)
1563 errlinno = plinno;
1564 sh_error("Syntax error: %s", msg);
1565 /* NOTREACHED */
1568 STATIC void
1569 setprompt(int which)
1571 struct stackmark smark;
1572 int show;
1574 needprompt = 0;
1575 whichprompt = which;
1577 #ifdef SMALL
1578 show = 1;
1579 #else
1580 show = !el;
1581 #endif
1582 if (show) {
1583 pushstackmark(&smark, stackblocksize());
1584 out2str(getprompt(NULL));
1585 popstackmark(&smark);
1589 const char *
1590 expandstr(const char *ps)
1592 struct parsefile *file_stop;
1593 struct jmploc *volatile savehandler;
1594 struct heredoc *saveheredoclist;
1595 const char *result;
1596 int saveprompt;
1597 struct jmploc jmploc;
1598 union node n;
1599 int err;
1601 file_stop = parsefile;
1603 /* XXX Fix (char *) cast. */
1604 setinputstring((char *)ps);
1606 saveheredoclist = heredoclist;
1607 heredoclist = NULL;
1608 saveprompt = doprompt;
1609 doprompt = 0;
1610 result = ps;
1611 savehandler = handler;
1612 if (unlikely(err = setjmp(jmploc.loc)))
1613 goto out;
1614 handler = &jmploc;
1616 readtoken1(pgetc_eatbnl(), DQSYNTAX, FAKEEOFMARK, 0);
1618 n.narg.type = NARG;
1619 n.narg.next = NULL;
1620 n.narg.text = wordtext;
1621 n.narg.backquote = backquotelist;
1623 expandarg(&n, NULL, EXP_QUOTED);
1624 result = stackblock();
1626 out:
1627 restore_handler_expandarg(savehandler, err);
1629 doprompt = saveprompt;
1630 unwindfiles(file_stop);
1631 heredoclist = saveheredoclist;
1633 return result;
1637 * called by editline -- any expansions to the prompt
1638 * should be added here.
1640 const char *
1641 getprompt(void *unused)
1643 const char *prompt;
1645 switch (whichprompt) {
1646 default:
1647 #ifdef DEBUG
1648 return "<internal prompt error>";
1649 #endif
1650 case 0:
1651 return nullstr;
1652 case 1:
1653 prompt = ps1val();
1654 break;
1655 case 2:
1656 prompt = ps2val();
1657 break;
1660 return expandstr(prompt);
1663 const char *const *
1664 findkwd(const char *s)
1666 return findstring(
1667 s, parsekwd, sizeof(parsekwd) / sizeof(const char *)