command mode: return "any" for tcl proc
[fw/openocd] / src / helper / command.c
index 89e217382bc581d309fbba70083ef560b34786aa..288ba99aa874ba53518e40eb64ab8dfb98757d6f 100644 (file)
@@ -53,6 +53,12 @@ static int unregister_command(struct command_context *context,
        struct command *parent, const char *name);
 static char *command_name(struct command *c, char delim);
 
+/* wrap jimtcl internal data */
+static inline bool jimcmd_is_proc(Jim_Cmd *cmd)
+{
+       return cmd->isproc;
+}
+
 static void tcl_output(void *privData, const char *file, unsigned line,
        const char *function, const char *string)
 {
@@ -244,12 +250,6 @@ static struct command *command_find(struct command *head, const char *name)
        return NULL;
 }
 
-struct command *command_find_in_context(struct command_context *cmd_ctx,
-       const char *name)
-{
-       return command_find(cmd_ctx->commands, name);
-}
-
 /**
  * Add the command into the linked list, sorted by name.
  * @param head Address to head of command list pointer, which may be
@@ -391,7 +391,7 @@ static struct command *register_command(struct command_context *context,
        return c;
 }
 
-int __register_commands(struct command_context *cmd_ctx, struct command *parent,
+static int ___register_commands(struct command_context *cmd_ctx, struct command *parent,
        const struct command_registration *cmds, void *data,
        struct target *override_target)
 {
@@ -412,7 +412,7 @@ int __register_commands(struct command_context *cmd_ctx, struct command *parent,
                }
                if (NULL != cr->chain) {
                        struct command *p = c ? : parent;
-                       retval = __register_commands(cmd_ctx, p, cr->chain, data, override_target);
+                       retval = ___register_commands(cmd_ctx, p, cr->chain, data, override_target);
                        if (ERROR_OK != retval)
                                break;
                }
@@ -424,6 +424,18 @@ int __register_commands(struct command_context *cmd_ctx, struct command *parent,
        return retval;
 }
 
+int __register_commands(struct command_context *cmd_ctx, const char *cmd_prefix,
+       const struct command_registration *cmds, void *data,
+       struct target *override_target)
+{
+       struct command *parent = NULL;
+
+       if (cmd_prefix)
+               parent = command_find(cmd_ctx->commands, cmd_prefix);
+
+       return ___register_commands(cmd_ctx, parent, cmds, data, override_target);
+}
+
 int unregister_all_commands(struct command_context *context,
        struct command *parent)
 {
@@ -1070,6 +1082,18 @@ static int jim_command_mode(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
        enum command_mode mode;
 
        if (argc > 1) {
+               char *full_name = alloc_concatenate_strings(argc - 1, argv + 1);
+               if (!full_name)
+                       return JIM_ERR;
+               Jim_Obj *s = Jim_NewStringObj(interp, full_name, -1);
+               Jim_IncrRefCount(s);
+               Jim_Cmd *cmd = Jim_GetCommand(interp, s, JIM_NONE);
+               Jim_DecrRefCount(interp, s);
+               free(full_name);
+               if (cmd && jimcmd_is_proc(cmd)) {
+                       Jim_SetResultString(interp, "any", -1);
+                       return JIM_OK;
+               }
                struct command *c = cmd_ctx->commands;
                int remaining = command_unknown_find(argc - 1, argv + 1, c, &c);
                /* if nothing could be consumed, then it's an unknown command */