From e216186fab59d71fdee24af926d1807a1d7fc950 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 13 May 2020 01:59:59 +0200 Subject: [PATCH] helper/command: register full-name commands in jim While still keeping the tree of struct command, stop registering commands in jim by the root "word" only. Register the full-name of the command and pass as private data the struct command of the command itself. Still use the tree of struct command to un-register the commands. Some "native" commands (.jim_handler) share the same handler, then the handler checks the command name to run the right code. Now argv[0] returns the full-name of the command, so check the name by looking in the struct command passed as private data. Change-Id: I5623c61cceee8a75f5d5a551ef3fbf5a303af6be Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5671 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/helper/command.c | 111 ++++++++++---------------------------- src/jtag/tcl.c | 6 ++- src/target/aarch64.c | 3 +- src/target/arm_tpiu_swo.c | 4 +- src/target/target.c | 3 +- 5 files changed, 39 insertions(+), 88 deletions(-) diff --git a/src/helper/command.c b/src/helper/command.c index 3b531807f3..41b86796a1 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -232,13 +232,6 @@ struct command_context *current_command_context(Jim_Interp *interp) return cmd_ctx; } -static struct command *command_root(struct command *c) -{ - while (NULL != c->parent) - c = c->parent; - return c; -} - /** * Find a command by name from a list of commands. * @returns Returns the named command if it exists in the list. @@ -349,18 +342,6 @@ command_new_error: static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv); -static int register_command_handler(struct command_context *cmd_ctx, - struct command *c) -{ - Jim_Interp *interp = cmd_ctx->interp; - -#if 0 - LOG_DEBUG("registering '%s'...", c->name); -#endif - - return Jim_CreateCommand(interp, c->name, command_unknown, c, NULL); -} - static struct command *register_command(struct command_context *context, struct command *parent, const struct command_registration *cr) { @@ -383,12 +364,13 @@ static struct command *register_command(struct command_context *context, if (NULL == c) return NULL; - if (cr->jim_handler || cr->handler) { - int retval = register_command_handler(context, command_root(c)); - if (retval != JIM_OK) { - unregister_command(context, parent, name); - return NULL; - } + char *full_name = command_name(c, ' '); + LOG_DEBUG("registering '%s'...", full_name); + int retval = Jim_CreateCommand(context->interp, full_name, + command_unknown, c, NULL); + if (retval != JIM_OK) { + unregister_command(context, parent, name); + return NULL; } return c; } @@ -563,7 +545,7 @@ static char *command_name(struct command *c, char delim) return __command_name(c, delim, 0); } -static bool command_can_run(struct command_context *cmd_ctx, struct command *c) +static bool command_can_run(struct command_context *cmd_ctx, struct command *c, const char *full_name) { if (c->mode == COMMAND_ANY || c->mode == cmd_ctx->mode) return true; @@ -582,10 +564,8 @@ static bool command_can_run(struct command_context *cmd_ctx, struct command *c) when = "if Cthulhu is summoned by"; break; } - char *full_name = command_name(c, ' '); LOG_ERROR("The '%s' command must be used %s 'init'.", full_name ? full_name : c->name, when); - free(full_name); return false; } @@ -980,41 +960,8 @@ static char *alloc_concatenate_strings(int argc, Jim_Obj * const *argv) 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 exec_command(Jim_Interp *interp, struct command_context *cmd_ctx, - struct command *c, int argc, Jim_Obj *const *argv) + struct command *c, int argc, Jim_Obj * const *argv) { if (c->jim_handler) return c->jim_handler(interp, argc, argv); @@ -1034,30 +981,30 @@ static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { script_debug(interp, argc, argv); - struct command_context *cmd_ctx = current_command_context(interp); - struct command *c = cmd_ctx->commands; - int remaining = command_unknown_find(argc, argv, c, &c); - /* if nothing could be consumed, then it's really an unknown command */ - if (remaining == argc) { - const char *cmd = Jim_GetString(argv[0], NULL); - LOG_ERROR("Unknown command:\n %s", cmd); - return JIM_OK; + /* check subcommands */ + if (argc > 1) { + char *s = alloc_printf("%s %s", Jim_GetString(argv[0], NULL), Jim_GetString(argv[1], NULL)); + Jim_Obj *js = Jim_NewStringObj(interp, s, -1); + Jim_IncrRefCount(js); + free(s); + Jim_Cmd *cmd = Jim_GetCommand(interp, js, JIM_NONE); + if (cmd) { + int retval = Jim_EvalObjPrefix(interp, js, argc - 2, argv + 2); + Jim_DecrRefCount(interp, js); + return retval; + } + Jim_DecrRefCount(interp, js); } - Jim_Obj *const *start; - unsigned count; - if (c->handler || c->jim_handler) { - /* include the command name in the list */ - count = remaining + 1; - start = argv + (argc - remaining - 1); - } else { - count = argc - remaining; - start = argv; - run_usage(interp, count, argc, start); + struct command *c = jim_to_command(interp); + if (!c->jim_handler && !c->handler) { + Jim_EvalObjPrefix(interp, Jim_NewStringObj(interp, "usage", -1), 1, argv); return JIM_ERR; } - if (!command_can_run(cmd_ctx, c)) + struct command_context *cmd_ctx = current_command_context(interp); + + if (!command_can_run(cmd_ctx, c, Jim_GetString(argv[0], NULL))) return JIM_ERR; target_call_timer_callbacks_now(); @@ -1076,7 +1023,7 @@ static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv) if (c->jim_override_target) cmd_ctx->current_target_override = c->jim_override_target; - int retval = exec_command(interp, cmd_ctx, c, count, start); + int retval = exec_command(interp, cmd_ctx, c, argc, argv); if (c->jim_override_target) cmd_ctx->current_target_override = saved_target_override; diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index 2fa162e56f..bf65e81193 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -767,7 +767,8 @@ static bool jtag_tap_disable(struct jtag_tap *t) int jim_jtag_tap_enabler(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - const char *cmd_name = Jim_GetString(argv[0], NULL); + struct command *c = jim_to_command(interp); + const char *cmd_name = c->name; Jim_GetOptInfo goi; Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1); if (goi.argc != 1) { @@ -804,7 +805,8 @@ int jim_jtag_tap_enabler(Jim_Interp *interp, int argc, Jim_Obj *const *argv) int jim_jtag_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - const char *cmd_name = Jim_GetString(argv[0], NULL); + struct command *c = jim_to_command(interp); + const char *cmd_name = c->name; Jim_GetOptInfo goi; Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1); goi.isconfigure = !strcmp(cmd_name, "configure"); diff --git a/src/target/aarch64.c b/src/target/aarch64.c index 46ed49f685..4ba92c8a0e 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -2966,6 +2966,7 @@ COMMAND_HANDLER(aarch64_mask_interrupts_command) static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) { + struct command *c = jim_to_command(interp); struct command_context *context; struct target *target; struct arm *arm; @@ -2973,7 +2974,7 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) bool is_mcr = false; int arg_cnt = 0; - if (Jim_CompareStringImmediate(interp, argv[0], "mcr")) { + if (!strcmp(c->name, "mcr")) { is_mcr = true; arg_cnt = 7; } else { diff --git a/src/target/arm_tpiu_swo.c b/src/target/arm_tpiu_swo.c index 186ce5d0e5..f93508622f 100644 --- a/src/target/arm_tpiu_swo.c +++ b/src/target/arm_tpiu_swo.c @@ -550,16 +550,16 @@ err_no_params: static int jim_arm_tpiu_swo_configure(Jim_Interp *interp, int argc, Jim_Obj * const *argv) { + struct command *c = jim_to_command(interp); Jim_GetOptInfo goi; Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); - goi.isconfigure = !strcmp(Jim_GetString(argv[0], NULL), "configure"); + goi.isconfigure = !strcmp(c->name, "configure"); if (goi.argc < 1) { Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv, "missing: -option ..."); return JIM_ERR; } - struct command *c = jim_to_command(interp); struct arm_tpiu_swo_object *obj = c->jim_handler_data; return arm_tpiu_swo_configure(&goi, obj); } diff --git a/src/target/target.c b/src/target/target.c index fa033d3515..e9d67702e6 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -5197,10 +5197,11 @@ no_params: static int jim_target_configure(Jim_Interp *interp, int argc, Jim_Obj * const *argv) { + struct command *c = jim_to_command(interp); Jim_GetOptInfo goi; Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); - goi.isconfigure = !strcmp(Jim_GetString(argv[0], NULL), "configure"); + goi.isconfigure = !strcmp(c->name, "configure"); if (goi.argc < 1) { Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv, "missing: -option ..."); -- 2.30.2