Commit | Line | Data |
---|---|---|
addae149 PP |
1 | // SPDX-FileCopyrightText: 2023 Philippe Proulx <eeppeliteloop@gmail.com> |
2 | // SPDX-License-Identifier: CC-BY-SA-4.0 | |
3 | ||
4 | // Render with Asciidoctor | |
5 | ||
6 | = argpar | |
7 | 15 March 2024 | |
8 | :bt2: Babeltrace{nbsp}2 | |
9 | ifdef::env-github[] | |
10 | :toc: macro | |
11 | endif::[] | |
12 | ifndef::env-github[] | |
13 | :toc: left | |
14 | endif::[] | |
15 | :idprefix: | |
16 | :idseparator: - | |
17 | ||
18 | **argpar**, an https://efficios.com/[EfficiOS] project, is yet another | |
19 | open-source command-line argument parser for C/{cpp} programs. | |
20 | ||
21 | ifdef::env-github[] | |
22 | toc::[] | |
23 | endif::[] | |
24 | ||
25 | == Features | |
26 | ||
27 | The most important features of argpar are: | |
28 | ||
29 | * A single MIT-licensed, independent C99 source file and its header that | |
30 | you can copy as is into your own project. | |
31 | ||
32 | * Declarative description of expected options: | |
33 | + | |
34 | [source,c] | |
35 | ---- | |
36 | enum my_opt_id { | |
37 | MY_OPT_ID_DATA, | |
38 | MY_OPT_ID_SQUEEZE, | |
39 | MY_OPT_ID_MEOW, | |
40 | }; | |
41 | ||
42 | static const struct argpar_opt_descr descrs[] = { | |
43 | { MY_OPT_ID_DATA, 'd', NULL, false }, | |
44 | { MY_OPT_ID_SQUEEZE, '\0', "squeeze", true }, | |
45 | { MY_OPT_ID_MEOW, 'm', "meow", true }, | |
46 | ARGPAR_OPT_DESCR_SENTINEL, | |
47 | }; | |
48 | ---- | |
49 | ||
50 | * Supports short (`-k`) and long (`--kernel`) options. | |
51 | + | |
52 | Multiple short options may be concatenated, and the argument of the | |
53 | last one may be "`attached`" (`-xvfmyfile`). | |
54 | + | |
55 | The argument of a long option may follow a space (`--meow{nbsp}mix`) or | |
56 | an `=` sign (`--meow=mix`). | |
57 | ||
58 | * Supports repeated options: | |
59 | + | |
60 | ---- | |
61 | --meow=mix salut -f4 /path/to/file --meow blend -cqc | |
62 | ---- | |
63 | ||
64 | * Fully documented, `const`-correct C99 API based on an argument | |
65 | iterator. | |
66 | + | |
67 | The `argpar_iter_next()` function produces items in the same order that | |
68 | it parses original arguments, including non-option items. This means, | |
69 | for example, that for: | |
70 | + | |
71 | ---- | |
72 | --hello --count=23 /path/to/file -ab --type file -- magie | |
73 | ---- | |
74 | + | |
75 | `argpar_iter_next()` produces the following items, in this order: | |
76 | ||
77 | ** Option item: `--hello`. | |
78 | ** Option item: `--count` with argument `23`. | |
79 | ** Non-option item: `/path/to/file`. | |
80 | ** Option item: `-a`. | |
81 | ** Option item: `-b`. | |
82 | ** Option item: `--type` with argument `file`. | |
83 | ** Non-option item: `--`. | |
84 | ** Non-option item: `magie`. | |
85 | ||
86 | * On parsing error, provides a detailed error object including the index | |
87 | of the argument (in `argv`) that caused the error as well as the name, | |
88 | if available, of the unknown option. | |
89 | ||
90 | == Known limitations | |
91 | ||
92 | Compared to other similar open-source command-line argument parsers, | |
93 | argpar has the following known limitations: | |
94 | ||
95 | * Doesn't support abbreviated long options. | |
96 | + | |
97 | For example, if your option descriptor describes `--fraction`, then | |
98 | `argpar_iter_next()` won't parse `--frac=23`: it will return an unknown | |
99 | option error instead. | |
100 | ||
101 | * Doesn't explicitly support "`end of option`" (`--`). | |
102 | + | |
103 | This is valid: | |
104 | + | |
105 | ---- | |
106 | --hello=world --meow -- mix --hut=23 | |
107 | ---- | |
108 | + | |
109 | `argpar_iter_next()` provides the `--` argument as a non-option item. | |
110 | ||
111 | * Doesn't support a non-option argument having the form of an option, | |
112 | for example if you need to pass the exact relative path `--calorie`. | |
113 | + | |
114 | In that case, you would need to pass `./--calorie`. There's no generic | |
115 | way to escape `-` as of this version. This is in part because argpar | |
116 | doesn't support "`end of option`" (`--`). | |
117 | + | |
118 | As a workaround, because argpar offers an iterator API, you may: | |
119 | + | |
120 | . Stop using `argpar_iter_next()` from the first `--` non-option item | |
121 | __**ITEM**__. | |
122 | . Use `argpar_item_non_opt_orig_index()` with __**ITEM**__ to get the | |
123 | original index __**I**__ of the first `--` within `argv` (as passed | |
124 | to `argpar_iter_create()`). | |
125 | . Read the remaining non-option arguments from `argv`, starting at | |
126 | __**I**__{nbsp}+{nbsp}1. | |
127 | ||
128 | * Doesn't handle the `-h`/`--help` option in a special way (doesn't show | |
129 | some automatic usage message). | |
130 | ||
131 | * Doesn't provide direct access to the value of an option. | |
132 | + | |
133 | This is because argpar offers an iterator API to support positional and | |
134 | repeated options. | |
135 | ||
136 | == Build argpar | |
137 | ||
138 | To use argpar in your own project, simply copy the `argpar/argpar.c` and | |
139 | `argpar/argpar.h` files and you're ready to go. | |
140 | ||
141 | To build this project, make sure you have | |
142 | https://docs.gtk.org/glib/[GLib]{nbsp}2 (required by the tests), and | |
143 | then: | |
144 | ||
145 | . **If you build from a Git clone**, run: | |
146 | + | |
147 | [role="term"] | |
148 | ---- | |
149 | $ ./bootstrap | |
150 | ---- | |
151 | + | |
152 | This generates the `configure` script and other important files. | |
153 | ||
154 | . Configure the project: | |
155 | + | |
156 | [role="term"] | |
157 | ---- | |
158 | $ ./configure | |
159 | ---- | |
160 | + | |
161 | See `./configure --help` for more options. | |
162 | ||
163 | . Build the project: | |
164 | + | |
165 | [role="term"] | |
166 | ---- | |
167 | $ make | |
168 | ---- | |
169 | ||
170 | == Build the API documentation | |
171 | ||
172 | To build the API documentation, make sure you have | |
173 | https://www.doxygen.nl/[Doxygen], and then: | |
174 | ||
175 | * From the root of the project, run: | |
176 | + | |
177 | ---- | |
178 | $ doxygen | |
179 | ---- | |
180 | ||
181 | Open `api-doc/html/index.html` with Netscape Navigator. | |
182 | ||
183 | == Run the tests | |
184 | ||
185 | To run the argpar tests: | |
186 | ||
187 | . <<build-argpar,Build the project>>. | |
188 | ||
189 | . Run the tests: | |
190 | + | |
191 | [role="term"] | |
192 | ---- | |
193 | $ make check | |
194 | ---- | |
195 | ||
196 | == Community | |
197 | ||
198 | argpar uses https://review.lttng.org/admin/repos/argpar,general[Gerrit] | |
199 | for code review. | |
200 | ||
201 | To report a bug, https://github.com/efficios/argpar/issues/new[create a | |
202 | GitHub issue]. |