aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-07-28 00:01:16 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-07-28 00:01:16 +0000
commitbe709c24d40c2fb52d3f57faa25b9134c7d25270 (patch)
tree8a2d3d0281ab92d0d961c7a783e01ba501e8a418
parent8d523cbcd79c5428f1ea5bcbec6b7d9fd3756dc3 (diff)
downloadbusybox-w32-be709c24d40c2fb52d3f57faa25b9134c7d25270.tar.gz
busybox-w32-be709c24d40c2fb52d3f57faa25b9134c7d25270.tar.bz2
busybox-w32-be709c24d40c2fb52d3f57faa25b9134c7d25270.zip
hush: finish and enable optional case...esac support. Code size cost:
function old new delta run_list 1891 2075 +184 parse_stream 1764 1847 +83 expand_strvec_to_string - 83 +83 done_word 647 715 +68 static.reserved_list 144 168 +24 static.reserved_match - 12 +12 done_pipe 95 105 +10 builtin_exit 48 46 -2 builtin_eval 127 54 -73 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 5/2 up/down: 464/-75) Total: 389 bytes
-rw-r--r--shell/Config.in16
-rw-r--r--shell/hush.c36
-rw-r--r--shell/hush_test/hush-misc/case1.right13
-rwxr-xr-xshell/hush_test/hush-misc/case1.tests17
4 files changed, 69 insertions, 13 deletions
diff --git a/shell/Config.in b/shell/Config.in
index f4a9e7b1c..ee2f832fa 100644
--- a/shell/Config.in
+++ b/shell/Config.in
@@ -178,9 +178,11 @@ config HUSH
178 hush is a very small shell (just 18k) and it has fairly complete 178 hush is a very small shell (just 18k) and it has fairly complete
179 Bourne shell grammar. It even handles all the normal flow control 179 Bourne shell grammar. It even handles all the normal flow control
180 options such as if/then/elif/else/fi, for/in/do/done, while loops, 180 options such as if/then/elif/else/fi, for/in/do/done, while loops,
181 etc. 181 case/esac.
182 182
183 It does not handle case/esac, select, function, here documents ( << 183 It uses only vfork, so it can be used on uClinux systems.
184
185 It does not handle select, functions, here documents ( <<
184 word ), arithmetic expansion, aliases, brace expansion, tilde 186 word ), arithmetic expansion, aliases, brace expansion, tilde
185 expansion, &> and >& redirection of stdout+stderr, etc. 187 expansion, &> and >& redirection of stdout+stderr, etc.
186 188
@@ -232,6 +234,14 @@ config HUSH_LOOPS
232 depends on HUSH 234 depends on HUSH
233 help 235 help
234 Enable for, while and until loops in hush. 236 Enable for, while and until loops in hush.
237 As of 2008-07, break and continue statements are not supported.
238
239config HUSH_CASE
240 bool "Support case ... esac statement"
241 default n
242 depends on HUSH
243 help
244 Enable case ... esac statement in hush. +400 bytes.
235 245
236config LASH 246config LASH
237 bool "lash" 247 bool "lash"
@@ -249,7 +259,7 @@ config MSH
249 shell to do. It is not always pedantically correct about Bourne 259 shell to do. It is not always pedantically correct about Bourne
250 shell grammar (try running the shell testscript "tests/sh.testcases" 260 shell grammar (try running the shell testscript "tests/sh.testcases"
251 on it and compare vs bash) but for most things it works quite well. 261 on it and compare vs bash) but for most things it works quite well.
252 It also uses only vfork, so it can be used on uClinux systems. 262 It uses only vfork, so it can be used on uClinux systems.
253 263
254comment "Bourne Shell Options" 264comment "Bourne Shell Options"
255 depends on MSH || LASH || HUSH || ASH 265 depends on MSH || LASH || HUSH || ASH
diff --git a/shell/hush.c b/shell/hush.c
index cf6a18f86..5a565b392 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -67,14 +67,12 @@
67 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. 67 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
68 */ 68 */
69 69
70
71#include <glob.h> /* glob, of course */
72/* #include <dmalloc.h> */
73
74#include "busybox.h" /* for APPLET_IS_NOFORK/NOEXEC */ 70#include "busybox.h" /* for APPLET_IS_NOFORK/NOEXEC */
75 71#include <glob.h>
76// TEMP 72/* #include <dmalloc.h> */
77#define ENABLE_HUSH_CASE 0 73#if ENABLE_HUSH_CASE
74#include <fnmatch.h>
75#endif
78 76
79 77
80#if !BB_MMU && ENABLE_HUSH_TICK 78#if !BB_MMU && ENABLE_HUSH_TICK
@@ -2064,6 +2062,10 @@ static int run_list(struct pipe *pi)
2064 rpipe = NULL; 2062 rpipe = NULL;
2065#endif 2063#endif
2066 2064
2065 /* Past this point, all code paths should jump to ret: label
2066 * in order to return, no direct "return" statements.
2067 * This helps to ensure that no memory is leaked */
2068
2067#if ENABLE_HUSH_JOB 2069#if ENABLE_HUSH_JOB
2068 /* Example of nested list: "while true; do { sleep 1 | exit 2; } done". 2070 /* Example of nested list: "while true; do { sleep 1 | exit 2; } done".
2069 * We are saving state before entering outermost list ("while...done") 2071 * We are saving state before entering outermost list ("while...done")
@@ -2170,6 +2172,7 @@ static int run_list(struct pipe *pi)
2170 if (!*for_lcur) { 2172 if (!*for_lcur) {
2171 /* for loop is over, clean up */ 2173 /* for loop is over, clean up */
2172 free(for_list); 2174 free(for_list);
2175 for_list = NULL;
2173 for_lcur = NULL; 2176 for_lcur = NULL;
2174 flag_rep = 0; 2177 flag_rep = 0;
2175 pi->progs->argv[0] = for_varname; 2178 pi->progs->argv[0] = for_varname;
@@ -2195,14 +2198,21 @@ static int run_list(struct pipe *pi)
2195#endif 2198#endif
2196#if ENABLE_HUSH_CASE 2199#if ENABLE_HUSH_CASE
2197 if (rword == RES_CASE) { 2200 if (rword == RES_CASE) {
2198 case_word = pi->progs->argv[0]; 2201 case_word = expand_strvec_to_string(pi->progs->argv);
2202 //bb_error_msg("case: arg:'%s' case_word:'%s'", pi->progs->argv[0], case_word);
2199 continue; 2203 continue;
2200 } 2204 }
2201 if (rword == RES_MATCH) { 2205 if (rword == RES_MATCH) {
2202 if (case_word) { 2206 if (case_word) {
2203 next_if_code = strcmp(case_word, pi->progs->argv[0]); 2207 char *pattern = expand_strvec_to_string(pi->progs->argv);
2204 if (next_if_code == 0) 2208 /* TODO: which FNM_xxx flags to use? */
2209 next_if_code = fnmatch(pattern, case_word, /*flags:*/ 0);
2210 //bb_error_msg("fnmatch('%s','%s'):%d", pattern, case_word, next_if_code);
2211 free(pattern);
2212 if (next_if_code == 0) {
2213 free(case_word);
2205 case_word = NULL; 2214 case_word = NULL;
2215 }
2206 continue; 2216 continue;
2207 } 2217 }
2208 break; 2218 break;
@@ -2276,6 +2286,12 @@ static int run_list(struct pipe *pi)
2276 } 2286 }
2277#endif 2287#endif
2278 debug_printf_exec("run_list lvl %d return %d\n", run_list_level + 1, rcode); 2288 debug_printf_exec("run_list lvl %d return %d\n", run_list_level + 1, rcode);
2289#if ENABLE_HUSH_LOOPS
2290 free(for_list);
2291#endif
2292#if ENABLE_HUSH_CASE
2293 free(case_word);
2294#endif
2279 return rcode; 2295 return rcode;
2280} 2296}
2281 2297
diff --git a/shell/hush_test/hush-misc/case1.right b/shell/hush_test/hush-misc/case1.right
new file mode 100644
index 000000000..9b88658af
--- /dev/null
+++ b/shell/hush_test/hush-misc/case1.right
@@ -0,0 +1,13 @@
1OK_1
2OK_21
3OK_22
4OK_23
5OK_31
6OK_32
7OK_41
8OK_42
9OK_43
10OK_44
11OK_51
12OK_52
13OK_53
diff --git a/shell/hush_test/hush-misc/case1.tests b/shell/hush_test/hush-misc/case1.tests
new file mode 100755
index 000000000..15f60f3a6
--- /dev/null
+++ b/shell/hush_test/hush-misc/case1.tests
@@ -0,0 +1,17 @@
1case w in a) echo SKIP;; w) echo OK_1;; w) echo WRONG;; esac
2
3t=w
4case $t in a) echo SKIP;; w) echo OK_21;; w) echo WRONG;; esac;
5case "$t" in a) echo SKIP;; w) echo OK_22;; w) echo WRONG;; esac;
6case w in a) echo SKIP;; $t) echo OK_23;; "$t") echo WRONG;; esac;
7
8case '' in a) echo SKIP;; w) echo WRONG;; *) echo OK_31;; esac;
9case '' in a) echo SKIP;; '') echo OK_32;; *) echo WRONG;; esac;
10
11case `echo w` in a) echo SKIP;; w) echo OK_41;; w) echo WRONG;; esac;
12case "`echo w`" in a) echo SKIP;; w) echo OK_42;; w) echo WRONG;; esac;
13case `echo w w` in a) echo SKIP;; w) echo WRONG;; 'w w') echo OK_43;; esac;
14case `echo w w` in a) echo SKIP;; w) echo WRONG;; w*) echo OK_44;; esac;
15
16case w in `echo w`) echo OK_51;; `echo WRONG >&2`w) echo WRONG;; esac;
17case w in `echo OK_52 >&2`) echo SKIP;; `echo`w) echo OK_53;; esac;