}
static __attribute__((format(ARGPAR_PRINTF_FORMAT, 2, 3)))
-bool append_string_printf(char ** const str, const char *fmt, ...)
+bool try_append_string_printf(char ** const str, const char *fmt, ...)
{
char *new_str = NULL;
- char *addendum;
+ char *addendum = NULL;
bool success;
va_list args;
+ if (!str) {
+ success = true;
+ goto end;
+ }
+
ARGPAR_ASSERT(str);
va_start(args, fmt);
addendum = argpar_vasprintf(fmt, args);
enum parse_orig_arg_opt_ret {
PARSE_ORIG_ARG_OPT_RET_OK,
- PARSE_ORIG_ARG_OPT_RET_ERROR_UNKNOWN_OPT = -2,
- PARSE_ORIG_ARG_OPT_RET_ERROR = -1,
+ PARSE_ORIG_ARG_OPT_RET_ERROR_UNKNOWN_OPT = -1,
+ PARSE_ORIG_ARG_OPT_RET_ERROR_MISSING_OPT_ARG = -2,
+ PARSE_ORIG_ARG_OPT_RET_ERROR_INVALID_ARG = -3,
+ PARSE_ORIG_ARG_OPT_RET_ERROR_UNEXPECTED_OPT_ARG = -4,
+ PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY = -5,
};
static
struct argpar_item_opt *opt_item;
if (strlen(short_opts) == 0) {
- append_string_printf(error, "Invalid argument");
+ try_append_string_printf(error, "Invalid argument");
+ ret = PARSE_ORIG_ARG_OPT_RET_ERROR_INVALID_ARG;
goto error;
}
/* Find corresponding option descriptor */
descr = find_descr(descrs, *iter->short_opt_ch, NULL);
if (!descr) {
- ret = PARSE_ORIG_ARG_OPT_RET_ERROR_UNKNOWN_OPT;
- append_string_printf(error, "Unknown option `-%c`",
+ try_append_string_printf(error, "Unknown option `-%c`",
*iter->short_opt_ch);
+ ret = PARSE_ORIG_ARG_OPT_RET_ERROR_UNKNOWN_OPT;
goto error;
}
*/
if (!opt_arg || (iter->short_opt_ch[1] &&
strlen(opt_arg) == 0)) {
- append_string_printf(error,
+ try_append_string_printf(error,
"Missing required argument for option `-%c`",
*iter->short_opt_ch);
used_next_orig_arg = false;
+ ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MISSING_OPT_ARG;
goto error;
}
}
/* Create and append option argument */
opt_item = create_opt_item(descr, opt_arg);
if (!opt_item) {
+ ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
goto error;
}
goto end;
error:
- if (ret == PARSE_ORIG_ARG_OPT_RET_OK) {
- ret = PARSE_ORIG_ARG_OPT_RET_ERROR;
- }
+ ARGPAR_ASSERT(ret != PARSE_ORIG_ARG_OPT_RET_OK);
end:
return ret;
const char *long_opt_name = long_opt_arg;
if (strlen(long_opt_arg) == 0) {
- append_string_printf(error, "Invalid argument");
+ try_append_string_printf(error, "Invalid argument");
+ ret = PARSE_ORIG_ARG_OPT_RET_ERROR_INVALID_ARG;
goto error;
}
/* Isolate the option name */
if (long_opt_name_size > max_len) {
- append_string_printf(error, "Invalid argument `--%s`",
- long_opt_arg);
+ try_append_string_printf(error,
+ "Invalid argument `--%s`", long_opt_arg);
+ ret = PARSE_ORIG_ARG_OPT_RET_ERROR_INVALID_ARG;
goto error;
}
/* Find corresponding option descriptor */
descr = find_descr(descrs, '\0', long_opt_name);
if (!descr) {
- append_string_printf(error, "Unknown option `--%s`",
+ try_append_string_printf(error, "Unknown option `--%s`",
long_opt_name);
ret = PARSE_ORIG_ARG_OPT_RET_ERROR_UNKNOWN_OPT;
goto error;
} else {
/* `--long-opt arg` style */
if (!next_orig_arg) {
- append_string_printf(error,
+ try_append_string_printf(error,
"Missing required argument for option `--%s`",
long_opt_name);
+ ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MISSING_OPT_ARG;
goto error;
}
* Unexpected `--opt=arg` style for a long option which
* doesn't accept an argument.
*/
- append_string_printf(error,
+ try_append_string_printf(error,
"Unexpected argument for option `--%s`", long_opt_name);
+ ret = PARSE_ORIG_ARG_OPT_RET_ERROR_UNEXPECTED_OPT_ARG;
goto error;
}
goto end;
error:
- if (ret == PARSE_ORIG_ARG_OPT_RET_OK) {
- ret = PARSE_ORIG_ARG_OPT_RET_ERROR;
- }
+ ARGPAR_ASSERT(ret != PARSE_ORIG_ARG_OPT_RET_OK);
end:
return ret;
}
static
-bool prepend_while_parsing_arg_to_error(char ** const error,
+bool try_prepend_while_parsing_arg_to_error(char ** const error,
const unsigned int i, const char * const arg)
{
char *new_error;
bool success;
- ARGPAR_ASSERT(error);
+ if (!error) {
+ success = true;
+ goto end;
+ }
+
ARGPAR_ASSERT(*error);
new_error = argpar_asprintf("While parsing argument #%u (`%s`): %s",
i + 1, arg, *error);
const char *next_orig_arg;
ARGPAR_ASSERT(iter->i <= iter->argc);
- *error = NULL;
+
+ if (error) {
+ *error = NULL;
+ }
if (iter->i == iter->argc) {
status = ARGPAR_ITER_PARSE_NEXT_STATUS_END;
iter->non_opt_index);
if (!non_opt_item) {
- status = ARGPAR_ITER_PARSE_NEXT_STATUS_ERROR;
+ status = ARGPAR_ITER_PARSE_NEXT_STATUS_ERROR_MEMORY;
goto end;
}
status = ARGPAR_ITER_PARSE_NEXT_STATUS_OK;
break;
case PARSE_ORIG_ARG_OPT_RET_ERROR_UNKNOWN_OPT:
- prepend_while_parsing_arg_to_error(error, iter->i, orig_arg);
- status = ARGPAR_ITER_PARSE_NEXT_STATUS_ERROR_UNKNOWN_OPT;
+ case PARSE_ORIG_ARG_OPT_RET_ERROR_MISSING_OPT_ARG:
+ case PARSE_ORIG_ARG_OPT_RET_ERROR_INVALID_ARG:
+ case PARSE_ORIG_ARG_OPT_RET_ERROR_UNEXPECTED_OPT_ARG:
+ try_prepend_while_parsing_arg_to_error(error, iter->i,
+ orig_arg);
+
+ switch (parse_orig_arg_opt_ret) {
+ case PARSE_ORIG_ARG_OPT_RET_ERROR_UNKNOWN_OPT:
+ status = ARGPAR_ITER_PARSE_NEXT_STATUS_ERROR_UNKNOWN_OPT;
+ break;
+ case PARSE_ORIG_ARG_OPT_RET_ERROR_MISSING_OPT_ARG:
+ status = ARGPAR_ITER_PARSE_NEXT_STATUS_ERROR_MISSING_OPT_ARG;
+ break;
+ case PARSE_ORIG_ARG_OPT_RET_ERROR_INVALID_ARG:
+ status = ARGPAR_ITER_PARSE_NEXT_STATUS_ERROR_INVALID_ARG;
+ break;
+ case PARSE_ORIG_ARG_OPT_RET_ERROR_UNEXPECTED_OPT_ARG:
+ status = ARGPAR_ITER_PARSE_NEXT_STATUS_ERROR_UNEXPECTED_OPT_ARG;
+ break;
+ default:
+ abort();
+ }
+
break;
- case PARSE_ORIG_ARG_OPT_RET_ERROR:
- prepend_while_parsing_arg_to_error(error, iter->i, orig_arg);
- status = ARGPAR_ITER_PARSE_NEXT_STATUS_ERROR;
+ case PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY:
+ status = ARGPAR_ITER_PARSE_NEXT_STATUS_ERROR_MEMORY;
break;
default:
abort();
const enum argpar_iter_parse_next_status status =
argpar_iter_parse_next(iter, &item, &parse_ret.error);
- if (status == ARGPAR_ITER_PARSE_NEXT_STATUS_ERROR) {
+ switch (status) {
+ case ARGPAR_ITER_PARSE_NEXT_STATUS_ERROR_MISSING_OPT_ARG:
+ case ARGPAR_ITER_PARSE_NEXT_STATUS_ERROR_INVALID_ARG:
+ case ARGPAR_ITER_PARSE_NEXT_STATUS_ERROR_UNEXPECTED_OPT_ARG:
+ case ARGPAR_ITER_PARSE_NEXT_STATUS_ERROR_MEMORY:
goto error;
- } else if (status == ARGPAR_ITER_PARSE_NEXT_STATUS_END) {
- break;
- } else if (status == ARGPAR_ITER_PARSE_NEXT_STATUS_ERROR_UNKNOWN_OPT) {
+ case ARGPAR_ITER_PARSE_NEXT_STATUS_ERROR_UNKNOWN_OPT:
if (fail_on_unknown_opt) {
parse_ret.ingested_orig_args =
argpar_iter_get_ingested_orig_args(iter);
free(parse_ret.error);
parse_ret.error = NULL;
+ goto success;
+ case ARGPAR_ITER_PARSE_NEXT_STATUS_END:
+ goto success;
+ default:
+ ARGPAR_ASSERT(status == ARGPAR_ITER_PARSE_NEXT_STATUS_OK);
break;
}
- ARGPAR_ASSERT(status == ARGPAR_ITER_PARSE_NEXT_STATUS_OK);
-
if (!push_item(parse_ret.items, item)) {
goto error;
}
item = NULL;
}
+success:
ARGPAR_ASSERT(!parse_ret.error);
parse_ret.ingested_orig_args = argpar_iter_get_ingested_orig_args(iter);
goto end;