Change-Id: I71d7d97e7dc315c42fc43b65cb5fcecd7bdfb581 Signed-off-by: Marc Schink <openocd-dev@marcschink.de>rtt
@@ -1356,6 +1356,7 @@ COMMAND_HANDLER(stellaris_handle_recover_command) | |||
{ | |||
struct flash_bank *bank; | |||
int retval; | |||
const char *tmp; | |||
if (CMD_ARGC != 0) | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
@@ -1370,8 +1371,11 @@ COMMAND_HANDLER(stellaris_handle_recover_command) | |||
* cycle to recover. | |||
*/ | |||
Jim_Eval_Named(CMD_CTX->interp, "catch { hla_command \"debug unlock\" }", 0, 0); | |||
if (!strcmp(Jim_GetString(Jim_GetResult(CMD_CTX->interp), NULL), "0")) { | |||
Jim_Eval_Named(CMD_CTX->interp->interp, | |||
"catch { hla_command \"debug unlock\" }", 0, 0); | |||
tmp = Jim_GetString(Jim_GetResult(CMD_CTX->interp->interp), NULL); | |||
if (!strcmp(tmp, "0")) { | |||
retval = ERROR_OK; | |||
goto user_action; | |||
} | |||
@@ -356,7 +356,7 @@ static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv); | |||
static int register_command_handler(struct command_context *cmd_ctx, | |||
struct command *c) | |||
{ | |||
Jim_Interp *interp = cmd_ctx->interp; | |||
Jim_Interp *interp = cmd_ctx->interp->interp; | |||
char *ocd_name = alloc_printf("ocd_%s", c->name); | |||
if (NULL == ocd_name) | |||
return JIM_ERR; | |||
@@ -406,7 +406,7 @@ struct command *register_command(struct command_context *context, | |||
int retval = ERROR_OK; | |||
if (NULL != cr->jim_handler && NULL == parent) { | |||
retval = Jim_CreateCommand(context->interp, cr->name, | |||
retval = Jim_CreateCommand(context->interp->interp, cr->name, | |||
cr->jim_handler, cr->jim_handler_data, NULL); | |||
} else if (NULL != cr->handler || NULL != parent) | |||
retval = register_command_handler(context, command_root(c)); | |||
@@ -643,7 +643,7 @@ int command_run_line(struct command_context *context, char *line) | |||
* happen when the Jim Tcl interpreter is provided by eCos for | |||
* instance. | |||
*/ | |||
Jim_Interp *interp = context->interp; | |||
Jim_Interp *interp = context->interp->interp; | |||
Jim_DeleteAssocData(interp, "context"); | |||
retcode = Jim_SetAssocData(interp, "context", NULL, context); | |||
if (retcode == JIM_OK) { | |||
@@ -720,8 +720,14 @@ void command_set_output_handler(struct command_context *context, | |||
struct command_context *copy_command_context(struct command_context *context) | |||
{ | |||
struct command_context *copy_context = malloc(sizeof(struct command_context)); | |||
struct command_context *copy_context; | |||
copy_context = malloc(sizeof(struct command_context)); | |||
if (!copy_context) | |||
return NULL; | |||
context->interp->refcnt++; | |||
*copy_context = *context; | |||
return copy_context; | |||
@@ -729,9 +735,18 @@ struct command_context *copy_command_context(struct command_context *context) | |||
void command_done(struct command_context *cmd_ctx) | |||
{ | |||
if (NULL == cmd_ctx) | |||
if (cmd_ctx == NULL) | |||
return; | |||
cmd_ctx->interp->refcnt--; | |||
if (!cmd_ctx->interp->refcnt) { | |||
if (cmd_ctx->interp->free) | |||
Jim_FreeInterp(cmd_ctx->interp->interp); | |||
free(cmd_ctx->interp); | |||
} | |||
free(cmd_ctx); | |||
} | |||
@@ -1269,14 +1284,28 @@ static const struct command_registration command_builtin_handlers[] = { | |||
struct command_context *command_init(const char *startup_tcl, Jim_Interp *interp) | |||
{ | |||
struct command_context *context = malloc(sizeof(struct command_context)); | |||
struct command_context *context; | |||
const char *HostOs; | |||
context = malloc(sizeof(struct command_context)); | |||
if (!context) { | |||
LOG_ERROR("Failed to allocate command context."); | |||
return NULL; | |||
} | |||
context->mode = COMMAND_EXEC; | |||
context->commands = NULL; | |||
context->current_target = 0; | |||
context->output_handler = NULL; | |||
context->output_handler_priv = NULL; | |||
context->interp = malloc(sizeof(struct command_interpreter)); | |||
if (!context->interp) { | |||
LOG_ERROR("Failed to allocate command interpreter."); | |||
free(context); | |||
return NULL; | |||
} | |||
/* Create a jim interpreter if we were not handed one */ | |||
if (interp == NULL) { | |||
@@ -1285,9 +1314,13 @@ struct command_context *command_init(const char *startup_tcl, Jim_Interp *interp | |||
/* Add all the Jim core commands */ | |||
Jim_RegisterCoreCommands(interp); | |||
Jim_InitStaticExtensions(interp); | |||
context->interp->free = true; | |||
} else { | |||
context->interp->free = false; | |||
} | |||
context->interp = interp; | |||
context->interp->interp = interp; | |||
context->interp->refcnt = 1; | |||
/* Stick to lowercase for HostOS strings. */ | |||
#if defined(_MSC_VER) | |||
@@ -1355,7 +1388,7 @@ void process_jim_events(struct command_context *cmd_ctx) | |||
return; | |||
recursion++; | |||
Jim_ProcessEvents(cmd_ctx->interp, JIM_ALL_EVENTS | JIM_DONT_WAIT); | |||
Jim_ProcessEvents(cmd_ctx->interp->interp, JIM_ALL_EVENTS | JIM_DONT_WAIT); | |||
recursion--; | |||
} | |||
@@ -39,6 +39,22 @@ enum command_mode { | |||
COMMAND_ANY, | |||
}; | |||
/** | |||
* Helper struct to share a common Jim interpreter among multiple command | |||
* contexts. | |||
*/ | |||
struct command_interpreter { | |||
/** Jim interpreter. */ | |||
Jim_Interp *interp; | |||
/** Number of references held on this interpreter. */ | |||
unsigned int refcnt; | |||
/** | |||
* Determines whether the Jim interpreter should be free'd when the last | |||
* reference is released. | |||
*/ | |||
bool free; | |||
}; | |||
struct command_context; | |||
/** The type signature for command context's output handler. */ | |||
@@ -46,7 +62,7 @@ typedef int (*command_output_handler_t)(struct command_context *context, | |||
const char *line); | |||
struct command_context { | |||
Jim_Interp *interp; | |||
struct command_interpreter *interp; | |||
enum command_mode mode; | |||
struct command *commands; | |||
int current_target; | |||
@@ -1582,7 +1582,10 @@ int jtag_init(struct command_context *cmd_ctx) | |||
if (retval != ERROR_OK) | |||
return retval; | |||
if (Jim_Eval_Named(cmd_ctx->interp, "jtag_init", __FILE__, __LINE__) != JIM_OK) | |||
retval = Jim_Eval_Named(cmd_ctx->interp->interp, "jtag_init", __FILE__, | |||
__LINE__); | |||
if (retval != JIM_OK) | |||
return ERROR_FAIL; | |||
return ERROR_OK; | |||
@@ -67,10 +67,23 @@ static int add_connection(struct service *service, struct command_context *cmd_c | |||
int flag = 1; | |||
c = malloc(sizeof(struct connection)); | |||
if (!c) { | |||
LOG_ERROR("Failed to allocate connection."); | |||
return ERROR_FAIL; | |||
} | |||
c->cmd_ctx = copy_command_context(cmd_ctx); | |||
if (!c->cmd_ctx) { | |||
LOG_ERROR("Failed to copy command context."); | |||
free(c); | |||
return ERROR_FAIL; | |||
} | |||
c->fd = -1; | |||
c->fd_out = -1; | |||
memset(&c->sin, 0, sizeof(c->sin)); | |||
c->cmd_ctx = copy_command_context(cmd_ctx); | |||
c->service = service; | |||
c->input_pending = 0; | |||
c->priv = NULL; | |||
@@ -173,7 +173,7 @@ static int tcl_new_connection(struct connection *connection) | |||
static int tcl_input(struct connection *connection) | |||
{ | |||
Jim_Interp *interp = (Jim_Interp *)connection->cmd_ctx->interp; | |||
Jim_Interp *interp; | |||
int retval; | |||
int i; | |||
ssize_t rlen; | |||
@@ -184,6 +184,8 @@ static int tcl_input(struct connection *connection) | |||
char *tc_line_new; | |||
int tc_line_size_new; | |||
interp = connection->cmd_ctx->interp->interp; | |||
rlen = connection_read(connection, &in, sizeof(in)); | |||
if (rlen <= 0) { | |||
if (rlen < 0) | |||
@@ -1470,7 +1470,7 @@ static int dsp563xx_get_default_memory(void) | |||
if (!global_cmd_ctx) | |||
return MEM_P; | |||
interp = global_cmd_ctx->interp; | |||
interp = global_cmd_ctx->interp->interp; | |||
if (!interp) | |||
return MEM_P; | |||
@@ -651,13 +651,14 @@ static int target_process_reset(struct command_context *cmd_ctx, enum target_res | |||
jtag_poll_set_enabled(false); | |||
sprintf(buf, "ocd_process_reset %s", n->name); | |||
retval = Jim_Eval(cmd_ctx->interp, buf); | |||
retval = Jim_Eval(cmd_ctx->interp->interp, buf); | |||
jtag_poll_set_enabled(save_poll); | |||
if (retval != JIM_OK) { | |||
Jim_MakeErrorMessage(cmd_ctx->interp); | |||
command_print(NULL, "%s\n", Jim_GetString(Jim_GetResult(cmd_ctx->interp), NULL)); | |||
Jim_MakeErrorMessage(cmd_ctx->interp->interp); | |||
command_print(NULL, "%s\n", | |||
Jim_GetString(Jim_GetResult(cmd_ctx->interp->interp), NULL)); | |||
return ERROR_FAIL; | |||
} | |||
@@ -1293,7 +1294,7 @@ static int target_init(struct command_context *cmd_ctx) | |||
return retval; | |||
retval = target_register_timer_callback(&handle_target, | |||
polling_interval, 1, cmd_ctx->interp); | |||
polling_interval, 1, cmd_ctx->interp->interp); | |||
if (ERROR_OK != retval) | |||
return retval; | |||