+-# 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>.
+*/
+
+/* Internal: `noexcept` specifier if C++ ≥ 11 */
+#if defined(__cplusplus) && (__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900))
+# define ARGPAR_NOEXCEPT noexcept
+#else
+# define ARGPAR_NOEXCEPT
+#endif
+
+typedef struct argpar_opt_descr argpar_opt_descr_t;
+
+/*!
+@name Item API
+@{
+*/
+
+/*!
+@brief
+ Type of a parsing item, as returned by
+ \link argpar_item_type(const argpar_item *) argpar_item_type()\endlink.
+*/
+typedef enum argpar_item_type
+{
+ /// Option
+ ARGPAR_ITEM_TYPE_OPT,
+
+ /// Non-option
+ ARGPAR_ITEM_TYPE_NON_OPT,
+} argpar_item_type_t;
+
+/*!
+@struct argpar_item
+
+@brief
+ Opaque parsing item type
+
+argpar_iter_next() sets a pointer to such a type.
+*/
+typedef struct argpar_item argpar_item_t;
+
+/*!
+@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.
+*/
+argpar_item_type_t argpar_item_type(const argpar_item_t *item) ARGPAR_NOEXCEPT;
+
+/*!
+@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.
+*/
+const argpar_opt_descr_t *argpar_item_opt_descr(const argpar_item_t *item) ARGPAR_NOEXCEPT;
+
+/*!
+@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.
+*/
+const char *argpar_item_opt_arg(const argpar_item_t *item) ARGPAR_NOEXCEPT;
+
+/*!
+@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.
+*/
+const char *argpar_item_non_opt_arg(const argpar_item_t *item) ARGPAR_NOEXCEPT;
+
+/*!
+@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 2 while the original
+argument index of \c mix is 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.
+*/
+unsigned int argpar_item_non_opt_orig_index(const argpar_item_t *item) ARGPAR_NOEXCEPT;
+
+/*!
+@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 0 while the original
+argument index of \c mix is 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.
+*/
+unsigned int argpar_item_non_opt_non_opt_index(const argpar_item_t *item) ARGPAR_NOEXCEPT;
+
+/*!
+@brief
+ Destroys the parsing item \p item.
+
+@param[in] item
+ Parsing item to destroy (may be \c NULL).
+*/
+void argpar_item_destroy(const argpar_item_t *item) ARGPAR_NOEXCEPT;
+
+/*!
+@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 argpar_item_t *</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 argpar_error_t *) argpar_error_type()\endlink.
+*/
+typedef 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,
+} argpar_error_type_t;
+
+/*!
+@struct argpar_error
+
+@brief
+ Opaque parsing error type
+*/
+typedef struct argpar_error argpar_error_t;
+
+/*!
+@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.
+*/
+argpar_error_type_t argpar_error_type(const argpar_error_t *error) ARGPAR_NOEXCEPT;
+
+/*!
+@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.
+*/
+unsigned int argpar_error_orig_index(const argpar_error_t *error) ARGPAR_NOEXCEPT;
+
+/*!
+@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 argpar_error_t *) argpar_error_type()\endlink,
+ is #ARGPAR_ERROR_TYPE_UNKNOWN_OPT.
+*/
+const char *argpar_error_unknown_opt_name(const argpar_error_t *error) ARGPAR_NOEXCEPT;
+
+/*!
+@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 argpar_error_t *) argpar_error_type()\endlink,
+ is #ARGPAR_ERROR_TYPE_MISSING_OPT_ARG or
+ #ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG.
+*/
+const argpar_opt_descr_t *argpar_error_opt_descr(const argpar_error_t *error,
+ bool *is_short) ARGPAR_NOEXCEPT;
+
+/*!
+@brief
+ Destroys the parsing error \p error.
+
+@param[in] error
+ Parsing error to destroy (may be \c NULL).
+*/
+void argpar_error_destroy(const argpar_error_t *error) ARGPAR_NOEXCEPT;
+
+/// @}
+
+/*!
+@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 argpar_opt_descr_t descrs[] = {
+ { 0, 'd', NULL, false },
+ { 1, '\0', "squeeze", true },
+ { 2, 'm', "meow", true },
+ ARGPAR_OPT_DESCR_SENTINEL,
+};
+@endcode
+*/
+typedef 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;
+} argpar_opt_descr_t;
+
+/*!
+@brief
+ Sentinel for an option descriptor array
+
+The typical usage is, for example:
+
+@code
+const argpar_opt_descr_t 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.
+*/
+typedef struct argpar_iter argpar_iter_t;
+
+/*!
+@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.
+*/
+argpar_iter_t *argpar_iter_create(unsigned int argc, const char * const *argv,
+ const argpar_opt_descr_t *descrs) ARGPAR_NOEXCEPT;
+
+/*!
+@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.
+*/
+void argpar_iter_destroy(argpar_iter_t *iter) ARGPAR_NOEXCEPT;
+
+/*!
+@brief
+ Return type of argpar_iter_next().
+
+Error status enumerators have a negative value.
+*/
+typedef 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,
+} argpar_iter_next_status_t;
+
+/*!
+@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.
+*/
+argpar_iter_next_status_t argpar_iter_next(argpar_iter_t *iter, const argpar_item_t **item,
+ const argpar_error_t **error) ARGPAR_NOEXCEPT;