[git commit] shell: fix arithmentic evaluation of "++7" and such (it is + + 7, i.e. 7)

Denys Vlasenko vda.linux at googlemail.com
Sat Sep 25 20:04:45 UTC 2021


commit: https://git.busybox.net/busybox/commit/?id=d84a604830a7ee3f8fb5f3908ae0d54513393a20
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
evaluate_string                                      945     988     +43

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 shell/ash_test/ash-arith/arith.right   | 20 +++++++++++++-------
 shell/ash_test/ash-arith/arith.tests   | 10 +++++-----
 shell/ash_test/ash-arith/arith1.sub    |  4 ++--
 shell/ash_test/ash-arith/arith2.sub    | 10 +++++-----
 shell/hush_test/hush-arith/arith.right | 20 +++++++++++++-------
 shell/hush_test/hush-arith/arith.tests | 10 +++++-----
 shell/hush_test/hush-arith/arith1.sub  |  4 ++--
 shell/hush_test/hush-arith/arith2.sub  | 10 +++++-----
 shell/math.c                           | 23 +++++++++++++++--------
 9 files changed, 65 insertions(+), 46 deletions(-)

diff --git a/shell/ash_test/ash-arith/arith.right b/shell/ash_test/ash-arith/arith.right
index 6936f1269..99ef825f5 100644
--- a/shell/ash_test/ash-arith/arith.right
+++ b/shell/ash_test/ash-arith/arith.right
@@ -97,6 +97,7 @@ ghi
 3 3
 4 4
 4 4
+7 7
 ./arith.tests: line 257: arithmetic syntax error
 ./arith.tests: line 259: arithmetic syntax error
 ./arith.tests: line 260: arithmetic syntax error
@@ -105,6 +106,8 @@ ghi
 4 4
 7 7
 -7 -7
+7
+7
 ./arith1.sub: line 2: arithmetic syntax error
 ./arith1.sub: line 3: arithmetic syntax error
 ./arith1.sub: line 4: arithmetic syntax error
@@ -119,11 +122,12 @@ ghi
 2 2
 -2 -2
 1 1
-./arith1.sub: line 37: arithmetic syntax error
-./arith2.sub: line 2: arithmetic syntax error
-./arith2.sub: line 3: arithmetic syntax error
-./arith2.sub: line 4: arithmetic syntax error
-./arith2.sub: line 5: arithmetic syntax error
+7
+7
+7
+7
+7
+7
 5 5
 1 1
 6 6
@@ -132,8 +136,10 @@ ghi
 1 1
 4 4
 0 0
-./arith2.sub: line 42: arithmetic syntax error
-./arith2.sub: line 47: arithmetic syntax error
+-7
+-7
+7
+7
 8 12
 ./arith.tests: line 290: arithmetic syntax error
 42
diff --git a/shell/ash_test/ash-arith/arith.tests b/shell/ash_test/ash-arith/arith.tests
index d65758e7d..746ccab71 100755
--- a/shell/ash_test/ash-arith/arith.tests
+++ b/shell/ash_test/ash-arith/arith.tests
@@ -252,8 +252,8 @@ echo 3 $x
 echo 4 $(( ++x ))
 echo 4 $x
 
-# bash 3.2 apparently thinks that ++7 is 7
-#ash# echo 7 $(( ++7 ))
+# ++ is not a inc operator on non-variable, it is the + + sequence
+echo 7 $(( ++7 ))
 (  echo $(( 7-- ))    )
 
 (  echo $(( --x=7 ))  )
@@ -267,9 +267,9 @@ echo 4 $x
 echo 7 $(( +7 ))
 echo -7 $(( -7 ))
 
-# bash 3.2 apparently thinks that ++7 is 7
-#ash# echo $(( ++7 ))
-#ash# echo $(( --7 ))
+# ++ is not a inc operator on non-variable, it is the + + sequence
+echo $(( ++7 ))
+echo $(( --7 ))
 
 ${THIS_SH} ./arith1.sub
 ${THIS_SH} ./arith2.sub
diff --git a/shell/ash_test/ash-arith/arith1.sub b/shell/ash_test/ash-arith/arith1.sub
index 80aa99922..a36785c67 100755
--- a/shell/ash_test/ash-arith/arith1.sub
+++ b/shell/ash_test/ash-arith/arith1.sub
@@ -35,6 +35,6 @@ echo 1 $a
 
 #ash# (( ++ ))
 (  echo $(( +++7 ))  )
-# bash 3.2 apparently thinks that ++ +7 is 7
-#ash# echo $(( ++ + 7 ))
+# ++ is not a inc operator on non-variable, it is the + + sequence
+echo $(( ++ + 7 ))
 #ash# (( -- ))
diff --git a/shell/ash_test/ash-arith/arith2.sub b/shell/ash_test/ash-arith/arith2.sub
index 9105059db..29f9471d6 100755
--- a/shell/ash_test/ash-arith/arith2.sub
+++ b/shell/ash_test/ash-arith/arith2.sub
@@ -1,4 +1,4 @@
-# bash 3.2 apparently thinks that ++7 is 7 etc
+# ++ and -- are not inc/dec operators on non-variables, they are + + and - - sequences
 (  echo $(( --7 ))   )
 (  echo $(( ++7 ))   )
 (  echo $(( -- 7 ))  )
@@ -37,13 +37,13 @@ echo 4 $(( 4 - -- a ))
 echo 0 $a
 
 #ash# (( -- ))
-# bash 3.2 apparently thinks that ---7 is -7
-#ash# echo $(( ---7 ))
+# -- is not a dec operator on non-variable, it is the - - sequence
+echo $(( ---7 ))
 (  echo $(( -- - 7 ))  )
 
 #ash# (( ++ ))
-# bash 3.2: 7
-#ash# echo 7 $(( ++7 ))
+# ++ is not a inc operator on non-variable, it is the + + sequence
+echo $(( ++7 ))
 (  echo $(( ++ + 7 ))  )
 
 # bash 3.2: -7
diff --git a/shell/hush_test/hush-arith/arith.right b/shell/hush_test/hush-arith/arith.right
index c48e468a5..2c389caea 100644
--- a/shell/hush_test/hush-arith/arith.right
+++ b/shell/hush_test/hush-arith/arith.right
@@ -106,6 +106,7 @@ hush: arithmetic syntax error
 3 3
 4 4
 4 4
+7 7
 hush: arithmetic syntax error
 hush: arithmetic syntax error
 hush: arithmetic syntax error
@@ -114,6 +115,8 @@ hush: arithmetic syntax error
 4 4
 7 7
 -7 -7
+7
+7
 hush: arithmetic syntax error
 hush: arithmetic syntax error
 hush: arithmetic syntax error
@@ -128,11 +131,12 @@ hush: arithmetic syntax error
 2 2
 -2 -2
 1 1
-hush: arithmetic syntax error
-hush: arithmetic syntax error
-hush: arithmetic syntax error
-hush: arithmetic syntax error
-hush: arithmetic syntax error
+7
+7
+7
+7
+7
+7
 5 5
 1 1
 6 6
@@ -141,8 +145,10 @@ hush: arithmetic syntax error
 1 1
 4 4
 0 0
-hush: arithmetic syntax error
-hush: arithmetic syntax error
+-7
+-7
+7
+7
 8 12
 hush: arithmetic syntax error
 42
diff --git a/shell/hush_test/hush-arith/arith.tests b/shell/hush_test/hush-arith/arith.tests
index bc6b341d1..a7aded17d 100755
--- a/shell/hush_test/hush-arith/arith.tests
+++ b/shell/hush_test/hush-arith/arith.tests
@@ -255,8 +255,8 @@ echo 3 $x
 echo 4 $(( ++x ))
 echo 4 $x
 
-# bash 3.2 apparently thinks that ++7 is 7
-#ash# echo 7 $(( ++7 ))
+# ++ is not a inc operator on non-variable, it is the + + sequence
+echo 7 $(( ++7 ))
 (  echo $(( 7-- ))    )
 
 (  echo $(( --x=7 ))  )
@@ -270,9 +270,9 @@ echo 4 $x
 echo 7 $(( +7 ))
 echo -7 $(( -7 ))
 
-# bash 3.2 apparently thinks that ++7 is 7
-#ash# echo $(( ++7 ))
-#ash# echo $(( --7 ))
+# ++ is not a inc operator on non-variable, it is the + + sequence
+echo $(( ++7 ))
+echo $(( --7 ))
 
 ${THIS_SH} ./arith1.sub
 ${THIS_SH} ./arith2.sub
diff --git a/shell/hush_test/hush-arith/arith1.sub b/shell/hush_test/hush-arith/arith1.sub
index 80aa99922..a36785c67 100755
--- a/shell/hush_test/hush-arith/arith1.sub
+++ b/shell/hush_test/hush-arith/arith1.sub
@@ -35,6 +35,6 @@ echo 1 $a
 
 #ash# (( ++ ))
 (  echo $(( +++7 ))  )
-# bash 3.2 apparently thinks that ++ +7 is 7
-#ash# echo $(( ++ + 7 ))
+# ++ is not a inc operator on non-variable, it is the + + sequence
+echo $(( ++ + 7 ))
 #ash# (( -- ))
diff --git a/shell/hush_test/hush-arith/arith2.sub b/shell/hush_test/hush-arith/arith2.sub
index 9105059db..29f9471d6 100755
--- a/shell/hush_test/hush-arith/arith2.sub
+++ b/shell/hush_test/hush-arith/arith2.sub
@@ -1,4 +1,4 @@
-# bash 3.2 apparently thinks that ++7 is 7 etc
+# ++ and -- are not inc/dec operators on non-variables, they are + + and - - sequences
 (  echo $(( --7 ))   )
 (  echo $(( ++7 ))   )
 (  echo $(( -- 7 ))  )
@@ -37,13 +37,13 @@ echo 4 $(( 4 - -- a ))
 echo 0 $a
 
 #ash# (( -- ))
-# bash 3.2 apparently thinks that ---7 is -7
-#ash# echo $(( ---7 ))
+# -- is not a dec operator on non-variable, it is the - - sequence
+echo $(( ---7 ))
 (  echo $(( -- - 7 ))  )
 
 #ash# (( ++ ))
-# bash 3.2: 7
-#ash# echo 7 $(( ++7 ))
+# ++ is not a inc operator on non-variable, it is the + + sequence
+echo $(( ++7 ))
 (  echo $(( ++ + 7 ))  )
 
 # bash 3.2: -7
diff --git a/shell/math.c b/shell/math.c
index 2942cdd26..049d5703b 100644
--- a/shell/math.c
+++ b/shell/math.c
@@ -668,19 +668,26 @@ 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:
+		/* Special case: XYZ--, XYZ++, --XYZ, ++XYZ are recognized
+		 * only if XYZ is a variable name, not a number or EXPR. IOW:
 		 * "a+++v" is a++ + v.
 		 * "7+++v" is 7 + ++v, not 7++ + v.
+		 * "--7" is - - 7, not --7.
+		 * "++++a" is + + ++a, not ++ ++ a.
+		 * (we still mishandle "(a)+++7", should be treated as (a) + + + 7, but we do increment a)
 		 */
-		if (lasttok == TOK_NUM && !numstackptr[-1].var /* number literal */
-		 && (expr[0] == '+' || expr[0] == '-')
+		if ((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;
+			if (numstackptr == numstack || !numstackptr[-1].var) { /* not a VAR++ */
+				char next = skip_whitespace(expr + 2)[0];
+				if (!(isalpha(next) || next == '_')) { /* not a ++VAR */
+					//bb_error_msg("special %c%c", expr[0], expr[0]);
+					op = (expr[0] == '+' ? TOK_ADD : TOK_SUB);
+					expr++;
+					goto tok_found1;
+				}
+			}
 		}
 
 		p = op_tokens;


More information about the busybox-cvs mailing list