aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-05-22 00:26:06 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-05-22 00:26:06 +0200
commita6ad397ea92cd9c53973243728d3e52640fe63ec (patch)
tree058f34aaf8877c15a1c667efaa491267f046c7e7
parent7436950a7516d1f4498285ccc81bf6d926f3af5e (diff)
downloadbusybox-w32-a6ad397ea92cd9c53973243728d3e52640fe63ec.tar.gz
busybox-w32-a6ad397ea92cd9c53973243728d3e52640fe63ec.tar.bz2
busybox-w32-a6ad397ea92cd9c53973243728d3e52640fe63ec.zip
hush: fix more obscure ${var%...} cases
function old new delta add_till_closing_paren 313 359 +46 builtin_exit 48 47 -1 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/hush.c39
-rw-r--r--shell/hush_test/hush-arith/arith.right9
-rwxr-xr-xshell/hush_test/hush-arith/arith.tests19
-rw-r--r--shell/hush_test/hush-vars/var_posix1.right1
-rwxr-xr-xshell/hush_test/hush-vars/var_posix1.tests1
5 files changed, 45 insertions, 24 deletions
diff --git a/shell/hush.c b/shell/hush.c
index a3df5edcd..32b90876f 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -45,6 +45,8 @@
45 * follow IFS rules more precisely, including update semantics 45 * follow IFS rules more precisely, including update semantics
46 * builtins mandated by standards we don't support: 46 * builtins mandated by standards we don't support:
47 * [un]alias, command, fc, getopts, newgrp, readonly, times 47 * [un]alias, command, fc, getopts, newgrp, readonly, times
48 * make complex ${var%...} constructs support optional
49 * make here documents optional
48 * 50 *
49 * Bash compat TODO: 51 * Bash compat TODO:
50 * redirection of stdout+stderr: &> and >& 52 * redirection of stdout+stderr: &> and >&
@@ -5887,36 +5889,36 @@ static void add_till_backquote(o_string *dest, struct in_str *input)
5887 * echo $(echo 'TEST)' BEST) TEST) BEST 5889 * echo $(echo 'TEST)' BEST) TEST) BEST
5888 * echo $(echo \(\(TEST\) BEST) ((TEST) BEST 5890 * echo $(echo \(\(TEST\) BEST) ((TEST) BEST
5889 * 5891 *
5890 * BUG: enter: echo $(( `printf '(\x28 1'` + `echo 2))` )) 5892 * Also adapted to eat ${var%...} constructs, since ... part
5891 * on the command line, press Enter. You get > prompt which is impossible 5893 * can contain arbitrary constructs, just like $(cmd).
5892 * to exit with ^C.
5893 */ 5894 */
5894#define DOUBLE_CLOSE_CHAR_FLAG 0x80 5895#define DOUBLE_CLOSE_CHAR_FLAG 0x80
5895static void add_till_closing_paren(o_string *dest, struct in_str *input, char end_ch) 5896static void add_till_closing_paren(o_string *dest, struct in_str *input, char end_ch)
5896{ 5897{
5897 int count = 0;
5898 char dbl = end_ch & DOUBLE_CLOSE_CHAR_FLAG; 5898 char dbl = end_ch & DOUBLE_CLOSE_CHAR_FLAG;
5899 end_ch &= (DOUBLE_CLOSE_CHAR_FLAG-1); 5899 end_ch &= (DOUBLE_CLOSE_CHAR_FLAG-1);
5900 while (1) { 5900 while (1) {
5901 int ch = i_getch(input); 5901 int ch = i_getch(input);
5902 if (ch == EOF) { 5902 if (ch == EOF) {
5903 syntax_error_unterm_ch(')'); 5903 syntax_error_unterm_ch(end_ch);
5904 /*xfunc_die(); - redundant */ 5904 /*xfunc_die(); - redundant */
5905 } 5905 }
5906 if (ch == '(' || ch == '{') 5906 if (ch == end_ch) {
5907 count++; 5907 if (!dbl)
5908 if (ch == ')' || ch == '}') { 5908 break;
5909 count--; 5909 /* we look for closing )) of $((EXPR)) */
5910 if (count < 0 && ch == end_ch) { 5910 if (i_peek(input) == end_ch) {
5911 if (!dbl) 5911 i_getch(input); /* eat second ')' */
5912 break; 5912 break;
5913 if (i_peek(input) == ')') {
5914 i_getch(input);
5915 break;
5916 }
5917 } 5913 }
5918 } 5914 }
5919 o_addchr(dest, ch); 5915 o_addchr(dest, ch);
5916 if (ch == '(' || ch == '{') {
5917 ch = (ch == '(' ? ')' : '}');
5918 add_till_closing_paren(dest, input, ch);
5919 o_addchr(dest, ch);
5920 continue;
5921 }
5920 if (ch == '\'') { 5922 if (ch == '\'') {
5921 add_till_single_quote(dest, input); 5923 add_till_single_quote(dest, input);
5922 o_addchr(dest, ch); 5924 o_addchr(dest, ch);
@@ -5927,6 +5929,11 @@ static void add_till_closing_paren(o_string *dest, struct in_str *input, char en
5927 o_addchr(dest, ch); 5929 o_addchr(dest, ch);
5928 continue; 5930 continue;
5929 } 5931 }
5932 if (ch == '`') {
5933 add_till_backquote(dest, input);
5934 o_addchr(dest, ch);
5935 continue;
5936 }
5930 if (ch == '\\') { 5937 if (ch == '\\') {
5931 /* \x. Copy verbatim. Important for \(, \) */ 5938 /* \x. Copy verbatim. Important for \(, \) */
5932 ch = i_getch(input); 5939 ch = i_getch(input);
diff --git a/shell/hush_test/hush-arith/arith.right b/shell/hush_test/hush-arith/arith.right
index 83155fb03..718c26ad0 100644
--- a/shell/hush_test/hush-arith/arith.right
+++ b/shell/hush_test/hush-arith/arith.right
@@ -43,21 +43,30 @@ Format: 'expected actual'
434 4 434 4
4429 29 4429 29
455 5 455 5
46unary plus, minus
46-4 -4 47-4 -4
474 4 484 4
49conditional expressions
481 1 501 1
4932 32 5132 32
5032 32 5232 32
511 1 531 1
521 1 541 1
5332 32 5532 32
56check that parentheses in `cmd` are interpreted correctly
573 3
58check that the unevaluated part of the ternary operator does not do evaluation or assignment
5420 20 5920 20
5530 30 6030 30
5620 20 6120 20
5730 30 6230 30
63check precedence of assignment vs. conditional operator
58hush: error in arithmetic 64hush: error in arithmetic
65check precedence of assignment vs. conditional operator
66associativity of assignment-operator operator
596 6 676 6
606,5,3 6,5,3 686,5,3 6,5,3
69octal, hex
61263 263 70263 263
62255 255 71255 255
6340 40 7240 40
diff --git a/shell/hush_test/hush-arith/arith.tests b/shell/hush_test/hush-arith/arith.tests
index 57e66e888..bc6b341d1 100755
--- a/shell/hush_test/hush-arith/arith.tests
+++ b/shell/hush_test/hush-arith/arith.tests
@@ -75,11 +75,11 @@ echo 4 $(( iv &= 4 ))
75echo 29 $(( iv += (jv + 9))) 75echo 29 $(( iv += (jv + 9)))
76echo 5 $(( (iv + 4) % 7 )) 76echo 5 $(( (iv + 4) % 7 ))
77 77
78# unary plus, minus 78echo unary plus, minus
79echo -4 $(( +4 - 8 )) 79echo -4 $(( +4 - 8 ))
80echo 4 $(( -4 + 8 )) 80echo 4 $(( -4 + 8 ))
81 81
82# conditional expressions 82echo conditional expressions
83echo 1 $(( 4<5 ? 1 : 32)) 83echo 1 $(( 4<5 ? 1 : 32))
84echo 32 $(( 4>5 ? 1 : 32)) 84echo 32 $(( 4>5 ? 1 : 32))
85echo 32 $(( 4>(2+3) ? 1 : 32)) 85echo 32 $(( 4>(2+3) ? 1 : 32))
@@ -87,8 +87,11 @@ echo 1 $(( 4<(2+3) ? 1 : 32))
87echo 1 $(( (2+2)<(2+3) ? 1 : 32)) 87echo 1 $(( (2+2)<(2+3) ? 1 : 32))
88echo 32 $(( (2+2)>(2+3) ? 1 : 32)) 88echo 32 $(( (2+2)>(2+3) ? 1 : 32))
89 89
90# check that the unevaluated part of the ternary operator does not do 90echo 'check that parentheses in `cmd` are interpreted correctly'
91# evaluation or assignment 91# \x28 is '('
92echo 3 $(( ( `printf '(\x28 1'` + `echo 2\)\)` ) ))
93
94echo check that the unevaluated part of the ternary operator does not do evaluation or assignment
92x=i+=2 95x=i+=2
93y=j+=2 96y=j+=2
94#ash# declare -i i=1 j=1 97#ash# declare -i i=1 j=1
@@ -109,20 +112,20 @@ echo 20 $((1 ? 20 : (x+=2)))
109echo 30 $((0 ? (y+=2) : 30)) 112echo 30 $((0 ? (y+=2) : 30))
110#ash# echo $i,$y # ash mishandles this 113#ash# echo $i,$y # ash mishandles this
111 114
112# check precedence of assignment vs. conditional operator 115echo check precedence of assignment vs. conditional operator
113# should be an error 116# should be an error
114#ash# declare -i x=2 117#ash# declare -i x=2
115 x=2 118 x=2
116#ashnote# bash reports error but continues, ash aborts - using subshell to 'emulate' bash: 119#ashnote# bash reports error but continues, ash aborts - using subshell to 'emulate' bash:
117( y=$((1 ? 20 : x+=2)) ) 120( y=$((1 ? 20 : x+=2)) )
118 121
119# check precedence of assignment vs. conditional operator 122echo check precedence of assignment vs. conditional operator
120#ash# declare -i x=2 123#ash# declare -i x=2
121 x=2 124 x=2
122# ash says "line NNN: syntax error: 0 ? x+=2 : 20" 125# ash says "line NNN: syntax error: 0 ? x+=2 : 20"
123#ash# echo 20 $((0 ? x+=2 : 20)) 126#ash# echo 20 $((0 ? x+=2 : 20))
124 127
125# associativity of assignment-operator operator 128echo associativity of assignment-operator operator
126#ash# declare -i i=1 j=2 k=3 129#ash# declare -i i=1 j=2 k=3
127i=1 130i=1
128j=2 131j=2
@@ -130,7 +133,7 @@ k=3
130echo 6 $((i += j += k)) 133echo 6 $((i += j += k))
131echo 6,5,3 $i,$j,$k 134echo 6,5,3 $i,$j,$k
132 135
133# octal, hex 136echo octal, hex
134echo 263 $(( 0x100 | 007 )) 137echo 263 $(( 0x100 | 007 ))
135echo 255 $(( 0xff )) 138echo 255 $(( 0xff ))
136#ash# echo 255 $(( 16#ff )) 139#ash# echo 255 $(( 16#ff ))
diff --git a/shell/hush_test/hush-vars/var_posix1.right b/shell/hush_test/hush-vars/var_posix1.right
index 813437e2f..7ff618ad0 100644
--- a/shell/hush_test/hush-vars/var_posix1.right
+++ b/shell/hush_test/hush-vars/var_posix1.right
@@ -37,4 +37,5 @@ ababcdcd_tail
37ababcdcd 37ababcdcd
38ab 38ab
39ab 39ab
40ab
40End 41End
diff --git a/shell/hush_test/hush-vars/var_posix1.tests b/shell/hush_test/hush-vars/var_posix1.tests
index e48fd98c7..82abe8198 100755
--- a/shell/hush_test/hush-vars/var_posix1.tests
+++ b/shell/hush_test/hush-vars/var_posix1.tests
@@ -47,5 +47,6 @@ echo ${var%\\*}
47 47
48a=ab}; echo ${a%\}}; 48a=ab}; echo ${a%\}};
49a=abc; c=c; echo ${a%${c}} 49a=abc; c=c; echo ${a%${c}}
50a=ab{{c; echo ${a%`echo {{c`}
50 51
51echo End 52echo End