X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fhelper%2Fcommand.c;h=b7c44efc91033058c43adab890945504eac0d0e5;hp=7edd585f060a3fecf1a4849495dc5568269eb71d;hb=4d8d1d32d0f0e0b8866a06cb1d3f304563fa6796;hpb=df9b12695f4ede8144491d257ea236cdbca0a15c diff --git a/src/helper/command.c b/src/helper/command.c index 7edd585f06..b7c44efc91 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -102,8 +102,7 @@ static int script_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv) script_debug(interp, c->name, argc, argv); - words = malloc(sizeof(char *) * (argc + 1)); - words[0] = c->name; + words = malloc(argc * sizeof(char *)); for (i = 0; i < argc; i++) { int len; @@ -113,12 +112,12 @@ static int script_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv) /* hit an end of line comment */ break; } - words[i + 1] = strdup(w); - if (words[i + 1] == NULL) + words[i] = strdup(w); + if (words[i] == NULL) { int j; for (j = 0; j < i; j++) - free(words[j + 1]); + free(words[j]); free(words); return JIM_ERR; } @@ -142,8 +141,8 @@ static int script_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv) log_add_callback(tcl_output, tclOutput); - // turn words[0] into args[-1] with this cast - retval = run_command(context, c, (const char **)words + 1, nwords); + // 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); @@ -152,7 +151,7 @@ static int script_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv) Jim_DecrRefCount(interp, tclOutput); for (i = 0; i < nwords; i++) - free(words[i + 1]); + free(words[i]); free(words); int *return_retval = Jim_GetAssocData(interp, "retval"); @@ -439,7 +438,6 @@ char *command_name(struct command *c, char delim) static int run_command(struct command_context *context, struct command *c, const char *words[], unsigned num_words) { - int start_word = 0; if (!((context->mode == COMMAND_CONFIG) || (c->mode == COMMAND_ANY) || (c->mode == context->mode))) { /* Config commands can not run after the config stage */ @@ -447,9 +445,13 @@ static int run_command(struct command_context *context, return ERROR_FAIL; } - unsigned argc = num_words - start_word - 1; - const char **args = words + start_word + 1; - int retval = c->handler(context, args, argc); + struct command_invocation cmd = { + .ctx = context, + .name = c->name, + .argc = num_words - 1, + .argv = words + 1, + }; + int retval = c->handler(&cmd); if (retval == ERROR_COMMAND_SYNTAX_ERROR) { /* Print help for command */ @@ -723,18 +725,18 @@ static int jim_capture(Jim_Interp *interp, int argc, Jim_Obj *const *argv) COMMAND_HANDLER(handle_sleep_command) { bool busy = false; - if (argc == 2) + if (CMD_ARGC == 2) { - if (strcmp(args[1], "busy") == 0) + if (strcmp(CMD_ARGV[1], "busy") == 0) busy = true; else return ERROR_COMMAND_SYNTAX_ERROR; } - else if (argc < 1 || argc > 2) + else if (CMD_ARGC < 1 || CMD_ARGC > 2) return ERROR_COMMAND_SYNTAX_ERROR; unsigned long duration = 0; - int retval = parse_ulong(args[0], &duration); + int retval = parse_ulong(CMD_ARGV[0], &duration); if (ERROR_OK != retval) return retval; @@ -755,19 +757,18 @@ COMMAND_HANDLER(handle_sleep_command) COMMAND_HANDLER(handle_fast_command) { - if (argc != 1) + if (CMD_ARGC != 1) return ERROR_COMMAND_SYNTAX_ERROR; - fast_and_dangerous = strcmp("enable", args[0]) == 0; + fast_and_dangerous = strcmp("enable", CMD_ARGV[0]) == 0; return ERROR_OK; } -struct command_context* command_init() +struct command_context* command_init(const char *startup_tcl) { struct command_context* context = malloc(sizeof(struct command_context)); - extern const char startup_tcl[]; const char *HostOs; context->mode = COMMAND_EXEC; @@ -953,3 +954,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; +} + +