diff options
Diffstat (limited to 'src/helper/command.c')
-rw-r--r-- | src/helper/command.c | 117 |
1 files changed, 66 insertions, 51 deletions
diff --git a/src/helper/command.c b/src/helper/command.c index a775c73..3d4379d 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -41,6 +41,7 @@ static int jim_command_dispatch(Jim_Interp *interp, int argc, Jim_Obj * const *a static int help_add_command(struct command_context *cmd_ctx, const char *cmd_name, const char *help_text, const char *usage_text); static int help_del_command(struct command_context *cmd_ctx, const char *cmd_name); +static enum command_mode get_command_mode(Jim_Interp *interp, const char *cmd_name); /* set of functions to wrap jimtcl internal data */ static inline bool jimcmd_is_proc(Jim_Cmd *cmd) @@ -58,7 +59,7 @@ void *jimcmd_privdata(Jim_Cmd *cmd) return cmd->isproc ? NULL : cmd->u.native.privData; } -static void tcl_output(void *privData, const char *file, unsigned line, +static void tcl_output(void *privData, const char *file, unsigned int line, const char *function, const char *string) { struct log_capture_state *state = privData; @@ -144,7 +145,7 @@ static void script_debug(Jim_Interp *interp, unsigned int argc, Jim_Obj * const return; char *dbg = alloc_printf("command -"); - for (unsigned i = 0; i < argc; i++) { + for (unsigned int i = 0; i < argc; i++) { const char *w = Jim_GetString(argv[i], NULL); char *t = alloc_printf("%s %s", dbg, w); free(dbg); @@ -288,7 +289,7 @@ int __register_commands(struct command_context *cmd_ctx, const char *cmd_prefix, struct target *override_target) { int retval = ERROR_OK; - unsigned i; + unsigned int i; for (i = 0; cmds[i].name || cmds[i].chain; i++) { const struct command_registration *cr = cmds + i; @@ -323,7 +324,7 @@ int __register_commands(struct command_context *cmd_ctx, const char *cmd_prefix, } } if (retval != ERROR_OK) { - for (unsigned j = 0; j < i; j++) + for (unsigned int j = 0; j < i; j++) unregister_command(cmd_ctx, cmd_prefix, cmds[j].name); } return retval; @@ -673,7 +674,7 @@ COMMAND_HANDLER(handle_echo) } if (CMD_ARGC != 1) - return ERROR_FAIL; + return ERROR_COMMAND_SYNTAX_ERROR; LOG_USER("%s", CMD_ARGV[0]); return ERROR_OK; @@ -728,12 +729,12 @@ static COMMAND_HELPER(command_help_show_list, bool show_help, const char *cmd_ma #define HELP_LINE_WIDTH(_n) (int)(76 - (2 * _n)) -static void command_help_show_indent(unsigned n) +static void command_help_show_indent(unsigned int n) { - for (unsigned i = 0; i < n; i++) + for (unsigned int i = 0; i < n; i++) LOG_USER_N(" "); } -static void command_help_show_wrap(const char *str, unsigned n, unsigned n2) +static void command_help_show_wrap(const char *str, unsigned int n, unsigned int n2) { const char *cp = str, *last = str; while (*cp) { @@ -779,24 +780,7 @@ static COMMAND_HELPER(command_help_show, struct help_entry *c, if (is_match && show_help) { char *msg; - /* TODO: factorize jim_command_mode() to avoid running jim command here */ - char *request = alloc_printf("command mode %s", c->cmd_name); - if (!request) { - LOG_ERROR("Out of memory"); - return ERROR_FAIL; - } - int retval = Jim_Eval(CMD_CTX->interp, request); - free(request); - enum command_mode mode = COMMAND_UNKNOWN; - if (retval != JIM_ERR) { - const char *result = Jim_GetString(Jim_GetResult(CMD_CTX->interp), NULL); - if (!strcmp(result, "any")) - mode = COMMAND_ANY; - else if (!strcmp(result, "config")) - mode = COMMAND_CONFIG; - else if (!strcmp(result, "exec")) - mode = COMMAND_EXEC; - } + enum command_mode mode = get_command_mode(CMD_CTX->interp, c->cmd_name); /* Normal commands are runtime-only; highlight exceptions */ if (mode != COMMAND_EXEC) { @@ -809,6 +793,7 @@ static COMMAND_HELPER(command_help_show, struct help_entry *c, case COMMAND_ANY: stage_msg = " (command valid any time)"; break; + case COMMAND_UNKNOWN: default: stage_msg = " (?mode error?)"; break; @@ -817,11 +802,13 @@ static COMMAND_HELPER(command_help_show, struct help_entry *c, } else msg = alloc_printf("%s", c->help ? c->help : ""); - if (msg) { - command_help_show_wrap(msg, n + 3, n + 3); - free(msg); - } else - return -ENOMEM; + if (!msg) { + LOG_ERROR("Out of memory"); + return ERROR_FAIL; + } + + command_help_show_wrap(msg, n + 3, n + 3); + free(msg); } return ERROR_OK; @@ -936,35 +923,41 @@ static int jim_command_dispatch(Jim_Interp *interp, int argc, Jim_Obj * const *a return retval; } +static enum command_mode get_command_mode(Jim_Interp *interp, const char *cmd_name) +{ + if (!cmd_name) + return COMMAND_UNKNOWN; + + Jim_Obj *s = Jim_NewStringObj(interp, cmd_name, -1); + Jim_IncrRefCount(s); + Jim_Cmd *cmd = Jim_GetCommand(interp, s, JIM_NONE); + Jim_DecrRefCount(interp, s); + + if (!cmd || !(jimcmd_is_proc(cmd) || jimcmd_is_oocd_command(cmd))) + return COMMAND_UNKNOWN; + + /* tcl proc */ + if (jimcmd_is_proc(cmd)) + return COMMAND_ANY; + + struct command *c = jimcmd_privdata(cmd); + return c->mode; +} + 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; + enum command_mode mode = cmd_ctx->mode; if (argc > 1) { char *full_name = alloc_concatenate_strings(argc - 1, argv + 1); if (!full_name) return JIM_ERR; - Jim_Obj *s = Jim_NewStringObj(interp, full_name, -1); - Jim_IncrRefCount(s); - Jim_Cmd *cmd = Jim_GetCommand(interp, s, JIM_NONE); - Jim_DecrRefCount(interp, s); - free(full_name); - if (!cmd || !(jimcmd_is_proc(cmd) || jimcmd_is_oocd_command(cmd))) { - Jim_SetResultString(interp, "unknown", -1); - return JIM_OK; - } - if (jimcmd_is_proc(cmd)) { - /* tcl proc */ - mode = COMMAND_ANY; - } else { - struct command *c = jimcmd_privdata(cmd); + mode = get_command_mode(interp, full_name); - mode = c->mode; - } - } else - mode = cmd_ctx->mode; + free(full_name); + } const char *mode_str; switch (mode) { @@ -977,6 +970,7 @@ static int jim_command_mode(Jim_Interp *interp, int argc, Jim_Obj *const *argv) case COMMAND_EXEC: mode_str = "exec"; break; + case COMMAND_UNKNOWN: default: mode_str = "unknown"; break; @@ -1317,7 +1311,7 @@ DEFINE_PARSE_NUM_TYPE(_llong, long long, strtoll, LLONG_MIN, LLONG_MAX) #define DEFINE_PARSE_ULONGLONG(name, type, min, max) \ DEFINE_PARSE_WRAPPER(name, type, min, max, unsigned long long, _ullong) -DEFINE_PARSE_ULONGLONG(_uint, unsigned, 0, UINT_MAX) +DEFINE_PARSE_ULONGLONG(_uint, unsigned int, 0, UINT_MAX) DEFINE_PARSE_ULONGLONG(_u64, uint64_t, 0, UINT64_MAX) DEFINE_PARSE_ULONGLONG(_u32, uint32_t, 0, UINT32_MAX) DEFINE_PARSE_ULONGLONG(_u16, uint16_t, 0, UINT16_MAX) @@ -1360,6 +1354,27 @@ int command_parse_bool_arg(const char *in, bool *out) return ERROR_COMMAND_SYNTAX_ERROR; } +COMMAND_HELPER(command_parse_str_to_buf, const char *str, void *buf, unsigned int buf_len) +{ + assert(str); + assert(buf); + + int ret = str_to_buf(str, buf, buf_len); + if (ret == ERROR_OK) + return ret; + + /* Provide a clear error message to the user */ + if (ret == ERROR_INVALID_NUMBER) { + command_print(CMD, "'%s' is not a valid number", str); + } else if (ret == ERROR_NUMBER_EXCEEDS_BUFFER) { + command_print(CMD, "Number %s exceeds %u bits", str, buf_len); + } else { + command_print(CMD, "Could not parse number '%s'", str); + } + + return ERROR_COMMAND_ARGUMENT_INVALID; +} + COMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label) { switch (CMD_ARGC) { |