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));
|
|| 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.
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user