Commit a521e674 authored by oharboe's avatar oharboe
Browse files

Jim Tcl support added

git-svn-id: svn://svn.berlios.de/openocd/trunk@739 b42882b7-edfa-0310-969c-e2dbd0fdcd60
parent 4d858f71
......@@ -7,7 +7,7 @@ MAINFILE = openocd.c
endif
openocd_SOURCES = $(MAINFILE)
openocd_SOURCES = $(MAINFILE) jim.c
# set the include path found by configure
INCLUDES = -I$(top_srcdir)/src/helper \
......@@ -78,3 +78,7 @@ openocd_LDADD = $(top_builddir)/src/xsvf/libxsvf.a \
$(top_builddir)/src/flash/libflash.a $(top_builddir)/src/target/libtarget.a \
$(top_builddir)/src/pld/libpld.a \
$(FTDI2232LIB) $(FTD2XXLIB) $(MINGWLDADD) $(LIBUSB)
nobase_dist_pkglib_DATA = tcl/commands.tcl
......@@ -49,6 +49,10 @@
#include <unistd.h>
#include <errno.h>
#define JIM_EMBEDDED
#include "jim.h"
/* Give TELNET a way to find out what version this is */
int handle_version_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
......@@ -154,15 +158,175 @@ void unlockBigLock()
{
}
/* Hook to add scripting language */
Jim_Interp *interp;
command_context_t *active_cmd_ctx;
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));
}
/* try to execute as Jim command, otherwise fall back to standard command.
Note that even if the Jim command caused an error, then we succeeded
to execute it, hence this fn pretty much always returns ERROR_OK.
*/
int jim_command(command_context_t *context, char *line)
{
LOG_ERROR("Syntax error");
return ERROR_COMMAND_SYNTAX_ERROR;
int retval=ERROR_OK;
active_cmd_ctx=context;
int retcode=Jim_Eval(interp, line);
active_cmd_ctx=NULL;
const char *result;
int reslen;
result = Jim_GetString(Jim_GetResult(interp), &reslen);
if (retcode == JIM_ERR) {
int len, i;
LOG_USER_N("Runtime error, file \"%s\", line %d:" JIM_NL,
interp->errorFileName, interp->errorLine);
LOG_USER_N(" %s" JIM_NL,
Jim_GetString(interp->result, NULL));
Jim_ListLength(interp, interp->stackTrace, &len);
for (i = 0; i < len; i+= 3) {
Jim_Obj *objPtr;
const char *proc, *file, *line;
Jim_ListIndex(interp, interp->stackTrace, i, &objPtr, JIM_NONE);
proc = Jim_GetString(objPtr, NULL);
Jim_ListIndex(interp, interp->stackTrace, i+1, &objPtr,
JIM_NONE);
file = Jim_GetString(objPtr, NULL);
Jim_ListIndex(interp, interp->stackTrace, i+2, &objPtr,
JIM_NONE);
line = Jim_GetString(objPtr, NULL);
LOG_USER_N("In procedure '%s' called at file \"%s\", line %s" JIM_NL,
proc, file, line);
}
} else if (retcode == JIM_EXIT) {
// ignore.
//exit(Jim_GetExitCode(interp));
} else {
if (reslen) {
int i;
char buff[256+1];
for (i=0; i<reslen; i+=256)
{
int chunk;
chunk=reslen-i;
if (chunk>256)
chunk=256;
strncpy(buff, result, chunk);
buff[chunk]=0;
LOG_USER_N("%s", buff);
}
LOG_USER_N("%s", "\n");
}
}
return retval;
}
static int startLoop=0;
static int
Jim_Command_openocd_ignore(Jim_Interp *interp,
int argc,
Jim_Obj *const *argv,
int ignore)
{
int retval;
char *cmd = (char*)Jim_GetString(argv[1], NULL);
lockBigLock();
Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
if (startLoop)
{
// We don't know whether or not the telnet/gdb server is running...
target_call_timer_callbacks_now();
}
log_add_callback(tcl_output, tclOutput);
retval=command_run_line_internal(active_cmd_ctx, cmd);
if (startLoop)
{
target_call_timer_callbacks_now();
}
log_remove_callback(tcl_output, tclOutput);
Jim_SetResult(interp, tclOutput);
unlockBigLock();
return (ignore||(retval==ERROR_OK))?JIM_OK:JIM_ERR;
}
static int
Jim_Command_openocd(Jim_Interp *interp,
int argc,
Jim_Obj *const *argv)
{
return Jim_Command_openocd_ignore(interp, argc, argv, 1);
}
static int
Jim_Command_openocd_throw(Jim_Interp *interp,
int argc,
Jim_Obj *const *argv)
{
return Jim_Command_openocd_ignore(interp, argc, argv, 0);
}
/* find full path to file */
static int
Jim_Command_find(Jim_Interp *interp,
int argc,
Jim_Obj *const *argv)
{
if (argc!=2)
return JIM_ERR;
char *file = (char*)Jim_GetString(argv[1], NULL);
char *full_path=find_file(file);
if (full_path==NULL)
return JIM_ERR;
Jim_Obj *result = Jim_NewStringObj(interp, full_path, strlen(full_path));
free(full_path);
Jim_SetResult(interp, result);
return JIM_OK;
}
void initJim(void)
{
Jim_InitEmbedded();
/* Create an interpreter */
interp = Jim_CreateInterp();
/* Add all the Jim core commands */
Jim_RegisterCoreCommands(interp);
Jim_CreateCommand(interp, "openocd", Jim_Command_openocd, NULL, NULL);
Jim_CreateCommand(interp, "openocd_throw", Jim_Command_openocd_throw, NULL, NULL);
Jim_CreateCommand(interp, "find", Jim_Command_find, NULL, NULL);
}
int main(int argc, char *argv[])
{
initJim();
/* initialize commandline interface */
command_context_t *cmd_ctx, *cfg_cmd_ctx;
cmd_ctx = command_init();
......@@ -188,7 +352,7 @@ int main(int argc, char *argv[])
if (log_init(cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
LOG_DEBUG("log init complete");
LOG_OUTPUT( OPENOCD_VERSION "\n" );
......@@ -214,6 +378,8 @@ int main(int argc, char *argv[])
if (parse_cmdline_args(cfg_cmd_ctx, argc, argv) != ERROR_OK)
return EXIT_FAILURE;
Jim_Eval(interp, "source [find tcl/commands.tcl]");
if (parse_config_file(cfg_cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
......@@ -225,6 +391,9 @@ int main(int argc, char *argv[])
if (daemon_startup)
command_run_line(cmd_ctx, "reset");
startLoop=1;
/* handle network connections */
server_loop(cmd_ctx);
......
# implements Tcl procedures/functions
proc peek {address} {
return [openocd mdw $address]
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment