aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-04-08 21:13:28 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-04-08 21:13:28 +0000
commit79cedcb2c0d88531323e5c2a31fd8465241fbffa (patch)
treed4a8ab06d87bb96cf8d5c003b464f8e1dfb53fbb
parent643dcf00e32bb131b8a8b77ef570289ed27dae57 (diff)
downloadbusybox-w32-79cedcb2c0d88531323e5c2a31fd8465241fbffa.tar.gz
busybox-w32-79cedcb2c0d88531323e5c2a31fd8465241fbffa.tar.bz2
busybox-w32-79cedcb2c0d88531323e5c2a31fd8465241fbffa.zip
Avoid linking in printf/bsearch if possible. -20k for static bbox with
"basename", "true" and "false" only. function old new delta full_write2_str - 25 +25 bb_show_usage 183 202 +19 main 883 898 +15 run_applet_and_exit 501 507 +6
-rw-r--r--applets/applet_tables.c14
-rw-r--r--libbb/appletlib.c96
2 files changed, 83 insertions, 27 deletions
diff --git a/applets/applet_tables.c b/applets/applet_tables.c
index 35b099eb4..17135ddc1 100644
--- a/applets/applet_tables.c
+++ b/applets/applet_tables.c
@@ -47,6 +47,7 @@ int main(int argc, char **argv)
47{ 47{
48 int i; 48 int i;
49 int ofs; 49 int ofs;
50 unsigned MAX_APPLET_NAME_LEN = 1;
50 51
51 qsort(applets, NUM_APPLETS, sizeof(applets[0]), cmp_name); 52 qsort(applets, NUM_APPLETS, sizeof(applets[0]), cmp_name);
52 53
@@ -71,18 +72,21 @@ int main(int argc, char **argv)
71 72
72 puts("/* This is a generated file, don't edit */\n"); 73 puts("/* This is a generated file, don't edit */\n");
73 74
75 printf("#define NUM_APPLETS %u\n", NUM_APPLETS);
74 if (NUM_APPLETS == 1) { 76 if (NUM_APPLETS == 1) {
75 printf("#define SINGLE_APPLET_STR \"%s\"\n", applets[0].name); 77 printf("#define SINGLE_APPLET_STR \"%s\"\n", applets[0].name);
76 printf("#define SINGLE_APPLET_MAIN %s_main\n\n", applets[0].name); 78 printf("#define SINGLE_APPLET_MAIN %s_main\n", applets[0].name);
77 } 79 }
78 80
79 puts("const char applet_names[] ALIGN1 = \"\""); 81 puts("\nconst char applet_names[] ALIGN1 = \"\"");
80 for (i = 0; i < NUM_APPLETS; i++) { 82 for (i = 0; i < NUM_APPLETS; i++) {
81 printf("\"%s\" \"\\0\"\n", applets[i].name); 83 printf("\"%s\" \"\\0\"\n", applets[i].name);
84 if (MAX_APPLET_NAME_LEN < strlen(applets[i].name))
85 MAX_APPLET_NAME_LEN = strlen(applets[i].name);
82 } 86 }
83 puts(";"); 87 puts(";");
84 88
85 puts("int (*const applet_main[])(int argc, char **argv) = {"); 89 puts("\nint (*const applet_main[])(int argc, char **argv) = {");
86 for (i = 0; i < NUM_APPLETS; i++) { 90 for (i = 0; i < NUM_APPLETS; i++) {
87 printf("%s_main,\n", applets[i].main); 91 printf("%s_main,\n", applets[i].main);
88 } 92 }
@@ -113,8 +117,10 @@ int main(int argc, char **argv)
113 printf("0x%02x,\n", v); 117 printf("0x%02x,\n", v);
114 i++; 118 i++;
115 } 119 }
116 puts("};"); 120 puts("};\n");
117#endif 121#endif
118 122
123 printf("#define MAX_APPLET_NAME_LEN %u\n", MAX_APPLET_NAME_LEN);
124
119 return 0; 125 return 0;
120} 126}
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index a48a26003..ed7d3912b 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -12,6 +12,21 @@
12 * Licensed under GPLv2 or later, see file License in this tarball for details. 12 * Licensed under GPLv2 or later, see file License in this tarball for details.
13 */ 13 */
14 14
15/* We are trying to not use printf, this benefits the case when selected
16 * applets are really simple. Example:
17 *
18 * $ ./busybox
19 * ...
20 * Currently defined functions:
21 * basename, false, true
22 *
23 * $ size busybox
24 * text data bss dec hex filename
25 * 4473 52 72 4597 11f5 busybox
26 *
27 * FEATURE_INSTALLER or FEATURE_SUID will still link printf routines in. :(
28 */
29
15#include <assert.h> 30#include <assert.h>
16#include "busybox.h" 31#include "busybox.h"
17 32
@@ -81,6 +96,11 @@ static const char *unpack_usage_messages(void)
81#endif /* FEATURE_COMPRESS_USAGE */ 96#endif /* FEATURE_COMPRESS_USAGE */
82 97
83 98
99static void full_write2_str(const char *str)
100{
101 full_write(2, str, strlen(str));
102}
103
84void bb_show_usage(void) 104void bb_show_usage(void)
85{ 105{
86 if (ENABLE_SHOW_USAGE) { 106 if (ENABLE_SHOW_USAGE) {
@@ -90,18 +110,14 @@ void bb_show_usage(void)
90 const char *usage_string = p = unpack_usage_messages(); 110 const char *usage_string = p = unpack_usage_messages();
91 111
92 if (*p == '\b') { 112 if (*p == '\b') {
93 write(2, "\nNo help available.\n\n", 113 full_write2_str("\nNo help available.\n\n");
94 sizeof("\nNo help available.\n\n") - 1);
95 } else { 114 } else {
96 write(2, "\nUsage: "SINGLE_APPLET_STR" ", 115 full_write2_str("\nUsage: "SINGLE_APPLET_STR" ");
97 sizeof("\nUsage: "SINGLE_APPLET_STR" ") - 1); 116 full_write2_str(p);
98 write(2, p, strlen(p)); 117 full_write2_str("\n\n");
99 write(2, "\n\n", 2);
100 } 118 }
101 dealloc_usage_messages((char*)usage_string); 119 dealloc_usage_messages((char*)usage_string);
102#else 120#else
103// TODO: in this case, stdio is sucked in by busybox_main() anyway...
104 const char *format_string;
105 const char *p; 121 const char *p;
106 const char *usage_string = p = unpack_usage_messages(); 122 const char *usage_string = p = unpack_usage_messages();
107 int ap = find_applet_by_name(applet_name); 123 int ap = find_applet_by_name(applet_name);
@@ -112,32 +128,52 @@ void bb_show_usage(void)
112 while (*p++) continue; 128 while (*p++) continue;
113 ap--; 129 ap--;
114 } 130 }
115 fprintf(stderr, "%s multi-call binary\n", bb_banner); 131 full_write2_str(bb_banner);
116 format_string = "\nUsage: %s %s\n\n"; 132 full_write2_str(" multi-call binary\n");
117 if (*p == '\b') 133 if (*p == '\b')
118 format_string = "\nNo help available.\n\n"; 134 full_write2_str("\nNo help available.\n\n");
119 fprintf(stderr, format_string, applet_name, p); 135 else {
136 full_write2_str("\nUsage: ");
137 full_write2_str(applet_name);
138 full_write2_str(" ");
139 full_write2_str(p);
140 full_write2_str("\n\n");
141 }
120 dealloc_usage_messages((char*)usage_string); 142 dealloc_usage_messages((char*)usage_string);
121#endif 143#endif
122 } 144 }
123 xfunc_die(); 145 xfunc_die();
124} 146}
125 147
126 148#if NUM_APPLETS > 8
127/* NB: any char pointer will work as well, not necessarily applet_names */ 149/* NB: any char pointer will work as well, not necessarily applet_names */
128static int applet_name_compare(const void *name, const void *v) 150static int applet_name_compare(const void *name, const void *v)
129{ 151{
130 int i = (const char *)v - applet_names; 152 int i = (const char *)v - applet_names;
131 return strcmp(name, APPLET_NAME(i)); 153 return strcmp(name, APPLET_NAME(i));
132} 154}
155#endif
133int find_applet_by_name(const char *name) 156int find_applet_by_name(const char *name)
134{ 157{
158#if NUM_APPLETS > 8
135 /* Do a binary search to find the applet entry given the name. */ 159 /* Do a binary search to find the applet entry given the name. */
136 const char *p; 160 const char *p;
137 p = bsearch(name, applet_names, ARRAY_SIZE(applet_main), 1, applet_name_compare); 161 p = bsearch(name, applet_names, ARRAY_SIZE(applet_main), 1, applet_name_compare);
138 if (!p) 162 if (!p)
139 return -1; 163 return -1;
140 return p - applet_names; 164 return p - applet_names;
165#else
166 /* A version which does not pull in bsearch */
167 int i = 0;
168 const char *p = applet_names;
169 while (i < NUM_APPLETS) {
170 if (strcmp(name, p) == 0)
171 return i;
172 p += strlen(p) + 1;
173 i++;
174 }
175 return -1;
176#endif
141} 177}
142 178
143 179
@@ -604,10 +640,11 @@ static int busybox_main(char **argv)
604 get_terminal_width_height(0, &output_width, NULL); 640 get_terminal_width_height(0, &output_width, NULL);
605 } 641 }
606 /* leading tab and room to wrap */ 642 /* leading tab and room to wrap */
607 output_width -= sizeof("start-stop-daemon, ") + 8; 643 output_width -= MAX_APPLET_NAME_LEN + 8;
608 644
609 printf("%s multi-call binary\n", bb_banner); /* reuse const string... */ 645 full_write2_str(bb_banner); /* reuse const string... */
610 printf("Copyright (C) 1998-2007 Erik Andersen, Rob Landley, Denys Vlasenko\n" 646 full_write2_str(" multi-call binary\n"
647 "Copyright (C) 1998-2007 Erik Andersen, Rob Landley, Denys Vlasenko\n"
611 "and others. Licensed under GPLv2.\n" 648 "and others. Licensed under GPLv2.\n"
612 "See source distribution for full notice.\n" 649 "See source distribution for full notice.\n"
613 "\n" 650 "\n"
@@ -623,14 +660,18 @@ static int busybox_main(char **argv)
623 col = 0; 660 col = 0;
624 a = applet_names; 661 a = applet_names;
625 while (*a) { 662 while (*a) {
663 int len;
626 if (col > output_width) { 664 if (col > output_width) {
627 puts(","); 665 full_write2_str(",\n");
628 col = 0; 666 col = 0;
629 } 667 }
630 col += printf("%s%s", (col ? ", " : "\t"), a); 668 full_write2_str(col ? ", " : "\t");
631 a += strlen(a) + 1; 669 full_write2_str(a);
670 len = strlen(a);
671 col += len + 2;
672 a += len + 1;
632 } 673 }
633 puts("\n"); 674 full_write2_str("\n\n");
634 return 0; 675 return 0;
635 } 676 }
636 677
@@ -659,7 +700,11 @@ static int busybox_main(char **argv)
659 * "#!/bin/busybox"-style wrappers */ 700 * "#!/bin/busybox"-style wrappers */
660 applet_name = bb_get_last_path_component_nostrip(argv[0]); 701 applet_name = bb_get_last_path_component_nostrip(argv[0]);
661 run_applet_and_exit(applet_name, argv); 702 run_applet_and_exit(applet_name, argv);
662 bb_error_msg_and_die("applet not found"); 703
704 /*bb_error_msg_and_die("applet not found"); - sucks in printf */
705 full_write2_str(applet_name);
706 full_write2_str(": applet not found\n");
707 xfunc_die();
663} 708}
664 709
665void run_applet_no_and_exit(int applet_no, char **argv) 710void run_applet_no_and_exit(int applet_no, char **argv)
@@ -701,7 +746,8 @@ int main(int argc ATTRIBUTE_UNUSED, char **argv)
701{ 746{
702#if ENABLE_FEATURE_INDIVIDUAL 747#if ENABLE_FEATURE_INDIVIDUAL
703 /* Only one applet is selected by the user! */ 748 /* Only one applet is selected by the user! */
704 lbb_prepare(SINGLE_APPLET_STR USE_FEATURE_INDIVIDUAL(, argv)); 749 /* applet_names in this case is just "applet\0\0" */
750 lbb_prepare(applet_names USE_FEATURE_INDIVIDUAL(, argv));
705 return SINGLE_APPLET_MAIN(argc, argv); 751 return SINGLE_APPLET_MAIN(argc, argv);
706#else 752#else
707 lbb_prepare("busybox" USE_FEATURE_INDIVIDUAL(, argv)); 753 lbb_prepare("busybox" USE_FEATURE_INDIVIDUAL(, argv));
@@ -721,6 +767,10 @@ int main(int argc ATTRIBUTE_UNUSED, char **argv)
721 parse_config_file(); /* ...maybe, if FEATURE_SUID_CONFIG */ 767 parse_config_file(); /* ...maybe, if FEATURE_SUID_CONFIG */
722 768
723 run_applet_and_exit(applet_name, argv); 769 run_applet_and_exit(applet_name, argv);
724 bb_error_msg_and_die("applet not found"); 770
771 /*bb_error_msg_and_die("applet not found"); - sucks in printf */
772 full_write2_str(applet_name);
773 full_write2_str(": applet not found\n");
774 xfunc_die();
725#endif 775#endif
726} 776}