Move argpar to vendor directory
authorSimon Marchi <simon.marchi@efficios.com>
Mon, 18 Mar 2024 18:21:45 +0000 (14:21 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 4 Sep 2024 21:09:06 +0000 (21:09 +0000)
Since this is source copied as-is from another project, I think it
belongs to the vendor directory.  This will make it so it will be
skipped by format-cpp, for instance.

Change-Id: I78892f80c4cbb3a2e863567b0021e895c6489402
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
12 files changed:
src/bin/lttng/Makefile.am
src/bin/lttng/commands/add_trigger.cpp
src/bin/lttng/commands/list_triggers.cpp
src/bin/lttng/commands/remove_trigger.cpp
src/bin/lttng/utils.hpp
src/common/Makefile.am
src/common/argpar-utils/argpar-utils.hpp
src/common/argpar/argpar.c [deleted file]
src/common/argpar/argpar.h [deleted file]
src/vendor/Makefile.am
src/vendor/argpar/argpar.c [new file with mode: 0644]
src/vendor/argpar/argpar.h [new file with mode: 0644]

index e3718374637deda24acccd4bc1ccc5c0cd7443ae..ed30ea1ab9d847ac086ef98fe0d8c1aa8fb65f96 100644 (file)
@@ -46,5 +46,5 @@ lttng_LDADD = $(top_builddir)/src/lib/lttng-ctl/liblttng-ctl.la \
                        $(top_builddir)/src/common/libstring-utils.la \
                        $(top_builddir)/src/common/libfilter.la \
                        $(top_builddir)/src/common/libargpar-utils.la \
-                       $(top_builddir)/src/common/libargpar.la \
+                       $(top_builddir)/src/vendor/argpar/libargpar.la \
                        $(POPT_LIBS)
index ad2fd47c11390b4b962fa803af272aefa390d671..18e91513b24711a5293053929bee9bb919ac4275 100644 (file)
@@ -9,11 +9,11 @@
 #include "../loglevel.hpp"
 #include "../uprobe.hpp"
 #include "common/argpar-utils/argpar-utils.hpp"
-#include "common/argpar/argpar.h"
 #include "common/dynamic-array.hpp"
 #include "common/mi-lttng.hpp"
 #include "common/string-utils/string-utils.hpp"
 #include "common/utils.hpp"
+#include "vendor/argpar/argpar.h"
 
 #include <lttng/domain-internal.hpp>
 
index db905bc4f34ac8ae4083c63d128d1c35eb18db7a..58262a9e3cef678c19bf2be678eef62c929bbdc5 100644 (file)
@@ -7,10 +7,10 @@
 
 #include "../command.hpp"
 #include "common/argpar-utils/argpar-utils.hpp"
-#include "common/argpar/argpar.h"
 #include "common/dynamic-array.hpp"
 #include "common/mi-lttng.hpp"
 #include "lttng/action/list-internal.hpp"
+#include "vendor/argpar/argpar.h"
 
 /* For lttng_condition_type_str(). */
 #include "lttng/condition/condition-internal.hpp"
index 08d4873f08a4cb9b9b66611eaeb51331c773ea76..81d9a73824020633eb4d5aeb0ed86d8cb21c67a4 100644 (file)
@@ -7,8 +7,8 @@
 
 #include "../command.hpp"
 #include "common/argpar-utils/argpar-utils.hpp"
-#include "common/argpar/argpar.h"
 #include "common/mi-lttng.hpp"
+#include "vendor/argpar/argpar.h"
 
 #include <lttng/lttng.h>
 
index 7f398397a95a38ca585bcfcd000095497f913c6d..15842b8bd7cefc66bae5bc399c8f891a0d5e1b8f 100644 (file)
@@ -8,7 +8,6 @@
 #ifndef _LTTNG_UTILS_H
 #define _LTTNG_UTILS_H
 
-#include <common/argpar/argpar.h>
 #include <common/container-wrapper.hpp>
 #include <common/dynamic-array.hpp>
 #include <common/make-unique-wrapper.hpp>
@@ -16,6 +15,8 @@
 #include <lttng/lttng.h>
 #include <lttng/session-internal.hpp>
 
+#include <vendor/argpar/argpar.h>
+
 #include <iterator>
 #include <memory>
 #include <popt.h>
index 2516a5042bf4dccdf4e1263652580b1addc8e824..499ffa9d8dce0f43e17e0451046164c01a6b0b86 100644 (file)
@@ -19,13 +19,6 @@ noinst_HEADERS = \
        utils.hpp
 
 
-# libargpar
-noinst_LTLIBRARIES += libargpar.la
-libargpar_la_SOURCES = \
-       argpar/argpar.c \
-       argpar/argpar.h
-
-
 # libargpar-utils
 noinst_LTLIBRARIES += libargpar-utils.la
 libargpar_utils_la_SOURCES = \
index 4d25b3a705ad13c3fbffeb764036a4c1d612d8fb..00a387f57ca703d26079b8e405c35d57124fb611 100644 (file)
@@ -8,10 +8,11 @@
 #ifndef COMMON_ARGPAR_UTILS_H
 #define COMMON_ARGPAR_UTILS_H
 
-#include <common/argpar/argpar.h>
 #include <common/macros.hpp>
 #include <common/string-utils/format.hpp>
 
+#include <vendor/argpar/argpar.h>
+
 #include <stdarg.h>
 
 #ifdef __cplusplus
diff --git a/src/common/argpar/argpar.c b/src/common/argpar/argpar.c
deleted file mode 100644 (file)
index f8280ce..0000000
+++ /dev/null
@@ -1,761 +0,0 @@
-/*
- * SPDX-License-Identifier: MIT
- *
- * Copyright (c) 2019-2021 Philippe Proulx <pproulx@efficios.com>
- * Copyright (c) 2020-2021 Simon Marchi <simon.marchi@efficios.com>
- */
-
-#include "argpar.h"
-
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define ARGPAR_REALLOC(_ptr, _type, _nmemb) ((_type *) realloc(_ptr, (_nmemb) * sizeof(_type)))
-
-#define ARGPAR_CALLOC(_type, _nmemb) ((_type *) calloc((_nmemb), sizeof(_type)))
-
-#define ARGPAR_ZALLOC(_type) ARGPAR_CALLOC(_type, 1)
-
-#ifdef NDEBUG
-/*
- * Force usage of the assertion condition to prevent unused variable warnings
- * when `assert()` are disabled by the `NDEBUG` definition.
- */
-#define ARGPAR_ASSERT(_cond) ((void) sizeof((void) (_cond), 0))
-#else
-#include <assert.h>
-#define ARGPAR_ASSERT(_cond) assert(_cond)
-#endif
-
-/*
- * An argpar iterator.
- *
- * Such a structure contains the state of an iterator between calls to
- * argpar_iter_next().
- */
-struct argpar_iter {
-       /*
-        * Data provided by the user to argpar_iter_create(); immutable
-        * afterwards.
-        */
-       struct {
-               unsigned int argc;
-               const char *const *argv;
-               const struct argpar_opt_descr *descrs;
-       } user;
-
-       /*
-        * Index of the argument to process in the next
-        * argpar_iter_next() call.
-        */
-       unsigned int i;
-
-       /* Counter of non-option arguments */
-       int non_opt_index;
-
-       /*
-        * Current character within the current short option group: if
-        * it's not `NULL`, the parser is within a short option group,
-        * therefore it must resume there in the next argpar_iter_next()
-        * call.
-        */
-       const char *short_opt_group_ch;
-
-       /* Temporary character buffer which only grows */
-       struct {
-               size_t size;
-               char *data;
-       } tmp_buf;
-};
-
-/* Base parsing item */
-struct argpar_item {
-       enum argpar_item_type type;
-};
-
-/* Option parsing item */
-struct argpar_item_opt {
-       struct argpar_item base;
-
-       /* Corresponding descriptor */
-       const struct argpar_opt_descr *descr;
-
-       /* Argument, or `NULL` if none; owned by this */
-       char *arg;
-};
-
-/* Non-option parsing item */
-struct argpar_item_non_opt {
-       struct argpar_item base;
-
-       /*
-        * Complete argument, pointing to one of the entries of the
-        * original arguments (`argv`).
-        */
-       const char *arg;
-
-       /*
-        * Index of this argument amongst all original arguments
-        * (`argv`).
-        */
-       unsigned int orig_index;
-
-       /* Index of this argument amongst other non-option arguments */
-       unsigned int non_opt_index;
-};
-
-/* Parsing error */
-struct argpar_error {
-       /* Error type */
-       enum argpar_error_type type;
-
-       /* Original argument index */
-       unsigned int orig_index;
-
-       /* Name of unknown option; owned by this */
-       char *unknown_opt_name;
-
-       /* Option descriptor */
-       const struct argpar_opt_descr *opt_descr;
-
-       /* `true` if a short option caused the error */
-       bool is_short;
-};
-
-ARGPAR_HIDDEN
-enum argpar_item_type argpar_item_type(const struct argpar_item *const item)
-{
-       ARGPAR_ASSERT(item);
-       return item->type;
-}
-
-ARGPAR_HIDDEN
-const struct argpar_opt_descr *argpar_item_opt_descr(const struct argpar_item *const item)
-{
-       ARGPAR_ASSERT(item);
-       ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_OPT);
-       return ((const struct argpar_item_opt *) item)->descr;
-}
-
-ARGPAR_HIDDEN
-const char *argpar_item_opt_arg(const struct argpar_item *const item)
-{
-       ARGPAR_ASSERT(item);
-       ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_OPT);
-       return ((const struct argpar_item_opt *) item)->arg;
-}
-
-ARGPAR_HIDDEN
-const char *argpar_item_non_opt_arg(const struct argpar_item *const item)
-{
-       ARGPAR_ASSERT(item);
-       ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_NON_OPT);
-       return ((const struct argpar_item_non_opt *) item)->arg;
-}
-
-ARGPAR_HIDDEN
-unsigned int argpar_item_non_opt_orig_index(const struct argpar_item *const item)
-{
-       ARGPAR_ASSERT(item);
-       ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_NON_OPT);
-       return ((const struct argpar_item_non_opt *) item)->orig_index;
-}
-
-ARGPAR_HIDDEN
-unsigned int argpar_item_non_opt_non_opt_index(const struct argpar_item *const item)
-{
-       ARGPAR_ASSERT(item);
-       ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_NON_OPT);
-       return ((const struct argpar_item_non_opt *) item)->non_opt_index;
-}
-
-ARGPAR_HIDDEN
-void argpar_item_destroy(const struct argpar_item *const item)
-{
-       if (!item) {
-               goto end;
-       }
-
-       if (item->type == ARGPAR_ITEM_TYPE_OPT) {
-               struct argpar_item_opt *const opt_item = (struct argpar_item_opt *) item;
-
-               free(opt_item->arg);
-       }
-
-       free((void *) item);
-
-end:
-       return;
-}
-
-/*
- * Creates and returns an option parsing item for the descriptor `descr`
- * and having the argument `arg` (copied; may be `NULL`).
- *
- * Returns `NULL` on memory error.
- */
-static struct argpar_item_opt *create_opt_item(const struct argpar_opt_descr *const descr,
-                                              const char *const arg)
-{
-       struct argpar_item_opt *opt_item = ARGPAR_ZALLOC(struct argpar_item_opt);
-
-       if (!opt_item) {
-               goto end;
-       }
-
-       opt_item->base.type = ARGPAR_ITEM_TYPE_OPT;
-       opt_item->descr = descr;
-
-       if (arg) {
-               opt_item->arg = strdup(arg);
-               if (!opt_item->arg) {
-                       goto error;
-               }
-       }
-
-       goto end;
-
-error:
-       argpar_item_destroy(&opt_item->base);
-       opt_item = NULL;
-
-end:
-       return opt_item;
-}
-
-/*
- * Creates and returns a non-option parsing item for the original
- * argument `arg` having the original index `orig_index` and the
- * non-option index `non_opt_index`.
- *
- * Returns `NULL` on memory error.
- */
-static struct argpar_item_non_opt *create_non_opt_item(const char *const arg,
-                                                      const unsigned int orig_index,
-                                                      const unsigned int non_opt_index)
-{
-       struct argpar_item_non_opt *const non_opt_item = ARGPAR_ZALLOC(struct argpar_item_non_opt);
-
-       if (!non_opt_item) {
-               goto end;
-       }
-
-       non_opt_item->base.type = ARGPAR_ITEM_TYPE_NON_OPT;
-       non_opt_item->arg = arg;
-       non_opt_item->orig_index = orig_index;
-       non_opt_item->non_opt_index = non_opt_index;
-
-end:
-       return non_opt_item;
-}
-
-/*
- * If `error` is not `NULL`, sets the error `error` to a new parsing
- * error object, setting its `unknown_opt_name`, `opt_descr`, and
- * `is_short` members from the parameters.
- *
- * `unknown_opt_name` is the unknown option name without any `-` or `--`
- * prefix: `is_short` controls which type of unknown option it is.
- *
- * Returns 0 on success (including if `error` is `NULL`) or -1 on memory
- * error.
- */
-static int set_error(struct argpar_error **const error,
-                    enum argpar_error_type type,
-                    const char *const unknown_opt_name,
-                    const struct argpar_opt_descr *const opt_descr,
-                    const bool is_short)
-{
-       int ret = 0;
-
-       if (!error) {
-               goto end;
-       }
-
-       *error = ARGPAR_ZALLOC(struct argpar_error);
-       if (!*error) {
-               goto error;
-       }
-
-       (*error)->type = type;
-
-       if (unknown_opt_name) {
-               (*error)->unknown_opt_name =
-                       ARGPAR_CALLOC(char, strlen(unknown_opt_name) + 1 + (is_short ? 1 : 2));
-               if (!(*error)->unknown_opt_name) {
-                       goto error;
-               }
-
-               if (is_short) {
-                       strcpy((*error)->unknown_opt_name, "-");
-               } else {
-                       strcpy((*error)->unknown_opt_name, "--");
-               }
-
-               strcat((*error)->unknown_opt_name, unknown_opt_name);
-       }
-
-       (*error)->opt_descr = opt_descr;
-       (*error)->is_short = is_short;
-       goto end;
-
-error:
-       argpar_error_destroy(*error);
-       ret = -1;
-
-end:
-       return ret;
-}
-
-ARGPAR_HIDDEN
-enum argpar_error_type argpar_error_type(const struct argpar_error *const error)
-{
-       ARGPAR_ASSERT(error);
-       return error->type;
-}
-
-ARGPAR_HIDDEN
-unsigned int argpar_error_orig_index(const struct argpar_error *const error)
-{
-       ARGPAR_ASSERT(error);
-       return error->orig_index;
-}
-
-ARGPAR_HIDDEN
-const char *argpar_error_unknown_opt_name(const struct argpar_error *const error)
-{
-       ARGPAR_ASSERT(error);
-       ARGPAR_ASSERT(error->type == ARGPAR_ERROR_TYPE_UNKNOWN_OPT);
-       ARGPAR_ASSERT(error->unknown_opt_name);
-       return error->unknown_opt_name;
-}
-
-ARGPAR_HIDDEN
-const struct argpar_opt_descr *argpar_error_opt_descr(const struct argpar_error *const error,
-                                                     bool *const is_short)
-{
-       ARGPAR_ASSERT(error);
-       ARGPAR_ASSERT(error->type == ARGPAR_ERROR_TYPE_MISSING_OPT_ARG ||
-                     error->type == ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG);
-       ARGPAR_ASSERT(error->opt_descr);
-
-       if (is_short) {
-               *is_short = error->is_short;
-       }
-
-       return error->opt_descr;
-}
-
-ARGPAR_HIDDEN
-void argpar_error_destroy(const struct argpar_error *const error)
-{
-       if (error) {
-               free(error->unknown_opt_name);
-               free((void *) error);
-       }
-}
-
-/*
- * Finds and returns the _first_ descriptor having the short option name
- * `short_name` or the long option name `long_name` within the option
- * descriptors `descrs`.
- *
- * `short_name` may be `'\0'` to not consider it.
- *
- * `long_name` may be `NULL` to not consider it.
- *
- * Returns `NULL` if no descriptor is found.
- */
-static const struct argpar_opt_descr *find_descr(const struct argpar_opt_descr *const descrs,
-                                                const char short_name,
-                                                const char *const long_name)
-{
-       const struct argpar_opt_descr *descr;
-
-       for (descr = descrs; descr->short_name || descr->long_name; descr++) {
-               if (short_name && descr->short_name && short_name == descr->short_name) {
-                       goto end;
-               }
-
-               if (long_name && descr->long_name && strcmp(long_name, descr->long_name) == 0) {
-                       goto end;
-               }
-       }
-
-end:
-       return !descr->short_name && !descr->long_name ? NULL : descr;
-}
-
-/* Return type of parse_short_opt_group() and parse_long_opt() */
-enum parse_orig_arg_opt_ret {
-       PARSE_ORIG_ARG_OPT_RET_OK,
-       PARSE_ORIG_ARG_OPT_RET_ERROR = -1,
-       PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY = -2,
-};
-
-/*
- * Parses the short option group argument `short_opt_group`, starting
- * where needed depending on the state of `iter`.
- *
- * On success, sets `*item`.
- *
- * On error (except for `PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY`), sets
- * `*error`.
- */
-static enum parse_orig_arg_opt_ret
-parse_short_opt_group(const char *const short_opt_group,
-                     const char *const next_orig_arg,
-                     const struct argpar_opt_descr *const descrs,
-                     struct argpar_iter *const iter,
-                     struct argpar_error **const error,
-                     struct argpar_item **const item)
-{
-       enum parse_orig_arg_opt_ret ret = PARSE_ORIG_ARG_OPT_RET_OK;
-       bool used_next_orig_arg = false;
-       const char *opt_arg = NULL;
-       const struct argpar_opt_descr *descr;
-       struct argpar_item_opt *opt_item;
-
-       ARGPAR_ASSERT(strlen(short_opt_group) != 0);
-
-       if (!iter->short_opt_group_ch) {
-               iter->short_opt_group_ch = short_opt_group;
-       }
-
-       /* Find corresponding option descriptor */
-       descr = find_descr(descrs, *iter->short_opt_group_ch, NULL);
-       if (!descr) {
-               const char unknown_opt_name[] = { *iter->short_opt_group_ch, '\0' };
-
-               ret = PARSE_ORIG_ARG_OPT_RET_ERROR;
-
-               if (set_error(error, ARGPAR_ERROR_TYPE_UNKNOWN_OPT, unknown_opt_name, NULL, true)) {
-                       ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
-               }
-
-               goto error;
-       }
-
-       if (descr->with_arg) {
-               if (iter->short_opt_group_ch[1]) {
-                       /* `-oarg` form */
-                       opt_arg = &iter->short_opt_group_ch[1];
-               } else {
-                       /* `-o arg` form */
-                       opt_arg = next_orig_arg;
-                       used_next_orig_arg = true;
-               }
-
-               /*
-                * We accept `-o ''` (empty option argument), but not
-                * `-o` alone if an option argument is expected.
-                */
-               if (!opt_arg || (iter->short_opt_group_ch[1] && strlen(opt_arg) == 0)) {
-                       ret = PARSE_ORIG_ARG_OPT_RET_ERROR;
-
-                       if (set_error(error, ARGPAR_ERROR_TYPE_MISSING_OPT_ARG, NULL, descr, true)) {
-                               ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
-                       }
-
-                       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;
-       }
-
-       *item = &opt_item->base;
-       iter->short_opt_group_ch++;
-
-       if (descr->with_arg || !*iter->short_opt_group_ch) {
-               /* Option has an argument: no more options */
-               iter->short_opt_group_ch = NULL;
-
-               if (used_next_orig_arg) {
-                       iter->i += 2;
-               } else {
-                       iter->i++;
-               }
-       }
-
-       goto end;
-
-error:
-       ARGPAR_ASSERT(ret != PARSE_ORIG_ARG_OPT_RET_OK);
-
-end:
-       return ret;
-}
-
-/*
- * Parses the long option argument `long_opt_arg`.
- *
- * On success, sets `*item`.
- *
- * On error (except for `PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY`), sets
- * `*error`.
- */
-static enum parse_orig_arg_opt_ret parse_long_opt(const char *const long_opt_arg,
-                                                 const char *const next_orig_arg,
-                                                 const struct argpar_opt_descr *const descrs,
-                                                 struct argpar_iter *const iter,
-                                                 struct argpar_error **const error,
-                                                 struct argpar_item **const item)
-{
-       enum parse_orig_arg_opt_ret ret = PARSE_ORIG_ARG_OPT_RET_OK;
-       const struct argpar_opt_descr *descr;
-       struct argpar_item_opt *opt_item;
-       bool used_next_orig_arg = false;
-
-       /* Option's argument, if any */
-       const char *opt_arg = NULL;
-
-       /* Position of first `=`, if any */
-       const char *eq_pos;
-
-       /* Option name */
-       const char *long_opt_name = long_opt_arg;
-
-       ARGPAR_ASSERT(strlen(long_opt_arg) != 0);
-
-       /* Find the first `=` in original argument */
-       eq_pos = strchr(long_opt_arg, '=');
-       if (eq_pos) {
-               const size_t long_opt_name_size = eq_pos - long_opt_arg;
-
-               /* Isolate the option name */
-               while (long_opt_name_size > iter->tmp_buf.size - 1) {
-                       iter->tmp_buf.size *= 2;
-                       iter->tmp_buf.data =
-                               ARGPAR_REALLOC(iter->tmp_buf.data, char, iter->tmp_buf.size);
-                       if (!iter->tmp_buf.data) {
-                               ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
-                               goto error;
-                       }
-               }
-
-               memcpy(iter->tmp_buf.data, long_opt_arg, long_opt_name_size);
-               iter->tmp_buf.data[long_opt_name_size] = '\0';
-               long_opt_name = iter->tmp_buf.data;
-       }
-
-       /* Find corresponding option descriptor */
-       descr = find_descr(descrs, '\0', long_opt_name);
-       if (!descr) {
-               ret = PARSE_ORIG_ARG_OPT_RET_ERROR;
-
-               if (set_error(error, ARGPAR_ERROR_TYPE_UNKNOWN_OPT, long_opt_name, NULL, false)) {
-                       ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
-               }
-
-               goto error;
-       }
-
-       /* Find option's argument if any */
-       if (descr->with_arg) {
-               if (eq_pos) {
-                       /* `--long-opt=arg` style */
-                       opt_arg = eq_pos + 1;
-               } else {
-                       /* `--long-opt arg` style */
-                       if (!next_orig_arg) {
-                               ret = PARSE_ORIG_ARG_OPT_RET_ERROR;
-
-                               if (set_error(error,
-                                             ARGPAR_ERROR_TYPE_MISSING_OPT_ARG,
-                                             NULL,
-                                             descr,
-                                             false)) {
-                                       ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
-                               }
-
-                               goto error;
-                       }
-
-                       opt_arg = next_orig_arg;
-                       used_next_orig_arg = true;
-               }
-       } else if (eq_pos) {
-               /*
-                * Unexpected `--opt=arg` style for a long option which
-                * doesn't accept an argument.
-                */
-               ret = PARSE_ORIG_ARG_OPT_RET_ERROR;
-
-               if (set_error(error, ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG, NULL, descr, false)) {
-                       ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
-               }
-
-               goto error;
-       }
-
-       /* Create and append option argument */
-       opt_item = create_opt_item(descr, opt_arg);
-       if (!opt_item) {
-               goto error;
-       }
-
-       if (used_next_orig_arg) {
-               iter->i += 2;
-       } else {
-               iter->i++;
-       }
-
-       *item = &opt_item->base;
-       goto end;
-
-error:
-       ARGPAR_ASSERT(ret != PARSE_ORIG_ARG_OPT_RET_OK);
-
-end:
-       return ret;
-}
-
-/*
- * Parses the original argument `orig_arg`.
- *
- * On success, sets `*item`.
- *
- * On error (except for `PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY`), sets
- * `*error`.
- */
-static enum parse_orig_arg_opt_ret parse_orig_arg_opt(const char *const orig_arg,
-                                                     const char *const next_orig_arg,
-                                                     const struct argpar_opt_descr *const descrs,
-                                                     struct argpar_iter *const iter,
-                                                     struct argpar_error **const error,
-                                                     struct argpar_item **const item)
-{
-       enum parse_orig_arg_opt_ret ret = PARSE_ORIG_ARG_OPT_RET_OK;
-
-       ARGPAR_ASSERT(orig_arg[0] == '-');
-
-       if (orig_arg[1] == '-') {
-               /* Long option */
-               ret = parse_long_opt(&orig_arg[2], next_orig_arg, descrs, iter, error, item);
-       } else {
-               /* Short option */
-               ret = parse_short_opt_group(&orig_arg[1], next_orig_arg, descrs, iter, error, item);
-       }
-
-       return ret;
-}
-
-ARGPAR_HIDDEN
-struct argpar_iter *argpar_iter_create(const unsigned int argc,
-                                      const char *const *const argv,
-                                      const struct argpar_opt_descr *const descrs)
-{
-       struct argpar_iter *iter = ARGPAR_ZALLOC(struct argpar_iter);
-
-       if (!iter) {
-               goto end;
-       }
-
-       iter->user.argc = argc;
-       iter->user.argv = argv;
-       iter->user.descrs = descrs;
-       iter->tmp_buf.size = 128;
-       iter->tmp_buf.data = ARGPAR_CALLOC(char, iter->tmp_buf.size);
-       if (!iter->tmp_buf.data) {
-               argpar_iter_destroy(iter);
-               iter = NULL;
-               goto end;
-       }
-
-end:
-       return iter;
-}
-
-ARGPAR_HIDDEN
-void argpar_iter_destroy(struct argpar_iter *const iter)
-{
-       if (iter) {
-               free(iter->tmp_buf.data);
-               free(iter);
-       }
-}
-
-ARGPAR_HIDDEN
-enum argpar_iter_next_status argpar_iter_next(struct argpar_iter *const iter,
-                                             const struct argpar_item **const item,
-                                             const struct argpar_error **const error)
-{
-       enum argpar_iter_next_status status;
-       enum parse_orig_arg_opt_ret parse_orig_arg_opt_ret;
-       const char *orig_arg;
-       const char *next_orig_arg;
-       struct argpar_error **const nc_error = (struct argpar_error **) error;
-
-       ARGPAR_ASSERT(iter->i <= iter->user.argc);
-
-       if (error) {
-               *nc_error = NULL;
-       }
-
-       if (iter->i == iter->user.argc) {
-               status = ARGPAR_ITER_NEXT_STATUS_END;
-               goto end;
-       }
-
-       orig_arg = iter->user.argv[iter->i];
-       next_orig_arg = iter->i < (iter->user.argc - 1) ? iter->user.argv[iter->i + 1] : NULL;
-
-       if (strcmp(orig_arg, "-") == 0 || strcmp(orig_arg, "--") == 0 || orig_arg[0] != '-') {
-               /* Non-option argument */
-               const struct argpar_item_non_opt *const non_opt_item =
-                       create_non_opt_item(orig_arg, iter->i, iter->non_opt_index);
-
-               if (!non_opt_item) {
-                       status = ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY;
-                       goto end;
-               }
-
-               iter->non_opt_index++;
-               iter->i++;
-               *item = &non_opt_item->base;
-               status = ARGPAR_ITER_NEXT_STATUS_OK;
-               goto end;
-       }
-
-       /* Option argument */
-       parse_orig_arg_opt_ret = parse_orig_arg_opt(orig_arg,
-                                                   next_orig_arg,
-                                                   iter->user.descrs,
-                                                   iter,
-                                                   nc_error,
-                                                   (struct argpar_item **) item);
-       switch (parse_orig_arg_opt_ret) {
-       case PARSE_ORIG_ARG_OPT_RET_OK:
-               status = ARGPAR_ITER_NEXT_STATUS_OK;
-               break;
-       case PARSE_ORIG_ARG_OPT_RET_ERROR:
-               if (error) {
-                       ARGPAR_ASSERT(*error);
-                       (*nc_error)->orig_index = iter->i;
-               }
-               status = ARGPAR_ITER_NEXT_STATUS_ERROR;
-               break;
-       case PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY:
-               status = ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY;
-               break;
-       default:
-               abort();
-       }
-
-end:
-       return status;
-}
-
-ARGPAR_HIDDEN
-unsigned int argpar_iter_ingested_orig_args(const struct argpar_iter *const iter)
-{
-       return iter->i;
-}
diff --git a/src/common/argpar/argpar.h b/src/common/argpar/argpar.h
deleted file mode 100644 (file)
index 909da9c..0000000
+++ /dev/null
@@ -1,725 +0,0 @@
-/*
- * SPDX-License-Identifier: MIT
- *
- * Copyright (c) 2019-2021 Philippe Proulx <pproulx@efficios.com>
- * Copyright (c) 2020-2021 Simon Marchi <simon.marchi@efficios.com>
- */
-
-#ifndef ARGPAR_ARGPAR_H
-#define ARGPAR_ARGPAR_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdbool.h>
-
-/*!
-@mainpage
-
-See the \ref api module.
-
-@addtogroup api argpar API
-@{
-
-argpar is a library which provides an iterator-based API to parse
-command-line arguments.
-
-The argpar parser supports:
-
-<ul>
-  <li>
-    Short options without an argument, possibly tied together:
-
-    @code{.unparsed}
-    -f -auf -n
-    @endcode
-
-  <li>
-    Short options with arguments:
-
-    @code{.unparsed}
-    -b 45 -f/mein/file -xyzhello
-    @endcode
-
-  <li>
-    Long options without an argument:
-
-    @code{.unparsed}
-    --five-guys --burger-king --pizza-hut --subway
-    @endcode
-
-  <li>
-    Long options with arguments (two original arguments or a single
-    one with a <code>=</code> character):
-
-    @code{.unparsed}
-    --security enable --time=18.56
-    @endcode
-
-  <li>
-    Non-option arguments (anything else, including
-    <code>-</code> and <code>\--</code>).
-
-    A non-option argument cannot have the form of an option, for example
-    if you need to pass the exact relative path
-    <code>\--component</code>. In that case, you would need to pass
-    <code>./\--component</code>. There's no generic way to escape
-    <code>-</code> as of this version.
-</ul>
-
-Create a parsing iterator with argpar_iter_create(), then repeatedly
-call argpar_iter_next() to access the parsing results (items), until one
-of:
-
-- There are no more arguments.
-
-- The argument parser encounters an error (for example, an unknown
-  option).
-
-- You need to stop.
-
-argpar_iter_create() accepts duplicate option descriptors in
-\p descrs (argpar_iter_next() produces one item for each
-instance).
-
-A parsing item (the result of argpar_iter_next()) has the type
-#argpar_item.
-
-Get the type (option or non-option) of an item with
-\link argpar_item_type(const struct argpar_item *) argpar_item_type()\endlink.
-Each item type has its set of dedicated functions
-(\c argpar_item_opt_ and \c argpar_item_non_opt_ prefixes).
-
-argpar_iter_next() produces the items in the same order that it parses
-original arguments, including non-option arguments. This means, for
-example, that for:
-
-@code{.unparsed}
---hello --count=23 /path/to/file -ab --type file -- magie
-@endcode
-
-argpar_iter_next() produces the following items, in this order:
-
--# Option item (<code>\--hello</code>).
--# Option item (<code>\--count</code> with argument <code>23</code>).
--# Non-option item (<code>/path/to/file</code>).
--# Option item (<code>-a</code>).
--# Option item (<code>-b</code>).
--# Option item (<code>\--type</code> with argument <code>file</code>).
--# Non-option item (<code>\--</code>).
--# Non-option item (<code>magie</code>).
-*/
-
-/*
- * If argpar is used in some shared library, we don't want said library
- * to export its symbols, so mark them as "hidden".
- *
- * On Windows, symbols are local unless explicitly exported; see
- * <https://gcc.gnu.org/wiki/Visibility>.
- */
-#if defined(_WIN32) || defined(__CYGWIN__)
-#define ARGPAR_HIDDEN
-#else
-#define ARGPAR_HIDDEN __attribute__((visibility("hidden")))
-#endif
-
-struct argpar_opt_descr;
-
-/*!
-@name Item API
-@{
-*/
-
-/*!
-@brief
-    Type of a parsing item, as returned by
-    \link argpar_item_type(const struct argpar_item *) argpar_item_type()\endlink.
-*/
-enum argpar_item_type {
-       /// Option
-       ARGPAR_ITEM_TYPE_OPT,
-
-       /// Non-option
-       ARGPAR_ITEM_TYPE_NON_OPT,
-};
-
-/*!
-@struct argpar_item
-
-@brief
-    Opaque parsing item type
-
-argpar_iter_next() sets a pointer to such a type.
-*/
-struct argpar_item;
-
-/*!
-@brief
-    Returns the type of the parsing item \p item.
-
-@param[in] item
-    Parsing item of which to get the type.
-
-@returns
-    Type of \p item.
-
-@pre
-    \p item is not \c NULL.
-*/
-/// @cond hidden_macro
-ARGPAR_HIDDEN
-/// @endcond
-enum argpar_item_type argpar_item_type(const struct argpar_item *item);
-
-/*!
-@brief
-    Returns the option descriptor of the option parsing item \p item.
-
-@param[in] item
-    Option parsing item of which to get the option descriptor.
-
-@returns
-    Option descriptor of \p item.
-
-@pre
-    \p item is not \c NULL.
-@pre
-    \p item has the type #ARGPAR_ITEM_TYPE_OPT.
-*/
-/// @cond hidden_macro
-ARGPAR_HIDDEN
-/// @endcond
-const struct argpar_opt_descr *argpar_item_opt_descr(const struct argpar_item *item);
-
-/*!
-@brief
-    Returns the argument of the option parsing item \p item, or
-    \c NULL if none.
-
-@param[in] item
-    Option parsing item of which to get the argument.
-
-@returns
-    Argument of \p item, or \c NULL if none.
-
-@pre
-    \p item is not \c NULL.
-@pre
-    \p item has the type #ARGPAR_ITEM_TYPE_OPT.
-*/
-/// @cond hidden_macro
-ARGPAR_HIDDEN
-/// @endcond
-const char *argpar_item_opt_arg(const struct argpar_item *item);
-
-/*!
-@brief
-    Returns the complete original argument, pointing to one of the
-    entries of the original arguments (in \p argv, as passed to
-    argpar_iter_create()), of the non-option parsing item \p item.
-
-@param[in] item
-    Non-option parsing item of which to get the complete original
-    argument.
-
-@returns
-    Complete original argument of \p item.
-
-@pre
-    \p item is not \c NULL.
-@pre
-    \p item has the type #ARGPAR_ITEM_TYPE_NON_OPT.
-*/
-/// @cond hidden_macro
-ARGPAR_HIDDEN
-/// @endcond
-const char *argpar_item_non_opt_arg(const struct argpar_item *item);
-
-/*!
-@brief
-    Returns the index, within \em all the original arguments (in
-    \p argv, as passed to argpar_iter_create()), of the non-option
-    parsing item \p item.
-
-For example, with the following command line (all options have no
-argument):
-
-@code{.unparsed}
--f -m meow --jus mix --kilo
-@endcode
-
-The original argument index of \c meow is&nbsp;2 while the original
-argument index of \c mix is&nbsp;4.
-
-@param[in] item
-    Non-option parsing item of which to get the original argument index.
-
-@returns
-    Original argument index of \p item.
-
-@pre
-    \p item is not \c NULL.
-@pre
-    \p item has the type #ARGPAR_ITEM_TYPE_NON_OPT.
-
-@sa
-    argpar_item_non_opt_non_opt_index() -- Returns the non-option index
-    of a non-option parsing item.
-*/
-/// @cond hidden_macro
-ARGPAR_HIDDEN
-/// @endcond
-unsigned int argpar_item_non_opt_orig_index(const struct argpar_item *item);
-
-/*!
-@brief
-    Returns the index, within the parsed non-option parsing items, of
-    the non-option parsing item \p item.
-
-For example, with the following command line (all options have no
-argument):
-
-@code{.unparsed}
--f -m meow --jus mix --kilo
-@endcode
-
-The non-option index of \c meow is&nbsp;0 while the original
-argument index of \c mix is&nbsp;1.
-
-@param[in] item
-    Non-option parsing item of which to get the non-option index.
-
-@returns
-    Non-option index of \p item.
-
-@pre
-    \p item is not \c NULL.
-@pre
-    \p item has the type #ARGPAR_ITEM_TYPE_NON_OPT.
-
-@sa
-    argpar_item_non_opt_orig_index() -- Returns the original argument
-    index of a non-option parsing item.
-*/
-/// @cond hidden_macro
-ARGPAR_HIDDEN
-/// @endcond
-unsigned int argpar_item_non_opt_non_opt_index(const struct argpar_item *item);
-
-/*!
-@brief
-    Destroys the parsing item \p item.
-
-@param[in] item
-    Parsing item to destroy (may be \c NULL).
-*/
-/// @cond hidden_macro
-ARGPAR_HIDDEN
-/// @endcond
-void argpar_item_destroy(const struct argpar_item *item);
-
-/*!
-@def ARGPAR_ITEM_DESTROY_AND_RESET(_item)
-
-@brief
-    Calls argpar_item_destroy() with \p _item, and then sets \p _item
-    to \c NULL.
-
-@param[in] _item
-    Item to destroy and variable to reset
-    (<code>const struct argpar_item *</code> type).
-*/
-#define ARGPAR_ITEM_DESTROY_AND_RESET(_item) \
-       {                                    \
-               argpar_item_destroy(_item);  \
-               ((_item)) = NULL;            \
-       }
-
-/// @}
-
-/*!
-@name Error API
-@{
-*/
-
-/*!
-@brief
-    Parsing error type, as returned by
-    \link argpar_error_type(const struct argpar_error *) argpar_error_type()\endlink.
-*/
-enum argpar_error_type {
-       /// Unknown option error
-       ARGPAR_ERROR_TYPE_UNKNOWN_OPT,
-
-       /// Missing option argument error
-       ARGPAR_ERROR_TYPE_MISSING_OPT_ARG,
-
-       /// Unexpected option argument error
-       ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG,
-};
-
-/*!
-@struct argpar_error
-
-@brief
-    Opaque parsing error type
-*/
-struct argpar_error;
-
-/*!
-@brief
-    Returns the type of the parsing error object \p error.
-
-@param[in] error
-    Parsing error of which to get the type.
-
-@returns
-    Type of \p error.
-
-@pre
-    \p error is not \c NULL.
-*/
-/// @cond hidden_macro
-ARGPAR_HIDDEN
-/// @endcond
-enum argpar_error_type argpar_error_type(const struct argpar_error *error);
-
-/*!
-@brief
-    Returns the index of the original argument (in \p argv, as passed to
-    argpar_iter_create()) for which the parsing error described by
-    \p error occurred.
-
-@param[in] error
-    Parsing error of which to get the original argument index.
-
-@returns
-    Original argument index of \p error.
-
-@pre
-    \p error is not \c NULL.
-*/
-/// @cond hidden_macro
-ARGPAR_HIDDEN
-/// @endcond
-unsigned int argpar_error_orig_index(const struct argpar_error *error);
-
-/*!
-@brief
-    Returns the name of the unknown option for which the parsing error
-    described by \p error occurred.
-
-The returned name includes any <code>-</code> or <code>\--</code>
-prefix.
-
-With the long option with argument form, for example
-<code>\--mireille=deyglun</code>, this function only returns the name
-part (<code>\--mireille</code> in the last example).
-
-@param[in] error
-    Parsing error of which to get the name of the unknown option.
-
-@returns
-    Name of the unknown option of \p error.
-
-@pre
-    \p error is not \c NULL.
-@pre
-    The type of \p error, as returned by
-    \link argpar_error_type(const struct argpar_error *) argpar_error_type()\endlink,
-    is #ARGPAR_ERROR_TYPE_UNKNOWN_OPT.
-*/
-/// @cond hidden_macro
-ARGPAR_HIDDEN
-/// @endcond
-const char *argpar_error_unknown_opt_name(const struct argpar_error *error);
-
-/*!
-@brief
-    Returns the descriptor of the option for which the parsing error
-    described by \p error occurred.
-
-@param[in] error
-    Parsing error of which to get the option descriptor.
-@param[out] is_short
-    @parblock
-    If not \c NULL, this function sets \p *is_short to:
-
-    - \c true if the option for which \p error occurred is a short
-      option.
-
-    - \c false if the option for which \p error occurred is a long
-      option.
-    @endparblock
-
-@returns
-    Descriptor of the option of \p error.
-
-@pre
-    \p error is not \c NULL.
-@pre
-    The type of \p error, as returned by
-    \link argpar_error_type(const struct argpar_error *) argpar_error_type()\endlink,
-    is #ARGPAR_ERROR_TYPE_MISSING_OPT_ARG or
-    #ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG.
-*/
-/// @cond hidden_macro
-ARGPAR_HIDDEN
-/// @endcond
-const struct argpar_opt_descr *argpar_error_opt_descr(const struct argpar_error *error,
-                                                     bool *is_short);
-
-/*!
-@brief
-    Destroys the parsing error \p error.
-
-@param[in] error
-    Parsing error to destroy (may be \c NULL).
-*/
-/// @cond hidden_macro
-ARGPAR_HIDDEN
-/// @endcond
-void argpar_error_destroy(const struct argpar_error *error);
-
-/// @}
-
-/*!
-@name Iterator API
-@{
-*/
-
-/*!
-@brief
-    Option descriptor
-
-argpar_iter_create() accepts an array of instances of such a type,
-terminated with #ARGPAR_OPT_DESCR_SENTINEL, as its \p descrs parameter.
-
-The typical usage is, for example:
-
-@code
-const struct argpar_opt_descr descrs[] = {
-    { 0, 'd', NULL, false },
-    { 1, '\0', "squeeze", true },
-    { 2, 'm', "meow", true },
-    ARGPAR_OPT_DESCR_SENTINEL,
-};
-@endcode
-*/
-struct argpar_opt_descr {
-       /// Numeric ID, to uniquely identify this descriptor
-       const int id;
-
-       /// Short option character, or <code>'\0'</code>
-       const char short_name;
-
-       /// Long option name (without the <code>\--</code> prefix), or \c NULL
-       const char *const long_name;
-
-       /// \c true if this option has an argument
-       const bool with_arg;
-};
-
-/*!
-@brief
-    Sentinel for an option descriptor array
-
-The typical usage is, for example:
-
-@code
-const struct argpar_opt_descr descrs[] = {
-    { 0, 'd', NULL, false },
-    { 1, '\0', "squeeze", true },
-    { 2, 'm', "meow", true },
-    ARGPAR_OPT_DESCR_SENTINEL,
-};
-@endcode
-*/
-#define ARGPAR_OPT_DESCR_SENTINEL     \
-       {                             \
-               -1, '\0', NULL, false \
-       }
-
-/*!
-@struct argpar_iter
-
-@brief
-    Opaque argpar iterator type
-
-argpar_iter_create() returns a pointer to such a type.
-*/
-struct argpar_iter;
-
-/*!
-@brief
-    Creates and returns an argument parsing iterator to parse the
-    original arguments \p argv of which the count is \p argc using the
-    option descriptors \p descrs.
-
-This function initializes the returned structure, but doesn't actually
-start parsing the arguments.
-
-argpar considers \em all the elements of \p argv, including the first
-one, so that you would typically pass <code>(argc - 1)</code> as \p argc
-and <code>\&argv[1]</code> as \p argv from what <code>main()</code>
-receives, or ignore the parsing item of the first call to
-argpar_iter_next().
-
-\p *argv and \p *descrs must \em not change for all of:
-
-- The lifetime of the returned iterator (until you call
-  argpar_iter_destroy()).
-
-- The lifetime of any parsing item (until you call
-  argpar_item_destroy()) which argpar_iter_next() creates from the
-  returned iterator.
-
-- The lifetime of any parsing error (until you call
-  argpar_error_destroy()) which argpar_iter_next() creates from the
-  returned iterator.
-
-@param[in] argc
-    Number of original arguments to parse in \p argv.
-@param[in] argv
-    Original arguments to parse, of which the count is \p argc.
-@param[in] descrs
-    @parblock
-    Option descriptor array, terminated with #ARGPAR_OPT_DESCR_SENTINEL.
-
-    May contain duplicate entries.
-    @endparblock
-
-@returns
-    New argument parsing iterator, or \c NULL on memory error.
-
-@pre
-    \p argc is greater than 0.
-@pre
-    \p argv is not \c NULL.
-@pre
-    The first \p argc elements of \p argv are not \c NULL.
-@pre
-    \p descrs is not \c NULL.
-
-@sa
-    argpar_iter_destroy() -- Destroys an argument parsing iterator.
-*/
-/// @cond hidden_macro
-ARGPAR_HIDDEN
-/// @endcond
-struct argpar_iter *argpar_iter_create(unsigned int argc,
-                                      const char *const *argv,
-                                      const struct argpar_opt_descr *descrs);
-
-/*!
-@brief
-    Destroys the argument parsing iterator \p iter.
-
-@param[in] iter
-    Argument parsing iterator to destroy (may be \c NULL).
-
-@sa
-    argpar_iter_create() -- Creates an argument parsing iterator.
-*/
-/// @cond hidden_macro
-ARGPAR_HIDDEN
-/// @endcond
-void argpar_iter_destroy(struct argpar_iter *iter);
-
-/*!
-@brief
-    Return type of argpar_iter_next().
-
-Error status enumerators have a negative value.
-*/
-enum argpar_iter_next_status {
-       /// Success
-       ARGPAR_ITER_NEXT_STATUS_OK,
-
-       /// End of iteration (no more original arguments to parse)
-       ARGPAR_ITER_NEXT_STATUS_END,
-
-       /// Parsing error
-       ARGPAR_ITER_NEXT_STATUS_ERROR = -1,
-
-       /// Memory error
-       ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY = -12,
-};
-
-/*!
-@brief
-    Sets \p *item to the next item of the argument parsing iterator
-    \p iter and advances \p iter.
-
-If there are no more original arguments to parse, this function returns
-#ARGPAR_ITER_NEXT_STATUS_END.
-
-@param[in] iter
-    Argument parsing iterator from which to get the next parsing item.
-@param[out] item
-    @parblock
-    On success, \p *item is the next parsing item of \p iter.
-
-    Destroy \p *item with argpar_item_destroy().
-    @endparblock
-@param[out] error
-    @parblock
-    When this function returns #ARGPAR_ITER_NEXT_STATUS_ERROR,
-    if this parameter is not \c NULL, \p *error contains details about
-    the error.
-
-    Destroy \p *error with argpar_error_destroy().
-    @endparblock
-
-@returns
-    Status code.
-
-@pre
-    \p iter is not \c NULL.
-@pre
-    \p item is not \c NULL.
-*/
-/// @cond hidden_macro
-ARGPAR_HIDDEN
-/// @endcond
-enum argpar_iter_next_status argpar_iter_next(struct argpar_iter *iter,
-                                             const struct argpar_item **item,
-                                             const struct argpar_error **error);
-
-/*
- * Returns the number of ingested elements from `argv`, as passed to
- * argpar_iter_create() to create `*iter`, that were required to produce
- * the previously returned items.
- */
-
-/*!
-@brief
-    Returns the number of ingested original arguments (in
-    \p argv, as passed to argpar_iter_create() to create \p iter) that
-    the parser ingested to produce the \em previous parsing items.
-
-@param[in] iter
-    Argument parsing iterator of which to get the number of ingested
-    original arguments.
-
-@returns
-    Number of original arguments which \p iter ingested.
-
-@pre
-    \p iter is not \c NULL.
-*/
-/// @cond hidden_macro
-ARGPAR_HIDDEN
-/// @endcond
-unsigned int argpar_iter_ingested_orig_args(const struct argpar_iter *iter);
-
-/// @}
-
-/// @}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ARGPAR_ARGPAR_H */
index e8b7a8159917f41acf6f4615f7ba6552958745d4..c2626cc16c978bc76571cefbe4b243d5cdcefae5 100644 (file)
@@ -3,3 +3,11 @@
 SUBDIRS = msgpack
 
 EXTRA_DIST = optional.hpp fmt nlohmann
+
+noinst_LTLIBRARIES =
+
+# libargpar
+noinst_LTLIBRARIES += argpar/libargpar.la
+argpar_libargpar_la_SOURCES = \
+       argpar/argpar.c \
+       argpar/argpar.h
diff --git a/src/vendor/argpar/argpar.c b/src/vendor/argpar/argpar.c
new file mode 100644 (file)
index 0000000..f8280ce
--- /dev/null
@@ -0,0 +1,761 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright (c) 2019-2021 Philippe Proulx <pproulx@efficios.com>
+ * Copyright (c) 2020-2021 Simon Marchi <simon.marchi@efficios.com>
+ */
+
+#include "argpar.h"
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ARGPAR_REALLOC(_ptr, _type, _nmemb) ((_type *) realloc(_ptr, (_nmemb) * sizeof(_type)))
+
+#define ARGPAR_CALLOC(_type, _nmemb) ((_type *) calloc((_nmemb), sizeof(_type)))
+
+#define ARGPAR_ZALLOC(_type) ARGPAR_CALLOC(_type, 1)
+
+#ifdef NDEBUG
+/*
+ * Force usage of the assertion condition to prevent unused variable warnings
+ * when `assert()` are disabled by the `NDEBUG` definition.
+ */
+#define ARGPAR_ASSERT(_cond) ((void) sizeof((void) (_cond), 0))
+#else
+#include <assert.h>
+#define ARGPAR_ASSERT(_cond) assert(_cond)
+#endif
+
+/*
+ * An argpar iterator.
+ *
+ * Such a structure contains the state of an iterator between calls to
+ * argpar_iter_next().
+ */
+struct argpar_iter {
+       /*
+        * Data provided by the user to argpar_iter_create(); immutable
+        * afterwards.
+        */
+       struct {
+               unsigned int argc;
+               const char *const *argv;
+               const struct argpar_opt_descr *descrs;
+       } user;
+
+       /*
+        * Index of the argument to process in the next
+        * argpar_iter_next() call.
+        */
+       unsigned int i;
+
+       /* Counter of non-option arguments */
+       int non_opt_index;
+
+       /*
+        * Current character within the current short option group: if
+        * it's not `NULL`, the parser is within a short option group,
+        * therefore it must resume there in the next argpar_iter_next()
+        * call.
+        */
+       const char *short_opt_group_ch;
+
+       /* Temporary character buffer which only grows */
+       struct {
+               size_t size;
+               char *data;
+       } tmp_buf;
+};
+
+/* Base parsing item */
+struct argpar_item {
+       enum argpar_item_type type;
+};
+
+/* Option parsing item */
+struct argpar_item_opt {
+       struct argpar_item base;
+
+       /* Corresponding descriptor */
+       const struct argpar_opt_descr *descr;
+
+       /* Argument, or `NULL` if none; owned by this */
+       char *arg;
+};
+
+/* Non-option parsing item */
+struct argpar_item_non_opt {
+       struct argpar_item base;
+
+       /*
+        * Complete argument, pointing to one of the entries of the
+        * original arguments (`argv`).
+        */
+       const char *arg;
+
+       /*
+        * Index of this argument amongst all original arguments
+        * (`argv`).
+        */
+       unsigned int orig_index;
+
+       /* Index of this argument amongst other non-option arguments */
+       unsigned int non_opt_index;
+};
+
+/* Parsing error */
+struct argpar_error {
+       /* Error type */
+       enum argpar_error_type type;
+
+       /* Original argument index */
+       unsigned int orig_index;
+
+       /* Name of unknown option; owned by this */
+       char *unknown_opt_name;
+
+       /* Option descriptor */
+       const struct argpar_opt_descr *opt_descr;
+
+       /* `true` if a short option caused the error */
+       bool is_short;
+};
+
+ARGPAR_HIDDEN
+enum argpar_item_type argpar_item_type(const struct argpar_item *const item)
+{
+       ARGPAR_ASSERT(item);
+       return item->type;
+}
+
+ARGPAR_HIDDEN
+const struct argpar_opt_descr *argpar_item_opt_descr(const struct argpar_item *const item)
+{
+       ARGPAR_ASSERT(item);
+       ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_OPT);
+       return ((const struct argpar_item_opt *) item)->descr;
+}
+
+ARGPAR_HIDDEN
+const char *argpar_item_opt_arg(const struct argpar_item *const item)
+{
+       ARGPAR_ASSERT(item);
+       ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_OPT);
+       return ((const struct argpar_item_opt *) item)->arg;
+}
+
+ARGPAR_HIDDEN
+const char *argpar_item_non_opt_arg(const struct argpar_item *const item)
+{
+       ARGPAR_ASSERT(item);
+       ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_NON_OPT);
+       return ((const struct argpar_item_non_opt *) item)->arg;
+}
+
+ARGPAR_HIDDEN
+unsigned int argpar_item_non_opt_orig_index(const struct argpar_item *const item)
+{
+       ARGPAR_ASSERT(item);
+       ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_NON_OPT);
+       return ((const struct argpar_item_non_opt *) item)->orig_index;
+}
+
+ARGPAR_HIDDEN
+unsigned int argpar_item_non_opt_non_opt_index(const struct argpar_item *const item)
+{
+       ARGPAR_ASSERT(item);
+       ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_NON_OPT);
+       return ((const struct argpar_item_non_opt *) item)->non_opt_index;
+}
+
+ARGPAR_HIDDEN
+void argpar_item_destroy(const struct argpar_item *const item)
+{
+       if (!item) {
+               goto end;
+       }
+
+       if (item->type == ARGPAR_ITEM_TYPE_OPT) {
+               struct argpar_item_opt *const opt_item = (struct argpar_item_opt *) item;
+
+               free(opt_item->arg);
+       }
+
+       free((void *) item);
+
+end:
+       return;
+}
+
+/*
+ * Creates and returns an option parsing item for the descriptor `descr`
+ * and having the argument `arg` (copied; may be `NULL`).
+ *
+ * Returns `NULL` on memory error.
+ */
+static struct argpar_item_opt *create_opt_item(const struct argpar_opt_descr *const descr,
+                                              const char *const arg)
+{
+       struct argpar_item_opt *opt_item = ARGPAR_ZALLOC(struct argpar_item_opt);
+
+       if (!opt_item) {
+               goto end;
+       }
+
+       opt_item->base.type = ARGPAR_ITEM_TYPE_OPT;
+       opt_item->descr = descr;
+
+       if (arg) {
+               opt_item->arg = strdup(arg);
+               if (!opt_item->arg) {
+                       goto error;
+               }
+       }
+
+       goto end;
+
+error:
+       argpar_item_destroy(&opt_item->base);
+       opt_item = NULL;
+
+end:
+       return opt_item;
+}
+
+/*
+ * Creates and returns a non-option parsing item for the original
+ * argument `arg` having the original index `orig_index` and the
+ * non-option index `non_opt_index`.
+ *
+ * Returns `NULL` on memory error.
+ */
+static struct argpar_item_non_opt *create_non_opt_item(const char *const arg,
+                                                      const unsigned int orig_index,
+                                                      const unsigned int non_opt_index)
+{
+       struct argpar_item_non_opt *const non_opt_item = ARGPAR_ZALLOC(struct argpar_item_non_opt);
+
+       if (!non_opt_item) {
+               goto end;
+       }
+
+       non_opt_item->base.type = ARGPAR_ITEM_TYPE_NON_OPT;
+       non_opt_item->arg = arg;
+       non_opt_item->orig_index = orig_index;
+       non_opt_item->non_opt_index = non_opt_index;
+
+end:
+       return non_opt_item;
+}
+
+/*
+ * If `error` is not `NULL`, sets the error `error` to a new parsing
+ * error object, setting its `unknown_opt_name`, `opt_descr`, and
+ * `is_short` members from the parameters.
+ *
+ * `unknown_opt_name` is the unknown option name without any `-` or `--`
+ * prefix: `is_short` controls which type of unknown option it is.
+ *
+ * Returns 0 on success (including if `error` is `NULL`) or -1 on memory
+ * error.
+ */
+static int set_error(struct argpar_error **const error,
+                    enum argpar_error_type type,
+                    const char *const unknown_opt_name,
+                    const struct argpar_opt_descr *const opt_descr,
+                    const bool is_short)
+{
+       int ret = 0;
+
+       if (!error) {
+               goto end;
+       }
+
+       *error = ARGPAR_ZALLOC(struct argpar_error);
+       if (!*error) {
+               goto error;
+       }
+
+       (*error)->type = type;
+
+       if (unknown_opt_name) {
+               (*error)->unknown_opt_name =
+                       ARGPAR_CALLOC(char, strlen(unknown_opt_name) + 1 + (is_short ? 1 : 2));
+               if (!(*error)->unknown_opt_name) {
+                       goto error;
+               }
+
+               if (is_short) {
+                       strcpy((*error)->unknown_opt_name, "-");
+               } else {
+                       strcpy((*error)->unknown_opt_name, "--");
+               }
+
+               strcat((*error)->unknown_opt_name, unknown_opt_name);
+       }
+
+       (*error)->opt_descr = opt_descr;
+       (*error)->is_short = is_short;
+       goto end;
+
+error:
+       argpar_error_destroy(*error);
+       ret = -1;
+
+end:
+       return ret;
+}
+
+ARGPAR_HIDDEN
+enum argpar_error_type argpar_error_type(const struct argpar_error *const error)
+{
+       ARGPAR_ASSERT(error);
+       return error->type;
+}
+
+ARGPAR_HIDDEN
+unsigned int argpar_error_orig_index(const struct argpar_error *const error)
+{
+       ARGPAR_ASSERT(error);
+       return error->orig_index;
+}
+
+ARGPAR_HIDDEN
+const char *argpar_error_unknown_opt_name(const struct argpar_error *const error)
+{
+       ARGPAR_ASSERT(error);
+       ARGPAR_ASSERT(error->type == ARGPAR_ERROR_TYPE_UNKNOWN_OPT);
+       ARGPAR_ASSERT(error->unknown_opt_name);
+       return error->unknown_opt_name;
+}
+
+ARGPAR_HIDDEN
+const struct argpar_opt_descr *argpar_error_opt_descr(const struct argpar_error *const error,
+                                                     bool *const is_short)
+{
+       ARGPAR_ASSERT(error);
+       ARGPAR_ASSERT(error->type == ARGPAR_ERROR_TYPE_MISSING_OPT_ARG ||
+                     error->type == ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG);
+       ARGPAR_ASSERT(error->opt_descr);
+
+       if (is_short) {
+               *is_short = error->is_short;
+       }
+
+       return error->opt_descr;
+}
+
+ARGPAR_HIDDEN
+void argpar_error_destroy(const struct argpar_error *const error)
+{
+       if (error) {
+               free(error->unknown_opt_name);
+               free((void *) error);
+       }
+}
+
+/*
+ * Finds and returns the _first_ descriptor having the short option name
+ * `short_name` or the long option name `long_name` within the option
+ * descriptors `descrs`.
+ *
+ * `short_name` may be `'\0'` to not consider it.
+ *
+ * `long_name` may be `NULL` to not consider it.
+ *
+ * Returns `NULL` if no descriptor is found.
+ */
+static const struct argpar_opt_descr *find_descr(const struct argpar_opt_descr *const descrs,
+                                                const char short_name,
+                                                const char *const long_name)
+{
+       const struct argpar_opt_descr *descr;
+
+       for (descr = descrs; descr->short_name || descr->long_name; descr++) {
+               if (short_name && descr->short_name && short_name == descr->short_name) {
+                       goto end;
+               }
+
+               if (long_name && descr->long_name && strcmp(long_name, descr->long_name) == 0) {
+                       goto end;
+               }
+       }
+
+end:
+       return !descr->short_name && !descr->long_name ? NULL : descr;
+}
+
+/* Return type of parse_short_opt_group() and parse_long_opt() */
+enum parse_orig_arg_opt_ret {
+       PARSE_ORIG_ARG_OPT_RET_OK,
+       PARSE_ORIG_ARG_OPT_RET_ERROR = -1,
+       PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY = -2,
+};
+
+/*
+ * Parses the short option group argument `short_opt_group`, starting
+ * where needed depending on the state of `iter`.
+ *
+ * On success, sets `*item`.
+ *
+ * On error (except for `PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY`), sets
+ * `*error`.
+ */
+static enum parse_orig_arg_opt_ret
+parse_short_opt_group(const char *const short_opt_group,
+                     const char *const next_orig_arg,
+                     const struct argpar_opt_descr *const descrs,
+                     struct argpar_iter *const iter,
+                     struct argpar_error **const error,
+                     struct argpar_item **const item)
+{
+       enum parse_orig_arg_opt_ret ret = PARSE_ORIG_ARG_OPT_RET_OK;
+       bool used_next_orig_arg = false;
+       const char *opt_arg = NULL;
+       const struct argpar_opt_descr *descr;
+       struct argpar_item_opt *opt_item;
+
+       ARGPAR_ASSERT(strlen(short_opt_group) != 0);
+
+       if (!iter->short_opt_group_ch) {
+               iter->short_opt_group_ch = short_opt_group;
+       }
+
+       /* Find corresponding option descriptor */
+       descr = find_descr(descrs, *iter->short_opt_group_ch, NULL);
+       if (!descr) {
+               const char unknown_opt_name[] = { *iter->short_opt_group_ch, '\0' };
+
+               ret = PARSE_ORIG_ARG_OPT_RET_ERROR;
+
+               if (set_error(error, ARGPAR_ERROR_TYPE_UNKNOWN_OPT, unknown_opt_name, NULL, true)) {
+                       ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
+               }
+
+               goto error;
+       }
+
+       if (descr->with_arg) {
+               if (iter->short_opt_group_ch[1]) {
+                       /* `-oarg` form */
+                       opt_arg = &iter->short_opt_group_ch[1];
+               } else {
+                       /* `-o arg` form */
+                       opt_arg = next_orig_arg;
+                       used_next_orig_arg = true;
+               }
+
+               /*
+                * We accept `-o ''` (empty option argument), but not
+                * `-o` alone if an option argument is expected.
+                */
+               if (!opt_arg || (iter->short_opt_group_ch[1] && strlen(opt_arg) == 0)) {
+                       ret = PARSE_ORIG_ARG_OPT_RET_ERROR;
+
+                       if (set_error(error, ARGPAR_ERROR_TYPE_MISSING_OPT_ARG, NULL, descr, true)) {
+                               ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
+                       }
+
+                       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;
+       }
+
+       *item = &opt_item->base;
+       iter->short_opt_group_ch++;
+
+       if (descr->with_arg || !*iter->short_opt_group_ch) {
+               /* Option has an argument: no more options */
+               iter->short_opt_group_ch = NULL;
+
+               if (used_next_orig_arg) {
+                       iter->i += 2;
+               } else {
+                       iter->i++;
+               }
+       }
+
+       goto end;
+
+error:
+       ARGPAR_ASSERT(ret != PARSE_ORIG_ARG_OPT_RET_OK);
+
+end:
+       return ret;
+}
+
+/*
+ * Parses the long option argument `long_opt_arg`.
+ *
+ * On success, sets `*item`.
+ *
+ * On error (except for `PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY`), sets
+ * `*error`.
+ */
+static enum parse_orig_arg_opt_ret parse_long_opt(const char *const long_opt_arg,
+                                                 const char *const next_orig_arg,
+                                                 const struct argpar_opt_descr *const descrs,
+                                                 struct argpar_iter *const iter,
+                                                 struct argpar_error **const error,
+                                                 struct argpar_item **const item)
+{
+       enum parse_orig_arg_opt_ret ret = PARSE_ORIG_ARG_OPT_RET_OK;
+       const struct argpar_opt_descr *descr;
+       struct argpar_item_opt *opt_item;
+       bool used_next_orig_arg = false;
+
+       /* Option's argument, if any */
+       const char *opt_arg = NULL;
+
+       /* Position of first `=`, if any */
+       const char *eq_pos;
+
+       /* Option name */
+       const char *long_opt_name = long_opt_arg;
+
+       ARGPAR_ASSERT(strlen(long_opt_arg) != 0);
+
+       /* Find the first `=` in original argument */
+       eq_pos = strchr(long_opt_arg, '=');
+       if (eq_pos) {
+               const size_t long_opt_name_size = eq_pos - long_opt_arg;
+
+               /* Isolate the option name */
+               while (long_opt_name_size > iter->tmp_buf.size - 1) {
+                       iter->tmp_buf.size *= 2;
+                       iter->tmp_buf.data =
+                               ARGPAR_REALLOC(iter->tmp_buf.data, char, iter->tmp_buf.size);
+                       if (!iter->tmp_buf.data) {
+                               ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
+                               goto error;
+                       }
+               }
+
+               memcpy(iter->tmp_buf.data, long_opt_arg, long_opt_name_size);
+               iter->tmp_buf.data[long_opt_name_size] = '\0';
+               long_opt_name = iter->tmp_buf.data;
+       }
+
+       /* Find corresponding option descriptor */
+       descr = find_descr(descrs, '\0', long_opt_name);
+       if (!descr) {
+               ret = PARSE_ORIG_ARG_OPT_RET_ERROR;
+
+               if (set_error(error, ARGPAR_ERROR_TYPE_UNKNOWN_OPT, long_opt_name, NULL, false)) {
+                       ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
+               }
+
+               goto error;
+       }
+
+       /* Find option's argument if any */
+       if (descr->with_arg) {
+               if (eq_pos) {
+                       /* `--long-opt=arg` style */
+                       opt_arg = eq_pos + 1;
+               } else {
+                       /* `--long-opt arg` style */
+                       if (!next_orig_arg) {
+                               ret = PARSE_ORIG_ARG_OPT_RET_ERROR;
+
+                               if (set_error(error,
+                                             ARGPAR_ERROR_TYPE_MISSING_OPT_ARG,
+                                             NULL,
+                                             descr,
+                                             false)) {
+                                       ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
+                               }
+
+                               goto error;
+                       }
+
+                       opt_arg = next_orig_arg;
+                       used_next_orig_arg = true;
+               }
+       } else if (eq_pos) {
+               /*
+                * Unexpected `--opt=arg` style for a long option which
+                * doesn't accept an argument.
+                */
+               ret = PARSE_ORIG_ARG_OPT_RET_ERROR;
+
+               if (set_error(error, ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG, NULL, descr, false)) {
+                       ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
+               }
+
+               goto error;
+       }
+
+       /* Create and append option argument */
+       opt_item = create_opt_item(descr, opt_arg);
+       if (!opt_item) {
+               goto error;
+       }
+
+       if (used_next_orig_arg) {
+               iter->i += 2;
+       } else {
+               iter->i++;
+       }
+
+       *item = &opt_item->base;
+       goto end;
+
+error:
+       ARGPAR_ASSERT(ret != PARSE_ORIG_ARG_OPT_RET_OK);
+
+end:
+       return ret;
+}
+
+/*
+ * Parses the original argument `orig_arg`.
+ *
+ * On success, sets `*item`.
+ *
+ * On error (except for `PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY`), sets
+ * `*error`.
+ */
+static enum parse_orig_arg_opt_ret parse_orig_arg_opt(const char *const orig_arg,
+                                                     const char *const next_orig_arg,
+                                                     const struct argpar_opt_descr *const descrs,
+                                                     struct argpar_iter *const iter,
+                                                     struct argpar_error **const error,
+                                                     struct argpar_item **const item)
+{
+       enum parse_orig_arg_opt_ret ret = PARSE_ORIG_ARG_OPT_RET_OK;
+
+       ARGPAR_ASSERT(orig_arg[0] == '-');
+
+       if (orig_arg[1] == '-') {
+               /* Long option */
+               ret = parse_long_opt(&orig_arg[2], next_orig_arg, descrs, iter, error, item);
+       } else {
+               /* Short option */
+               ret = parse_short_opt_group(&orig_arg[1], next_orig_arg, descrs, iter, error, item);
+       }
+
+       return ret;
+}
+
+ARGPAR_HIDDEN
+struct argpar_iter *argpar_iter_create(const unsigned int argc,
+                                      const char *const *const argv,
+                                      const struct argpar_opt_descr *const descrs)
+{
+       struct argpar_iter *iter = ARGPAR_ZALLOC(struct argpar_iter);
+
+       if (!iter) {
+               goto end;
+       }
+
+       iter->user.argc = argc;
+       iter->user.argv = argv;
+       iter->user.descrs = descrs;
+       iter->tmp_buf.size = 128;
+       iter->tmp_buf.data = ARGPAR_CALLOC(char, iter->tmp_buf.size);
+       if (!iter->tmp_buf.data) {
+               argpar_iter_destroy(iter);
+               iter = NULL;
+               goto end;
+       }
+
+end:
+       return iter;
+}
+
+ARGPAR_HIDDEN
+void argpar_iter_destroy(struct argpar_iter *const iter)
+{
+       if (iter) {
+               free(iter->tmp_buf.data);
+               free(iter);
+       }
+}
+
+ARGPAR_HIDDEN
+enum argpar_iter_next_status argpar_iter_next(struct argpar_iter *const iter,
+                                             const struct argpar_item **const item,
+                                             const struct argpar_error **const error)
+{
+       enum argpar_iter_next_status status;
+       enum parse_orig_arg_opt_ret parse_orig_arg_opt_ret;
+       const char *orig_arg;
+       const char *next_orig_arg;
+       struct argpar_error **const nc_error = (struct argpar_error **) error;
+
+       ARGPAR_ASSERT(iter->i <= iter->user.argc);
+
+       if (error) {
+               *nc_error = NULL;
+       }
+
+       if (iter->i == iter->user.argc) {
+               status = ARGPAR_ITER_NEXT_STATUS_END;
+               goto end;
+       }
+
+       orig_arg = iter->user.argv[iter->i];
+       next_orig_arg = iter->i < (iter->user.argc - 1) ? iter->user.argv[iter->i + 1] : NULL;
+
+       if (strcmp(orig_arg, "-") == 0 || strcmp(orig_arg, "--") == 0 || orig_arg[0] != '-') {
+               /* Non-option argument */
+               const struct argpar_item_non_opt *const non_opt_item =
+                       create_non_opt_item(orig_arg, iter->i, iter->non_opt_index);
+
+               if (!non_opt_item) {
+                       status = ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY;
+                       goto end;
+               }
+
+               iter->non_opt_index++;
+               iter->i++;
+               *item = &non_opt_item->base;
+               status = ARGPAR_ITER_NEXT_STATUS_OK;
+               goto end;
+       }
+
+       /* Option argument */
+       parse_orig_arg_opt_ret = parse_orig_arg_opt(orig_arg,
+                                                   next_orig_arg,
+                                                   iter->user.descrs,
+                                                   iter,
+                                                   nc_error,
+                                                   (struct argpar_item **) item);
+       switch (parse_orig_arg_opt_ret) {
+       case PARSE_ORIG_ARG_OPT_RET_OK:
+               status = ARGPAR_ITER_NEXT_STATUS_OK;
+               break;
+       case PARSE_ORIG_ARG_OPT_RET_ERROR:
+               if (error) {
+                       ARGPAR_ASSERT(*error);
+                       (*nc_error)->orig_index = iter->i;
+               }
+               status = ARGPAR_ITER_NEXT_STATUS_ERROR;
+               break;
+       case PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY:
+               status = ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY;
+               break;
+       default:
+               abort();
+       }
+
+end:
+       return status;
+}
+
+ARGPAR_HIDDEN
+unsigned int argpar_iter_ingested_orig_args(const struct argpar_iter *const iter)
+{
+       return iter->i;
+}
diff --git a/src/vendor/argpar/argpar.h b/src/vendor/argpar/argpar.h
new file mode 100644 (file)
index 0000000..909da9c
--- /dev/null
@@ -0,0 +1,725 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright (c) 2019-2021 Philippe Proulx <pproulx@efficios.com>
+ * Copyright (c) 2020-2021 Simon Marchi <simon.marchi@efficios.com>
+ */
+
+#ifndef ARGPAR_ARGPAR_H
+#define ARGPAR_ARGPAR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+
+/*!
+@mainpage
+
+See the \ref api module.
+
+@addtogroup api argpar API
+@{
+
+argpar is a library which provides an iterator-based API to parse
+command-line arguments.
+
+The argpar parser supports:
+
+<ul>
+  <li>
+    Short options without an argument, possibly tied together:
+
+    @code{.unparsed}
+    -f -auf -n
+    @endcode
+
+  <li>
+    Short options with arguments:
+
+    @code{.unparsed}
+    -b 45 -f/mein/file -xyzhello
+    @endcode
+
+  <li>
+    Long options without an argument:
+
+    @code{.unparsed}
+    --five-guys --burger-king --pizza-hut --subway
+    @endcode
+
+  <li>
+    Long options with arguments (two original arguments or a single
+    one with a <code>=</code> character):
+
+    @code{.unparsed}
+    --security enable --time=18.56
+    @endcode
+
+  <li>
+    Non-option arguments (anything else, including
+    <code>-</code> and <code>\--</code>).
+
+    A non-option argument cannot have the form of an option, for example
+    if you need to pass the exact relative path
+    <code>\--component</code>. In that case, you would need to pass
+    <code>./\--component</code>. There's no generic way to escape
+    <code>-</code> as of this version.
+</ul>
+
+Create a parsing iterator with argpar_iter_create(), then repeatedly
+call argpar_iter_next() to access the parsing results (items), until one
+of:
+
+- There are no more arguments.
+
+- The argument parser encounters an error (for example, an unknown
+  option).
+
+- You need to stop.
+
+argpar_iter_create() accepts duplicate option descriptors in
+\p descrs (argpar_iter_next() produces one item for each
+instance).
+
+A parsing item (the result of argpar_iter_next()) has the type
+#argpar_item.
+
+Get the type (option or non-option) of an item with
+\link argpar_item_type(const struct argpar_item *) argpar_item_type()\endlink.
+Each item type has its set of dedicated functions
+(\c argpar_item_opt_ and \c argpar_item_non_opt_ prefixes).
+
+argpar_iter_next() produces the items in the same order that it parses
+original arguments, including non-option arguments. This means, for
+example, that for:
+
+@code{.unparsed}
+--hello --count=23 /path/to/file -ab --type file -- magie
+@endcode
+
+argpar_iter_next() produces the following items, in this order:
+
+-# Option item (<code>\--hello</code>).
+-# Option item (<code>\--count</code> with argument <code>23</code>).
+-# Non-option item (<code>/path/to/file</code>).
+-# Option item (<code>-a</code>).
+-# Option item (<code>-b</code>).
+-# Option item (<code>\--type</code> with argument <code>file</code>).
+-# Non-option item (<code>\--</code>).
+-# Non-option item (<code>magie</code>).
+*/
+
+/*
+ * If argpar is used in some shared library, we don't want said library
+ * to export its symbols, so mark them as "hidden".
+ *
+ * On Windows, symbols are local unless explicitly exported; see
+ * <https://gcc.gnu.org/wiki/Visibility>.
+ */
+#if defined(_WIN32) || defined(__CYGWIN__)
+#define ARGPAR_HIDDEN
+#else
+#define ARGPAR_HIDDEN __attribute__((visibility("hidden")))
+#endif
+
+struct argpar_opt_descr;
+
+/*!
+@name Item API
+@{
+*/
+
+/*!
+@brief
+    Type of a parsing item, as returned by
+    \link argpar_item_type(const struct argpar_item *) argpar_item_type()\endlink.
+*/
+enum argpar_item_type {
+       /// Option
+       ARGPAR_ITEM_TYPE_OPT,
+
+       /// Non-option
+       ARGPAR_ITEM_TYPE_NON_OPT,
+};
+
+/*!
+@struct argpar_item
+
+@brief
+    Opaque parsing item type
+
+argpar_iter_next() sets a pointer to such a type.
+*/
+struct argpar_item;
+
+/*!
+@brief
+    Returns the type of the parsing item \p item.
+
+@param[in] item
+    Parsing item of which to get the type.
+
+@returns
+    Type of \p item.
+
+@pre
+    \p item is not \c NULL.
+*/
+/// @cond hidden_macro
+ARGPAR_HIDDEN
+/// @endcond
+enum argpar_item_type argpar_item_type(const struct argpar_item *item);
+
+/*!
+@brief
+    Returns the option descriptor of the option parsing item \p item.
+
+@param[in] item
+    Option parsing item of which to get the option descriptor.
+
+@returns
+    Option descriptor of \p item.
+
+@pre
+    \p item is not \c NULL.
+@pre
+    \p item has the type #ARGPAR_ITEM_TYPE_OPT.
+*/
+/// @cond hidden_macro
+ARGPAR_HIDDEN
+/// @endcond
+const struct argpar_opt_descr *argpar_item_opt_descr(const struct argpar_item *item);
+
+/*!
+@brief
+    Returns the argument of the option parsing item \p item, or
+    \c NULL if none.
+
+@param[in] item
+    Option parsing item of which to get the argument.
+
+@returns
+    Argument of \p item, or \c NULL if none.
+
+@pre
+    \p item is not \c NULL.
+@pre
+    \p item has the type #ARGPAR_ITEM_TYPE_OPT.
+*/
+/// @cond hidden_macro
+ARGPAR_HIDDEN
+/// @endcond
+const char *argpar_item_opt_arg(const struct argpar_item *item);
+
+/*!
+@brief
+    Returns the complete original argument, pointing to one of the
+    entries of the original arguments (in \p argv, as passed to
+    argpar_iter_create()), of the non-option parsing item \p item.
+
+@param[in] item
+    Non-option parsing item of which to get the complete original
+    argument.
+
+@returns
+    Complete original argument of \p item.
+
+@pre
+    \p item is not \c NULL.
+@pre
+    \p item has the type #ARGPAR_ITEM_TYPE_NON_OPT.
+*/
+/// @cond hidden_macro
+ARGPAR_HIDDEN
+/// @endcond
+const char *argpar_item_non_opt_arg(const struct argpar_item *item);
+
+/*!
+@brief
+    Returns the index, within \em all the original arguments (in
+    \p argv, as passed to argpar_iter_create()), of the non-option
+    parsing item \p item.
+
+For example, with the following command line (all options have no
+argument):
+
+@code{.unparsed}
+-f -m meow --jus mix --kilo
+@endcode
+
+The original argument index of \c meow is&nbsp;2 while the original
+argument index of \c mix is&nbsp;4.
+
+@param[in] item
+    Non-option parsing item of which to get the original argument index.
+
+@returns
+    Original argument index of \p item.
+
+@pre
+    \p item is not \c NULL.
+@pre
+    \p item has the type #ARGPAR_ITEM_TYPE_NON_OPT.
+
+@sa
+    argpar_item_non_opt_non_opt_index() -- Returns the non-option index
+    of a non-option parsing item.
+*/
+/// @cond hidden_macro
+ARGPAR_HIDDEN
+/// @endcond
+unsigned int argpar_item_non_opt_orig_index(const struct argpar_item *item);
+
+/*!
+@brief
+    Returns the index, within the parsed non-option parsing items, of
+    the non-option parsing item \p item.
+
+For example, with the following command line (all options have no
+argument):
+
+@code{.unparsed}
+-f -m meow --jus mix --kilo
+@endcode
+
+The non-option index of \c meow is&nbsp;0 while the original
+argument index of \c mix is&nbsp;1.
+
+@param[in] item
+    Non-option parsing item of which to get the non-option index.
+
+@returns
+    Non-option index of \p item.
+
+@pre
+    \p item is not \c NULL.
+@pre
+    \p item has the type #ARGPAR_ITEM_TYPE_NON_OPT.
+
+@sa
+    argpar_item_non_opt_orig_index() -- Returns the original argument
+    index of a non-option parsing item.
+*/
+/// @cond hidden_macro
+ARGPAR_HIDDEN
+/// @endcond
+unsigned int argpar_item_non_opt_non_opt_index(const struct argpar_item *item);
+
+/*!
+@brief
+    Destroys the parsing item \p item.
+
+@param[in] item
+    Parsing item to destroy (may be \c NULL).
+*/
+/// @cond hidden_macro
+ARGPAR_HIDDEN
+/// @endcond
+void argpar_item_destroy(const struct argpar_item *item);
+
+/*!
+@def ARGPAR_ITEM_DESTROY_AND_RESET(_item)
+
+@brief
+    Calls argpar_item_destroy() with \p _item, and then sets \p _item
+    to \c NULL.
+
+@param[in] _item
+    Item to destroy and variable to reset
+    (<code>const struct argpar_item *</code> type).
+*/
+#define ARGPAR_ITEM_DESTROY_AND_RESET(_item) \
+       {                                    \
+               argpar_item_destroy(_item);  \
+               ((_item)) = NULL;            \
+       }
+
+/// @}
+
+/*!
+@name Error API
+@{
+*/
+
+/*!
+@brief
+    Parsing error type, as returned by
+    \link argpar_error_type(const struct argpar_error *) argpar_error_type()\endlink.
+*/
+enum argpar_error_type {
+       /// Unknown option error
+       ARGPAR_ERROR_TYPE_UNKNOWN_OPT,
+
+       /// Missing option argument error
+       ARGPAR_ERROR_TYPE_MISSING_OPT_ARG,
+
+       /// Unexpected option argument error
+       ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG,
+};
+
+/*!
+@struct argpar_error
+
+@brief
+    Opaque parsing error type
+*/
+struct argpar_error;
+
+/*!
+@brief
+    Returns the type of the parsing error object \p error.
+
+@param[in] error
+    Parsing error of which to get the type.
+
+@returns
+    Type of \p error.
+
+@pre
+    \p error is not \c NULL.
+*/
+/// @cond hidden_macro
+ARGPAR_HIDDEN
+/// @endcond
+enum argpar_error_type argpar_error_type(const struct argpar_error *error);
+
+/*!
+@brief
+    Returns the index of the original argument (in \p argv, as passed to
+    argpar_iter_create()) for which the parsing error described by
+    \p error occurred.
+
+@param[in] error
+    Parsing error of which to get the original argument index.
+
+@returns
+    Original argument index of \p error.
+
+@pre
+    \p error is not \c NULL.
+*/
+/// @cond hidden_macro
+ARGPAR_HIDDEN
+/// @endcond
+unsigned int argpar_error_orig_index(const struct argpar_error *error);
+
+/*!
+@brief
+    Returns the name of the unknown option for which the parsing error
+    described by \p error occurred.
+
+The returned name includes any <code>-</code> or <code>\--</code>
+prefix.
+
+With the long option with argument form, for example
+<code>\--mireille=deyglun</code>, this function only returns the name
+part (<code>\--mireille</code> in the last example).
+
+@param[in] error
+    Parsing error of which to get the name of the unknown option.
+
+@returns
+    Name of the unknown option of \p error.
+
+@pre
+    \p error is not \c NULL.
+@pre
+    The type of \p error, as returned by
+    \link argpar_error_type(const struct argpar_error *) argpar_error_type()\endlink,
+    is #ARGPAR_ERROR_TYPE_UNKNOWN_OPT.
+*/
+/// @cond hidden_macro
+ARGPAR_HIDDEN
+/// @endcond
+const char *argpar_error_unknown_opt_name(const struct argpar_error *error);
+
+/*!
+@brief
+    Returns the descriptor of the option for which the parsing error
+    described by \p error occurred.
+
+@param[in] error
+    Parsing error of which to get the option descriptor.
+@param[out] is_short
+    @parblock
+    If not \c NULL, this function sets \p *is_short to:
+
+    - \c true if the option for which \p error occurred is a short
+      option.
+
+    - \c false if the option for which \p error occurred is a long
+      option.
+    @endparblock
+
+@returns
+    Descriptor of the option of \p error.
+
+@pre
+    \p error is not \c NULL.
+@pre
+    The type of \p error, as returned by
+    \link argpar_error_type(const struct argpar_error *) argpar_error_type()\endlink,
+    is #ARGPAR_ERROR_TYPE_MISSING_OPT_ARG or
+    #ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG.
+*/
+/// @cond hidden_macro
+ARGPAR_HIDDEN
+/// @endcond
+const struct argpar_opt_descr *argpar_error_opt_descr(const struct argpar_error *error,
+                                                     bool *is_short);
+
+/*!
+@brief
+    Destroys the parsing error \p error.
+
+@param[in] error
+    Parsing error to destroy (may be \c NULL).
+*/
+/// @cond hidden_macro
+ARGPAR_HIDDEN
+/// @endcond
+void argpar_error_destroy(const struct argpar_error *error);
+
+/// @}
+
+/*!
+@name Iterator API
+@{
+*/
+
+/*!
+@brief
+    Option descriptor
+
+argpar_iter_create() accepts an array of instances of such a type,
+terminated with #ARGPAR_OPT_DESCR_SENTINEL, as its \p descrs parameter.
+
+The typical usage is, for example:
+
+@code
+const struct argpar_opt_descr descrs[] = {
+    { 0, 'd', NULL, false },
+    { 1, '\0', "squeeze", true },
+    { 2, 'm', "meow", true },
+    ARGPAR_OPT_DESCR_SENTINEL,
+};
+@endcode
+*/
+struct argpar_opt_descr {
+       /// Numeric ID, to uniquely identify this descriptor
+       const int id;
+
+       /// Short option character, or <code>'\0'</code>
+       const char short_name;
+
+       /// Long option name (without the <code>\--</code> prefix), or \c NULL
+       const char *const long_name;
+
+       /// \c true if this option has an argument
+       const bool with_arg;
+};
+
+/*!
+@brief
+    Sentinel for an option descriptor array
+
+The typical usage is, for example:
+
+@code
+const struct argpar_opt_descr descrs[] = {
+    { 0, 'd', NULL, false },
+    { 1, '\0', "squeeze", true },
+    { 2, 'm', "meow", true },
+    ARGPAR_OPT_DESCR_SENTINEL,
+};
+@endcode
+*/
+#define ARGPAR_OPT_DESCR_SENTINEL     \
+       {                             \
+               -1, '\0', NULL, false \
+       }
+
+/*!
+@struct argpar_iter
+
+@brief
+    Opaque argpar iterator type
+
+argpar_iter_create() returns a pointer to such a type.
+*/
+struct argpar_iter;
+
+/*!
+@brief
+    Creates and returns an argument parsing iterator to parse the
+    original arguments \p argv of which the count is \p argc using the
+    option descriptors \p descrs.
+
+This function initializes the returned structure, but doesn't actually
+start parsing the arguments.
+
+argpar considers \em all the elements of \p argv, including the first
+one, so that you would typically pass <code>(argc - 1)</code> as \p argc
+and <code>\&argv[1]</code> as \p argv from what <code>main()</code>
+receives, or ignore the parsing item of the first call to
+argpar_iter_next().
+
+\p *argv and \p *descrs must \em not change for all of:
+
+- The lifetime of the returned iterator (until you call
+  argpar_iter_destroy()).
+
+- The lifetime of any parsing item (until you call
+  argpar_item_destroy()) which argpar_iter_next() creates from the
+  returned iterator.
+
+- The lifetime of any parsing error (until you call
+  argpar_error_destroy()) which argpar_iter_next() creates from the
+  returned iterator.
+
+@param[in] argc
+    Number of original arguments to parse in \p argv.
+@param[in] argv
+    Original arguments to parse, of which the count is \p argc.
+@param[in] descrs
+    @parblock
+    Option descriptor array, terminated with #ARGPAR_OPT_DESCR_SENTINEL.
+
+    May contain duplicate entries.
+    @endparblock
+
+@returns
+    New argument parsing iterator, or \c NULL on memory error.
+
+@pre
+    \p argc is greater than 0.
+@pre
+    \p argv is not \c NULL.
+@pre
+    The first \p argc elements of \p argv are not \c NULL.
+@pre
+    \p descrs is not \c NULL.
+
+@sa
+    argpar_iter_destroy() -- Destroys an argument parsing iterator.
+*/
+/// @cond hidden_macro
+ARGPAR_HIDDEN
+/// @endcond
+struct argpar_iter *argpar_iter_create(unsigned int argc,
+                                      const char *const *argv,
+                                      const struct argpar_opt_descr *descrs);
+
+/*!
+@brief
+    Destroys the argument parsing iterator \p iter.
+
+@param[in] iter
+    Argument parsing iterator to destroy (may be \c NULL).
+
+@sa
+    argpar_iter_create() -- Creates an argument parsing iterator.
+*/
+/// @cond hidden_macro
+ARGPAR_HIDDEN
+/// @endcond
+void argpar_iter_destroy(struct argpar_iter *iter);
+
+/*!
+@brief
+    Return type of argpar_iter_next().
+
+Error status enumerators have a negative value.
+*/
+enum argpar_iter_next_status {
+       /// Success
+       ARGPAR_ITER_NEXT_STATUS_OK,
+
+       /// End of iteration (no more original arguments to parse)
+       ARGPAR_ITER_NEXT_STATUS_END,
+
+       /// Parsing error
+       ARGPAR_ITER_NEXT_STATUS_ERROR = -1,
+
+       /// Memory error
+       ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY = -12,
+};
+
+/*!
+@brief
+    Sets \p *item to the next item of the argument parsing iterator
+    \p iter and advances \p iter.
+
+If there are no more original arguments to parse, this function returns
+#ARGPAR_ITER_NEXT_STATUS_END.
+
+@param[in] iter
+    Argument parsing iterator from which to get the next parsing item.
+@param[out] item
+    @parblock
+    On success, \p *item is the next parsing item of \p iter.
+
+    Destroy \p *item with argpar_item_destroy().
+    @endparblock
+@param[out] error
+    @parblock
+    When this function returns #ARGPAR_ITER_NEXT_STATUS_ERROR,
+    if this parameter is not \c NULL, \p *error contains details about
+    the error.
+
+    Destroy \p *error with argpar_error_destroy().
+    @endparblock
+
+@returns
+    Status code.
+
+@pre
+    \p iter is not \c NULL.
+@pre
+    \p item is not \c NULL.
+*/
+/// @cond hidden_macro
+ARGPAR_HIDDEN
+/// @endcond
+enum argpar_iter_next_status argpar_iter_next(struct argpar_iter *iter,
+                                             const struct argpar_item **item,
+                                             const struct argpar_error **error);
+
+/*
+ * Returns the number of ingested elements from `argv`, as passed to
+ * argpar_iter_create() to create `*iter`, that were required to produce
+ * the previously returned items.
+ */
+
+/*!
+@brief
+    Returns the number of ingested original arguments (in
+    \p argv, as passed to argpar_iter_create() to create \p iter) that
+    the parser ingested to produce the \em previous parsing items.
+
+@param[in] iter
+    Argument parsing iterator of which to get the number of ingested
+    original arguments.
+
+@returns
+    Number of original arguments which \p iter ingested.
+
+@pre
+    \p iter is not \c NULL.
+*/
+/// @cond hidden_macro
+ARGPAR_HIDDEN
+/// @endcond
+unsigned int argpar_iter_ingested_orig_args(const struct argpar_iter *iter);
+
+/// @}
+
+/// @}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ARGPAR_ARGPAR_H */
This page took 0.05491 seconds and 4 git commands to generate.