diff options
author | Denys Vlasenko <dvlasenk@redhat.com> | 2010-09-13 12:49:52 +0200 |
---|---|---|
committer | Denys Vlasenko <dvlasenk@redhat.com> | 2010-09-13 12:49:52 +0200 |
commit | 0eac8ff1648f94a79a0e21731ec993dd73d946db (patch) | |
tree | e042b1fa115124dc7df79c143fac2de7ce9e128a | |
parent | 06d44d7dfb709bfe02e74d187cceb8591bbda3b4 (diff) | |
download | busybox-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.c | 54 | ||||
-rw-r--r-- | shell/math.h | 5 |
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 | |||
235 | typedef struct { | 236 | typedef 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 | ||
243 | typedef struct chk_var_recursive_looped_t { | 244 | typedef 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 | ||
248 | static chk_var_recursive_looped_t *prev_chk_var_recursive; | 250 | static arith_t FAST_FUNC |
251 | evaluate_string(arith_state_t *math_state, const char *expr); | ||
249 | 252 | ||
250 | static int | 253 | static int |
251 | arith_lookup_val(arith_state_t *math_state, v_n_t *t) | 254 | arith_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 | ||
490 | arith_t | 497 | static arith_t FAST_FUNC |
491 | arith(arith_state_t *math_state, const char *expr) | 498 | evaluate_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 | ||
687 | arith_t FAST_FUNC | ||
688 | arith(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 | ||
97 | typedef struct arith_state_t { | 97 | typedef 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 | ||
104 | arith_t arith(arith_state_t *state, const char *expr); | 105 | arith_t FAST_FUNC arith(arith_state_t *state, const char *expr); |
105 | 106 | ||
106 | POP_SAVED_FUNCTION_VISIBILITY | 107 | POP_SAVED_FUNCTION_VISIBILITY |
107 | 108 | ||