aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-11-30 07:29:05 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-11-30 07:29:05 +0000
commit6672c8e480994a3d9c928ddedd0542c9ed9b3271 (patch)
tree43fa46479002d6c7129c772adbf25d3b0cc8edde /coreutils
parentb539c8452f823a377bf629cf0e44ccda4a16c6c4 (diff)
downloadbusybox-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.c92
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)
94enum token_types { 98enum token_types {
95 UNOP, 99 UNOP,
96 BINOP, 100 BINOP,
@@ -153,13 +157,33 @@ typedef int64_t arith_t;
153typedef int arith_t; 157typedef 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. */
158static char **t_wp; 162struct statics {
159static const struct t_op *t_wp_op; 163 char **t_wp;
160static gid_t *group_array; 164 const struct t_op *t_wp_op;
161static int ngroups; 165 gid_t *group_array;
162static 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. */
172static 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
164static arith_t primary(enum token n); 188static 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}