aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-06-10 13:39:35 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-06-10 13:39:35 +0200
commit9ca656b14945ec8462dc529ef5dc7662cce08296 (patch)
treee9a2ba84e8b5ed5a4ce3c8e541d784012250bf07
parent1d77db8459e1948cdde407f5010f772b81048dbd (diff)
downloadbusybox-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.in13
-rw-r--r--shell/hush.c58
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
46comment "Ash Shell Options"
47 depends on ASH
48
49config ASH_BASH_COMPAT 46config 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
169config HUSH_BASH_COMPAT
170 bool "bash-compatible extensions"
171 default y
172 depends on HUSH
173 help
174 Enable bash-compatible extensions.
175
172config HUSH_HELP 176config 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
271comment "Bourne Shell Options"
272 depends on MSH || LASH || HUSH || ASH
273
274config SH_MATH_SUPPORT 275config 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
2487static char **expand_strvec_to_strvec_singleword_noglob(char **argv) 2490static 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
2493static char **expand_strvec_to_strvec_singleword_noglob_cond(char **argv) 2497static 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) {