diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2023-06-17 22:43:46 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2023-06-18 18:12:04 +0200 |
commit | 182e5a4d000cdb5808830b1f02c59d40c6e61150 (patch) | |
tree | 6324aa78cac5689e66f31f2576b97a9edbeb38aa | |
parent | 96769486e20fd5f1142cae0db2cbacef31dc75e9 (diff) | |
download | busybox-w32-182e5a4d000cdb5808830b1f02c59d40c6e61150.tar.gz busybox-w32-182e5a4d000cdb5808830b1f02c59d40c6e61150.tar.bz2 busybox-w32-182e5a4d000cdb5808830b1f02c59d40c6e61150.zip |
shell/math: decrease stack usage
function old new delta
evaluate_string 1412 1467 +55
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/math.c | 62 |
1 files changed, 27 insertions, 35 deletions
diff --git a/shell/math.c b/shell/math.c index 4b56d1397..f6fed805c 100644 --- a/shell/math.c +++ b/shell/math.c | |||
@@ -579,48 +579,40 @@ static arith_t strto_arith_t(const char *nptr, char **endptr) | |||
579 | # endif | 579 | # endif |
580 | #endif | 580 | #endif |
581 | 581 | ||
582 | //TODO: much better estimation than expr_len/2? Such as: | ||
583 | //static unsigned estimate_nums_and_names(const char *expr) | ||
584 | //{ | ||
585 | // unsigned count = 0; | ||
586 | // while (*(expr = skip_whitespace(expr)) != '\0') { | ||
587 | // const char *p; | ||
588 | // if (isdigit(*expr)) { | ||
589 | // while (isdigit(*++expr)) | ||
590 | // continue; | ||
591 | // count++; | ||
592 | // continue; | ||
593 | // } | ||
594 | // p = endofname(expr); | ||
595 | // if (p != expr) { | ||
596 | // expr = p; | ||
597 | // count++; | ||
598 | // continue; | ||
599 | // } | ||
600 | // } | ||
601 | // return count; | ||
602 | //} | ||
603 | |||
604 | static arith_t | 582 | static arith_t |
605 | evaluate_string(arith_state_t *math_state, const char *expr) | 583 | evaluate_string(arith_state_t *math_state, const char *expr) |
606 | { | 584 | { |
607 | operator lasttok; | ||
608 | const char *errmsg = NULL; | ||
609 | const char *start_expr = expr = skip_whitespace(expr); | ||
610 | unsigned expr_len = strlen(expr) + 2; | ||
611 | /* Stack of integers/names */ | 585 | /* Stack of integers/names */ |
612 | /* There can be no more than strlen(startbuf)/2+1 | 586 | var_or_num_t *numstack, *numstackptr; |
613 | * integers/names in any given correct or incorrect expression. | ||
614 | * (modulo "09v09v09v09v09v" case, | ||
615 | * but we have code to detect that early) | ||
616 | */ | ||
617 | var_or_num_t *const numstack = alloca((expr_len / 2) * sizeof(numstack[0])); | ||
618 | var_or_num_t *numstackptr = numstack; | ||
619 | /* Stack of operator tokens */ | 587 | /* Stack of operator tokens */ |
620 | operator *const opstack = alloca(expr_len * sizeof(opstack[0])); | 588 | operator *opstack, *opstackptr; |
621 | operator *opstackptr = opstack; | 589 | operator lasttok; |
622 | operator insert_op = 0xff; | 590 | operator insert_op = 0xff; |
623 | unsigned ternary_level = 0; | 591 | unsigned ternary_level = 0; |
592 | const char *errmsg; | ||
593 | const char *start_expr = expr = skip_whitespace(expr); | ||
594 | |||
595 | { | ||
596 | unsigned expr_len = strlen(expr) + 2; | ||
597 | /* If LOTS of whitespace, do not blow up the estimation */ | ||
598 | const char *p = expr; | ||
599 | while (*p) { | ||
600 | /* in a run of whitespace, count only 1st char */ | ||
601 | if (isspace(*p)) { | ||
602 | while (p++, isspace(*p)) | ||
603 | expr_len--; | ||
604 | } else { | ||
605 | p++; | ||
606 | } | ||
607 | } | ||
608 | /* There can be no more than expr_len/2 | ||
609 | * integers/names in any given correct or incorrect expression. | ||
610 | * (modulo "09v09v09v09v09v" case, | ||
611 | * but we have code to detect that early) | ||
612 | */ | ||
613 | numstackptr = numstack = alloca((expr_len / 2) * sizeof(numstack[0])); | ||
614 | opstackptr = opstack = alloca(expr_len * sizeof(opstack[0])); | ||
615 | } | ||
624 | 616 | ||
625 | /* Start with a left paren */ | 617 | /* Start with a left paren */ |
626 | dbg("(%d) op:TOK_LPAREN", (int)(opstackptr - opstack)); | 618 | dbg("(%d) op:TOK_LPAREN", (int)(opstackptr - opstack)); |