aboutsummaryrefslogtreecommitdiff
path: root/src/helper/command.c
diff options
context:
space:
mode:
authorAntonio Borneo <borneo.antonio@gmail.com>2020-05-13 15:35:19 +0200
committerAntonio Borneo <borneo.antonio@gmail.com>2021-04-18 15:34:43 +0100
commita7d68878e4ba5dfd5ca15c058980cf6c5fc55208 (patch)
tree8932ed57728608b61f807bc7c5538126c7b5e1ed /src/helper/command.c
parentd8d24f3b3696f5d2e64a67df87684132b48031d2 (diff)
downloadriscv-openocd-a7d68878e4ba5dfd5ca15c058980cf6c5fc55208.zip
riscv-openocd-a7d68878e4ba5dfd5ca15c058980cf6c5fc55208.tar.gz
riscv-openocd-a7d68878e4ba5dfd5ca15c058980cf6c5fc55208.tar.bz2
helper/command: unregister commands through their full-name
While keeping the struct command in place, unregister the jim commands by scanning the list of jim commands through their full-name. Change-Id: I0e903fbc31172858b703d67ccd471809c7949e86 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/5674 Tested-by: jenkins Reviewed-by: Oleksij Rempel <linux@rempel-privat.de>
Diffstat (limited to 'src/helper/command.c')
-rw-r--r--src/helper/command.c98
1 files changed, 95 insertions, 3 deletions
diff --git a/src/helper/command.c b/src/helper/command.c
index 5cddf21..d79d7f4 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -244,6 +244,26 @@ 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_Obj *jim_name = Jim_NewStringObj(interp, name, -1);
+ Jim_IncrRefCount(jim_name);
+ Jim_Cmd *cmd = Jim_GetCommand(interp, jim_name, JIM_NONE);
+ Jim_DecrRefCount(interp, jim_name);
+ 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.
@@ -429,12 +449,80 @@ 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(struct command_context *cmd_ctx, const char *format, ...)
+{
+ Jim_Interp *interp = cmd_ctx->interp;
+ 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, elem);
+
+ help_del_command(cmd_ctx, name);
+
+ 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, "*");
+ if (retval != ERROR_OK)
+ return retval;
+ } else {
+ Jim_Cmd *cmd = Jim_GetCommand(context->interp, Jim_NewStringObj(context->interp, cmd_prefix, -1), JIM_NONE);
+ if (cmd && jimcmd_is_ocd_command(cmd))
+ parent = jimcmd_privdata(cmd);
+
+ int retval = unregister_commands_match(context, "%s *", cmd_prefix);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = unregister_commands_match(context, "%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;
@@ -458,7 +546,11 @@ static int unregister_command(struct command_context *context,
continue;
char *full_name = command_name(c, ' ');
- help_del_command(context, full_name);
+
+ int retval = unregister_commands_match(context, "%s", full_name);
+ if (retval != ERROR_OK)
+ return retval;
+
free(full_name);
if (p)