| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: parser.c,v 1.114 2016/03/31 16:12:52 christos Exp $ */ | | 1 | /* $NetBSD: parser.c,v 1.115 2016/03/31 23:11:05 christos Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 1991, 1993 | | 4 | * Copyright (c) 1991, 1993 |
5 | * The Regents of the University of California. All rights reserved. | | 5 | * The Regents of the University of California. All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to Berkeley by | | 7 | * This code is derived from software contributed to Berkeley by |
8 | * Kenneth Almquist. | | 8 | * Kenneth Almquist. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -27,27 +27,27 @@ | | | @@ -27,27 +27,27 @@ |
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 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 | | 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 | | 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 | | 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
32 | * SUCH DAMAGE. | | 32 | * SUCH DAMAGE. |
33 | */ | | 33 | */ |
34 | | | 34 | |
35 | #include <sys/cdefs.h> | | 35 | #include <sys/cdefs.h> |
36 | #ifndef lint | | 36 | #ifndef lint |
37 | #if 0 | | 37 | #if 0 |
38 | static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95"; | | 38 | static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95"; |
39 | #else | | 39 | #else |
40 | __RCSID("$NetBSD: parser.c,v 1.114 2016/03/31 16:12:52 christos Exp $"); | | 40 | __RCSID("$NetBSD: parser.c,v 1.115 2016/03/31 23:11:05 christos Exp $"); |
41 | #endif | | 41 | #endif |
42 | #endif /* not lint */ | | 42 | #endif /* not lint */ |
43 | | | 43 | |
44 | #include <stdio.h> | | 44 | #include <stdio.h> |
45 | #include <stdlib.h> | | 45 | #include <stdlib.h> |
46 | #include <limits.h> | | 46 | #include <limits.h> |
47 | | | 47 | |
48 | #include "shell.h" | | 48 | #include "shell.h" |
49 | #include "parser.h" | | 49 | #include "parser.h" |
50 | #include "nodes.h" | | 50 | #include "nodes.h" |
51 | #include "expand.h" /* defines rmescapes() */ | | 51 | #include "expand.h" /* defines rmescapes() */ |
52 | #include "eval.h" /* defines commandname */ | | 52 | #include "eval.h" /* defines commandname */ |
53 | #include "redir.h" /* defines copyfd() */ | | 53 | #include "redir.h" /* defines copyfd() */ |
| @@ -99,27 +99,27 @@ union node *redirnode; | | | @@ -99,27 +99,27 @@ union node *redirnode; |
99 | struct heredoc *heredoc; | | 99 | struct heredoc *heredoc; |
100 | int quoteflag; /* set if (part of) last token was quoted */ | | 100 | int quoteflag; /* set if (part of) last token was quoted */ |
101 | int startlinno; /* line # where last token started */ | | 101 | int startlinno; /* line # where last token started */ |
102 | int funclinno; /* line # where the current function started */ | | 102 | int funclinno; /* line # where the current function started */ |
103 | | | 103 | |
104 | | | 104 | |
105 | STATIC union node *list(int, int); | | 105 | STATIC union node *list(int, int); |
106 | STATIC union node *andor(void); | | 106 | STATIC union node *andor(void); |
107 | STATIC union node *pipeline(void); | | 107 | STATIC union node *pipeline(void); |
108 | STATIC union node *command(void); | | 108 | STATIC union node *command(void); |
109 | STATIC union node *simplecmd(union node **, union node *); | | 109 | STATIC union node *simplecmd(union node **, union node *); |
110 | STATIC union node *makename(void); | | 110 | STATIC union node *makename(void); |
111 | STATIC void parsefname(void); | | 111 | STATIC void parsefname(void); |
112 | STATIC void slurp_heredoc(char *const, int, int); | | 112 | STATIC void slurp_heredoc(char *const, const int, const int); |
113 | STATIC void readheredocs(void); | | 113 | STATIC void readheredocs(void); |
114 | STATIC int peektoken(void); | | 114 | STATIC int peektoken(void); |
115 | STATIC int readtoken(void); | | 115 | STATIC int readtoken(void); |
116 | STATIC int xxreadtoken(void); | | 116 | STATIC int xxreadtoken(void); |
117 | STATIC int readtoken1(int, char const *, int); | | 117 | STATIC int readtoken1(int, char const *, int); |
118 | STATIC int noexpand(char *); | | 118 | STATIC int noexpand(char *); |
119 | STATIC void synexpect(int, const char *) __dead; | | 119 | STATIC void synexpect(int, const char *) __dead; |
120 | STATIC void synerror(const char *) __dead; | | 120 | STATIC void synerror(const char *) __dead; |
121 | STATIC void setprompt(int); | | 121 | STATIC void setprompt(int); |
122 | | | 122 | |
123 | | | 123 | |
124 | static const char EOFhere[] = "EOF reading here (<<) document"; | | 124 | static const char EOFhere[] = "EOF reading here (<<) document"; |
125 | | | 125 | |
| @@ -749,27 +749,27 @@ checkend(int c, char * const eofmark, co | | | @@ -749,27 +749,27 @@ checkend(int c, char * const eofmark, co |
749 | c = PEOF; | | 749 | c = PEOF; |
750 | plinno++; | | 750 | plinno++; |
751 | needprompt = doprompt; | | 751 | needprompt = doprompt; |
752 | } | | 752 | } |
753 | return (c); | | 753 | return (c); |
754 | } | | 754 | } |
755 | | | 755 | |
756 | | | 756 | |
757 | /* | | 757 | /* |
758 | * Input any here documents. | | 758 | * Input any here documents. |
759 | */ | | 759 | */ |
760 | | | 760 | |
761 | STATIC void | | 761 | STATIC void |
762 | slurp_heredoc(char *const eofmark, int striptabs, int sq) | | 762 | slurp_heredoc(char *const eofmark, const int striptabs, const int sq) |
763 | { | | 763 | { |
764 | int c; | | 764 | int c; |
765 | char *out; | | 765 | char *out; |
766 | | | 766 | |
767 | c = pgetc(); | | 767 | c = pgetc(); |
768 | | | 768 | |
769 | /* | | 769 | /* |
770 | * If we hit EOF on the input, and the eofmark is a null string ('') | | 770 | * If we hit EOF on the input, and the eofmark is a null string ('') |
771 | * we consider this empty line to be the eofmark, and exit without err. | | 771 | * we consider this empty line to be the eofmark, and exit without err. |
772 | */ | | 772 | */ |
773 | if (c == PEOF && *eofmark != '\0') | | 773 | if (c == PEOF && *eofmark != '\0') |
774 | synerror(EOFhere); | | 774 | synerror(EOFhere); |
775 | | | 775 | |
| @@ -842,46 +842,39 @@ readheredocs(void) | | | @@ -842,46 +842,39 @@ readheredocs(void) |
842 | setprompt(2); | | 842 | setprompt(2); |
843 | needprompt = 0; | | 843 | needprompt = 0; |
844 | } | | 844 | } |
845 | | | 845 | |
846 | slurp_heredoc(here->eofmark, here->striptabs, | | 846 | slurp_heredoc(here->eofmark, here->striptabs, |
847 | here->here->nhere.type == NHERE); | | 847 | here->here->nhere.type == NHERE); |
848 | | | 848 | |
849 | n = stalloc(sizeof(struct narg)); | | 849 | n = stalloc(sizeof(struct narg)); |
850 | n->narg.type = NARG; | | 850 | n->narg.type = NARG; |
851 | n->narg.next = NULL; | | 851 | n->narg.next = NULL; |
852 | n->narg.text = wordtext; | | 852 | n->narg.text = wordtext; |
853 | n->narg.backquote = backquotelist; | | 853 | n->narg.backquote = backquotelist; |
854 | here->here->nhere.doc = n; | | 854 | here->here->nhere.doc = n; |
855 | } | | | |
856 | } | | | |
857 | | | | |
858 | void | | | |
859 | parse_heredoc(union node *n) | | | |
860 | { | | | |
861 | if (n->narg.type != NARG) | | | |
862 | abort(); | | | |
863 | | | | |
864 | if (n->narg.text[0] == '\0') /* nothing to do */ | | | |
865 | return; | | | |
866 | | | | |
867 | setinputstring(n->narg.text, 1); | | | |
868 | | | | |
869 | readtoken1(pgetc(), DQSYNTAX, 1); | | | |
870 | | | 855 | |
871 | n->narg.text = wordtext; | | 856 | if (here->here->nhere.type == NHERE) |
872 | n->narg.backquote = backquotelist; | | 857 | continue; |
873 | | | 858 | |
874 | popfile(); | | 859 | /* |
| | | 860 | * Now "parse" here docs that have unquoted eofmarkers. |
| | | 861 | */ |
| | | 862 | setinputstring(wordtext, 1); |
| | | 863 | readtoken1(pgetc(), DQSYNTAX, 1); |
| | | 864 | n->narg.text = wordtext; |
| | | 865 | n->narg.backquote = backquotelist; |
| | | 866 | popfile(); |
| | | 867 | } |
875 | } | | 868 | } |
876 | | | 869 | |
877 | STATIC int | | 870 | STATIC int |
878 | peektoken(void) | | 871 | peektoken(void) |
879 | { | | 872 | { |
880 | int t; | | 873 | int t; |
881 | | | 874 | |
882 | t = readtoken(); | | 875 | t = readtoken(); |
883 | tokpushback++; | | 876 | tokpushback++; |
884 | return (t); | | 877 | return (t); |
885 | } | | 878 | } |
886 | | | 879 | |
887 | STATIC int | | 880 | STATIC int |