summaryrefslogtreecommitdiff
path: root/src/helper
diff options
context:
space:
mode:
authorZachary T Welch <zw@superlucidity.net>2009-11-21 19:55:50 -0800
committerZachary T Welch <zw@superlucidity.net>2009-11-24 21:37:30 -0800
commit62e56496009796497665c1d06819c163589a3877 (patch)
treeef698494bccbc427a6ced251bb674a1879e83ccb /src/helper
parent769fbfa058946e1581d5f9ad75d17947d1ee9ff1 (diff)
downloadopenocd+libswd-62e56496009796497665c1d06819c163589a3877.tar.gz
openocd+libswd-62e56496009796497665c1d06819c163589a3877.tar.bz2
openocd+libswd-62e56496009796497665c1d06819c163589a3877.tar.xz
openocd+libswd-62e56496009796497665c1d06819c163589a3877.zip
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.
Diffstat (limited to 'src/helper')
-rw-r--r--src/helper/command.c65
-rw-r--r--src/helper/startup.tcl17
2 files changed, 65 insertions, 17 deletions
diff --git a/src/helper/command.c b/src/helper/command.c
index 54bfb964..dd109657 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -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);
diff --git a/src/helper/startup.tcl b/src/helper/startup.tcl
index 845198ad..ede8cdb9 100644
--- a/src/helper/startup.tcl
+++ b/src/helper/startup.tcl
@@ -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} {