Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.busybox.net/busybox.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2023-06-17 23:43:46 +0300
committerDenys Vlasenko <vda.linux@googlemail.com>2023-06-18 19:12:04 +0300
commit182e5a4d000cdb5808830b1f02c59d40c6e61150 (patch)
tree6324aa78cac5689e66f31f2576b97a9edbeb38aa
parent96769486e20fd5f1142cae0db2cbacef31dc75e9 (diff)
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.c62
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)
# endif
#endif
-//TODO: much better estimation than expr_len/2? Such as:
-//static unsigned estimate_nums_and_names(const char *expr)
-//{
-// unsigned count = 0;
-// while (*(expr = skip_whitespace(expr)) != '\0') {
-// const char *p;
-// if (isdigit(*expr)) {
-// while (isdigit(*++expr))
-// continue;
-// count++;
-// continue;
-// }
-// p = endofname(expr);
-// if (p != expr) {
-// expr = p;
-// count++;
-// continue;
-// }
-// }
-// return count;
-//}
-
static arith_t
evaluate_string(arith_state_t *math_state, const char *expr)
{
- operator lasttok;
- const char *errmsg = NULL;
- const char *start_expr = expr = skip_whitespace(expr);
- unsigned expr_len = strlen(expr) + 2;
/* Stack of integers/names */
- /* There can be no more than strlen(startbuf)/2+1
- * integers/names in any given correct or incorrect expression.
- * (modulo "09v09v09v09v09v" case,
- * but we have code to detect that early)
- */
- var_or_num_t *const numstack = alloca((expr_len / 2) * sizeof(numstack[0]));
- var_or_num_t *numstackptr = numstack;
+ var_or_num_t *numstack, *numstackptr;
/* Stack of operator tokens */
- operator *const opstack = alloca(expr_len * sizeof(opstack[0]));
- operator *opstackptr = opstack;
+ operator *opstack, *opstackptr;
+ operator lasttok;
operator insert_op = 0xff;
unsigned ternary_level = 0;
+ const char *errmsg;
+ const char *start_expr = expr = skip_whitespace(expr);
+
+ {
+ unsigned expr_len = strlen(expr) + 2;
+ /* If LOTS of whitespace, do not blow up the estimation */
+ const char *p = expr;
+ while (*p) {
+ /* in a run of whitespace, count only 1st char */
+ if (isspace(*p)) {
+ while (p++, isspace(*p))
+ expr_len--;
+ } else {
+ p++;
+ }
+ }
+ /* There can be no more than expr_len/2
+ * integers/names in any given correct or incorrect expression.
+ * (modulo "09v09v09v09v09v" case,
+ * but we have code to detect that early)
+ */
+ numstackptr = numstack = alloca((expr_len / 2) * sizeof(numstack[0]));
+ opstackptr = opstack = alloca(expr_len * sizeof(opstack[0]));
+ }
/* Start with a left paren */
dbg("(%d) op:TOK_LPAREN", (int)(opstackptr - opstack));