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 */
int nwords;
char **words;
+ /* DANGER!!!! be careful what we invoke here, since interp->cmdPrivData might
+ * get overwritten by running other Jim commands! Treat it as an
+ * emphemeral global variable that is used in lieu of an argument
+ * to the fn and fish it out manually.
+ */
+ c = interp->cmdPrivData;
+ if (c==NULL)
+ {
+ LOG_ERROR("BUG: interp->cmdPrivData==NULL");
+ return JIM_ERR;
+ }
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);
return (retval==ERROR_OK)?JIM_OK:JIM_ERR;
}
+/* nice short description of source file */
+#define __THIS__FILE__ "command.c"
+
command_t* register_command(command_context_t *context, command_t *parent, char *name, int (*handler)(struct command_context_s *context, char* name, char** args, int argc), enum command_mode mode, char *help)
{
command_t *c, *p;
/* we now need to add an overrideable proc */
const char *override_name=alloc_printf("proc %s%s%s {args} {if {[catch {eval \"ocd_%s%s%s $args\"}]==0} {return \"\"} else { return -code error }", t1, t2, t3, t1, t2, t3);
- Jim_Eval_Named(interp, override_name, __FILE__, __LINE__ );
+ Jim_Eval_Named(interp, override_name, __THIS__FILE__, __LINE__ );
free((void *)override_name);
/* accumulate help text in Tcl helptext list. */
return ERROR_INVALID_ARGUMENTS;
/* find command */
- for (c = context->commands; c; c = c->next)
- {
+ c = context->commands;
+
+ while(NULL != c)
+ {
if (strcmp(name, c->name) == 0)
{
/* unlink command */
}
else
{
+ /* first element in command list */
context->commands = c->next;
}
-
+
/* unregister children */
- if (c->children)
+ while(NULL != c->children)
{
- for (c2 = c->children; c2; c2 = c2->next)
- {
- free(c2->name);
- free(c2);
- }
+ c2 = c->children;
+ c->children = c->children->next;
+ free(c2->name);
+ c2->name = NULL;
+ free(c2);
+ c2 = NULL;
}
-
+
/* delete command */
free(c->name);
+ c->name = NULL;
free(c);
+ c = NULL;
+ return ERROR_OK;
}
-
+
/* remember the last command for unlinking */
p = c;
+ c = c->next;
}
return ERROR_OK;
retcode = Jim_SetAssocData(interp, "retval", NULL, &retval);
if (retcode == JIM_OK)
{
- retcode = Jim_Eval_Named(interp, line, __FILE__, __LINE__ );
+ retcode = Jim_Eval_Named(interp, line, __THIS__FILE__, __LINE__ );
Jim_DeleteAssocData(interp, "retval");
}
return NULL;
}
+
+static int jim_capture(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ if (argc != 2)
+ return JIM_ERR;
+ int retcode;
+ const char *str = Jim_GetString(argv[1], NULL);
+
+ /* 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);
+
+ retcode = Jim_Eval_Named(interp, str, __THIS__FILE__, __LINE__ );
+
+ log_remove_callback(tcl_output, tclOutput);
+
+ /* We dump output into this local variable */
+ Jim_SetResult(interp, tclOutput);
+ Jim_DecrRefCount(interp, tclOutput);
+
+ return retcode;
+}
+
command_context_t* command_init()
{
command_context_t* context = malloc(sizeof(command_context_t));
- extern unsigned const char startup_tcl[];
+ extern const char startup_tcl[];
context->mode = COMMAND_EXEC;
context->commands = NULL;
Jim_CreateCommand(interp, "ocd_find", jim_find, NULL, NULL);
Jim_CreateCommand(interp, "echo", jim_echo, NULL, NULL);
+ Jim_CreateCommand(interp, "capture", jim_capture, NULL, NULL);
/* Set Jim's STDIO */
interp->cookie_stdin = interp;
busy_sleep(duration);
} else
{
- alive_sleep(duration);
+ long long then=timeval_ms();
+ while ((timeval_ms()-then)<duration)
+ {
+ target_call_timer_callbacks_now();
+ usleep(1000);
+ }
}
return ERROR_OK;
Jim_ListAppendElement(interp, cmd_entry, Jim_NewStringObj(interp, help, -1));
Jim_ListAppendElement(interp, helptext, cmd_entry);
}
+
+
+/* return global variable long value or 0 upon failure */
+long jim_global_long(const char *variable)
+{
+ Jim_Obj *objPtr=Jim_GetGlobalVariableStr(interp, variable, JIM_ERRMSG);
+ long t;
+ if (Jim_GetLong(interp, objPtr, &t)==JIM_OK)
+ {
+ return t;
+ }
+ return 0;
+}