diff options
author | Kang-Che Sung <explorer09@gmail.com> | 2017-01-11 14:18:15 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-11 14:18:30 +0100 |
commit | 027d3ab57d6a3a5a872543a6f30e55347d975149 (patch) | |
tree | 350985cb3b94227757b737a26bb6fc0230e714a0 /shell | |
parent | 7d4aec0c3ecb0c10de60070616d9d8fb9b074497 (diff) | |
download | busybox-w32-027d3ab57d6a3a5a872543a6f30e55347d975149.tar.gz busybox-w32-027d3ab57d6a3a5a872543a6f30e55347d975149.tar.bz2 busybox-w32-027d3ab57d6a3a5a872543a6f30e55347d975149.zip |
hush: split bash compatible extensions into separate defines. No code changes
Splitting these options makes it self-documenting about what
bash-compatible features we have.
Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r-- | shell/hush.c | 73 |
1 files changed, 44 insertions, 29 deletions
diff --git a/shell/hush.c b/shell/hush.c index ecef099ac..fb0321a2c 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -326,6 +326,15 @@ | |||
326 | #endif | 326 | #endif |
327 | 327 | ||
328 | 328 | ||
329 | /* So far, all bash compat is controlled by one config option */ | ||
330 | /* Separate defines document which part of code implements what */ | ||
331 | #define BASH_PATTERN_SUBST ENABLE_HUSH_BASH_COMPAT | ||
332 | #define BASH_SUBSTR ENABLE_HUSH_BASH_COMPAT | ||
333 | #define BASH_TEST2 ENABLE_HUSH_BASH_COMPAT | ||
334 | #define BASH_SOURCE ENABLE_HUSH_BASH_COMPAT | ||
335 | #define BASH_HOSTNAME_VAR ENABLE_HUSH_BASH_COMPAT | ||
336 | |||
337 | |||
329 | /* Build knobs */ | 338 | /* Build knobs */ |
330 | #define LEAK_HUNTING 0 | 339 | #define LEAK_HUNTING 0 |
331 | #define BUILD_AS_NOMMU 0 | 340 | #define BUILD_AS_NOMMU 0 |
@@ -411,7 +420,7 @@ | |||
411 | #define _SPECIAL_VARS_STR "_*@$!?#" | 420 | #define _SPECIAL_VARS_STR "_*@$!?#" |
412 | #define SPECIAL_VARS_STR ("_*@$!?#" + 1) | 421 | #define SPECIAL_VARS_STR ("_*@$!?#" + 1) |
413 | #define NUMERIC_SPECVARS_STR ("_*@$!?#" + 3) | 422 | #define NUMERIC_SPECVARS_STR ("_*@$!?#" + 3) |
414 | #if ENABLE_HUSH_BASH_COMPAT | 423 | #if BASH_PATTERN_SUBST |
415 | /* Support / and // replace ops */ | 424 | /* Support / and // replace ops */ |
416 | /* Note that // is stored as \ in "encoded" string representation */ | 425 | /* Note that // is stored as \ in "encoded" string representation */ |
417 | # define VAR_ENCODED_SUBST_OPS "\\/%#:-=+?" | 426 | # define VAR_ENCODED_SUBST_OPS "\\/%#:-=+?" |
@@ -572,7 +581,7 @@ struct command { | |||
572 | smallint cmd_type; /* CMD_xxx */ | 581 | smallint cmd_type; /* CMD_xxx */ |
573 | #define CMD_NORMAL 0 | 582 | #define CMD_NORMAL 0 |
574 | #define CMD_SUBSHELL 1 | 583 | #define CMD_SUBSHELL 1 |
575 | #if ENABLE_HUSH_BASH_COMPAT | 584 | #if BASH_TEST2 |
576 | /* used for "[[ EXPR ]]" */ | 585 | /* used for "[[ EXPR ]]" */ |
577 | # define CMD_SINGLEWORD_NOGLOB 2 | 586 | # define CMD_SINGLEWORD_NOGLOB 2 |
578 | #endif | 587 | #endif |
@@ -947,7 +956,7 @@ static int builtin_set(char **argv) FAST_FUNC; | |||
947 | #endif | 956 | #endif |
948 | static int builtin_shift(char **argv) FAST_FUNC; | 957 | static int builtin_shift(char **argv) FAST_FUNC; |
949 | static int builtin_source(char **argv) FAST_FUNC; | 958 | static int builtin_source(char **argv) FAST_FUNC; |
950 | #if ENABLE_HUSH_TEST | 959 | #if ENABLE_HUSH_TEST || BASH_TEST2 |
951 | static int builtin_test(char **argv) FAST_FUNC; | 960 | static int builtin_test(char **argv) FAST_FUNC; |
952 | #endif | 961 | #endif |
953 | #if ENABLE_HUSH_TRAP | 962 | #if ENABLE_HUSH_TRAP |
@@ -1044,7 +1053,7 @@ static const struct built_in_command bltins1[] = { | |||
1044 | BLTIN("set" , builtin_set , "Set positional parameters"), | 1053 | BLTIN("set" , builtin_set , "Set positional parameters"), |
1045 | #endif | 1054 | #endif |
1046 | BLTIN("shift" , builtin_shift , "Shift positional parameters"), | 1055 | BLTIN("shift" , builtin_shift , "Shift positional parameters"), |
1047 | #if ENABLE_HUSH_BASH_COMPAT | 1056 | #if BASH_SOURCE |
1048 | BLTIN("source" , builtin_source , NULL), | 1057 | BLTIN("source" , builtin_source , NULL), |
1049 | #endif | 1058 | #endif |
1050 | #if ENABLE_HUSH_TRAP | 1059 | #if ENABLE_HUSH_TRAP |
@@ -2174,7 +2183,7 @@ static void unset_vars(char **strings) | |||
2174 | free(strings); | 2183 | free(strings); |
2175 | } | 2184 | } |
2176 | 2185 | ||
2177 | #if ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_BASH_COMPAT || ENABLE_HUSH_READ | 2186 | #if BASH_HOSTNAME_VAR || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_READ |
2178 | static void FAST_FUNC set_local_var_from_halves(const char *name, const char *val) | 2187 | static void FAST_FUNC set_local_var_from_halves(const char *name, const char *val) |
2179 | { | 2188 | { |
2180 | char *var = xasprintf("%s=%s", name, val); | 2189 | char *var = xasprintf("%s=%s", name, val); |
@@ -3633,7 +3642,7 @@ static int done_word(o_string *word, struct parse_context *ctx) | |||
3633 | (ctx->ctx_res_w == RES_SNTX)); | 3642 | (ctx->ctx_res_w == RES_SNTX)); |
3634 | return (ctx->ctx_res_w == RES_SNTX); | 3643 | return (ctx->ctx_res_w == RES_SNTX); |
3635 | } | 3644 | } |
3636 | # if ENABLE_HUSH_BASH_COMPAT | 3645 | # if BASH_TEST2 |
3637 | if (strcmp(word->data, "[[") == 0) { | 3646 | if (strcmp(word->data, "[[") == 0) { |
3638 | command->cmd_type = CMD_SINGLEWORD_NOGLOB; | 3647 | command->cmd_type = CMD_SINGLEWORD_NOGLOB; |
3639 | } | 3648 | } |
@@ -4231,7 +4240,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign | |||
4231 | { | 4240 | { |
4232 | int ch; | 4241 | int ch; |
4233 | char dbl = end_ch & DOUBLE_CLOSE_CHAR_FLAG; | 4242 | char dbl = end_ch & DOUBLE_CLOSE_CHAR_FLAG; |
4234 | # if ENABLE_HUSH_BASH_COMPAT | 4243 | # if BASH_SUBSTR || BASH_PATTERN_SUBST |
4235 | char end_char2 = end_ch >> 8; | 4244 | char end_char2 = end_ch >> 8; |
4236 | # endif | 4245 | # endif |
4237 | end_ch &= (DOUBLE_CLOSE_CHAR_FLAG - 1); | 4246 | end_ch &= (DOUBLE_CLOSE_CHAR_FLAG - 1); |
@@ -4242,7 +4251,11 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign | |||
4242 | syntax_error_unterm_ch(end_ch); | 4251 | syntax_error_unterm_ch(end_ch); |
4243 | return 0; | 4252 | return 0; |
4244 | } | 4253 | } |
4245 | if (ch == end_ch IF_HUSH_BASH_COMPAT( || ch == end_char2)) { | 4254 | if (ch == end_ch |
4255 | # if BASH_SUBSTR || BASH_PATTERN_SUBST | ||
4256 | || ch == end_char2 | ||
4257 | # endif | ||
4258 | ) { | ||
4246 | if (!dbl) | 4259 | if (!dbl) |
4247 | break; | 4260 | break; |
4248 | /* we look for closing )) of $((EXPR)) */ | 4261 | /* we look for closing )) of $((EXPR)) */ |
@@ -4395,14 +4408,14 @@ static int parse_dollar(o_string *as_string, | |||
4395 | 4408 | ||
4396 | /* Eat everything until closing '}' (or ':') */ | 4409 | /* Eat everything until closing '}' (or ':') */ |
4397 | end_ch = '}'; | 4410 | end_ch = '}'; |
4398 | if (ENABLE_HUSH_BASH_COMPAT | 4411 | if (BASH_SUBSTR |
4399 | && ch == ':' | 4412 | && ch == ':' |
4400 | && !strchr(MINUS_PLUS_EQUAL_QUESTION, i_peek(input)) | 4413 | && !strchr(MINUS_PLUS_EQUAL_QUESTION, i_peek(input)) |
4401 | ) { | 4414 | ) { |
4402 | /* It's ${var:N[:M]} thing */ | 4415 | /* It's ${var:N[:M]} thing */ |
4403 | end_ch = '}' * 0x100 + ':'; | 4416 | end_ch = '}' * 0x100 + ':'; |
4404 | } | 4417 | } |
4405 | if (ENABLE_HUSH_BASH_COMPAT | 4418 | if (BASH_PATTERN_SUBST |
4406 | && ch == '/' | 4419 | && ch == '/' |
4407 | ) { | 4420 | ) { |
4408 | /* It's ${var/[/]pattern[/repl]} thing */ | 4421 | /* It's ${var/[/]pattern[/repl]} thing */ |
@@ -4429,7 +4442,9 @@ static int parse_dollar(o_string *as_string, | |||
4429 | o_addchr(as_string, last_ch); | 4442 | o_addchr(as_string, last_ch); |
4430 | } | 4443 | } |
4431 | 4444 | ||
4432 | if (ENABLE_HUSH_BASH_COMPAT && (end_ch & 0xff00)) { | 4445 | if ((BASH_SUBSTR || BASH_PATTERN_SUBST) |
4446 | && (end_ch & 0xff00) | ||
4447 | ) { | ||
4433 | /* close the first block: */ | 4448 | /* close the first block: */ |
4434 | o_addchr(dest, SPECIAL_VAR_SYMBOL); | 4449 | o_addchr(dest, SPECIAL_VAR_SYMBOL); |
4435 | /* while parsing N from ${var:N[:M]} | 4450 | /* while parsing N from ${var:N[:M]} |
@@ -4440,7 +4455,7 @@ static int parse_dollar(o_string *as_string, | |||
4440 | goto again; | 4455 | goto again; |
4441 | } | 4456 | } |
4442 | /* got '}' */ | 4457 | /* got '}' */ |
4443 | if (end_ch == '}' * 0x100 + ':') { | 4458 | if (BASH_SUBSTR && end_ch == '}' * 0x100 + ':') { |
4444 | /* it's ${var:N} - emulate :999999999 */ | 4459 | /* it's ${var:N} - emulate :999999999 */ |
4445 | o_addstr(dest, "999999999"); | 4460 | o_addstr(dest, "999999999"); |
4446 | } /* else: it's ${var/[/]pattern} */ | 4461 | } /* else: it's ${var/[/]pattern} */ |
@@ -4515,7 +4530,7 @@ static int parse_dollar(o_string *as_string, | |||
4515 | } | 4530 | } |
4516 | 4531 | ||
4517 | #if BB_MMU | 4532 | #if BB_MMU |
4518 | # if ENABLE_HUSH_BASH_COMPAT | 4533 | # if BASH_PATTERN_SUBST |
4519 | #define encode_string(as_string, dest, input, dquote_end, process_bkslash) \ | 4534 | #define encode_string(as_string, dest, input, dquote_end, process_bkslash) \ |
4520 | encode_string(dest, input, dquote_end, process_bkslash) | 4535 | encode_string(dest, input, dquote_end, process_bkslash) |
4521 | # else | 4536 | # else |
@@ -4527,7 +4542,7 @@ static int parse_dollar(o_string *as_string, | |||
4527 | 4542 | ||
4528 | #else /* !MMU */ | 4543 | #else /* !MMU */ |
4529 | 4544 | ||
4530 | # if ENABLE_HUSH_BASH_COMPAT | 4545 | # if BASH_PATTERN_SUBST |
4531 | /* all parameters are needed, no macro tricks */ | 4546 | /* all parameters are needed, no macro tricks */ |
4532 | # else | 4547 | # else |
4533 | #define encode_string(as_string, dest, input, dquote_end, process_bkslash) \ | 4548 | #define encode_string(as_string, dest, input, dquote_end, process_bkslash) \ |
@@ -4540,7 +4555,7 @@ static int encode_string(o_string *as_string, | |||
4540 | int dquote_end, | 4555 | int dquote_end, |
4541 | int process_bkslash) | 4556 | int process_bkslash) |
4542 | { | 4557 | { |
4543 | #if !ENABLE_HUSH_BASH_COMPAT | 4558 | #if !BASH_PATTERN_SUBST |
4544 | const int process_bkslash = 1; | 4559 | const int process_bkslash = 1; |
4545 | #endif | 4560 | #endif |
4546 | int ch; | 4561 | int ch; |
@@ -5183,7 +5198,7 @@ static struct pipe *parse_stream(char **pstring, | |||
5183 | /*** Execution routines ***/ | 5198 | /*** Execution routines ***/ |
5184 | 5199 | ||
5185 | /* Expansion can recurse, need forward decls: */ | 5200 | /* Expansion can recurse, need forward decls: */ |
5186 | #if !ENABLE_HUSH_BASH_COMPAT | 5201 | #if !BASH_PATTERN_SUBST |
5187 | /* only ${var/pattern/repl} (its pattern part) needs additional mode */ | 5202 | /* only ${var/pattern/repl} (its pattern part) needs additional mode */ |
5188 | #define expand_string_to_string(str, do_unbackslash) \ | 5203 | #define expand_string_to_string(str, do_unbackslash) \ |
5189 | expand_string_to_string(str) | 5204 | expand_string_to_string(str) |
@@ -5304,7 +5319,7 @@ static int expand_on_ifs(int *ended_with_ifs, o_string *output, int n, const cha | |||
5304 | * Returns malloced string. | 5319 | * Returns malloced string. |
5305 | * As an optimization, we return NULL if expansion is not needed. | 5320 | * As an optimization, we return NULL if expansion is not needed. |
5306 | */ | 5321 | */ |
5307 | #if !ENABLE_HUSH_BASH_COMPAT | 5322 | #if !BASH_PATTERN_SUBST |
5308 | /* only ${var/pattern/repl} (its pattern part) needs additional mode */ | 5323 | /* only ${var/pattern/repl} (its pattern part) needs additional mode */ |
5309 | #define encode_then_expand_string(str, process_bkslash, do_unbackslash) \ | 5324 | #define encode_then_expand_string(str, process_bkslash, do_unbackslash) \ |
5310 | encode_then_expand_string(str) | 5325 | encode_then_expand_string(str) |
@@ -5358,7 +5373,7 @@ static arith_t expand_and_evaluate_arith(const char *arg, const char **errmsg_p) | |||
5358 | } | 5373 | } |
5359 | #endif | 5374 | #endif |
5360 | 5375 | ||
5361 | #if ENABLE_HUSH_BASH_COMPAT | 5376 | #if BASH_PATTERN_SUBST |
5362 | /* ${var/[/]pattern[/repl]} helpers */ | 5377 | /* ${var/[/]pattern[/repl]} helpers */ |
5363 | static char *strstr_pattern(char *val, const char *pattern, int *size) | 5378 | static char *strstr_pattern(char *val, const char *pattern, int *size) |
5364 | { | 5379 | { |
@@ -5410,7 +5425,7 @@ static char *replace_pattern(char *val, const char *pattern, const char *repl, c | |||
5410 | debug_printf_varexp("result:'%s'\n", result); | 5425 | debug_printf_varexp("result:'%s'\n", result); |
5411 | return result; | 5426 | return result; |
5412 | } | 5427 | } |
5413 | #endif | 5428 | #endif /* BASH_PATTERN_SUBST */ |
5414 | 5429 | ||
5415 | /* Helper: | 5430 | /* Helper: |
5416 | * Handles <SPECIAL_VAR_SYMBOL>varname...<SPECIAL_VAR_SYMBOL> construct. | 5431 | * Handles <SPECIAL_VAR_SYMBOL>varname...<SPECIAL_VAR_SYMBOL> construct. |
@@ -5458,7 +5473,7 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha | |||
5458 | if (exp_op == ':') { | 5473 | if (exp_op == ':') { |
5459 | exp_op = *exp_word++; | 5474 | exp_op = *exp_word++; |
5460 | //TODO: try ${var:} and ${var:bogus} in non-bash config | 5475 | //TODO: try ${var:} and ${var:bogus} in non-bash config |
5461 | if (ENABLE_HUSH_BASH_COMPAT | 5476 | if (BASH_SUBSTR |
5462 | && (!exp_op || !strchr(MINUS_PLUS_EQUAL_QUESTION, exp_op)) | 5477 | && (!exp_op || !strchr(MINUS_PLUS_EQUAL_QUESTION, exp_op)) |
5463 | ) { | 5478 | ) { |
5464 | /* oops... it's ${var:N[:M]}, not ${var:?xxx} or some such */ | 5479 | /* oops... it's ${var:N[:M]}, not ${var:?xxx} or some such */ |
@@ -5540,7 +5555,7 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha | |||
5540 | } | 5555 | } |
5541 | } | 5556 | } |
5542 | } | 5557 | } |
5543 | #if ENABLE_HUSH_BASH_COMPAT | 5558 | #if BASH_PATTERN_SUBST |
5544 | else if (exp_op == '/' || exp_op == '\\') { | 5559 | else if (exp_op == '/' || exp_op == '\\') { |
5545 | /* It's ${var/[/]pattern[/repl]} thing. | 5560 | /* It's ${var/[/]pattern[/repl]} thing. |
5546 | * Note that in encoded form it has TWO parts: | 5561 | * Note that in encoded form it has TWO parts: |
@@ -5587,9 +5602,9 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha | |||
5587 | free(repl); | 5602 | free(repl); |
5588 | } | 5603 | } |
5589 | } | 5604 | } |
5590 | #endif | 5605 | #endif /* BASH_PATTERN_SUBST */ |
5591 | else if (exp_op == ':') { | 5606 | else if (exp_op == ':') { |
5592 | #if ENABLE_HUSH_BASH_COMPAT && ENABLE_FEATURE_SH_MATH | 5607 | #if BASH_SUBSTR && ENABLE_FEATURE_SH_MATH |
5593 | /* It's ${var:N[:M]} bashism. | 5608 | /* It's ${var:N[:M]} bashism. |
5594 | * Note that in encoded form it has TWO parts: | 5609 | * Note that in encoded form it has TWO parts: |
5595 | * var:N<SPECIAL_VAR_SYMBOL>M<SPECIAL_VAR_SYMBOL> | 5610 | * var:N<SPECIAL_VAR_SYMBOL>M<SPECIAL_VAR_SYMBOL> |
@@ -5625,7 +5640,7 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha | |||
5625 | } | 5640 | } |
5626 | debug_printf_varexp("val:'%s'\n", val); | 5641 | debug_printf_varexp("val:'%s'\n", val); |
5627 | } else | 5642 | } else |
5628 | #endif | 5643 | #endif /* HUSH_SUBSTR_EXPANSION && FEATURE_SH_MATH */ |
5629 | { | 5644 | { |
5630 | die_if_script("malformed ${%s:...}", var); | 5645 | die_if_script("malformed ${%s:...}", var); |
5631 | val = NULL; | 5646 | val = NULL; |
@@ -5915,7 +5930,7 @@ static char **expand_strvec_to_strvec(char **argv) | |||
5915 | return expand_variables(argv, EXP_FLAG_GLOB | EXP_FLAG_ESC_GLOB_CHARS); | 5930 | return expand_variables(argv, EXP_FLAG_GLOB | EXP_FLAG_ESC_GLOB_CHARS); |
5916 | } | 5931 | } |
5917 | 5932 | ||
5918 | #if ENABLE_HUSH_BASH_COMPAT | 5933 | #if BASH_TEST2 |
5919 | static char **expand_strvec_to_strvec_singleword_noglob(char **argv) | 5934 | static char **expand_strvec_to_strvec_singleword_noglob(char **argv) |
5920 | { | 5935 | { |
5921 | return expand_variables(argv, EXP_FLAG_SINGLEWORD); | 5936 | return expand_variables(argv, EXP_FLAG_SINGLEWORD); |
@@ -5930,7 +5945,7 @@ static char **expand_strvec_to_strvec_singleword_noglob(char **argv) | |||
5930 | */ | 5945 | */ |
5931 | static char *expand_string_to_string(const char *str, int do_unbackslash) | 5946 | static char *expand_string_to_string(const char *str, int do_unbackslash) |
5932 | { | 5947 | { |
5933 | #if !ENABLE_HUSH_BASH_COMPAT | 5948 | #if !BASH_PATTERN_SUBST |
5934 | const int do_unbackslash = 1; | 5949 | const int do_unbackslash = 1; |
5935 | #endif | 5950 | #endif |
5936 | char *argv[2], **list; | 5951 | char *argv[2], **list; |
@@ -7652,7 +7667,7 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
7652 | } | 7667 | } |
7653 | 7668 | ||
7654 | /* Expand the rest into (possibly) many strings each */ | 7669 | /* Expand the rest into (possibly) many strings each */ |
7655 | #if ENABLE_HUSH_BASH_COMPAT | 7670 | #if BASH_TEST2 |
7656 | if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) { | 7671 | if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) { |
7657 | argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt); | 7672 | argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt); |
7658 | } else | 7673 | } else |
@@ -8408,7 +8423,7 @@ int hush_main(int argc, char **argv) | |||
8408 | /* Export PWD */ | 8423 | /* Export PWD */ |
8409 | set_pwd_var(/*exp:*/ 1); | 8424 | set_pwd_var(/*exp:*/ 1); |
8410 | 8425 | ||
8411 | #if ENABLE_HUSH_BASH_COMPAT | 8426 | #if BASH_HOSTNAME_VAR |
8412 | /* Set (but not export) HOSTNAME unless already set */ | 8427 | /* Set (but not export) HOSTNAME unless already set */ |
8413 | if (!get_local_var_value("HOSTNAME")) { | 8428 | if (!get_local_var_value("HOSTNAME")) { |
8414 | struct utsname uts; | 8429 | struct utsname uts; |
@@ -8816,7 +8831,7 @@ static int run_applet_main(char **argv, int (*applet_main_func)(int argc, char * | |||
8816 | return applet_main_func(argc, argv - argc); | 8831 | return applet_main_func(argc, argv - argc); |
8817 | } | 8832 | } |
8818 | #endif | 8833 | #endif |
8819 | #if ENABLE_HUSH_TEST | 8834 | #if ENABLE_HUSH_TEST || BASH_TEST2 |
8820 | static int FAST_FUNC builtin_test(char **argv) | 8835 | static int FAST_FUNC builtin_test(char **argv) |
8821 | { | 8836 | { |
8822 | return run_applet_main(argv, test_main); | 8837 | return run_applet_main(argv, test_main); |