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