Force usage of ARGPAR_ASSERT() condition when NDEBUG is defined
[argpar.git] / argpar / argpar.h
CommitLineData
903a5b8a 1/*
03e1579f 2 * SPDX-License-Identifier: MIT
903a5b8a 3 *
fc07e526
SM
4 * Copyright (c) 2019-2021 Philippe Proulx <pproulx@efficios.com>
5 * Copyright (c) 2020-2021 Simon Marchi <simon.marchi@efficios.com>
903a5b8a
SM
6 */
7
fe5a18f8
PP
8#ifndef ARGPAR_ARGPAR_H
9#define ARGPAR_ARGPAR_H
03e1579f 10
903a5b8a
SM
11#include <stdbool.h>
12
9e2c879b
PP
13/*!
14@mainpage
fc07e526 15
9e2c879b
PP
16See the \ref api module.
17
18@addtogroup api argpar API
19@{
20
21argpar is a library which provides an iterator-based API to parse
22command-line arguments.
23
24The argpar parser supports:
25
26<ul>
27 <li>
28 Short options without an argument, possibly tied together:
29
30 @code{.unparsed}
31 -f -auf -n
32 @endcode
33
34 <li>
35 Short options with arguments:
36
37 @code{.unparsed}
38 -b 45 -f/mein/file -xyzhello
39 @endcode
40
41 <li>
42 Long options without an argument:
43
44 @code{.unparsed}
45 --five-guys --burger-king --pizza-hut --subway
46 @endcode
47
48 <li>
49 Long options with arguments (two original arguments or a single
50 one with a <code>=</code> character):
51
52 @code{.unparsed}
53 --security enable --time=18.56
54 @endcode
55
56 <li>
57 Non-option arguments (anything else, including
58 <code>-</code> and <code>\--</code>).
59
60 A non-option argument cannot have the form of an option, for example
61 if you need to pass the exact relative path
62 <code>\--component</code>. In that case, you would need to pass
63 <code>./\--component</code>. There's no generic way to escape
64 <code>-</code> as of this version.
65</ul>
66
67Create a parsing iterator with argpar_iter_create(), then repeatedly
68call argpar_iter_next() to access the parsing results (items), until one
69of:
70
71- There are no more arguments.
72
73- The argument parser encounters an error (for example, an unknown
74 option).
75
76- You need to stop.
77
78argpar_iter_create() accepts duplicate option descriptors in
79\p descrs (argpar_iter_next() produces one item for each
80instance).
81
82A parsing item (the result of argpar_iter_next()) has the type
83#argpar_item.
84
85Get the type (option or non-option) of an item with
1c881812
PP
86\link argpar_item_type(const struct argpar_item *) argpar_item_type()\endlink.
87Each item type has its set of dedicated functions
9e2c879b
PP
88(\c argpar_item_opt_ and \c argpar_item_non_opt_ prefixes).
89
90argpar_iter_next() produces the items in the same order that it parses
91original arguments, including non-option arguments. This means, for
92example, that for:
93
94@code{.unparsed}
95--hello --count=23 /path/to/file -ab --type file -- magie
96@endcode
97
98argpar_iter_next() produces the following items, in this order:
99
100-# Option item (<code>\--hello</code>).
101-# Option item (<code>\--count</code> with argument <code>23</code>).
102-# Non-option item (<code>/path/to/file</code>).
103-# Option item (<code>-a</code>).
104-# Option item (<code>-b</code>).
105-# Option item (<code>\--type</code> with argument <code>file</code>).
106-# Non-option item (<code>\--</code>).
107-# Non-option item (<code>magie</code>).
108*/
903a5b8a 109
7ac57709 110/*
fb12ac67
PP
111 * If argpar is used in some shared library, we don't want said library
112 * to export its symbols, so mark them as "hidden".
7ac57709 113 *
fc07e526
SM
114 * On Windows, symbols are local unless explicitly exported; see
115 * <https://gcc.gnu.org/wiki/Visibility>.
7ac57709
SM
116 */
117#if defined(_WIN32) || defined(__CYGWIN__)
fb12ac67 118# define ARGPAR_HIDDEN
7ac57709 119#else
fb12ac67 120# define ARGPAR_HIDDEN __attribute__((visibility("hidden")))
7ac57709
SM
121#endif
122
9e2c879b 123struct argpar_opt_descr;
903a5b8a 124
9e2c879b
PP
125/*!
126@name Item API
127@{
128*/
903a5b8a 129
9e2c879b
PP
130/*!
131@brief
1c881812
PP
132 Type of a parsing item, as returned by
133 \link argpar_item_type(const struct argpar_item *) argpar_item_type()\endlink.
9e2c879b 134*/
1c9a6bde 135enum argpar_item_type {
9e2c879b 136 /// Option
1c9a6bde 137 ARGPAR_ITEM_TYPE_OPT,
903a5b8a 138
9e2c879b 139 /// Non-option
1c9a6bde 140 ARGPAR_ITEM_TYPE_NON_OPT,
903a5b8a
SM
141};
142
9e2c879b
PP
143/*!
144@struct argpar_item
145
146@brief
147 Opaque parsing item type
148
149argpar_iter_next() sets a pointer to such a type.
150*/
d4539a90 151struct argpar_item;
903a5b8a 152
9e2c879b
PP
153/*!
154@brief
155 Returns the type of the parsing item \p item.
156
157@param[in] item
158 Parsing item of which to get the type.
159
160@returns
161 Type of \p item.
162
163@pre
164 \p item is not \c NULL.
165*/
166/// @cond hidden_macro
d4539a90 167ARGPAR_HIDDEN
9e2c879b 168/// @endcond
d4539a90 169enum argpar_item_type argpar_item_type(const struct argpar_item *item);
903a5b8a 170
9e2c879b
PP
171/*!
172@brief
173 Returns the option descriptor of the option parsing item \p item.
174
175@param[in] item
176 Option parsing item of which to get the option descriptor.
177
178@returns
179 Option descriptor of \p item.
180
181@pre
182 \p item is not \c NULL.
183@pre
184 \p item has the type #ARGPAR_ITEM_TYPE_OPT.
185*/
186/// @cond hidden_macro
d4539a90 187ARGPAR_HIDDEN
9e2c879b 188/// @endcond
d4539a90
PP
189const struct argpar_opt_descr *argpar_item_opt_descr(
190 const struct argpar_item *item);
903a5b8a 191
9e2c879b
PP
192/*!
193@brief
194 Returns the argument of the option parsing item \p item, or
195 \c NULL if none.
196
197@param[in] item
198 Option parsing item of which to get the argument.
199
200@returns
201 Argument of \p item, or \c NULL if none.
202
203@pre
204 \p item is not \c NULL.
205@pre
206 \p item has the type #ARGPAR_ITEM_TYPE_OPT.
207*/
208/// @cond hidden_macro
d4539a90 209ARGPAR_HIDDEN
9e2c879b 210/// @endcond
d4539a90 211const char *argpar_item_opt_arg(const struct argpar_item *item);
903a5b8a 212
9e2c879b
PP
213/*!
214@brief
215 Returns the complete original argument, pointing to one of the
8b95d883 216 entries of the original arguments (in \p argv, as passed to
9e2c879b
PP
217 argpar_iter_create()), of the non-option parsing item \p item.
218
219@param[in] item
220 Non-option parsing item of which to get the complete original
221 argument.
222
223@returns
224 Complete original argument of \p item.
225
226@pre
227 \p item is not \c NULL.
228@pre
229 \p item has the type #ARGPAR_ITEM_TYPE_NON_OPT.
230*/
231/// @cond hidden_macro
d4539a90 232ARGPAR_HIDDEN
9e2c879b 233/// @endcond
d4539a90 234const char *argpar_item_non_opt_arg(const struct argpar_item *item);
903a5b8a 235
9e2c879b
PP
236/*!
237@brief
8b95d883
PP
238 Returns the index, within \em all the original arguments (in
239 \p argv, as passed to argpar_iter_create()), of the non-option
240 parsing item \p item.
9e2c879b
PP
241
242For example, with the following command line (all options have no
243argument):
244
245@code{.unparsed}
246-f -m meow --jus mix --kilo
247@endcode
248
249The original argument index of \c meow is&nbsp;2 while the original
250argument index of \c mix is&nbsp;4.
251
252@param[in] item
253 Non-option parsing item of which to get the original argument index.
254
255@returns
256 Original argument index of \p item.
257
258@pre
259 \p item is not \c NULL.
260@pre
261 \p item has the type #ARGPAR_ITEM_TYPE_NON_OPT.
262
263@sa
264 argpar_item_non_opt_non_opt_index() -- Returns the non-option index
265 of a non-option parsing item.
266*/
267/// @cond hidden_macro
d4539a90 268ARGPAR_HIDDEN
9e2c879b 269/// @endcond
d4539a90 270unsigned int argpar_item_non_opt_orig_index(const struct argpar_item *item);
903a5b8a 271
9e2c879b
PP
272/*!
273@brief
274 Returns the index, within the parsed non-option parsing items, of
275 the non-option parsing item \p item.
276
277For example, with the following command line (all options have no
278argument):
279
280@code{.unparsed}
281-f -m meow --jus mix --kilo
282@endcode
283
284The non-option index of \c meow is&nbsp;0 while the original
285argument index of \c mix is&nbsp;1.
286
287@param[in] item
288 Non-option parsing item of which to get the non-option index.
289
290@returns
291 Non-option index of \p item.
292
293@pre
294 \p item is not \c NULL.
295@pre
296 \p item has the type #ARGPAR_ITEM_TYPE_NON_OPT.
297
298@sa
299 argpar_item_non_opt_orig_index() -- Returns the original argument
300 index of a non-option parsing item.
301*/
302/// @cond hidden_macro
d4539a90 303ARGPAR_HIDDEN
9e2c879b 304/// @endcond
d4539a90 305unsigned int argpar_item_non_opt_non_opt_index(const struct argpar_item *item);
903a5b8a 306
9e2c879b
PP
307/*!
308@brief
309 Destroys the parsing item \p item.
310
311@param[in] item
312 Parsing item to destroy (may be \c NULL).
313*/
314/// @cond hidden_macro
a473f6cb 315ARGPAR_HIDDEN
9e2c879b 316/// @endcond
a473f6cb
PP
317void argpar_item_destroy(const struct argpar_item *item);
318
9e2c879b
PP
319/*!
320@def ARGPAR_ITEM_DESTROY_AND_RESET(_item)
321
322@brief
323 Calls argpar_item_destroy() with \p _item, and then sets \p _item
324 to \c NULL.
325
326@param[in] _item
327 Item to destroy and variable to reset
328 (<code>const struct argpar_item *</code> type).
329*/
330#define ARGPAR_ITEM_DESTROY_AND_RESET(_item) \
331 { \
332 argpar_item_destroy(_item); \
333 _item = NULL; \
334 }
335
336/// @}
337
8b95d883
PP
338/*!
339@name Error API
340@{
341*/
342
1c881812
PP
343/*!
344@brief
345 Parsing error type, as returned by
346 \link argpar_error_type(const struct argpar_error *) argpar_error_type()\endlink.
347*/
10aefab2
SM
348enum argpar_error_type {
349 /// Unknown option error
350 ARGPAR_ERROR_TYPE_UNKNOWN_OPT,
351
352 /// Missing option argument error
353 ARGPAR_ERROR_TYPE_MISSING_OPT_ARG,
354
355 /// Unexpected option argument error
356 ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG,
357};
358
8b95d883
PP
359/*!
360@struct argpar_error
361
362@brief
363 Opaque parsing error type
364*/
365struct argpar_error;
366
1c881812
PP
367/*!
368@brief
369 Returns the type of the parsing error object \p error.
370
371@param[in] error
372 Parsing error of which to get the type.
373
374@returns
375 Type of \p error.
376
377@pre
378 \p error is not \c NULL.
379*/
380/// @cond hidden_macro
10aefab2 381ARGPAR_HIDDEN
1c881812
PP
382/// @endcond
383enum argpar_error_type argpar_error_type(const struct argpar_error *error);
10aefab2 384
8b95d883
PP
385/*!
386@brief
387 Returns the index of the original argument (in \p argv, as passed to
388 argpar_iter_create()) for which the parsing error described by
389 \p error occurred.
390
391@param[in] error
392 Parsing error of which to get the original argument index.
393
394@returns
395 Original argument index of \p error.
396
397@pre
398 \p error is not \c NULL.
399*/
400/// @cond hidden_macro
401ARGPAR_HIDDEN
402/// @endcond
403unsigned int argpar_error_orig_index(const struct argpar_error *error);
404
405/*!
406@brief
407 Returns the name of the unknown option for which the parsing error
408 described by \p error occurred.
409
410The returned name includes any <code>-</code> or <code>\--</code>
411prefix.
412
413With the long option with argument form, for example
414<code>\--mireille=deyglun</code>, this function only returns the name
415part (<code>\--mireille</code> in the last example).
416
8b95d883
PP
417@param[in] error
418 Parsing error of which to get the name of the unknown option.
419
420@returns
421 Name of the unknown option of \p error.
422
423@pre
424 \p error is not \c NULL.
425@pre
1c881812
PP
426 The type of \p error, as returned by
427 \link argpar_error_type(const struct argpar_error *) argpar_error_type()\endlink,
428 is #ARGPAR_ERROR_TYPE_UNKNOWN_OPT.
8b95d883
PP
429*/
430/// @cond hidden_macro
431ARGPAR_HIDDEN
432/// @endcond
433const char *argpar_error_unknown_opt_name(const struct argpar_error *error);
434
435/*!
436@brief
437 Returns the descriptor of the option for which the parsing error
438 described by \p error occurred.
439
8b95d883
PP
440@param[in] error
441 Parsing error of which to get the option descriptor.
442@param[out] is_short
443 @parblock
444 If not \c NULL, this function sets \p *is_short to:
445
446 - \c true if the option for which \p error occurred is a short
447 option.
448
449 - \c false if the option for which \p error occurred is a long
450 option.
451 @endparblock
452
453@returns
454 Descriptor of the option of \p error.
455
456@pre
457 \p error is not \c NULL.
458@pre
1c881812
PP
459 The type of \p error, as returned by
460 \link argpar_error_type(const struct argpar_error *) argpar_error_type()\endlink,
461 is #ARGPAR_ERROR_TYPE_MISSING_OPT_ARG or
462 #ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG.
8b95d883
PP
463*/
464/// @cond hidden_macro
465ARGPAR_HIDDEN
466/// @endcond
467const struct argpar_opt_descr *argpar_error_opt_descr(
468 const struct argpar_error *error, bool *is_short);
469
470/*!
471@brief
472 Destroys the parsing error \p error.
473
474@param[in] error
475 Parsing error to destroy (may be \c NULL).
476*/
477/// @cond hidden_macro
478ARGPAR_HIDDEN
479/// @endcond
480void argpar_error_destroy(const struct argpar_error *error);
481
482/// @}
483
9e2c879b
PP
484/*!
485@name Iterator API
486@{
487*/
488
489/*!
490@brief
491 Option descriptor
492
493argpar_iter_create() accepts an array of instances of such a type,
494terminated with #ARGPAR_OPT_DESCR_SENTINEL, as its \p descrs parameter.
495
496The typical usage is, for example:
497
498@code
499const struct argpar_opt_descr descrs[] = {
500 { 0, 'd', NULL, false },
501 { 1, '\0', "squeeze", true },
502 { 2, 'm', "meow", true },
503 ARGPAR_OPT_DESCR_SENTINEL,
504};
505@endcode
506*/
507struct argpar_opt_descr {
508 /// Numeric ID, to uniquely identify this descriptor
509 const int id;
510
511 /// Short option character, or <code>'\0'</code>
512 const char short_name;
513
514 /// Long option name (without the <code>\--</code> prefix), or \c NULL
515 const char * const long_name;
516
517 /// \c true if this option has an argument
518 const bool with_arg;
519};
520
521/*!
522@brief
523 Sentinel for an option descriptor array
524
525The typical usage is, for example:
526
527@code
528const struct argpar_opt_descr descrs[] = {
529 { 0, 'd', NULL, false },
530 { 1, '\0', "squeeze", true },
531 { 2, 'm', "meow", true },
532 ARGPAR_OPT_DESCR_SENTINEL,
533};
534@endcode
535*/
536#define ARGPAR_OPT_DESCR_SENTINEL { -1, '\0', NULL, false }
537
538/*!
539@struct argpar_iter
540
541@brief
542 Opaque argpar iterator type
543
544argpar_iter_create() returns a pointer to such a type.
545*/
546struct argpar_iter;
547
548/*!
549@brief
550 Creates and returns an argument parsing iterator to parse the
551 original arguments \p argv of which the count is \p argc using the
552 option descriptors \p descrs.
553
554This function initializes the returned structure, but doesn't actually
555start parsing the arguments.
556
557argpar considers \em all the elements of \p argv, including the first
558one, so that you would typically pass <code>(argc - 1)</code> as \p argc
559and <code>\&argv[1]</code> as \p argv from what <code>main()</code>
560receives, or ignore the parsing item of the first call to
561argpar_iter_next().
562
8b95d883
PP
563\p *argv and \p *descrs must \em not change for all of:
564
565- The lifetime of the returned iterator (until you call
566 argpar_iter_destroy()).
567
568- The lifetime of any parsing item (until you call
569 argpar_item_destroy()) which argpar_iter_next() creates from the
570 returned iterator.
571
572- The lifetime of any parsing error (until you call
573 argpar_error_destroy()) which argpar_iter_next() creates from the
574 returned iterator.
9e2c879b
PP
575
576@param[in] argc
577 Number of original arguments to parse in \p argv.
578@param[in] argv
579 Original arguments to parse, of which the count is \p argc.
580@param[in] descrs
581 @parblock
582 Option descriptor array, terminated with #ARGPAR_OPT_DESCR_SENTINEL.
583
584 May contain duplicate entries.
585 @endparblock
586
587@returns
588 New argument parsing iterator, or \c NULL on memory error.
589
590@pre
591 \p argc is greater than 0.
592@pre
593 \p argv is not \c NULL.
594@pre
595 The first \p argc elements of \p argv are not \c NULL.
596@pre
597 \p descrs is not \c NULL.
598
599@sa
600 argpar_iter_destroy() -- Destroys an argument parsing iterator.
601*/
602/// @cond hidden_macro
fc07e526 603ARGPAR_HIDDEN
9e2c879b 604/// @endcond
fc07e526
SM
605struct argpar_iter *argpar_iter_create(unsigned int argc,
606 const char * const *argv,
607 const struct argpar_opt_descr *descrs);
608
9e2c879b
PP
609/*!
610@brief
611 Destroys the argument parsing iterator \p iter.
612
613@param[in] iter
614 Argument parsing iterator to destroy (may be \c NULL).
615
616@sa
617 argpar_iter_create() -- Creates an argument parsing iterator.
618*/
619/// @cond hidden_macro
fc07e526 620ARGPAR_HIDDEN
9e2c879b 621/// @endcond
fc07e526
SM
622void argpar_iter_destroy(struct argpar_iter *iter);
623
9e2c879b
PP
624/*!
625@brief
626 Return type of argpar_iter_next().
10197dcc
PP
627
628Error status enumerators have a negative value.
9e2c879b 629*/
2af370d0 630enum argpar_iter_next_status {
9e2c879b 631 /// Success
2af370d0 632 ARGPAR_ITER_NEXT_STATUS_OK,
9e2c879b
PP
633
634 /// End of iteration (no more original arguments to parse)
2af370d0 635 ARGPAR_ITER_NEXT_STATUS_END,
9e2c879b 636
1c881812 637 /// Parsing error
10aefab2 638 ARGPAR_ITER_NEXT_STATUS_ERROR = -1,
9e2c879b
PP
639
640 /// Memory error
10197dcc 641 ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY = -12,
fc07e526
SM
642};
643
9e2c879b
PP
644/*!
645@brief
646 Sets \p *item to the next item of the argument parsing iterator
647 \p iter and advances \p iter.
648
649If there are no more original arguments to parse, this function returns
650#ARGPAR_ITER_NEXT_STATUS_END.
651
652@param[in] iter
653 Argument parsing iterator from which to get the next parsing item.
654@param[out] item
655 @parblock
656 On success, \p *item is the next parsing item of \p iter.
657
658 Destroy \p *item with argpar_item_destroy().
659 @endparblock
660@param[out] error
661 @parblock
1c881812
PP
662 When this function returns #ARGPAR_ITER_NEXT_STATUS_ERROR,
663 if this parameter is not \c NULL, \p *error contains details about
664 the error.
9e2c879b 665
8b95d883 666 Destroy \p *error with argpar_error_destroy().
9e2c879b
PP
667 @endparblock
668
669@returns
670 Status code.
671
672@pre
673 \p iter is not \c NULL.
674@pre
675 \p item is not \c NULL.
676*/
677/// @cond hidden_macro
678ARGPAR_HIDDEN
679/// @endcond
2af370d0 680enum argpar_iter_next_status argpar_iter_next(
fc07e526 681 struct argpar_iter *iter, const struct argpar_item **item,
8b95d883 682 const struct argpar_error **error);
fc07e526
SM
683
684/*
685 * Returns the number of ingested elements from `argv`, as passed to
686 * argpar_iter_create() to create `*iter`, that were required to produce
687 * the previously returned items.
688 */
9e2c879b
PP
689
690/*!
691@brief
692 Returns the number of ingested original arguments (in
8b95d883 693 \p argv, as passed to argpar_iter_create() to create \p iter) that
9e2c879b
PP
694 the parser ingested to produce the \em previous parsing items.
695
696@param[in] iter
697 Argument parsing iterator of which to get the number of ingested
698 original arguments.
699
700@returns
701 Number of original arguments which \p iter ingested.
702
703@pre
704 \p iter is not \c NULL.
705*/
706/// @cond hidden_macro
fc07e526 707ARGPAR_HIDDEN
9e2c879b 708/// @endcond
f3ab5ca1 709unsigned int argpar_iter_ingested_orig_args(const struct argpar_iter *iter);
fc07e526 710
9e2c879b
PP
711/// @}
712
713/// @}
fc07e526 714
fe5a18f8 715#endif /* ARGPAR_ARGPAR_H */
This page took 0.051276 seconds and 4 git commands to generate.