]> www.infradead.org Git - users/borneoa/openocd-next.git/commitdiff
target: rewrite function target_configure() as COMMAND_HELPER
authorAntonio Borneo <borneo.antonio@gmail.com>
Sun, 3 Dec 2023 14:41:27 +0000 (15:41 +0100)
committerAntonio Borneo <borneo.antonio@gmail.com>
Sat, 19 Apr 2025 09:22:42 +0000 (09:22 +0000)
The function target_configure() is used by the commands
'target create', 'configure' and 'cget', already rewritten as
COMMAND_HANDLER.

Rewrite the common function as COMMAND_HELPER.
While there:
- fix the check on arguments, even if it should be coded better;
- keep jimtcl code for target_type::target_jim_configure() and for
  rtos_create(); these would be rewritten later on.

Change-Id: I7e5699ca6d124e34d3b2199714e3ce584bfcce80
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8829
Tested-by: jenkins
src/target/target.c

index 4bd2f24ccae7b423484a64e65330827b680f6280..99481622db43a6f9210dc998d09491e5da9bc41d 100644 (file)
@@ -214,8 +214,6 @@ static const struct nvp nvp_target_event[] = {
        { .name = NULL, .value = -1 }
 };
 
-static const struct jim_nvp *jim_nvp_target_event = (const struct jim_nvp *)nvp_target_event;
-
 static const struct nvp nvp_target_state[] = {
        { .name = "unknown", .value = TARGET_UNKNOWN },
        { .name = "running", .value = TARGET_RUNNING },
@@ -238,7 +236,7 @@ static const struct nvp nvp_target_debug_reason[] = {
        { .name = NULL, .value = -1 },
 };
 
-static const struct jim_nvp nvp_target_endian[] = {
+static const struct nvp nvp_target_endian[] = {
        { .name = "big",    .value = TARGET_BIG_ENDIAN },
        { .name = "little", .value = TARGET_LITTLE_ENDIAN },
        { .name = "be",     .value = TARGET_BIG_ENDIAN },
@@ -2844,8 +2842,7 @@ COMMAND_HANDLER(handle_targets_command)
                                marker,
                                target_name(target),
                                target_type_name(target),
-                               jim_nvp_value2name_simple(nvp_target_endian,
-                                       target->endianness)->name,
+                               nvp_value2name(nvp_target_endian, target->endianness)->name,
                                target->tap->dotted_name,
                                state);
        }
@@ -4859,7 +4856,7 @@ enum target_cfg_param {
        TCFG_GDB_MAX_CONNECTIONS,
 };
 
-static struct jim_nvp nvp_config_opts[] = {
+static struct nvp nvp_config_opts[] = {
        { .name = "-type",             .value = TCFG_TYPE },
        { .name = "-event",            .value = TCFG_EVENT },
        { .name = "-work-area-virt",   .value = TCFG_WORK_AREA_VIRT },
@@ -4877,78 +4874,71 @@ static struct jim_nvp nvp_config_opts[] = {
        { .name = NULL, .value = -1 }
 };
 
-static int target_configure(struct jim_getopt_info *goi, struct target *target)
+static COMMAND_HELPER(target_configure, struct target *target, unsigned int index, bool is_configure)
 {
-       struct jim_nvp *n;
-       Jim_Obj *o;
-       jim_wide w;
-       int e;
+       const struct nvp *n;
+       int retval;
 
        /* parse config or cget options ... */
-       while (goi->argc > 0) {
-               Jim_SetEmptyResult(goi->interp);
-               /* jim_getopt_debug(goi); */
-
+       while (index < CMD_ARGC) {
                if (target->type->target_jim_configure) {
                        /* target defines a configure function */
                        /* target gets first dibs on parameters */
-                       e = (*(target->type->target_jim_configure))(target, goi);
+                       struct jim_getopt_info goi;
+                       jim_getopt_setup(&goi, CMD_CTX->interp, CMD_ARGC - index, CMD_JIMTCL_ARGV + index);
+                       goi.is_configure = is_configure;
+                       int e = (*target->type->target_jim_configure)(target, &goi);
+                       index = CMD_ARGC - goi.argc;
                        if (e == JIM_OK) {
                                /* more? */
                                continue;
                        }
                        if (e == JIM_ERR) {
                                /* An error */
-                               return e;
+                               int reslen;
+                               const char *result = Jim_GetString(Jim_GetResult(CMD_CTX->interp), &reslen);
+                               if (reslen > 0)
+                                       command_print(CMD, "%s", result);
+                               return ERROR_FAIL;
                        }
                        /* otherwise we 'continue' below */
                }
-               e = jim_getopt_nvp(goi, nvp_config_opts, &n);
-               if (e != JIM_OK) {
-                       jim_getopt_nvp_unknown(goi, nvp_config_opts, 0);
-                       return e;
+               n = nvp_name2value(nvp_config_opts, CMD_ARGV[index]);
+               if (!n->name) {
+                       nvp_unknown_command_print(CMD, nvp_config_opts, NULL, CMD_ARGV[index]);
+                       return ERROR_COMMAND_ARGUMENT_INVALID;
                }
+               index++;
                switch (n->value) {
                case TCFG_TYPE:
                        /* not settable */
-                       if (goi->is_configure) {
-                               Jim_SetResultFormatted(goi->interp,
-                                               "not settable: %s", n->name);
-                               return JIM_ERR;
-                       } else {
-no_params:
-                               if (goi->argc != 0) {
-                                       Jim_WrongNumArgs(goi->interp,
-                                                       goi->argc, goi->argv,
-                                                       "NO PARAMS");
-                                       return JIM_ERR;
-                               }
+                       if (is_configure) {
+                               command_print(CMD, "not settable: %s", n->name);
+                               return ERROR_COMMAND_ARGUMENT_INVALID;
                        }
-                       Jim_SetResultString(goi->interp,
-                                       target_type_name(target), -1);
+                       if (index != CMD_ARGC)
+                               return ERROR_COMMAND_SYNTAX_ERROR;
+                       command_print(CMD, "%s", target_type_name(target));
                        /* loop for more */
                        break;
+
                case TCFG_EVENT:
-                       if (goi->argc == 0) {
-                               Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name? ...");
-                               return JIM_ERR;
+                       if (index == CMD_ARGC) {
+                               command_print(CMD, "missing event-name");
+                               return ERROR_COMMAND_ARGUMENT_INVALID;
                        }
 
-                       e = jim_getopt_nvp(goi, jim_nvp_target_event, &n);
-                       if (e != JIM_OK) {
-                               jim_getopt_nvp_unknown(goi, jim_nvp_target_event, 1);
-                               return e;
+                       n = nvp_name2value(nvp_target_event, CMD_ARGV[index]);
+                       if (!n->name) {
+                               nvp_unknown_command_print(CMD, nvp_target_event, CMD_ARGV[index - 1], CMD_ARGV[index]);
+                               return ERROR_COMMAND_ARGUMENT_INVALID;
                        }
+                       index++;
 
-                       if (goi->is_configure) {
-                               if (goi->argc != 1) {
-                                       Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name? ?EVENT-BODY?");
-                                       return JIM_ERR;
-                               }
-                       } else {
-                               if (goi->argc != 0) {
-                                       Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name?");
-                                       return JIM_ERR;
+                       if (is_configure) {
+                               if (index == CMD_ARGC) {
+                                       command_print(CMD, "missing event-body");
+                                       return ERROR_COMMAND_ARGUMENT_INVALID;
                                }
                        }
 
@@ -4964,20 +4954,20 @@ no_params:
                                if (&teap->list == &target->events_action)
                                        teap = NULL;
 
-                               if (goi->is_configure) {
+                               if (is_configure) {
                                        /* START_DEPRECATED_TPIU */
                                        if (n->value == TARGET_EVENT_TRACE_CONFIG)
                                                LOG_INFO("DEPRECATED target event %s; use TPIU events {pre,post}-{enable,disable}", n->name);
                                        /* END_DEPRECATED_TPIU */
 
-                                       jim_getopt_obj(goi, &o);
-                                       if (Jim_Length(o) == 0) {
+                                       if (strlen(CMD_ARGV[index]) == 0) {
                                                /* empty action, drop existing one */
                                                if (teap) {
                                                        list_del(&teap->list);
                                                        Jim_DecrRefCount(teap->interp, teap->body);
                                                        free(teap);
                                                }
+                                               index++;
                                                break;
                                        }
 
@@ -4988,10 +4978,12 @@ no_params:
                                                replace = false;
                                        }
                                        teap->event = n->value;
-                                       teap->interp = goi->interp;
+                                       teap->interp = CMD_CTX->interp;
                                        if (teap->body)
                                                Jim_DecrRefCount(teap->interp, teap->body);
-                                       teap->body  = Jim_DuplicateObj(goi->interp, o);
+                                       /* use jim object to keep its reference on tcl file and line */
+                                       /* TODO: need duplicate? isn't IncrRefCount enough? */
+                                       teap->body  = Jim_DuplicateObj(teap->interp, CMD_JIMTCL_ARGV[index++]);
                                        /*
                                         * FIXME:
                                         *     Tcl/TK - "tk events" have a nice feature.
@@ -5008,219 +5000,266 @@ no_params:
                                                /* add to head of event list */
                                                list_add(&teap->list, &target->events_action);
                                        }
-                                       Jim_SetEmptyResult(goi->interp);
                                } else {
-                                       /* get */
-                                       if (!teap)
-                                               Jim_SetEmptyResult(goi->interp);
-                                       else
-                                               Jim_SetResult(goi->interp, Jim_DuplicateObj(goi->interp, teap->body));
+                                       /* cget */
+                                       if (index != CMD_ARGC)
+                                               return ERROR_COMMAND_SYNTAX_ERROR;
+
+                                       if (teap)
+                                               command_print(CMD, "%s", Jim_GetString(teap->body, NULL));
                                }
                        }
                        /* loop for more */
                        break;
 
                case TCFG_WORK_AREA_VIRT:
-                       if (goi->is_configure) {
-                               target_free_all_working_areas(target);
-                               e = jim_getopt_wide(goi, &w);
-                               if (e != JIM_OK)
-                                       return e;
-                               target->working_area_virt = w;
+                       if (is_configure) {
+                               if (index == CMD_ARGC) {
+                                       command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]);
+                                       return ERROR_COMMAND_ARGUMENT_INVALID;
+                               }
+                               COMMAND_PARSE_NUMBER(u64, CMD_ARGV[index], target->working_area_virt);
+                               index++;
                                target->working_area_virt_spec = true;
+                               target_free_all_working_areas(target);
                        } else {
-                               if (goi->argc != 0)
-                                       goto no_params;
+                               if (index != CMD_ARGC)
+                                       return ERROR_COMMAND_SYNTAX_ERROR;
+                               command_print(CMD, TARGET_ADDR_FMT, target->working_area_virt);
                        }
-                       Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_virt));
                        /* loop for more */
                        break;
 
                case TCFG_WORK_AREA_PHYS:
-                       if (goi->is_configure) {
-                               target_free_all_working_areas(target);
-                               e = jim_getopt_wide(goi, &w);
-                               if (e != JIM_OK)
-                                       return e;
-                               target->working_area_phys = w;
+                       if (is_configure) {
+                               if (index == CMD_ARGC) {
+                                       command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]);
+                                       return ERROR_COMMAND_ARGUMENT_INVALID;
+                               }
+                               COMMAND_PARSE_NUMBER(u64, CMD_ARGV[index], target->working_area_phys);
+                               index++;
                                target->working_area_phys_spec = true;
+                               target_free_all_working_areas(target);
                        } else {
-                               if (goi->argc != 0)
-                                       goto no_params;
+                               if (index != CMD_ARGC)
+                                       return ERROR_COMMAND_SYNTAX_ERROR;
+                               command_print(CMD, TARGET_ADDR_FMT, target->working_area_phys);
                        }
-                       Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_phys));
                        /* loop for more */
                        break;
 
                case TCFG_WORK_AREA_SIZE:
-                       if (goi->is_configure) {
+                       if (is_configure) {
+                               if (index == CMD_ARGC) {
+                                       command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]);
+                                       return ERROR_COMMAND_ARGUMENT_INVALID;
+                               }
+                               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[index], target->working_area_size);
+                               index++;
                                target_free_all_working_areas(target);
-                               e = jim_getopt_wide(goi, &w);
-                               if (e != JIM_OK)
-                                       return e;
-                               target->working_area_size = w;
                        } else {
-                               if (goi->argc != 0)
-                                       goto no_params;
+                               if (index != CMD_ARGC)
+                                       return ERROR_COMMAND_SYNTAX_ERROR;
+                               command_print(CMD, "0x%08" PRIx32, target->working_area_size);
                        }
-                       Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_size));
                        /* loop for more */
                        break;
 
                case TCFG_WORK_AREA_BACKUP:
-                       if (goi->is_configure) {
+                       if (is_configure) {
+                               if (index == CMD_ARGC) {
+                                       command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]);
+                                       return ERROR_COMMAND_ARGUMENT_INVALID;
+                               }
+                               retval = command_parse_bool_arg(CMD_ARGV[index], &target->backup_working_area);
+                               if (retval != ERROR_OK)
+                                       return retval;
+                               index++;
                                target_free_all_working_areas(target);
-                               e = jim_getopt_wide(goi, &w);
-                               if (e != JIM_OK)
-                                       return e;
-                               /* make this boolean */
-                               target->backup_working_area = (w != 0);
                        } else {
-                               if (goi->argc != 0)
-                                       goto no_params;
+                               if (index != CMD_ARGC)
+                                       return ERROR_COMMAND_SYNTAX_ERROR;
+                               command_print(CMD, target->backup_working_area ? "1" : "0");
                        }
-                       Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->backup_working_area ? 1 : 0));
-                       /* loop for more e*/
+                       /* loop for more */
                        break;
 
-
                case TCFG_ENDIAN:
-                       if (goi->is_configure) {
-                               e = jim_getopt_nvp(goi, nvp_target_endian, &n);
-                               if (e != JIM_OK) {
-                                       jim_getopt_nvp_unknown(goi, nvp_target_endian, 1);
-                                       return e;
+                       if (is_configure) {
+                               if (index == CMD_ARGC) {
+                                       command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]);
+                                       return ERROR_COMMAND_ARGUMENT_INVALID;
+                               }
+                               n = nvp_name2value(nvp_target_endian, CMD_ARGV[index]);
+                               if (!n->name) {
+                                       nvp_unknown_command_print(CMD, nvp_target_endian, CMD_ARGV[index - 1], CMD_ARGV[index]);
+                                       return ERROR_COMMAND_ARGUMENT_INVALID;
                                }
+                               index++;
                                target->endianness = n->value;
                        } else {
-                               if (goi->argc != 0)
-                                       goto no_params;
-                       }
-                       n = jim_nvp_value2name_simple(nvp_target_endian, target->endianness);
-                       if (!n->name) {
-                               target->endianness = TARGET_LITTLE_ENDIAN;
-                               n = jim_nvp_value2name_simple(nvp_target_endian, target->endianness);
+                               if (index != CMD_ARGC)
+                                       return ERROR_COMMAND_SYNTAX_ERROR;
+                               n = nvp_value2name(nvp_target_endian, target->endianness);
+                               if (!n->name) {
+                                       target->endianness = TARGET_LITTLE_ENDIAN;
+                                       n = nvp_value2name(nvp_target_endian, target->endianness);
+                               }
+                               command_print(CMD, "%s", n->name);
                        }
-                       Jim_SetResultString(goi->interp, n->name, -1);
                        /* loop for more */
                        break;
 
                case TCFG_COREID:
-                       if (goi->is_configure) {
-                               e = jim_getopt_wide(goi, &w);
-                               if (e != JIM_OK)
-                                       return e;
-                               target->coreid = (int32_t)w;
+                       if (is_configure) {
+                               if (index == CMD_ARGC) {
+                                       command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]);
+                                       return ERROR_COMMAND_ARGUMENT_INVALID;
+                               }
+                               COMMAND_PARSE_NUMBER(s32, CMD_ARGV[index], target->coreid);
+                               index++;
                        } else {
-                               if (goi->argc != 0)
-                                       goto no_params;
+                               if (index != CMD_ARGC)
+                                       return ERROR_COMMAND_SYNTAX_ERROR;
+                               command_print(CMD, "%" PRIi32, target->coreid);
                        }
-                       Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->coreid));
                        /* loop for more */
                        break;
 
                case TCFG_CHAIN_POSITION:
-                       if (goi->is_configure) {
-                               Jim_Obj *o_t;
-                               struct jtag_tap *tap;
-
+                       if (is_configure) {
                                if (target->has_dap) {
-                                       Jim_SetResultString(goi->interp,
-                                               "target requires -dap parameter instead of -chain-position!", -1);
-                                       return JIM_ERR;
+                                       command_print(CMD, "target requires -dap parameter instead of -chain-position!");
+                                       return ERROR_COMMAND_ARGUMENT_INVALID;
                                }
 
-                               e = jim_getopt_obj(goi, &o_t);
-                               if (e != JIM_OK)
-                                       return e;
-                               tap = jtag_tap_by_jim_obj(goi->interp, o_t);
-                               if (!tap)
-                                       return JIM_ERR;
+                               if (index == CMD_ARGC) {
+                                       command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]);
+                                       return ERROR_COMMAND_ARGUMENT_INVALID;
+                               }
+                               struct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[index]);
+                               if (!tap) {
+                                       command_print(CMD, "Tap '%s' could not be found", CMD_ARGV[index]);
+                                       return ERROR_COMMAND_ARGUMENT_INVALID;
+                               }
+                               index++;
                                target->tap = tap;
                                target->tap_configured = true;
                        } else {
-                               if (goi->argc != 0)
-                                       goto no_params;
+                               if (index != CMD_ARGC)
+                                       return ERROR_COMMAND_SYNTAX_ERROR;
+                               command_print(CMD, "%s", target->tap->dotted_name);
                        }
-                       Jim_SetResultString(goi->interp, target->tap->dotted_name, -1);
-                       /* loop for more e*/
+                       /* loop for more */
                        break;
+
                case TCFG_DBGBASE:
-                       if (goi->is_configure) {
-                               e = jim_getopt_wide(goi, &w);
-                               if (e != JIM_OK)
-                                       return e;
-                               target->dbgbase = (uint32_t)w;
+                       if (is_configure) {
+                               if (index == CMD_ARGC) {
+                                       command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]);
+                                       return ERROR_COMMAND_ARGUMENT_INVALID;
+                               }
+                               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[index], target->dbgbase);
+                               index++;
                                target->dbgbase_set = true;
                        } else {
-                               if (goi->argc != 0)
-                                       goto no_params;
+                               if (index != CMD_ARGC)
+                                       return ERROR_COMMAND_SYNTAX_ERROR;
+                               command_print(CMD, "0x%08" PRIx32, target->dbgbase);
                        }
-                       Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->dbgbase));
                        /* loop for more */
                        break;
+
                case TCFG_RTOS:
-                       /* RTOS */
-                       {
-                               int result = rtos_create(goi, target);
-                               if (result != JIM_OK)
-                                       return result;
+                       if (is_configure) {
+                               if (index == CMD_ARGC) {
+                                       command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]);
+                                       return ERROR_COMMAND_ARGUMENT_INVALID;
+                               }
+                               struct jim_getopt_info goi;
+                               jim_getopt_setup(&goi, CMD_CTX->interp, CMD_ARGC - index, CMD_JIMTCL_ARGV + index);
+                               index++;
+                               goi.is_configure = true;
+                               int resval = rtos_create(&goi, target);
+                               int reslen;
+                               const char *result = Jim_GetString(Jim_GetResult(CMD_CTX->interp), &reslen);
+                               if (reslen > 0)
+                                       command_print(CMD, "%s", result);
+                               if (resval != JIM_OK)
+                                       return ERROR_FAIL;
+                       } else {
+                               if (index != CMD_ARGC)
+                                       return ERROR_COMMAND_SYNTAX_ERROR;
+                               if (target->rtos)
+                                       command_print(CMD, "%s", target->rtos->type->name);
                        }
                        /* loop for more */
                        break;
 
                case TCFG_DEFER_EXAMINE:
-                       /* DEFER_EXAMINE */
-                       target->defer_examine = true;
+                       if (is_configure)
+                               target->defer_examine = true;
+                       else
+                               command_print(CMD, "%s", target->defer_examine ? "true" : "false");
                        /* loop for more */
                        break;
 
                case TCFG_GDB_PORT:
-                       if (goi->is_configure) {
-                               struct command_context *cmd_ctx = current_command_context(goi->interp);
-                               if (cmd_ctx->mode != COMMAND_CONFIG) {
-                                       Jim_SetResultString(goi->interp, "-gdb-port must be configured before 'init'", -1);
-                                       return JIM_ERR;
+                       if (is_configure) {
+                               if (index == CMD_ARGC) {
+                                       command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]);
+                                       return ERROR_COMMAND_ARGUMENT_INVALID;
+                               }
+
+                               /* TODO: generalize test of COMMAND_CONFIG */
+                               if (CMD_CTX->mode != COMMAND_CONFIG) {
+                                       command_print(CMD, "-gdb-port must be configured before 'init'");
+                                       return ERROR_COMMAND_ARGUMENT_INVALID;
                                }
 
-                               const char *s;
-                               e = jim_getopt_string(goi, &s, NULL);
-                               if (e != JIM_OK)
-                                       return e;
+                               char *s = strdup(CMD_ARGV[index]);
+                               if (!s) {
+                                       LOG_ERROR("Out of memory");
+                                       return ERROR_FAIL;
+                               }
                                free(target->gdb_port_override);
-                               target->gdb_port_override = strdup(s);
+                               target->gdb_port_override = s;
+                               index++;
                        } else {
-                               if (goi->argc != 0)
-                                       goto no_params;
+                               if (index != CMD_ARGC)
+                                       return ERROR_COMMAND_SYNTAX_ERROR;
+                               command_print(CMD, "%s", target->gdb_port_override ? target->gdb_port_override : "undefined");
                        }
-                       Jim_SetResultString(goi->interp, target->gdb_port_override ? target->gdb_port_override : "undefined", -1);
                        /* loop for more */
                        break;
 
                case TCFG_GDB_MAX_CONNECTIONS:
-                       if (goi->is_configure) {
-                               struct command_context *cmd_ctx = current_command_context(goi->interp);
-                               if (cmd_ctx->mode != COMMAND_CONFIG) {
-                                       Jim_SetResultString(goi->interp, "-gdb-max-connections must be configured before 'init'", -1);
-                                       return JIM_ERR;
+                       if (is_configure) {
+                               if (index == CMD_ARGC) {
+                                       command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]);
+                                       return ERROR_COMMAND_ARGUMENT_INVALID;
+                               }
+
+                               if (CMD_CTX->mode != COMMAND_CONFIG) {
+                                       command_print(CMD, "-gdb-max-connections must be configured before 'init'");
+                                       return ERROR_COMMAND_ARGUMENT_INVALID;
                                }
 
-                               e = jim_getopt_wide(goi, &w);
-                               if (e != JIM_OK)
-                                       return e;
-                               target->gdb_max_connections = (w < 0) ? CONNECTION_LIMIT_UNLIMITED : (int)w;
+                               COMMAND_PARSE_NUMBER(int, CMD_ARGV[index], target->gdb_max_connections);
+                               index++;
+                               if (target->gdb_max_connections < 0)
+                                       target->gdb_max_connections = CONNECTION_LIMIT_UNLIMITED;
                        } else {
-                               if (goi->argc != 0)
-                                       goto no_params;
+                               if (index != CMD_ARGC)
+                                       return ERROR_COMMAND_SYNTAX_ERROR;
+                               command_print(CMD, "%d", target->gdb_max_connections);
                        }
-                       Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->gdb_max_connections));
+                       /* loop for more */
                        break;
                }
-       } /* while (goi->argc) */
-
+       }
 
-               /* done - we return */
-       return JIM_OK;
+       return ERROR_OK;
 }
 
 COMMAND_HANDLER(handle_target_configure)
@@ -5228,23 +5267,11 @@ COMMAND_HANDLER(handle_target_configure)
        if (!CMD_ARGC)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       struct jim_getopt_info goi;
-
-       jim_getopt_setup(&goi, CMD_CTX->interp, CMD_ARGC, CMD_JIMTCL_ARGV);
-       goi.is_configure = !strcmp(CMD_NAME, "configure");
+       bool is_configure = !strcmp(CMD_NAME, "configure");
 
        struct target *target = get_current_target(CMD_CTX);
-       int e = target_configure(&goi, target);
-
-       int reslen;
-       const char *result = Jim_GetString(Jim_GetResult(CMD_CTX->interp), &reslen);
-       if (reslen > 0)
-               command_print(CMD, "%s", result);
-
-       if (e != JIM_OK)
-               return ERROR_FAIL;
 
-       return ERROR_OK;
+       return CALL_COMMAND_HANDLER(target_configure, target, 0, is_configure);
 }
 
 COMMAND_HANDLER(handle_target_examine)
@@ -5803,18 +5830,9 @@ COMMAND_HANDLER(handle_target_create)
        }
 
        /* Do the rest as "configure" options */
-       struct jim_getopt_info goi;
-       jim_getopt_setup(&goi, CMD_CTX->interp, CMD_ARGC - 2, CMD_JIMTCL_ARGV + 2);
-
-       goi.is_configure = 1;
-       int e = target_configure(&goi, target);
-
-       int reslen;
-       const char *result = Jim_GetString(Jim_GetResult(CMD_CTX->interp), &reslen);
-       if (reslen > 0)
-               command_print(CMD, "%s", result);
-
-       if (e == JIM_OK) {
+       bool is_configure = true;
+       retval = CALL_COMMAND_HANDLER(target_configure, target, 2, is_configure);
+       if (retval == ERROR_OK) {
                if (target->has_dap) {
                        if (!target->dap_configured) {
                                command_print(CMD, "-dap ?name? required when creating target");
@@ -5829,8 +5847,6 @@ COMMAND_HANDLER(handle_target_create)
                /* tap must be set after target was configured */
                if (!target->tap)
                        retval = ERROR_COMMAND_ARGUMENT_INVALID;
-       } else {
-               retval = ERROR_FAIL;
        }
 
        if (retval != ERROR_OK) {