aboutsummaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-04-10 14:20:48 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2018-04-10 14:27:08 +0200
commit92a930b4e8dce1b8d884a83d7f38bb139ab8317f (patch)
tree1e55c79906309d2bf2ded71fc0a562f75a4c478d /shell/hush.c
parente8b1bc0481828d84cea2862eab0ad13a73b0caca (diff)
downloadbusybox-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.c100
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 */