aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-06-17 12:30:25 +0100
committerPeter Maydell <peter.maydell@linaro.org>2014-10-28 18:35:54 +0000
commit5618d4d833a7cd78caf81aa4c6ec8c1f562c1e13 (patch)
treebd97f0a73f11898d8d08288937f26c7e5b6b6c11
parent3a037cb22025e39279f8c93ccc8b5b20ee14e256 (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.h4
-rw-r--r--android-console.c57
-rw-r--r--monitor.c71
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 <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 4c2cae39ea..fc38c913f8 100644
--- a/monitor.c
+++ b/monitor.c
@@ -889,6 +889,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 <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 (;;) {
+ 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");