summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko2018-04-10 14:20:48 +0200
committerDenys Vlasenko2018-04-10 14:27:08 +0200
commit92a930b4e8dce1b8d884a83d7f38bb139ab8317f (patch)
tree1e55c79906309d2bf2ded71fc0a562f75a4c478d
parente8b1bc0481828d84cea2862eab0ad13a73b0caca (diff)
downloadbusybox-92a930b4e8dce1b8d884a83d7f38bb139ab8317f.zip
busybox-92a930b4e8dce1b8d884a83d7f38bb139ab8317f.tar.gz
hush: simplify \<newline> code, part 3
function old new delta parse_stream 2780 2762 -18 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/hush.c100
1 files changed, 45 insertions, 55 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 3c67186..6cd85cc 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -5052,19 +5052,43 @@ static struct pipe *parse_stream(char **pstring,
}
nommu_addchr(&ctx.as_string, ch);
+ if (ch == '\'') {
+ ctx.word.has_quoted_part = 1;
+ next = i_getch(input);
+ if (next == '\'' && !ctx.pending_redirect)
+ goto insert_empty_quoted_str_marker;
+
+ ch = next;
+ while (1) {
+ if (ch == EOF) {
+ syntax_error_unterm_ch('\'');
+ goto parse_error;
+ }
+ nommu_addchr(&ctx.as_string, ch);
+ if (ch == '\'')
+ break;
+ if (ch == SPECIAL_VAR_SYMBOL) {
+ /* Convert raw ^C to corresponding special variable reference */
+ o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
+ o_addchr(&ctx.word, SPECIAL_VAR_QUOTED_SVS);
+ }
+ o_addqchr(&ctx.word, ch);
+ ch = i_getch(input);
+ }
+ continue; /* get next char */
+ }
+
next = '\0';
- if (ch != '\n') {
- /* Do not break this case:
- * echo '\
- * '
- * and
- * echo z\\
+ if (ch != '\n' && ch != '\\') {
+ /* Not on '\': do not break the case of "echo z\\":
+ * on 2nd '\', i_peek_and_eat_bkslash_nl()
+ * would stop and try to read next line,
+ * not letting the command to execute.
*/
- next = (ch == '\'' || ch == '\\') ? i_peek(input) : i_peek_and_eat_bkslash_nl(input);
-///
+ next = i_peek_and_eat_bkslash_nl(input);
}
- is_special = "{}<>;&|()#'" /* special outside of "str" */
+ is_special = "{}<>;&|()#" /* special outside of "str" */
"\\$\"" IF_HUSH_TICK("`") /* always special */
SPECIAL_VAR_SYMBOL_STR;
/* Are { and } special here? */
@@ -5252,7 +5276,7 @@ static struct pipe *parse_stream(char **pstring,
return ctx.list_head;
}
}
- skip_end_trigger:
+
if (is_blank)
continue;
@@ -5278,7 +5302,7 @@ static struct pipe *parse_stream(char **pstring,
#endif
if (parse_redirect(&ctx, redir_fd, redir_style, input))
goto parse_error;
- continue; /* back to top of while (1) */
+ continue; /* get next char */
case '<':
redir_fd = redirect_opt_num(&ctx.word);
if (done_word(&ctx)) {
@@ -5304,7 +5328,7 @@ static struct pipe *parse_stream(char **pstring,
#endif
if (parse_redirect(&ctx, redir_fd, redir_style, input))
goto parse_error;
- continue; /* back to top of while (1) */
+ continue; /* get next char */
case '#':
if (ctx.word.length == 0 && !ctx.word.has_quoted_part) {
/* skip "#comment" */
@@ -5325,23 +5349,11 @@ static struct pipe *parse_stream(char **pstring,
if (ch == EOF)
break;
}
- continue; /* back to top of while (1) */
- }
- break;
-#if 0 /* looks like we never reach this code */
- case '\\':
- if (next == '\n') {
- /* It's "\<newline>" */
-#if !BB_MMU
- /* Remove trailing '\' from ctx.as_string */
- ctx.as_string.data[--ctx.as_string.length] = '\0';
-#endif
- ch = i_getch(input); /* eat it */
- continue; /* back to top of while (1) */
+ continue; /* get next char */
}
break;
-#endif
}
+ skip_end_trigger:
if (ctx.is_assignment == MAYBE_ASSIGNMENT
/* check that we are not in word in "a=1 2>word b=1": */
@@ -5366,20 +5378,19 @@ static struct pipe *parse_stream(char **pstring,
o_addchr(&ctx.word, ch);
continue; /* get next char */
case '\\':
- if (next == EOF) {
+ /*nommu_addchr(&ctx.as_string, '\\'); - already done */
+ o_addchr(&ctx.word, '\\');
+ ch = i_getch(input);
+ if (ch == EOF) {
//TODO: in ". FILE" containing "cmd\" (no newline) bash ignores last "\"
syntax_error("\\<eof>");
xfunc_die();
}
- ch = i_getch(input);
- /* note: ch != '\n' (that case does not reach this place) */
- o_addchr(&ctx.word, '\\');
- /*nommu_addchr(&ctx.as_string, '\\'); - already done */
- o_addchr(&ctx.word, ch);
- nommu_addchr(&ctx.as_string, ch);
/* Example: echo Hello \2>file
* we need to know that word 2 is quoted */
ctx.word.has_quoted_part = 1;
+ nommu_addchr(&ctx.as_string, ch);
+ o_addchr(&ctx.word, ch);
continue; /* get next char */
case '$':
if (!parse_dollar(&ctx.as_string, &ctx.word, input, /*quote_mask:*/ 0)) {
@@ -5388,33 +5399,12 @@ static struct pipe *parse_stream(char **pstring,
goto parse_error;
}
continue; /* get next char */
- case '\'':
- ctx.word.has_quoted_part = 1;
- if (next == '\'' && !ctx.pending_redirect)
- goto insert_empty_quoted_str_marker;
- while (1) {
- ch = i_getch(input);
- if (ch == EOF) {
- syntax_error_unterm_ch('\'');
- goto parse_error;
- }
- nommu_addchr(&ctx.as_string, ch);
- if (ch == '\'')
- break;
- if (ch == SPECIAL_VAR_SYMBOL) {
- /* Convert raw ^C to corresponding special variable reference */
- o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
- o_addchr(&ctx.word, SPECIAL_VAR_QUOTED_SVS);
- }
- o_addqchr(&ctx.word, ch);
- }
- continue; /* get next char */
case '"':
ctx.word.has_quoted_part = 1;
if (next == '"' && !ctx.pending_redirect) {
+ i_getch(input); /* eat second " */
insert_empty_quoted_str_marker:
nommu_addchr(&ctx.as_string, next);
- i_getch(input); /* eat second ' */
o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
continue; /* get next char */