diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-30 07:29:05 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-30 07:29:05 +0000 |
commit | 6672c8e480994a3d9c928ddedd0542c9ed9b3271 (patch) | |
tree | 43fa46479002d6c7129c772adbf25d3b0cc8edde /coreutils | |
parent | b539c8452f823a377bf629cf0e44ccda4a16c6c4 (diff) | |
download | busybox-w32-6672c8e480994a3d9c928ddedd0542c9ed9b3271.tar.gz busybox-w32-6672c8e480994a3d9c928ddedd0542c9ed9b3271.tar.bz2 busybox-w32-6672c8e480994a3d9c928ddedd0542c9ed9b3271.zip |
test: stop using lots of bss.
function old new delta
test_main 425 456 +31
t_lex 69 73 +4
syntax 100 104 +4
ptr_to_statics 8 12 +4
t_wp_op 4 - -4
t_wp 4 - -4
ngroups 4 - -4
group_array 4 - -4
binop 590 585 -5
oexpr 104 97 -7
aexpr 101 94 -7
nexpr 831 820 -11
leaving 156 - -156
------------------------------------------------------------------------------
(add/remove: 0/5 grow/shrink: 4/4 up/down: 43/-202) Total: -159 bytes
text data bss dec hex filename
775098 929 9084 785111 bfad7 busybox_old
775107 933 8908 784948 bfa34 busybox_unstripped
Diffstat (limited to 'coreutils')
-rw-r--r-- | coreutils/test.c | 92 |
1 files changed, 64 insertions, 28 deletions
diff --git a/coreutils/test.c b/coreutils/test.c index 0b94100c1..a30a5087d 100644 --- a/coreutils/test.c +++ b/coreutils/test.c | |||
@@ -23,7 +23,11 @@ | |||
23 | #include "libbb.h" | 23 | #include "libbb.h" |
24 | #include <setjmp.h> | 24 | #include <setjmp.h> |
25 | 25 | ||
26 | /* This is a NOEXEC applet. Be very careful! */ | 26 | /* This is a NOFORK applet. Be very careful! */ |
27 | |||
28 | /* test_main() is called from shells, and we need to be extra careful here. | ||
29 | * This is true regardless of PREFER_APPLETS and STANDALONE_SHELL | ||
30 | * state. */ | ||
27 | 31 | ||
28 | 32 | ||
29 | /* test(1) accepts the following grammar: | 33 | /* test(1) accepts the following grammar: |
@@ -85,12 +89,12 @@ enum token { | |||
85 | RPAREN, | 89 | RPAREN, |
86 | OPERAND | 90 | OPERAND |
87 | }; | 91 | }; |
88 | #define is_int_op(a) (((unsigned char)((a) - INTEQ)) <= 5) | 92 | #define is_int_op(a) (((unsigned char)((a) - INTEQ)) <= 5) |
89 | #define is_str_op(a) (((unsigned char)((a) - STREZ)) <= 5) | 93 | #define is_str_op(a) (((unsigned char)((a) - STREZ)) <= 5) |
90 | #define is_file_op(a) (((unsigned char)((a) - FILNT)) <= 2) | 94 | #define is_file_op(a) (((unsigned char)((a) - FILNT)) <= 2) |
91 | #define is_file_access(a) (((unsigned char)((a) - FILRD)) <= 2) | 95 | #define is_file_access(a) (((unsigned char)((a) - FILRD)) <= 2) |
92 | #define is_file_type(a) (((unsigned char)((a) - FILREG)) <= 5) | 96 | #define is_file_type(a) (((unsigned char)((a) - FILREG)) <= 5) |
93 | #define is_file_bit(a) (((unsigned char)((a) - FILSUID)) <= 2) | 97 | #define is_file_bit(a) (((unsigned char)((a) - FILSUID)) <= 2) |
94 | enum token_types { | 98 | enum token_types { |
95 | UNOP, | 99 | UNOP, |
96 | BINOP, | 100 | BINOP, |
@@ -153,13 +157,33 @@ typedef int64_t arith_t; | |||
153 | typedef int arith_t; | 157 | typedef int arith_t; |
154 | #endif | 158 | #endif |
155 | 159 | ||
156 | /* Cannot eliminate these static data (do the G trick) | 160 | |
157 | * because of test_main usage from other applets */ | 161 | /* We try to minimize both static and stack usage. */ |
158 | static char **t_wp; | 162 | struct statics { |
159 | static const struct t_op *t_wp_op; | 163 | char **t_wp; |
160 | static gid_t *group_array; | 164 | const struct t_op *t_wp_op; |
161 | static int ngroups; | 165 | gid_t *group_array; |
162 | static jmp_buf leaving; | 166 | int ngroups; |
167 | jmp_buf leaving; | ||
168 | }; | ||
169 | |||
170 | /* Make it reside in writable memory, yet make compiler understand | ||
171 | * that it is not going to change. */ | ||
172 | static struct statics *const ptr_to_statics __attribute__ ((section (".data"))); | ||
173 | |||
174 | #define S (*ptr_to_statics) | ||
175 | #define t_wp (S.t_wp ) | ||
176 | #define t_wp_op (S.t_wp_op ) | ||
177 | #define group_array (S.group_array ) | ||
178 | #define ngroups (S.ngroups ) | ||
179 | #define leaving (S.leaving ) | ||
180 | |||
181 | #define INIT_S() do { \ | ||
182 | (*(struct statics**)&ptr_to_statics) = xzalloc(sizeof(S)); \ | ||
183 | } while (0) | ||
184 | #define DEINIT_S() do { \ | ||
185 | free(ptr_to_statics); \ | ||
186 | } while (0) | ||
163 | 187 | ||
164 | static arith_t primary(enum token n); | 188 | static arith_t primary(enum token n); |
165 | 189 | ||
@@ -550,9 +574,13 @@ int test_main(int argc, char **argv) | |||
550 | argv[argc] = NULL; | 574 | argv[argc] = NULL; |
551 | } | 575 | } |
552 | 576 | ||
577 | /* We must do DEINIT_S() prior to returning */ | ||
578 | INIT_S(); | ||
579 | |||
553 | res = setjmp(leaving); | 580 | res = setjmp(leaving); |
554 | if (res) | 581 | if (res) { |
555 | return res; | 582 | goto ret; |
583 | } | ||
556 | 584 | ||
557 | /* resetting ngroups is probably unnecessary. it will | 585 | /* resetting ngroups is probably unnecessary. it will |
558 | * force a new call to getgroups(), which prevents using | 586 | * force a new call to getgroups(), which prevents using |
@@ -565,24 +593,30 @@ int test_main(int argc, char **argv) | |||
565 | ngroups = 0; | 593 | ngroups = 0; |
566 | 594 | ||
567 | /* Implement special cases from POSIX.2, section 4.62.4 */ | 595 | /* Implement special cases from POSIX.2, section 4.62.4 */ |
568 | if (argc == 1) | 596 | if (argc == 1) { |
569 | return 1; | 597 | res = 1; |
570 | if (argc == 2) | 598 | goto ret; |
571 | return *argv[1] == '\0'; | 599 | } |
572 | //assert(argc); | 600 | if (argc == 2) { |
601 | res = (*argv[1] == '\0'); | ||
602 | goto ret; | ||
603 | } | ||
604 | |||
573 | /* remember if we saw argc==4 which wants *no* '!' test */ | 605 | /* remember if we saw argc==4 which wants *no* '!' test */ |
574 | _off = argc - 4; | 606 | _off = argc - 4; |
575 | if (_off ? | 607 | if (_off ? (LONE_CHAR(argv[1], '!')) |
576 | (LONE_CHAR(argv[1], '!')) | 608 | : (argv[1][0] != '!' || argv[1][1] != '\0') |
577 | : (argv[1][0] != '!' || argv[1][1] != '\0')) | 609 | ) { |
578 | { | 610 | if (argc == 3) { |
579 | if (argc == 3) | 611 | res = (*argv[2] != '\0'); |
580 | return *argv[2] != '\0'; | 612 | goto ret; |
613 | } | ||
581 | 614 | ||
582 | t_lex(argv[2 + _off]); | 615 | t_lex(argv[2 + _off]); |
583 | if (t_wp_op && t_wp_op->op_type == BINOP) { | 616 | if (t_wp_op && t_wp_op->op_type == BINOP) { |
584 | t_wp = &argv[1 + _off]; | 617 | t_wp = &argv[1 + _off]; |
585 | return binop() == _off; | 618 | res = (binop() == _off); |
619 | goto ret; | ||
586 | } | 620 | } |
587 | } | 621 | } |
588 | t_wp = &argv[1]; | 622 | t_wp = &argv[1]; |
@@ -590,7 +624,9 @@ int test_main(int argc, char **argv) | |||
590 | 624 | ||
591 | if (*t_wp != NULL && *++t_wp != NULL) { | 625 | if (*t_wp != NULL && *++t_wp != NULL) { |
592 | bb_error_msg("%s: unknown operand", *t_wp); | 626 | bb_error_msg("%s: unknown operand", *t_wp); |
593 | return 2; | 627 | res = 2; |
594 | } | 628 | } |
629 | ret: | ||
630 | DEINIT_S(); | ||
595 | return res; | 631 | return res; |
596 | } | 632 | } |