#include "config.h"
#endif
-#include "replacements.h"
+#if !BUILD_ECOSBOARD
+/* see Embedder-HOWTO.txt in Jim Tcl project hosted on BerliOS*/
+#define JIM_EMBEDDED
+#endif
+
+// @todo the inclusion of target.h here is a layering violation
#include "target.h"
#include "command.h"
#include "configuration.h"
-
#include "log.h"
#include "time_support.h"
#include "jim-eventloop.h"
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
int fast_and_dangerous = 0;
Jim_Interp *interp = NULL;
extern command_context_t *global_cmd_ctx;
+void script_debug(Jim_Interp *interp, const char *name, int argc, Jim_Obj *const *argv)
+{
+ int i;
+
+ LOG_DEBUG("command - %s", name);
+ for (i = 0; i < argc; i++) {
+ int len;
+ const char *w = Jim_GetString(argv[i], &len);
+
+ /* end of line comment? */
+ if (*w == '#')
+ break;
+
+ LOG_DEBUG("%s - argv[%d]=%s", name, i, w);
+ }
+}
+
static int script_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
/* the private data is stashed in the interp structure */
target_call_timer_callbacks_now();
LOG_USER_N("%s", ""); /* Keep GDB connection alive*/
- LOG_DEBUG("script_command - %s", c->name);
+ script_debug(interp, c->name, argc, argv);
words = malloc(sizeof(char *) * argc);
for (i = 0; i < argc; i++)
{
return JIM_ERR;
}
- LOG_DEBUG("script_command - %s, argv[%u]=%s", c->name, i, words[i]);
}
nwords = i;
free((void *)full_name);
/* 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);
+ 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, __THIS__FILE__, __LINE__ );
free((void *)override_name);
void command_output_text(command_context_t *context, const char *data)
{
- if( context && context->output_handler && data ){
+ if ( context && context->output_handler && data ){
context->output_handler( context, data );
}
}
-void command_print_n(command_context_t *context, char *format, ...)
+void command_print_sameline(command_context_t *context, const char *format, ...)
{
char *string;
va_end(ap);
}
-void command_print(command_context_t *context, char *format, ...)
+void command_print(command_context_t *context, const char *format, ...)
{
char *string;
if (!((context->mode == COMMAND_CONFIG) || (c->mode == COMMAND_ANY) || (c->mode == context->mode) ))
{
/* Config commands can not run after the config stage */
- LOG_ERROR("Illegal mode for command");
+ LOG_ERROR("Command '%s' only runs during configuration stage", c->name);
return ERROR_FAIL;
}
int reslen;
result = Jim_GetString(Jim_GetResult(interp), &reslen);
- int i;
- char buff[256+1];
- for (i = 0; i < reslen; i += 256)
+ if (reslen>0)
{
- int chunk;
- chunk = reslen - i;
- if (chunk > 256)
- chunk = 256;
- strncpy(buff, result+i, chunk);
- buff[chunk] = 0;
- LOG_USER_N("%s", buff);
+ 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+i, chunk);
+ buff[chunk] = 0;
+ LOG_USER_N("%s", buff);
+ }
+ LOG_USER_N("%s", "\n");
}
- LOG_USER_N("%s", "\n");
retval=ERROR_OK;
}
return retval;
}
-int command_run_linef(command_context_t *context, char *format, ...)
+int command_run_linef(command_context_t *context, const char *format, ...)
{
int retval=ERROR_FAIL;
char *string;
context->output_handler = NULL;
context->output_handler_priv = NULL;
-#ifdef JIM_EMBEDDED
+#if !BUILD_ECOSBOARD
Jim_InitEmbedded();
/* Create an interpreter */
interp = Jim_CreateInterp();
#if defined( _MSC_VER )
/* WinXX - is generic, the forward
* looking problem is this:
- *
+ *
* "win32" or "win64"
*
* "winxx" is generic.
add_default_dirs();
-#ifdef JIM_EMBEDDED
+#if !BUILD_ECOSBOARD
Jim_EventLoopOnLoad(interp);
#endif
if (Jim_Eval_Named(interp, startup_tcl, "embedded:startup.tcl",1)==JIM_ERR)
/* sleep command sleeps for <n> miliseconds
* this is useful in target startup scripts
*/
-int handle_sleep_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+int handle_sleep_command(struct command_context_s *cmd_ctx,
+ char *cmd, char **args, int argc)
{
- unsigned long duration = 0;
- int busy = 0;
-
- if (argc==1)
- {
-
- } else if (argc==2)
+ bool busy = false;
+ if (argc == 2)
{
- if (strcmp(args[1], "busy")!=0)
+ if (strcmp(args[1], "busy") == 0)
+ busy = true;
+ else
return ERROR_COMMAND_SYNTAX_ERROR;
- busy = 1;
- } else
- {
- return ERROR_COMMAND_SYNTAX_ERROR;
}
+ else if (argc < 1 || argc > 2)
+ return ERROR_COMMAND_SYNTAX_ERROR;
- duration = strtoul(args[0], NULL, 0);
+ unsigned long duration = 0;
+ int retval = parse_ulong(args[0], &duration);
+ if (ERROR_OK != retval)
+ return retval;
- if (busy)
- {
- busy_sleep(duration);
- } else
+ if (!busy)
{
- long long then=timeval_ms();
- while ((timeval_ms()-then)<(long long)duration)
+ long long then = timeval_ms();
+ while (timeval_ms() - then < (long long)duration)
{
target_call_timer_callbacks_now();
usleep(1000);
}
}
+ else
+ busy_sleep(duration);
return ERROR_OK;
}
void process_jim_events(void)
{
-#ifdef JIM_EMBEDDED
+#if !BUILD_ECOSBOARD
static int recursion = 0;
if (!recursion)
}
return 0;
}
+
+#define DEFINE_PARSE_NUM_TYPE(name, type, func, min, max) \
+ int parse##name(const char *str, type *ul) \
+ { \
+ if (!*str) \
+ return ERROR_COMMAND_ARGUMENT_INVALID; \
+ char *end; \
+ *ul = func(str, &end, 0); \
+ if (*end) \
+ return ERROR_COMMAND_ARGUMENT_INVALID; \
+ if ((max == *ul) && (ERANGE == errno)) \
+ return ERROR_COMMAND_ARGUMENT_OVERFLOW; \
+ if (min && (min == *ul) && (ERANGE == errno)) \
+ return ERROR_COMMAND_ARGUMENT_UNDERFLOW; \
+ return ERROR_OK; \
+ }
+DEFINE_PARSE_NUM_TYPE(_ulong, unsigned long , strtoul, 0, ULONG_MAX)
+DEFINE_PARSE_NUM_TYPE(_ullong, unsigned long long, strtoull, 0, ULLONG_MAX)
+DEFINE_PARSE_NUM_TYPE(_long, long , strtol, LONG_MIN, LONG_MAX)
+DEFINE_PARSE_NUM_TYPE(_llong, long long, strtoll, LLONG_MIN, LLONG_MAX)
+
+#define DEFINE_PARSE_WRAPPER(name, type, min, max, functype, funcname) \
+ int parse##name(const char *str, type *ul) \
+ { \
+ functype n; \
+ int retval = parse##funcname(str, &n); \
+ if (ERROR_OK != retval) \
+ return retval; \
+ if (n > max) \
+ return ERROR_COMMAND_ARGUMENT_OVERFLOW; \
+ if (min) \
+ return ERROR_COMMAND_ARGUMENT_UNDERFLOW; \
+ *ul = n; \
+ return ERROR_OK; \
+ }
+
+#define DEFINE_PARSE_ULONG(name, type, min, max) \
+ DEFINE_PARSE_WRAPPER(name, type, min, max, unsigned long, _ulong)
+DEFINE_PARSE_ULONG(_uint, unsigned, 0, UINT_MAX)
+DEFINE_PARSE_ULONG(_u32, uint32_t, 0, UINT32_MAX)
+DEFINE_PARSE_ULONG(_u16, uint16_t, 0, UINT16_MAX)
+DEFINE_PARSE_ULONG(_u8, uint8_t, 0, UINT8_MAX)
+
+#define DEFINE_PARSE_LONG(name, type, min, max) \
+ DEFINE_PARSE_WRAPPER(name, type, min, max, long, _long)
+DEFINE_PARSE_LONG(_int, int, n < INT_MIN, INT_MAX)
+DEFINE_PARSE_LONG(_s32, int32_t, n < INT32_MIN, INT32_MAX)
+DEFINE_PARSE_LONG(_s16, int16_t, n < INT16_MIN, INT16_MAX)
+DEFINE_PARSE_LONG(_s8, int8_t, n < INT8_MIN, INT8_MAX)