diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2023-06-26 09:59:56 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2023-06-26 10:02:54 +0200 |
| commit | 5d8f8570c0c4220bfadb6d24d4fbc3e722d44802 (patch) | |
| tree | da5bb43110d253f9b111e0e7efedec3f616efcb7 | |
| parent | c1c267fd36b0fcac8c8871232eecc1e360173990 (diff) | |
| download | busybox-w32-5d8f8570c0c4220bfadb6d24d4fbc3e722d44802.tar.gz busybox-w32-5d8f8570c0c4220bfadb6d24d4fbc3e722d44802.tar.bz2 busybox-w32-5d8f8570c0c4220bfadb6d24d4fbc3e722d44802.zip | |
shell/math: rename TOK_NUM to TOK_VALUE, improve comments
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | shell/math.c | 49 |
1 files changed, 25 insertions, 24 deletions
diff --git a/shell/math.c b/shell/math.c index fbf5c587e..0426e2daa 100644 --- a/shell/math.c +++ b/shell/math.c | |||
| @@ -94,7 +94,6 @@ | |||
| 94 | * | 94 | * |
| 95 | * Merge in Aaron's comments previously posted to the busybox list, | 95 | * Merge in Aaron's comments previously posted to the busybox list, |
| 96 | * modified slightly to take account of my changes to the code. | 96 | * modified slightly to take account of my changes to the code. |
| 97 | * | ||
| 98 | */ | 97 | */ |
| 99 | /* | 98 | /* |
| 100 | * (C) 2003 Vladimir Oleynik <dzo@simtreas.ru> | 99 | * (C) 2003 Vladimir Oleynik <dzo@simtreas.ru> |
| @@ -212,18 +211,18 @@ typedef unsigned char operator; | |||
| 212 | #define TOK_UPLUS tok_decl(UNARYPREC+1,1) | 211 | #define TOK_UPLUS tok_decl(UNARYPREC+1,1) |
| 213 | 212 | ||
| 214 | #define PREC_PRE (UNARYPREC+2) | 213 | #define PREC_PRE (UNARYPREC+2) |
| 215 | |||
| 216 | #define TOK_PRE_INC tok_decl(PREC_PRE, 0) | 214 | #define TOK_PRE_INC tok_decl(PREC_PRE, 0) |
| 217 | #define TOK_PRE_DEC tok_decl(PREC_PRE, 1) | 215 | #define TOK_PRE_DEC tok_decl(PREC_PRE, 1) |
| 218 | 216 | ||
| 219 | #define PREC_POST (UNARYPREC+3) | 217 | #define PREC_POST (UNARYPREC+3) |
| 220 | |||
| 221 | #define TOK_POST_INC tok_decl(PREC_POST, 0) | 218 | #define TOK_POST_INC tok_decl(PREC_POST, 0) |
| 222 | #define TOK_POST_DEC tok_decl(PREC_POST, 1) | 219 | #define TOK_POST_DEC tok_decl(PREC_POST, 1) |
| 223 | 220 | ||
| 224 | #define SPEC_PREC (UNARYPREC+4) | 221 | /* TOK_VALUE marks a number, name, name++/name--, or (EXPR): |
| 225 | 222 | * IOW: something which can be used as the left side of a binary op. | |
| 226 | #define TOK_NUM tok_decl(SPEC_PREC, 0) | 223 | * Since it's never pushed to opstack, its precedence does not matter. |
| 224 | */ | ||
| 225 | #define TOK_VALUE tok_decl(PREC_POST, 2) | ||
| 227 | 226 | ||
| 228 | static int | 227 | static int |
| 229 | is_assign_op(operator op) | 228 | is_assign_op(operator op) |
| @@ -625,7 +624,9 @@ evaluate_string(arith_state_t *math_state, const char *expr) | |||
| 625 | var_or_num_t *numstack, *numstackptr; | 624 | var_or_num_t *numstack, *numstackptr; |
| 626 | /* Stack of operator tokens */ | 625 | /* Stack of operator tokens */ |
| 627 | operator *opstack, *opstackptr; | 626 | operator *opstack, *opstackptr; |
| 627 | /* To detect whether we are after a "value": */ | ||
| 628 | operator lasttok; | 628 | operator lasttok; |
| 629 | /* To insert implicit () in ?: ternary op: */ | ||
| 629 | operator insert_op = 0xff; | 630 | operator insert_op = 0xff; |
| 630 | unsigned ternary_level = 0; | 631 | unsigned ternary_level = 0; |
| 631 | const char *errmsg; | 632 | const char *errmsg; |
| @@ -720,12 +721,12 @@ evaluate_string(arith_state_t *math_state, const char *expr) | |||
| 720 | } else { | 721 | } else { |
| 721 | dbg("[%d] var:IGNORED", (int)(numstackptr - numstack)); | 722 | dbg("[%d] var:IGNORED", (int)(numstackptr - numstack)); |
| 722 | expr = p; | 723 | expr = p; |
| 723 | numstackptr->var_name = NULL; | 724 | numstackptr->var_name = NULL; /* not needed, paranoia */ |
| 724 | numstackptr->val = 0; | 725 | numstackptr->val = 0; /* not needed, paranoia */ |
| 725 | } | 726 | } |
| 726 | push_num: | 727 | push_value: |
| 727 | numstackptr++; | 728 | numstackptr++; |
| 728 | lasttok = TOK_NUM; | 729 | lasttok = TOK_VALUE; |
| 729 | continue; | 730 | continue; |
| 730 | } | 731 | } |
| 731 | 732 | ||
| @@ -747,7 +748,7 @@ evaluate_string(arith_state_t *math_state, const char *expr) | |||
| 747 | */ | 748 | */ |
| 748 | if (isalnum(*expr) || *expr == '_') | 749 | if (isalnum(*expr) || *expr == '_') |
| 749 | goto syntax_err; | 750 | goto syntax_err; |
| 750 | goto push_num; | 751 | goto push_value; |
| 751 | } | 752 | } |
| 752 | 753 | ||
| 753 | /* Should be an operator */ | 754 | /* Should be an operator */ |
| @@ -818,15 +819,14 @@ evaluate_string(arith_state_t *math_state, const char *expr) | |||
| 818 | dbg("insert_op=%02x op=%02x", insert_op, op); | 819 | dbg("insert_op=%02x op=%02x", insert_op, op); |
| 819 | } | 820 | } |
| 820 | tok_found1: | 821 | tok_found1: |
| 821 | /* post grammar: a++ reduce to num */ | 822 | /* NAME++ is a "value" (something suitable for a binop) */ |
| 822 | if (lasttok == TOK_POST_INC || lasttok == TOK_POST_DEC) | 823 | if (PREC(lasttok) == PREC_POST) |
| 823 | lasttok = TOK_NUM; | 824 | lasttok = TOK_VALUE; |
| 824 | 825 | ||
| 825 | /* Plus and minus are binary (not unary) _only_ if the last | 826 | /* Plus and minus are binary (not unary) _only_ if the last |
| 826 | * token was a number, or a right paren (which pretends to be | 827 | * token was a "value". Think about it. It makes sense. |
| 827 | * a number, since it evaluates to one). Think about it. | 828 | */ |
| 828 | * It makes sense. */ | 829 | if (lasttok != TOK_VALUE) { |
| 829 | if (lasttok != TOK_NUM) { | ||
| 830 | switch (op) { | 830 | switch (op) { |
| 831 | case TOK_ADD: | 831 | case TOK_ADD: |
| 832 | //op = TOK_UPLUS; | 832 | //op = TOK_UPLUS; |
| @@ -857,8 +857,8 @@ evaluate_string(arith_state_t *math_state, const char *expr) | |||
| 857 | prec = PREC(op); | 857 | prec = PREC(op); |
| 858 | if (prec != PREC_LPAREN && prec < UNARYPREC) { | 858 | if (prec != PREC_LPAREN && prec < UNARYPREC) { |
| 859 | /* binary, ternary or RPAREN */ | 859 | /* binary, ternary or RPAREN */ |
| 860 | if (lasttok != TOK_NUM) { | 860 | if (lasttok != TOK_VALUE) { |
| 861 | /* must be preceded by a num */ | 861 | /* must be preceded by a num (example?) */ |
| 862 | goto syntax_err; | 862 | goto syntax_err; |
| 863 | } | 863 | } |
| 864 | /* if op is RPAREN: | 864 | /* if op is RPAREN: |
| @@ -883,11 +883,12 @@ evaluate_string(arith_state_t *math_state, const char *expr) | |||
| 883 | operator prev_op = *--opstackptr; | 883 | operator prev_op = *--opstackptr; |
| 884 | if (op == TOK_RPAREN) { | 884 | if (op == TOK_RPAREN) { |
| 885 | if (prev_op == TOK_LPAREN) { | 885 | if (prev_op == TOK_LPAREN) { |
| 886 | /* Erase var name: (var) is just a number, for example, (var) = 1 is not valid */ | 886 | /* Erase var name: for example, (VAR) = 1 is not valid */ |
| 887 | numstackptr[-1].var_name = NULL; | 887 | numstackptr[-1].var_name = NULL; |
| 888 | /* Any operator directly after a | 888 | /* (EXPR) is a "value": next operator directly after |
| 889 | * close paren should consider itself binary */ | 889 | * close paren should be considered binary |
| 890 | lasttok = TOK_NUM; | 890 | */ |
| 891 | lasttok = TOK_VALUE; | ||
| 891 | goto next; | 892 | goto next; |
| 892 | } | 893 | } |
| 893 | /* Not (y), but ...x~y). Fall through to evaluate x~y */ | 894 | /* Not (y), but ...x~y). Fall through to evaluate x~y */ |
