factor script_command argv allocation
[openocd.git] / src / helper / command.c
index 708a8024f291927f227cab17103aec495d9a9b0b..ba28784da3cf604f53ff23e160cb0fcabe3fe570 100644 (file)
@@ -44,7 +44,6 @@
 #include "jim-eventloop.h"
 
 
-int fast_and_dangerous = 0;
 Jim_Interp *interp = NULL;
 
 static int run_command(struct command_context *context,
@@ -76,15 +75,45 @@ void script_debug(Jim_Interp *interp, const char *name,
        }
 }
 
+static void script_command_args_free(const char **words, unsigned nwords)
+{
+       for (unsigned i = 0; i < nwords; i++)
+               free((void *)words[i]);
+       free(words);
+}
+static const char **script_command_args_alloc(
+               unsigned argc, Jim_Obj *const *argv, unsigned *nwords)
+{
+       const char **words = malloc(argc * sizeof(char *));
+       if (NULL == words)
+               return NULL;
+
+       unsigned i;
+       for (i = 0; i < argc; i++)
+       {
+               int len;
+               const char *w = Jim_GetString(argv[i], &len);
+               /* a comment may end the line early */
+               if (*w == '#')
+                       break;
+
+               words[i] = strdup(w);
+               if (words[i] == NULL)
+               {
+                       script_command_args_free(words, i);
+                       return NULL;
+               }
+       }
+       *nwords = i;
+       return words;
+}
+
 static int script_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 {
        /* the private data is stashed in the interp structure */
        struct command *c;
        struct command_context *context;
        int retval;
-       int i;
-       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
@@ -102,27 +131,10 @@ static int script_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 
        script_debug(interp, c->name, argc, argv);
 
-       words = malloc(argc * sizeof(char *));
-       for (i = 0; i < argc; i++)
-       {
-               int len;
-               const char *w = Jim_GetString(argv[i], &len);
-               if (*w=='#')
-               {
-                       /* hit an end of line comment */
-                       break;
-               }
-               words[i] = strdup(w);
-               if (words[i] == NULL)
-               {
-                       int j;
-                       for (j = 0; j < i; j++)
-                               free(words[j]);
-                       free(words);
-                       return JIM_ERR;
-               }
-       }
-       nwords = i;
+       unsigned nwords;
+       const char **words = script_command_args_alloc(argc, argv, &nwords);
+       if (NULL == words)
+               return JIM_ERR;
 
        /* grab the command context from the associated data */
        context = Jim_GetAssocData(interp, "context");
@@ -141,7 +153,6 @@ static int script_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 
        log_add_callback(tcl_output, tclOutput);
 
-       // turn words[0] into CMD_ARGV[-1] with this cast
        retval = run_command(context, c, (const char **)words, nwords);
 
        log_remove_callback(tcl_output, tclOutput);
@@ -150,9 +161,7 @@ static int script_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
        Jim_SetResult(interp, tclOutput);
        Jim_DecrRefCount(interp, tclOutput);
 
-       for (i = 0; i < nwords; i++)
-               free(words[i]);
-       free(words);
+       script_command_args_free(words, nwords);
 
        int *return_retval = Jim_GetAssocData(interp, "retval");
        if (return_retval != NULL)
@@ -755,17 +764,6 @@ COMMAND_HANDLER(handle_sleep_command)
        return ERROR_OK;
 }
 
-COMMAND_HANDLER(handle_fast_command)
-{
-       if (CMD_ARGC != 1)
-               return ERROR_COMMAND_SYNTAX_ERROR;
-
-       fast_and_dangerous = strcmp("enable", CMD_ARGV[0]) == 0;
-
-       return ERROR_OK;
-}
-
-
 struct command_context* command_init(const char *startup_tcl)
 {
        struct command_context* context = malloc(sizeof(struct command_context));
@@ -839,10 +837,6 @@ struct command_context* command_init(const char *startup_tcl)
                        handle_sleep_command, COMMAND_ANY,
                        "<n> [busy] - sleep for n milliseconds. "
                        "\"busy\" means busy wait");
-       register_command(context, NULL, "fast",
-                       handle_fast_command, COMMAND_ANY,
-                       "fast <enable/disable> - place at beginning of "
-                       "config files. Sets defaults to fast and dangerous.");
 
        return context;
 }
@@ -882,18 +876,6 @@ void register_jim(struct command_context *cmd_ctx, const char *name,
        command_helptext_add(cmd_list, help);
 }
 
-/* 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;
-}
-
 #define DEFINE_PARSE_NUM_TYPE(name, type, func, min, max) \
        int parse##name(const char *str, type *ul) \
        { \
@@ -954,3 +936,53 @@ 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)
+
+static int command_parse_bool(const char *in, bool *out,
+               const char *on, const char *off)
+{
+       if (strcasecmp(in, on) == 0)
+               *out = true;
+       else if (strcasecmp(in, off) == 0)
+               *out = false;
+       else
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       return  ERROR_OK;
+}
+
+int command_parse_bool_arg(const char *in, bool *out)
+{
+       if (command_parse_bool(in, out, "on", "off") == ERROR_OK)
+               return ERROR_OK;
+       if (command_parse_bool(in, out, "enable", "disable") == ERROR_OK)
+               return ERROR_OK;
+       if (command_parse_bool(in, out, "true", "false") == ERROR_OK)
+               return ERROR_OK;
+       if (command_parse_bool(in, out, "yes", "no") == ERROR_OK)
+               return ERROR_OK;
+       if (command_parse_bool(in, out, "1", "0") == ERROR_OK)
+               return ERROR_OK;
+       return ERROR_INVALID_ARGUMENTS;
+}
+
+COMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label)
+{
+       switch (CMD_ARGC) {
+       case 1: {
+               const char *in = CMD_ARGV[0];
+               if (command_parse_bool_arg(in, out) != ERROR_OK)
+               {
+                       LOG_ERROR("%s: argument '%s' is not valid", CMD_NAME, in);
+                       return ERROR_INVALID_ARGUMENTS;
+               }
+               // fall through
+       }
+       case 0:
+               LOG_INFO("%s is %s", label, *out ? "enabled" : "disabled");
+               break;
+       default:
+               return ERROR_INVALID_ARGUMENTS;
+       }
+       return ERROR_OK;
+}
+
+

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)