diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-04-08 21:13:28 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-04-08 21:13:28 +0000 |
commit | 79cedcb2c0d88531323e5c2a31fd8465241fbffa (patch) | |
tree | d4a8ab06d87bb96cf8d5c003b464f8e1dfb53fbb | |
parent | 643dcf00e32bb131b8a8b77ef570289ed27dae57 (diff) | |
download | busybox-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.c | 14 | ||||
-rw-r--r-- | libbb/appletlib.c | 96 |
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 | ||
99 | static void full_write2_str(const char *str) | ||
100 | { | ||
101 | full_write(2, str, strlen(str)); | ||
102 | } | ||
103 | |||
84 | void bb_show_usage(void) | 104 | void 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 */ |
128 | static int applet_name_compare(const void *name, const void *v) | 150 | static 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 | ||
133 | int find_applet_by_name(const char *name) | 156 | int 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 | ||
665 | void run_applet_no_and_exit(int applet_no, char **argv) | 710 | void 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 | } |