aboutsummaryrefslogtreecommitdiff
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
parent06d44d7dfb709bfe02e74d187cceb8591bbda3b4 (diff)
downloadbusybox-w32-0eac8ff1648f94a79a0e21731ec993dd73d946db.tar.gz
busybox-w32-0eac8ff1648f94a79a0e21731ec993dd73d946db.tar.bz2
busybox-w32-0eac8ff1648f94a79a0e21731ec993dd73d946db.zip
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>
-rw-r--r--shell/math.c54
-rw-r--r--shell/math.h5
2 files changed, 37 insertions, 22 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)
232 || prec == PREC(TOK_CONDITIONAL)); 232 || prec == PREC(TOK_CONDITIONAL));
233} 233}
234 234
235
235typedef struct { 236typedef struct {
236 arith_t val; 237 arith_t val;
237 arith_t contidional_second_val; 238 arith_t contidional_second_val;
@@ -240,43 +241,49 @@ typedef struct {
240 else is variable name */ 241 else is variable name */
241} v_n_t; 242} v_n_t;
242 243
243typedef struct chk_var_recursive_looped_t { 244typedef struct remembered_name {
245 struct remembered_name *next;
244 const char *var; 246 const char *var;
245 struct chk_var_recursive_looped_t *next; 247} remembered_name;
246} chk_var_recursive_looped_t; 248
247 249
248static chk_var_recursive_looped_t *prev_chk_var_recursive; 250static arith_t FAST_FUNC
251evaluate_string(arith_state_t *math_state, const char *expr);
249 252
250static int 253static int
251arith_lookup_val(arith_state_t *math_state, v_n_t *t) 254arith_lookup_val(arith_state_t *math_state, v_n_t *t)
252{ 255{
253 if (t->var) { 256 if (t->var) {
254 const char *p = lookupvar(t->var); 257 const char *p = lookupvar(t->var);
255
256 if (p) { 258 if (p) {
257 chk_var_recursive_looped_t *cur; 259 remembered_name *cur;
258 chk_var_recursive_looped_t cur_save; 260 remembered_name cur_save;
259 261
260 /* recursively try p as expression */ 262 /* did we already see this name?
261 263 * testcase: a=b; b=a; echo $((a))
262 for (cur = prev_chk_var_recursive; cur; cur = cur->next) { 264 */
265 for (cur = math_state->list_of_recursed_names; cur; cur = cur->next) {
263 if (strcmp(cur->var, t->var) == 0) { 266 if (strcmp(cur->var, t->var) == 0) {
264 /* expression recursion loop detected */ 267 /* Yes. Expression recursion loop detected */
265 return -5; 268 return -5;
266 } 269 }
267 } 270 }
268 /* save current var name */ 271
269 cur = prev_chk_var_recursive; 272 /* push current var name */
273 cur = math_state->list_of_recursed_names;
270 cur_save.var = t->var; 274 cur_save.var = t->var;
271 cur_save.next = cur; 275 cur_save.next = cur;
272 prev_chk_var_recursive = &cur_save; 276 math_state->list_of_recursed_names = &cur_save;
277
278 /* recursively evaluate p as expression */
279 t->val = evaluate_string(math_state, p);
280
281 /* pop current var name */
282 math_state->list_of_recursed_names = cur;
273 283
274 t->val = arith(math_state, p);
275 /* restore previous ptr after recursion */
276 prev_chk_var_recursive = cur;
277 return math_state->errcode; 284 return math_state->errcode;
278 } 285 }
279 /* allow undefined var as 0 */ 286 /* treat undefined var as 0 */
280 t->val = 0; 287 t->val = 0;
281 } 288 }
282 return 0; 289 return 0;
@@ -487,8 +494,8 @@ endofname(const char *name)
487 return name; 494 return name;
488} 495}
489 496
490arith_t 497static arith_t FAST_FUNC
491arith(arith_state_t *math_state, const char *expr) 498evaluate_string(arith_state_t *math_state, const char *expr)
492{ 499{
493 operator lasttok; 500 operator lasttok;
494 int errcode; 501 int errcode;
@@ -677,6 +684,13 @@ arith(arith_state_t *math_state, const char *expr)
677 return numstack->val; 684 return numstack->val;
678} 685}
679 686
687arith_t FAST_FUNC
688arith(arith_state_t *math_state, const char *expr)
689{
690 math_state->list_of_recursed_names = NULL;
691 return evaluate_string(math_state, expr);
692}
693
680/* 694/*
681 * Copyright (c) 1989, 1991, 1993, 1994 695 * Copyright (c) 1989, 1991, 1993, 1994
682 * The Regents of the University of California. All rights reserved. 696 * The Regents of the University of California. All rights reserved.
diff --git a/shell/math.h b/shell/math.h
index 9f3da7f59..e34b65d5d 100644
--- a/shell/math.h
+++ b/shell/math.h
@@ -95,13 +95,14 @@ typedef void FAST_FUNC (*arith_var_set_t)(const char *name, const char *v
95//typedef const char* FAST_FUNC (*arith_var_endofname_t)(const char *name); 95//typedef const char* FAST_FUNC (*arith_var_endofname_t)(const char *name);
96 96
97typedef struct arith_state_t { 97typedef struct arith_state_t {
98 int errcode;
98 arith_var_lookup_t lookupvar; 99 arith_var_lookup_t lookupvar;
99 arith_var_set_t setvar; 100 arith_var_set_t setvar;
100// arith_var_endofname_t endofname; 101// arith_var_endofname_t endofname;
101 int errcode; 102 void *list_of_recursed_names;
102} arith_state_t; 103} arith_state_t;
103 104
104arith_t arith(arith_state_t *state, const char *expr); 105arith_t FAST_FUNC arith(arith_state_t *state, const char *expr);
105 106
106POP_SAVED_FUNCTION_VISIBILITY 107POP_SAVED_FUNCTION_VISIBILITY
107 108