aboutsummaryrefslogtreecommitdiff
path: root/shell/hush.c
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 /shell/hush.c
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>
Diffstat (limited to 'shell/hush.c')
-rw-r--r--shell/hush.c58
1 files changed, 34 insertions, 24 deletions
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) {