diff options
author | Ron Yorston <rmy@pobox.com> | 2015-11-06 16:38:39 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2015-11-06 16:38:39 +0000 |
commit | d6c9296168ad0a770967714515ffa1fca5e60145 (patch) | |
tree | d72556385814a18a0ac039ee0b43ef6f561c317f /shell | |
parent | b60a9b30ba420808c4c9f540dcf92b11ee87a87b (diff) | |
parent | 196e400441652946b9c7ad7bc2d78c73885f2359 (diff) | |
download | busybox-w32-d6c9296168ad0a770967714515ffa1fca5e60145.tar.gz busybox-w32-d6c9296168ad0a770967714515ffa1fca5e60145.tar.bz2 busybox-w32-d6c9296168ad0a770967714515ffa1fca5e60145.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 101 | ||||
-rw-r--r-- | shell/ash_test/ash-misc/func1.right | 6 | ||||
-rwxr-xr-x | shell/ash_test/ash-misc/func1.tests | 16 | ||||
-rw-r--r-- | shell/ash_test/ash-misc/func2.right | 5 | ||||
-rwxr-xr-x | shell/ash_test/ash-misc/func2.tests | 9 | ||||
-rw-r--r-- | shell/ash_test/ash-misc/func3.right | 4 | ||||
-rwxr-xr-x | shell/ash_test/ash-misc/func3.tests | 8 | ||||
-rw-r--r-- | shell/ash_test/ash-misc/func4.right | 2 | ||||
-rwxr-xr-x | shell/ash_test/ash-misc/func4.tests | 7 | ||||
-rw-r--r-- | shell/ash_test/ash-misc/func5.right | 6 | ||||
-rwxr-xr-x | shell/ash_test/ash-misc/func5.tests | 13 | ||||
-rw-r--r-- | shell/ash_test/ash-misc/func_args1.right | 5 | ||||
-rwxr-xr-x | shell/ash_test/ash-misc/func_args1.tests | 8 | ||||
-rw-r--r-- | shell/ash_test/ash-misc/func_bash1.right | 12 | ||||
-rwxr-xr-x | shell/ash_test/ash-misc/func_bash1.tests | 28 | ||||
-rw-r--r-- | shell/ash_test/ash-misc/func_local1.right | 3 | ||||
-rwxr-xr-x | shell/ash_test/ash-misc/func_local1.tests | 5 | ||||
-rw-r--r-- | shell/ash_test/ash-misc/func_local2.right | 14 | ||||
-rwxr-xr-x | shell/ash_test/ash-misc/func_local2.tests | 7 | ||||
-rwxr-xr-x | shell/hush_test/hush-misc/func_args1.tests | 2 |
20 files changed, 228 insertions, 33 deletions
diff --git a/shell/ash.c b/shell/ash.c index 08b6aa430..de5c44ead 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -8073,36 +8073,40 @@ changepath(const char *new) | |||
8073 | clearcmdentry(firstchange); | 8073 | clearcmdentry(firstchange); |
8074 | builtinloc = idx_bltin; | 8074 | builtinloc = idx_bltin; |
8075 | } | 8075 | } |
8076 | 8076 | enum { | |
8077 | #define TEOF 0 | 8077 | TEOF, |
8078 | #define TNL 1 | 8078 | TNL, |
8079 | #define TREDIR 2 | 8079 | TREDIR, |
8080 | #define TWORD 3 | 8080 | TWORD, |
8081 | #define TSEMI 4 | 8081 | TSEMI, |
8082 | #define TBACKGND 5 | 8082 | TBACKGND, |
8083 | #define TAND 6 | 8083 | TAND, |
8084 | #define TOR 7 | 8084 | TOR, |
8085 | #define TPIPE 8 | 8085 | TPIPE, |
8086 | #define TLP 9 | 8086 | TLP, |
8087 | #define TRP 10 | 8087 | TRP, |
8088 | #define TENDCASE 11 | 8088 | TENDCASE, |
8089 | #define TENDBQUOTE 12 | 8089 | TENDBQUOTE, |
8090 | #define TNOT 13 | 8090 | TNOT, |
8091 | #define TCASE 14 | 8091 | TCASE, |
8092 | #define TDO 15 | 8092 | TDO, |
8093 | #define TDONE 16 | 8093 | TDONE, |
8094 | #define TELIF 17 | 8094 | TELIF, |
8095 | #define TELSE 18 | 8095 | TELSE, |
8096 | #define TESAC 19 | 8096 | TESAC, |
8097 | #define TFI 20 | 8097 | TFI, |
8098 | #define TFOR 21 | 8098 | TFOR, |
8099 | #define TIF 22 | 8099 | #if ENABLE_ASH_BASH_COMPAT |
8100 | #define TIN 23 | 8100 | TFUNCTION, |
8101 | #define TTHEN 24 | 8101 | #endif |
8102 | #define TUNTIL 25 | 8102 | TIF, |
8103 | #define TWHILE 26 | 8103 | TIN, |
8104 | #define TBEGIN 27 | 8104 | TTHEN, |
8105 | #define TEND 28 | 8105 | TUNTIL, |
8106 | TWHILE, | ||
8107 | TBEGIN, | ||
8108 | TEND | ||
8109 | }; | ||
8106 | typedef smallint token_id_t; | 8110 | typedef smallint token_id_t; |
8107 | 8111 | ||
8108 | /* first char is indicating which tokens mark the end of a list */ | 8112 | /* first char is indicating which tokens mark the end of a list */ |
@@ -8131,6 +8135,9 @@ static const char *const tokname_array[] = { | |||
8131 | "\1esac", | 8135 | "\1esac", |
8132 | "\1fi", | 8136 | "\1fi", |
8133 | "\0for", | 8137 | "\0for", |
8138 | #if ENABLE_ASH_BASH_COMPAT | ||
8139 | "\0function", | ||
8140 | #endif | ||
8134 | "\0if", | 8141 | "\0if", |
8135 | "\0in", | 8142 | "\0in", |
8136 | "\1then", | 8143 | "\1then", |
@@ -11205,6 +11212,7 @@ simplecmd(void) | |||
11205 | int savecheckkwd; | 11212 | int savecheckkwd; |
11206 | #if ENABLE_ASH_BASH_COMPAT | 11213 | #if ENABLE_ASH_BASH_COMPAT |
11207 | smallint double_brackets_flag = 0; | 11214 | smallint double_brackets_flag = 0; |
11215 | smallint function_flag = 0; | ||
11208 | #endif | 11216 | #endif |
11209 | 11217 | ||
11210 | args = NULL; | 11218 | args = NULL; |
@@ -11221,6 +11229,11 @@ simplecmd(void) | |||
11221 | t = readtoken(); | 11229 | t = readtoken(); |
11222 | switch (t) { | 11230 | switch (t) { |
11223 | #if ENABLE_ASH_BASH_COMPAT | 11231 | #if ENABLE_ASH_BASH_COMPAT |
11232 | case TFUNCTION: | ||
11233 | if (peektoken() != TWORD) | ||
11234 | raise_error_unexpected_syntax(TWORD); | ||
11235 | function_flag = 1; | ||
11236 | break; | ||
11224 | case TAND: /* "&&" */ | 11237 | case TAND: /* "&&" */ |
11225 | case TOR: /* "||" */ | 11238 | case TOR: /* "||" */ |
11226 | if (!double_brackets_flag) { | 11239 | if (!double_brackets_flag) { |
@@ -11249,6 +11262,29 @@ simplecmd(void) | |||
11249 | app = &n->narg.next; | 11262 | app = &n->narg.next; |
11250 | savecheckkwd = 0; | 11263 | savecheckkwd = 0; |
11251 | } | 11264 | } |
11265 | #if ENABLE_ASH_BASH_COMPAT | ||
11266 | if (function_flag) { | ||
11267 | checkkwd = CHKNL | CHKKWD; | ||
11268 | switch (peektoken()) { | ||
11269 | case TBEGIN: | ||
11270 | case TIF: | ||
11271 | case TCASE: | ||
11272 | case TUNTIL: | ||
11273 | case TWHILE: | ||
11274 | case TFOR: | ||
11275 | goto do_func; | ||
11276 | case TLP: | ||
11277 | function_flag = 0; | ||
11278 | break; | ||
11279 | case TWORD: | ||
11280 | if (strcmp("[[", wordtext) == 0) | ||
11281 | goto do_func; | ||
11282 | /* fall through */ | ||
11283 | default: | ||
11284 | raise_error_unexpected_syntax(-1); | ||
11285 | } | ||
11286 | } | ||
11287 | #endif | ||
11252 | break; | 11288 | break; |
11253 | case TREDIR: | 11289 | case TREDIR: |
11254 | *rpp = n = redirnode; | 11290 | *rpp = n = redirnode; |
@@ -11256,6 +11292,7 @@ simplecmd(void) | |||
11256 | parsefname(); /* read name of redirection file */ | 11292 | parsefname(); /* read name of redirection file */ |
11257 | break; | 11293 | break; |
11258 | case TLP: | 11294 | case TLP: |
11295 | IF_ASH_BASH_COMPAT(do_func:) | ||
11259 | if (args && app == &args->narg.next | 11296 | if (args && app == &args->narg.next |
11260 | && !vars && !redir | 11297 | && !vars && !redir |
11261 | ) { | 11298 | ) { |
@@ -11263,7 +11300,7 @@ simplecmd(void) | |||
11263 | const char *name; | 11300 | const char *name; |
11264 | 11301 | ||
11265 | /* We have a function */ | 11302 | /* We have a function */ |
11266 | if (readtoken() != TRP) | 11303 | if (IF_ASH_BASH_COMPAT(!function_flag &&) readtoken() != TRP) |
11267 | raise_error_unexpected_syntax(TRP); | 11304 | raise_error_unexpected_syntax(TRP); |
11268 | name = n->narg.text; | 11305 | name = n->narg.text; |
11269 | if (!goodname(name) | 11306 | if (!goodname(name) |
@@ -11276,6 +11313,7 @@ simplecmd(void) | |||
11276 | n->narg.next = parse_command(); | 11313 | n->narg.next = parse_command(); |
11277 | return n; | 11314 | return n; |
11278 | } | 11315 | } |
11316 | IF_ASH_BASH_COMPAT(function_flag = 0;) | ||
11279 | /* fall through */ | 11317 | /* fall through */ |
11280 | default: | 11318 | default: |
11281 | tokpushback = 1; | 11319 | tokpushback = 1; |
@@ -11456,6 +11494,7 @@ parse_command(void) | |||
11456 | n1 = list(0); | 11494 | n1 = list(0); |
11457 | t = TEND; | 11495 | t = TEND; |
11458 | break; | 11496 | break; |
11497 | IF_ASH_BASH_COMPAT(case TFUNCTION:) | ||
11459 | case TWORD: | 11498 | case TWORD: |
11460 | case TREDIR: | 11499 | case TREDIR: |
11461 | tokpushback = 1; | 11500 | tokpushback = 1; |
diff --git a/shell/ash_test/ash-misc/func1.right b/shell/ash_test/ash-misc/func1.right new file mode 100644 index 000000000..e21665aaf --- /dev/null +++ b/shell/ash_test/ash-misc/func1.right | |||
@@ -0,0 +1,6 @@ | |||
1 | Hello | ||
2 | Zero: 0 | ||
3 | One: 1 Param1: World | ||
4 | Zero: 0 Param1: Restored | ||
5 | Multi line function | ||
6 | One: 1 | ||
diff --git a/shell/ash_test/ash-misc/func1.tests b/shell/ash_test/ash-misc/func1.tests new file mode 100755 index 000000000..ffb269fad --- /dev/null +++ b/shell/ash_test/ash-misc/func1.tests | |||
@@ -0,0 +1,16 @@ | |||
1 | f() { echo Hello; } | ||
2 | g () { echo One: $# Param1: $1; } | ||
3 | h ( ) | ||
4 | { | ||
5 | echo -n 'Multi ' && echo -n 'line ' | ||
6 | echo function | ||
7 | false | ||
8 | } | ||
9 | |||
10 | f | ||
11 | echo Zero: $? | ||
12 | set -- Restored | ||
13 | { g World; } | ||
14 | echo Zero: $? Param1: $1 | ||
15 | ( h ) | ||
16 | echo One: $? | ||
diff --git a/shell/ash_test/ash-misc/func2.right b/shell/ash_test/ash-misc/func2.right new file mode 100644 index 000000000..f2a041da7 --- /dev/null +++ b/shell/ash_test/ash-misc/func2.right | |||
@@ -0,0 +1,5 @@ | |||
1 | First 0 | ||
2 | Second 0 | ||
3 | First 1 | ||
4 | Second 1 | ||
5 | Done | ||
diff --git a/shell/ash_test/ash-misc/func2.tests b/shell/ash_test/ash-misc/func2.tests new file mode 100755 index 000000000..763203f15 --- /dev/null +++ b/shell/ash_test/ash-misc/func2.tests | |||
@@ -0,0 +1,9 @@ | |||
1 | i=0 | ||
2 | while test $i != 2; do | ||
3 | f() { echo First $i; } | ||
4 | f | ||
5 | f() { echo Second $i; } | ||
6 | f | ||
7 | : $((i++)) | ||
8 | done | ||
9 | echo Done | ||
diff --git a/shell/ash_test/ash-misc/func3.right b/shell/ash_test/ash-misc/func3.right new file mode 100644 index 000000000..b6d73459a --- /dev/null +++ b/shell/ash_test/ash-misc/func3.right | |||
@@ -0,0 +1,4 @@ | |||
1 | One:1 | ||
2 | Zero:0 | ||
3 | One:1 | ||
4 | Five:5 | ||
diff --git a/shell/ash_test/ash-misc/func3.tests b/shell/ash_test/ash-misc/func3.tests new file mode 100755 index 000000000..fa6f26a23 --- /dev/null +++ b/shell/ash_test/ash-misc/func3.tests | |||
@@ -0,0 +1,8 @@ | |||
1 | f() { false; return; echo BAD; }; | ||
2 | { f; echo One:$?; }; echo Zero:$? | ||
3 | |||
4 | f() { false; return; }; | ||
5 | f; echo One:$? | ||
6 | |||
7 | f() { return 5; }; | ||
8 | f; echo Five:$? | ||
diff --git a/shell/ash_test/ash-misc/func4.right b/shell/ash_test/ash-misc/func4.right new file mode 100644 index 000000000..0c87e316a --- /dev/null +++ b/shell/ash_test/ash-misc/func4.right | |||
@@ -0,0 +1,2 @@ | |||
1 | 24 | ||
2 | Done | ||
diff --git a/shell/ash_test/ash-misc/func4.tests b/shell/ash_test/ash-misc/func4.tests new file mode 100755 index 000000000..74c1b9a46 --- /dev/null +++ b/shell/ash_test/ash-misc/func4.tests | |||
@@ -0,0 +1,7 @@ | |||
1 | func() { | ||
2 | eval "echo \"\${val_${1}}\"" | ||
3 | } | ||
4 | |||
5 | val_x=24 | ||
6 | (func x) | ||
7 | echo Done | ||
diff --git a/shell/ash_test/ash-misc/func5.right b/shell/ash_test/ash-misc/func5.right new file mode 100644 index 000000000..2c9d316b3 --- /dev/null +++ b/shell/ash_test/ash-misc/func5.right | |||
@@ -0,0 +1,6 @@ | |||
1 | 1 | ||
2 | 2 | ||
3 | 3 | ||
4 | 1 | ||
5 | 2 | ||
6 | 3 | ||
diff --git a/shell/ash_test/ash-misc/func5.tests b/shell/ash_test/ash-misc/func5.tests new file mode 100755 index 000000000..e967208cc --- /dev/null +++ b/shell/ash_test/ash-misc/func5.tests | |||
@@ -0,0 +1,13 @@ | |||
1 | f() { echo $1; } | ||
2 | f 1 | ||
3 | |||
4 | f() ( echo $1; ) | ||
5 | f 2 | ||
6 | |||
7 | f() ( echo $1 ) | ||
8 | f 3 | ||
9 | |||
10 | f() for i in 1 2 3; do | ||
11 | echo $i | ||
12 | done | ||
13 | f | ||
diff --git a/shell/ash_test/ash-misc/func_args1.right b/shell/ash_test/ash-misc/func_args1.right new file mode 100644 index 000000000..2dfb9629b --- /dev/null +++ b/shell/ash_test/ash-misc/func_args1.right | |||
@@ -0,0 +1,5 @@ | |||
1 | params: a b c | ||
2 | 'f 1 2 3' called | ||
3 | params: a b c | ||
4 | 'f 1 2 3' called | ||
5 | params: a b c | ||
diff --git a/shell/ash_test/ash-misc/func_args1.tests b/shell/ash_test/ash-misc/func_args1.tests new file mode 100755 index 000000000..d394c637f --- /dev/null +++ b/shell/ash_test/ash-misc/func_args1.tests | |||
@@ -0,0 +1,8 @@ | |||
1 | f() { echo "'f $1 $2 $3' called"; } | ||
2 | |||
3 | set -- a b c | ||
4 | echo "params: $1 $2 $3" | ||
5 | f 1 2 3 | ||
6 | echo "params: $1 $2 $3" | ||
7 | true | f 1 2 3 | ||
8 | echo "params: $1 $2 $3" | ||
diff --git a/shell/ash_test/ash-misc/func_bash1.right b/shell/ash_test/ash-misc/func_bash1.right new file mode 100644 index 000000000..41bf8828c --- /dev/null +++ b/shell/ash_test/ash-misc/func_bash1.right | |||
@@ -0,0 +1,12 @@ | |||
1 | 1 | ||
2 | 2 | ||
3 | 3 | ||
4 | 1 | ||
5 | 2 | ||
6 | 3 | ||
7 | 1 | ||
8 | 2 | ||
9 | 3 | ||
10 | 1 | ||
11 | 2 | ||
12 | 3 | ||
diff --git a/shell/ash_test/ash-misc/func_bash1.tests b/shell/ash_test/ash-misc/func_bash1.tests new file mode 100755 index 000000000..2cc0970e8 --- /dev/null +++ b/shell/ash_test/ash-misc/func_bash1.tests | |||
@@ -0,0 +1,28 @@ | |||
1 | function f() { echo $1; } | ||
2 | f 1 | ||
3 | |||
4 | function f() ( echo $1; ) | ||
5 | f 2 | ||
6 | |||
7 | function f() ( echo $1 ) | ||
8 | f 3 | ||
9 | |||
10 | function f() for i in 1 2 3; do | ||
11 | echo $i | ||
12 | done | ||
13 | f | ||
14 | |||
15 | function f { echo $1; } | ||
16 | f 1 | ||
17 | |||
18 | # the next two don't work | ||
19 | #function f ( echo $1; ) | ||
20 | f 2 | ||
21 | |||
22 | #function f ( echo $1 ) | ||
23 | f 3 | ||
24 | |||
25 | function f for i in 1 2 3; do | ||
26 | echo $i | ||
27 | done | ||
28 | f | ||
diff --git a/shell/ash_test/ash-misc/func_local1.right b/shell/ash_test/ash-misc/func_local1.right new file mode 100644 index 000000000..312178366 --- /dev/null +++ b/shell/ash_test/ash-misc/func_local1.right | |||
@@ -0,0 +1,3 @@ | |||
1 | z=a | ||
2 | z=z | ||
3 | Done | ||
diff --git a/shell/ash_test/ash-misc/func_local1.tests b/shell/ash_test/ash-misc/func_local1.tests new file mode 100755 index 000000000..1d594e20c --- /dev/null +++ b/shell/ash_test/ash-misc/func_local1.tests | |||
@@ -0,0 +1,5 @@ | |||
1 | export z=z | ||
2 | f() { local z=a; env | grep ^z; } | ||
3 | f | ||
4 | env | grep ^z | ||
5 | echo Done | ||
diff --git a/shell/ash_test/ash-misc/func_local2.right b/shell/ash_test/ash-misc/func_local2.right new file mode 100644 index 000000000..fe9343ac8 --- /dev/null +++ b/shell/ash_test/ash-misc/func_local2.right | |||
@@ -0,0 +1,14 @@ | |||
1 | 1 | ||
2 | 2 | ||
3 | 1 | ||
4 | 2 | ||
5 | 1 | ||
6 | 1 | ||
7 | 2 | ||
8 | 2 | ||
9 | 3 | ||
10 | 2 | ||
11 | 2 | ||
12 | 3 | ||
13 | 1 | ||
14 | Done | ||
diff --git a/shell/ash_test/ash-misc/func_local2.tests b/shell/ash_test/ash-misc/func_local2.tests new file mode 100755 index 000000000..1a9ae559d --- /dev/null +++ b/shell/ash_test/ash-misc/func_local2.tests | |||
@@ -0,0 +1,7 @@ | |||
1 | x=1 | ||
2 | f() { echo $x; local x=$((x+1)); echo $x; } | ||
3 | g() { f; echo $x; f; local x=$((x+1)); f; echo $x; f; } | ||
4 | f | ||
5 | g | ||
6 | echo $x | ||
7 | echo Done | ||
diff --git a/shell/hush_test/hush-misc/func_args1.tests b/shell/hush_test/hush-misc/func_args1.tests index 157921fb1..d394c637f 100755 --- a/shell/hush_test/hush-misc/func_args1.tests +++ b/shell/hush_test/hush-misc/func_args1.tests | |||
@@ -1,5 +1,3 @@ | |||
1 | # UNFIXED BUG | ||
2 | |||
3 | f() { echo "'f $1 $2 $3' called"; } | 1 | f() { echo "'f $1 $2 $3' called"; } |
4 | 2 | ||
5 | set -- a b c | 3 | set -- a b c |