aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-06-17 12:30:25 +0100
committerAlex Bennée <alex.bennee@linaro.org>2014-12-19 12:29:36 +0000
commitc9c24adceb7bfaf9ebe0063d8283bf7b50551d5a (patch)
treea32603a0c62206ee844f660cbd2f40bc98e40bd6
parent483fbff485b3a9d6adc9e0df9074a99a972b1c00 (diff)
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 <peter.maydell@linaro.org>
-rw-r--r--android-commands.h6
-rw-r--r--android-console.c57
-rw-r--r--monitor.c78
3 files changed, 125 insertions, 16 deletions
diff --git a/android-commands.h b/android-commands.h
index 34a4fb34e..3d1423483 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",
@@ -53,7 +53,7 @@ static mon_cmd_t android_cmds[] = {
.params = "",
.help = "manage port redirections",
.mhandler.cmd = android_console_redir,
- .sub_table = android_redir_cmds,
+ .sub_cmds.static_table = android_redir_cmds,
},
{ NULL, NULL, },
};
diff --git a/android-console.c b/android-console.c
index 1ff334117..c2e41da74 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 <protocol>:<host-port>:<guest-port>\n"
+ "\n"
+ "where: <protocol> is either 'tcp' or 'udp'\n"
+ " <host-port> a number indicating which "
+ "port on the host to open\n"
+ " <guest-port> 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 <protocol>:<host-port>\n\n"
+ "see the 'help redir add' for the meaning of <protocol> and <host-port>\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 c758d6075..73b26df6b 100644
--- a/monitor.c
+++ b/monitor.c
@@ -911,6 +911,80 @@ static mon_cmd_t * get_command_table(Monitor *mon, cmd_table_t cmds)
}
}
+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 = get_command_table(mon, mon->cmds);
+ 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 <command>' 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 (;;) {
+ mon_cmd_t *sub_cmds;
+
+ 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++;
+ sub_cmds = get_command_table(mon, cmd->sub_cmds);
+
+ if (thisarg >= nb_args || !sub_cmds) {
+ /* 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 (sub_cmds) {
+ cmd->mhandler.cmd(mon, qdict);
+ } else {
+ monitor_printf(mon, "%s\nOK\n", cmd->help);
+ }
+ return;
+ }
+
+ parent_cmd = cmd;
+ cmds = sub_cmds;
+ }
+}
+
static void do_trace_event_set_state(Monitor *mon, const QDict *qdict)
{
const char *tp_name = qdict_get_str(qdict, "name");
@@ -3740,7 +3814,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
cmd = search_dispatch_table(table, cmdname);
if (!cmd) {
- if (mon->cmd_table == android_cmds) {
+ if (mon->flags & MONITOR_ANDROID_CONSOLE) {
monitor_printf(mon, "KO: unknown command, try 'help'\n");
} else {
monitor_printf(mon, "unknown command: '%.*s'\n",
@@ -5423,7 +5497,7 @@ Monitor * monitor_init(CharDriverState *chr, int flags)
mon->print_error = monitor_printf;
if (flags & MONITOR_ANDROID_CONSOLE) {
- mon->cmd_table = android_cmds;
+ mon->cmds.static_table = android_cmds;
mon->prompt = "";
mon->banner = "Android Console: type 'help' for a list of commands";
mon->print_error = android_monitor_print_error;