aboutsummaryrefslogtreecommitdiff
path: root/shell/math.c
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2010-09-13 12:49:52 +0200
committerDenys Vlasenko <dvlasenk@redhat.com>2010-09-13 12:49:52 +0200
commit0eac8ff1648f94a79a0e21731ec993dd73d946db (patch)
treee042b1fa115124dc7df79c143fac2de7ce9e128a /shell/math.c
parent06d44d7dfb709bfe02e74d187cceb8591bbda3b4 (diff)
downloadbusybox-0eac8ff1648f94a79a0e21731ec993dd73d946db.tar.gz
shell/math.c: stop using bss variable
function old new delta evaluate_string - 678 +678 expand_one_var 1543 1563 +20 builtin_type 114 116 +2 expand_and_evaluate_arith 89 87 -2 prev_chk_var_recursive 4 - -4 ash_arith 122 118 -4 arith_lookup_val 142 132 -10 arith 674 12 -662 ------------------------------------------------------------------------------ (add/remove: 1/1 grow/shrink: 2/4 up/down: 700/-682) Total: 18 bytes Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Diffstat (limited to 'shell/math.c')
-rw-r--r--shell/math.c54
1 files changed, 34 insertions, 20 deletions
diff --git a/shell/math.c b/shell/math.c
index 555559a26..839715776 100644
--- a/shell/math.c
+++ b/shell/math.c
@@ -232,6 +232,7 @@ is_right_associative(operator prec)
|| prec == PREC(TOK_CONDITIONAL));
}
+
typedef struct {
arith_t val;
arith_t contidional_second_val;
@@ -240,43 +241,49 @@ typedef struct {
else is variable name */
} v_n_t;
-typedef struct chk_var_recursive_looped_t {
+typedef struct remembered_name {
+ struct remembered_name *next;
const char *var;
- struct chk_var_recursive_looped_t *next;
-} chk_var_recursive_looped_t;
+} remembered_name;
+
-static chk_var_recursive_looped_t *prev_chk_var_recursive;
+static arith_t FAST_FUNC
+evaluate_string(arith_state_t *math_state, const char *expr);
static int
arith_lookup_val(arith_state_t *math_state, v_n_t *t)
{
if (t->var) {
const char *p = lookupvar(t->var);
-
if (p) {
- chk_var_recursive_looped_t *cur;
- chk_var_recursive_looped_t cur_save;
+ remembered_name *cur;
+ remembered_name cur_save;
- /* recursively try p as expression */
-
- for (cur = prev_chk_var_recursive; cur; cur = cur->next) {
+ /* did we already see this name?
+ * testcase: a=b; b=a; echo $((a))
+ */
+ for (cur = math_state->list_of_recursed_names; cur; cur = cur->next) {
if (strcmp(cur->var, t->var) == 0) {
- /* expression recursion loop detected */
+ /* Yes. Expression recursion loop detected */
return -5;
}
}
- /* save current var name */
- cur = prev_chk_var_recursive;
+
+ /* push current var name */
+ cur = math_state->list_of_recursed_names;
cur_save.var = t->var;
cur_save.next = cur;
- prev_chk_var_recursive = &cur_save;
+ math_state->list_of_recursed_names = &cur_save;
+
+ /* recursively evaluate p as expression */
+ t->val = evaluate_string(math_state, p);
+
+ /* pop current var name */
+ math_state->list_of_recursed_names = cur;
- t->val = arith(math_state, p);
- /* restore previous ptr after recursion */
- prev_chk_var_recursive = cur;
return math_state->errcode;
}
- /* allow undefined var as 0 */
+ /* treat undefined var as 0 */
t->val = 0;
}
return 0;
@@ -487,8 +494,8 @@ endofname(const char *name)
return name;
}
-arith_t
-arith(arith_state_t *math_state, const char *expr)
+static arith_t FAST_FUNC
+evaluate_string(arith_state_t *math_state, const char *expr)
{
operator lasttok;
int errcode;
@@ -677,6 +684,13 @@ arith(arith_state_t *math_state, const char *expr)
return numstack->val;
}
+arith_t FAST_FUNC
+arith(arith_state_t *math_state, const char *expr)
+{
+ math_state->list_of_recursed_names = NULL;
+ return evaluate_string(math_state, expr);
+}
+
/*
* Copyright (c) 1989, 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.