From: Zach W. <zw...@us...> - 2009-11-28 22:04:17
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 2da2864632c281a2523f924b406e532d610857a6 (commit) via 8795b8f9df5ba1fd8466a04b515aa5f56c0c4015 (commit) via 42e00bb379fe7591b6d74768a45855ed5cd0c24f (commit) via fd343bea7f11796a9fba77158fe84b0ccaac1a4b (commit) via 933b4579f06d25e349e6648ec4aff114e634164d (commit) via 3b5751a4d4aa4eb980aee6931b7d100a6d37224a (commit) from 89fa493a3bc34d22eeca06fa4e78523ac3b766a8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2da2864632c281a2523f924b406e532d610857a6 Author: Zachary T Welch <zw...@su...> Date: Sat Nov 28 10:46:53 2009 -0800 remove redundant 'rm' command handler Two 'rm' commands were implemented and registered. This removes the version that would have never been called prior to refactoring the command registration. diff --git a/src/helper/ioutil.c b/src/helper/ioutil.c index e13f590..ed82ba1 100644 --- a/src/helper/ioutil.c +++ b/src/helper/ioutil.c @@ -38,9 +38,6 @@ #ifdef HAVE_NET_IF_H #include <net/if.h> #endif -//#ifdef HAVE_NETINET_TCP_H -//#include <netinet/tcp.h> -//#endif #ifdef HAVE_SYS_IOCTL_H #include <sys/ioctl.h> #endif @@ -57,23 +54,6 @@ #endif -COMMAND_HANDLER(handle_rm_command) -{ - if (CMD_ARGC != 1) - { - command_print(CMD_CTX, "rm <filename>"); - return ERROR_INVALID_ARGUMENTS; - } - - if (unlink(CMD_ARGV[0]) != 0) - { - command_print(CMD_CTX, "failed: %d", errno); - } - - return ERROR_OK; -} - - /* loads a file and returns a pointer to it in memory. The file contains * a 0 byte(sentinel) after len bytes - the length of the file. */ int loadFile(const char *fileName, void **data, size_t *len) @@ -645,13 +625,6 @@ static int zylinjtag_Jim_Command_mac(Jim_Interp *interp, int argc, static const struct command_registration ioutil_command_handlers[] = { { - .name = "rm", - .handler = &handle_rm_command, - .mode = COMMAND_ANY, - .help = "remove file", - .usage= "<file_name>", - }, - { .name = "cat", .handler = &handle_cat_command, .mode = COMMAND_ANY, commit 8795b8f9df5ba1fd8466a04b515aa5f56c0c4015 Author: Zachary T Welch <zw...@su...> Date: Sat Nov 28 10:42:51 2009 -0800 add error checking in command_new Adds checks for memory allocation failures. Started to use calloc() instead of malloc()/memset(), but I got carried away. This kind of work should be done throughout the tree, but it's almost hopeless at present. diff --git a/src/helper/command.c b/src/helper/command.c index 4b7d8cb..ce857dd 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -253,19 +253,44 @@ static struct command **command_list_for_parent( return parent ? &parent->children : &cmd_ctx->commands; } +static void command_free(struct command *c) +{ + /// @todo if command has a handler, unregister its jim command! + + while (NULL != c->children) + { + struct command *tmp = c->children; + c->children = tmp->next; + command_free(tmp); + } + + if (c->name) + free(c->name); + if (c->help) + free((void*)c->help); + if (c->usage) + free((void*)c->usage); + free(c); +} + static struct command *command_new(struct command_context *cmd_ctx, struct command *parent, const struct command_registration *cr) { assert(cr->name); - struct command *c = malloc(sizeof(struct command)); - memset(c, 0, sizeof(struct command)); + struct command *c = calloc(1, sizeof(struct command)); + if (NULL == c) + return NULL; c->name = strdup(cr->name); if (cr->help) c->help = strdup(cr->help); if (cr->usage) c->usage = strdup(cr->usage); + + if (!c->name || (cr->help && !c->help) || (cr->usage && !c->usage)) + goto command_new_error; + c->parent = parent; c->handler = cr->handler; c->jim_handler = cr->jim_handler; @@ -275,25 +300,10 @@ static struct command *command_new(struct command_context *cmd_ctx, command_add_child(command_list_for_parent(cmd_ctx, parent), c); return c; -} -static void command_free(struct command *c) -{ - /// @todo if command has a handler, unregister its jim command! - while (NULL != c->children) - { - struct command *tmp = c->children; - c->children = tmp->next; - command_free(tmp); - } - - if (c->name) - free(c->name); - if (c->help) - free((void*)c->help); - if (c->usage) - free((void*)c->usage); - free(c); +command_new_error: + command_free(c); + return NULL; } static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv); commit 42e00bb379fe7591b6d74768a45855ed5cd0c24f Author: Zachary T Welch <zw...@su...> Date: Sat Nov 28 12:42:06 2009 -0800 include mode information in help text. Extends the help output to list the valid modes for each commands. Fixes a memory leak of the returned command_name() string. diff --git a/src/helper/command.c b/src/helper/command.c index 3f43942..4b7d8cb 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -862,16 +862,40 @@ static void command_help_show_wrap(const char *str, unsigned n, unsigned n2) static COMMAND_HELPER(command_help_show, struct command *c, unsigned n, bool show_help) { + char *cmd_name = command_name(c, ' '); + if (NULL == cmd_name) + return -ENOMEM; + command_help_show_indent(n); - LOG_USER_N("%s", command_name(c, ' ')); + LOG_USER_N("%s", cmd_name); + free(cmd_name); + if (c->usage) { LOG_USER_N(" "); command_help_show_wrap(c->usage, 0, n + 5); } else LOG_USER_N("\n"); - if (show_help && c->help) - command_help_show_wrap(c->help, n + 3, n + 3); + + if (show_help) + { + const char *stage_msg; + switch (c->mode) { + case COMMAND_CONFIG: stage_msg = "CONFIG"; break; + case COMMAND_EXEC: stage_msg = "EXEC"; break; + case COMMAND_ANY: stage_msg = "CONFIG or EXEC"; break; + default: stage_msg = "***UNKNOWN***"; break; + } + char *msg = alloc_printf("%s%sValid Modes: %s", + c->help ? : "", c->help ? " " : "", stage_msg); + if (NULL != msg) + { + command_help_show_wrap(msg, n + 3, n + 3); + free(msg); + } else + return -ENOMEM; + } + if (++n >= 2) return ERROR_OK; commit fd343bea7f11796a9fba77158fe84b0ccaac1a4b Author: Zachary T Welch <zw...@su...> Date: Fri Nov 27 10:16:42 2009 -0800 refactor command mode detection Splits the check for a command's ability to run into a helper. This also fixes a bug whereby commands that specified COMMAND_EXEC were allowed to run during the configuration stage. This allowed problematic commands to be called before 'init', defeating the intention of specifying that command mode. With this change, the run_command() helper denies access to handlers that should run only after 'init' during the configuration stage. diff --git a/src/helper/command.c b/src/helper/command.c index b2aa76b..3f43942 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -525,13 +525,18 @@ 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) +{ + return c->mode == COMMAND_ANY || c->mode == cmd_ctx->mode; +} + static int run_command(struct command_context *context, struct command *c, const char *words[], unsigned num_words) { - if (!((context->mode == COMMAND_CONFIG) || (c->mode == COMMAND_ANY) || (c->mode == context->mode))) + if (!command_can_run(context, c)) { /* Config commands can not run after the config stage */ - LOG_ERROR("Command '%s' only runs during configuration stage", c->name); + LOG_ERROR("The '%s' command must be used before 'init'.", c->name); return ERROR_FAIL; } commit 933b4579f06d25e349e6648ec4aff114e634164d Author: Zachary T Welch <zw...@su...> Date: Fri Nov 27 16:30:28 2009 -0800 add command private data setter/accessor Presently, commands registration taks a static handler data pointer. This patch adds support for commands that require a dynamic pointer, such as those registered in a dynamic context (e.g. subcommands for a user-created 'foo.cpu' command). The command_set_handler_data will update a command (group) to use a new context pointer, while the CMD_DATA macro allows command handlers to access the value. Jim handlers should find this value in interp->cmdPrivData. diff --git a/src/helper/command.c b/src/helper/command.c index 61a791d..b2aa76b 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -439,6 +439,14 @@ int unregister_command(struct command_context *context, return ERROR_OK; } +void command_set_handler_data(struct command *c, void *p) +{ + if (NULL != c->handler || NULL != c->jim_handler) + c->jim_handler_data = p; + for (struct command *cc = c->children; NULL != cc; cc = cc->next) + command_set_handler_data(cc, p); +} + void command_output_text(struct command_context *context, const char *data) { if (context && context->output_handler && data) { diff --git a/src/helper/command.h b/src/helper/command.h index 84bdb71..2d33484 100644 --- a/src/helper/command.h +++ b/src/helper/command.h @@ -80,6 +80,8 @@ struct command_context void *output_handler_priv; }; +struct command; + /** * When run_command is called, a new instance will be created on the * stack, filled with the proper values, and passed by reference to the @@ -87,6 +89,7 @@ struct command_context */ struct command_invocation { struct command_context *ctx; + struct command *current; const char *name; unsigned argc; const char **argv; @@ -151,6 +154,16 @@ struct command_invocation { * rather than accessing the variable directly. It may be moved. */ #define CMD_NAME cmd->name +/** + * Use this macro to access the current command being handled, + * rather than accessing the variable directly. It may be moved. + */ +#define CMD_CURRENT cmd->current +/** + * Use this macro to access the invoked command handler's data pointer, + * rather than accessing the variable directly. It may be moved. + */ +#define CMD_DATA CMD_CURRENT->jim_handler_data /// The type signature for commands' handler functions. @@ -290,6 +303,16 @@ struct command *command_find_in_context(struct command_context *cmd_ctx, struct command *command_find_in_parent(struct command *parent, const char *name); +/** + * Update the private command data field for a command and all descendents. + * This is used when creating a new heirarchy of commands that depends + * on obtaining a dynamically created context. The value will be available + * in command handlers by using the CMD_DATA macro. + * @param c The command (group) whose data pointer(s) will be updated. + * @param p The new data pointer to use for the command or its descendents. + */ +void command_set_handler_data(struct command *c, void *p); + void command_set_output_handler(struct command_context* context, command_output_handler_t output_handler, void *priv); commit 3b5751a4d4aa4eb980aee6931b7d100a6d37224a Author: Zachary T Welch <zw...@su...> Date: Sat Nov 28 12:29:42 2009 -0800 add 'command mode' introspective handler Allows scripts to behave different depending on the current mode. Also allows introspection of the mode required for commands. diff --git a/src/helper/command.c b/src/helper/command.c index 2b29956..61a791d 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -950,6 +950,36 @@ static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return script_command_run(interp, count, start, c, found); } +static int jim_command_mode(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct command_context *cmd_ctx = current_command_context(); + enum command_mode mode; + if (argc > 1) + { + struct command *c = cmd_ctx->commands; + int remaining = command_unknown_find(argc - 1, argv + 1, c, &c, true); + // if nothing could be consumed, then it's an unknown command + if (remaining == argc - 1) + { + Jim_SetResultString(interp, "unknown", -1); + return JIM_OK; + } + mode = c->mode; + } + else + mode = cmd_ctx->mode; + + const char *mode_str; + switch (mode) { + case COMMAND_ANY: mode_str = "any"; break; + case COMMAND_CONFIG: mode_str = "config"; break; + case COMMAND_EXEC: mode_str = "exec"; break; + default: mode_str = "unknown"; break; + } + Jim_SetResultString(interp, mode_str, -1); + return JIM_OK; +} + static int jim_command_type(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { if (1 == argc) @@ -1098,6 +1128,15 @@ COMMAND_HANDLER(handle_sleep_command) static const struct command_registration command_subcommand_handlers[] = { { + .name = "mode", + .mode = COMMAND_ANY, + .jim_handler = &jim_command_mode, + .usage = "[<name> ...]", + .help = "Returns the command modes allowed by a command:" + "'any', 'config', or 'exec'. If no command is" + "specified, returns the current command mode.", + }, + { .name = "type", .mode = COMMAND_ANY, .jim_handler = &jim_command_type, ----------------------------------------------------------------------- Summary of changes: src/helper/command.c | 136 ++++++++++++++++++++++++++++++++++++++++--------- src/helper/command.h | 23 ++++++++ src/helper/ioutil.c | 27 ---------- 3 files changed, 134 insertions(+), 52 deletions(-) hooks/post-receive -- Main OpenOCD repository |