This is an automated email from Gerrit. Antonio Borneo ([email protected]) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/5674
-- gerrit commit 5dbab7f7684dcfd7f62be98f0753c8e1fb6a0d59 Author: Antonio Borneo <[email protected]> Date: Wed May 13 15:35:19 2020 +0200 helper/command: unregister commands through their full-name While keeping the struct command in place, unregister the jim commands and remove the associated help/usage by scanning the list of jim commands through their full-name. Change-Id: I0e903fbc31172858b703d67ccd471809c7949e86 Signed-off-by: Antonio Borneo <[email protected]> diff --git a/src/helper/command.c b/src/helper/command.c index c244329..be08004 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -207,6 +207,23 @@ struct command_context *current_command_context(Jim_Interp *interp) } /** + * Find a openocd command from fullname. + * @returns Returns the named command if it is registred in interp. + * Returns NULL otherwise. + */ +static struct command *command_find_from_name(Jim_Interp *interp, const char *name) +{ + if (!name) + return NULL; + + Jim_Cmd *cmd = Jim_GetCommand(interp, Jim_NewStringObj(interp, name, -1), JIM_ERRMSG); + if (!cmd || jimcmd_is_proc(cmd) || !jimcmd_is_ocd_command(cmd)) + return NULL; + + return jimcmd_privdata(cmd); +} + +/** * Find a command by name from a list of commands. * @returns Returns the named command if it exists in the list. * Returns NULL otherwise. @@ -399,12 +416,83 @@ int __register_commands(struct command_context *cmd_ctx, const char *cmd_prefix, return ___register_commands(cmd_ctx, parent, cmds, data, override_target); } +static __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3))) +int unregister_commands_match(Jim_Interp *interp, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + char *query = alloc_vprintf(format, ap); + va_end(ap); + if (!query) + return ERROR_FAIL; + + char *query_cmd = alloc_printf("info commands {%s}", query); + free(query); + if (!query_cmd) + return ERROR_FAIL; + + int retval = Jim_EvalSource(interp, __THIS__FILE__, __LINE__, query_cmd); + free(query_cmd); + if (retval != JIM_OK) + return ERROR_FAIL; + + Jim_Obj *list = Jim_GetResult(interp); + Jim_IncrRefCount(list); + + int len = Jim_ListLength(interp, list); + for (int i = 0; i < len; i++) { + Jim_Obj *elem = Jim_ListGetIndex(interp, list, i); + Jim_IncrRefCount(elem); + + const char *name = Jim_GetString(elem, NULL); + struct command *c = command_find_from_name(interp, name); + if (!c) { + /* not openocd command */ + Jim_DecrRefCount(interp, elem); + continue; + } + LOG_DEBUG("delete command \"%s\"", name); + Jim_DeleteCommand(interp, name); + char *cmd = alloc_printf("del_help_text {%s}", name); + Jim_EvalSource(interp, __THIS__FILE__, __LINE__, cmd); + free(cmd); + cmd = alloc_printf("del_usage_text {%s}", name); + Jim_EvalSource(interp, __THIS__FILE__, __LINE__, cmd); + free(cmd); + + Jim_DecrRefCount(interp, elem); + } + + Jim_DecrRefCount(interp, list); + return ERROR_OK; +} + int unregister_all_commands(struct command_context *context, - struct command *parent) + const char *cmd_prefix) { - if (context == NULL) + struct command *parent = NULL; + + if (!context) return ERROR_OK; + if (!cmd_prefix || !*cmd_prefix) { + int retval = unregister_commands_match(context->interp, "*"); + if (retval != ERROR_OK) + return retval; + } else { + Jim_Cmd *cmd = Jim_GetCommand(context->interp, Jim_NewStringObj(context->interp, cmd_prefix, -1), JIM_ERRMSG); + if (cmd && jimcmd_is_ocd_command(cmd)) + parent = jimcmd_privdata(cmd); + + int retval = unregister_commands_match(context->interp, "%s *", cmd_prefix); + if (retval != ERROR_OK) + return retval; + retval = unregister_commands_match(context->interp, "%s", cmd_prefix); + if (retval != ERROR_OK) + return retval; + } + struct command **head = command_list_for_parent(context, parent); while (NULL != *head) { struct command *tmp = *head; @@ -415,6 +503,24 @@ int unregister_all_commands(struct command_context *context, return ERROR_OK; } +static __attribute__ ((unused)) +int _unregister_command(struct command_context *context, + const char *cmd_prefix, const char *name) +{ + struct command *parent = NULL; + + if (!context || !name) + return ERROR_COMMAND_SYNTAX_ERROR; + + if (cmd_prefix && *cmd_prefix) { + Jim_Cmd *cmd = Jim_GetCommand(context->interp, Jim_NewStringObj(context->interp, cmd_prefix, -1), JIM_ERRMSG); + if (cmd && jimcmd_is_ocd_command(cmd)) + parent = jimcmd_privdata(cmd); + } + + return unregister_command(context, parent, name); +} + static int unregister_command(struct command_context *context, struct command *parent, const char *name) { @@ -429,8 +535,9 @@ static int unregister_command(struct command_context *context, char *full_name = command_name(c, ' '); - command_run_linef(context, "del_help_text {%s}", full_name); - command_run_linef(context, "del_usage_text {%s}", full_name); + int retval = unregister_commands_match(context->interp, "%s", full_name); + if (retval != ERROR_OK) + return retval; free(full_name); diff --git a/src/helper/command.h b/src/helper/command.h index 84ff029..24b3bba 100644 --- a/src/helper/command.h +++ b/src/helper/command.h @@ -299,11 +299,11 @@ static inline int register_commands_with_data(struct command_context *cmd_ctx, /** * Unregisters all commands from the specfied context. * @param cmd_ctx The context that will be cleared of registered commands. - * @param parent If given, only clear commands from under this one command. + * @param cmd_prefix If given, only clear commands from under this one command. * @returns ERROR_OK on success, or an error code. */ int unregister_all_commands(struct command_context *cmd_ctx, - struct command *parent); + const char *cmd_prefix); void command_set_output_handler(struct command_context *context, command_output_handler_t output_handler, void *priv); -- _______________________________________________ OpenOCD-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openocd-devel
