From f19e3c1c6c96e3c709ac732ff70c586521f792d3 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 28 Jan 2018 20:13:33 +0100 Subject: [PATCH] shell: handle $((NUM++...) like bash does. Closes 10706 function old new delta evaluate_string 680 729 +49 Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-arith/arith-postinc.right | 5 +++++ shell/ash_test/ash-arith/arith-postinc.tests | 5 +++++ shell/ash_test/ash-arith/arith.right | 4 ++++ shell/ash_test/ash-arith/arith2.sub | 12 ++++++------ .../hush_test/hush-arith/arith-postinc.right | 5 +++++ .../hush_test/hush-arith/arith-postinc.tests | 5 +++++ shell/hush_test/hush-arith/arith.right | 4 ++++ shell/hush_test/hush-arith/arith2.sub | 12 ++++++------ shell/math.c | 19 +++++++++++++++++-- 9 files changed, 57 insertions(+), 14 deletions(-) create mode 100644 shell/ash_test/ash-arith/arith-postinc.right create mode 100755 shell/ash_test/ash-arith/arith-postinc.tests create mode 100644 shell/hush_test/hush-arith/arith-postinc.right create mode 100755 shell/hush_test/hush-arith/arith-postinc.tests 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 @@ +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 index 000000000..3fd9bfed5 --- /dev/null +++ b/shell/ash_test/ash-arith/arith-postinc.tests @@ -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:$? 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 ./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 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 @@ 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 index 000000000..c95ce02bf --- /dev/null +++ b/shell/hush_test/hush-arith/arith-postinc.right @@ -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 index 000000000..3fd9bfed5 --- /dev/null +++ b/shell/hush_test/hush-arith/arith-postinc.tests @@ -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:$? 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 hush: arithmetic syntax error 5 5 1 1 +6 6 +2 2 +3 3 +1 1 4 4 0 0 hush: 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 @@ 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/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) } /* 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 */