cli: sync argpar - adjust to iterator API
[babeltrace.git] / src / argpar / argpar.h
CommitLineData
fac21c87 1/*
0235b0db 2 * SPDX-License-Identifier: MIT
fac21c87 3 *
a93e984c
SM
4 * Copyright (c) 2019-2021 Philippe Proulx <pproulx@efficios.com>
5 * Copyright (c) 2020-2021 Simon Marchi <simon.marchi@efficios.com>
fac21c87
PP
6 */
7
a93e984c
SM
8#ifndef ARGPAR_ARGPAR_H
9#define ARGPAR_ARGPAR_H
0235b0db 10
fac21c87
PP
11#include <stdbool.h>
12
a93e984c
SM
13/*!
14@mainpage
15
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
86\link argpar_item_type(const struct argpar_item *) argpar_item_type()\endlink.
87Each item type has its set of dedicated functions
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*/
65966041
SM
109
110/*
a93e984c
SM
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".
65966041 113 *
a93e984c
SM
114 * On Windows, symbols are local unless explicitly exported; see
115 * <https://gcc.gnu.org/wiki/Visibility>.
65966041
SM
116 */
117#if defined(_WIN32) || defined(__CYGWIN__)
a93e984c 118# define ARGPAR_HIDDEN
65966041 119#else
a93e984c 120# define ARGPAR_HIDDEN __attribute__((visibility("hidden")))
65966041 121#endif
fac21c87 122
a93e984c
SM
123struct argpar_opt_descr;
124
125/*!
126@name Item API
127@{
128*/
129
130/*!
131@brief
132 Type of a parsing item, as returned by
133 \link argpar_item_type(const struct argpar_item *) argpar_item_type()\endlink.
134*/
135enum argpar_item_type {
136 /// Option
137 ARGPAR_ITEM_TYPE_OPT,
138
139 /// Non-option
140 ARGPAR_ITEM_TYPE_NON_OPT,
141};
142
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*/
151struct argpar_item;
152
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
167ARGPAR_HIDDEN
168/// @endcond
169enum argpar_item_type argpar_item_type(const struct argpar_item *item);
170
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
187ARGPAR_HIDDEN
188/// @endcond
189const struct argpar_opt_descr *argpar_item_opt_descr(
190 const struct argpar_item *item);
191
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
209ARGPAR_HIDDEN
210/// @endcond
211const char *argpar_item_opt_arg(const struct argpar_item *item);
212
213/*!
214@brief
215 Returns the complete original argument, pointing to one of the
216 entries of the original arguments (in \p argv, as passed to
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
232ARGPAR_HIDDEN
233/// @endcond
234const char *argpar_item_non_opt_arg(const struct argpar_item *item);
235
236/*!
237@brief
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.
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
268ARGPAR_HIDDEN
269/// @endcond
270unsigned int argpar_item_non_opt_orig_index(const struct argpar_item *item);
271
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
303ARGPAR_HIDDEN
304/// @endcond
305unsigned int argpar_item_non_opt_non_opt_index(const struct argpar_item *item);
306
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
315ARGPAR_HIDDEN
316/// @endcond
317void argpar_item_destroy(const struct argpar_item *item);
318
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
338/*!
339@name Error API
340@{
341*/
342
343/*!
344@brief
345 Parsing error type, as returned by
346 \link argpar_error_type(const struct argpar_error *) argpar_error_type()\endlink.
347*/
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
359/*!
360@struct argpar_error
361
362@brief
363 Opaque parsing error type
364*/
365struct argpar_error;
366
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
381ARGPAR_HIDDEN
382/// @endcond
383enum argpar_error_type argpar_error_type(const struct argpar_error *error);
384
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
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
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.
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
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
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.
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
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*/
65966041 507struct argpar_opt_descr {
a93e984c 508 /// Numeric ID, to uniquely identify this descriptor
fac21c87
PP
509 const int id;
510
a93e984c 511 /// Short option character, or <code>'\0'</code>
fac21c87
PP
512 const char short_name;
513
a93e984c 514 /// Long option name (without the <code>\--</code> prefix), or \c NULL
fac21c87
PP
515 const char * const long_name;
516
a93e984c 517 /// \c true if this option has an argument
fac21c87
PP
518 const bool with_arg;
519};
520
a93e984c
SM
521/*!
522@brief
523 Sentinel for an option descriptor array
fac21c87 524
a93e984c 525The typical usage is, for example:
fac21c87 526
a93e984c
SM
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,
fac21c87 533};
a93e984c
SM
534@endcode
535*/
536#define ARGPAR_OPT_DESCR_SENTINEL { -1, '\0', NULL, false }
fac21c87 537
a93e984c
SM
538/*!
539@struct argpar_iter
fac21c87 540
a93e984c
SM
541@brief
542 Opaque argpar iterator type
fac21c87 543
a93e984c
SM
544argpar_iter_create() returns a pointer to such a type.
545*/
546struct argpar_iter;
fac21c87 547
a93e984c
SM
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.
fac21c87 553
a93e984c
SM
554This function initializes the returned structure, but doesn't actually
555start parsing the arguments.
fac21c87 556
a93e984c
SM
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().
fac21c87 562
a93e984c 563\p *argv and \p *descrs must \em not change for all of:
fac21c87 564
a93e984c
SM
565- The lifetime of the returned iterator (until you call
566 argpar_iter_destroy()).
65966041 567
a93e984c
SM
568- The lifetime of any parsing item (until you call
569 argpar_item_destroy()) which argpar_iter_next() creates from the
570 returned iterator.
65966041 571
a93e984c
SM
572- The lifetime of any parsing error (until you call
573 argpar_error_destroy()) which argpar_iter_next() creates from the
574 returned iterator.
65966041 575
a93e984c
SM
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.
fac21c87 583
a93e984c
SM
584 May contain duplicate entries.
585 @endparblock
fac21c87 586
a93e984c
SM
587@returns
588 New argument parsing iterator, or \c NULL on memory error.
fac21c87 589
a93e984c
SM
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
65966041 603ARGPAR_HIDDEN
a93e984c
SM
604/// @endcond
605struct argpar_iter *argpar_iter_create(unsigned int argc,
fac21c87 606 const char * const *argv,
a93e984c
SM
607 const struct argpar_opt_descr *descrs);
608
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
620ARGPAR_HIDDEN
621/// @endcond
622void argpar_iter_destroy(struct argpar_iter *iter);
623
624/*!
625@brief
626 Return type of argpar_iter_next().
627
628Error status enumerators have a negative value.
629*/
630enum argpar_iter_next_status {
631 /// Success
632 ARGPAR_ITER_NEXT_STATUS_OK,
633
634 /// End of iteration (no more original arguments to parse)
635 ARGPAR_ITER_NEXT_STATUS_END,
636
637 /// Parsing error
638 ARGPAR_ITER_NEXT_STATUS_ERROR = -1,
639
640 /// Memory error
641 ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY = -12,
642};
643
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
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.
665
666 Destroy \p *error with argpar_error_destroy().
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
680enum argpar_iter_next_status argpar_iter_next(
681 struct argpar_iter *iter, const struct argpar_item **item,
682 const struct argpar_error **error);
fac21c87
PP
683
684/*
a93e984c
SM
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.
fac21c87 688 */
a93e984c
SM
689
690/*!
691@brief
692 Returns the number of ingested original arguments (in
693 \p argv, as passed to argpar_iter_create() to create \p iter) that
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
65966041 707ARGPAR_HIDDEN
a93e984c
SM
708/// @endcond
709unsigned int argpar_iter_ingested_orig_args(const struct argpar_iter *iter);
710
711/// @}
712
713/// @}
fac21c87 714
a93e984c 715#endif /* ARGPAR_ARGPAR_H */
This page took 0.068556 seconds and 4 git commands to generate.