rewrite 'unknown' command dispatching in C
Rewrite the magical 'unknown' command in C as a Jim handler, allowing it to dispatch commands to any level in the tree.
This commit is contained in:
parent
769fbfa058
commit
62e5649600
|
@ -853,6 +853,70 @@ COMMAND_HANDLER(handle_usage_command)
|
|||
return CALL_COMMAND_HANDLER(command_help_show, c, 0, false);
|
||||
}
|
||||
|
||||
static int command_unknown_find(unsigned argc, Jim_Obj *const *argv,
|
||||
struct command *head, struct command **out)
|
||||
{
|
||||
if (0 == argc)
|
||||
return argc;
|
||||
struct command *c = command_find(head, Jim_GetString(argv[0], NULL));
|
||||
if (NULL == c)
|
||||
return argc;
|
||||
*out = c;
|
||||
return command_unknown_find(--argc, ++argv, (*out)->children, out);
|
||||
}
|
||||
|
||||
static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
const char *cmd_name = Jim_GetString(argv[0], NULL);
|
||||
script_debug(interp, cmd_name, argc - 1, argv + 1);
|
||||
|
||||
struct command_context *cmd_ctx = current_command_context();
|
||||
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 really an unknown command
|
||||
if (remaining == argc - 1)
|
||||
{
|
||||
const char *cmd = Jim_GetString(argv[1], NULL);
|
||||
LOG_ERROR("Unknown command:\n %s", cmd);
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
bool found = true;
|
||||
Jim_Obj *const *start;
|
||||
unsigned count;
|
||||
if (c->handler)
|
||||
{
|
||||
// include the command name in the list
|
||||
count = remaining + 1;
|
||||
start = argv + (argc - remaining - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
c = command_find(cmd_ctx->commands, "help");
|
||||
if (NULL == c)
|
||||
{
|
||||
LOG_ERROR("unknown command, but help is missing too");
|
||||
return JIM_ERR;
|
||||
}
|
||||
count = argc - remaining;
|
||||
start = argv;
|
||||
found = false;
|
||||
}
|
||||
|
||||
unsigned nwords;
|
||||
const char **words = script_command_args_alloc(count, start, &nwords);
|
||||
if (NULL == words)
|
||||
return JIM_ERR;
|
||||
|
||||
int retval = run_command(cmd_ctx, c, words, nwords);
|
||||
|
||||
script_command_args_free(words, nwords);
|
||||
|
||||
if (!found && ERROR_OK == retval)
|
||||
retval = ERROR_FAIL;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int help_add_command(struct command_context *cmd_ctx, struct command *parent,
|
||||
const char *cmd_name, const char *help_text, const char *usage)
|
||||
|
@ -1032,6 +1096,7 @@ struct command_context* command_init(const char *startup_tcl)
|
|||
Jim_SetGlobalVariableStr(interp, "ocd_HOSTOS",
|
||||
Jim_NewStringObj(interp, HostOs , strlen(HostOs)));
|
||||
|
||||
Jim_CreateCommand(interp, "unknown", &command_unknown, NULL, NULL);
|
||||
Jim_CreateCommand(interp, "ocd_find", jim_find, NULL, NULL);
|
||||
Jim_CreateCommand(interp, "echo", jim_echo, NULL, NULL);
|
||||
Jim_CreateCommand(interp, "capture", jim_capture, NULL, NULL);
|
||||
|
|
|
@ -44,23 +44,6 @@ proc cmd_help {cmdname h indent} {
|
|||
}
|
||||
}
|
||||
|
||||
# If a fn is unknown to Tcl, we try to execute it as an OpenOCD command
|
||||
#
|
||||
# We also support two level commands. "flash banks" is translated to
|
||||
# flash_banks
|
||||
proc unknown {args} {
|
||||
# do the name mangling from "flash banks" to "flash_banks"
|
||||
if {[llength $args]>=2} {
|
||||
set cmd_name "[lindex $args 0]_[lindex $args 1]"
|
||||
if {[catch {info body $cmd_name}]==0} {
|
||||
# the command exists, try it...
|
||||
return [eval "$cmd_name [lrange $args 2 end]"]
|
||||
}
|
||||
}
|
||||
# This really is an unknown command.
|
||||
return -code error "Unknown command: $args"
|
||||
}
|
||||
|
||||
# Try flipping / and \ to find file if the filename does not
|
||||
# match the precise spelling
|
||||
proc find {filename} {
|
||||
|
|
Loading…
Reference in New Issue