configure.ac: set the version of the project to 0.1.0
[argpar.git] / argpar / argpar.h
... / ...
CommitLineData
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#include <stdbool.h>
12
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
86argpar_item_type(). Each item type has its set of dedicated functions
87(\c argpar_item_opt_ and \c argpar_item_non_opt_ prefixes).
88
89argpar_iter_next() produces the items in the same order that it parses
90original arguments, including non-option arguments. This means, for
91example, that for:
92
93@code{.unparsed}
94--hello --count=23 /path/to/file -ab --type file -- magie
95@endcode
96
97argpar_iter_next() produces the following items, in this order:
98
99-# Option item (<code>\--hello</code>).
100-# Option item (<code>\--count</code> with argument <code>23</code>).
101-# Non-option item (<code>/path/to/file</code>).
102-# Option item (<code>-a</code>).
103-# Option item (<code>-b</code>).
104-# Option item (<code>\--type</code> with argument <code>file</code>).
105-# Non-option item (<code>\--</code>).
106-# Non-option item (<code>magie</code>).
107*/
108
109/*
110 * If argpar is used in some shared library, we don't want said library
111 * to export its symbols, so mark them as "hidden".
112 *
113 * On Windows, symbols are local unless explicitly exported; see
114 * <https://gcc.gnu.org/wiki/Visibility>.
115 */
116#if defined(_WIN32) || defined(__CYGWIN__)
117# define ARGPAR_HIDDEN
118#else
119# define ARGPAR_HIDDEN __attribute__((visibility("hidden")))
120#endif
121
122struct argpar_opt_descr;
123
124/*!
125@name Item API
126@{
127*/
128
129/*!
130@brief
131 Type of a parsing item, as returned by argpar_item_type().
132*/
133enum argpar_item_type {
134 /// Option
135 ARGPAR_ITEM_TYPE_OPT,
136
137 /// Non-option
138 ARGPAR_ITEM_TYPE_NON_OPT,
139};
140
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*/
149struct argpar_item;
150
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*/
164/// @cond hidden_macro
165ARGPAR_HIDDEN
166/// @endcond
167enum argpar_item_type argpar_item_type(const struct argpar_item *item);
168
169/*!
170@brief
171 Returns the option descriptor of the option parsing item \p item.
172
173@param[in] item
174 Option parsing item of which to get the option descriptor.
175
176@returns
177 Option descriptor of \p item.
178
179@pre
180 \p item is not \c NULL.
181@pre
182 \p item has the type #ARGPAR_ITEM_TYPE_OPT.
183*/
184/// @cond hidden_macro
185ARGPAR_HIDDEN
186/// @endcond
187const struct argpar_opt_descr *argpar_item_opt_descr(
188 const struct argpar_item *item);
189
190/*!
191@brief
192 Returns the argument of the option parsing item \p item, or
193 \c NULL if none.
194
195@param[in] item
196 Option parsing item of which to get the argument.
197
198@returns
199 Argument of \p item, or \c NULL if none.
200
201@pre
202 \p item is not \c NULL.
203@pre
204 \p item has the type #ARGPAR_ITEM_TYPE_OPT.
205*/
206/// @cond hidden_macro
207ARGPAR_HIDDEN
208/// @endcond
209const char *argpar_item_opt_arg(const struct argpar_item *item);
210
211/*!
212@brief
213 Returns the complete original argument, pointing to one of the
214 entries of the original arguments (\p argv as passed to
215 argpar_iter_create()), of the non-option parsing item \p item.
216
217@param[in] item
218 Non-option parsing item of which to get the complete original
219 argument.
220
221@returns
222 Complete original argument of \p item.
223
224@pre
225 \p item is not \c NULL.
226@pre
227 \p item has the type #ARGPAR_ITEM_TYPE_NON_OPT.
228*/
229/// @cond hidden_macro
230ARGPAR_HIDDEN
231/// @endcond
232const char *argpar_item_non_opt_arg(const struct argpar_item *item);
233
234/*!
235@brief
236 Returns the index, within \em all the original arguments (\p argv
237 as passed to argpar_iter_create()), of the non-option parsing item
238 \p item.
239
240For example, with the following command line (all options have no
241argument):
242
243@code{.unparsed}
244-f -m meow --jus mix --kilo
245@endcode
246
247The original argument index of \c meow is&nbsp;2 while the original
248argument index of \c mix is&nbsp;4.
249
250@param[in] item
251 Non-option parsing item of which to get the original argument index.
252
253@returns
254 Original argument index of \p item.
255
256@pre
257 \p item is not \c NULL.
258@pre
259 \p item has the type #ARGPAR_ITEM_TYPE_NON_OPT.
260
261@sa
262 argpar_item_non_opt_non_opt_index() -- Returns the non-option index
263 of a non-option parsing item.
264*/
265/// @cond hidden_macro
266ARGPAR_HIDDEN
267/// @endcond
268unsigned int argpar_item_non_opt_orig_index(const struct argpar_item *item);
269
270/*!
271@brief
272 Returns the index, within the parsed non-option parsing items, of
273 the non-option parsing item \p item.
274
275For example, with the following command line (all options have no
276argument):
277
278@code{.unparsed}
279-f -m meow --jus mix --kilo
280@endcode
281
282The non-option index of \c meow is&nbsp;0 while the original
283argument index of \c mix is&nbsp;1.
284
285@param[in] item
286 Non-option parsing item of which to get the non-option index.
287
288@returns
289 Non-option index of \p item.
290
291@pre
292 \p item is not \c NULL.
293@pre
294 \p item has the type #ARGPAR_ITEM_TYPE_NON_OPT.
295
296@sa
297 argpar_item_non_opt_orig_index() -- Returns the original argument
298 index of a non-option parsing item.
299*/
300/// @cond hidden_macro
301ARGPAR_HIDDEN
302/// @endcond
303unsigned int argpar_item_non_opt_non_opt_index(const struct argpar_item *item);
304
305/*!
306@brief
307 Destroys the parsing item \p item.
308
309@param[in] item
310 Parsing item to destroy (may be \c NULL).
311*/
312/// @cond hidden_macro
313ARGPAR_HIDDEN
314/// @endcond
315void argpar_item_destroy(const struct argpar_item *item);
316
317/*!
318@def ARGPAR_ITEM_DESTROY_AND_RESET(_item)
319
320@brief
321 Calls argpar_item_destroy() with \p _item, and then sets \p _item
322 to \c NULL.
323
324@param[in] _item
325 Item to destroy and variable to reset
326 (<code>const struct argpar_item *</code> type).
327*/
328#define ARGPAR_ITEM_DESTROY_AND_RESET(_item) \
329 { \
330 argpar_item_destroy(_item); \
331 _item = NULL; \
332 }
333
334/// @}
335
336/*!
337@name Iterator API
338@{
339*/
340
341/*!
342@brief
343 Option descriptor
344
345argpar_iter_create() accepts an array of instances of such a type,
346terminated with #ARGPAR_OPT_DESCR_SENTINEL, as its \p descrs parameter.
347
348The typical usage is, for example:
349
350@code
351const struct argpar_opt_descr descrs[] = {
352 { 0, 'd', NULL, false },
353 { 1, '\0', "squeeze", true },
354 { 2, 'm', "meow", true },
355 ARGPAR_OPT_DESCR_SENTINEL,
356};
357@endcode
358*/
359struct argpar_opt_descr {
360 /// Numeric ID, to uniquely identify this descriptor
361 const int id;
362
363 /// Short option character, or <code>'\0'</code>
364 const char short_name;
365
366 /// Long option name (without the <code>\--</code> prefix), or \c NULL
367 const char * const long_name;
368
369 /// \c true if this option has an argument
370 const bool with_arg;
371};
372
373/*!
374@brief
375 Sentinel for an option descriptor array
376
377The typical usage is, for example:
378
379@code
380const struct argpar_opt_descr descrs[] = {
381 { 0, 'd', NULL, false },
382 { 1, '\0', "squeeze", true },
383 { 2, 'm', "meow", true },
384 ARGPAR_OPT_DESCR_SENTINEL,
385};
386@endcode
387*/
388#define ARGPAR_OPT_DESCR_SENTINEL { -1, '\0', NULL, false }
389
390/*!
391@struct argpar_iter
392
393@brief
394 Opaque argpar iterator type
395
396argpar_iter_create() returns a pointer to such a type.
397*/
398struct argpar_iter;
399
400/*!
401@brief
402 Creates and returns an argument parsing iterator to parse the
403 original arguments \p argv of which the count is \p argc using the
404 option descriptors \p descrs.
405
406This function initializes the returned structure, but doesn't actually
407start parsing the arguments.
408
409argpar considers \em all the elements of \p argv, including the first
410one, so that you would typically pass <code>(argc - 1)</code> as \p argc
411and <code>\&argv[1]</code> as \p argv from what <code>main()</code>
412receives, or ignore the parsing item of the first call to
413argpar_iter_next().
414
415\p *argv and \p *descrs must \em not change for the lifetime of the
416returned iterator (until you call argpar_iter_destroy()) and for the
417lifetime of any parsing item (until you call argpar_item_destroy())
418which argpar_iter_next() creates from the returned iterator.
419
420@param[in] argc
421 Number of original arguments to parse in \p argv.
422@param[in] argv
423 Original arguments to parse, of which the count is \p argc.
424@param[in] descrs
425 @parblock
426 Option descriptor array, terminated with #ARGPAR_OPT_DESCR_SENTINEL.
427
428 May contain duplicate entries.
429 @endparblock
430
431@returns
432 New argument parsing iterator, or \c NULL on memory error.
433
434@pre
435 \p argc is greater than 0.
436@pre
437 \p argv is not \c NULL.
438@pre
439 The first \p argc elements of \p argv are not \c NULL.
440@pre
441 \p descrs is not \c NULL.
442
443@sa
444 argpar_iter_destroy() -- Destroys an argument parsing iterator.
445*/
446/// @cond hidden_macro
447ARGPAR_HIDDEN
448/// @endcond
449struct argpar_iter *argpar_iter_create(unsigned int argc,
450 const char * const *argv,
451 const struct argpar_opt_descr *descrs);
452
453/*!
454@brief
455 Destroys the argument parsing iterator \p iter.
456
457@param[in] iter
458 Argument parsing iterator to destroy (may be \c NULL).
459
460@sa
461 argpar_iter_create() -- Creates an argument parsing iterator.
462*/
463/// @cond hidden_macro
464ARGPAR_HIDDEN
465/// @endcond
466void argpar_iter_destroy(struct argpar_iter *iter);
467
468/*!
469@brief
470 Return type of argpar_iter_next().
471*/
472enum argpar_iter_next_status {
473 /// Success
474 ARGPAR_ITER_NEXT_STATUS_OK,
475
476 /// End of iteration (no more original arguments to parse)
477 ARGPAR_ITER_NEXT_STATUS_END,
478
479 /// Unknown option error
480 ARGPAR_ITER_NEXT_STATUS_ERROR_UNKNOWN_OPT,
481
482 /// Missing option argument error
483 ARGPAR_ITER_NEXT_STATUS_ERROR_MISSING_OPT_ARG,
484
485 /// Unexpected option argument error
486 ARGPAR_ITER_NEXT_STATUS_ERROR_UNEXPECTED_OPT_ARG,
487
488 /// Memory error
489 ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY,
490};
491
492/*!
493@brief
494 Sets \p *item to the next item of the argument parsing iterator
495 \p iter and advances \p iter.
496
497If there are no more original arguments to parse, this function returns
498#ARGPAR_ITER_NEXT_STATUS_END.
499
500@param[in] iter
501 Argument parsing iterator from which to get the next parsing item.
502@param[out] item
503 @parblock
504 On success, \p *item is the next parsing item of \p iter.
505
506 Destroy \p *item with argpar_item_destroy().
507 @endparblock
508@param[out] error
509 @parblock
510 When this function returns
511 #ARGPAR_ITER_NEXT_STATUS_ERROR_UNKNOWN_OPT,
512 #ARGPAR_ITER_NEXT_STATUS_ERROR_MISSING_OPT_ARG, or
513 #ARGPAR_ITER_NEXT_STATUS_ERROR_UNEXPECTED_OPG_ARG, if this parameter
514 is not \c NULL,
515 \p *error is a string which explains the parsing error in English.
516
517 Free \p *error with <code>free()</code>.
518 @endparblock
519
520@returns
521 Status code.
522
523@pre
524 \p iter is not \c NULL.
525@pre
526 \p item is not \c NULL.
527*/
528/// @cond hidden_macro
529ARGPAR_HIDDEN
530/// @endcond
531enum argpar_iter_next_status argpar_iter_next(
532 struct argpar_iter *iter, const struct argpar_item **item,
533 char **error);
534
535/*
536 * Returns the number of ingested elements from `argv`, as passed to
537 * argpar_iter_create() to create `*iter`, that were required to produce
538 * the previously returned items.
539 */
540
541/*!
542@brief
543 Returns the number of ingested original arguments (in
544 \p argv as passed to argpar_iter_create() to create \p iter) that
545 the parser ingested to produce the \em previous parsing items.
546
547@param[in] iter
548 Argument parsing iterator of which to get the number of ingested
549 original arguments.
550
551@returns
552 Number of original arguments which \p iter ingested.
553
554@pre
555 \p iter is not \c NULL.
556*/
557/// @cond hidden_macro
558ARGPAR_HIDDEN
559/// @endcond
560unsigned int argpar_iter_ingested_orig_args(const struct argpar_iter *iter);
561
562/// @}
563
564/// @}
565
566#endif /* ARGPAR_ARGPAR_H */
This page took 0.023079 seconds and 4 git commands to generate.