[RFC] redo --help parsing
Bernhard Fischer
rep.nop at aon.at
Fri Jun 9 06:51:07 PDT 2006
Hi,
[post 1.2.0 stuff, probably..]
First a quick question.
IIRC there was demand to be able to emit a list of available applets
which can be parsed easily ¹).
Therefor, i'm thinking about adding the possibility to writeout the
applets by something like
$ ./busybox --list
[ [[ false lash ls sh test true
To stdout, without "busybox" and not comma separated.
I imagine this to be configurable via something like the --install
config option, just for --list.
Does that sound ok?
Now a proposal with an unfinished patchlet to show what i mean:
Currently we parse for --help in more than one place.
The attached patch
- removes this double-parsing
- moves the static busybox help banner to usage.h
text data bss dec hex filename
1788 0 4 1792 700 applets/applets.o.orig
676 0 0 676 2a4 applets/busybox.o.orig
2464 0 4 2468 9a4 (TOTALS)
text data bss dec hex filename
2238 0 4 2242 8c2 applets/applets.o
121 0 0 121 79 applets/busybox.o
2359 0 4 2363 93b (TOTALS)
function old new delta
bb_show_usage 89 226 +137
.rodata 4268 4300 +32
run_applet_by_name 113 88 -25
busybox_main 222 32 -190
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/2 up/down: 169/-215) Total: -46 bytes
The functionality is the same as before (patch will be fixed to print to
stderr to match the old behaviour) except that i dropped support for
this sequence:
$ ./busybox --help ls
as it doesn't make sense, imho.
./busybox; ./busybox --help; ./ls --help; ./busybox ls --help
work as before.
Is this proposed patch something we want to have, generally?
Thanks for your time and for your comments.
Bernhard
¹) Currently doing something like this works, but is not exactly
elegant:
./busybox 2>&1 | awk \
'{if(/^Curr/){i=1;};if(((i>0)&&(!/^Currently/))&&(!/^$/)){print}}'
-------------- next part --------------
Index: include/usage.h
===================================================================
--- include/usage.h (revision 15346)
+++ include/usage.h (working copy)
@@ -89,6 +89,11 @@
"$ basename /foo/bar.txt .txt\n" \
"bar"
+#define bbconfig_trivial_usage \
+ ""
+#define bbconfig_full_usage \
+ "Print the config file which built busybox"
+
#define bunzip2_trivial_usage \
"[OPTION]... [FILE]"
#define bunzip2_full_usage \
@@ -97,6 +102,16 @@
"\t-c\tWrite output to standard output\n" \
"\t-f\tForce"
+#define busybox_trivial_usage \
+ "[function] [arguments]...\n" \
+ " or: [function] [arguments]...\n\n" \
+ "\tBusyBox is a multi-call binary that combines many common Unix\n" \
+ "\tutilities into a single executable. Most people will create a\n" \
+ "\tlink to busybox for each function they wish to use and BusyBox\n" \
+ "\twill act like whatever it was invoked as!\n" \
+ "\nCurrently defined functions:"
+#define busybox_full_usage \
+ ""
#define busybox_notes_usage \
"Hello world!\n"
@@ -259,11 +274,6 @@
"\t-2\tSuppress lines unique to FILE2\n" \
"\t-3\tSuppress lines common to both files"
-#define bbconfig_trivial_usage \
- ""
-#define bbconfig_full_usage \
- "Print the config file which built busybox"
-
#define cp_trivial_usage \
"[OPTION]... SOURCE DEST"
#define cp_full_usage \
Index: include/applets.h
===================================================================
--- include/applets.h (revision 15346)
+++ include/applets.h (working copy)
@@ -59,7 +59,7 @@
USE_BBCONFIG(APPLET(bbconfig, _BB_DIR_BIN, _BB_SUID_NEVER))
USE_BUNZIP2(APPLET(bunzip2, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
/* Always enabled. */
-APPLET_NOUSAGE(busybox, busybox, _BB_DIR_BIN, _BB_SUID_MAYBE)
+APPLET(busybox, _BB_DIR_BIN, _BB_SUID_MAYBE)
USE_BUNZIP2(APPLET_ODDNAME(bzcat, bunzip2, _BB_DIR_USR_BIN, _BB_SUID_NEVER, bzcat))
USE_CAL(APPLET(cal, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
USE_CAT(APPLET(cat, _BB_DIR_BIN, _BB_SUID_NEVER))
Index: applets/applets.c
===================================================================
--- applets/applets.c (revision 15346)
+++ applets/applets.c (working copy)
@@ -437,6 +437,11 @@
#define unpack_usage_messages() usage_messages
#endif /* ENABLE_FEATURE_COMPRESS_USAGE */
+/*static const char* busybox_usage(void)
+{
+ return buf;
+}
+*/
void bb_show_usage (void)
{
if (ENABLE_SHOW_USAGE) {
@@ -448,11 +453,36 @@
if (!*usage_string++) --i;
format_string = "%s\n\nUsage: %s %s\n\n";
- if (*usage_string == '\b')
- format_string = "%s\n\nNo help available.\n\n";
+ if (*usage_string == '\b') {
+ format_string = "%s\n\nNo help available.\n\n";
+ }
fprintf (stderr, format_string, bb_msg_full_version,
applet_using->name, usage_string);
+ if (!strncmp(applet_using->name, "busybox", 7)) {
+ /* emit a list of available applets */
+ const struct BB_applet *a;
+ int col = 0, output_width;
+#if 1
+ if (ENABLE_FEATURE_AUTOWIDTH) {
+ /* Obtain the terminal width. */
+ get_terminal_width_height(0, &output_width, NULL);
+ /* leading tab and room to wrap */
+ output_width -= 20;
+ } else
+#endif
+ output_width = 60;
+
+ for(a = applets; a->name;) {
+ col += printf("%s%s", (col ? ", " : "\t"), (a++)->name);
+ if (col > output_width && a->name) {
+ printf(",\n");
+ col = 0;
+ }
+ }
+
}
+ printf("\n\n");
+ }
exit (bb_default_error_retval);
}
@@ -475,9 +505,12 @@
void run_applet_by_name (const char *name, int argc, char **argv)
{
+//fprintf(stderr,"run_applet_by_name='%s' argc=%d, argv='%s'\n", name,argc,argv);
+ if (name == NULL)
+ bb_show_usage();
if(ENABLE_FEATURE_SUID_CONFIG) parse_config_file ();
- if(!strncmp(name, "busybox", 7)) busybox_main(argc, argv);
+// if(!strncmp(name, "busybox", 7)) busybox_main(argc, argv);
/* Do a binary search to find the applet entry given the name. */
applet_using = find_applet_by_name(name);
if(applet_using) {
@@ -486,4 +519,5 @@
if(ENABLE_FEATURE_SUID) check_suid (applet_using);
exit ((*(applet_using->main)) (argc, argv));
}
+// bb_show_usage();
}
Index: applets/busybox.c
===================================================================
--- applets/busybox.c (revision 15346)
+++ applets/busybox.c (working copy)
@@ -75,7 +75,7 @@
if (*(s++) == '/') bb_applet_name = s;
/* Set locale for everybody except `init' */
- if(ENABLE_LOCALE_SUPPORT && getpid() != 1)
+ if (ENABLE_LOCALE_SUPPORT && getpid() != 1)
setlocale(LC_ALL, "");
run_applet_by_name(bb_applet_name, argc, argv);
@@ -112,43 +112,7 @@
return rc;
}
- /* Deal with --help. (Also print help when called with no arguments) */
+ run_applet_by_name(argv[1], argc-1, argv+1);
- if (argc==1 || !strcmp(argv[1],"--help") ) {
- if (argc>2) {
- run_applet_by_name(bb_applet_name=argv[2], 2, argv);
- } else {
- const struct BB_applet *a;
- int col, output_width;
-
- if (ENABLE_FEATURE_AUTOWIDTH) {
- /* Obtain the terminal width. */
- get_terminal_width_height(0, &output_width, NULL);
- /* leading tab and room to wrap */
- output_width -= 20;
- } else output_width = 60;
-
- printf("%s\n\n"
- "Usage: busybox [function] [arguments]...\n"
- " or: [function] [arguments]...\n\n"
- "\tBusyBox is a multi-call binary that combines many common Unix\n"
- "\tutilities into a single executable. Most people will create a\n"
- "\tlink to busybox for each function they wish to use and BusyBox\n"
- "\twill act like whatever it was invoked as!\n"
- "\nCurrently defined functions:\n", bb_msg_full_version);
-
- col=0;
- for(a = applets; a->name;) {
- col += printf("%s%s", (col ? ", " : "\t"), (a++)->name);
- if (col > output_width && a->name) {
- printf(",\n");
- col = 0;
- }
- }
- printf("\n\n");
- exit(0);
- }
- } else run_applet_by_name(argv[1], argc-1, argv+1);
-
bb_error_msg_and_die("applet not found");
}
More information about the busybox
mailing list