diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2025-08-13 02:29:26 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2025-08-13 02:30:09 +0200 |
| commit | a5cf673c9cf53a3a4bcb127875d4bc544965862e (patch) | |
| tree | 77019891c26020b29058a9d8aaa16161d1070143 /shell | |
| parent | 1847fee2d4ee7ce13edd676d3e69b8e11c3d1e7d (diff) | |
| download | busybox-w32-a5cf673c9cf53a3a4bcb127875d4bc544965862e.tar.gz busybox-w32-a5cf673c9cf53a3a4bcb127875d4bc544965862e.tar.bz2 busybox-w32-a5cf673c9cf53a3a4bcb127875d4bc544965862e.zip | |
hush: create a macro IS_NULL_WORD to test for null shell word
No logic changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/hush.c | 30 |
1 files changed, 14 insertions, 16 deletions
diff --git a/shell/hush.c b/shell/hush.c index 9ec813df2..10ade0b9e 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -558,6 +558,8 @@ typedef struct o_string { | |||
| 558 | smallint has_empty_slot; | 558 | smallint has_empty_slot; |
| 559 | smallint ended_in_ifs; | 559 | smallint ended_in_ifs; |
| 560 | } o_string; | 560 | } o_string; |
| 561 | #define IS_NULL_WORD(str) \ | ||
| 562 | ((str).length == 0 && !(str).has_quoted_part) | ||
| 561 | enum { | 563 | enum { |
| 562 | /* Protect all newly added chars against globbing by prepending \ to *, ?, [, -, \ */ | 564 | /* Protect all newly added chars against globbing by prepending \ to *, ?, [, -, \ */ |
| 563 | EXP_FLAG_GLOBPROTECT_CHARS = 0x1, | 565 | EXP_FLAG_GLOBPROTECT_CHARS = 0x1, |
| @@ -4271,7 +4273,7 @@ static int done_word(struct parse_context *ctx) | |||
| 4271 | struct command *command = ctx->command; | 4273 | struct command *command = ctx->command; |
| 4272 | 4274 | ||
| 4273 | debug_printf_parse("done_word entered: '%s' %p\n", ctx->word.data, command); | 4275 | debug_printf_parse("done_word entered: '%s' %p\n", ctx->word.data, command); |
| 4274 | if (ctx->word.length == 0 && !ctx->word.has_quoted_part) { | 4276 | if (IS_NULL_WORD(ctx->word)) { |
| 4275 | debug_printf_parse("done_word return 0: no word, ignored\n"); | 4277 | debug_printf_parse("done_word return 0: no word, ignored\n"); |
| 4276 | return 0; | 4278 | return 0; |
| 4277 | } | 4279 | } |
| @@ -4843,11 +4845,11 @@ static int parse_group(struct parse_context *ctx, | |||
| 4843 | 4845 | ||
| 4844 | #if 0 /* Prevented by caller */ | 4846 | #if 0 /* Prevented by caller */ |
| 4845 | if (command->argv /* word [word]{... */ | 4847 | if (command->argv /* word [word]{... */ |
| 4846 | || ctx->word.length /* word{... */ | 4848 | || !IS_NULL_WORD(ctx->word) /* word{... or ""{... */ |
| 4847 | || ctx->word.has_quoted_part /* ""{... */ | 4849 | ) { |
| 4848 | ) | ||
| 4849 | debug_printf_parse("parse_group return -1: " | 4850 | debug_printf_parse("parse_group return -1: " |
| 4850 | "syntax error, groups and arglists don't mix\n"); | 4851 | "syntax error, groups and arglists don't mix\n"); |
| 4852 | } | ||
| 4851 | #endif | 4853 | #endif |
| 4852 | 4854 | ||
| 4853 | IF_HUSH_FUNCTIONS(skip:) | 4855 | IF_HUSH_FUNCTIONS(skip:) |
| @@ -5700,8 +5702,7 @@ static struct pipe *parse_stream(char **pstring, | |||
| 5700 | #endif | 5702 | #endif |
| 5701 | /* Are { and } special here? */ | 5703 | /* Are { and } special here? */ |
| 5702 | if (ctx.command->argv /* word [word]{... - non-special */ | 5704 | if (ctx.command->argv /* word [word]{... - non-special */ |
| 5703 | || ctx.word.length /* word{... - non-special */ | 5705 | || !IS_NULL_WORD(ctx.word) /* word{... ""{... - non-special */ |
| 5704 | || ctx.word.has_quoted_part /* ""{... - non-special */ | ||
| 5705 | || (next != ';' /* }; - special */ | 5706 | || (next != ';' /* }; - special */ |
| 5706 | && next != ')' /* }) - special */ | 5707 | && next != ')' /* }) - special */ |
| 5707 | && next != '(' /* {( - special */ | 5708 | && next != '(' /* {( - special */ |
| @@ -5756,8 +5757,7 @@ static struct pipe *parse_stream(char **pstring, | |||
| 5756 | * "case ... in <newline> word) ..." | 5757 | * "case ... in <newline> word) ..." |
| 5757 | */ | 5758 | */ |
| 5758 | if (IS_NULL_CMD(ctx.command) | 5759 | if (IS_NULL_CMD(ctx.command) |
| 5759 | && ctx.word.length == 0 | 5760 | && IS_NULL_WORD(ctx.word) |
| 5760 | && !ctx.word.has_quoted_part | ||
| 5761 | && heredoc_cnt == 0 | 5761 | && heredoc_cnt == 0 |
| 5762 | ) { | 5762 | ) { |
| 5763 | /* This newline can be ignored. But... | 5763 | /* This newline can be ignored. But... |
| @@ -5805,9 +5805,8 @@ static struct pipe *parse_stream(char **pstring, | |||
| 5805 | * Pathological example: { ""}; } should run "}" command. | 5805 | * Pathological example: { ""}; } should run "}" command. |
| 5806 | */ | 5806 | */ |
| 5807 | if (ch == '}') { | 5807 | if (ch == '}') { |
| 5808 | if (ctx.word.length != 0 /* word} */ | 5808 | if (!IS_NULL_WORD(ctx.word)) { |
| 5809 | || ctx.word.has_quoted_part /* ""} */ | 5809 | /* word} or ""} */ |
| 5810 | ) { | ||
| 5811 | goto ordinary_char; | 5810 | goto ordinary_char; |
| 5812 | } | 5811 | } |
| 5813 | if (!IS_NULL_CMD(ctx.command)) { /* cmd } */ | 5812 | if (!IS_NULL_CMD(ctx.command)) { /* cmd } */ |
| @@ -5928,7 +5927,7 @@ static struct pipe *parse_stream(char **pstring, | |||
| 5928 | goto parse_error_exitcode1; | 5927 | goto parse_error_exitcode1; |
| 5929 | continue; /* get next char */ | 5928 | continue; /* get next char */ |
| 5930 | case '#': | 5929 | case '#': |
| 5931 | if (ctx.word.length == 0 && !ctx.word.has_quoted_part) { | 5930 | if (IS_NULL_WORD(ctx.word)) { |
| 5932 | /* skip "#comment" */ | 5931 | /* skip "#comment" */ |
| 5933 | /* note: we do not add it to &ctx.as_string */ | 5932 | /* note: we do not add it to &ctx.as_string */ |
| 5934 | /* TODO: in bash: | 5933 | /* TODO: in bash: |
| @@ -6086,8 +6085,8 @@ static struct pipe *parse_stream(char **pstring, | |||
| 6086 | } | 6085 | } |
| 6087 | } else { | 6086 | } else { |
| 6088 | if (IS_NULL_CMD(ctx.command)) { | 6087 | if (IS_NULL_CMD(ctx.command)) { |
| 6089 | /* Example: "| cat" */ | 6088 | /* Testcase: sh -c '| cat' */ |
| 6090 | /* Example: "date | | cat" */ | 6089 | /* Testcase: sh -c 'date | | cat' */ |
| 6091 | syntax_error_unexpected_ch('|'); | 6090 | syntax_error_unexpected_ch('|'); |
| 6092 | goto parse_error_exitcode1; | 6091 | goto parse_error_exitcode1; |
| 6093 | } | 6092 | } |
| @@ -6099,8 +6098,7 @@ static struct pipe *parse_stream(char **pstring, | |||
| 6099 | /* "case... in [(]word)..." - skip '(' */ | 6098 | /* "case... in [(]word)..." - skip '(' */ |
| 6100 | if (ctx.ctx_res_w == RES_MATCH | 6099 | if (ctx.ctx_res_w == RES_MATCH |
| 6101 | && ctx.command->argv == NULL /* not (word|(... */ | 6100 | && ctx.command->argv == NULL /* not (word|(... */ |
| 6102 | && ctx.word.length == 0 /* not word(... */ | 6101 | && IS_NULL_WORD(ctx.word) /* not word(... or ""(... */ |
| 6103 | && ctx.word.has_quoted_part == 0 /* not ""(... */ | ||
| 6104 | ) { | 6102 | ) { |
| 6105 | continue; /* get next char */ | 6103 | continue; /* get next char */ |
| 6106 | } | 6104 | } |
