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));
}
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.

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 struct arith_state_t {
int errcode;
arith_var_lookup_t lookupvar;
arith_var_set_t setvar;
// arith_var_endofname_t endofname;
int errcode;
void *list_of_recursed_names;
} 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