summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZachary T Welch <zw@superlucidity.net>2009-11-29 18:39:13 -0800
committerZachary T Welch <zw@superlucidity.net>2009-11-30 16:29:34 -0800
commitcbc894ed7b07f7eea34acfea62c728bdf182918f (patch)
tree4981e470bf59a4ec7e6f15f509d7c1ce21265ba4 /src
parent7b2906de246bc37af99d432b3edf12e9f5f63521 (diff)
downloadopenocd+libswd-cbc894ed7b07f7eea34acfea62c728bdf182918f.tar.gz
openocd+libswd-cbc894ed7b07f7eea34acfea62c728bdf182918f.tar.bz2
openocd+libswd-cbc894ed7b07f7eea34acfea62c728bdf182918f.tar.xz
openocd+libswd-cbc894ed7b07f7eea34acfea62c728bdf182918f.zip
command output capture: do not use interp global
Adds a log_capture_state structure to pass to the log capture callback used by the command module. Ensures that the capture occurs in the proper context.
Diffstat (limited to 'src')
-rw-r--r--src/helper/command.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/src/helper/command.c b/src/helper/command.c
index 5df4a453..607693cc 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -52,30 +52,50 @@ Jim_Interp *interp = NULL;
static int run_command(struct command_context *context,
struct command *c, const char *words[], unsigned num_words);
+struct log_capture_state {
+ Jim_Interp *interp;
+ Jim_Obj *output;
+};
+
static void tcl_output(void *privData, const char *file, unsigned line,
const char *function, const char *string)
{
- Jim_Obj *tclOutput = (Jim_Obj *)privData;
- Jim_AppendString(interp, tclOutput, string, strlen(string));
+ struct log_capture_state *state = (struct log_capture_state *)privData;
+ Jim_AppendString(state->interp, state->output, string, strlen(string));
}
-static Jim_Obj *command_log_capture_start(Jim_Interp *interp)
+static struct log_capture_state *command_log_capture_start(Jim_Interp *interp)
{
/* capture log output and return it. A garbage collect can
* happen, so we need a reference count to this object */
Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
if (NULL == tclOutput)
return NULL;
+
+ struct log_capture_state *state = malloc(sizeof(*state));
+ if (NULL == state)
+ return NULL;
+
+ state->interp = interp;
Jim_IncrRefCount(tclOutput);
- log_add_callback(tcl_output, tclOutput);
- return tclOutput;
+ state->output = tclOutput;
+
+ log_add_callback(tcl_output, state);
+
+ return state;
}
-static void command_log_capture_finish(Jim_Interp *interp, Jim_Obj *tclOutput)
+static void command_log_capture_finish(struct log_capture_state *state)
{
- log_remove_callback(tcl_output, tclOutput);
- Jim_SetResult(interp, tclOutput);
- Jim_DecrRefCount(interp, tclOutput);
+ if (NULL == state)
+ return;
+
+ log_remove_callback(tcl_output, state);
+
+ Jim_SetResult(state->interp, state->output);
+ Jim_DecrRefCount(state->interp, state->output);
+
+ free(state);
}
static int command_retval_set(Jim_Interp *interp, int retval)
@@ -164,15 +184,14 @@ static int script_command_run(Jim_Interp *interp,
if (NULL == words)
return JIM_ERR;
- Jim_Obj *tclOutput = NULL;
+ struct log_capture_state *state = NULL;
if (capture)
- tclOutput = command_log_capture_start(interp);
+ state = command_log_capture_start(interp);
struct command_context *cmd_ctx = current_command_context();
int retval = run_command(cmd_ctx, c, (const char **)words, nwords);
- if (capture)
- command_log_capture_finish(interp, tclOutput);
+ command_log_capture_finish(state);
script_command_args_free(words, nwords);
return command_retval_set(interp, retval);
@@ -804,12 +823,12 @@ static int jim_capture(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
if (argc != 2)
return JIM_ERR;
- Jim_Obj *tclOutput = command_log_capture_start(interp);
+ struct log_capture_state *state = command_log_capture_start(interp);
const char *str = Jim_GetString(argv[1], NULL);
int retcode = Jim_Eval_Named(interp, str, __THIS__FILE__, __LINE__);
- command_log_capture_finish(interp, tclOutput);
+ command_log_capture_finish(state);
return retcode;
}