aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2025-08-17 17:59:30 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2025-08-17 17:59:30 +0200
commit2ccb8918190f95fe6119bee46ae4b595a2e8306d (patch)
tree977da2f40b7c5e615a3e5b3e6cc49a353097ece8 /shell
parent84d4ac375408f44d282aa49a21a2451eb41638e2 (diff)
downloadbusybox-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.c33
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
716struct pipe { 725struct pipe {
@@ -4200,7 +4209,7 @@ static void initialize_context(struct parse_context *ctx)
4200 */ 4209 */
4201#if HAS_KEYWORDS 4210#if HAS_KEYWORDS
4202struct reserved_combo { 4211struct 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 */
4237static const struct reserved_combo reserved_list[] ALIGN4 = { 4246static 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");