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>
This commit is contained in:
Denys Vlasenko 2010-09-13 12:49:52 +02:00
parent 06d44d7dfb
commit 0eac8ff164
2 changed files with 37 additions and 22 deletions

View File

@ -232,6 +232,7 @@ is_right_associative(operator prec)
|| prec == PREC(TOK_CONDITIONAL)); || prec == PREC(TOK_CONDITIONAL));
} }
typedef struct { typedef struct {
arith_t val; arith_t val;
arith_t contidional_second_val; arith_t contidional_second_val;
@ -240,43 +241,49 @@ typedef struct {
else is variable name */ else is variable name */
} v_n_t; } v_n_t;
typedef struct chk_var_recursive_looped_t { typedef struct remembered_name {
struct remembered_name *next;
const char *var; const char *var;
struct chk_var_recursive_looped_t *next; } remembered_name;
} chk_var_recursive_looped_t;
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 static int
arith_lookup_val(arith_state_t *math_state, v_n_t *t) arith_lookup_val(arith_state_t *math_state, v_n_t *t)
{ {
if (t->var) { if (t->var) {
const char *p = lookupvar(t->var); const char *p = lookupvar(t->var);
if (p) { if (p) {
chk_var_recursive_looped_t *cur; remembered_name *cur;
chk_var_recursive_looped_t cur_save; remembered_name cur_save;
/* recursively try p as expression */ /* did we already see this name?
* testcase: a=b; b=a; echo $((a))
for (cur = prev_chk_var_recursive; cur; cur = cur->next) { */
for (cur = math_state->list_of_recursed_names; cur; cur = cur->next) {
if (strcmp(cur->var, t->var) == 0) { if (strcmp(cur->var, t->var) == 0) {
/* expression recursion loop detected */ /* Yes. Expression recursion loop detected */
return -5; 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.var = t->var;
cur_save.next = cur; 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; return math_state->errcode;
} }
/* allow undefined var as 0 */ /* treat undefined var as 0 */
t->val = 0; t->val = 0;
} }
return 0; return 0;
@ -487,8 +494,8 @@ endofname(const char *name)
return name; return name;
} }
arith_t static arith_t FAST_FUNC
arith(arith_state_t *math_state, const char *expr) evaluate_string(arith_state_t *math_state, const char *expr)
{ {
operator lasttok; operator lasttok;
int errcode; int errcode;
@ -677,6 +684,13 @@ arith(arith_state_t *math_state, const char *expr)
return numstack->val; 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 * Copyright (c) 1989, 1991, 1993, 1994
* The Regents of the University of California. All rights reserved. * The Regents of the University of California. All rights reserved.

View File

@ -95,13 +95,14 @@ typedef void FAST_FUNC (*arith_var_set_t)(const char *name, const char *v
//typedef const char* FAST_FUNC (*arith_var_endofname_t)(const char *name); //typedef const char* FAST_FUNC (*arith_var_endofname_t)(const char *name);
typedef struct arith_state_t { typedef struct arith_state_t {
int errcode;
arith_var_lookup_t lookupvar; arith_var_lookup_t lookupvar;
arith_var_set_t setvar; arith_var_set_t setvar;
// arith_var_endofname_t endofname; // arith_var_endofname_t endofname;
int errcode; void *list_of_recursed_names;
} arith_state_t; } arith_state_t;
arith_t arith(arith_state_t *state, const char *expr); arith_t FAST_FUNC arith(arith_state_t *state, const char *expr);
POP_SAVED_FUNCTION_VISIBILITY POP_SAVED_FUNCTION_VISIBILITY