diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-06-10 13:39:35 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-06-10 13:39:35 +0200 |
commit | 9ca656b14945ec8462dc529ef5dc7662cce08296 (patch) | |
tree | e9a2ba84e8b5ed5a4ce3c8e541d784012250bf07 | |
parent | 1d77db8459e1948cdde407f5010f772b81048dbd (diff) | |
download | busybox-w32-9ca656b14945ec8462dc529ef5dc7662cce08296.tar.gz busybox-w32-9ca656b14945ec8462dc529ef5dc7662cce08296.tar.bz2 busybox-w32-9ca656b14945ec8462dc529ef5dc7662cce08296.zip |
hush: add HUSH_BASH_COMPAT, make [[ special handling depend on it
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/Config.in | 13 | ||||
-rw-r--r-- | shell/hush.c | 58 |
2 files changed, 41 insertions, 30 deletions
diff --git a/shell/Config.in b/shell/Config.in index ee56d89f3..126dba8e5 100644 --- a/shell/Config.in +++ b/shell/Config.in | |||
@@ -43,9 +43,6 @@ config ASH | |||
43 | shell (by Herbert Xu), which was created by porting the 'ash' shell | 43 | shell (by Herbert Xu), which was created by porting the 'ash' shell |
44 | (written by Kenneth Almquist) from NetBSD. | 44 | (written by Kenneth Almquist) from NetBSD. |
45 | 45 | ||
46 | comment "Ash Shell Options" | ||
47 | depends on ASH | ||
48 | |||
49 | config ASH_BASH_COMPAT | 46 | config ASH_BASH_COMPAT |
50 | bool "bash-compatible extensions" | 47 | bool "bash-compatible extensions" |
51 | default y | 48 | default y |
@@ -169,6 +166,13 @@ config HUSH | |||
169 | It does not handle select, aliases, brace expansion, | 166 | It does not handle select, aliases, brace expansion, |
170 | tilde expansion, &>file and >&file redirection of stdout+stderr. | 167 | tilde expansion, &>file and >&file redirection of stdout+stderr. |
171 | 168 | ||
169 | config HUSH_BASH_COMPAT | ||
170 | bool "bash-compatible extensions" | ||
171 | default y | ||
172 | depends on HUSH | ||
173 | help | ||
174 | Enable bash-compatible extensions. | ||
175 | |||
172 | config HUSH_HELP | 176 | config HUSH_HELP |
173 | bool "help builtin" | 177 | bool "help builtin" |
174 | default n | 178 | default n |
@@ -268,9 +272,6 @@ config MSH | |||
268 | # It uses only vfork, so it can be used on uClinux systems. | 272 | # It uses only vfork, so it can be used on uClinux systems. |
269 | 273 | ||
270 | 274 | ||
271 | comment "Bourne Shell Options" | ||
272 | depends on MSH || LASH || HUSH || ASH | ||
273 | |||
274 | config SH_MATH_SUPPORT | 275 | config SH_MATH_SUPPORT |
275 | bool "POSIX math support" | 276 | bool "POSIX math support" |
276 | default y | 277 | default y |
diff --git a/shell/hush.c b/shell/hush.c index c9962e33b..54ab78b27 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -42,11 +42,18 @@ | |||
42 | * <(list) and >(list) Process Substitution | 42 | * <(list) and >(list) Process Substitution |
43 | * Tilde Expansion | 43 | * Tilde Expansion |
44 | * | 44 | * |
45 | * Bash stuff (maybe optionally enable?): | 45 | * Bash stuff (optionally enabled): |
46 | * &> and >& redirection of stdout+stderr | 46 | * &> and >& redirection of stdout+stderr |
47 | * Brace Expansion | 47 | * Brace Expansion |
48 | * reserved words: [[ ]] function select | 48 | * reserved words: [[ ]] function select |
49 | * substrings ${var:1:5} | 49 | * substrings ${var:1:5} |
50 | * let EXPR [EXPR...] | ||
51 | * Each EXPR is an arithmetic expression (ARITHMETIC EVALUATION) | ||
52 | * If the last arg evaluates to 0, let returns 1; 0 otherwise. | ||
53 | * NB: let `echo 'a=a + 1'` - error (IOW: multi-word expansion is used) | ||
54 | * ((EXPR)) | ||
55 | * The EXPR is evaluated according to ARITHMETIC EVALUATION. | ||
56 | * This is exactly equivalent to let "expression". | ||
50 | * | 57 | * |
51 | * TODOs: | 58 | * TODOs: |
52 | * grep for "TODO" and fix (some of them are easy) | 59 | * grep for "TODO" and fix (some of them are easy) |
@@ -59,7 +66,7 @@ | |||
59 | * $ ls i=`echo 'a b'` # ls has two args: "i=a" and "b" | 66 | * $ ls i=`echo 'a b'` # ls has two args: "i=a" and "b" |
60 | * ls: cannot access i=a: No such file or directory | 67 | * ls: cannot access i=a: No such file or directory |
61 | * ls: cannot access b: No such file or directory | 68 | * ls: cannot access b: No such file or directory |
62 | * Note1: same applies to local builtin when we'll have it. | 69 | * Note1: same applies to local builtin. |
63 | * Note2: bash 3.2.33(1) does this only if export word itself | 70 | * Note2: bash 3.2.33(1) does this only if export word itself |
64 | * is not quoted: | 71 | * is not quoted: |
65 | * $ export i=`echo 'aaa bbb'`; echo "$i" | 72 | * $ export i=`echo 'aaa bbb'`; echo "$i" |
@@ -299,28 +306,11 @@ struct command { | |||
299 | smallint cmd_type; /* CMD_xxx */ | 306 | smallint cmd_type; /* CMD_xxx */ |
300 | #define CMD_NORMAL 0 | 307 | #define CMD_NORMAL 0 |
301 | #define CMD_SUBSHELL 1 | 308 | #define CMD_SUBSHELL 1 |
309 | |||
302 | /* used for "[[ EXPR ]]" */ | 310 | /* used for "[[ EXPR ]]" */ |
303 | #define CMD_SINGLEWORD_NOGLOB 2 | 311 | #if ENABLE_HUSH_BASH_COMPAT |
304 | /* used for "export noglob=* glob* a=`echo a b`" */ | 312 | # define CMD_SINGLEWORD_NOGLOB 2 |
305 | /* #define CMD_SINGLEWORD_NOGLOB_COND 3 */ | 313 | #endif |
306 | // It is hard to implement correctly, adds significant amounts of tricky code, | ||
307 | // and all this only useful for really obscure export statements | ||
308 | // almost nobody would use anyway. #ifdef CMD_SINGLEWORD_NOGLOB_COND | ||
309 | // guard the code which implement it, but I have doubts it works | ||
310 | // in all cases (especially with mixed globbed/non-globbed arguments) | ||
311 | #if ENABLE_HUSH_FUNCTIONS | ||
312 | # define CMD_FUNCDEF 4 | ||
313 | #endif | ||
314 | //TODO | ||
315 | //#define CMD_ARITH - let EXPR, ((EXPR)) | ||
316 | //let EXPR [EXPR...] | ||
317 | // Each EXPR is an arithmetic expression to be evaluated (ARITHMETIC EVALUATION) | ||
318 | // If the last arg evaluates to 0, let returns 1; 0 is returned otherwise. | ||
319 | // NB: let `echo 'a=a + 1'` - error (IOW: multi-word expansion is used) | ||
320 | //((EXPR)) | ||
321 | // The EXPR is evaluated according to ARITHMETIC EVALUATION. | ||
322 | // This is exactly equivalent to let "expression". | ||
323 | //[[ EXPR ]] | ||
324 | // Basically, word splitting and pathname expansion should NOT be performed | 314 | // Basically, word splitting and pathname expansion should NOT be performed |
325 | // Examples: | 315 | // Examples: |
326 | // no word splitting: a="a b"; [[ $a = "a b" ]]; echo $? should print "0" | 316 | // no word splitting: a="a b"; [[ $a = "a b" ]]; echo $? should print "0" |
@@ -330,6 +320,18 @@ struct command { | |||
330 | // =~ regexp match | 320 | // =~ regexp match |
331 | // Apart from the above, [[ expr ]] should work as [ expr ] | 321 | // Apart from the above, [[ expr ]] should work as [ expr ] |
332 | 322 | ||
323 | /* used for "export noglob=* glob* a=`echo a b`" */ | ||
324 | /*#define CMD_SINGLEWORD_NOGLOB_COND 3 */ | ||
325 | // It is hard to implement correctly, it adds significant amounts of tricky code, | ||
326 | // and all this is only useful for really obscure export statements | ||
327 | // almost nobody would use anyway. #ifdef CMD_SINGLEWORD_NOGLOB_COND | ||
328 | // guards the code which implements it, but I have doubts it works | ||
329 | // in all cases (especially with mixed globbed/non-globbed arguments) | ||
330 | |||
331 | #if ENABLE_HUSH_FUNCTIONS | ||
332 | # define CMD_FUNCDEF 3 | ||
333 | #endif | ||
334 | |||
333 | /* if non-NULL, this "command" is { list }, ( list ), or a compound statement */ | 335 | /* if non-NULL, this "command" is { list }, ( list ), or a compound statement */ |
334 | struct pipe *group; | 336 | struct pipe *group; |
335 | #if !BB_MMU | 337 | #if !BB_MMU |
@@ -2484,10 +2486,12 @@ static char **expand_strvec_to_strvec(char **argv) | |||
2484 | return expand_variables(argv, 0x100); | 2486 | return expand_variables(argv, 0x100); |
2485 | } | 2487 | } |
2486 | 2488 | ||
2489 | #if ENABLE_HUSH_BASH_COMPAT | ||
2487 | static char **expand_strvec_to_strvec_singleword_noglob(char **argv) | 2490 | static char **expand_strvec_to_strvec_singleword_noglob(char **argv) |
2488 | { | 2491 | { |
2489 | return expand_variables(argv, 0x80); | 2492 | return expand_variables(argv, 0x80); |
2490 | } | 2493 | } |
2494 | #endif | ||
2491 | 2495 | ||
2492 | #ifdef CMD_SINGLEWORD_NOGLOB_COND | 2496 | #ifdef CMD_SINGLEWORD_NOGLOB_COND |
2493 | static char **expand_strvec_to_strvec_singleword_noglob_cond(char **argv) | 2497 | static char **expand_strvec_to_strvec_singleword_noglob_cond(char **argv) |
@@ -3838,9 +3842,12 @@ static int run_pipe(struct pipe *pi) | |||
3838 | } | 3842 | } |
3839 | 3843 | ||
3840 | /* Expand the rest into (possibly) many strings each */ | 3844 | /* Expand the rest into (possibly) many strings each */ |
3841 | if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) { | 3845 | if (0) {} |
3846 | #if ENABLE_HUSH_BASH_COMPAT | ||
3847 | else if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) { | ||
3842 | argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt); | 3848 | argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt); |
3843 | } | 3849 | } |
3850 | #endif | ||
3844 | #ifdef CMD_SINGLEWORD_NOGLOB_COND | 3851 | #ifdef CMD_SINGLEWORD_NOGLOB_COND |
3845 | else if (command->cmd_type == CMD_SINGLEWORD_NOGLOB_COND) { | 3852 | else if (command->cmd_type == CMD_SINGLEWORD_NOGLOB_COND) { |
3846 | argv_expanded = expand_strvec_to_strvec_singleword_noglob_cond(argv + command->assignment_cnt); | 3853 | argv_expanded = expand_strvec_to_strvec_singleword_noglob_cond(argv + command->assignment_cnt); |
@@ -4094,6 +4101,7 @@ static void debug_print_tree(struct pipe *pi, int lvl) | |||
4094 | static const char *const CMDTYPE[] = { | 4101 | static const char *const CMDTYPE[] = { |
4095 | "{}", | 4102 | "{}", |
4096 | "()", | 4103 | "()", |
4104 | "[noglob]", | ||
4097 | #if ENABLE_HUSH_FUNCTIONS | 4105 | #if ENABLE_HUSH_FUNCTIONS |
4098 | "func()", | 4106 | "func()", |
4099 | #endif | 4107 | #endif |
@@ -4833,10 +4841,12 @@ static int done_word(o_string *word, struct parse_context *ctx) | |||
4833 | command->cmd_type = CMD_SINGLEWORD_NOGLOB_COND; | 4841 | command->cmd_type = CMD_SINGLEWORD_NOGLOB_COND; |
4834 | } else | 4842 | } else |
4835 | # endif | 4843 | # endif |
4844 | # if ENABLE_HUSH_BASH_COMPAT | ||
4836 | if (strcmp(word->data, "[[") == 0) { | 4845 | if (strcmp(word->data, "[[") == 0) { |
4837 | command->cmd_type = CMD_SINGLEWORD_NOGLOB; | 4846 | command->cmd_type = CMD_SINGLEWORD_NOGLOB; |
4838 | } | 4847 | } |
4839 | /* fall through */ | 4848 | /* fall through */ |
4849 | # endif | ||
4840 | } | 4850 | } |
4841 | #endif | 4851 | #endif |
4842 | if (command->group) { | 4852 | if (command->group) { |