diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2025-08-17 17:59:30 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2025-08-17 17:59:30 +0200 |
| commit | 2ccb8918190f95fe6119bee46ae4b595a2e8306d (patch) | |
| tree | 977da2f40b7c5e615a3e5b3e6cc49a353097ece8 /shell | |
| parent | 84d4ac375408f44d282aa49a21a2451eb41638e2 (diff) | |
| download | busybox-w32-2ccb8918190f95fe6119bee46ae4b595a2e8306d.tar.gz busybox-w32-2ccb8918190f95fe6119bee46ae4b595a2e8306d.tar.bz2 busybox-w32-2ccb8918190f95fe6119bee46ae4b595a2e8306d.zip | |
hush: make "function" keyword support optional
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/hush.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/shell/hush.c b/shell/hush.c index 6bc86fcd0..00887d45f 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -205,6 +205,13 @@ | |||
| 205 | //config: help | 205 | //config: help |
| 206 | //config: Enable support for shell functions. +800 bytes. | 206 | //config: Enable support for shell functions. +800 bytes. |
| 207 | //config: | 207 | //config: |
| 208 | //config:config HUSH_FUNCTION_KEYWORD | ||
| 209 | //config: bool "Support function keyword" | ||
| 210 | //config: default y | ||
| 211 | //config: depends on HUSH_FUNCTIONS | ||
| 212 | //config: help | ||
| 213 | //config: Support "function FUNCNAME { CMD; }" syntax. | ||
| 214 | //config: | ||
| 208 | //config:config HUSH_LOCAL | 215 | //config:config HUSH_LOCAL |
| 209 | //config: bool "local builtin" | 216 | //config: bool "local builtin" |
| 210 | //config: default y | 217 | //config: default y |
| @@ -671,7 +678,9 @@ struct command { | |||
| 671 | # define CMD_SINGLEWORD_NOGLOB 3 | 678 | # define CMD_SINGLEWORD_NOGLOB 3 |
| 672 | #endif | 679 | #endif |
| 673 | #if ENABLE_HUSH_FUNCTIONS | 680 | #if ENABLE_HUSH_FUNCTIONS |
| 674 | # define CMD_FUNCTION_KWORD 4 | 681 | # if ENABLE_HUSH_FUNCTION_KEYWORD |
| 682 | # define CMD_FUNCTION_KWORD 4 | ||
| 683 | # endif | ||
| 675 | # define CMD_FUNCDEF 5 | 684 | # define CMD_FUNCDEF 5 |
| 676 | #endif | 685 | #endif |
| 677 | 686 | ||
| @@ -710,7 +719,7 @@ struct command { | |||
| 710 | /* Is there anything in this command at all? */ | 719 | /* Is there anything in this command at all? */ |
| 711 | #define IS_NULL_CMD(cmd) \ | 720 | #define IS_NULL_CMD(cmd) \ |
| 712 | (!(cmd)->group && !(cmd)->argv && !(cmd)->redirects \ | 721 | (!(cmd)->group && !(cmd)->argv && !(cmd)->redirects \ |
| 713 | /* maybe? IF_HUSH_FUNCTIONS(&& !(cmd)->cmd_type) */ \ | 722 | /* maybe? IF_HUSH_FUNCTION_KEYWORD(&& !(cmd)->cmd_type) */ \ |
| 714 | ) | 723 | ) |
| 715 | 724 | ||
| 716 | struct pipe { | 725 | struct pipe { |
| @@ -4200,7 +4209,7 @@ static void initialize_context(struct parse_context *ctx) | |||
| 4200 | */ | 4209 | */ |
| 4201 | #if HAS_KEYWORDS | 4210 | #if HAS_KEYWORDS |
| 4202 | struct reserved_combo { | 4211 | struct reserved_combo { |
| 4203 | char literal[ENABLE_HUSH_FUNCTIONS ? 9 : 6]; | 4212 | char literal[ENABLE_HUSH_FUNCTION_KEYWORD ? 9 : 6]; |
| 4204 | unsigned char res; | 4213 | unsigned char res; |
| 4205 | unsigned char assignment_flag; | 4214 | unsigned char assignment_flag; |
| 4206 | uint32_t flag; | 4215 | uint32_t flag; |
| @@ -4235,7 +4244,7 @@ enum { | |||
| 4235 | * FLAG_START means the word must start a new compound list. | 4244 | * FLAG_START means the word must start a new compound list. |
| 4236 | */ | 4245 | */ |
| 4237 | static const struct reserved_combo reserved_list[] ALIGN4 = { | 4246 | static const struct reserved_combo reserved_list[] ALIGN4 = { |
| 4238 | # if ENABLE_HUSH_FUNCTIONS | 4247 | # if ENABLE_HUSH_FUNCTION_KEYWORD |
| 4239 | { "function", RES_NONE, NOT_ASSIGNMENT, 0 }, | 4248 | { "function", RES_NONE, NOT_ASSIGNMENT, 0 }, |
| 4240 | # endif | 4249 | # endif |
| 4241 | # if ENABLE_HUSH_IF | 4250 | # if ENABLE_HUSH_IF |
| @@ -4294,7 +4303,7 @@ static const struct reserved_combo* reserved_word(struct parse_context *ctx) | |||
| 4294 | } else | 4303 | } else |
| 4295 | # endif | 4304 | # endif |
| 4296 | if (r->flag == 0) { /* 'function' or '!' */ | 4305 | if (r->flag == 0) { /* 'function' or '!' */ |
| 4297 | # if ENABLE_HUSH_FUNCTIONS | 4306 | # if ENABLE_HUSH_FUNCTION_KEYWORD |
| 4298 | if (r == &reserved_list[0]) { | 4307 | if (r == &reserved_list[0]) { |
| 4299 | ctx->command->cmd_type = CMD_FUNCTION_KWORD; | 4308 | ctx->command->cmd_type = CMD_FUNCTION_KWORD; |
| 4300 | return r; | 4309 | return r; |
| @@ -4922,7 +4931,9 @@ static int parse_group(struct parse_context *ctx, | |||
| 4922 | debug_printf_parse("parse_group entered\n"); | 4931 | debug_printf_parse("parse_group entered\n"); |
| 4923 | #if ENABLE_HUSH_FUNCTIONS | 4932 | #if ENABLE_HUSH_FUNCTIONS |
| 4924 | if ((ch == '(' | 4933 | if ((ch == '(' |
| 4934 | # if ENABLE_HUSH_FUNCTION_KEYWORD | ||
| 4925 | || command->cmd_type == CMD_FUNCTION_KWORD /* "function WORD" */ | 4935 | || command->cmd_type == CMD_FUNCTION_KWORD /* "function WORD" */ |
| 4936 | # endif | ||
| 4926 | ) | 4937 | ) |
| 4927 | && !ctx->word.has_quoted_part | 4938 | && !ctx->word.has_quoted_part |
| 4928 | ) { | 4939 | ) { |
| @@ -5964,7 +5975,7 @@ static struct pipe *parse_stream(char **pstring, | |||
| 5964 | #endif | 5975 | #endif |
| 5965 | if (done_word(&ctx)) | 5976 | if (done_word(&ctx)) |
| 5966 | goto parse_error_exitcode1; | 5977 | goto parse_error_exitcode1; |
| 5967 | #if ENABLE_HUSH_FUNCTIONS | 5978 | #if ENABLE_HUSH_FUNCTION_KEYWORD |
| 5968 | if (ctx.command->cmd_type == CMD_FUNCTION_KWORD | 5979 | if (ctx.command->cmd_type == CMD_FUNCTION_KWORD |
| 5969 | && ctx.command->argv /* "function WORD" */ | 5980 | && ctx.command->argv /* "function WORD" */ |
| 5970 | ) | 5981 | ) |
| @@ -6018,7 +6029,7 @@ static struct pipe *parse_stream(char **pstring, | |||
| 6018 | continue; /* ignore newline */ | 6029 | continue; /* ignore newline */ |
| 6019 | } | 6030 | } |
| 6020 | } | 6031 | } |
| 6021 | #if ENABLE_HUSH_FUNCTIONS | 6032 | #if ENABLE_HUSH_FUNCTION_KEYWORD |
| 6022 | if (ctx.command->cmd_type == CMD_FUNCTION_KWORD) { | 6033 | if (ctx.command->cmd_type == CMD_FUNCTION_KWORD) { |
| 6023 | if (!ctx.command->argv) { | 6034 | if (!ctx.command->argv) { |
| 6024 | /* Testcase: sh -c $'function\n' */ | 6035 | /* Testcase: sh -c $'function\n' */ |
| @@ -6134,7 +6145,7 @@ static struct pipe *parse_stream(char **pstring, | |||
| 6134 | #endif | 6145 | #endif |
| 6135 | if (done_word(&ctx)) | 6146 | if (done_word(&ctx)) |
| 6136 | goto parse_error_exitcode1; | 6147 | goto parse_error_exitcode1; |
| 6137 | #if ENABLE_HUSH_FUNCTIONS | 6148 | #if ENABLE_HUSH_FUNCTION_KEYWORD |
| 6138 | if (ctx.command->cmd_type == CMD_FUNCTION_KWORD) { | 6149 | if (ctx.command->cmd_type == CMD_FUNCTION_KWORD) { |
| 6139 | /* Testcase: sh -c '(function)' */ | 6150 | /* Testcase: sh -c '(function)' */ |
| 6140 | syntax_error("expected funcdef"); | 6151 | syntax_error("expected funcdef"); |
| @@ -6333,7 +6344,7 @@ static struct pipe *parse_stream(char **pstring, | |||
| 6333 | #endif | 6344 | #endif |
| 6334 | if (done_word(&ctx)) | 6345 | if (done_word(&ctx)) |
| 6335 | goto parse_error_exitcode1; | 6346 | goto parse_error_exitcode1; |
| 6336 | #if ENABLE_HUSH_FUNCTIONS | 6347 | #if ENABLE_HUSH_FUNCTION_KEYWORD |
| 6337 | if (ctx.command->cmd_type == CMD_FUNCTION_KWORD) { | 6348 | if (ctx.command->cmd_type == CMD_FUNCTION_KWORD) { |
| 6338 | /* Testcase: sh -c '{ function; }'; sh -c '{ function f; }' */ | 6349 | /* Testcase: sh -c '{ function; }'; sh -c '{ function f; }' */ |
| 6339 | syntax_error("expected funcdef"); | 6350 | syntax_error("expected funcdef"); |
| @@ -6451,7 +6462,7 @@ static struct pipe *parse_stream(char **pstring, | |||
| 6451 | case '{': { | 6462 | case '{': { |
| 6452 | int n; | 6463 | int n; |
| 6453 | /* "function WORD" -> */ | 6464 | /* "function WORD" -> */ |
| 6454 | parse_group: | 6465 | IF_HUSH_FUNCTION_KEYWORD(parse_group:) |
| 6455 | /* Try to parse as { CMDS; } or (CMDS) */ | 6466 | /* Try to parse as { CMDS; } or (CMDS) */ |
| 6456 | n = parse_group(&ctx, input, ch); | 6467 | n = parse_group(&ctx, input, ch); |
| 6457 | if (n < 0) | 6468 | if (n < 0) |
| @@ -6507,7 +6518,7 @@ static struct pipe *parse_stream(char **pstring, | |||
| 6507 | 6518 | ||
| 6508 | if (done_word(&ctx)) | 6519 | if (done_word(&ctx)) |
| 6509 | goto parse_error_exitcode1; | 6520 | goto parse_error_exitcode1; |
| 6510 | #if ENABLE_HUSH_FUNCTIONS | 6521 | #if ENABLE_HUSH_FUNCTION_KEYWORD |
| 6511 | if (ctx.command->cmd_type == CMD_FUNCTION_KWORD) { | 6522 | if (ctx.command->cmd_type == CMD_FUNCTION_KWORD) { |
| 6512 | /* Testcase: sh -c 'function'; sh -c 'function f' */ | 6523 | /* Testcase: sh -c 'function'; sh -c 'function f' */ |
| 6513 | syntax_error("expected funcdef"); | 6524 | syntax_error("expected funcdef"); |
