shell: handle $((NUM++...) like bash does. Closes 10706
authorDenys Vlasenko <vda.linux@googlemail.com>
Sun, 28 Jan 2018 19:13:33 +0000 (20:13 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sun, 28 Jan 2018 19:13:33 +0000 (20:13 +0100)
function                                             old     new   delta
evaluate_string                                      680     729     +49

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
shell/ash_test/ash-arith/arith-postinc.right [new file with mode: 0644]
shell/ash_test/ash-arith/arith-postinc.tests [new file with mode: 0755]
shell/ash_test/ash-arith/arith.right
shell/ash_test/ash-arith/arith2.sub
shell/hush_test/hush-arith/arith-postinc.right [new file with mode: 0644]
shell/hush_test/hush-arith/arith-postinc.tests [new file with mode: 0755]
shell/hush_test/hush-arith/arith.right
shell/hush_test/hush-arith/arith2.sub
shell/math.c

diff --git a/shell/ash_test/ash-arith/arith-postinc.right b/shell/ash_test/ash-arith/arith-postinc.right
new file mode 100644 (file)
index 0000000..c95ce02
--- /dev/null
@@ -0,0 +1,5 @@
+1 1
+1 1
+1 1
+1 1
+Ok: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 (executable)
index 0000000..3fd9bfe
--- /dev/null
@@ -0,0 +1,5 @@
+echo 1 $((0++1))
+echo 1 $((0--1))
+x=-1; echo 1 $((0-$x))
+x=+1; echo 1 $((0+$x))
+echo Ok:$?
index 9b9ca8e2f71ae441f39943f6c742a2713c4799ba..6936f12691f96f0fa54f6d6629042230583dc0d8 100644 (file)
@@ -126,6 +126,10 @@ ghi
 ./arith2.sub: line 5: arithmetic syntax error
 5 5
 1 1
+6 6
+2 2
+3 3
+1 1
 4 4
 0 0
 ./arith2.sub: line 42: arithmetic syntax error
index f7e3c9235ce5af5ed60e8bc20d3341062bb7d917..9105059db28eab7d1ed1f8f5d1fdecffc4327b6b 100755 (executable)
 echo 5 $(( 4 + ++a ))
 echo 1 $a
 
-# ash doesn't handle it right...
-#ash# echo 6 $(( 4+++a ))
-#ash# echo 2 $a
+# this is treated as 4 + ++a
+echo 6 $(( 4+++a ))
+echo 2 $a
       a=2
 
-# ash doesn't handle it right...
-#ash# echo 3 $(( 4---a ))
-#ash# echo 1 $a
+# this is treated as 4 - --a
+echo 3 $(( 4---a ))
+echo 1 $a
       a=1
 
 echo 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 (file)
index 0000000..c95ce02
--- /dev/null
@@ -0,0 +1,5 @@
+1 1
+1 1
+1 1
+1 1
+Ok: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 (executable)
index 0000000..3fd9bfe
--- /dev/null
@@ -0,0 +1,5 @@
+echo 1 $((0++1))
+echo 1 $((0--1))
+x=-1; echo 1 $((0-$x))
+x=+1; echo 1 $((0+$x))
+echo Ok:$?
index 8a201fb3b0f763471438ee912920a5e1b2a33458..c48e468a5b8ed3ee194ba21992850df0dbef467b 100644 (file)
@@ -135,6 +135,10 @@ hush: arithmetic syntax error
 hush: arithmetic syntax error
 5 5
 1 1
+6 6
+2 2
+3 3
+1 1
 4 4
 0 0
 hush: arithmetic syntax error
index f7e3c9235ce5af5ed60e8bc20d3341062bb7d917..9105059db28eab7d1ed1f8f5d1fdecffc4327b6b 100755 (executable)
 echo 5 $(( 4 + ++a ))
 echo 1 $a
 
-# ash doesn't handle it right...
-#ash# echo 6 $(( 4+++a ))
-#ash# echo 2 $a
+# this is treated as 4 + ++a
+echo 6 $(( 4+++a ))
+echo 2 $a
       a=2
 
-# ash doesn't handle it right...
-#ash# echo 3 $(( 4---a ))
-#ash# echo 1 $a
+# this is treated as 4 - --a
+echo 3 $(( 4---a ))
+echo 1 $a
       a=1
 
 echo 4 $(( 4 - -- a ))
index f01f24362941ee447b7bfe7e223a382e7905dd8e..611b3beabd0199dbc77f89a1c1c41cde915ec5eb 100644 (file)
@@ -598,10 +598,24 @@ evaluate_string(arith_state_t *math_state, const char *expr)
                }
 
                /* Should be an operator */
+
+               /* Special case: NUM-- and NUM++ are not recognized if NUM
+                * is a literal number, not a variable. IOW:
+                * "a+++v" is a++ + v.
+                * "7+++v" is 7 + ++v, not 7++ + v.
+                */
+               if (lasttok == TOK_NUM && !numstackptr[-1].var /* number literal */
+                && (expr[0] == '+' || expr[0] == '-')
+                && (expr[1] == expr[0])
+               ) {
+                       //bb_error_msg("special %c%c", expr[0], expr[0]);
+                       op = (expr[0] == '+' ? TOK_ADD : TOK_SUB);
+                       expr += 1;
+                       goto tok_found1;
+               }
+
                p = op_tokens;
                while (1) {
-// TODO: bash allows 7+++v, treats it as 7 + ++v
-// we treat it as 7++ + v and reject
                        /* Compare expr to current op_tokens[] element */
                        const char *e = expr;
                        while (1) {
@@ -627,6 +641,7 @@ evaluate_string(arith_state_t *math_state, const char *expr)
                }
  tok_found:
                op = p[1]; /* fetch TOK_foo value */
+ tok_found1:
                /* NB: expr now points past the operator */
 
                /* post grammar: a++ reduce to num */