diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-10 14:20:48 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-10 14:27:08 +0200 |
commit | 92a930b4e8dce1b8d884a83d7f38bb139ab8317f (patch) | |
tree | 1e55c79906309d2bf2ded71fc0a562f75a4c478d /shell/hush.c | |
parent | e8b1bc0481828d84cea2862eab0ad13a73b0caca (diff) | |
download | busybox-w32-92a930b4e8dce1b8d884a83d7f38bb139ab8317f.tar.gz busybox-w32-92a930b4e8dce1b8d884a83d7f38bb139ab8317f.tar.bz2 busybox-w32-92a930b4e8dce1b8d884a83d7f38bb139ab8317f.zip |
hush: simplify \<newline> code, part 3
function old new delta
parse_stream 2780 2762 -18
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to '')
-rw-r--r-- | shell/hush.c | 100 |
1 files changed, 45 insertions, 55 deletions
diff --git a/shell/hush.c b/shell/hush.c index 3c6718648..6cd85cc4d 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -5052,19 +5052,43 @@ static struct pipe *parse_stream(char **pstring, | |||
5052 | } | 5052 | } |
5053 | nommu_addchr(&ctx.as_string, ch); | 5053 | nommu_addchr(&ctx.as_string, ch); |
5054 | 5054 | ||
5055 | if (ch == '\'') { | ||
5056 | ctx.word.has_quoted_part = 1; | ||
5057 | next = i_getch(input); | ||
5058 | if (next == '\'' && !ctx.pending_redirect) | ||
5059 | goto insert_empty_quoted_str_marker; | ||
5060 | |||
5061 | ch = next; | ||
5062 | while (1) { | ||
5063 | if (ch == EOF) { | ||
5064 | syntax_error_unterm_ch('\''); | ||
5065 | goto parse_error; | ||
5066 | } | ||
5067 | nommu_addchr(&ctx.as_string, ch); | ||
5068 | if (ch == '\'') | ||
5069 | break; | ||
5070 | if (ch == SPECIAL_VAR_SYMBOL) { | ||
5071 | /* Convert raw ^C to corresponding special variable reference */ | ||
5072 | o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL); | ||
5073 | o_addchr(&ctx.word, SPECIAL_VAR_QUOTED_SVS); | ||
5074 | } | ||
5075 | o_addqchr(&ctx.word, ch); | ||
5076 | ch = i_getch(input); | ||
5077 | } | ||
5078 | continue; /* get next char */ | ||
5079 | } | ||
5080 | |||
5055 | next = '\0'; | 5081 | next = '\0'; |
5056 | if (ch != '\n') { | 5082 | if (ch != '\n' && ch != '\\') { |
5057 | /* Do not break this case: | 5083 | /* Not on '\': do not break the case of "echo z\\": |
5058 | * echo '\ | 5084 | * on 2nd '\', i_peek_and_eat_bkslash_nl() |
5059 | * ' | 5085 | * would stop and try to read next line, |
5060 | * and | 5086 | * not letting the command to execute. |
5061 | * echo z\\ | ||
5062 | */ | 5087 | */ |
5063 | next = (ch == '\'' || ch == '\\') ? i_peek(input) : i_peek_and_eat_bkslash_nl(input); | 5088 | next = i_peek_and_eat_bkslash_nl(input); |
5064 | /// | ||
5065 | } | 5089 | } |
5066 | 5090 | ||
5067 | is_special = "{}<>;&|()#'" /* special outside of "str" */ | 5091 | is_special = "{}<>;&|()#" /* special outside of "str" */ |
5068 | "\\$\"" IF_HUSH_TICK("`") /* always special */ | 5092 | "\\$\"" IF_HUSH_TICK("`") /* always special */ |
5069 | SPECIAL_VAR_SYMBOL_STR; | 5093 | SPECIAL_VAR_SYMBOL_STR; |
5070 | /* Are { and } special here? */ | 5094 | /* Are { and } special here? */ |
@@ -5252,7 +5276,7 @@ static struct pipe *parse_stream(char **pstring, | |||
5252 | return ctx.list_head; | 5276 | return ctx.list_head; |
5253 | } | 5277 | } |
5254 | } | 5278 | } |
5255 | skip_end_trigger: | 5279 | |
5256 | if (is_blank) | 5280 | if (is_blank) |
5257 | continue; | 5281 | continue; |
5258 | 5282 | ||
@@ -5278,7 +5302,7 @@ static struct pipe *parse_stream(char **pstring, | |||
5278 | #endif | 5302 | #endif |
5279 | if (parse_redirect(&ctx, redir_fd, redir_style, input)) | 5303 | if (parse_redirect(&ctx, redir_fd, redir_style, input)) |
5280 | goto parse_error; | 5304 | goto parse_error; |
5281 | continue; /* back to top of while (1) */ | 5305 | continue; /* get next char */ |
5282 | case '<': | 5306 | case '<': |
5283 | redir_fd = redirect_opt_num(&ctx.word); | 5307 | redir_fd = redirect_opt_num(&ctx.word); |
5284 | if (done_word(&ctx)) { | 5308 | if (done_word(&ctx)) { |
@@ -5304,7 +5328,7 @@ static struct pipe *parse_stream(char **pstring, | |||
5304 | #endif | 5328 | #endif |
5305 | if (parse_redirect(&ctx, redir_fd, redir_style, input)) | 5329 | if (parse_redirect(&ctx, redir_fd, redir_style, input)) |
5306 | goto parse_error; | 5330 | goto parse_error; |
5307 | continue; /* back to top of while (1) */ | 5331 | continue; /* get next char */ |
5308 | case '#': | 5332 | case '#': |
5309 | if (ctx.word.length == 0 && !ctx.word.has_quoted_part) { | 5333 | if (ctx.word.length == 0 && !ctx.word.has_quoted_part) { |
5310 | /* skip "#comment" */ | 5334 | /* skip "#comment" */ |
@@ -5325,23 +5349,11 @@ static struct pipe *parse_stream(char **pstring, | |||
5325 | if (ch == EOF) | 5349 | if (ch == EOF) |
5326 | break; | 5350 | break; |
5327 | } | 5351 | } |
5328 | continue; /* back to top of while (1) */ | 5352 | continue; /* get next char */ |
5329 | } | ||
5330 | break; | ||
5331 | #if 0 /* looks like we never reach this code */ | ||
5332 | case '\\': | ||
5333 | if (next == '\n') { | ||
5334 | /* It's "\<newline>" */ | ||
5335 | #if !BB_MMU | ||
5336 | /* Remove trailing '\' from ctx.as_string */ | ||
5337 | ctx.as_string.data[--ctx.as_string.length] = '\0'; | ||
5338 | #endif | ||
5339 | ch = i_getch(input); /* eat it */ | ||
5340 | continue; /* back to top of while (1) */ | ||
5341 | } | 5353 | } |
5342 | break; | 5354 | break; |
5343 | #endif | ||
5344 | } | 5355 | } |
5356 | skip_end_trigger: | ||
5345 | 5357 | ||
5346 | if (ctx.is_assignment == MAYBE_ASSIGNMENT | 5358 | if (ctx.is_assignment == MAYBE_ASSIGNMENT |
5347 | /* check that we are not in word in "a=1 2>word b=1": */ | 5359 | /* 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, | |||
5366 | o_addchr(&ctx.word, ch); | 5378 | o_addchr(&ctx.word, ch); |
5367 | continue; /* get next char */ | 5379 | continue; /* get next char */ |
5368 | case '\\': | 5380 | case '\\': |
5369 | if (next == EOF) { | 5381 | /*nommu_addchr(&ctx.as_string, '\\'); - already done */ |
5382 | o_addchr(&ctx.word, '\\'); | ||
5383 | ch = i_getch(input); | ||
5384 | if (ch == EOF) { | ||
5370 | //TODO: in ". FILE" containing "cmd\" (no newline) bash ignores last "\" | 5385 | //TODO: in ". FILE" containing "cmd\" (no newline) bash ignores last "\" |
5371 | syntax_error("\\<eof>"); | 5386 | syntax_error("\\<eof>"); |
5372 | xfunc_die(); | 5387 | xfunc_die(); |
5373 | } | 5388 | } |
5374 | ch = i_getch(input); | ||
5375 | /* note: ch != '\n' (that case does not reach this place) */ | ||
5376 | o_addchr(&ctx.word, '\\'); | ||
5377 | /*nommu_addchr(&ctx.as_string, '\\'); - already done */ | ||
5378 | o_addchr(&ctx.word, ch); | ||
5379 | nommu_addchr(&ctx.as_string, ch); | ||
5380 | /* Example: echo Hello \2>file | 5389 | /* Example: echo Hello \2>file |
5381 | * we need to know that word 2 is quoted */ | 5390 | * we need to know that word 2 is quoted */ |
5382 | ctx.word.has_quoted_part = 1; | 5391 | ctx.word.has_quoted_part = 1; |
5392 | nommu_addchr(&ctx.as_string, ch); | ||
5393 | o_addchr(&ctx.word, ch); | ||
5383 | continue; /* get next char */ | 5394 | continue; /* get next char */ |
5384 | case '$': | 5395 | case '$': |
5385 | if (!parse_dollar(&ctx.as_string, &ctx.word, input, /*quote_mask:*/ 0)) { | 5396 | if (!parse_dollar(&ctx.as_string, &ctx.word, input, /*quote_mask:*/ 0)) { |
@@ -5388,33 +5399,12 @@ static struct pipe *parse_stream(char **pstring, | |||
5388 | goto parse_error; | 5399 | goto parse_error; |
5389 | } | 5400 | } |
5390 | continue; /* get next char */ | 5401 | continue; /* get next char */ |
5391 | case '\'': | ||
5392 | ctx.word.has_quoted_part = 1; | ||
5393 | if (next == '\'' && !ctx.pending_redirect) | ||
5394 | goto insert_empty_quoted_str_marker; | ||
5395 | while (1) { | ||
5396 | ch = i_getch(input); | ||
5397 | if (ch == EOF) { | ||
5398 | syntax_error_unterm_ch('\''); | ||
5399 | goto parse_error; | ||
5400 | } | ||
5401 | nommu_addchr(&ctx.as_string, ch); | ||
5402 | if (ch == '\'') | ||
5403 | break; | ||
5404 | if (ch == SPECIAL_VAR_SYMBOL) { | ||
5405 | /* Convert raw ^C to corresponding special variable reference */ | ||
5406 | o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL); | ||
5407 | o_addchr(&ctx.word, SPECIAL_VAR_QUOTED_SVS); | ||
5408 | } | ||
5409 | o_addqchr(&ctx.word, ch); | ||
5410 | } | ||
5411 | continue; /* get next char */ | ||
5412 | case '"': | 5402 | case '"': |
5413 | ctx.word.has_quoted_part = 1; | 5403 | ctx.word.has_quoted_part = 1; |
5414 | if (next == '"' && !ctx.pending_redirect) { | 5404 | if (next == '"' && !ctx.pending_redirect) { |
5405 | i_getch(input); /* eat second " */ | ||
5415 | insert_empty_quoted_str_marker: | 5406 | insert_empty_quoted_str_marker: |
5416 | nommu_addchr(&ctx.as_string, next); | 5407 | nommu_addchr(&ctx.as_string, next); |
5417 | i_getch(input); /* eat second ' */ | ||
5418 | o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL); | 5408 | o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL); |
5419 | o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL); | 5409 | o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL); |
5420 | continue; /* get next char */ | 5410 | continue; /* get next char */ |