From c9bfac34bad08e5d115c6693e97a372cc5f4572e Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Tue, 17 Jun 2014 12:30:25 +0100 Subject: android-console: Make 'help' output match the classic emulator Implement the 'help' command ourselves rather than using the monitor's usual version, so we can make the output text match the format of the classic emulator. This might not be necessary but perhaps external tools are parsing the output to see what commands are supported. Signed-off-by: Peter Maydell --- android-commands.h | 4 +-- android-console.c | 57 ++++++++++++++++++++++++++++++++++--------- monitor.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+), 13 deletions(-) diff --git a/android-commands.h b/android-commands.h index 34a4fb34e3..1bfd15d8e2 100644 --- a/android-commands.h +++ b/android-commands.h @@ -28,10 +28,10 @@ static mon_cmd_t android_redir_cmds[] = { static mon_cmd_t android_cmds[] = { { .name = "help|h|?", - .args_type = "name:S?", + .args_type = "helptext:S?", .params = "", .help = "print a list of commands", - .mhandler.cmd = do_help_cmd, + .mhandler.cmd = android_console_help, }, { .name = "kill", diff --git a/android-console.c b/android-console.c index 1ff3341174..c2e41da74e 100644 --- a/android-console.c +++ b/android-console.c @@ -240,18 +240,53 @@ void android_console_redir_remove(Monitor *mon, const QDict *qdict) } #endif +static const char *redir_list_help = + "list current port redirections. " + "use 'redir add' and 'redir del' to add and remove them\n" + "OK\n"; + +static const char *redir_add_help = + "add a new port redirection, arguments must be:\n" + "\n" + " redir add ::\n" + "\n" + "where: is either 'tcp' or 'udp'\n" + " a number indicating which " + "port on the host to open\n" + " a number indicating which " + "port to route to on the device\n" + "\n" + "as an example, 'redir tcp:5000:6000' will allow any packets sent to\n" + "the host's TCP port 5000 to be routed to TCP port 6000 of the " + "emulated device\n" + "OK\n"; + +static const char *redir_del_help = + "remove a port redirecion that was created with 'redir add', " + "arguments must be:\n\n" + " redir del :\n\n" + "see the 'help redir add' for the meaning of and \n" + "OK\n"; + void android_console_redir(Monitor *mon, const QDict *qdict) { - const char *arg = qdict_get_try_str(qdict, "arg"); - - if (!arg) { - goto fail; + /* This only gets called for bad subcommands and help requests */ + const char *helptext = qdict_get_try_str(qdict, "helptext"); + + monitor_printf(mon, "help text %s\n", helptext ? helptext : "(null)"); + + if (helptext) { + if (strstr(helptext, "add")) { + monitor_printf(mon, "%s", redir_add_help); + return; + } else if (strstr(helptext, "del")) { + monitor_printf(mon, "%s", redir_del_help); + return; + } else if (strstr(helptext, "list")) { + monitor_printf(mon, "%s", redir_list_help); + return; + } } - - monitor_printf(mon, "redir: arg %s\n", arg); - return; - -fail: monitor_printf(mon, "allows you to add, list and remove and/or " "PORT redirection from the host to the device\n" "as an example, 'redir tcp:5000:6000' will route " @@ -262,6 +297,6 @@ fail: " list list current redirections\n" " add add new redirection\n" " del remove existing redirection\n" - "\n" - "KO: missing sub-command\n"); + "\n%s\n", + helptext ? "OK" : "KO: missing sub-command"); } diff --git a/monitor.c b/monitor.c index 50ad7d15f2..f0718786c1 100644 --- a/monitor.c +++ b/monitor.c @@ -940,6 +940,77 @@ static void do_help_cmd(Monitor *mon, const QDict *qdict) help_cmd(mon, qdict_get_try_str(qdict, "name")); } +static void android_console_help(Monitor *mon, const QDict *qdict) +{ + const char *name = qdict_get_try_str(qdict, "helptext"); + const mon_cmd_t *cmd; + const mon_cmd_t *cmds = mon->cmd_table; + char *args[MAX_ARGS]; + int nb_args = 0; + int thisarg = 0; + const mon_cmd_t *parent_cmd = NULL; + + if (!name) { + /* No arguments, just print command list */ + monitor_printf(mon, "Android console command help:\n\n"); + for (cmd = cmds; cmd->name; cmd++) { + monitor_printf(mon, " %-15s %s\n", cmd->name, cmd->help); + } + monitor_printf(mon, + "\ntry 'help ' for command-specific help\n"); + return; + } + + /* With an argument, look for it */ + if (!parse_cmdline(name, &nb_args, args) < 0 || nb_args == 0) { + monitor_printf(mon, "KO: couldn't parse help text\n"); + return; + } + + for (;;) { + for (cmd = cmds; cmd->name; cmd++) { + if (compare_cmd(args[thisarg], cmd->name)) { + break; + } + } + if (!cmd->name) { + /* command/subcommand not found */ + monitor_printf(mon, "try one of these instead:\n\n"); + for (cmd = cmds; cmd->name; cmd++) { + int i; + monitor_printf(mon, " "); + for (i = 0; i < thisarg; i++) { + monitor_printf(mon, "%s ", args[i]); + } + monitor_printf(mon, "%s\n", cmd->name); + } + monitor_printf(mon, "\nKO: unknown command\n"); + return; + } + + thisarg++; + + if (thisarg >= nb_args || !cmd->sub_table) { + /* For subtables, the command handler for the entry in the 1st + * level of commands deals with help (including "help subcommand" + * where there is no following second level command in the help + * string). For top level commands, we just print the short text. + */ + if (parent_cmd) { + parent_cmd->mhandler.cmd(mon, qdict); + } else if (cmd->sub_table) { + cmd->mhandler.cmd(mon, qdict); + } else { + monitor_printf(mon, "%s\nOK\n", cmd->help); + } + return; + } + + parent_cmd = cmd; + cmds = cmd->sub_table; + } +} + static void do_trace_event_set_state(Monitor *mon, const QDict *qdict) { const char *tp_name = qdict_get_str(qdict, "name"); -- cgit v1.2.3