diff options
-rw-r--r-- | src/helper/command.c | 56 | ||||
-rw-r--r-- | src/helper/command.h | 1 | ||||
-rw-r--r-- | src/helper/startup.tcl | 18 |
3 files changed, 55 insertions, 20 deletions
diff --git a/src/helper/command.c b/src/helper/command.c index 87a898f2..f135bb03 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -250,6 +250,8 @@ static struct command *command_new(struct command_context *cmd_ctx, memset(c, 0, sizeof(struct command)); c->name = strdup(name); + if (help) + c->help = strdup(help); c->parent = parent; c->handler = handler; c->mode = mode; @@ -273,6 +275,8 @@ static void command_free(struct command *c) if (c->name) free(c->name); + if (c->help) + free((void*)c->help); free(c); } @@ -721,6 +725,52 @@ static int jim_capture(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return retcode; } +static COMMAND_HELPER(command_help_find, struct command *head, + struct command **out) +{ + if (0 == CMD_ARGC) + return ERROR_INVALID_ARGUMENTS; + *out = command_find(head, CMD_ARGV[0]); + if (NULL == *out) + return ERROR_INVALID_ARGUMENTS; + if (--CMD_ARGC == 0) + return ERROR_OK; + CMD_ARGV++; + return CALL_COMMAND_HANDLER(command_help_find, (*out)->children, out); +} + +static COMMAND_HELPER(command_help_show, struct command *c, unsigned n); + +static COMMAND_HELPER(command_help_show_list, struct command *head, unsigned n) +{ + for (struct command *c = head; NULL != c; c = c->next) + CALL_COMMAND_HANDLER(command_help_show, c, n); + return ERROR_OK; +} +static COMMAND_HELPER(command_help_show, struct command *c, unsigned n) +{ + command_run_linef(CMD_CTX, "cmd_help {%s} {%s} %d", command_name(c, ' '), + c->help ? : "no help available", n); + + if (++n >= 2) + return ERROR_OK; + + return CALL_COMMAND_HANDLER(command_help_show_list, c->children, n); +} +COMMAND_HANDLER(handle_help_command) +{ + struct command *c = CMD_CTX->commands; + + if (0 == CMD_ARGC) + return CALL_COMMAND_HANDLER(command_help_show_list, c, 0); + + int retval = CALL_COMMAND_HANDLER(command_help_find, c, &c); + if (ERROR_OK != retval) + return retval; + + return CALL_COMMAND_HANDLER(command_help_show, c, 0); +} + /* sleep command sleeps for <n> miliseconds * this is useful in target startup scripts */ @@ -831,6 +881,10 @@ struct command_context* command_init(const char *startup_tcl) "<n> [busy] - sleep for n milliseconds. " "\"busy\" means busy wait"); + register_command(context, NULL, "help", + &handle_help_command, COMMAND_ANY, + "[<command_name> ...] - show built-in command help"); + return context; } @@ -977,5 +1031,3 @@ COMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label) } return ERROR_OK; } - - diff --git a/src/helper/command.h b/src/helper/command.h index a7b422ad..837b4bdd 100644 --- a/src/helper/command.h +++ b/src/helper/command.h @@ -159,6 +159,7 @@ typedef __COMMAND_HANDLER((*command_handler_t)); struct command { char *name; + const char *help; struct command *parent; struct command *children; command_handler_t handler; diff --git a/src/helper/startup.tcl b/src/helper/startup.tcl index 30dc184f..ddfef1dc 100644 --- a/src/helper/startup.tcl +++ b/src/helper/startup.tcl @@ -58,24 +58,6 @@ proc cmd_help {cmdname h indent} { } } -#Print help text for a command. Word wrap -#help text that is too wide inside column. -proc help {args} { - global ocd_helptext - set cmd $args - foreach a [lsort $ocd_helptext] { - if {[string length $cmd] == 0 || \ - [string first $cmd $a] != -1 || \ - [string first $cmd [lindex $a 1]] != -1} \ - { - cmd_help [lindex $a 0] [lindex $a 1] 0 - } - } -} - -add_help_text help "Tcl implementation of help command" - - # If a fn is unknown to Tcl, we try to execute it as an OpenOCD command # # We also support two level commands. "flash banks" is translated to |