vscode: Add configurations to run the executables under the debugger
[lttng-tools.git] / src / common / argpar / argpar.h
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright (c) 2019-2021 Philippe Proulx <pproulx@efficios.com>
5 * Copyright (c) 2020-2021 Simon Marchi <simon.marchi@efficios.com>
6 */
7
8 #ifndef ARGPAR_ARGPAR_H
9 #define ARGPAR_ARGPAR_H
10
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14
15 #include <stdbool.h>
16
17 /*!
18 @mainpage
19
20 See the \ref api module.
21
22 @addtogroup api argpar API
23 @{
24
25 argpar is a library which provides an iterator-based API to parse
26 command-line arguments.
27
28 The 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
71 Create a parsing iterator with argpar_iter_create(), then repeatedly
72 call argpar_iter_next() to access the parsing results (items), until one
73 of:
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
82 argpar_iter_create() accepts duplicate option descriptors in
83 \p descrs (argpar_iter_next() produces one item for each
84 instance).
85
86 A parsing item (the result of argpar_iter_next()) has the type
87 #argpar_item.
88
89 Get the type (option or non-option) of an item with
90 \link argpar_item_type(const struct argpar_item *) 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).
93
94 argpar_iter_next() produces the items in the same order that it parses
95 original arguments, including non-option arguments. This means, for
96 example, that for:
97
98 @code{.unparsed}
99 --hello --count=23 /path/to/file -ab --type file -- magie
100 @endcode
101
102 argpar_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 */
113
114 /*
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".
117 *
118 * On Windows, symbols are local unless explicitly exported; see
119 * <https://gcc.gnu.org/wiki/Visibility>.
120 */
121 #if defined(_WIN32) || defined(__CYGWIN__)
122 #define ARGPAR_HIDDEN
123 #else
124 #define ARGPAR_HIDDEN __attribute__((visibility("hidden")))
125 #endif
126
127 struct argpar_opt_descr;
128
129 /*!
130 @name Item API
131 @{
132 */
133
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 */
139 enum argpar_item_type {
140 /// Option
141 ARGPAR_ITEM_TYPE_OPT,
142
143 /// Non-option
144 ARGPAR_ITEM_TYPE_NON_OPT,
145 };
146
147 /*!
148 @struct argpar_item
149
150 @brief
151 Opaque parsing item type
152
153 argpar_iter_next() sets a pointer to such a type.
154 */
155 struct 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
171 ARGPAR_HIDDEN
172 /// @endcond
173 enum 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
191 ARGPAR_HIDDEN
192 /// @endcond
193 const struct argpar_opt_descr *argpar_item_opt_descr(const struct argpar_item *item);
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
212 ARGPAR_HIDDEN
213 /// @endcond
214 const 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
235 ARGPAR_HIDDEN
236 /// @endcond
237 const 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
245 For example, with the following command line (all options have no
246 argument):
247
248 @code{.unparsed}
249 -f -m meow --jus mix --kilo
250 @endcode
251
252 The original argument index of \c meow is&nbsp;2 while the original
253 argument 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.
265
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
271 ARGPAR_HIDDEN
272 /// @endcond
273 unsigned 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
280 For example, with the following command line (all options have no
281 argument):
282
283 @code{.unparsed}
284 -f -m meow --jus mix --kilo
285 @endcode
286
287 The non-option index of \c meow is&nbsp;0 while the original
288 argument 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.
292
293 @returns
294 Non-option index of \p item.
295
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
306 ARGPAR_HIDDEN
307 /// @endcond
308 unsigned 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
318 ARGPAR_HIDDEN
319 /// @endcond
320 void 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 */
333 #define ARGPAR_ITEM_DESTROY_AND_RESET(_item) \
334 { \
335 argpar_item_destroy(_item); \
336 ((_item)) = NULL; \
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 */
351 enum 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,
360 };
361
362 /*!
363 @struct argpar_error
364
365 @brief
366 Opaque parsing error type
367 */
368 struct 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.
379
380 @pre
381 \p error is not \c NULL.
382 */
383 /// @cond hidden_macro
384 ARGPAR_HIDDEN
385 /// @endcond
386 enum 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
404 ARGPAR_HIDDEN
405 /// @endcond
406 unsigned 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
413 The returned name includes any <code>-</code> or <code>\--</code>
414 prefix.
415
416 With the long option with argument form, for example
417 <code>\--mireille=deyglun</code>, this function only returns the name
418 part (<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
434 ARGPAR_HIDDEN
435 /// @endcond
436 const 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
468 ARGPAR_HIDDEN
469 /// @endcond
470 const struct argpar_opt_descr *argpar_error_opt_descr(const struct argpar_error *error,
471 bool *is_short);
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
481 ARGPAR_HIDDEN
482 /// @endcond
483 void argpar_error_destroy(const struct argpar_error *error);
484
485 /// @}
486
487 /*!
488 @name Iterator API
489 @{
490 */
491
492 /*!
493 @brief
494 Option descriptor
495
496 argpar_iter_create() accepts an array of instances of such a type,
497 terminated with #ARGPAR_OPT_DESCR_SENTINEL, as its \p descrs parameter.
498
499 The typical usage is, for example:
500
501 @code
502 const 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,
507 };
508 @endcode
509 */
510 struct argpar_opt_descr {
511 /// Numeric ID, to uniquely identify this descriptor
512 const int id;
513
514 /// Short option character, or <code>'\0'</code>
515 const char short_name;
516
517 /// Long option name (without the <code>\--</code> prefix), or \c NULL
518 const char *const long_name;
519
520 /// \c true if this option has an argument
521 const bool with_arg;
522 };
523
524 /*!
525 @brief
526 Sentinel for an option descriptor array
527
528 The typical usage is, for example:
529
530 @code
531 const 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,
536 };
537 @endcode
538 */
539 #define ARGPAR_OPT_DESCR_SENTINEL \
540 { \
541 -1, '\0', NULL, false \
542 }
543
544 /*!
545 @struct argpar_iter
546
547 @brief
548 Opaque argpar iterator type
549
550 argpar_iter_create() returns a pointer to such a type.
551 */
552 struct 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
560 This function initializes the returned structure, but doesn't actually
561 start parsing the arguments.
562
563 argpar considers \em all the elements of \p argv, including the first
564 one, so that you would typically pass <code>(argc - 1)</code> as \p argc
565 and <code>\&argv[1]</code> as \p argv from what <code>main()</code>
566 receives, or ignore the parsing item of the first call to
567 argpar_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
609 ARGPAR_HIDDEN
610 /// @endcond
611 struct argpar_iter *argpar_iter_create(unsigned int argc,
612 const char *const *argv,
613 const struct argpar_opt_descr *descrs);
614
615 /*!
616 @brief
617 Destroys the argument parsing iterator \p iter.
618
619 @param[in] iter
620 Argument parsing iterator to destroy (may be \c NULL).
621
622 @sa
623 argpar_iter_create() -- Creates an argument parsing iterator.
624 */
625 /// @cond hidden_macro
626 ARGPAR_HIDDEN
627 /// @endcond
628 void argpar_iter_destroy(struct argpar_iter *iter);
629
630 /*!
631 @brief
632 Return type of argpar_iter_next().
633
634 Error status enumerators have a negative value.
635 */
636 enum argpar_iter_next_status {
637 /// Success
638 ARGPAR_ITER_NEXT_STATUS_OK,
639
640 /// End of iteration (no more original arguments to parse)
641 ARGPAR_ITER_NEXT_STATUS_END,
642
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
655 If 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
684 ARGPAR_HIDDEN
685 /// @endcond
686 enum argpar_iter_next_status argpar_iter_next(struct argpar_iter *iter,
687 const struct argpar_item **item,
688 const struct argpar_error **error);
689
690 /*
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.
694 */
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
713 ARGPAR_HIDDEN
714 /// @endcond
715 unsigned int argpar_iter_ingested_orig_args(const struct argpar_iter *iter);
716
717 /// @}
718
719 /// @}
720
721 #ifdef __cplusplus
722 }
723 #endif
724
725 #endif /* ARGPAR_ARGPAR_H */
This page took 0.04191 seconds and 5 git commands to generate.