diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-08 09:29:14 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-08 09:29:14 +0000 |
commit | 3dfb035d8df33e59492e78a97bf42e961ba178e4 (patch) | |
tree | 78ce918f14531d99a0b95a205a7984823ed4ad6b | |
parent | df6f95cedf4fe621048647f869db45daa7e5975a (diff) | |
download | busybox-w32-3dfb035d8df33e59492e78a97bf42e961ba178e4.tar.gz busybox-w32-3dfb035d8df33e59492e78a97bf42e961ba178e4.tar.bz2 busybox-w32-3dfb035d8df33e59492e78a97bf42e961ba178e4.zip |
hush: echo \2>file fix
-rw-r--r-- | shell/hush.c | 29 | ||||
-rw-r--r-- | shell/hush_test/hush-misc/heredoc2.right | 1 | ||||
-rwxr-xr-x | shell/hush_test/hush-misc/heredoc2.tests | 1 | ||||
-rw-r--r-- | shell/hush_test/hush-misc/heredoc3.right | 1 | ||||
-rwxr-xr-x | shell/hush_test/hush-misc/heredoc3.tests | 1 | ||||
-rw-r--r-- | shell/hush_test/hush-misc/redir2.right | 1 | ||||
-rwxr-xr-x | shell/hush_test/hush-misc/redir2.tests | 2 |
7 files changed, 28 insertions, 8 deletions
diff --git a/shell/hush.c b/shell/hush.c index d5c90a262..5594aaea4 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -4081,7 +4081,7 @@ static int parse_redirect(struct parse_context *ctx, | |||
4081 | * the redirection expression. For example: | 4081 | * the redirection expression. For example: |
4082 | * echo \2>a | 4082 | * echo \2>a |
4083 | * writes the character 2 into file a" | 4083 | * writes the character 2 into file a" |
4084 | * I am not sure we do it right (and not sure we care) | 4084 | * We are getting it right by setting ->o_quoted on any \<char> |
4085 | * | 4085 | * |
4086 | * A -1 return means no valid number was found, | 4086 | * A -1 return means no valid number was found, |
4087 | * the caller should use the appropriate default for this redirection. | 4087 | * the caller should use the appropriate default for this redirection. |
@@ -4141,6 +4141,9 @@ static char *fetch_till_str(o_string *as_string, | |||
4141 | } | 4141 | } |
4142 | } | 4142 | } |
4143 | 4143 | ||
4144 | /* Look at entire parse tree for not-yet-loaded REDIRECT_HEREDOCs | ||
4145 | * and load them all. There should be exactly heredoc_cnt of them. | ||
4146 | */ | ||
4144 | static int fetch_heredocs(int heredoc_cnt, struct parse_context *ctx, struct in_str *input) | 4147 | static int fetch_heredocs(int heredoc_cnt, struct parse_context *ctx, struct in_str *input) |
4145 | { | 4148 | { |
4146 | struct pipe *pi = ctx->list_head; | 4149 | struct pipe *pi = ctx->list_head; |
@@ -4161,14 +4164,18 @@ static int fetch_heredocs(int heredoc_cnt, struct parse_context *ctx, struct in_ | |||
4161 | if (redir->rd_type == REDIRECT_HEREDOC) { | 4164 | if (redir->rd_type == REDIRECT_HEREDOC) { |
4162 | char *p; | 4165 | char *p; |
4163 | 4166 | ||
4164 | if (heredoc_cnt <= 0) | 4167 | if (heredoc_cnt <= 0) { |
4168 | syntax("heredoc BUG 1"); | ||
4165 | return 1; /* error */ | 4169 | return 1; /* error */ |
4170 | } | ||
4166 | redir->rd_type = REDIRECT_HEREDOC2; | 4171 | redir->rd_type = REDIRECT_HEREDOC2; |
4167 | /* redir->dup is (ab)used to indicate <<- */ | 4172 | /* redir->dup is (ab)used to indicate <<- */ |
4168 | p = fetch_till_str(&ctx->as_string, input, | 4173 | p = fetch_till_str(&ctx->as_string, input, |
4169 | redir->rd_filename, redir->rd_dup & HEREDOC_SKIPTABS); | 4174 | redir->rd_filename, redir->rd_dup & HEREDOC_SKIPTABS); |
4170 | if (!p) | 4175 | if (!p) { |
4171 | return 1; /* unexpected EOF */ | 4176 | syntax("unexpected EOF in here document"); |
4177 | return 1; | ||
4178 | } | ||
4172 | free(redir->rd_filename); | 4179 | free(redir->rd_filename); |
4173 | redir->rd_filename = p; | 4180 | redir->rd_filename = p; |
4174 | heredoc_cnt--; | 4181 | heredoc_cnt--; |
@@ -4180,6 +4187,8 @@ static int fetch_heredocs(int heredoc_cnt, struct parse_context *ctx, struct in_ | |||
4180 | pi = pi->next; | 4187 | pi = pi->next; |
4181 | } | 4188 | } |
4182 | /* Should be 0. If it isn't, it's a parse error */ | 4189 | /* Should be 0. If it isn't, it's a parse error */ |
4190 | if (heredoc_cnt) | ||
4191 | syntax("heredoc BUG 2"); | ||
4183 | return heredoc_cnt; | 4192 | return heredoc_cnt; |
4184 | } | 4193 | } |
4185 | 4194 | ||
@@ -4673,12 +4682,12 @@ static int parse_stream_dquoted(o_string *as_string, | |||
4673 | if (ch != EOF) | 4682 | if (ch != EOF) |
4674 | nommu_addchr(as_string, ch); | 4683 | nommu_addchr(as_string, ch); |
4675 | if (ch == dquote_end) { /* may be only '"' or EOF */ | 4684 | if (ch == dquote_end) { /* may be only '"' or EOF */ |
4676 | dest->o_quoted = 1; | ||
4677 | if (dest->o_assignment == NOT_ASSIGNMENT) | 4685 | if (dest->o_assignment == NOT_ASSIGNMENT) |
4678 | dest->o_escape ^= 1; | 4686 | dest->o_escape ^= 1; |
4679 | debug_printf_parse("parse_stream_dquoted return 0\n"); | 4687 | debug_printf_parse("parse_stream_dquoted return 0\n"); |
4680 | return 0; | 4688 | return 0; |
4681 | } | 4689 | } |
4690 | /* note: can't move it above ch == dquote_end check! */ | ||
4682 | if (ch == EOF) { | 4691 | if (ch == EOF) { |
4683 | syntax("unterminated \""); | 4692 | syntax("unterminated \""); |
4684 | debug_printf_parse("parse_stream_dquoted return 1: unterminated \"\n"); | 4693 | debug_printf_parse("parse_stream_dquoted return 1: unterminated \"\n"); |
@@ -4787,6 +4796,7 @@ static struct pipe *parse_stream(char **pstring, | |||
4787 | redir_type redir_style; | 4796 | redir_type redir_style; |
4788 | 4797 | ||
4789 | if (is_in_dquote) { | 4798 | if (is_in_dquote) { |
4799 | /* dest.o_quoted = 1; - already is (see below) */ | ||
4790 | if (parse_stream_dquoted(&ctx.as_string, &dest, input, '"')) { | 4800 | if (parse_stream_dquoted(&ctx.as_string, &dest, input, '"')) { |
4791 | goto parse_error; | 4801 | goto parse_error; |
4792 | } | 4802 | } |
@@ -4863,8 +4873,9 @@ static struct pipe *parse_stream(char **pstring, | |||
4863 | done_pipe(&ctx, PIPE_SEQ); | 4873 | done_pipe(&ctx, PIPE_SEQ); |
4864 | debug_printf_parse("heredoc_cnt:%d\n", heredoc_cnt); | 4874 | debug_printf_parse("heredoc_cnt:%d\n", heredoc_cnt); |
4865 | if (heredoc_cnt) { | 4875 | if (heredoc_cnt) { |
4866 | if (fetch_heredocs(heredoc_cnt, &ctx, input)) | 4876 | if (fetch_heredocs(heredoc_cnt, &ctx, input)) { |
4867 | goto parse_error; | 4877 | goto parse_error; |
4878 | } | ||
4868 | heredoc_cnt = 0; | 4879 | heredoc_cnt = 0; |
4869 | } | 4880 | } |
4870 | dest.o_assignment = MAYBE_ASSIGNMENT; | 4881 | dest.o_assignment = MAYBE_ASSIGNMENT; |
@@ -4938,7 +4949,6 @@ static struct pipe *parse_stream(char **pstring, | |||
4938 | i_getch(input); | 4949 | i_getch(input); |
4939 | /* note: we do not add it to &ctx.as_string */ | 4950 | /* note: we do not add it to &ctx.as_string */ |
4940 | } | 4951 | } |
4941 | //TODO: go back one char? | ||
4942 | nommu_addchr(&ctx.as_string, '\n'); | 4952 | nommu_addchr(&ctx.as_string, '\n'); |
4943 | } else { | 4953 | } else { |
4944 | o_addQchr(&dest, ch); | 4954 | o_addQchr(&dest, ch); |
@@ -4951,8 +4961,11 @@ static struct pipe *parse_stream(char **pstring, | |||
4951 | } | 4961 | } |
4952 | o_addchr(&dest, '\\'); | 4962 | o_addchr(&dest, '\\'); |
4953 | ch = i_getch(input); | 4963 | ch = i_getch(input); |
4954 | o_addchr(&dest, ch); | ||
4955 | nommu_addchr(&ctx.as_string, ch); | 4964 | nommu_addchr(&ctx.as_string, ch); |
4965 | o_addchr(&dest, ch); | ||
4966 | /* Example: echo Hello \2>file | ||
4967 | * we need to know that word 2 is quoted */ | ||
4968 | dest.o_quoted = 1; | ||
4956 | break; | 4969 | break; |
4957 | case '$': | 4970 | case '$': |
4958 | if (handle_dollar(&ctx.as_string, &dest, input) != 0) { | 4971 | if (handle_dollar(&ctx.as_string, &dest, input) != 0) { |
diff --git a/shell/hush_test/hush-misc/heredoc2.right b/shell/hush_test/hush-misc/heredoc2.right index 66545ae76..74110e3b5 100644 --- a/shell/hush_test/hush-misc/heredoc2.right +++ b/shell/hush_test/hush-misc/heredoc2.right | |||
@@ -6,3 +6,4 @@ moo | |||
6 | EOF-f | 6 | EOF-f |
7 | EOF-f f | 7 | EOF-f f |
8 | EOF-f | 8 | EOF-f |
9 | Ok | ||
diff --git a/shell/hush_test/hush-misc/heredoc2.tests b/shell/hush_test/hush-misc/heredoc2.tests index 19d9c9681..e619bded1 100755 --- a/shell/hush_test/hush-misc/heredoc2.tests +++ b/shell/hush_test/hush-misc/heredoc2.tests | |||
@@ -9,3 +9,4 @@ echo `echo Hello World` | |||
9 | EOF-f f | 9 | EOF-f f |
10 | EOF-f | 10 | EOF-f |
11 | EOF-f | 11 | EOF-f |
12 | echo Ok | ||
diff --git a/shell/hush_test/hush-misc/heredoc3.right b/shell/hush_test/hush-misc/heredoc3.right index 9b114fabf..6ed517f74 100644 --- a/shell/hush_test/hush-misc/heredoc3.right +++ b/shell/hush_test/hush-misc/heredoc3.right | |||
@@ -6,3 +6,4 @@ moo | |||
6 | EOF-f | 6 | EOF-f |
7 | EOF-f f | 7 | EOF-f f |
8 | EOF-f | 8 | EOF-f |
9 | Ok | ||
diff --git a/shell/hush_test/hush-misc/heredoc3.tests b/shell/hush_test/hush-misc/heredoc3.tests index 6391e49f9..938577a89 100755 --- a/shell/hush_test/hush-misc/heredoc3.tests +++ b/shell/hush_test/hush-misc/heredoc3.tests | |||
@@ -9,3 +9,4 @@ echo `echo Hello World` | |||
9 | EOF-f f | 9 | EOF-f f |
10 | EOF-f | 10 | EOF-f |
11 | EOF-f | 11 | EOF-f |
12 | echo Ok | ||
diff --git a/shell/hush_test/hush-misc/redir2.right b/shell/hush_test/hush-misc/redir2.right new file mode 100644 index 000000000..7326d9603 --- /dev/null +++ b/shell/hush_test/hush-misc/redir2.right | |||
@@ -0,0 +1 @@ | |||
Ok | |||
diff --git a/shell/hush_test/hush-misc/redir2.tests b/shell/hush_test/hush-misc/redir2.tests new file mode 100755 index 000000000..81983cae2 --- /dev/null +++ b/shell/hush_test/hush-misc/redir2.tests | |||
@@ -0,0 +1,2 @@ | |||
1 | echo NOT SHOWN \2>/dev/null | ||
2 | echo Ok | ||