aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2025-08-13 02:29:26 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2025-08-13 02:30:09 +0200
commita5cf673c9cf53a3a4bcb127875d4bc544965862e (patch)
tree77019891c26020b29058a9d8aaa16161d1070143 /shell
parent1847fee2d4ee7ce13edd676d3e69b8e11c3d1e7d (diff)
downloadbusybox-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.c30
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)
561enum { 563enum {
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 }