noinst_LTLIBRARIES = libargpar-utils.la
libargpar_utils_la_SOURCES = \
- argpar-utils.c \
+ argpar-utils.cpp \
argpar-utils.h
+++ /dev/null
-/*
- * Copyright (C) 2021 Simon Marchi <simon.marchi@efficios.com>
- *
- * SPDX-License-Identifier: GPL-2.0-only
- *
- */
-
-#include "argpar-utils.h"
-
-#include <stdio.h>
-
-#include <common/error.h>
-#include <common/string-utils/string-utils.h>
-
-/*
- * Given argpar error status `status` and error `error`, return a formatted
- * error message describing the error.
- *
- * `argv` is the argument vector that was being parsed.
- *
- * `context_fmt`, if non-NULL, is formatted using `args` and prepended to the
- * error message.
- *
- * Add `argc_offset` the the argument index mentioned in the error message.
- *
- * The returned string must be freed by the caller.
- */
-static ATTR_FORMAT_PRINTF(4, 0)
-char *format_arg_error_v(const struct argpar_error *error, int argc_offset,
- const char **argv, const char *context_fmt, va_list args)
-{
- char *str = NULL;
- char *str_ret = NULL;
- int ret;
-
- if (context_fmt) {
- ret = vasprintf(&str, context_fmt, args);
- if (ret == -1) {
- /*
- * If vasprintf fails, the content of str is undefined,
- * and we shouldn't try to free it.
- */
- str = NULL;
- goto end;
- }
-
- ret = strutils_append_str(&str, ": ");
- if (ret < 0) {
- goto end;
- }
- }
-
- switch (argpar_error_type(error))
- {
- case ARGPAR_ERROR_TYPE_MISSING_OPT_ARG:
- {
- const int orig_index = argpar_error_orig_index(error);
- const char *arg = argv[orig_index];
-
- ret = strutils_appendf(&str,
- WHILE_PARSING_ARG_N_ARG_FMT "Missing required argument for option `%s`",
- orig_index + 1 + argc_offset, argv[orig_index], arg);
- if (ret < 0) {
- goto end;
- }
-
- break;
- }
- case ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG:
- {
- bool is_short;
- const struct argpar_opt_descr *descr =
- argpar_error_opt_descr(error, &is_short);
- int orig_index = argpar_error_orig_index(error);
- const char *arg = argv[orig_index];
-
- if (is_short) {
- ret = strutils_appendf(&str,
- WHILE_PARSING_ARG_N_ARG_FMT "Unexpected argument for option `-%c`",
- orig_index + 1 + argc_offset, arg, descr->short_name);
- } else {
- ret = strutils_appendf(&str,
- WHILE_PARSING_ARG_N_ARG_FMT "Unexpected argument for option `--%s`",
- orig_index + 1 + argc_offset, arg, descr->long_name);
- }
-
- if (ret < 0) {
- goto end;
- }
-
- break;
- }
- case ARGPAR_ERROR_TYPE_UNKNOWN_OPT:
- {
- int orig_index = argpar_error_orig_index(error);
- const char *unknown_opt = argpar_error_unknown_opt_name(error);
-
- ret = strutils_appendf(&str,
- WHILE_PARSING_ARG_N_ARG_FMT "Unknown option `%s`",
- orig_index + 1 + argc_offset, argv[orig_index], unknown_opt);
-
- if (ret < 0) {
- goto end;
- }
-
- break;
- }
- default:
- abort ();
- }
-
- str_ret = str;
- str = NULL;
-
-end:
- free(str);
- return str_ret;
-}
-
-enum parse_next_item_status parse_next_item(struct argpar_iter *iter,
- const struct argpar_item **item, int argc_offset,
- const char **argv, bool unknown_opt_is_error,
- const struct argpar_error **error_out,
- const char *context_fmt, ...)
-{
- enum argpar_iter_next_status status;
- const struct argpar_error *error = NULL;
- enum parse_next_item_status ret;
-
- ARGPAR_ITEM_DESTROY_AND_RESET(*item);
- status = argpar_iter_next(iter, item, &error);
-
- switch (status) {
- case ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY:
- ERR("Failed to get next argpar item.");
- ret = PARSE_NEXT_ITEM_STATUS_ERROR_MEMORY;
- break;
- case ARGPAR_ITER_NEXT_STATUS_ERROR:
- {
- va_list args;
- char *err_str;
-
- if (argpar_error_type(error) == ARGPAR_ERROR_TYPE_UNKNOWN_OPT &&
- !unknown_opt_is_error) {
- ret = PARSE_NEXT_ITEM_STATUS_END;
- break;
- }
-
- va_start(args, context_fmt);
- err_str = format_arg_error_v(error, argc_offset, argv,
- context_fmt, args);
- va_end(args);
-
- if (err_str) {
- ERR("%s", err_str);
- free(err_str);
- } else {
- ERR("%s", "Failed to format argpar error.");
- }
-
- ret = PARSE_NEXT_ITEM_STATUS_ERROR;
- break;
- }
- case ARGPAR_ITER_NEXT_STATUS_END:
- ret = PARSE_NEXT_ITEM_STATUS_END;
- break;
- case ARGPAR_ITER_NEXT_STATUS_OK:
- ret = PARSE_NEXT_ITEM_STATUS_OK;
- break;
- default:
- abort();
- }
-
- if (error_out) {
- argpar_error_destroy(*error_out);
- *error_out = error;
- error = NULL;
- }
-
- argpar_error_destroy(error);
-
- return ret;
-}
--- /dev/null
+/*
+ * Copyright (C) 2021 Simon Marchi <simon.marchi@efficios.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ */
+
+#include "argpar-utils.h"
+
+#include <stdio.h>
+
+#include <common/error.h>
+#include <common/string-utils/string-utils.h>
+
+/*
+ * Given argpar error status `status` and error `error`, return a formatted
+ * error message describing the error.
+ *
+ * `argv` is the argument vector that was being parsed.
+ *
+ * `context_fmt`, if non-NULL, is formatted using `args` and prepended to the
+ * error message.
+ *
+ * Add `argc_offset` the the argument index mentioned in the error message.
+ *
+ * The returned string must be freed by the caller.
+ */
+static ATTR_FORMAT_PRINTF(4, 0)
+char *format_arg_error_v(const struct argpar_error *error, int argc_offset,
+ const char **argv, const char *context_fmt, va_list args)
+{
+ char *str = NULL;
+ char *str_ret = NULL;
+ int ret;
+
+ if (context_fmt) {
+ ret = vasprintf(&str, context_fmt, args);
+ if (ret == -1) {
+ /*
+ * If vasprintf fails, the content of str is undefined,
+ * and we shouldn't try to free it.
+ */
+ str = NULL;
+ goto end;
+ }
+
+ ret = strutils_append_str(&str, ": ");
+ if (ret < 0) {
+ goto end;
+ }
+ }
+
+ switch (argpar_error_type(error))
+ {
+ case ARGPAR_ERROR_TYPE_MISSING_OPT_ARG:
+ {
+ const int orig_index = argpar_error_orig_index(error);
+ const char *arg = argv[orig_index];
+
+ ret = strutils_appendf(&str,
+ WHILE_PARSING_ARG_N_ARG_FMT "Missing required argument for option `%s`",
+ orig_index + 1 + argc_offset, argv[orig_index], arg);
+ if (ret < 0) {
+ goto end;
+ }
+
+ break;
+ }
+ case ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG:
+ {
+ bool is_short;
+ const struct argpar_opt_descr *descr =
+ argpar_error_opt_descr(error, &is_short);
+ int orig_index = argpar_error_orig_index(error);
+ const char *arg = argv[orig_index];
+
+ if (is_short) {
+ ret = strutils_appendf(&str,
+ WHILE_PARSING_ARG_N_ARG_FMT "Unexpected argument for option `-%c`",
+ orig_index + 1 + argc_offset, arg, descr->short_name);
+ } else {
+ ret = strutils_appendf(&str,
+ WHILE_PARSING_ARG_N_ARG_FMT "Unexpected argument for option `--%s`",
+ orig_index + 1 + argc_offset, arg, descr->long_name);
+ }
+
+ if (ret < 0) {
+ goto end;
+ }
+
+ break;
+ }
+ case ARGPAR_ERROR_TYPE_UNKNOWN_OPT:
+ {
+ int orig_index = argpar_error_orig_index(error);
+ const char *unknown_opt = argpar_error_unknown_opt_name(error);
+
+ ret = strutils_appendf(&str,
+ WHILE_PARSING_ARG_N_ARG_FMT "Unknown option `%s`",
+ orig_index + 1 + argc_offset, argv[orig_index], unknown_opt);
+
+ if (ret < 0) {
+ goto end;
+ }
+
+ break;
+ }
+ default:
+ abort ();
+ }
+
+ str_ret = str;
+ str = NULL;
+
+end:
+ free(str);
+ return str_ret;
+}
+
+enum parse_next_item_status parse_next_item(struct argpar_iter *iter,
+ const struct argpar_item **item, int argc_offset,
+ const char **argv, bool unknown_opt_is_error,
+ const struct argpar_error **error_out,
+ const char *context_fmt, ...)
+{
+ enum argpar_iter_next_status status;
+ const struct argpar_error *error = NULL;
+ enum parse_next_item_status ret;
+
+ ARGPAR_ITEM_DESTROY_AND_RESET(*item);
+ status = argpar_iter_next(iter, item, &error);
+
+ switch (status) {
+ case ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY:
+ ERR("Failed to get next argpar item.");
+ ret = PARSE_NEXT_ITEM_STATUS_ERROR_MEMORY;
+ break;
+ case ARGPAR_ITER_NEXT_STATUS_ERROR:
+ {
+ va_list args;
+ char *err_str;
+
+ if (argpar_error_type(error) == ARGPAR_ERROR_TYPE_UNKNOWN_OPT &&
+ !unknown_opt_is_error) {
+ ret = PARSE_NEXT_ITEM_STATUS_END;
+ break;
+ }
+
+ va_start(args, context_fmt);
+ err_str = format_arg_error_v(error, argc_offset, argv,
+ context_fmt, args);
+ va_end(args);
+
+ if (err_str) {
+ ERR("%s", err_str);
+ free(err_str);
+ } else {
+ ERR("%s", "Failed to format argpar error.");
+ }
+
+ ret = PARSE_NEXT_ITEM_STATUS_ERROR;
+ break;
+ }
+ case ARGPAR_ITER_NEXT_STATUS_END:
+ ret = PARSE_NEXT_ITEM_STATUS_END;
+ break;
+ case ARGPAR_ITER_NEXT_STATUS_OK:
+ ret = PARSE_NEXT_ITEM_STATUS_OK;
+ break;
+ default:
+ abort();
+ }
+
+ if (error_out) {
+ argpar_error_destroy(*error_out);
+ *error_out = error;
+ error = NULL;
+ }
+
+ argpar_error_destroy(error);
+
+ return ret;
+}