X-Git-Url: http://git.tuebingen.mpg.de/?p=lopsub.git;a=blobdiff_plain;f=lopsub.c;h=d495663408d12fbe85f471a1ba406c3b5c64dcaf;hp=2ba26213c9c803f398208812b4069ea24321a3d4;hb=HEAD;hpb=9d3fd447f36e1a144a40037d559a92562d120703 diff --git a/lopsub.c b/lopsub.c index 2ba2621..b5017c3 100644 --- a/lopsub.c +++ b/lopsub.c @@ -155,7 +155,7 @@ static int xrealloc(void *p, size_t size) return 0; } -/* Print a formated message to a dynamically allocated string. */ +/* Print a formatted message to a dynamically allocated string. */ __attribute__ ((format (printf, 2, 0))) static int xvasprintf(char **result, const char *fmt, va_list ap) { @@ -632,17 +632,23 @@ static int lls_parse_arg(struct lls_arg *la, const struct lls_option *opts, bool multiple; int idx, ret; - if (!la->arg) - goto success; - if (opt->arg_info == LLS_NO_ARGUMENT) { + if (la->arg && opt->arg_info == LLS_NO_ARGUMENT) { xasprintf(errctx, "arg: %s, option: %s", la->arg, opt->name); return -E_LLS_ARG_GIVEN; } multiple = opt->flags & LLS_MULTIPLE; + if (opt->arg_type == LLS_STRING && !opt->values && !multiple) { + if (lor->value) { /* discard previous value */ + free(lor->value[0].string_val); + free(lor->value); + lor->value = NULL; + } + } + if (!la->arg) + goto success; idx = multiple? lor->given : 0; - if (lor->given == 0 || multiple) { - ret = xrealloc(&lor->value, - (lor->given + 1) * sizeof(*lor->value)); + if (!lor->value || multiple) { + ret = xrealloc(&lor->value, (idx + 1) * sizeof(*lor->value)); if (ret < 0) { xasprintf(errctx, "option value array for --%s", opt->name); @@ -651,8 +657,6 @@ static int lls_parse_arg(struct lls_arg *la, const struct lls_option *opts, } switch (opt->arg_type) { case LLS_STRING: - if (lor->given > 0 && !multiple) - free(lor->value[idx].string_val); if (opt->values) { ret = check_enum_arg(la->arg, opt, errctx); if (ret < 0) @@ -724,9 +728,11 @@ int lls_check_arg_count(const struct lls_parse_result *lpr, { if (errctx) *errctx = NULL; + assert(min_argc <= max_argc); if (lpr->num_inputs < min_argc) { - xasprintf(errctx, "at least %u non-option args required, " - "%u given", min_argc, lpr->num_inputs); + xasprintf(errctx, "%s %u non-option args required, %u given", + min_argc < max_argc? "at least" : "exactly", + min_argc, lpr->num_inputs); return -E_LLS_BAD_ARG_COUNT; } if (lpr->num_inputs > max_argc) { @@ -734,8 +740,11 @@ int lls_check_arg_count(const struct lls_parse_result *lpr, xasprintf(errctx, "no non-option args allowed, " "%u given", lpr->num_inputs); else - xasprintf(errctx, "at most %u non-option args allowed, " - "%u given", max_argc, lpr->num_inputs); + xasprintf(errctx, "%s %u non-option args %s, %u given", + min_argc < max_argc? "at most" : "exactly", + max_argc, + min_argc < max_argc? "allowed" : "required", + lpr->num_inputs); return -E_LLS_BAD_ARG_COUNT; } return 1; @@ -1296,6 +1305,7 @@ int lls_deserialize_parse_result(const char *buf, const struct lls_command *cmd, if (!lor->value[j].string_val) { for (; j >= 0; j--) free(lor->value[j].string_val); + free(lor->value); goto free_options; } p += strlen(lor->value[j].string_val) + 1; @@ -1313,7 +1323,7 @@ int lls_deserialize_parse_result(const char *buf, const struct lls_command *cmd, *lprp = lpr; return 1; free_options: - for (; i >= 0; i--) { + for (i--; i >= 0; i--) { const struct lls_option *opt = cmd->options + i; struct lls_opt_result *lor = lpr->opt_result + i; unsigned num_vals = (opt->flags & LLS_MULTIPLE)? lor->given : 1;