aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-01-28 20:13:33 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-01-28 20:13:33 +0100
commitf19e3c1c6c96e3c709ac732ff70c586521f792d3 (patch)
treef2b16759f1eae8ac09205f0fb29f822d70610a36
parent675d24aeaff29dbce6dc116a4b7c9f6026ed5069 (diff)
downloadbusybox-w32-f19e3c1c6c96e3c709ac732ff70c586521f792d3.tar.gz
busybox-w32-f19e3c1c6c96e3c709ac732ff70c586521f792d3.tar.bz2
busybox-w32-f19e3c1c6c96e3c709ac732ff70c586521f792d3.zip
shell: handle $((NUM++...) like bash does. Closes 10706
function old new delta evaluate_string 680 729 +49 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/ash_test/ash-arith/arith-postinc.right5
-rwxr-xr-xshell/ash_test/ash-arith/arith-postinc.tests5
-rw-r--r--shell/ash_test/ash-arith/arith.right4
-rwxr-xr-xshell/ash_test/ash-arith/arith2.sub12
-rw-r--r--shell/hush_test/hush-arith/arith-postinc.right5
-rwxr-xr-xshell/hush_test/hush-arith/arith-postinc.tests5
-rw-r--r--shell/hush_test/hush-arith/arith.right4
-rwxr-xr-xshell/hush_test/hush-arith/arith2.sub12
-rw-r--r--shell/math.c19
9 files changed, 57 insertions, 14 deletions
diff --git a/shell/ash_test/ash-arith/arith-postinc.right b/shell/ash_test/ash-arith/arith-postinc.right
new file mode 100644
index 000000000..c95ce02bf
--- /dev/null
+++ b/shell/ash_test/ash-arith/arith-postinc.right
@@ -0,0 +1,5 @@
11 1
21 1
31 1
41 1
5Ok:0
diff --git a/shell/ash_test/ash-arith/arith-postinc.tests b/shell/ash_test/ash-arith/arith-postinc.tests
new file mode 100755
index 000000000..3fd9bfed5
--- /dev/null
+++ b/shell/ash_test/ash-arith/arith-postinc.tests
@@ -0,0 +1,5 @@
1echo 1 $((0++1))
2echo 1 $((0--1))
3x=-1; echo 1 $((0-$x))
4x=+1; echo 1 $((0+$x))
5echo Ok:$?
diff --git a/shell/ash_test/ash-arith/arith.right b/shell/ash_test/ash-arith/arith.right
index 9b9ca8e2f..6936f1269 100644
--- a/shell/ash_test/ash-arith/arith.right
+++ b/shell/ash_test/ash-arith/arith.right
@@ -126,6 +126,10 @@ ghi
126./arith2.sub: line 5: arithmetic syntax error 126./arith2.sub: line 5: arithmetic syntax error
1275 5 1275 5
1281 1 1281 1
1296 6
1302 2
1313 3
1321 1
1294 4 1334 4
1300 0 1340 0
131./arith2.sub: line 42: arithmetic syntax error 135./arith2.sub: line 42: arithmetic syntax error
diff --git a/shell/ash_test/ash-arith/arith2.sub b/shell/ash_test/ash-arith/arith2.sub
index f7e3c9235..9105059db 100755
--- a/shell/ash_test/ash-arith/arith2.sub
+++ b/shell/ash_test/ash-arith/arith2.sub
@@ -23,14 +23,14 @@
23echo 5 $(( 4 + ++a )) 23echo 5 $(( 4 + ++a ))
24echo 1 $a 24echo 1 $a
25 25
26# ash doesn't handle it right... 26# this is treated as 4 + ++a
27#ash# echo 6 $(( 4+++a )) 27echo 6 $(( 4+++a ))
28#ash# echo 2 $a 28echo 2 $a
29 a=2 29 a=2
30 30
31# ash doesn't handle it right... 31# this is treated as 4 - --a
32#ash# echo 3 $(( 4---a )) 32echo 3 $(( 4---a ))
33#ash# echo 1 $a 33echo 1 $a
34 a=1 34 a=1
35 35
36echo 4 $(( 4 - -- a )) 36echo 4 $(( 4 - -- a ))
diff --git a/shell/hush_test/hush-arith/arith-postinc.right b/shell/hush_test/hush-arith/arith-postinc.right
new file mode 100644
index 000000000..c95ce02bf
--- /dev/null
+++ b/shell/hush_test/hush-arith/arith-postinc.right
@@ -0,0 +1,5 @@
11 1
21 1
31 1
41 1
5Ok:0
diff --git a/shell/hush_test/hush-arith/arith-postinc.tests b/shell/hush_test/hush-arith/arith-postinc.tests
new file mode 100755
index 000000000..3fd9bfed5
--- /dev/null
+++ b/shell/hush_test/hush-arith/arith-postinc.tests
@@ -0,0 +1,5 @@
1echo 1 $((0++1))
2echo 1 $((0--1))
3x=-1; echo 1 $((0-$x))
4x=+1; echo 1 $((0+$x))
5echo Ok:$?
diff --git a/shell/hush_test/hush-arith/arith.right b/shell/hush_test/hush-arith/arith.right
index 8a201fb3b..c48e468a5 100644
--- a/shell/hush_test/hush-arith/arith.right
+++ b/shell/hush_test/hush-arith/arith.right
@@ -135,6 +135,10 @@ hush: arithmetic syntax error
135hush: arithmetic syntax error 135hush: arithmetic syntax error
1365 5 1365 5
1371 1 1371 1
1386 6
1392 2
1403 3
1411 1
1384 4 1424 4
1390 0 1430 0
140hush: arithmetic syntax error 144hush: arithmetic syntax error
diff --git a/shell/hush_test/hush-arith/arith2.sub b/shell/hush_test/hush-arith/arith2.sub
index f7e3c9235..9105059db 100755
--- a/shell/hush_test/hush-arith/arith2.sub
+++ b/shell/hush_test/hush-arith/arith2.sub
@@ -23,14 +23,14 @@
23echo 5 $(( 4 + ++a )) 23echo 5 $(( 4 + ++a ))
24echo 1 $a 24echo 1 $a
25 25
26# ash doesn't handle it right... 26# this is treated as 4 + ++a
27#ash# echo 6 $(( 4+++a )) 27echo 6 $(( 4+++a ))
28#ash# echo 2 $a 28echo 2 $a
29 a=2 29 a=2
30 30
31# ash doesn't handle it right... 31# this is treated as 4 - --a
32#ash# echo 3 $(( 4---a )) 32echo 3 $(( 4---a ))
33#ash# echo 1 $a 33echo 1 $a
34 a=1 34 a=1
35 35
36echo 4 $(( 4 - -- a )) 36echo 4 $(( 4 - -- a ))
diff --git a/shell/math.c b/shell/math.c
index f01f24362..611b3beab 100644
--- a/shell/math.c
+++ b/shell/math.c
@@ -598,10 +598,24 @@ evaluate_string(arith_state_t *math_state, const char *expr)
598 } 598 }
599 599
600 /* Should be an operator */ 600 /* Should be an operator */
601
602 /* Special case: NUM-- and NUM++ are not recognized if NUM
603 * is a literal number, not a variable. IOW:
604 * "a+++v" is a++ + v.
605 * "7+++v" is 7 + ++v, not 7++ + v.
606 */
607 if (lasttok == TOK_NUM && !numstackptr[-1].var /* number literal */
608 && (expr[0] == '+' || expr[0] == '-')
609 && (expr[1] == expr[0])
610 ) {
611 //bb_error_msg("special %c%c", expr[0], expr[0]);
612 op = (expr[0] == '+' ? TOK_ADD : TOK_SUB);
613 expr += 1;
614 goto tok_found1;
615 }
616
601 p = op_tokens; 617 p = op_tokens;
602 while (1) { 618 while (1) {
603// TODO: bash allows 7+++v, treats it as 7 + ++v
604// we treat it as 7++ + v and reject
605 /* Compare expr to current op_tokens[] element */ 619 /* Compare expr to current op_tokens[] element */
606 const char *e = expr; 620 const char *e = expr;
607 while (1) { 621 while (1) {
@@ -627,6 +641,7 @@ evaluate_string(arith_state_t *math_state, const char *expr)
627 } 641 }
628 tok_found: 642 tok_found:
629 op = p[1]; /* fetch TOK_foo value */ 643 op = p[1]; /* fetch TOK_foo value */
644 tok_found1:
630 /* NB: expr now points past the operator */ 645 /* NB: expr now points past the operator */
631 646
632 /* post grammar: a++ reduce to num */ 647 /* post grammar: a++ reduce to num */