helper/command: register full-name commands in jim 71/5671/9
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 ...");

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)