aboutsummaryrefslogtreecommitdiff
path: root/shell/math.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-09-25 22:04:45 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-09-25 22:04:45 +0200
commitd84a604830a7ee3f8fb5f3908ae0d54513393a20 (patch)
tree3e9dc05e082e41328a84c8eaa3d45f36c2ba5d44 /shell/math.c
parent627821e42b06adfe6bbc6004d8eeb7c35f65120d (diff)
downloadbusybox-w32-d84a604830a7ee3f8fb5f3908ae0d54513393a20.tar.gz
busybox-w32-d84a604830a7ee3f8fb5f3908ae0d54513393a20.tar.bz2
busybox-w32-d84a604830a7ee3f8fb5f3908ae0d54513393a20.zip
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 <vda.linux@googlemail.com>
Diffstat (limited to 'shell/math.c')
-rw-r--r--shell/math.c23
1 files changed, 15 insertions, 8 deletions
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)
668 668
669 /* Should be an operator */ 669 /* Should be an operator */
670 670
671 /* Special case: NUM-- and NUM++ are not recognized if NUM 671 /* Special case: XYZ--, XYZ++, --XYZ, ++XYZ are recognized
672 * is a literal number, not a variable. IOW: 672 * only if XYZ is a variable name, not a number or EXPR. IOW:
673 * "a+++v" is a++ + v. 673 * "a+++v" is a++ + v.
674 * "7+++v" is 7 + ++v, not 7++ + v. 674 * "7+++v" is 7 + ++v, not 7++ + v.
675 * "--7" is - - 7, not --7.
676 * "++++a" is + + ++a, not ++ ++ a.
677 * (we still mishandle "(a)+++7", should be treated as (a) + + + 7, but we do increment a)
675 */ 678 */
676 if (lasttok == TOK_NUM && !numstackptr[-1].var /* number literal */ 679 if ((expr[0] == '+' || expr[0] == '-')
677 && (expr[0] == '+' || expr[0] == '-')
678 && (expr[1] == expr[0]) 680 && (expr[1] == expr[0])
679 ) { 681 ) {
680 //bb_error_msg("special %c%c", expr[0], expr[0]); 682 if (numstackptr == numstack || !numstackptr[-1].var) { /* not a VAR++ */
681 op = (expr[0] == '+' ? TOK_ADD : TOK_SUB); 683 char next = skip_whitespace(expr + 2)[0];
682 expr += 1; 684 if (!(isalpha(next) || next == '_')) { /* not a ++VAR */
683 goto tok_found1; 685 //bb_error_msg("special %c%c", expr[0], expr[0]);
686 op = (expr[0] == '+' ? TOK_ADD : TOK_SUB);
687 expr++;
688 goto tok_found1;
689 }
690 }
684 } 691 }
685 692
686 p = op_tokens; 693 p = op_tokens;