X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fhelper%2Fcommand.c;h=3625508f26b584afc09177dd19e391623ccdff34;hp=e55f9e73e48682fbb331c7fc5514b846416cae86;hb=709f08f17ad5128b86966365510dbe8f67736304;hpb=be01786186951b42d8aa8b8968ac1615e080a9c7 diff --git a/src/helper/command.c b/src/helper/command.c index e55f9e73e4..3625508f26 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -108,10 +108,15 @@ static int command_retval_set(Jim_Interp *interp, int retval) extern struct command_context *global_cmd_ctx; +/* dump a single line to the log for the command. + * Do nothing in case we are not at debug level 3 */ void script_debug(Jim_Interp *interp, const char *name, unsigned argc, Jim_Obj *const *argv) { - LOG_DEBUG("command - %s", name); + if (debug_level < LOG_LVL_DEBUG) + return; + + char * dbg = alloc_printf("command - %s", name); for (unsigned i = 0; i < argc; i++) { int len; @@ -121,8 +126,12 @@ void script_debug(Jim_Interp *interp, const char *name, if (*w == '#') break; - LOG_DEBUG("%s - argv[%d]=%s", name, i, w); + char * t = alloc_printf("%s %s", dbg, w); + free (dbg); + dbg = t; } + LOG_DEBUG("%s", dbg); + free(dbg); } static void script_command_args_free(const char **words, unsigned nwords) @@ -349,7 +358,7 @@ static int register_command_handler(struct command_context *cmd_ctx, if (NULL == override_name) return JIM_ERR; - retval = Jim_Eval_Named(interp, override_name, __FILE__, __LINE__); + retval = Jim_Eval_Named(interp, override_name, __THIS__FILE__ , __LINE__); free((void *)override_name); return retval; @@ -366,7 +375,10 @@ struct command* register_command(struct command_context *context, struct command *c = command_find(*head, name); if (NULL != c) { - LOG_ERROR("command '%s' is already registered in '%s' context", + /* TODO: originally we treated attempting to register a cmd twice as an error + * Sometimes we need this behaviour, such as with flash banks. + * http://www.mail-archive.com/openocd-development@lists.berlios.de/msg11152.html */ + LOG_DEBUG("command '%s' is already registered in '%s' context", name, parent ? parent->name : ""); return c; } @@ -914,7 +926,7 @@ static COMMAND_HELPER(command_help_show, struct command *c, unsigned n, bool is_match = (strstr(cmd_name, match) != NULL) || ((c->usage != NULL) && (strstr(c->usage, match) != NULL)) || ((c->help != NULL) && (strstr(c->help, match) != NULL)); - + if (is_match) { command_help_show_indent(n); @@ -934,15 +946,27 @@ static COMMAND_HELPER(command_help_show, struct command *c, unsigned n, if (is_match && 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); + char *msg; + + /* Normal commands are runtime-only; highlight exceptions */ + if (c->mode != COMMAND_EXEC) { + const char *stage_msg = ""; + + switch (c->mode) { + case COMMAND_CONFIG: + stage_msg = " (configuration command)"; + break; + case COMMAND_ANY: + stage_msg = " (command valid any time)"; + break; + default: + stage_msg = " (?mode error?)"; + break; + } + msg = alloc_printf("%s%s", c->help ? : "", stage_msg); + } else + msg = alloc_printf("%s", c->help ? : ""); + if (NULL != msg) { command_help_show_wrap(msg, n + 3, n + 3); @@ -960,18 +984,45 @@ static COMMAND_HELPER(command_help_show, struct command *c, unsigned n, COMMAND_HANDLER(handle_help_command) { bool full = strcmp(CMD_NAME, "help") == 0; - + int retval; struct command *c = CMD_CTX->commands; + char *match = NULL; - const char *match = ""; if (CMD_ARGC == 0) match = ""; - else if (CMD_ARGC == 1) - match = CMD_ARGV[0]; - else + else if (CMD_ARGC >= 1) { + unsigned i; + + for (i = 0; i < CMD_ARGC; ++i) { + if (NULL != match) { + char *prev = match; + + match = alloc_printf("%s %s", match, + CMD_ARGV[i]); + free(prev); + if (NULL == match) { + LOG_ERROR("unable to build " + "search string"); + return -ENOMEM; + } + } else { + match = alloc_printf("%s", CMD_ARGV[i]); + if (NULL == match) { + LOG_ERROR("unable to build " + "search string"); + return -ENOMEM; + } + } + } + } else return ERROR_COMMAND_SYNTAX_ERROR; - - return CALL_COMMAND_HANDLER(command_help_show_list, c, 0, full, match); + + retval = CALL_COMMAND_HANDLER(command_help_show_list, + c, 0, full, match); + + if (CMD_ARGC >= 1) + free(match); + return retval; } static int command_unknown_find(unsigned argc, Jim_Obj *const *argv, @@ -1048,6 +1099,7 @@ static int jim_command_mode(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { struct command_context *cmd_ctx = current_command_context(interp); enum command_mode mode; + if (argc > 1) { struct command *c = cmd_ctx->commands; @@ -1184,7 +1236,7 @@ COMMAND_HANDLER(handle_help_add_command) return help_add_command(CMD_CTX, c, cmd_name, help, usage); } -/* sleep command sleeps for miliseconds +/* sleep command sleeps for milliseconds * this is useful in target startup scripts */ COMMAND_HANDLER(handle_sleep_command) @@ -1224,19 +1276,22 @@ static const struct command_registration command_subcommand_handlers[] = { { .name = "mode", .mode = COMMAND_ANY, - .jim_handler = &jim_command_mode, - .usage = "[ ...]", + .jim_handler = jim_command_mode, + .usage = "[command_name ...]", .help = "Returns the command modes allowed by a command:" "'any', 'config', or 'exec'. If no command is" - "specified, returns the current command mode.", + "specified, returns the current command mode. " + "Returns 'unknown' if an unknown command is given. " + "Command can be multiple tokens.", }, { .name = "type", .mode = COMMAND_ANY, - .jim_handler = &jim_command_type, - .usage = " ...", + .jim_handler = jim_command_type, + .usage = "command_name [...]", .help = "Returns the type of built-in command:" - "'native', 'simple', 'group', or 'unknown'", + "'native', 'simple', 'group', or 'unknown'. " + "Command can be multiple tokens.", }, COMMAND_REGISTRATION_DONE }; @@ -1244,39 +1299,43 @@ static const struct command_registration command_subcommand_handlers[] = { static const struct command_registration command_builtin_handlers[] = { { .name = "add_help_text", - .handler = &handle_help_add_command, + .handler = handle_help_add_command, .mode = COMMAND_ANY, - .help = "add new command help text", - .usage = " [...] ]", + .help = "Add new command help text; " + "Command can be multiple tokens.", + .usage = "command_name helptext_string", }, { .name = "add_usage_text", - .handler = &handle_help_add_command, + .handler = handle_help_add_command, .mode = COMMAND_ANY, - .help = "add new command usage text", - .usage = " [...] ]", + .help = "Add new command usage text; " + "command can be multiple tokens.", + .usage = "command_name usage_string", }, { .name = "sleep", - .handler = &handle_sleep_command, + .handler = handle_sleep_command, .mode = COMMAND_ANY, - .help = "sleep for n milliseconds. " - "\"busy\" will busy wait", - .usage = " [busy]", + .help = "Sleep for specified number of milliseconds. " + "\"busy\" will busy wait instead (avoid this).", + .usage = "milliseconds ['busy']", }, { .name = "help", - .handler = &handle_help_command, + .handler = handle_help_command, .mode = COMMAND_ANY, - .help = "show full command help", - .usage = "[ ...]", + .help = "Show full command help; " + "command can be multiple tokens.", + .usage = "[command_name]", }, { .name = "usage", - .handler = &handle_help_command, + .handler = handle_help_command, .mode = COMMAND_ANY, - .help = "show basic command usage", - .usage = "[ ...]", + .help = "Show basic command usage; " + "command can be multiple tokens.", + .usage = "[command_name]", }, { .name = "command", @@ -1311,6 +1370,7 @@ struct command_context* command_init(const char *startup_tcl, Jim_Interp *interp #endif context->interp = interp; + /* Stick to lowercase for HostOS strings. */ #if defined(_MSC_VER) /* WinXX - is generic, the forward * looking problem is this: @@ -1322,7 +1382,7 @@ struct command_context* command_init(const char *startup_tcl, Jim_Interp *interp HostOs = "winxx"; #elif defined(__linux__) HostOs = "linux"; -#elif defined(__DARWIN__) +#elif defined(__APPLE__) || defined(__DARWIN__) HostOs = "darwin"; #elif defined(__CYGWIN__) HostOs = "cygwin"; @@ -1330,8 +1390,10 @@ struct command_context* command_init(const char *startup_tcl, Jim_Interp *interp HostOs = "mingw32"; #elif defined(__ECOS) HostOs = "ecos"; +#elif defined(__FreeBSD__) + HostOs = "freebsd"; #else -#warn unrecognized host OS... +#warning "Unrecognized host OS..." HostOs = "other"; #endif Jim_SetGlobalVariableStr(interp, "ocd_HOSTOS",