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

Reply via email to