+int run_command(command_context_t *context, command_t *c, char *words[], int num_words);
+
+static void tcl_output(void *privData, const char *file, int line, const char *function, const char *string)
+{
+ Jim_Obj *tclOutput=(Jim_Obj *)privData;
+
+ Jim_AppendString(interp, tclOutput, string, strlen(string));
+}
+
+extern command_context_t *global_cmd_ctx;
+
+
+static int script_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ /* the private data is stashed in the interp structure */
+ command_t *c;
+ command_context_t *context;
+ int retval;
+ int i;
+ int nwords;
+ char **words;
+
+ target_call_timer_callbacks_now();
+ LOG_USER_N("%s", ""); /* Keep GDB connection alive*/
+
+ c = interp->cmdPrivData;
+ LOG_DEBUG("script_command - %s", c->name);
+
+ words = malloc(sizeof(char *) * argc);
+ for (i = 0; i < argc; i++)
+ {
+ int len;
+ const char *w=Jim_GetString(argv[i], &len);
+ if (*w=='#')
+ {
+ /* hit an end of line comment */
+ break;
+ }
+ words[i] = strdup(w);
+ if (words[i] == NULL)
+ {
+ return JIM_ERR;
+ }
+ LOG_DEBUG("script_command - %s, argv[%u]=%s", c->name, i, words[i]);
+ }
+ nwords = i;
+
+ /* grab the command context from the associated data */
+ context = Jim_GetAssocData(interp, "context");
+ if (context == NULL)
+ {
+ /* Tcl can invoke commands directly instead of via command_run_line(). This would
+ * happen when the Jim Tcl interpreter is provided by eCos.
+ */
+ context = global_cmd_ctx;
+ }
+
+ /* capture log output and return it */
+ Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
+ /* a garbage collect can happen, so we need a reference count to this object */
+ Jim_IncrRefCount(tclOutput);
+
+ log_add_callback(tcl_output, tclOutput);