From d84a604830a7ee3f8fb5f3908ae0d54513393a20 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 25 Sep 2021 22:04:45 +0200 Subject: shell: fix arithmentic evaluation of "++7" and such (it is + + 7, i.e. 7) function old new delta evaluate_string 945 988 +43 Signed-off-by: Denys Vlasenko --- 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; -- cgit v1.2.3