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