From 92b582ed62ca4f21f469d71637befb0880555b7a Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 12 May 2019 14:09:51 +0200 Subject: [PATCH] helper/command: fix printing usage for incomplete commands The commit "helper/command: do not replace new commands with ocd_ prefix" breaks the print of usage text when a multi-word command is typed incompletely. Fix it by explicitly running the "usage" command. Change-Id: I46f8e521d9b6ac617bff8938cf8fc96f0ade45c8 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5166 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/helper/command.c | 66 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/src/helper/command.c b/src/helper/command.c index ddf77d1872..e8ade3f703 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -968,6 +968,65 @@ static int command_unknown_find(unsigned argc, Jim_Obj *const *argv, return command_unknown_find(--argc, ++argv, (*out)->children, out); } +static char *alloc_concatenate_strings(int argc, Jim_Obj * const *argv) +{ + char *prev, *all; + int i; + + assert(argc >= 1); + + all = strdup(Jim_GetString(argv[0], NULL)); + if (!all) { + LOG_ERROR("Out of memory"); + return NULL; + } + + for (i = 1; i < argc; ++i) { + prev = all; + all = alloc_printf("%s %s", all, Jim_GetString(argv[i], NULL)); + free(prev); + if (!all) { + LOG_ERROR("Out of memory"); + return NULL; + } + } + + return all; +} + +static int run_usage(Jim_Interp *interp, int argc_valid, int argc, Jim_Obj * const *argv) +{ + struct command_context *cmd_ctx = current_command_context(interp); + char *command; + int retval; + + assert(argc_valid >= 1); + assert(argc >= argc_valid); + + command = alloc_concatenate_strings(argc_valid, argv); + if (!command) + return JIM_ERR; + + retval = command_run_linef(cmd_ctx, "usage %s", command); + if (retval != ERROR_OK) { + LOG_ERROR("unable to execute command \"usage %s\"", command); + return JIM_ERR; + } + + if (argc_valid == argc) + LOG_ERROR("%s: command requires more arguments", command); + else { + free(command); + command = alloc_concatenate_strings(argc - argc_valid, argv + argc_valid); + if (!command) + return JIM_ERR; + LOG_ERROR("invalid subcommand \"%s\"", command); + } + + free(command); + return retval; +} + static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { const char *cmd_name = Jim_GetString(argv[0], NULL); @@ -996,13 +1055,10 @@ static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv) count = remaining + 1; start = argv + (argc - remaining - 1); } else { - c = command_find(cmd_ctx->commands, "usage"); - if (NULL == c) { - LOG_ERROR("unknown command, but usage is missing too"); - return JIM_ERR; - } count = argc - remaining; start = argv; + run_usage(interp, count, argc, start); + return JIM_ERR; } /* pass the command through to the intended handler */ if (c->jim_handler) { -- 2.30.2