helper/command: register full-name commands in jim
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>
This commit is contained in:
parent
aacc26559e
commit
e216186fab
|
@ -232,13 +232,6 @@ struct command_context *current_command_context(Jim_Interp *interp)
|
||||||
return cmd_ctx;
|
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.
|
* Find a command by name from a list of commands.
|
||||||
* @returns Returns the named command if it exists in the list.
|
* @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 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,
|
static struct command *register_command(struct command_context *context,
|
||||||
struct command *parent, const struct command_registration *cr)
|
struct command *parent, const struct command_registration *cr)
|
||||||
{
|
{
|
||||||
|
@ -383,12 +364,13 @@ static struct command *register_command(struct command_context *context,
|
||||||
if (NULL == c)
|
if (NULL == c)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (cr->jim_handler || cr->handler) {
|
char *full_name = command_name(c, ' ');
|
||||||
int retval = register_command_handler(context, command_root(c));
|
LOG_DEBUG("registering '%s'...", full_name);
|
||||||
if (retval != JIM_OK) {
|
int retval = Jim_CreateCommand(context->interp, full_name,
|
||||||
unregister_command(context, parent, name);
|
command_unknown, c, NULL);
|
||||||
return NULL;
|
if (retval != JIM_OK) {
|
||||||
}
|
unregister_command(context, parent, name);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
@ -563,7 +545,7 @@ static char *command_name(struct command *c, char delim)
|
||||||
return __command_name(c, delim, 0);
|
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)
|
if (c->mode == COMMAND_ANY || c->mode == cmd_ctx->mode)
|
||||||
return true;
|
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";
|
when = "if Cthulhu is summoned by";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
char *full_name = command_name(c, ' ');
|
|
||||||
LOG_ERROR("The '%s' command must be used %s 'init'.",
|
LOG_ERROR("The '%s' command must be used %s 'init'.",
|
||||||
full_name ? full_name : c->name, when);
|
full_name ? full_name : c->name, when);
|
||||||
free(full_name);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -980,41 +960,8 @@ static char *alloc_concatenate_strings(int argc, Jim_Obj * const *argv)
|
||||||
return all;
|
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,
|
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)
|
if (c->jim_handler)
|
||||||
return c->jim_handler(interp, argc, argv);
|
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);
|
script_debug(interp, argc, argv);
|
||||||
|
|
||||||
struct command_context *cmd_ctx = current_command_context(interp);
|
/* check subcommands */
|
||||||
struct command *c = cmd_ctx->commands;
|
if (argc > 1) {
|
||||||
int remaining = command_unknown_find(argc, argv, c, &c);
|
char *s = alloc_printf("%s %s", Jim_GetString(argv[0], NULL), Jim_GetString(argv[1], NULL));
|
||||||
/* if nothing could be consumed, then it's really an unknown command */
|
Jim_Obj *js = Jim_NewStringObj(interp, s, -1);
|
||||||
if (remaining == argc) {
|
Jim_IncrRefCount(js);
|
||||||
const char *cmd = Jim_GetString(argv[0], NULL);
|
free(s);
|
||||||
LOG_ERROR("Unknown command:\n %s", cmd);
|
Jim_Cmd *cmd = Jim_GetCommand(interp, js, JIM_NONE);
|
||||||
return JIM_OK;
|
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;
|
struct command *c = jim_to_command(interp);
|
||||||
unsigned count;
|
if (!c->jim_handler && !c->handler) {
|
||||||
if (c->handler || c->jim_handler) {
|
Jim_EvalObjPrefix(interp, Jim_NewStringObj(interp, "usage", -1), 1, argv);
|
||||||
/* 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);
|
|
||||||
return JIM_ERR;
|
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;
|
return JIM_ERR;
|
||||||
|
|
||||||
target_call_timer_callbacks_now();
|
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)
|
if (c->jim_override_target)
|
||||||
cmd_ctx->current_target_override = 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)
|
if (c->jim_override_target)
|
||||||
cmd_ctx->current_target_override = saved_target_override;
|
cmd_ctx->current_target_override = saved_target_override;
|
||||||
|
|
|
@ -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)
|
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_GetOptInfo goi;
|
||||||
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
|
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
|
||||||
if (goi.argc != 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)
|
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_GetOptInfo goi;
|
||||||
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
|
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
|
||||||
goi.isconfigure = !strcmp(cmd_name, "configure");
|
goi.isconfigure = !strcmp(cmd_name, "configure");
|
||||||
|
|
|
@ -2966,6 +2966,7 @@ COMMAND_HANDLER(aarch64_mask_interrupts_command)
|
||||||
|
|
||||||
static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
|
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 command_context *context;
|
||||||
struct target *target;
|
struct target *target;
|
||||||
struct arm *arm;
|
struct arm *arm;
|
||||||
|
@ -2973,7 +2974,7 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
|
||||||
bool is_mcr = false;
|
bool is_mcr = false;
|
||||||
int arg_cnt = 0;
|
int arg_cnt = 0;
|
||||||
|
|
||||||
if (Jim_CompareStringImmediate(interp, argv[0], "mcr")) {
|
if (!strcmp(c->name, "mcr")) {
|
||||||
is_mcr = true;
|
is_mcr = true;
|
||||||
arg_cnt = 7;
|
arg_cnt = 7;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -550,16 +550,16 @@ err_no_params:
|
||||||
|
|
||||||
static int jim_arm_tpiu_swo_configure(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
|
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_GetOptInfo goi;
|
||||||
|
|
||||||
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
|
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) {
|
if (goi.argc < 1) {
|
||||||
Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
|
Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
|
||||||
"missing: -option ...");
|
"missing: -option ...");
|
||||||
return JIM_ERR;
|
return JIM_ERR;
|
||||||
}
|
}
|
||||||
struct command *c = jim_to_command(interp);
|
|
||||||
struct arm_tpiu_swo_object *obj = c->jim_handler_data;
|
struct arm_tpiu_swo_object *obj = c->jim_handler_data;
|
||||||
return arm_tpiu_swo_configure(&goi, obj);
|
return arm_tpiu_swo_configure(&goi, obj);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5197,10 +5197,11 @@ no_params:
|
||||||
|
|
||||||
static int jim_target_configure(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
|
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_GetOptInfo goi;
|
||||||
|
|
||||||
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
|
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) {
|
if (goi.argc < 1) {
|
||||||
Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
|
Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
|
||||||
"missing: -option ...");
|
"missing: -option ...");
|
||||||
|
|
Loading…
Reference in New Issue