shell/math: fix the order of variable resolution in binops
function old new delta arith_apply 1134 1143 +9 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
5febdb1223
commit
3df885abe3
9 changed files with 48 additions and 12 deletions
3
shell/hush_test/hush-arith/arith-assign-in-varexp.right
Normal file
3
shell/hush_test/hush-arith/arith-assign-in-varexp.right
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
20:20
|
||||||
|
a=b=10
|
||||||
|
b=10
|
8
shell/hush_test/hush-arith/arith-assign-in-varexp.tests
Executable file
8
shell/hush_test/hush-arith/arith-assign-in-varexp.tests
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
exec 2>&1
|
||||||
|
a='b=10'
|
||||||
|
b=3
|
||||||
|
# The variables should evaluate left-to-right,
|
||||||
|
# thus b is set to 10 _before_ addition
|
||||||
|
echo 20:$((a + b))
|
||||||
|
echo "a=$a"
|
||||||
|
echo "b=$b"
|
3
shell/hush_test/hush-arith/arith-comma1.right
Normal file
3
shell/hush_test/hush-arith/arith-comma1.right
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
10:10
|
||||||
|
a=b=10
|
||||||
|
b=10
|
6
shell/hush_test/hush-arith/arith-comma1.tests
Executable file
6
shell/hush_test/hush-arith/arith-comma1.tests
Executable file
|
@ -0,0 +1,6 @@
|
||||||
|
exec 2>&1
|
||||||
|
a='b=10'
|
||||||
|
b=3
|
||||||
|
echo 10:$((a,b))
|
||||||
|
echo "a=$a"
|
||||||
|
echo "b=$b"
|
3
shell/hush_test/hush-arith/arith-ternary2.right
Normal file
3
shell/hush_test/hush-arith/arith-ternary2.right
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
6:6
|
||||||
|
a=b=+err+
|
||||||
|
b=6
|
7
shell/hush_test/hush-arith/arith-ternary2.tests
Executable file
7
shell/hush_test/hush-arith/arith-ternary2.tests
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
exec 2>&1
|
||||||
|
a='b=+err+'
|
||||||
|
b=5
|
||||||
|
# The not-taken branch should not parse variables
|
||||||
|
echo 6:$((0 ? a : ++b))
|
||||||
|
echo "a=$a"
|
||||||
|
echo "b=$b"
|
1
shell/hush_test/hush-arith/arith-ternary_nested.right
Normal file
1
shell/hush_test/hush-arith/arith-ternary_nested.right
Normal file
|
@ -0,0 +1 @@
|
||||||
|
5:5
|
2
shell/hush_test/hush-arith/arith-ternary_nested.tests
Executable file
2
shell/hush_test/hush-arith/arith-ternary_nested.tests
Executable file
|
@ -0,0 +1,2 @@
|
||||||
|
exec 2>&1
|
||||||
|
echo 5:$((1?2?3?4?5:6:7:8:9))
|
27
shell/math.c
27
shell/math.c
|
@ -340,7 +340,20 @@ arith_apply(arith_state_t *math_state, operator op, var_or_num_t *numstack, var_
|
||||||
if (op == TOK_CONDITIONAL) /* Example: $((a ? b)) */
|
if (op == TOK_CONDITIONAL) /* Example: $((a ? b)) */
|
||||||
return "malformed ?: operator";
|
return "malformed ?: operator";
|
||||||
|
|
||||||
/* Resolve name to value, if needed */
|
if (PREC(op) < UNARYPREC) {
|
||||||
|
/* In binops a ~ b, variables are resolved left-to-right,
|
||||||
|
* resolve top_of_stack[-1] _before_ resolving top_of_stack[0]
|
||||||
|
*/
|
||||||
|
if (top_of_stack == numstack) /* need two arguments */
|
||||||
|
goto syntax_err;
|
||||||
|
/* Unless it is =, resolve top_of_stack[-1] name to value */
|
||||||
|
if (op != TOK_ASSIGN) {
|
||||||
|
err = arith_lookup_val(math_state, top_of_stack - 1);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Resolve top_of_stack[0] name to value */
|
||||||
err = arith_lookup_val(math_state, top_of_stack);
|
err = arith_lookup_val(math_state, top_of_stack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
@ -360,20 +373,10 @@ arith_apply(arith_state_t *math_state, operator op, var_or_num_t *numstack, var_
|
||||||
/* Binary operators */
|
/* Binary operators */
|
||||||
arith_t right_side_val;
|
arith_t right_side_val;
|
||||||
|
|
||||||
/* Binary operators need two arguments */
|
/* Pop numstack */
|
||||||
if (top_of_stack == numstack)
|
|
||||||
goto syntax_err;
|
|
||||||
/* ...and they pop one */
|
|
||||||
NUMPTR = top_of_stack; /* this decrements NUMPTR */
|
NUMPTR = top_of_stack; /* this decrements NUMPTR */
|
||||||
top_of_stack--; /* now points to left side */
|
top_of_stack--; /* now points to left side */
|
||||||
|
|
||||||
if (op != TOK_ASSIGN) {
|
|
||||||
/* Resolve left side value (unless the op is '=') */
|
|
||||||
err = arith_lookup_val(math_state, top_of_stack);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
right_side_val = rez;
|
right_side_val = rez;
|
||||||
rez = top_of_stack->val;
|
rez = top_of_stack->val;
|
||||||
if (op == TOK_BOR || op == TOK_OR_ASSIGN)
|
if (op == TOK_BOR || op == TOK_OR_ASSIGN)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue