- Replace 'if(' with 'if ('.
[fw/openocd] / src / helper / command.c
index 9d4956c777fc348f81426f03b75a052d4671d3dd..ec1d637f15abebca01d195eaf5869eacf32fecb0 100644 (file)
@@ -61,6 +61,23 @@ static void tcl_output(void *privData, const char *file, int line, const char *f
 
 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 */
@@ -85,7 +102,7 @@ static int script_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
        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++)
@@ -102,7 +119,6 @@ static int script_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
                {
                        return JIM_ERR;
                }
-               LOG_DEBUG("script_command - %s, argv[%u]=%s", c->name, i, words[i]);
        }
        nwords = i;
 
@@ -221,7 +237,7 @@ command_t* register_command(command_context_t *context, command_t *parent, char
        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);
 
@@ -332,12 +348,12 @@ int unregister_command(command_context_t *context, char *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;
 
@@ -361,7 +377,7 @@ void command_print_n(command_context_t *context, char *format, ...)
        va_end(ap);
 }
 
-void command_print(command_context_t *context, char *format, ...)
+void command_print(command_context_t *context, const char *format, ...)
 {
        char *string;
 
@@ -392,7 +408,7 @@ int run_command(command_context_t *context, command_t *c, char *words[], int num
        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;
        }
 
@@ -497,7 +513,7 @@ int command_run_line(command_context_t *context, char *line)
        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;
@@ -757,38 +773,36 @@ int command_context_mode(command_context_t *cmd_ctx, enum command_mode mode)
 /* 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)
+       if (!busy)
        {
-               busy_sleep(duration);
-       } else
-       {
-               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;
 }
@@ -848,3 +862,52 @@ long jim_global_long(const char *variable)
        }
        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)