helper/command: register full-name commands in jim
authorAntonio Borneo <borneo.antonio@gmail.com>
Tue, 12 May 2020 23:59:59 +0000 (01:59 +0200)
committerAntonio Borneo <borneo.antonio@gmail.com>
Sun, 18 Apr 2021 14:34:10 +0000 (15:34 +0100)
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 <borneo.antonio@gmail.com>
Reviewed-on: http://openocd.zylin.com/5671
Tested-by: jenkins
Reviewed-by: Oleksij Rempel <linux@rempel-privat.de>
src/helper/command.c
src/jtag/tcl.c
src/target/aarch64.c
src/target/arm_tpiu_swo.c
src/target/target.c

index 3b531807f3dd1aba1d0364aaf6278c84d7982905..41b86796a1b7a1b5e9cd646e4eb8163d7a485e66 100644 (file)
@@ -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;
index 2fa162e56ff84658019468c4ce50c6f6be6d4c9a..bf65e811931817b1f2b9f0ac8e9897fdc659a383 100644 (file)
@@ -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");
index 46ed49f685d16e96d2dd86806a062dd477c22a07..4ba92c8a0edf86403c301612687173ed76fda50e 100644 (file)
@@ -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 {
index 186ce5d0e50179a680197a62e2c3d20456e540c4..f93508622f38b1c521b008dc6f6ca79649ded5e7 100644 (file)
@@ -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);
 }
index fa033d35158b82f2d7b85d2b07cf671ad2b9e151..e9d67702e60ec8c039b540c730b0820a0d83e727 100644 (file)
@@ -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 ...");