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:
parent
06d44d7dfb
commit
0eac8ff164
54
shell/math.c
54
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.
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user