Fix up help plumbing. It's got HELP_FLAGS now.

Last release "help toybox", "help -u", and "help -au" didn't work, and
the "see" logic was all wrong.

New rule: command --help and toybox --help command show toybox URL banner,
but "help command" doesn't.
This commit is contained in:
Rob Landley 2023-03-09 22:57:24 -06:00
parent dd56ea0864
commit 53272482ef
3 changed files with 33 additions and 23 deletions

25
main.c
View File

@ -76,31 +76,32 @@ static char *help_data =
#include "generated/newtoys.h"
;
void show_help(FILE *out, int full)
void show_help(FILE *out, int flags)
{
int i = toys.which-toy_list;
char *s, *ss;
if (!(full&2))
fprintf(out, "Toybox %s"USE_TOYBOX(" multicall binary")"%s\n\n",
toybox_version, (CFG_TOYBOX && i) ? " (see toybox --help)"
: " (see https://landley.net/toybox)");
if (CFG_TOYBOX_HELP) {
if (flags & HELP_HEADER)
fprintf(out, "Toybox %s"USE_TOYBOX(" multicall binary")"%s\n\n",
toybox_version, (CFG_TOYBOX && i) ? " (see toybox --help)"
: " (see https://landley.net/toybox)");
for (;;) {
s = help_data;
while (i--) s += strlen(s) + 1;
// If it's an alias, restart search for real name
if (*s != 255) break;
i = toy_find(++s)-toy_list;
if ((full&4) && toy_list[i].flags) {
fprintf(out, "See <a href=#%s>%s</a>\n", s, s);
if ((flags & HELP_SEE) && toy_list[i].flags) {
if (flags & HELP_HTML) fprintf(out, "See <a href=#%s>%s</a>\n", s, s);
else fprintf(out, "%s see %s\n", toys.which->name, s);
return;
}
}
if (full) fprintf(out, "%s\n", s);
if (!(flags & HELP_USAGE)) fprintf(out, "%s\n", s);
else {
strstart(&s, "usage: ");
for (ss = s; *ss && *ss!='\n'; ss++);
@ -124,9 +125,11 @@ void check_help(char **arg)
if (toys.which->flags&TOYFLAG_NOHELP) return;
if (!strcmp(*arg, "--help")) {
if (CFG_TOYBOX && toys.which == toy_list && arg[1])
if (CFG_TOYBOX && toys.which == toy_list && arg[1]) {
toys.which = 0;
if (!(toys.which = toy_find(arg[1]))) unknown(arg[1]);
show_help(stdout, 1);
}
show_help(stdout, HELP_HEADER);
xexit();
}

5
toys.h
View File

@ -82,6 +82,11 @@
// These live in main.c
#define HELP_USAGE 1 // usage: line only
#define HELP_HEADER 2 // Add Toybox header line to help output
#define HELP_SEE 4 // "See COMMAND" instead of dereferencing alias
#define HELP_HTML 8 // Output HTML
struct toy_list *toy_find(char *name);
void show_help(FILE *out, int full);
void check_help(char **arg);

View File

@ -30,44 +30,46 @@ static void do_help(struct toy_list *t)
xprintf("<a name=\"%s\"><h1>%s</h1><blockquote><pre>\n", t->name, t->name);
toys.which = t;
show_help(stdout, !FLAG(u)+(!!toys.argv[1]<<1)+(FLAG(h)<<2));
show_help(stdout, HELP_USAGE*FLAG(u) + (HELP_SEE|HELP_HTML)*FLAG(h));
if (FLAG(h)) xprintf("</blockquote></pre>\n");
}
// Simple help is just toys.which = toy_find("name"); show_help(stdout, 1);
// Simple help is just toys.which = toy_find("name"); show_help(stdout, 0);
// but iterating through html output and all commands is a bit more
void help_main(void)
{
int i;
long i;
// If called with no arguments as a builtin from the shell, show all builtins
if (toys.rebound && !*toys.optargs && !toys.optflags) {
for (i = 0; i < toys.toycount; i++) {
if (!(toy_list[i].flags&(TOYFLAG_NOFORK|TOYFLAG_MAYFORK))) continue;
toys.which = toy_list+i;
show_help(stdout, FLAG(u));
show_help(stdout, HELP_SEE|HELP_USAGE*!toys.optflags);
}
return;
}
if (!FLAG(a)) {
struct toy_list *t = toys.which;
struct toy_list *t = toys.which, *tt;
if (*toys.optargs && !(t = toy_find(*toys.optargs)))
error_exit("Unknown command '%s'", *toys.optargs);
do_help(t);
return;
// Zero which to include "toybox" in search, put it back for error msg
toys.which = 0;
tt = *toys.optargs ? toy_find(*toys.optargs) : t;
toys.which = t;
if (tt) return do_help(tt);
else error_exit("Unknown command '%s'", *toys.optargs);
}
if (FLAG(h)) {
sprintf(toybuf, "Toybox %s command help", toybox_version);
xprintf("<html>\n<title>%s</title>\n<body>\n<h1>%s</h1><hr /><p>",
toybuf, toybuf);
for (i=0; i<toys.toycount; i++)
if (toy_list[i].flags)
xprintf("<a href=\"#%s\">%s</a> \n", toy_list[i].name,toy_list[i].name);
for (i = 0; i<toys.toycount; i++) if (toy_list[i].flags)
xprintf("<a href=\"#%s\">%s</a>\n", toy_list[i].name,toy_list[i].name);
xprintf("</p>\n");
}