2 * SPDX-License-Identifier: MIT
4 * Copyright (c) 2019-2021 Philippe Proulx <pproulx@efficios.com>
5 * Copyright (c) 2020-2021 Simon Marchi <simon.marchi@efficios.com>
8 #ifndef ARGPAR_ARGPAR_H
9 #define ARGPAR_ARGPAR_H
13 #if defined(__cplusplus)
20 See the \ref api module.
22 @addtogroup api argpar API
25 argpar is a library which provides an iterator-based API to parse
26 command-line arguments.
28 The argpar parser supports:
32 Short options without an argument, possibly tied together:
39 Short options with arguments:
42 -b 45 -f/mein/file -xyzhello
46 Long options without an argument:
49 --five-guys --burger-king --pizza-hut --subway
53 Long options with arguments (two original arguments or a single
54 one with a <code>=</code> character):
57 --security enable --time=18.56
61 Non-option arguments (anything else, including
62 <code>-</code> and <code>\--</code>).
64 A non-option argument cannot have the form of an option, for example
65 if you need to pass the exact relative path
66 <code>\--component</code>. In that case, you would need to pass
67 <code>./\--component</code>. There's no generic way to escape
68 <code>-</code> as of this version.
71 Create a parsing iterator with argpar_iter_create(), then repeatedly
72 call argpar_iter_next() to access the parsing results (items), until one
75 - There are no more arguments.
77 - The argument parser encounters an error (for example, an unknown
82 argpar_iter_create() accepts duplicate option descriptors in
83 \p descrs (argpar_iter_next() produces one item for each
86 A parsing item (the result of argpar_iter_next()) has the type
89 Get the type (option or non-option) of an item with
90 \link argpar_item_type(const argpar_item_t *) argpar_item_type()\endlink.
91 Each item type has its set of dedicated functions
92 (\c argpar_item_opt_ and \c argpar_item_non_opt_ prefixes).
94 argpar_iter_next() produces the items in the same order that it parses
95 original arguments, including non-option arguments. This means, for
99 --hello --count=23 /path/to/file -ab --type file -- magie
102 argpar_iter_next() produces the following items, in this order:
104 -# Option item: <code>\--hello</code>.
105 -# Option item: <code>\--count</code> with argument <code>23</code>.
106 -# Non-option item: <code>/path/to/file</code>.
107 -# Option item: <code>-a</code>.
108 -# Option item: <code>-b</code>.
109 -# Option item: <code>\--type</code> with argument <code>file</code>.
110 -# Non-option item: <code>\--</code>.
111 -# Non-option item: <code>magie</code>.
115 * If argpar is used in some shared library, we don't want said library
116 * to export its symbols, so mark them as "hidden".
118 * On Windows, symbols are local unless explicitly exported; see
119 * <https://gcc.gnu.org/wiki/Visibility>.
121 #if defined(_WIN32) || defined(__CYGWIN__)
122 # define ARGPAR_HIDDEN
124 # define ARGPAR_HIDDEN __attribute__((visibility("hidden")))
127 /* Internal: `noexcept` specifier if C++ ≥ 11 */
128 #if defined(__cplusplus) && (__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900))
129 # define ARGPAR_NOEXCEPT noexcept
131 # define ARGPAR_NOEXCEPT
134 typedef struct argpar_opt_descr argpar_opt_descr_t
;
143 Type of a parsing item, as returned by
144 \link argpar_item_type(const argpar_item *) argpar_item_type()\endlink.
146 typedef enum argpar_item_type
{
148 ARGPAR_ITEM_TYPE_OPT
,
151 ARGPAR_ITEM_TYPE_NON_OPT
,
152 } argpar_item_type_t
;
158 Opaque parsing item type
160 argpar_iter_next() sets a pointer to such a type.
162 typedef struct argpar_item argpar_item_t
;
166 Returns the type of the parsing item \p item.
169 Parsing item of which to get the type.
175 \p item is not \c NULL.
177 /// @cond hidden_macro
180 argpar_item_type_t
argpar_item_type(const argpar_item_t
*item
) ARGPAR_NOEXCEPT
;
184 Returns the option descriptor of the option parsing item \p item.
187 Option parsing item of which to get the option descriptor.
190 Option descriptor of \p item.
193 \p item is not \c NULL.
195 \p item has the type #ARGPAR_ITEM_TYPE_OPT.
197 /// @cond hidden_macro
200 const argpar_opt_descr_t
*argpar_item_opt_descr(
201 const argpar_item_t
*item
) ARGPAR_NOEXCEPT
;
205 Returns the argument of the option parsing item \p item, or
209 Option parsing item of which to get the argument.
212 Argument of \p item, or \c NULL if none.
215 \p item is not \c NULL.
217 \p item has the type #ARGPAR_ITEM_TYPE_OPT.
219 /// @cond hidden_macro
222 const char *argpar_item_opt_arg(const argpar_item_t
*item
) ARGPAR_NOEXCEPT
;
226 Returns the complete original argument, pointing to one of the
227 entries of the original arguments (in \p argv, as passed to
228 argpar_iter_create()), of the non-option parsing item \p item.
231 Non-option parsing item of which to get the complete original
235 Complete original argument of \p item.
238 \p item is not \c NULL.
240 \p item has the type #ARGPAR_ITEM_TYPE_NON_OPT.
242 /// @cond hidden_macro
245 const char *argpar_item_non_opt_arg(
246 const argpar_item_t
*item
) ARGPAR_NOEXCEPT
;
250 Returns the index, within \em all the original arguments (in
251 \p argv, as passed to argpar_iter_create()), of the non-option
252 parsing item \p item.
254 For example, with the following command line (all options have no
258 -f -m meow --jus mix --kilo
261 The original argument index of \c meow is 2 while the original
262 argument index of \c mix is 4.
265 Non-option parsing item of which to get the original argument index.
268 Original argument index of \p item.
271 \p item is not \c NULL.
273 \p item has the type #ARGPAR_ITEM_TYPE_NON_OPT.
276 argpar_item_non_opt_non_opt_index() -- Returns the non-option index
277 of a non-option parsing item.
279 /// @cond hidden_macro
282 unsigned int argpar_item_non_opt_orig_index(
283 const argpar_item_t
*item
) ARGPAR_NOEXCEPT
;
287 Returns the index, within the parsed non-option parsing items, of
288 the non-option parsing item \p item.
290 For example, with the following command line (all options have no
294 -f -m meow --jus mix --kilo
297 The non-option index of \c meow is 0 while the original
298 argument index of \c mix is 1.
301 Non-option parsing item of which to get the non-option index.
304 Non-option index of \p item.
307 \p item is not \c NULL.
309 \p item has the type #ARGPAR_ITEM_TYPE_NON_OPT.
312 argpar_item_non_opt_orig_index() -- Returns the original argument
313 index of a non-option parsing item.
315 /// @cond hidden_macro
318 unsigned int argpar_item_non_opt_non_opt_index(
319 const argpar_item_t
*item
) ARGPAR_NOEXCEPT
;
323 Destroys the parsing item \p item.
326 Parsing item to destroy (may be \c NULL).
328 /// @cond hidden_macro
331 void argpar_item_destroy(const argpar_item_t
*item
) ARGPAR_NOEXCEPT
;
334 @def ARGPAR_ITEM_DESTROY_AND_RESET(_item)
337 Calls argpar_item_destroy() with \p _item, and then sets \p _item
341 Item to destroy and variable to reset
342 (<code>const argpar_item_t *</code> type).
344 #define ARGPAR_ITEM_DESTROY_AND_RESET(_item) \
346 argpar_item_destroy(_item); \
359 Parsing error type, as returned by
360 \link argpar_error_type(const argpar_error_t *) argpar_error_type()\endlink.
362 typedef enum argpar_error_type
{
363 /// Unknown option error
364 ARGPAR_ERROR_TYPE_UNKNOWN_OPT
,
366 /// Missing option argument error
367 ARGPAR_ERROR_TYPE_MISSING_OPT_ARG
,
369 /// Unexpected option argument error
370 ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG
,
371 } argpar_error_type_t
;
377 Opaque parsing error type
379 typedef struct argpar_error argpar_error_t
;
383 Returns the type of the parsing error object \p error.
386 Parsing error of which to get the type.
392 \p error is not \c NULL.
394 /// @cond hidden_macro
397 argpar_error_type_t
argpar_error_type(
398 const argpar_error_t
*error
) ARGPAR_NOEXCEPT
;
402 Returns the index of the original argument (in \p argv, as passed to
403 argpar_iter_create()) for which the parsing error described by
407 Parsing error of which to get the original argument index.
410 Original argument index of \p error.
413 \p error is not \c NULL.
415 /// @cond hidden_macro
418 unsigned int argpar_error_orig_index(
419 const argpar_error_t
*error
) ARGPAR_NOEXCEPT
;
423 Returns the name of the unknown option for which the parsing error
424 described by \p error occurred.
426 The returned name includes any <code>-</code> or <code>\--</code>
429 With the long option with argument form, for example
430 <code>\--mireille=deyglun</code>, this function only returns the name
431 part (<code>\--mireille</code> in the last example).
434 Parsing error of which to get the name of the unknown option.
437 Name of the unknown option of \p error.
440 \p error is not \c NULL.
442 The type of \p error, as returned by
443 \link argpar_error_type(const argpar_error_t *) argpar_error_type()\endlink,
444 is #ARGPAR_ERROR_TYPE_UNKNOWN_OPT.
446 /// @cond hidden_macro
449 const char *argpar_error_unknown_opt_name(
450 const argpar_error_t
*error
) ARGPAR_NOEXCEPT
;
454 Returns the descriptor of the option for which the parsing error
455 described by \p error occurred.
458 Parsing error of which to get the option descriptor.
461 If not \c NULL, this function sets \p *is_short to:
463 - \c true if the option for which \p error occurred is a short
466 - \c false if the option for which \p error occurred is a long
471 Descriptor of the option of \p error.
474 \p error is not \c NULL.
476 The type of \p error, as returned by
477 \link argpar_error_type(const argpar_error_t *) argpar_error_type()\endlink,
478 is #ARGPAR_ERROR_TYPE_MISSING_OPT_ARG or
479 #ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG.
481 /// @cond hidden_macro
484 const argpar_opt_descr_t
*argpar_error_opt_descr(const argpar_error_t
*error
,
485 bool *is_short
) ARGPAR_NOEXCEPT
;
489 Destroys the parsing error \p error.
492 Parsing error to destroy (may be \c NULL).
494 /// @cond hidden_macro
497 void argpar_error_destroy(const argpar_error_t
*error
) ARGPAR_NOEXCEPT
;
510 argpar_iter_create() accepts an array of instances of such a type,
511 terminated with #ARGPAR_OPT_DESCR_SENTINEL, as its \p descrs parameter.
513 The typical usage is, for example:
516 const argpar_opt_descr_t descrs[] = {
517 { 0, 'd', NULL, false },
518 { 1, '\0', "squeeze", true },
519 { 2, 'm', "meow", true },
520 ARGPAR_OPT_DESCR_SENTINEL,
524 typedef struct argpar_opt_descr
{
525 /// Numeric ID, to uniquely identify this descriptor
528 /// Short option character, or <code>'\0'</code>
529 const char short_name
;
531 /// Long option name (without the <code>\--</code> prefix), or \c NULL
532 const char * const long_name
;
534 /// \c true if this option has an argument
536 } argpar_opt_descr_t
;
540 Sentinel for an option descriptor array
542 The typical usage is, for example:
545 const argpar_opt_descr_t descrs[] = {
546 { 0, 'd', NULL, false },
547 { 1, '\0', "squeeze", true },
548 { 2, 'm', "meow", true },
549 ARGPAR_OPT_DESCR_SENTINEL,
553 #define ARGPAR_OPT_DESCR_SENTINEL { -1, '\0', NULL, false }
559 Opaque argpar iterator type
561 argpar_iter_create() returns a pointer to such a type.
563 typedef struct argpar_iter argpar_iter_t
;
567 Creates and returns an argument parsing iterator to parse the
568 original arguments \p argv of which the count is \p argc using the
569 option descriptors \p descrs.
571 This function initializes the returned structure, but doesn't actually
572 start parsing the arguments.
574 argpar considers \em all the elements of \p argv, including the first
575 one, so that you would typically pass <code>(argc - 1)</code> as \p argc
576 and <code>\&argv[1]</code> as \p argv from what <code>main()</code>
577 receives, or ignore the parsing item of the first call to
580 \p *argv and \p *descrs must \em not change for all of:
582 - The lifetime of the returned iterator (until you call
583 argpar_iter_destroy()).
585 - The lifetime of any parsing item (until you call
586 argpar_item_destroy()) which argpar_iter_next() creates from the
589 - The lifetime of any parsing error (until you call
590 argpar_error_destroy()) which argpar_iter_next() creates from the
594 Number of original arguments to parse in \p argv.
596 Original arguments to parse, of which the count is \p argc.
599 Option descriptor array, terminated with #ARGPAR_OPT_DESCR_SENTINEL.
601 May contain duplicate entries.
605 New argument parsing iterator, or \c NULL on memory error.
608 \p argc is greater than 0.
610 \p argv is not \c NULL.
612 The first \p argc elements of \p argv are not \c NULL.
614 \p descrs is not \c NULL.
617 argpar_iter_destroy() -- Destroys an argument parsing iterator.
619 /// @cond hidden_macro
622 argpar_iter_t
*argpar_iter_create(unsigned int argc
, const char * const *argv
,
623 const argpar_opt_descr_t
*descrs
) ARGPAR_NOEXCEPT
;
627 Destroys the argument parsing iterator \p iter.
630 Argument parsing iterator to destroy (may be \c NULL).
633 argpar_iter_create() -- Creates an argument parsing iterator.
635 /// @cond hidden_macro
638 void argpar_iter_destroy(argpar_iter_t
*iter
) ARGPAR_NOEXCEPT
;
642 Return type of argpar_iter_next().
644 Error status enumerators have a negative value.
646 typedef enum argpar_iter_next_status
{
648 ARGPAR_ITER_NEXT_STATUS_OK
,
650 /// End of iteration (no more original arguments to parse)
651 ARGPAR_ITER_NEXT_STATUS_END
,
654 ARGPAR_ITER_NEXT_STATUS_ERROR
= -1,
657 ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY
= -12,
658 } argpar_iter_next_status_t
;
662 Sets \p *item to the next item of the argument parsing iterator
663 \p iter and advances \p iter.
665 If there are no more original arguments to parse, this function returns
666 #ARGPAR_ITER_NEXT_STATUS_END.
669 Argument parsing iterator from which to get the next parsing item.
672 On success, \p *item is the next parsing item of \p iter.
674 Destroy \p *item with argpar_item_destroy().
678 When this function returns #ARGPAR_ITER_NEXT_STATUS_ERROR,
679 if this parameter is not \c NULL, \p *error contains details about
682 Destroy \p *error with argpar_error_destroy().
689 \p iter is not \c NULL.
691 \p item is not \c NULL.
693 /// @cond hidden_macro
696 argpar_iter_next_status_t
argpar_iter_next(argpar_iter_t
*iter
,
697 const argpar_item_t
**item
,
698 const argpar_error_t
**error
) ARGPAR_NOEXCEPT
;
701 * Returns the number of ingested elements from `argv`, as passed to
702 * argpar_iter_create() to create `*iter`, that were required to produce
703 * the previously returned items.
708 Returns the number of ingested original arguments (in
709 \p argv, as passed to argpar_iter_create() to create \p iter) that
710 the parser ingested to produce the \em previous parsing items.
713 Argument parsing iterator of which to get the number of ingested
717 Number of original arguments which \p iter ingested.
720 \p iter is not \c NULL.
722 /// @cond hidden_macro
725 unsigned int argpar_iter_ingested_orig_args(
726 const argpar_iter_t
*iter
) ARGPAR_NOEXCEPT
;
732 #if defined(__cplusplus)
736 #endif /* ARGPAR_ARGPAR_H */