X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fhelper%2Fcommand.c;h=6762ad4d1412dbe63497c51a26bbb6de72f39867;hp=be262f2e463d684ca8db4db51b7dd74d5771dee2;hb=2ff1adfa79853dde77fe2698dd83e34b116daacc;hpb=91b9f3de0b8e3277ab5c584c6076ddfe491ffc86 diff --git a/src/helper/command.c b/src/helper/command.c index be262f2e46..6762ad4d14 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -36,6 +36,7 @@ #endif // @todo the inclusion of target.h here is a layering violation +#include #include #include "command.h" #include "configuration.h" @@ -84,14 +85,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); @@ -362,7 +385,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; @@ -651,7 +674,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"); } @@ -845,6 +868,9 @@ static char* openocd_jim_fgets(char *s, int size, void *cookie) return NULL; } +/* Capture progress output and return as tcl return value. If the + * progress output was empty, return tcl return value. + */ static int jim_capture(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { if (argc != 2) @@ -852,9 +878,21 @@ static int jim_capture(Jim_Interp *interp, int argc, Jim_Obj *const *argv) struct log_capture_state *state = command_log_capture_start(interp); + /* disable polling during capture. This avoids capturing output + * from polling. + * + * This is necessary in order to avoid accidentially getting a non-empty + * string for tcl fn's. + */ + bool save_poll = jtag_poll_get_enabled(); + + jtag_poll_set_enabled(false); + const char *str = Jim_GetString(argv[1], NULL); int retcode = Jim_Eval_Named(interp, str, __THIS__FILE__, __LINE__); + jtag_poll_set_enabled(save_poll); + command_log_capture_finish(state); return retcode; @@ -918,9 +956,6 @@ 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, const char *match) { - if (!command_can_run(CMD_CTX, c)) - return ERROR_OK; - char *cmd_name = command_name(c, ' '); if (NULL == cmd_name) return -ENOMEM;