X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fhelper%2Fcommand.c;h=086b03d3e0b068ade1175f1e2346b700da88ec23;hb=f6a3fc818bc6a24b6c5bbcc6057f72d2b0b2e2ab;hp=cf66f8a4c701a2c402a4133880e294ca76441f9d;hpb=6d8604de37855da6e9acf79adbb488788bdc9917;p=openocd.git diff --git a/src/helper/command.c b/src/helper/command.c index cf66f8a4c7..086b03d3e0 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -84,14 +84,36 @@ static struct log_capture_state *command_log_capture_start(Jim_Interp *interp) return state; } -static void command_log_capture_finish(struct log_capture_state *state) +/* Classic openocd commands provide progress output which we + * will capture and return as a Tcl return value. + * + * However, if a non-openocd command has been invoked, then it + * makes sense to return the tcl return value from that command. + * + * The tcl return value is empty for openocd commands that provide + * progress output. + * + * Therefore we set the tcl return value only if we actually + * captured output. + */ +static void command_log_capture_finish(struct log_capture_state *state) { if (NULL == state) return; log_remove_callback(tcl_output, state); - Jim_SetResult(state->interp, state->output); + int length; + Jim_GetString(state->output, &length); + + if (length > 0) + { + Jim_SetResult(state->interp, state->output); + } else + { + /* No output captured, use tcl return value (which could + * be empty too). */ + } Jim_DecrRefCount(state->interp, state->output); free(state); @@ -108,10 +130,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 +148,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) @@ -158,14 +189,18 @@ static const char **script_command_args_alloc( return words; } -static struct command_context *current_command_context(Jim_Interp *interp) +struct command_context *current_command_context(Jim_Interp *interp) { /* grab the command context from the associated data */ struct command_context *cmd_ctx = Jim_GetAssocData(interp, "context"); if (NULL == cmd_ctx) { /* Tcl can invoke commands directly instead of via command_run_line(). This would - * happen when the Jim Tcl interpreter is provided by eCos. + * happen when the Jim Tcl interpreter is provided by eCos or if we are running + * commands in a startup script. + * + * A telnet or gdb server would provide a non-default command context to + * handle piping of error output, have a separate current target, etc. */ cmd_ctx = global_cmd_ctx; } @@ -349,7 +384,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, __THIS__FILE__ , __LINE__); + retval = Jim_Eval_Named(interp, override_name, 0, 0); free((void *)override_name); return retval; @@ -366,7 +401,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; } @@ -635,7 +673,7 @@ int command_run_line(struct command_context *context, char *line) retcode = Jim_SetAssocData(interp, "retval", NULL, &retval); if (retcode == JIM_OK) { - retcode = Jim_Eval_Named(interp, line, __THIS__FILE__, __LINE__); + retcode = Jim_Eval_Named(interp, line, 0, 0); Jim_DeleteAssocData(interp, "retval"); }