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