contrek 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rspec +3 -0
  4. data/Gemfile +3 -0
  5. data/Gemfile.lock +84 -0
  6. data/LICENSE.md +9 -0
  7. data/README.md +118 -0
  8. data/Rakefile +19 -0
  9. data/contrek.gemspec +23 -0
  10. data/contrek.png +0 -0
  11. data/ext/cpp_polygon_finder/PolygonFinder/.cproject +136 -0
  12. data/ext/cpp_polygon_finder/PolygonFinder/.project +27 -0
  13. data/ext/cpp_polygon_finder/PolygonFinder/.settings/org.eclipse.ltk.core.refactoring.prefs +2 -0
  14. data/ext/cpp_polygon_finder/PolygonFinder/images/labyrinth.png +0 -0
  15. data/ext/cpp_polygon_finder/PolygonFinder/src/Main.cpp +41 -0
  16. data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.cpp +69 -0
  17. data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.h +19 -0
  18. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/Bitmap.cpp +52 -0
  19. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/Bitmap.h +32 -0
  20. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/FastPngBitmap.cpp +656 -0
  21. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/FastPngBitmap.h +42 -0
  22. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/PngBitmap.cpp +48 -0
  23. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/PngBitmap.h +32 -0
  24. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/RemoteFastPngBitmap.cpp +30 -0
  25. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/RemoteFastPngBitmap.h +26 -0
  26. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/X_picopng.cpp +576 -0
  27. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/List.cpp +120 -0
  28. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/List.h +40 -0
  29. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Lists.cpp +36 -0
  30. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Lists.h +30 -0
  31. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.cpp +111 -0
  32. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.h +80 -0
  33. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.cpp +325 -0
  34. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.h +59 -0
  35. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.cpp +206 -0
  36. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.h +69 -0
  37. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/optionparser.h +2858 -0
  38. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/Matcher.cpp +23 -0
  39. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/Matcher.h +23 -0
  40. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBMatcher.cpp +20 -0
  41. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBMatcher.h +23 -0
  42. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBNotMatcher.cpp +20 -0
  43. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBNotMatcher.h +23 -0
  44. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/ValueNotMatcher.cpp +20 -0
  45. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/ValueNotMatcher.h +21 -0
  46. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.cpp +40 -0
  47. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.h +23 -0
  48. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.cpp +19 -0
  49. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.h +25 -0
  50. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.cpp +30 -0
  51. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.h +21 -0
  52. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.cpp +50 -0
  53. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.h +121 -0
  54. data/ext/cpp_polygon_finder/cpp_polygon_finder.cpp +260 -0
  55. data/ext/cpp_polygon_finder/extconf.rb +2 -0
  56. data/lib/contrek/bitmaps/bitmap.rb +21 -0
  57. data/lib/contrek/bitmaps/chunky_bitmap.rb +33 -0
  58. data/lib/contrek/bitmaps/painting.rb +40 -0
  59. data/lib/contrek/bitmaps/png_bitmap.rb +62 -0
  60. data/lib/contrek/bitmaps/rgb_color.rb +25 -0
  61. data/lib/contrek/finder/list.rb +132 -0
  62. data/lib/contrek/finder/list_entry.rb +11 -0
  63. data/lib/contrek/finder/listable.rb +8 -0
  64. data/lib/contrek/finder/lists.rb +25 -0
  65. data/lib/contrek/finder/node.rb +126 -0
  66. data/lib/contrek/finder/node_cluster.rb +294 -0
  67. data/lib/contrek/finder/polygon_finder.rb +121 -0
  68. data/lib/contrek/map/mercator_projection.rb +76 -0
  69. data/lib/contrek/matchers/matcher.rb +20 -0
  70. data/lib/contrek/matchers/matcher_hsb.rb +24 -0
  71. data/lib/contrek/matchers/value_not_matcher.rb +9 -0
  72. data/lib/contrek/reducers/linear_reducer.rb +25 -0
  73. data/lib/contrek/reducers/reducer.rb +14 -0
  74. data/lib/contrek/reducers/uniq_reducer.rb +9 -0
  75. data/lib/contrek/reducers/visvalingam_reducer.rb +139 -0
  76. data/lib/contrek/version.rb +3 -0
  77. data/lib/contrek.rb +58 -0
  78. metadata +175 -0
@@ -0,0 +1,2858 @@
1
+ /*
2
+ * The Lean Mean C++ Option Parser
3
+ *
4
+ * Copyright (C) 2012-2017 Matthias S. Benkmann
5
+ *
6
+ * The "Software" in the following 2 paragraphs refers to this file containing
7
+ * the code to The Lean Mean C++ Option Parser.
8
+ * The "Software" does NOT refer to any other files which you
9
+ * may have received alongside this file (e.g. as part of a larger project that
10
+ * incorporates The Lean Mean C++ Option Parser).
11
+ *
12
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
13
+ * of this software, to deal in the Software without restriction, including
14
+ * without limitation the rights to use, copy, modify, merge, publish,
15
+ * distribute, sublicense, and/or sell copies of the Software, and to permit
16
+ * persons to whom the Software is furnished to do so, subject to the following
17
+ * conditions:
18
+ * The above copyright notice and this permission notice shall be included in
19
+ * all copies or substantial portions of the Software.
20
+ *
21
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ * SOFTWARE.
28
+ */
29
+
30
+ /*
31
+ * NOTE: It is recommended that you read the processed HTML doxygen documentation
32
+ * rather than this source. If you don't know doxygen, it's like javadoc for C++.
33
+ * If you don't want to install doxygen you can find a copy of the processed
34
+ * documentation at
35
+ *
36
+ * http://optionparser.sourceforge.net/
37
+ *
38
+ */
39
+
40
+ /**
41
+ * @file
42
+ *
43
+ * @brief This is the only file required to use The Lean Mean C++ Option Parser.
44
+ * Just \#include it and you're set.
45
+ *
46
+ * The Lean Mean C++ Option Parser handles the program's command line arguments
47
+ * (argc, argv).
48
+ * It supports the short and long option formats of getopt(), getopt_long()
49
+ * and getopt_long_only() but has a more convenient interface.
50
+ *
51
+ * @par Feedback:
52
+ * Send questions, bug reports, feature requests etc. to: <tt><b>optionparser-feedback(a)lists.sourceforge.net</b></tt>
53
+ *
54
+ * @par Highlights:
55
+ * <ul style="padding-left:1em;margin-left:0">
56
+ * <li> It is a header-only library. Just <code>\#include "optionparser.h"</code> and you're set.
57
+ * <li> It is freestanding. There are no dependencies whatsoever, not even the
58
+ * C or C++ standard library.
59
+ * <li> It has a usage message formatter that supports column alignment and
60
+ * line wrapping. This aids localization because it adapts to
61
+ * translated strings that are shorter or longer (even if they contain
62
+ * Asian wide characters).
63
+ * <li> Unlike getopt() and derivatives it doesn't force you to loop through
64
+ * options sequentially. Instead you can access options directly like this:
65
+ * <ul style="margin-top:.5em">
66
+ * <li> Test for presence of a switch in the argument vector:
67
+ * @code if ( options[QUIET] ) ... @endcode
68
+ * <li> Evaluate --enable-foo/--disable-foo pair where the last one used wins:
69
+ * @code if ( options[FOO].last()->type() == DISABLE ) ... @endcode
70
+ * <li> Cumulative option (-v verbose, -vv more verbose, -vvv even more verbose):
71
+ * @code int verbosity = options[VERBOSE].count(); @endcode
72
+ * <li> Iterate over all --file=&lt;fname> arguments:
73
+ * @code for (Option* opt = options[FILE]; opt; opt = opt->next())
74
+ * fname = opt->arg; ... @endcode
75
+ * <li> If you really want to, you can still process all arguments in order:
76
+ * @code
77
+ * for (int i = 0; i < p.optionsCount(); ++i) {
78
+ * Option& opt = buffer[i];
79
+ * switch(opt.index()) {
80
+ * case HELP: ...
81
+ * case VERBOSE: ...
82
+ * case FILE: fname = opt.arg; ...
83
+ * case UNKNOWN: ...
84
+ * @endcode
85
+ * </ul>
86
+ * </ul> @n
87
+ * Despite these features the code size remains tiny.
88
+ * It is smaller than <a href="http://uclibc.org">uClibc</a>'s GNU getopt() and just a
89
+ * couple 100 bytes larger than uClibc's SUSv3 getopt(). @n
90
+ * (This does not include the usage formatter, of course. But you don't have to use that.)
91
+ *
92
+ * @par Download:
93
+ * Tarball with examples and test programs:
94
+ * <a style="font-size:larger;font-weight:bold" href="http://sourceforge.net/projects/optionparser/files/optionparser-1.7.tar.gz/download">optionparser-1.7.tar.gz</a> @n
95
+ * Just the header (this is all you really need):
96
+ * <a style="font-size:larger;font-weight:bold" href="http://optionparser.sourceforge.net/optionparser.h">optionparser.h</a>
97
+ *
98
+ * @par Changelog:
99
+ * <b>Version 1.7:</b> Work on const-correctness. @n
100
+ * <b>Version 1.6:</b> Fix for MSC compiler. @n
101
+ * <b>Version 1.5:</b> Fixed 2 warnings about potentially uninitialized variables. @n
102
+ * Added const version of Option::next(). @n
103
+ * <b>Version 1.4:</b> Fixed 2 printUsage() bugs that messed up output with small COLUMNS values. @n
104
+ * <b>Version 1.3:</b> Compatible with Microsoft Visual C++. @n
105
+ * <b>Version 1.2:</b> Added @ref option::Option::namelen "Option::namelen" and removed the extraction
106
+ * of short option characters into a special buffer. @n
107
+ * Changed @ref option::Arg::Optional "Arg::Optional" to accept arguments if they are attached
108
+ * rather than separate. This is what GNU getopt() does and how POSIX recommends
109
+ * utilities should interpret their arguments.@n
110
+ * <b>Version 1.1:</b> Optional mode with argument reordering as done by GNU getopt(), so that
111
+ * options and non-options can be mixed. See
112
+ * @ref option::Parser::parse() "Parser::parse()".
113
+ *
114
+ *
115
+ * @par Example program:
116
+ * (Note: @c option::* identifiers are links that take you to their documentation.)
117
+ * @code
118
+ * #error EXAMPLE SHORTENED FOR READABILITY. BETTER EXAMPLES ARE IN THE .TAR.GZ!
119
+ * #include <iostream>
120
+ * #include "optionparser.h"
121
+ *
122
+ * enum optionIndex { UNKNOWN, HELP, PLUS };
123
+ * const option::Descriptor usage[] =
124
+ * {
125
+ * {UNKNOWN, 0,"" , "" ,option::Arg::None, "USAGE: example [options]\n\n"
126
+ * "Options:" },
127
+ * {HELP, 0,"" , "help",option::Arg::None, " --help \tPrint usage and exit." },
128
+ * {PLUS, 0,"p", "plus",option::Arg::None, " --plus, -p \tIncrement count." },
129
+ * {UNKNOWN, 0,"" , "" ,option::Arg::None, "\nExamples:\n"
130
+ * " example --unknown -- --this_is_no_option\n"
131
+ * " example -unk --plus -ppp file1 file2\n" },
132
+ * {0,0,0,0,0,0}
133
+ * };
134
+ *
135
+ * int main(int argc, char* argv[])
136
+ * {
137
+ * argc-=(argc>0); argv+=(argc>0); // skip program name argv[0] if present
138
+ * option::Stats stats(usage, argc, argv);
139
+ * option::Option options[stats.options_max], buffer[stats.buffer_max];
140
+ * option::Parser parse(usage, argc, argv, options, buffer);
141
+ *
142
+ * if (parse.error())
143
+ * return 1;
144
+ *
145
+ * if (options[HELP] || argc == 0) {
146
+ * option::printUsage(std::cout, usage);
147
+ * return 0;
148
+ * }
149
+ *
150
+ * std::cout << "--plus count: " <<
151
+ * options[PLUS].count() << "\n";
152
+ *
153
+ * for (option::Option* opt = options[UNKNOWN]; opt; opt = opt->next())
154
+ * std::cout << "Unknown option: " << opt->name << "\n";
155
+ *
156
+ * for (int i = 0; i < parse.nonOptionsCount(); ++i)
157
+ * std::cout << "Non-option #" << i << ": " << parse.nonOption(i) << "\n";
158
+ * }
159
+ * @endcode
160
+ *
161
+ * @par Option syntax:
162
+ * @li The Lean Mean C++ Option Parser follows POSIX <code>getopt()</code> conventions and supports
163
+ * GNU-style <code>getopt_long()</code> long options as well as Perl-style single-minus
164
+ * long options (<code>getopt_long_only()</code>).
165
+ * @li short options have the format @c -X where @c X is any character that fits in a char.
166
+ * @li short options can be grouped, i.e. <code>-X -Y</code> is equivalent to @c -XY.
167
+ * @li a short option may take an argument either separate (<code>-X foo</code>) or
168
+ * attached (@c -Xfoo). You can make the parser accept the additional format @c -X=foo by
169
+ * registering @c X as a long option (in addition to being a short option) and
170
+ * enabling single-minus long options.
171
+ * @li an argument-taking short option may be grouped if it is the last in the group, e.g.
172
+ * @c -ABCXfoo or <code> -ABCX foo </code> (@c foo is the argument to the @c -X option).
173
+ * @li a lone minus character @c '-' is not treated as an option. It is customarily used where
174
+ * a file name is expected to refer to stdin or stdout.
175
+ * @li long options have the format @c --option-name.
176
+ * @li the option-name of a long option can be anything and include any characters.
177
+ * Even @c = characters will work, but don't do that.
178
+ * @li [optional] long options may be abbreviated as long as the abbreviation is unambiguous.
179
+ * You can set a minimum length for abbreviations.
180
+ * @li [optional] long options may begin with a single minus. The double minus form is always
181
+ * accepted, too.
182
+ * @li a long option may take an argument either separate (<code> --option arg </code>) or
183
+ * attached (<code> --option=arg </code>). In the attached form the equals sign is mandatory.
184
+ * @li an empty string can be passed as an attached long option argument: <code> --option-name= </code>.
185
+ * Note the distinction between an empty string as argument and no argument at all.
186
+ * @li an empty string is permitted as separate argument to both long and short options.
187
+ * @li Arguments to both short and long options may start with a @c '-' character. E.g.
188
+ * <code> -X-X </code>, <code>-X -X</code> or <code> --long-X=-X </code>. If @c -X
189
+ * and @c --long-X take an argument, that argument will be @c "-X" in all 3 cases.
190
+ * @li If using the built-in @ref option::Arg::Optional "Arg::Optional", optional arguments must
191
+ * be attached.
192
+ * @li the special option @c -- (i.e. without a name) terminates the list of
193
+ * options. Everything that follows is a non-option argument, even if it starts with
194
+ * a @c '-' character. The @c -- itself will not appear in the parse results.
195
+ * @li the first argument that doesn't start with @c '-' or @c '--' and does not belong to
196
+ * a preceding argument-taking option, will terminate the option list and is the
197
+ * first non-option argument. All following command line arguments are treated as
198
+ * non-option arguments, even if they start with @c '-' . @n
199
+ * NOTE: This behaviour is mandated by POSIX, but GNU getopt() only honours this if it is
200
+ * explicitly requested (e.g. by setting POSIXLY_CORRECT). @n
201
+ * You can enable the GNU behaviour by passing @c true as first argument to
202
+ * e.g. @ref option::Parser::parse() "Parser::parse()".
203
+ * @li Arguments that look like options (i.e. @c '-' followed by at least 1 character) but
204
+ * aren't, are NOT treated as non-option arguments. They are treated as unknown options and
205
+ * are collected into a list of unknown options for error reporting. @n
206
+ * This means that in order to pass a first non-option
207
+ * argument beginning with the minus character it is required to use the
208
+ * @c -- special option, e.g.
209
+ * @code
210
+ * program -x -- --strange-filename
211
+ * @endcode
212
+ * In this example, @c --strange-filename is a non-option argument. If the @c --
213
+ * were omitted, it would be treated as an unknown option. @n
214
+ * See @ref option::Descriptor::longopt for information on how to collect unknown options.
215
+ *
216
+ */
217
+
218
+ #ifndef OPTIONPARSER_H_
219
+ #define OPTIONPARSER_H_
220
+
221
+ #ifdef _MSC_VER
222
+ #include <intrin.h>
223
+ #pragma intrinsic(_BitScanReverse)
224
+ #endif
225
+
226
+ /** @brief The namespace of The Lean Mean C++ Option Parser. */
227
+ namespace option
228
+ {
229
+
230
+ #ifdef _MSC_VER
231
+ struct MSC_Builtin_CLZ
232
+ {
233
+ static int builtin_clz(unsigned x)
234
+ {
235
+ unsigned long index;
236
+ _BitScanReverse(&index, x);
237
+ return 32-index; // int is always 32bit on Windows, even for target x64
238
+ }
239
+ };
240
+ #define __builtin_clz(x) MSC_Builtin_CLZ::builtin_clz(x)
241
+ #endif
242
+
243
+ class Option;
244
+
245
+ /**
246
+ * @brief Possible results when checking if an argument is valid for a certain option.
247
+ *
248
+ * In the case that no argument is provided for an option that takes an
249
+ * optional argument, return codes @c ARG_OK and @c ARG_IGNORE are equivalent.
250
+ */
251
+ enum ArgStatus
252
+ {
253
+ //! The option does not take an argument.
254
+ ARG_NONE,
255
+ //! The argument is acceptable for the option.
256
+ ARG_OK,
257
+ //! The argument is not acceptable but that's non-fatal because the option's argument is optional.
258
+ ARG_IGNORE,
259
+ //! The argument is not acceptable and that's fatal.
260
+ ARG_ILLEGAL
261
+ };
262
+
263
+ /**
264
+ * @brief Signature of functions that check if an argument is valid for a certain type of option.
265
+ *
266
+ * Every Option has such a function assigned in its Descriptor.
267
+ * @code
268
+ * Descriptor usage[] = { {UNKNOWN, 0, "", "", Arg::None, ""}, ... };
269
+ * @endcode
270
+ *
271
+ * A CheckArg function has the following signature:
272
+ * @code ArgStatus CheckArg(const Option& option, bool msg); @endcode
273
+ *
274
+ * It is used to check if a potential argument would be acceptable for the option.
275
+ * It will even be called if there is no argument. In that case @c option.arg will be @c NULL.
276
+ *
277
+ * If @c msg is @c true and the function determines that an argument is not acceptable and
278
+ * that this is a fatal error, it should output a message to the user before
279
+ * returning @ref ARG_ILLEGAL. If @c msg is @c false the function should remain silent (or you
280
+ * will get duplicate messages).
281
+ *
282
+ * See @ref ArgStatus for the meaning of the return values.
283
+ *
284
+ * While you can provide your own functions,
285
+ * often the following pre-defined checks (which never return @ref ARG_ILLEGAL) will suffice:
286
+ *
287
+ * @li @c Arg::None @copybrief Arg::None
288
+ * @li @c Arg::Optional @copybrief Arg::Optional
289
+ *
290
+ */
291
+ typedef ArgStatus (*CheckArg)(const Option& option, bool msg);
292
+
293
+ /**
294
+ * @brief Describes an option, its help text (usage) and how it should be parsed.
295
+ *
296
+ * The main input when constructing an option::Parser is an array of Descriptors.
297
+
298
+ * @par Example:
299
+ * @code
300
+ * enum OptionIndex {CREATE, ...};
301
+ * enum OptionType {DISABLE, ENABLE, OTHER};
302
+ *
303
+ * const option::Descriptor usage[] = {
304
+ * { CREATE, // index
305
+ * OTHER, // type
306
+ * "c", // shortopt
307
+ * "create", // longopt
308
+ * Arg::None, // check_arg
309
+ * "--create Tells the program to create something." // help
310
+ * }
311
+ * , ...
312
+ * };
313
+ * @endcode
314
+ */
315
+ struct Descriptor
316
+ {
317
+ /**
318
+ * @brief Index of this option's linked list in the array filled in by the parser.
319
+ *
320
+ * Command line options whose Descriptors have the same index will end up in the same
321
+ * linked list in the order in which they appear on the command line. If you have
322
+ * multiple long option aliases that refer to the same option, give their descriptors
323
+ * the same @c index.
324
+ *
325
+ * If you have options that mean exactly opposite things
326
+ * (e.g. @c --enable-foo and @c --disable-foo ), you should also give them the same
327
+ * @c index, but distinguish them through different values for @ref type.
328
+ * That way they end up in the same list and you can just take the last element of the
329
+ * list and use its type. This way you get the usual behaviour where switches later
330
+ * on the command line override earlier ones without having to code it manually.
331
+ *
332
+ * @par Tip:
333
+ * Use an enum rather than plain ints for better readability, as shown in the example
334
+ * at Descriptor.
335
+ */
336
+ const unsigned index;
337
+
338
+ /**
339
+ * @brief Used to distinguish between options with the same @ref index.
340
+ * See @ref index for details.
341
+ *
342
+ * It is recommended that you use an enum rather than a plain int to make your
343
+ * code more readable.
344
+ */
345
+ const int type;
346
+
347
+ /**
348
+ * @brief Each char in this string will be accepted as a short option character.
349
+ *
350
+ * The string must not include the minus character @c '-' or you'll get undefined
351
+ * behaviour.
352
+ *
353
+ * If this Descriptor should not have short option characters, use the empty
354
+ * string "". NULL is not permitted here!
355
+ *
356
+ * See @ref longopt for more information.
357
+ */
358
+ const char* const shortopt;
359
+
360
+ /**
361
+ * @brief The long option name (without the leading @c -- ).
362
+ *
363
+ * If this Descriptor should not have a long option name, use the empty
364
+ * string "". NULL is not permitted here!
365
+ *
366
+ * While @ref shortopt allows multiple short option characters, each
367
+ * Descriptor can have only a single long option name. If you have multiple
368
+ * long option names referring to the same option use separate Descriptors
369
+ * that have the same @ref index and @ref type. You may repeat
370
+ * short option characters in such an alias Descriptor but there's no need to.
371
+ *
372
+ * @par Dummy Descriptors:
373
+ * You can use dummy Descriptors with an
374
+ * empty string for both @ref shortopt and @ref longopt to add text to
375
+ * the usage that is not related to a specific option. See @ref help.
376
+ * The first dummy Descriptor will be used for unknown options (see below).
377
+ *
378
+ * @par Unknown Option Descriptor:
379
+ * The first dummy Descriptor in the list of Descriptors,
380
+ * whose @ref shortopt and @ref longopt are both the empty string, will be used
381
+ * as the Descriptor for unknown options. An unknown option is a string in
382
+ * the argument vector that is not a lone minus @c '-' but starts with a minus
383
+ * character and does not match any Descriptor's @ref shortopt or @ref longopt. @n
384
+ * Note that the dummy descriptor's @ref check_arg function @e will be called and
385
+ * its return value will be evaluated as usual. I.e. if it returns @ref ARG_ILLEGAL
386
+ * the parsing will be aborted with <code>Parser::error()==true</code>. @n
387
+ * if @c check_arg does not return @ref ARG_ILLEGAL the descriptor's
388
+ * @ref index @e will be used to pick the linked list into which
389
+ * to put the unknown option. @n
390
+ * If there is no dummy descriptor, unknown options will be dropped silently.
391
+ *
392
+ */
393
+ const char* const longopt;
394
+
395
+ /**
396
+ * @brief For each option that matches @ref shortopt or @ref longopt this function
397
+ * will be called to check a potential argument to the option.
398
+ *
399
+ * This function will be called even if there is no potential argument. In that case
400
+ * it will be passed @c NULL as @c arg parameter. Do not confuse this with the empty
401
+ * string.
402
+ *
403
+ * See @ref CheckArg for more information.
404
+ */
405
+ const CheckArg check_arg;
406
+
407
+ /**
408
+ * @brief The usage text associated with the options in this Descriptor.
409
+ *
410
+ * You can use option::printUsage() to format your usage message based on
411
+ * the @c help texts. You can use dummy Descriptors where
412
+ * @ref shortopt and @ref longopt are both the empty string to add text to
413
+ * the usage that is not related to a specific option.
414
+ *
415
+ * See option::printUsage() for special formatting characters you can use in
416
+ * @c help to get a column layout.
417
+ *
418
+ * @attention
419
+ * Must be UTF-8-encoded. If your compiler supports C++11 you can use the "u8"
420
+ * prefix to make sure string literals are properly encoded.
421
+ */
422
+ const char* help;
423
+ };
424
+
425
+ /**
426
+ * @brief A parsed option from the command line together with its argument if it has one.
427
+ *
428
+ * The Parser chains all parsed options with the same Descriptor::index together
429
+ * to form a linked list. This allows you to easily implement all of the common ways
430
+ * of handling repeated options and enable/disable pairs.
431
+ *
432
+ * @li Test for presence of a switch in the argument vector:
433
+ * @code if ( options[QUIET] ) ... @endcode
434
+ * @li Evaluate --enable-foo/--disable-foo pair where the last one used wins:
435
+ * @code if ( options[FOO].last()->type() == DISABLE ) ... @endcode
436
+ * @li Cumulative option (-v verbose, -vv more verbose, -vvv even more verbose):
437
+ * @code int verbosity = options[VERBOSE].count(); @endcode
438
+ * @li Iterate over all --file=&lt;fname> arguments:
439
+ * @code for (Option* opt = options[FILE]; opt; opt = opt->next())
440
+ * fname = opt->arg; ... @endcode
441
+ */
442
+ class Option
443
+ {
444
+ Option* next_;
445
+ Option* prev_;
446
+ public:
447
+ /**
448
+ * @brief Pointer to this Option's Descriptor.
449
+ *
450
+ * Remember that the first dummy descriptor (see @ref Descriptor::longopt) is used
451
+ * for unknown options.
452
+ *
453
+ * @attention
454
+ * @c desc==NULL signals that this Option is unused. This is the default state of
455
+ * elements in the result array. You don't need to test @c desc explicitly. You
456
+ * can simply write something like this:
457
+ * @code
458
+ * if (options[CREATE])
459
+ * {
460
+ * ...
461
+ * }
462
+ * @endcode
463
+ * This works because of <code> operator const Option*() </code>.
464
+ */
465
+ const Descriptor* desc;
466
+
467
+ /**
468
+ * @brief The name of the option as used on the command line.
469
+ *
470
+ * The main purpose of this string is to be presented to the user in messages.
471
+ *
472
+ * In the case of a long option, this is the actual @c argv pointer, i.e. the first
473
+ * character is a '-'. In the case of a short option this points to the option
474
+ * character within the @c argv string.
475
+ *
476
+ * Note that in the case of a short option group or an attached option argument, this
477
+ * string will contain additional characters following the actual name. Use @ref namelen
478
+ * to filter out the actual option name only.
479
+ *
480
+ */
481
+ const char* name;
482
+
483
+ /**
484
+ * @brief Pointer to this Option's argument (if any).
485
+ *
486
+ * NULL if this option has no argument. Do not confuse this with the empty string which
487
+ * is a valid argument.
488
+ */
489
+ const char* arg;
490
+
491
+ /**
492
+ * @brief The length of the option @ref name.
493
+ *
494
+ * Because @ref name points into the actual @c argv string, the option name may be
495
+ * followed by more characters (e.g. other short options in the same short option group).
496
+ * This value is the number of bytes (not characters!) that are part of the actual name.
497
+ *
498
+ * For a short option, this length is always 1. For a long option this length is always
499
+ * at least 2 if single minus long options are permitted and at least 3 if they are disabled.
500
+ *
501
+ * @note
502
+ * In the pathological case of a minus within a short option group (e.g. @c -xf-z), this
503
+ * length is incorrect, because this case will be misinterpreted as a long option and the
504
+ * name will therefore extend to the string's 0-terminator or a following '=" character
505
+ * if there is one. This is irrelevant for most uses of @ref name and @c namelen. If you
506
+ * really need to distinguish the case of a long and a short option, compare @ref name to
507
+ * the @c argv pointers. A long option's @c name is always identical to one of them,
508
+ * whereas a short option's is never.
509
+ */
510
+ int namelen;
511
+
512
+ /**
513
+ * @brief Returns Descriptor::type of this Option's Descriptor, or 0 if this Option
514
+ * is invalid (unused).
515
+ *
516
+ * Because this method (and last(), too) can be used even on unused Options with desc==0, you can (provided
517
+ * you arrange your types properly) switch on type() without testing validity first.
518
+ * @code
519
+ * enum OptionType { UNUSED=0, DISABLED=0, ENABLED=1 };
520
+ * enum OptionIndex { FOO };
521
+ * const Descriptor usage[] = {
522
+ * { FOO, ENABLED, "", "enable-foo", Arg::None, 0 },
523
+ * { FOO, DISABLED, "", "disable-foo", Arg::None, 0 },
524
+ * { 0, 0, 0, 0, 0, 0 } };
525
+ * ...
526
+ * switch(options[FOO].last()->type()) // no validity check required!
527
+ * {
528
+ * case ENABLED: ...
529
+ * case DISABLED: ... // UNUSED==DISABLED !
530
+ * }
531
+ * @endcode
532
+ */
533
+ int type() const
534
+ {
535
+ return desc == 0 ? 0 : desc->type;
536
+ }
537
+
538
+ /**
539
+ * @brief Returns Descriptor::index of this Option's Descriptor, or -1 if this Option
540
+ * is invalid (unused).
541
+ */
542
+ int index() const
543
+ {
544
+ return desc == 0 ? -1 : (int)desc->index;
545
+ }
546
+
547
+ /**
548
+ * @brief Returns the number of times this Option (or others with the same Descriptor::index)
549
+ * occurs in the argument vector.
550
+ *
551
+ * This corresponds to the number of elements in the linked list this Option is part of.
552
+ * It doesn't matter on which element you call count(). The return value is always the same.
553
+ *
554
+ * Use this to implement cumulative options, such as -v, -vv, -vvv for
555
+ * different verbosity levels.
556
+ *
557
+ * Returns 0 when called for an unused/invalid option.
558
+ */
559
+ int count() const
560
+ {
561
+ int c = (desc == 0 ? 0 : 1);
562
+ const Option* p = first();
563
+ while (!p->isLast())
564
+ {
565
+ ++c;
566
+ p = p->next_;
567
+ };
568
+ return c;
569
+ }
570
+
571
+ /**
572
+ * @brief Returns true iff this is the first element of the linked list.
573
+ *
574
+ * The first element in the linked list is the first option on the command line
575
+ * that has the respective Descriptor::index value.
576
+ *
577
+ * Returns true for an unused/invalid option.
578
+ */
579
+ bool isFirst() const
580
+ {
581
+ return isTagged(prev_);
582
+ }
583
+
584
+ /**
585
+ * @brief Returns true iff this is the last element of the linked list.
586
+ *
587
+ * The last element in the linked list is the last option on the command line
588
+ * that has the respective Descriptor::index value.
589
+ *
590
+ * Returns true for an unused/invalid option.
591
+ */
592
+ bool isLast() const
593
+ {
594
+ return isTagged(next_);
595
+ }
596
+
597
+ /**
598
+ * @brief Returns a pointer to the first element of the linked list.
599
+ *
600
+ * Use this when you want the first occurrence of an option on the command line to
601
+ * take precedence. Note that this is not the way most programs handle options.
602
+ * You should probably be using last() instead.
603
+ *
604
+ * @note
605
+ * This method may be called on an unused/invalid option and will return a pointer to the
606
+ * option itself.
607
+ */
608
+ Option* first()
609
+ {
610
+ Option* p = this;
611
+ while (!p->isFirst())
612
+ p = p->prev_;
613
+ return p;
614
+ }
615
+
616
+ /**
617
+ * const version of Option::first().
618
+ */
619
+ const Option* first() const
620
+ {
621
+ return const_cast<Option*>(this)->first();
622
+ }
623
+
624
+ /**
625
+ * @brief Returns a pointer to the last element of the linked list.
626
+ *
627
+ * Use this when you want the last occurrence of an option on the command line to
628
+ * take precedence. This is the most common way of handling conflicting options.
629
+ *
630
+ * @note
631
+ * This method may be called on an unused/invalid option and will return a pointer to the
632
+ * option itself.
633
+ *
634
+ * @par Tip:
635
+ * If you have options with opposite meanings (e.g. @c --enable-foo and @c --disable-foo), you
636
+ * can assign them the same Descriptor::index to get them into the same list. Distinguish them by
637
+ * Descriptor::type and all you have to do is check <code> last()->type() </code> to get
638
+ * the state listed last on the command line.
639
+ */
640
+ Option* last()
641
+ {
642
+ return first()->prevwrap();
643
+ }
644
+
645
+ /**
646
+ * const version of Option::last().
647
+ */
648
+ const Option* last() const
649
+ {
650
+ return first()->prevwrap();
651
+ }
652
+
653
+ /**
654
+ * @brief Returns a pointer to the previous element of the linked list or NULL if
655
+ * called on first().
656
+ *
657
+ * If called on first() this method returns NULL. Otherwise it will return the
658
+ * option with the same Descriptor::index that precedes this option on the command
659
+ * line.
660
+ */
661
+ Option* prev()
662
+ {
663
+ return isFirst() ? 0 : prev_;
664
+ }
665
+
666
+ /**
667
+ * @brief Returns a pointer to the previous element of the linked list with wrap-around from
668
+ * first() to last().
669
+ *
670
+ * If called on first() this method returns last(). Otherwise it will return the
671
+ * option with the same Descriptor::index that precedes this option on the command
672
+ * line.
673
+ */
674
+ Option* prevwrap()
675
+ {
676
+ return untag(prev_);
677
+ }
678
+
679
+ /**
680
+ * const version of Option::prevwrap().
681
+ */
682
+ const Option* prevwrap() const
683
+ {
684
+ return untag(prev_);
685
+ }
686
+
687
+ /**
688
+ * @brief Returns a pointer to the next element of the linked list or NULL if called
689
+ * on last().
690
+ *
691
+ * If called on last() this method returns NULL. Otherwise it will return the
692
+ * option with the same Descriptor::index that follows this option on the command
693
+ * line.
694
+ */
695
+ Option* next()
696
+ {
697
+ return isLast() ? 0 : next_;
698
+ }
699
+
700
+ /**
701
+ * const version of Option::next().
702
+ */
703
+ const Option* next() const
704
+ {
705
+ return isLast() ? 0 : next_;
706
+ }
707
+
708
+ /**
709
+ * @brief Returns a pointer to the next element of the linked list with wrap-around from
710
+ * last() to first().
711
+ *
712
+ * If called on last() this method returns first(). Otherwise it will return the
713
+ * option with the same Descriptor::index that follows this option on the command
714
+ * line.
715
+ */
716
+ Option* nextwrap()
717
+ {
718
+ return untag(next_);
719
+ }
720
+
721
+ /**
722
+ * @brief Makes @c new_last the new last() by chaining it into the list after last().
723
+ *
724
+ * It doesn't matter which element you call append() on. The new element will always
725
+ * be appended to last().
726
+ *
727
+ * @attention
728
+ * @c new_last must not yet be part of a list, or that list will become corrupted, because
729
+ * this method does not unchain @c new_last from an existing list.
730
+ */
731
+ void append(Option* new_last)
732
+ {
733
+ Option* p = last();
734
+ Option* f = first();
735
+ p->next_ = new_last;
736
+ new_last->prev_ = p;
737
+ new_last->next_ = tag(f);
738
+ f->prev_ = tag(new_last);
739
+ }
740
+
741
+ /**
742
+ * @brief Casts from Option to const Option* but only if this Option is valid.
743
+ *
744
+ * If this Option is valid (i.e. @c desc!=NULL), returns this.
745
+ * Otherwise returns NULL. This allows testing an Option directly
746
+ * in an if-clause to see if it is used:
747
+ * @code
748
+ * if (options[CREATE])
749
+ * {
750
+ * ...
751
+ * }
752
+ * @endcode
753
+ * It also allows you to write loops like this:
754
+ * @code for (Option* opt = options[FILE]; opt; opt = opt->next())
755
+ * fname = opt->arg; ... @endcode
756
+ */
757
+ operator const Option*() const
758
+ {
759
+ return desc ? this : 0;
760
+ }
761
+
762
+ /**
763
+ * @brief Casts from Option to Option* but only if this Option is valid.
764
+ *
765
+ * If this Option is valid (i.e. @c desc!=NULL), returns this.
766
+ * Otherwise returns NULL. This allows testing an Option directly
767
+ * in an if-clause to see if it is used:
768
+ * @code
769
+ * if (options[CREATE])
770
+ * {
771
+ * ...
772
+ * }
773
+ * @endcode
774
+ * It also allows you to write loops like this:
775
+ * @code for (Option* opt = options[FILE]; opt; opt = opt->next())
776
+ * fname = opt->arg; ... @endcode
777
+ */
778
+ operator Option*()
779
+ {
780
+ return desc ? this : 0;
781
+ }
782
+
783
+ /**
784
+ * @brief Creates a new Option that is a one-element linked list and has NULL
785
+ * @ref desc, @ref name, @ref arg and @ref namelen.
786
+ */
787
+ Option() :
788
+ desc(0), name(0), arg(0), namelen(0)
789
+ {
790
+ prev_ = tag(this);
791
+ next_ = tag(this);
792
+ }
793
+
794
+ /**
795
+ * @brief Creates a new Option that is a one-element linked list and has the given
796
+ * values for @ref desc, @ref name and @ref arg.
797
+ *
798
+ * If @c name_ points at a character other than '-' it will be assumed to refer to a
799
+ * short option and @ref namelen will be set to 1. Otherwise the length will extend to
800
+ * the first '=' character or the string's 0-terminator.
801
+ */
802
+ Option(const Descriptor* desc_, const char* name_, const char* arg_)
803
+ {
804
+ init(desc_, name_, arg_);
805
+ }
806
+
807
+ /**
808
+ * @brief Makes @c *this a copy of @c orig except for the linked list pointers.
809
+ *
810
+ * After this operation @c *this will be a one-element linked list.
811
+ */
812
+ void operator=(const Option& orig)
813
+ {
814
+ init(orig.desc, orig.name, orig.arg);
815
+ }
816
+
817
+ /**
818
+ * @brief Makes @c *this a copy of @c orig except for the linked list pointers.
819
+ *
820
+ * After this operation @c *this will be a one-element linked list.
821
+ */
822
+ Option(const Option& orig)
823
+ {
824
+ init(orig.desc, orig.name, orig.arg);
825
+ }
826
+
827
+ private:
828
+ /**
829
+ * @internal
830
+ * @brief Sets the fields of this Option to the given values (extracting @c name if necessary).
831
+ *
832
+ * If @c name_ points at a character other than '-' it will be assumed to refer to a
833
+ * short option and @ref namelen will be set to 1. Otherwise the length will extend to
834
+ * the first '=' character or the string's 0-terminator.
835
+ */
836
+ void init(const Descriptor* desc_, const char* name_, const char* arg_)
837
+ {
838
+ desc = desc_;
839
+ name = name_;
840
+ arg = arg_;
841
+ prev_ = tag(this);
842
+ next_ = tag(this);
843
+ namelen = 0;
844
+ if (name == 0)
845
+ return;
846
+ namelen = 1;
847
+ if (name[0] != '-')
848
+ return;
849
+ while (name[namelen] != 0 && name[namelen] != '=')
850
+ ++namelen;
851
+ }
852
+
853
+ static Option* tag(Option* ptr)
854
+ {
855
+ return (Option*) ((unsigned long long) ptr | 1);
856
+ }
857
+
858
+ static Option* untag(Option* ptr)
859
+ {
860
+ return (Option*) ((unsigned long long) ptr & ~1ull);
861
+ }
862
+
863
+ static bool isTagged(Option* ptr)
864
+ {
865
+ return ((unsigned long long) ptr & 1);
866
+ }
867
+ };
868
+
869
+ /**
870
+ * @brief Functions for checking the validity of option arguments.
871
+ *
872
+ * @copydetails CheckArg
873
+ *
874
+ * The following example code
875
+ * can serve as starting place for writing your own more complex CheckArg functions:
876
+ * @code
877
+ * struct Arg: public option::Arg
878
+ * {
879
+ * static void printError(const char* msg1, const option::Option& opt, const char* msg2)
880
+ * {
881
+ * fprintf(stderr, "ERROR: %s", msg1);
882
+ * fwrite(opt.name, opt.namelen, 1, stderr);
883
+ * fprintf(stderr, "%s", msg2);
884
+ * }
885
+ *
886
+ * static option::ArgStatus Unknown(const option::Option& option, bool msg)
887
+ * {
888
+ * if (msg) printError("Unknown option '", option, "'\n");
889
+ * return option::ARG_ILLEGAL;
890
+ * }
891
+ *
892
+ * static option::ArgStatus Required(const option::Option& option, bool msg)
893
+ * {
894
+ * if (option.arg != 0)
895
+ * return option::ARG_OK;
896
+ *
897
+ * if (msg) printError("Option '", option, "' requires an argument\n");
898
+ * return option::ARG_ILLEGAL;
899
+ * }
900
+ *
901
+ * static option::ArgStatus NonEmpty(const option::Option& option, bool msg)
902
+ * {
903
+ * if (option.arg != 0 && option.arg[0] != 0)
904
+ * return option::ARG_OK;
905
+ *
906
+ * if (msg) printError("Option '", option, "' requires a non-empty argument\n");
907
+ * return option::ARG_ILLEGAL;
908
+ * }
909
+ *
910
+ * static option::ArgStatus Numeric(const option::Option& option, bool msg)
911
+ * {
912
+ * char* endptr = 0;
913
+ * if (option.arg != 0 && strtol(option.arg, &endptr, 10)){};
914
+ * if (endptr != option.arg && *endptr == 0)
915
+ * return option::ARG_OK;
916
+ *
917
+ * if (msg) printError("Option '", option, "' requires a numeric argument\n");
918
+ * return option::ARG_ILLEGAL;
919
+ * }
920
+ * };
921
+ * @endcode
922
+ */
923
+ struct Arg
924
+ {
925
+ //! @brief For options that don't take an argument: Returns ARG_NONE.
926
+ static ArgStatus None(const Option&, bool)
927
+ {
928
+ return ARG_NONE;
929
+ }
930
+
931
+ //! @brief Returns ARG_OK if the argument is attached and ARG_IGNORE otherwise.
932
+ static ArgStatus Optional(const Option& option, bool)
933
+ {
934
+ if (option.arg && option.name[option.namelen] != 0)
935
+ return ARG_OK;
936
+ else
937
+ return ARG_IGNORE;
938
+ }
939
+ };
940
+
941
+ /**
942
+ * @brief Determines the minimum lengths of the buffer and options arrays used for Parser.
943
+ *
944
+ * Because Parser doesn't use dynamic memory its output arrays have to be pre-allocated.
945
+ * If you don't want to use fixed size arrays (which may turn out too small, causing
946
+ * command line arguments to be dropped), you can use Stats to determine the correct sizes.
947
+ * Stats work cumulative. You can first pass in your default options and then the real
948
+ * options and afterwards the counts will reflect the union.
949
+ */
950
+ struct Stats
951
+ {
952
+ /**
953
+ * @brief Number of elements needed for a @c buffer[] array to be used for
954
+ * @ref Parser::parse() "parsing" the same argument vectors that were fed
955
+ * into this Stats object.
956
+ *
957
+ * @note
958
+ * This number is always 1 greater than the actual number needed, to give
959
+ * you a sentinel element.
960
+ */
961
+ unsigned buffer_max;
962
+
963
+ /**
964
+ * @brief Number of elements needed for an @c options[] array to be used for
965
+ * @ref Parser::parse() "parsing" the same argument vectors that were fed
966
+ * into this Stats object.
967
+ *
968
+ * @note
969
+ * @li This number is always 1 greater than the actual number needed, to give
970
+ * you a sentinel element.
971
+ * @li This number depends only on the @c usage, not the argument vectors, because
972
+ * the @c options array needs exactly one slot for each possible Descriptor::index.
973
+ */
974
+ unsigned options_max;
975
+
976
+ /**
977
+ * @brief Creates a Stats object with counts set to 1 (for the sentinel element).
978
+ */
979
+ Stats() :
980
+ buffer_max(1), options_max(1) // 1 more than necessary as sentinel
981
+ {
982
+ }
983
+
984
+ /**
985
+ * @brief Creates a new Stats object and immediately updates it for the
986
+ * given @c usage and argument vector. You may pass 0 for @c argc and/or @c argv,
987
+ * if you just want to update @ref options_max.
988
+ *
989
+ * @note
990
+ * The calls to Stats methods must match the later calls to Parser methods.
991
+ * See Parser::parse() for the meaning of the arguments.
992
+ */
993
+ Stats(bool gnu, const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //
994
+ bool single_minus_longopt = false) :
995
+ buffer_max(1), options_max(1) // 1 more than necessary as sentinel
996
+ {
997
+ add(gnu, usage, argc, argv, min_abbr_len, single_minus_longopt);
998
+ }
999
+
1000
+ //! @brief Stats(...) with non-const argv.
1001
+ Stats(bool gnu, const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //
1002
+ bool single_minus_longopt = false) :
1003
+ buffer_max(1), options_max(1) // 1 more than necessary as sentinel
1004
+ {
1005
+ add(gnu, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);
1006
+ }
1007
+
1008
+ //! @brief POSIX Stats(...) (gnu==false).
1009
+ Stats(const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //
1010
+ bool single_minus_longopt = false) :
1011
+ buffer_max(1), options_max(1) // 1 more than necessary as sentinel
1012
+ {
1013
+ add(false, usage, argc, argv, min_abbr_len, single_minus_longopt);
1014
+ }
1015
+
1016
+ //! @brief POSIX Stats(...) (gnu==false) with non-const argv.
1017
+ Stats(const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //
1018
+ bool single_minus_longopt = false) :
1019
+ buffer_max(1), options_max(1) // 1 more than necessary as sentinel
1020
+ {
1021
+ add(false, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);
1022
+ }
1023
+
1024
+ /**
1025
+ * @brief Updates this Stats object for the
1026
+ * given @c usage and argument vector. You may pass 0 for @c argc and/or @c argv,
1027
+ * if you just want to update @ref options_max.
1028
+ *
1029
+ * @note
1030
+ * The calls to Stats methods must match the later calls to Parser methods.
1031
+ * See Parser::parse() for the meaning of the arguments.
1032
+ */
1033
+ void add(bool gnu, const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //
1034
+ bool single_minus_longopt = false);
1035
+
1036
+ //! @brief add() with non-const argv.
1037
+ void add(bool gnu, const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //
1038
+ bool single_minus_longopt = false)
1039
+ {
1040
+ add(gnu, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);
1041
+ }
1042
+
1043
+ //! @brief POSIX add() (gnu==false).
1044
+ void add(const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //
1045
+ bool single_minus_longopt = false)
1046
+ {
1047
+ add(false, usage, argc, argv, min_abbr_len, single_minus_longopt);
1048
+ }
1049
+
1050
+ //! @brief POSIX add() (gnu==false) with non-const argv.
1051
+ void add(const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //
1052
+ bool single_minus_longopt = false)
1053
+ {
1054
+ add(false, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);
1055
+ }
1056
+ private:
1057
+ class CountOptionsAction;
1058
+ };
1059
+
1060
+ /**
1061
+ * @brief Checks argument vectors for validity and parses them into data
1062
+ * structures that are easier to work with.
1063
+ *
1064
+ * @par Example:
1065
+ * @code
1066
+ * int main(int argc, char* argv[])
1067
+ * {
1068
+ * argc-=(argc>0); argv+=(argc>0); // skip program name argv[0] if present
1069
+ * option::Stats stats(usage, argc, argv);
1070
+ * option::Option options[stats.options_max], buffer[stats.buffer_max];
1071
+ * option::Parser parse(usage, argc, argv, options, buffer);
1072
+ *
1073
+ * if (parse.error())
1074
+ * return 1;
1075
+ *
1076
+ * if (options[HELP])
1077
+ * ...
1078
+ * @endcode
1079
+ */
1080
+ class Parser
1081
+ {
1082
+ int op_count; //!< @internal @brief see optionsCount()
1083
+ int nonop_count; //!< @internal @brief see nonOptionsCount()
1084
+ const char** nonop_args; //!< @internal @brief see nonOptions()
1085
+ bool err; //!< @internal @brief see error()
1086
+ public:
1087
+
1088
+ /**
1089
+ * @brief Creates a new Parser.
1090
+ */
1091
+ Parser() :
1092
+ op_count(0), nonop_count(0), nonop_args(0), err(false)
1093
+ {
1094
+ }
1095
+
1096
+ /**
1097
+ * @brief Creates a new Parser and immediately parses the given argument vector.
1098
+ * @copydetails parse()
1099
+ */
1100
+ Parser(bool gnu, const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[],
1101
+ int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1) :
1102
+ op_count(0), nonop_count(0), nonop_args(0), err(false)
1103
+ {
1104
+ parse(gnu, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1105
+ }
1106
+
1107
+ //! @brief Parser(...) with non-const argv.
1108
+ Parser(bool gnu, const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[],
1109
+ int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1) :
1110
+ op_count(0), nonop_count(0), nonop_args(0), err(false)
1111
+ {
1112
+ parse(gnu, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1113
+ }
1114
+
1115
+ //! @brief POSIX Parser(...) (gnu==false).
1116
+ Parser(const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[], int min_abbr_len = 0,
1117
+ bool single_minus_longopt = false, int bufmax = -1) :
1118
+ op_count(0), nonop_count(0), nonop_args(0), err(false)
1119
+ {
1120
+ parse(false, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1121
+ }
1122
+
1123
+ //! @brief POSIX Parser(...) (gnu==false) with non-const argv.
1124
+ Parser(const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[], int min_abbr_len = 0,
1125
+ bool single_minus_longopt = false, int bufmax = -1) :
1126
+ op_count(0), nonop_count(0), nonop_args(0), err(false)
1127
+ {
1128
+ parse(false, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1129
+ }
1130
+
1131
+ /**
1132
+ * @brief Parses the given argument vector.
1133
+ *
1134
+ * @param gnu if true, parse() will not stop at the first non-option argument. Instead it will
1135
+ * reorder arguments so that all non-options are at the end. This is the default behaviour
1136
+ * of GNU getopt() but is not conforming to POSIX. @n
1137
+ * Note, that once the argument vector has been reordered, the @c gnu flag will have
1138
+ * no further effect on this argument vector. So it is enough to pass @c gnu==true when
1139
+ * creating Stats.
1140
+ * @param usage Array of Descriptor objects that describe the options to support. The last entry
1141
+ * of this array must have 0 in all fields.
1142
+ * @param argc The number of elements from @c argv that are to be parsed. If you pass -1, the number
1143
+ * will be determined automatically. In that case the @c argv list must end with a NULL
1144
+ * pointer.
1145
+ * @param argv The arguments to be parsed. If you pass -1 as @c argc the last pointer in the @c argv
1146
+ * list must be NULL to mark the end.
1147
+ * @param options Each entry is the first element of a linked list of Options. Each new option
1148
+ * that is parsed will be appended to the list specified by that Option's
1149
+ * Descriptor::index. If an entry is not yet used (i.e. the Option is invalid),
1150
+ * it will be replaced rather than appended to. @n
1151
+ * The minimum length of this array is the greatest Descriptor::index value that
1152
+ * occurs in @c usage @e PLUS ONE.
1153
+ * @param buffer Each argument that is successfully parsed (including unknown arguments, if they
1154
+ * have a Descriptor whose CheckArg does not return @ref ARG_ILLEGAL) will be stored in this
1155
+ * array. parse() scans the array for the first invalid entry and begins writing at that
1156
+ * index. You can pass @c bufmax to limit the number of options stored.
1157
+ * @param min_abbr_len Passing a value <code> min_abbr_len > 0 </code> enables abbreviated long
1158
+ * options. The parser will match a prefix of a long option as if it was
1159
+ * the full long option (e.g. @c --foob=10 will be interpreted as if it was
1160
+ * @c --foobar=10 ), as long as the prefix has at least @c min_abbr_len characters
1161
+ * (not counting the @c -- ) and is unambiguous.
1162
+ * @n Be careful if combining @c min_abbr_len=1 with @c single_minus_longopt=true
1163
+ * because the ambiguity check does not consider short options and abbreviated
1164
+ * single minus long options will take precedence over short options.
1165
+ * @param single_minus_longopt Passing @c true for this option allows long options to begin with
1166
+ * a single minus. The double minus form will still be recognized. Note that
1167
+ * single minus long options take precedence over short options and short option
1168
+ * groups. E.g. @c -file would be interpreted as @c --file and not as
1169
+ * <code> -f -i -l -e </code> (assuming a long option named @c "file" exists).
1170
+ * @param bufmax The greatest index in the @c buffer[] array that parse() will write to is
1171
+ * @c bufmax-1. If there are more options, they will be processed (in particular
1172
+ * their CheckArg will be called) but not stored. @n
1173
+ * If you used Stats::buffer_max to dimension this array, you can pass
1174
+ * -1 (or not pass @c bufmax at all) which tells parse() that the buffer is
1175
+ * "large enough".
1176
+ * @attention
1177
+ * Remember that @c options and @c buffer store Option @e objects, not pointers. Therefore it
1178
+ * is not possible for the same object to be in both arrays. For those options that are found in
1179
+ * both @c buffer[] and @c options[] the respective objects are independent copies. And only the
1180
+ * objects in @c options[] are properly linked via Option::next() and Option::prev().
1181
+ * You can iterate over @c buffer[] to
1182
+ * process all options in the order they appear in the argument vector, but if you want access to
1183
+ * the other Options with the same Descriptor::index, then you @e must access the linked list via
1184
+ * @c options[]. You can get the linked list in options from a buffer object via something like
1185
+ * @c options[buffer[i].index()].
1186
+ */
1187
+ void parse(bool gnu, const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[],
1188
+ int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1);
1189
+
1190
+ //! @brief parse() with non-const argv.
1191
+ void parse(bool gnu, const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[],
1192
+ int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1)
1193
+ {
1194
+ parse(gnu, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1195
+ }
1196
+
1197
+ //! @brief POSIX parse() (gnu==false).
1198
+ void parse(const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[],
1199
+ int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1)
1200
+ {
1201
+ parse(false, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1202
+ }
1203
+
1204
+ //! @brief POSIX parse() (gnu==false) with non-const argv.
1205
+ void parse(const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[], int min_abbr_len = 0,
1206
+ bool single_minus_longopt = false, int bufmax = -1)
1207
+ {
1208
+ parse(false, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1209
+ }
1210
+
1211
+ /**
1212
+ * @brief Returns the number of valid Option objects in @c buffer[].
1213
+ *
1214
+ * @note
1215
+ * @li The returned value always reflects the number of Options in the buffer[] array used for
1216
+ * the most recent call to parse().
1217
+ * @li The count (and the buffer[]) includes unknown options if they are collected
1218
+ * (see Descriptor::longopt).
1219
+ */
1220
+ int optionsCount()
1221
+ {
1222
+ return op_count;
1223
+ }
1224
+
1225
+ /**
1226
+ * @brief Returns the number of non-option arguments that remained at the end of the
1227
+ * most recent parse() that actually encountered non-option arguments.
1228
+ *
1229
+ * @note
1230
+ * A parse() that does not encounter non-option arguments will leave this value
1231
+ * as well as nonOptions() undisturbed. This means you can feed the Parser a
1232
+ * default argument vector that contains non-option arguments (e.g. a default filename).
1233
+ * Then you feed it the actual arguments from the user. If the user has supplied at
1234
+ * least one non-option argument, all of the non-option arguments from the default
1235
+ * disappear and are replaced by the user's non-option arguments. However, if the
1236
+ * user does not supply any non-option arguments the defaults will still be in
1237
+ * effect.
1238
+ */
1239
+ int nonOptionsCount()
1240
+ {
1241
+ return nonop_count;
1242
+ }
1243
+
1244
+ /**
1245
+ * @brief Returns a pointer to an array of non-option arguments (only valid
1246
+ * if <code>nonOptionsCount() >0 </code>).
1247
+ *
1248
+ * @note
1249
+ * @li parse() does not copy arguments, so this pointer points into the actual argument
1250
+ * vector as passed to parse().
1251
+ * @li As explained at nonOptionsCount() this pointer is only changed by parse() calls
1252
+ * that actually encounter non-option arguments. A parse() call that encounters only
1253
+ * options, will not change nonOptions().
1254
+ */
1255
+ const char** nonOptions()
1256
+ {
1257
+ return nonop_args;
1258
+ }
1259
+
1260
+ /**
1261
+ * @brief Returns <b><code>nonOptions()[i]</code></b> (@e without checking if i is in range!).
1262
+ */
1263
+ const char* nonOption(int i)
1264
+ {
1265
+ return nonOptions()[i];
1266
+ }
1267
+
1268
+ /**
1269
+ * @brief Returns @c true if an unrecoverable error occurred while parsing options.
1270
+ *
1271
+ * An illegal argument to an option (i.e. CheckArg returns @ref ARG_ILLEGAL) is an
1272
+ * unrecoverable error that aborts the parse. Unknown options are only an error if
1273
+ * their CheckArg function returns @ref ARG_ILLEGAL. Otherwise they are collected.
1274
+ * In that case if you want to exit the program if either an illegal argument
1275
+ * or an unknown option has been passed, use code like this
1276
+ *
1277
+ * @code
1278
+ * if (parser.error() || options[UNKNOWN])
1279
+ * exit(1);
1280
+ * @endcode
1281
+ *
1282
+ */
1283
+ bool error()
1284
+ {
1285
+ return err;
1286
+ }
1287
+
1288
+ private:
1289
+ friend struct Stats;
1290
+ class StoreOptionAction;
1291
+ struct Action;
1292
+
1293
+ /**
1294
+ * @internal
1295
+ * @brief This is the core function that does all the parsing.
1296
+ * @retval false iff an unrecoverable error occurred.
1297
+ */
1298
+ static bool workhorse(bool gnu, const Descriptor usage[], int numargs, const char** args, Action& action,
1299
+ bool single_minus_longopt, bool print_errors, int min_abbr_len);
1300
+
1301
+ /**
1302
+ * @internal
1303
+ * @brief Returns true iff @c st1 is a prefix of @c st2 and
1304
+ * in case @c st2 is longer than @c st1, then
1305
+ * the first additional character is '='.
1306
+ *
1307
+ * @par Examples:
1308
+ * @code
1309
+ * streq("foo", "foo=bar") == true
1310
+ * streq("foo", "foobar") == false
1311
+ * streq("foo", "foo") == true
1312
+ * streq("foo=bar", "foo") == false
1313
+ * @endcode
1314
+ */
1315
+ static bool streq(const char* st1, const char* st2)
1316
+ {
1317
+ while (*st1 != 0)
1318
+ if (*st1++ != *st2++)
1319
+ return false;
1320
+ return (*st2 == 0 || *st2 == '=');
1321
+ }
1322
+
1323
+ /**
1324
+ * @internal
1325
+ * @brief Like streq() but handles abbreviations.
1326
+ *
1327
+ * Returns true iff @c st1 and @c st2 have a common
1328
+ * prefix with the following properties:
1329
+ * @li (if min > 0) its length is at least @c min characters or the same length as @c st1 (whichever is smaller).
1330
+ * @li (if min <= 0) its length is the same as that of @c st1
1331
+ * @li within @c st2 the character following the common prefix is either '=' or end-of-string.
1332
+ *
1333
+ * Examples:
1334
+ * @code
1335
+ * streqabbr("foo", "foo=bar",<anything>) == true
1336
+ * streqabbr("foo", "fo=bar" , 2) == true
1337
+ * streqabbr("foo", "fo" , 2) == true
1338
+ * streqabbr("foo", "fo" , 0) == false
1339
+ * streqabbr("foo", "f=bar" , 2) == false
1340
+ * streqabbr("foo", "f" , 2) == false
1341
+ * streqabbr("fo" , "foo=bar",<anything>) == false
1342
+ * streqabbr("foo", "foobar" ,<anything>) == false
1343
+ * streqabbr("foo", "fobar" ,<anything>) == false
1344
+ * streqabbr("foo", "foo" ,<anything>) == true
1345
+ * @endcode
1346
+ */
1347
+ static bool streqabbr(const char* st1, const char* st2, long long min)
1348
+ {
1349
+ const char* st1start = st1;
1350
+ while (*st1 != 0 && (*st1 == *st2))
1351
+ {
1352
+ ++st1;
1353
+ ++st2;
1354
+ }
1355
+
1356
+ return (*st1 == 0 || (min > 0 && (st1 - st1start) >= min)) && (*st2 == 0 || *st2 == '=');
1357
+ }
1358
+
1359
+ /**
1360
+ * @internal
1361
+ * @brief Returns true iff character @c ch is contained in the string @c st.
1362
+ *
1363
+ * Returns @c true for @c ch==0 .
1364
+ */
1365
+ static bool instr(char ch, const char* st)
1366
+ {
1367
+ while (*st != 0 && *st != ch)
1368
+ ++st;
1369
+ return *st == ch;
1370
+ }
1371
+
1372
+ /**
1373
+ * @internal
1374
+ * @brief Rotates <code>args[-count],...,args[-1],args[0]</code> to become
1375
+ * <code>args[0],args[-count],...,args[-1]</code>.
1376
+ */
1377
+ static void shift(const char** args, int count)
1378
+ {
1379
+ for (int i = 0; i > -count; --i)
1380
+ {
1381
+ const char* temp = args[i];
1382
+ args[i] = args[i - 1];
1383
+ args[i - 1] = temp;
1384
+ }
1385
+ }
1386
+ };
1387
+
1388
+ /**
1389
+ * @internal
1390
+ * @brief Interface for actions Parser::workhorse() should perform for each Option it
1391
+ * parses.
1392
+ */
1393
+ struct Parser::Action
1394
+ {
1395
+ /**
1396
+ * @brief Called by Parser::workhorse() for each Option that has been successfully
1397
+ * parsed (including unknown
1398
+ * options if they have a Descriptor whose Descriptor::check_arg does not return
1399
+ * @ref ARG_ILLEGAL.
1400
+ *
1401
+ * Returns @c false iff a fatal error has occured and the parse should be aborted.
1402
+ */
1403
+ virtual bool perform(Option&)
1404
+ {
1405
+ return true;
1406
+ }
1407
+
1408
+ /**
1409
+ * @brief Called by Parser::workhorse() after finishing the parse.
1410
+ * @param numargs the number of non-option arguments remaining
1411
+ * @param args pointer to the first remaining non-option argument (if numargs > 0).
1412
+ *
1413
+ * @return
1414
+ * @c false iff a fatal error has occurred.
1415
+ */
1416
+ virtual bool finished(int numargs, const char** args)
1417
+ {
1418
+ (void) numargs;
1419
+ (void) args;
1420
+ return true;
1421
+ }
1422
+ };
1423
+
1424
+ /**
1425
+ * @internal
1426
+ * @brief An Action to pass to Parser::workhorse() that will increment a counter for
1427
+ * each parsed Option.
1428
+ */
1429
+ class Stats::CountOptionsAction: public Parser::Action
1430
+ {
1431
+ unsigned* buffer_max;
1432
+ public:
1433
+ /**
1434
+ * Creates a new CountOptionsAction that will increase @c *buffer_max_ for each
1435
+ * parsed Option.
1436
+ */
1437
+ CountOptionsAction(unsigned* buffer_max_) :
1438
+ buffer_max(buffer_max_)
1439
+ {
1440
+ }
1441
+
1442
+ bool perform(Option&)
1443
+ {
1444
+ if (*buffer_max == 0x7fffffff)
1445
+ return false; // overflow protection: don't accept number of options that doesn't fit signed int
1446
+ ++*buffer_max;
1447
+ return true;
1448
+ }
1449
+ };
1450
+
1451
+ /**
1452
+ * @internal
1453
+ * @brief An Action to pass to Parser::workhorse() that will store each parsed Option in
1454
+ * appropriate arrays (see Parser::parse()).
1455
+ */
1456
+ class Parser::StoreOptionAction: public Parser::Action
1457
+ {
1458
+ Parser& parser;
1459
+ Option* options;
1460
+ Option* buffer;
1461
+ int bufmax; //! Number of slots in @c buffer. @c -1 means "large enough".
1462
+ public:
1463
+ /**
1464
+ * @brief Creates a new StoreOption action.
1465
+ * @param parser_ the parser whose op_count should be updated.
1466
+ * @param options_ each Option @c o is chained into the linked list @c options_[o.desc->index]
1467
+ * @param buffer_ each Option is appended to this array as long as there's a free slot.
1468
+ * @param bufmax_ number of slots in @c buffer_. @c -1 means "large enough".
1469
+ */
1470
+ StoreOptionAction(Parser& parser_, Option options_[], Option buffer_[], int bufmax_) :
1471
+ parser(parser_), options(options_), buffer(buffer_), bufmax(bufmax_)
1472
+ {
1473
+ // find first empty slot in buffer (if any)
1474
+ int bufidx = 0;
1475
+ while ((bufmax < 0 || bufidx < bufmax) && buffer[bufidx])
1476
+ ++bufidx;
1477
+
1478
+ // set parser's optionCount
1479
+ parser.op_count = bufidx;
1480
+ }
1481
+
1482
+ bool perform(Option& option)
1483
+ {
1484
+ if (bufmax < 0 || parser.op_count < bufmax)
1485
+ {
1486
+ if (parser.op_count == 0x7fffffff)
1487
+ return false; // overflow protection: don't accept number of options that doesn't fit signed int
1488
+
1489
+ buffer[parser.op_count] = option;
1490
+ int idx = buffer[parser.op_count].desc->index;
1491
+ if (options[idx])
1492
+ options[idx].append(buffer[parser.op_count]);
1493
+ else
1494
+ options[idx] = buffer[parser.op_count];
1495
+ ++parser.op_count;
1496
+ }
1497
+ return true; // NOTE: an option that is discarded because of a full buffer is not fatal
1498
+ }
1499
+
1500
+ bool finished(int numargs, const char** args)
1501
+ {
1502
+ // only overwrite non-option argument list if there's at least 1
1503
+ // new non-option argument. Otherwise we keep the old list. This
1504
+ // makes it easy to use default non-option arguments.
1505
+ if (numargs > 0)
1506
+ {
1507
+ parser.nonop_count = numargs;
1508
+ parser.nonop_args = args;
1509
+ }
1510
+
1511
+ return true;
1512
+ }
1513
+ };
1514
+
1515
+ inline void Parser::parse(bool gnu, const Descriptor usage[], int argc, const char** argv, Option options[],
1516
+ Option buffer[], int min_abbr_len, bool single_minus_longopt, int bufmax)
1517
+ {
1518
+ StoreOptionAction action(*this, options, buffer, bufmax);
1519
+ err = !workhorse(gnu, usage, argc, argv, action, single_minus_longopt, true, min_abbr_len);
1520
+ }
1521
+
1522
+ inline void Stats::add(bool gnu, const Descriptor usage[], int argc, const char** argv, int min_abbr_len,
1523
+ bool single_minus_longopt)
1524
+ {
1525
+ // determine size of options array. This is the greatest index used in the usage + 1
1526
+ int i = 0;
1527
+ while (usage[i].shortopt != 0)
1528
+ {
1529
+ if (usage[i].index + 1 >= options_max)
1530
+ options_max = (usage[i].index + 1) + 1; // 1 more than necessary as sentinel
1531
+
1532
+ ++i;
1533
+ }
1534
+
1535
+ CountOptionsAction action(&buffer_max);
1536
+ Parser::workhorse(gnu, usage, argc, argv, action, single_minus_longopt, false, min_abbr_len);
1537
+ }
1538
+
1539
+ inline bool Parser::workhorse(bool gnu, const Descriptor usage[], int numargs, const char** args, Action& action,
1540
+ bool single_minus_longopt, bool print_errors, int min_abbr_len)
1541
+ {
1542
+ // protect against NULL pointer
1543
+ if (args == 0)
1544
+ numargs = 0;
1545
+
1546
+ int nonops = 0;
1547
+
1548
+ while (numargs != 0 && *args != 0)
1549
+ {
1550
+ const char* param = *args; // param can be --long-option, -srto or non-option argument
1551
+
1552
+ // in POSIX mode the first non-option argument terminates the option list
1553
+ // a lone minus character is a non-option argument
1554
+ if (param[0] != '-' || param[1] == 0)
1555
+ {
1556
+ if (gnu)
1557
+ {
1558
+ ++nonops;
1559
+ ++args;
1560
+ if (numargs > 0)
1561
+ --numargs;
1562
+ continue;
1563
+ }
1564
+ else
1565
+ break;
1566
+ }
1567
+
1568
+ // -- terminates the option list. The -- itself is skipped.
1569
+ if (param[1] == '-' && param[2] == 0)
1570
+ {
1571
+ shift(args, nonops);
1572
+ ++args;
1573
+ if (numargs > 0)
1574
+ --numargs;
1575
+ break;
1576
+ }
1577
+
1578
+ bool handle_short_options;
1579
+ const char* longopt_name;
1580
+ if (param[1] == '-') // if --long-option
1581
+ {
1582
+ handle_short_options = false;
1583
+ longopt_name = param + 2;
1584
+ }
1585
+ else
1586
+ {
1587
+ handle_short_options = true;
1588
+ longopt_name = param + 1; //for testing a potential -long-option
1589
+ }
1590
+
1591
+ bool try_single_minus_longopt = single_minus_longopt;
1592
+ bool have_more_args = (numargs > 1 || numargs < 0); // is referencing argv[1] valid?
1593
+
1594
+ do // loop over short options in group, for long options the body is executed only once
1595
+ {
1596
+ int idx = 0;
1597
+
1598
+ const char* optarg = 0;
1599
+
1600
+ /******************** long option **********************/
1601
+ if (handle_short_options == false || try_single_minus_longopt)
1602
+ {
1603
+ idx = 0;
1604
+ while (usage[idx].longopt != 0 && !streq(usage[idx].longopt, longopt_name))
1605
+ ++idx;
1606
+
1607
+ if (usage[idx].longopt == 0 && min_abbr_len > 0) // if we should try to match abbreviated long options
1608
+ {
1609
+ int i1 = 0;
1610
+ while (usage[i1].longopt != 0 && !streqabbr(usage[i1].longopt, longopt_name, min_abbr_len))
1611
+ ++i1;
1612
+ if (usage[i1].longopt != 0)
1613
+ { // now test if the match is unambiguous by checking for another match
1614
+ int i2 = i1 + 1;
1615
+ while (usage[i2].longopt != 0 && !streqabbr(usage[i2].longopt, longopt_name, min_abbr_len))
1616
+ ++i2;
1617
+
1618
+ if (usage[i2].longopt == 0) // if there was no second match it's unambiguous, so accept i1 as idx
1619
+ idx = i1;
1620
+ }
1621
+ }
1622
+
1623
+ // if we found something, disable handle_short_options (only relevant if single_minus_longopt)
1624
+ if (usage[idx].longopt != 0)
1625
+ handle_short_options = false;
1626
+
1627
+ try_single_minus_longopt = false; // prevent looking for longopt in the middle of shortopt group
1628
+
1629
+ optarg = longopt_name;
1630
+ while (*optarg != 0 && *optarg != '=')
1631
+ ++optarg;
1632
+ if (*optarg == '=') // attached argument
1633
+ ++optarg;
1634
+ else
1635
+ // possibly detached argument
1636
+ optarg = (have_more_args ? args[1] : 0);
1637
+ }
1638
+
1639
+ /************************ short option ***********************************/
1640
+ if (handle_short_options)
1641
+ {
1642
+ if (*++param == 0) // point at the 1st/next option character
1643
+ break; // end of short option group
1644
+
1645
+ idx = 0;
1646
+ while (usage[idx].shortopt != 0 && !instr(*param, usage[idx].shortopt))
1647
+ ++idx;
1648
+
1649
+ if (param[1] == 0) // if the potential argument is separate
1650
+ optarg = (have_more_args ? args[1] : 0);
1651
+ else
1652
+ // if the potential argument is attached
1653
+ optarg = param + 1;
1654
+ }
1655
+
1656
+ const Descriptor* descriptor = &usage[idx];
1657
+
1658
+ if (descriptor->shortopt == 0) /************** unknown option ********************/
1659
+ {
1660
+ // look for dummy entry (shortopt == "" and longopt == "") to use as Descriptor for unknown options
1661
+ idx = 0;
1662
+ while (usage[idx].shortopt != 0 && (usage[idx].shortopt[0] != 0 || usage[idx].longopt[0] != 0))
1663
+ ++idx;
1664
+ descriptor = (usage[idx].shortopt == 0 ? 0 : &usage[idx]);
1665
+ }
1666
+
1667
+ if (descriptor != 0)
1668
+ {
1669
+ Option option(descriptor, param, optarg);
1670
+ switch (descriptor->check_arg(option, print_errors))
1671
+ {
1672
+ case ARG_ILLEGAL:
1673
+ return false; // fatal
1674
+ case ARG_OK:
1675
+ // skip one element of the argument vector, if it's a separated argument
1676
+ if (optarg != 0 && have_more_args && optarg == args[1])
1677
+ {
1678
+ shift(args, nonops);
1679
+ if (numargs > 0)
1680
+ --numargs;
1681
+ ++args;
1682
+ }
1683
+
1684
+ // No further short options are possible after an argument
1685
+ handle_short_options = false;
1686
+
1687
+ break;
1688
+ case ARG_IGNORE:
1689
+ case ARG_NONE:
1690
+ option.arg = 0;
1691
+ break;
1692
+ }
1693
+
1694
+ if (!action.perform(option))
1695
+ return false;
1696
+ }
1697
+
1698
+ } while (handle_short_options);
1699
+
1700
+ shift(args, nonops);
1701
+ ++args;
1702
+ if (numargs > 0)
1703
+ --numargs;
1704
+
1705
+ } // while
1706
+
1707
+ if (numargs > 0 && *args == 0) // It's a bug in the caller if numargs is greater than the actual number
1708
+ numargs = 0; // of arguments, but as a service to the user we fix this if we spot it.
1709
+
1710
+ if (numargs < 0) // if we don't know the number of remaining non-option arguments
1711
+ { // we need to count them
1712
+ numargs = 0;
1713
+ while (args[numargs] != 0)
1714
+ ++numargs;
1715
+ }
1716
+
1717
+ return action.finished(numargs + nonops, args - nonops);
1718
+ }
1719
+
1720
+ /**
1721
+ * @internal
1722
+ * @brief The implementation of option::printUsage().
1723
+ */
1724
+ struct PrintUsageImplementation
1725
+ {
1726
+ /**
1727
+ * @internal
1728
+ * @brief Interface for Functors that write (part of) a string somewhere.
1729
+ */
1730
+ struct IStringWriter
1731
+ {
1732
+ /**
1733
+ * @brief Writes the given number of chars beginning at the given pointer somewhere.
1734
+ */
1735
+ virtual void operator()(const char*, int)
1736
+ {
1737
+ }
1738
+ };
1739
+
1740
+ /**
1741
+ * @internal
1742
+ * @brief Encapsulates a function with signature <code>func(string, size)</code> where
1743
+ * string can be initialized with a const char* and size with an int.
1744
+ */
1745
+ template<typename Function>
1746
+ struct FunctionWriter: public IStringWriter
1747
+ {
1748
+ Function* write;
1749
+
1750
+ virtual void operator()(const char* str, int size)
1751
+ {
1752
+ (*write)(str, size);
1753
+ }
1754
+
1755
+ FunctionWriter(Function* w) :
1756
+ write(w)
1757
+ {
1758
+ }
1759
+ };
1760
+
1761
+ /**
1762
+ * @internal
1763
+ * @brief Encapsulates a reference to an object with a <code>write(string, size)</code>
1764
+ * method like that of @c std::ostream.
1765
+ */
1766
+ template<typename OStream>
1767
+ struct OStreamWriter: public IStringWriter
1768
+ {
1769
+ OStream& ostream;
1770
+
1771
+ virtual void operator()(const char* str, int size)
1772
+ {
1773
+ ostream.write(str, size);
1774
+ }
1775
+
1776
+ OStreamWriter(OStream& o) :
1777
+ ostream(o)
1778
+ {
1779
+ }
1780
+ };
1781
+
1782
+ /**
1783
+ * @internal
1784
+ * @brief Like OStreamWriter but encapsulates a @c const reference, which is
1785
+ * typically a temporary object of a user class.
1786
+ */
1787
+ template<typename Temporary>
1788
+ struct TemporaryWriter: public IStringWriter
1789
+ {
1790
+ const Temporary& userstream;
1791
+
1792
+ virtual void operator()(const char* str, int size)
1793
+ {
1794
+ userstream.write(str, size);
1795
+ }
1796
+
1797
+ TemporaryWriter(const Temporary& u) :
1798
+ userstream(u)
1799
+ {
1800
+ }
1801
+ };
1802
+
1803
+ /**
1804
+ * @internal
1805
+ * @brief Encapsulates a function with the signature <code>func(fd, string, size)</code> (the
1806
+ * signature of the @c write() system call)
1807
+ * where fd can be initialized from an int, string from a const char* and size from an int.
1808
+ */
1809
+ template<typename Syscall>
1810
+ struct SyscallWriter: public IStringWriter
1811
+ {
1812
+ Syscall* write;
1813
+ int fd;
1814
+
1815
+ virtual void operator()(const char* str, int size)
1816
+ {
1817
+ (*write)(fd, str, size);
1818
+ }
1819
+
1820
+ SyscallWriter(Syscall* w, int f) :
1821
+ write(w), fd(f)
1822
+ {
1823
+ }
1824
+ };
1825
+
1826
+ /**
1827
+ * @internal
1828
+ * @brief Encapsulates a function with the same signature as @c std::fwrite().
1829
+ */
1830
+ template<typename Function, typename Stream>
1831
+ struct StreamWriter: public IStringWriter
1832
+ {
1833
+ Function* fwrite;
1834
+ Stream* stream;
1835
+
1836
+ virtual void operator()(const char* str, int size)
1837
+ {
1838
+ (*fwrite)(str, size, 1, stream);
1839
+ }
1840
+
1841
+ StreamWriter(Function* w, Stream* s) :
1842
+ fwrite(w), stream(s)
1843
+ {
1844
+ }
1845
+ };
1846
+
1847
+ /**
1848
+ * @internal
1849
+ * @brief Sets <code> i1 = max(i1, i2) </code>
1850
+ */
1851
+ static void upmax(int& i1, int i2)
1852
+ {
1853
+ i1 = (i1 >= i2 ? i1 : i2);
1854
+ }
1855
+
1856
+ /**
1857
+ * @internal
1858
+ * @brief Moves the "cursor" to column @c want_x assuming it is currently at column @c x
1859
+ * and sets @c x=want_x .
1860
+ * If <code> x > want_x </code>, a line break is output before indenting.
1861
+ *
1862
+ * @param write Spaces and possibly a line break are written via this functor to get
1863
+ * the desired indentation @c want_x .
1864
+ * @param[in,out] x the current indentation. Set to @c want_x by this method.
1865
+ * @param want_x the desired indentation.
1866
+ */
1867
+ static void indent(IStringWriter& write, int& x, int want_x)
1868
+ {
1869
+ int indent = want_x - x;
1870
+ if (indent < 0)
1871
+ {
1872
+ write("\n", 1);
1873
+ indent = want_x;
1874
+ }
1875
+
1876
+ if (indent > 0)
1877
+ {
1878
+ char space = ' ';
1879
+ for (int i = 0; i < indent; ++i)
1880
+ write(&space, 1);
1881
+ x = want_x;
1882
+ }
1883
+ }
1884
+
1885
+ /**
1886
+ * @brief Returns true if ch is the unicode code point of a wide character.
1887
+ *
1888
+ * @note
1889
+ * The following character ranges are treated as wide
1890
+ * @code
1891
+ * 1100..115F
1892
+ * 2329..232A (just 2 characters!)
1893
+ * 2E80..A4C6 except for 303F
1894
+ * A960..A97C
1895
+ * AC00..D7FB
1896
+ * F900..FAFF
1897
+ * FE10..FE6B
1898
+ * FF01..FF60
1899
+ * FFE0..FFE6
1900
+ * 1B000......
1901
+ * @endcode
1902
+ */
1903
+ static bool isWideChar(unsigned ch)
1904
+ {
1905
+ if (ch == 0x303F)
1906
+ return false;
1907
+
1908
+ return ((0x1100 <= ch && ch <= 0x115F) || (0x2329 <= ch && ch <= 0x232A) || (0x2E80 <= ch && ch <= 0xA4C6)
1909
+ || (0xA960 <= ch && ch <= 0xA97C) || (0xAC00 <= ch && ch <= 0xD7FB) || (0xF900 <= ch && ch <= 0xFAFF)
1910
+ || (0xFE10 <= ch && ch <= 0xFE6B) || (0xFF01 <= ch && ch <= 0xFF60) || (0xFFE0 <= ch && ch <= 0xFFE6)
1911
+ || (0x1B000 <= ch));
1912
+ }
1913
+
1914
+ /**
1915
+ * @internal
1916
+ * @brief Splits a @c Descriptor[] array into tables, rows, lines and columns and
1917
+ * iterates over these components.
1918
+ *
1919
+ * The top-level organizational unit is the @e table.
1920
+ * A table begins at a Descriptor with @c help!=NULL and extends up to
1921
+ * a Descriptor with @c help==NULL.
1922
+ *
1923
+ * A table consists of @e rows. Due to line-wrapping and explicit breaks
1924
+ * a row may take multiple lines on screen. Rows within the table are separated
1925
+ * by \\n. They never cross Descriptor boundaries. This means a row ends either
1926
+ * at \\n or the 0 at the end of the help string.
1927
+ *
1928
+ * A row consists of columns/cells. Columns/cells within a row are separated by \\t.
1929
+ * Line breaks within a cell are marked by \\v.
1930
+ *
1931
+ * Rows in the same table need not have the same number of columns/cells. The
1932
+ * extreme case are interjections, which are rows that contain neither \\t nor \\v.
1933
+ * These are NOT treated specially by LinePartIterator, but they are treated
1934
+ * specially by printUsage().
1935
+ *
1936
+ * LinePartIterator iterates through the usage at 3 levels: table, row and part.
1937
+ * Tables and rows are as described above. A @e part is a line within a cell.
1938
+ * LinePartIterator iterates through 1st parts of all cells, then through the 2nd
1939
+ * parts of all cells (if any),... @n
1940
+ * Example: The row <code> "1 \v 3 \t 2 \v 4" </code> has 2 cells/columns and 4 parts.
1941
+ * The parts will be returned in the order 1, 2, 3, 4.
1942
+ *
1943
+ * It is possible that some cells have fewer parts than others. In this case
1944
+ * LinePartIterator will "fill up" these cells with 0-length parts. IOW, LinePartIterator
1945
+ * always returns the same number of parts for each column. Note that this is different
1946
+ * from the way rows and columns are handled. LinePartIterator does @e not guarantee that
1947
+ * the same number of columns will be returned for each row.
1948
+ *
1949
+ */
1950
+ class LinePartIterator
1951
+ {
1952
+ const Descriptor* tablestart; //!< The 1st descriptor of the current table.
1953
+ const Descriptor* rowdesc; //!< The Descriptor that contains the current row.
1954
+ const char* rowstart; //!< Ptr to 1st character of current row within rowdesc->help.
1955
+ const char* ptr; //!< Ptr to current part within the current row.
1956
+ int col; //!< Index of current column.
1957
+ int len; //!< Length of the current part (that ptr points at) in BYTES
1958
+ int screenlen; //!< Length of the current part in screen columns (taking narrow/wide chars into account).
1959
+ int max_line_in_block; //!< Greatest index of a line within the block. This is the number of \\v within the cell with the most \\vs.
1960
+ int line_in_block; //!< Line index within the current cell of the current part.
1961
+ int target_line_in_block; //!< Line index of the parts we should return to the user on this iteration.
1962
+ bool hit_target_line; //!< Flag whether we encountered a part with line index target_line_in_block in the current cell.
1963
+
1964
+ /**
1965
+ * @brief Determines the byte and character lengths of the part at @ref ptr and
1966
+ * stores them in @ref len and @ref screenlen respectively.
1967
+ */
1968
+ void update_length()
1969
+ {
1970
+ screenlen = 0;
1971
+ for (len = 0; ptr[len] != 0 && ptr[len] != '\v' && ptr[len] != '\t' && ptr[len] != '\n'; ++len)
1972
+ {
1973
+ ++screenlen;
1974
+ unsigned ch = (unsigned char) ptr[len];
1975
+ if (ch > 0xC1) // everything <= 0xC1 (yes, even 0xC1 itself) is not a valid UTF-8 start byte
1976
+ {
1977
+ // int __builtin_clz (unsigned int x)
1978
+ // Returns the number of leading 0-bits in x, starting at the most significant bit
1979
+ unsigned mask = (unsigned) -1 >> __builtin_clz(ch ^ 0xff);
1980
+ ch = ch & mask; // mask out length bits, we don't verify their correctness
1981
+ while (((unsigned char) ptr[len + 1] ^ 0x80) <= 0x3F) // while next byte is continuation byte
1982
+ {
1983
+ ch = (ch << 6) ^ (unsigned char) ptr[len + 1] ^ 0x80; // add continuation to char code
1984
+ ++len;
1985
+ }
1986
+ // ch is the decoded unicode code point
1987
+ if (ch >= 0x1100 && isWideChar(ch)) // the test for 0x1100 is here to avoid the function call in the Latin case
1988
+ ++screenlen;
1989
+ }
1990
+ }
1991
+ }
1992
+
1993
+ public:
1994
+ //! @brief Creates an iterator for @c usage.
1995
+ LinePartIterator(const Descriptor usage[]) :
1996
+ tablestart(usage), rowdesc(0), rowstart(0), ptr(0), col(-1), len(0), max_line_in_block(0), line_in_block(0),
1997
+ target_line_in_block(0), hit_target_line(true)
1998
+ {
1999
+ }
2000
+
2001
+ /**
2002
+ * @brief Moves iteration to the next table (if any). Has to be called once on a new
2003
+ * LinePartIterator to move to the 1st table.
2004
+ * @retval false if moving to next table failed because no further table exists.
2005
+ */
2006
+ bool nextTable()
2007
+ {
2008
+ // If this is NOT the first time nextTable() is called after the constructor,
2009
+ // then skip to the next table break (i.e. a Descriptor with help == 0)
2010
+ if (rowdesc != 0)
2011
+ {
2012
+ while (tablestart->help != 0 && tablestart->shortopt != 0)
2013
+ ++tablestart;
2014
+ }
2015
+
2016
+ // Find the next table after the break (if any)
2017
+ while (tablestart->help == 0 && tablestart->shortopt != 0)
2018
+ ++tablestart;
2019
+
2020
+ restartTable();
2021
+ return rowstart != 0;
2022
+ }
2023
+
2024
+ /**
2025
+ * @brief Reset iteration to the beginning of the current table.
2026
+ */
2027
+ void restartTable()
2028
+ {
2029
+ rowdesc = tablestart;
2030
+ rowstart = tablestart->help;
2031
+ ptr = 0;
2032
+ }
2033
+
2034
+ /**
2035
+ * @brief Moves iteration to the next row (if any). Has to be called once after each call to
2036
+ * @ref nextTable() to move to the 1st row of the table.
2037
+ * @retval false if moving to next row failed because no further row exists.
2038
+ */
2039
+ bool nextRow()
2040
+ {
2041
+ if (ptr == 0)
2042
+ {
2043
+ restartRow();
2044
+ return rowstart != 0;
2045
+ }
2046
+
2047
+ while (*ptr != 0 && *ptr != '\n')
2048
+ ++ptr;
2049
+
2050
+ if (*ptr == 0)
2051
+ {
2052
+ if ((rowdesc + 1)->help == 0) // table break
2053
+ return false;
2054
+
2055
+ ++rowdesc;
2056
+ rowstart = rowdesc->help;
2057
+ }
2058
+ else // if (*ptr == '\n')
2059
+ {
2060
+ rowstart = ptr + 1;
2061
+ }
2062
+
2063
+ restartRow();
2064
+ return true;
2065
+ }
2066
+
2067
+ /**
2068
+ * @brief Reset iteration to the beginning of the current row.
2069
+ */
2070
+ void restartRow()
2071
+ {
2072
+ ptr = rowstart;
2073
+ col = -1;
2074
+ len = 0;
2075
+ screenlen = 0;
2076
+ max_line_in_block = 0;
2077
+ line_in_block = 0;
2078
+ target_line_in_block = 0;
2079
+ hit_target_line = true;
2080
+ }
2081
+
2082
+ /**
2083
+ * @brief Moves iteration to the next part (if any). Has to be called once after each call to
2084
+ * @ref nextRow() to move to the 1st part of the row.
2085
+ * @retval false if moving to next part failed because no further part exists.
2086
+ *
2087
+ * See @ref LinePartIterator for details about the iteration.
2088
+ */
2089
+ bool next()
2090
+ {
2091
+ if (ptr == 0)
2092
+ return false;
2093
+
2094
+ if (col == -1)
2095
+ {
2096
+ col = 0;
2097
+ update_length();
2098
+ return true;
2099
+ }
2100
+
2101
+ ptr += len;
2102
+ while (true)
2103
+ {
2104
+ switch (*ptr)
2105
+ {
2106
+ case '\v':
2107
+ upmax(max_line_in_block, ++line_in_block);
2108
+ ++ptr;
2109
+ break;
2110
+ case '\t':
2111
+ if (!hit_target_line) // if previous column did not have the targetline
2112
+ { // then "insert" a 0-length part
2113
+ update_length();
2114
+ hit_target_line = true;
2115
+ return true;
2116
+ }
2117
+
2118
+ hit_target_line = false;
2119
+ line_in_block = 0;
2120
+ ++col;
2121
+ ++ptr;
2122
+ break;
2123
+ case 0:
2124
+ case '\n':
2125
+ if (!hit_target_line) // if previous column did not have the targetline
2126
+ { // then "insert" a 0-length part
2127
+ update_length();
2128
+ hit_target_line = true;
2129
+ return true;
2130
+ }
2131
+
2132
+ if (++target_line_in_block > max_line_in_block)
2133
+ {
2134
+ update_length();
2135
+ return false;
2136
+ }
2137
+
2138
+ hit_target_line = false;
2139
+ line_in_block = 0;
2140
+ col = 0;
2141
+ ptr = rowstart;
2142
+ continue;
2143
+ default:
2144
+ ++ptr;
2145
+ continue;
2146
+ } // switch
2147
+
2148
+ if (line_in_block == target_line_in_block)
2149
+ {
2150
+ update_length();
2151
+ hit_target_line = true;
2152
+ return true;
2153
+ }
2154
+ } // while
2155
+ }
2156
+
2157
+ /**
2158
+ * @brief Returns the index (counting from 0) of the column in which
2159
+ * the part pointed to by @ref data() is located.
2160
+ */
2161
+ int column()
2162
+ {
2163
+ return col;
2164
+ }
2165
+
2166
+ /**
2167
+ * @brief Returns the index (counting from 0) of the line within the current column
2168
+ * this part belongs to.
2169
+ */
2170
+ int line()
2171
+ {
2172
+ return target_line_in_block; // NOT line_in_block !!! It would be wrong if !hit_target_line
2173
+ }
2174
+
2175
+ /**
2176
+ * @brief Returns the length of the part pointed to by @ref data() in raw chars (not UTF-8 characters).
2177
+ */
2178
+ int length()
2179
+ {
2180
+ return len;
2181
+ }
2182
+
2183
+ /**
2184
+ * @brief Returns the width in screen columns of the part pointed to by @ref data().
2185
+ * Takes multi-byte UTF-8 sequences and wide characters into account.
2186
+ */
2187
+ int screenLength()
2188
+ {
2189
+ return screenlen;
2190
+ }
2191
+
2192
+ /**
2193
+ * @brief Returns the current part of the iteration.
2194
+ */
2195
+ const char* data()
2196
+ {
2197
+ return ptr;
2198
+ }
2199
+ };
2200
+
2201
+ /**
2202
+ * @internal
2203
+ * @brief Takes input and line wraps it, writing out one line at a time so that
2204
+ * it can be interleaved with output from other columns.
2205
+ *
2206
+ * The LineWrapper is used to handle the last column of each table as well as interjections.
2207
+ * The LineWrapper is called once for each line of output. If the data given to it fits
2208
+ * into the designated width of the last column it is simply written out. If there
2209
+ * is too much data, an appropriate split point is located and only the data up to this
2210
+ * split point is written out. The rest of the data is queued for the next line.
2211
+ * That way the last column can be line wrapped and interleaved with data from
2212
+ * other columns. The following example makes this clearer:
2213
+ * @code
2214
+ * Column 1,1 Column 2,1 This is a long text
2215
+ * Column 1,2 Column 2,2 that does not fit into
2216
+ * a single line.
2217
+ * @endcode
2218
+ *
2219
+ * The difficulty in producing this output is that the whole string
2220
+ * "This is a long text that does not fit into a single line" is the
2221
+ * 1st and only part of column 3. In order to produce the above
2222
+ * output the string must be output piecemeal, interleaved with
2223
+ * the data from the other columns.
2224
+ */
2225
+ class LineWrapper
2226
+ {
2227
+ static const int bufmask = 15; //!< Must be a power of 2 minus 1.
2228
+ /**
2229
+ * @brief Ring buffer for length component of pair (data, length).
2230
+ */
2231
+ int lenbuf[bufmask + 1];
2232
+ /**
2233
+ * @brief Ring buffer for data component of pair (data, length).
2234
+ */
2235
+ const char* datbuf[bufmask + 1];
2236
+ /**
2237
+ * @brief The indentation of the column to which the LineBuffer outputs. LineBuffer
2238
+ * assumes that the indentation has already been written when @ref process()
2239
+ * is called, so this value is only used when a buffer flush requires writing
2240
+ * additional lines of output.
2241
+ */
2242
+ int x;
2243
+ /**
2244
+ * @brief The width of the column to line wrap.
2245
+ */
2246
+ int width;
2247
+ int head; //!< @brief index for next write
2248
+ int tail; //!< @brief index for next read - 1 (i.e. increment tail BEFORE read)
2249
+
2250
+ /**
2251
+ * @brief Multiple methods of LineWrapper may decide to flush part of the buffer to
2252
+ * free up space. The contract of process() says that only 1 line is output. So
2253
+ * this variable is used to track whether something has output a line. It is
2254
+ * reset at the beginning of process() and checked at the end to decide if
2255
+ * output has already occurred or is still needed.
2256
+ */
2257
+ bool wrote_something;
2258
+
2259
+ bool buf_empty()
2260
+ {
2261
+ return ((tail + 1) & bufmask) == head;
2262
+ }
2263
+
2264
+ bool buf_full()
2265
+ {
2266
+ return tail == head;
2267
+ }
2268
+
2269
+ void buf_store(const char* data, int len)
2270
+ {
2271
+ lenbuf[head] = len;
2272
+ datbuf[head] = data;
2273
+ head = (head + 1) & bufmask;
2274
+ }
2275
+
2276
+ //! @brief Call BEFORE reading ...buf[tail].
2277
+ void buf_next()
2278
+ {
2279
+ tail = (tail + 1) & bufmask;
2280
+ }
2281
+
2282
+ /**
2283
+ * @brief Writes (data,len) into the ring buffer. If the buffer is full, a single line
2284
+ * is flushed out of the buffer into @c write.
2285
+ */
2286
+ void output(IStringWriter& write, const char* data, int len)
2287
+ {
2288
+ if (buf_full())
2289
+ write_one_line(write);
2290
+
2291
+ buf_store(data, len);
2292
+ }
2293
+
2294
+ /**
2295
+ * @brief Writes a single line of output from the buffer to @c write.
2296
+ */
2297
+ void write_one_line(IStringWriter& write)
2298
+ {
2299
+ if (wrote_something) // if we already wrote something, we need to start a new line
2300
+ {
2301
+ write("\n", 1);
2302
+ int _ = 0;
2303
+ indent(write, _, x);
2304
+ }
2305
+
2306
+ if (!buf_empty())
2307
+ {
2308
+ buf_next();
2309
+ write(datbuf[tail], lenbuf[tail]);
2310
+ }
2311
+
2312
+ wrote_something = true;
2313
+ }
2314
+ public:
2315
+
2316
+ /**
2317
+ * @brief Writes out all remaining data from the LineWrapper using @c write.
2318
+ * Unlike @ref process() this method indents all lines including the first and
2319
+ * will output a \\n at the end (but only if something has been written).
2320
+ */
2321
+ void flush(IStringWriter& write)
2322
+ {
2323
+ if (buf_empty())
2324
+ return;
2325
+ int _ = 0;
2326
+ indent(write, _, x);
2327
+ wrote_something = false;
2328
+ while (!buf_empty())
2329
+ write_one_line(write);
2330
+ write("\n", 1);
2331
+ }
2332
+
2333
+ /**
2334
+ * @brief Process, wrap and output the next piece of data.
2335
+ *
2336
+ * process() will output at least one line of output. This is not necessarily
2337
+ * the @c data passed in. It may be data queued from a prior call to process().
2338
+ * If the internal buffer is full, more than 1 line will be output.
2339
+ *
2340
+ * process() assumes that the a proper amount of indentation has already been
2341
+ * output. It won't write any further indentation before the 1st line. If
2342
+ * more than 1 line is written due to buffer constraints, the lines following
2343
+ * the first will be indented by this method, though.
2344
+ *
2345
+ * No \\n is written by this method after the last line that is written.
2346
+ *
2347
+ * @param write where to write the data.
2348
+ * @param data the new chunk of data to write.
2349
+ * @param len the length of the chunk of data to write.
2350
+ */
2351
+ void process(IStringWriter& write, const char* data, int len)
2352
+ {
2353
+ wrote_something = false;
2354
+
2355
+ while (len > 0)
2356
+ {
2357
+ if (len <= width) // quick test that works because utf8width <= len (all wide chars have at least 2 bytes)
2358
+ {
2359
+ output(write, data, len);
2360
+ len = 0;
2361
+ }
2362
+ else // if (len > width) it's possible (but not guaranteed) that utf8len > width
2363
+ {
2364
+ int utf8width = 0;
2365
+ int maxi = 0;
2366
+ while (maxi < len && utf8width < width)
2367
+ {
2368
+ int charbytes = 1;
2369
+ unsigned ch = (unsigned char) data[maxi];
2370
+ if (ch > 0xC1) // everything <= 0xC1 (yes, even 0xC1 itself) is not a valid UTF-8 start byte
2371
+ {
2372
+ // int __builtin_clz (unsigned int x)
2373
+ // Returns the number of leading 0-bits in x, starting at the most significant bit
2374
+ unsigned mask = (unsigned) -1 >> __builtin_clz(ch ^ 0xff);
2375
+ ch = ch & mask; // mask out length bits, we don't verify their correctness
2376
+ while ((maxi + charbytes < len) && //
2377
+ (((unsigned char) data[maxi + charbytes] ^ 0x80) <= 0x3F)) // while next byte is continuation byte
2378
+ {
2379
+ ch = (ch << 6) ^ (unsigned char) data[maxi + charbytes] ^ 0x80; // add continuation to char code
2380
+ ++charbytes;
2381
+ }
2382
+ // ch is the decoded unicode code point
2383
+ if (ch >= 0x1100 && isWideChar(ch)) // the test for 0x1100 is here to avoid the function call in the Latin case
2384
+ {
2385
+ if (utf8width + 2 > width)
2386
+ break;
2387
+ ++utf8width;
2388
+ }
2389
+ }
2390
+ ++utf8width;
2391
+ maxi += charbytes;
2392
+ }
2393
+
2394
+ // data[maxi-1] is the last byte of the UTF-8 sequence of the last character that fits
2395
+ // onto the 1st line. If maxi == len, all characters fit on the line.
2396
+
2397
+ if (maxi == len)
2398
+ {
2399
+ output(write, data, len);
2400
+ len = 0;
2401
+ }
2402
+ else // if (maxi < len) at least 1 character (data[maxi] that is) doesn't fit on the line
2403
+ {
2404
+ int i;
2405
+ for (i = maxi; i >= 0; --i)
2406
+ if (data[i] == ' ')
2407
+ break;
2408
+
2409
+ if (i >= 0)
2410
+ {
2411
+ output(write, data, i);
2412
+ data += i + 1;
2413
+ len -= i + 1;
2414
+ }
2415
+ else // did not find a space to split at => split before data[maxi]
2416
+ { // data[maxi] is always the beginning of a character, never a continuation byte
2417
+ output(write, data, maxi);
2418
+ data += maxi;
2419
+ len -= maxi;
2420
+ }
2421
+ }
2422
+ }
2423
+ }
2424
+ if (!wrote_something) // if we didn't already write something to make space in the buffer
2425
+ write_one_line(write); // write at most one line of actual output
2426
+ }
2427
+
2428
+ /**
2429
+ * @brief Constructs a LineWrapper that wraps its output to fit into
2430
+ * screen columns @c x1 (incl.) to @c x2 (excl.).
2431
+ *
2432
+ * @c x1 gives the indentation LineWrapper uses if it needs to indent.
2433
+ */
2434
+ LineWrapper(int x1, int x2) :
2435
+ x(x1), width(x2 - x1), head(0), tail(bufmask)
2436
+ {
2437
+ if (width < 2) // because of wide characters we need at least width 2 or the code breaks
2438
+ width = 2;
2439
+ }
2440
+ };
2441
+
2442
+ /**
2443
+ * @internal
2444
+ * @brief This is the implementation that is shared between all printUsage() templates.
2445
+ * Because all printUsage() templates share this implementation, there is no template bloat.
2446
+ */
2447
+ static void printUsage(IStringWriter& write, const Descriptor usage[], int width = 80, //
2448
+ int last_column_min_percent = 50, int last_column_own_line_max_percent = 75)
2449
+ {
2450
+ if (width < 1) // protect against nonsense values
2451
+ width = 80;
2452
+
2453
+ if (width > 10000) // protect against overflow in the following computation
2454
+ width = 10000;
2455
+
2456
+ int last_column_min_width = ((width * last_column_min_percent) + 50) / 100;
2457
+ int last_column_own_line_max_width = ((width * last_column_own_line_max_percent) + 50) / 100;
2458
+ if (last_column_own_line_max_width == 0)
2459
+ last_column_own_line_max_width = 1;
2460
+
2461
+ LinePartIterator part(usage);
2462
+ while (part.nextTable())
2463
+ {
2464
+
2465
+ /***************** Determine column widths *******************************/
2466
+
2467
+ const int maxcolumns = 8; // 8 columns are enough for everyone
2468
+ int col_width[maxcolumns];
2469
+ int lastcolumn;
2470
+ int leftwidth;
2471
+ int overlong_column_threshold = 10000;
2472
+ do
2473
+ {
2474
+ lastcolumn = 0;
2475
+ for (int i = 0; i < maxcolumns; ++i)
2476
+ col_width[i] = 0;
2477
+
2478
+ part.restartTable();
2479
+ while (part.nextRow())
2480
+ {
2481
+ while (part.next())
2482
+ {
2483
+ if (part.column() < maxcolumns)
2484
+ {
2485
+ upmax(lastcolumn, part.column());
2486
+ if (part.screenLength() < overlong_column_threshold)
2487
+ // We don't let rows that don't use table separators (\t or \v) influence
2488
+ // the width of column 0. This allows the user to interject section headers
2489
+ // or explanatory paragraphs that do not participate in the table layout.
2490
+ if (part.column() > 0 || part.line() > 0 || part.data()[part.length()] == '\t'
2491
+ || part.data()[part.length()] == '\v')
2492
+ upmax(col_width[part.column()], part.screenLength());
2493
+ }
2494
+ }
2495
+ }
2496
+
2497
+ /*
2498
+ * If the last column doesn't fit on the same
2499
+ * line as the other columns, we can fix that by starting it on its own line.
2500
+ * However we can't do this for any of the columns 0..lastcolumn-1.
2501
+ * If their sum exceeds the maximum width we try to fix this by iteratively
2502
+ * ignoring the widest line parts in the width determination until
2503
+ * we arrive at a series of column widths that fit into one line.
2504
+ * The result is a layout where everything is nicely formatted
2505
+ * except for a few overlong fragments.
2506
+ * */
2507
+
2508
+ leftwidth = 0;
2509
+ overlong_column_threshold = 0;
2510
+ for (int i = 0; i < lastcolumn; ++i)
2511
+ {
2512
+ leftwidth += col_width[i];
2513
+ upmax(overlong_column_threshold, col_width[i]);
2514
+ }
2515
+
2516
+ } while (leftwidth > width);
2517
+
2518
+ /**************** Determine tab stops and last column handling **********************/
2519
+
2520
+ int tabstop[maxcolumns];
2521
+ tabstop[0] = 0;
2522
+ for (int i = 1; i < maxcolumns; ++i)
2523
+ tabstop[i] = tabstop[i - 1] + col_width[i - 1];
2524
+
2525
+ int rightwidth = width - tabstop[lastcolumn];
2526
+ bool print_last_column_on_own_line = false;
2527
+ if (rightwidth < last_column_min_width && // if we don't have the minimum requested width for the last column
2528
+ ( col_width[lastcolumn] == 0 || // and all last columns are > overlong_column_threshold
2529
+ rightwidth < col_width[lastcolumn] // or there is at least one last column that requires more than the space available
2530
+ )
2531
+ )
2532
+ {
2533
+ print_last_column_on_own_line = true;
2534
+ rightwidth = last_column_own_line_max_width;
2535
+ }
2536
+
2537
+ // If lastcolumn == 0 we must disable print_last_column_on_own_line because
2538
+ // otherwise 2 copies of the last (and only) column would be output.
2539
+ // Actually this is just defensive programming. It is currently not
2540
+ // possible that lastcolumn==0 and print_last_column_on_own_line==true
2541
+ // at the same time, because lastcolumn==0 => tabstop[lastcolumn] == 0 =>
2542
+ // rightwidth==width => rightwidth>=last_column_min_width (unless someone passes
2543
+ // a bullshit value >100 for last_column_min_percent) => the above if condition
2544
+ // is false => print_last_column_on_own_line==false
2545
+ if (lastcolumn == 0)
2546
+ print_last_column_on_own_line = false;
2547
+
2548
+ LineWrapper lastColumnLineWrapper(width - rightwidth, width);
2549
+ LineWrapper interjectionLineWrapper(0, width);
2550
+
2551
+ part.restartTable();
2552
+
2553
+ /***************** Print out all rows of the table *************************************/
2554
+
2555
+ while (part.nextRow())
2556
+ {
2557
+ int x = -1;
2558
+ while (part.next())
2559
+ {
2560
+ if (part.column() > lastcolumn)
2561
+ continue; // drop excess columns (can happen if lastcolumn == maxcolumns-1)
2562
+
2563
+ if (part.column() == 0)
2564
+ {
2565
+ if (x >= 0)
2566
+ write("\n", 1);
2567
+ x = 0;
2568
+ }
2569
+
2570
+ indent(write, x, tabstop[part.column()]);
2571
+
2572
+ if ((part.column() < lastcolumn)
2573
+ && (part.column() > 0 || part.line() > 0 || part.data()[part.length()] == '\t'
2574
+ || part.data()[part.length()] == '\v'))
2575
+ {
2576
+ write(part.data(), part.length());
2577
+ x += part.screenLength();
2578
+ }
2579
+ else // either part.column() == lastcolumn or we are in the special case of
2580
+ // an interjection that doesn't contain \v or \t
2581
+ {
2582
+ // NOTE: This code block is not necessarily executed for
2583
+ // each line, because some rows may have fewer columns.
2584
+
2585
+ LineWrapper& lineWrapper = (part.column() == 0) ? interjectionLineWrapper : lastColumnLineWrapper;
2586
+
2587
+ if (!print_last_column_on_own_line || part.column() != lastcolumn)
2588
+ lineWrapper.process(write, part.data(), part.length());
2589
+ }
2590
+ } // while
2591
+
2592
+ if (print_last_column_on_own_line)
2593
+ {
2594
+ part.restartRow();
2595
+ while (part.next())
2596
+ {
2597
+ if (part.column() == lastcolumn)
2598
+ {
2599
+ write("\n", 1);
2600
+ int _ = 0;
2601
+ indent(write, _, width - rightwidth);
2602
+ lastColumnLineWrapper.process(write, part.data(), part.length());
2603
+ }
2604
+ }
2605
+ }
2606
+
2607
+ write("\n", 1);
2608
+ lastColumnLineWrapper.flush(write);
2609
+ interjectionLineWrapper.flush(write);
2610
+ }
2611
+ }
2612
+ }
2613
+
2614
+ }
2615
+ ;
2616
+
2617
+ /**
2618
+ * @brief Outputs a nicely formatted usage string with support for multi-column formatting
2619
+ * and line-wrapping.
2620
+ *
2621
+ * printUsage() takes the @c help texts of a Descriptor[] array and formats them into
2622
+ * a usage message, wrapping lines to achieve the desired output width.
2623
+ *
2624
+ * <b>Table formatting:</b>
2625
+ *
2626
+ * Aside from plain strings which are simply line-wrapped, the usage may contain tables. Tables
2627
+ * are used to align elements in the output.
2628
+ *
2629
+ * @code
2630
+ * // Without a table. The explanatory texts are not aligned.
2631
+ * -c, --create |Creates something.
2632
+ * -k, --kill |Destroys something.
2633
+ *
2634
+ * // With table formatting. The explanatory texts are aligned.
2635
+ * -c, --create |Creates something.
2636
+ * -k, --kill |Destroys something.
2637
+ * @endcode
2638
+ *
2639
+ * Table formatting removes the need to pad help texts manually with spaces to achieve
2640
+ * alignment. To create a table, simply insert \\t (tab) characters to separate the cells
2641
+ * within a row.
2642
+ *
2643
+ * @code
2644
+ * const option::Descriptor usage[] = {
2645
+ * {..., "-c, --create \tCreates something." },
2646
+ * {..., "-k, --kill \tDestroys something." }, ...
2647
+ * @endcode
2648
+ *
2649
+ * Note that you must include the minimum amount of space desired between cells yourself.
2650
+ * Table formatting will insert further spaces as needed to achieve alignment.
2651
+ *
2652
+ * You can insert line breaks within cells by using \\v (vertical tab).
2653
+ *
2654
+ * @code
2655
+ * const option::Descriptor usage[] = {
2656
+ * {..., "-c,\v--create \tCreates\vsomething." },
2657
+ * {..., "-k,\v--kill \tDestroys\vsomething." }, ...
2658
+ *
2659
+ * // results in
2660
+ *
2661
+ * -c, Creates
2662
+ * --create something.
2663
+ * -k, Destroys
2664
+ * --kill something.
2665
+ * @endcode
2666
+ *
2667
+ * You can mix lines that do not use \\t or \\v with those that do. The plain
2668
+ * lines will not mess up the table layout. Alignment of the table columns will
2669
+ * be maintained even across these interjections.
2670
+ *
2671
+ * @code
2672
+ * const option::Descriptor usage[] = {
2673
+ * {..., "-c, --create \tCreates something." },
2674
+ * {..., "----------------------------------" },
2675
+ * {..., "-k, --kill \tDestroys something." }, ...
2676
+ *
2677
+ * // results in
2678
+ *
2679
+ * -c, --create Creates something.
2680
+ * ----------------------------------
2681
+ * -k, --kill Destroys something.
2682
+ * @endcode
2683
+ *
2684
+ * You can have multiple tables within the same usage whose columns are
2685
+ * aligned independently. Simply insert a dummy Descriptor with @c help==0.
2686
+ *
2687
+ * @code
2688
+ * const option::Descriptor usage[] = {
2689
+ * {..., "Long options:" },
2690
+ * {..., "--very-long-option \tDoes something long." },
2691
+ * {..., "--ultra-super-mega-long-option \tTakes forever to complete." },
2692
+ * {..., 0 }, // ---------- table break -----------
2693
+ * {..., "Short options:" },
2694
+ * {..., "-s \tShort." },
2695
+ * {..., "-q \tQuick." }, ...
2696
+ *
2697
+ * // results in
2698
+ *
2699
+ * Long options:
2700
+ * --very-long-option Does something long.
2701
+ * --ultra-super-mega-long-option Takes forever to complete.
2702
+ * Short options:
2703
+ * -s Short.
2704
+ * -q Quick.
2705
+ *
2706
+ * // Without the table break it would be
2707
+ *
2708
+ * Long options:
2709
+ * --very-long-option Does something long.
2710
+ * --ultra-super-mega-long-option Takes forever to complete.
2711
+ * Short options:
2712
+ * -s Short.
2713
+ * -q Quick.
2714
+ * @endcode
2715
+ *
2716
+ * <b>Output methods:</b>
2717
+ *
2718
+ * Because TheLeanMeanC++Option parser is freestanding, you have to provide the means for
2719
+ * output in the first argument(s) to printUsage(). Because printUsage() is implemented as
2720
+ * a set of template functions, you have great flexibility in your choice of output
2721
+ * method. The following example demonstrates typical uses. Anything that's similar enough
2722
+ * will work.
2723
+ *
2724
+ * @code
2725
+ * #include <unistd.h> // write()
2726
+ * #include <iostream> // cout
2727
+ * #include <sstream> // ostringstream
2728
+ * #include <cstdio> // fwrite()
2729
+ * using namespace std;
2730
+ *
2731
+ * void my_write(const char* str, int size) {
2732
+ * fwrite(str, size, 1, stdout);
2733
+ * }
2734
+ *
2735
+ * struct MyWriter {
2736
+ * void write(const char* buf, size_t size) const {
2737
+ * fwrite(str, size, 1, stdout);
2738
+ * }
2739
+ * };
2740
+ *
2741
+ * struct MyWriteFunctor {
2742
+ * void operator()(const char* buf, size_t size) {
2743
+ * fwrite(str, size, 1, stdout);
2744
+ * }
2745
+ * };
2746
+ * ...
2747
+ * printUsage(my_write, usage); // custom write function
2748
+ * printUsage(MyWriter(), usage); // temporary of a custom class
2749
+ * MyWriter writer;
2750
+ * printUsage(writer, usage); // custom class object
2751
+ * MyWriteFunctor wfunctor;
2752
+ * printUsage(&wfunctor, usage); // custom functor
2753
+ * printUsage(write, 1, usage); // write() to file descriptor 1
2754
+ * printUsage(cout, usage); // an ostream&
2755
+ * printUsage(fwrite, stdout, usage); // fwrite() to stdout
2756
+ * ostringstream sstr;
2757
+ * printUsage(sstr, usage); // an ostringstream&
2758
+ *
2759
+ * @endcode
2760
+ *
2761
+ * @par Notes:
2762
+ * @li the @c write() method of a class that is to be passed as a temporary
2763
+ * as @c MyWriter() is in the example, must be a @c const method, because
2764
+ * temporary objects are passed as const reference. This only applies to
2765
+ * temporary objects that are created and destroyed in the same statement.
2766
+ * If you create an object like @c writer in the example, this restriction
2767
+ * does not apply.
2768
+ * @li a functor like @c MyWriteFunctor in the example must be passed as a pointer.
2769
+ * This differs from the way functors are passed to e.g. the STL algorithms.
2770
+ * @li All printUsage() templates are tiny wrappers around a shared non-template implementation.
2771
+ * So there's no penalty for using different versions in the same program.
2772
+ * @li printUsage() always interprets Descriptor::help as UTF-8 and always produces UTF-8-encoded
2773
+ * output. If your system uses a different charset, you must do your own conversion. You
2774
+ * may also need to change the font of the console to see non-ASCII characters properly.
2775
+ * This is particularly true for Windows.
2776
+ * @li @b Security @b warning: Do not insert untrusted strings (such as user-supplied arguments)
2777
+ * into the usage. printUsage() has no protection against malicious UTF-8 sequences.
2778
+ *
2779
+ * @param prn The output method to use. See the examples above.
2780
+ * @param usage the Descriptor[] array whose @c help texts will be formatted.
2781
+ * @param width the maximum number of characters per output line. Note that this number is
2782
+ * in actual characters, not bytes. printUsage() supports UTF-8 in @c help and will
2783
+ * count multi-byte UTF-8 sequences properly. Asian wide characters are counted
2784
+ * as 2 characters.
2785
+ * @param last_column_min_percent (0-100) The minimum percentage of @c width that should be available
2786
+ * for the last column (which typically contains the textual explanation of an option).
2787
+ * If less space is available, the last column will be printed on its own line, indented
2788
+ * according to @c last_column_own_line_max_percent.
2789
+ * @param last_column_own_line_max_percent (0-100) If the last column is printed on its own line due to
2790
+ * less than @c last_column_min_percent of the width being available, then only
2791
+ * @c last_column_own_line_max_percent of the extra line(s) will be used for the
2792
+ * last column's text. This ensures an indentation. See example below.
2793
+ *
2794
+ * @code
2795
+ * // width=20, last_column_min_percent=50 (i.e. last col. min. width=10)
2796
+ * --3456789 1234567890
2797
+ * 1234567890
2798
+ *
2799
+ * // width=20, last_column_min_percent=75 (i.e. last col. min. width=15)
2800
+ * // last_column_own_line_max_percent=75
2801
+ * --3456789
2802
+ * 123456789012345
2803
+ * 67890
2804
+ *
2805
+ * // width=20, last_column_min_percent=75 (i.e. last col. min. width=15)
2806
+ * // last_column_own_line_max_percent=33 (i.e. max. 5)
2807
+ * --3456789
2808
+ * 12345
2809
+ * 67890
2810
+ * 12345
2811
+ * 67890
2812
+ * @endcode
2813
+ */
2814
+ template<typename OStream>
2815
+ void printUsage(OStream& prn, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,
2816
+ int last_column_own_line_max_percent = 75)
2817
+ {
2818
+ PrintUsageImplementation::OStreamWriter<OStream> write(prn);
2819
+ PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2820
+ }
2821
+
2822
+ template<typename Function>
2823
+ void printUsage(Function* prn, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,
2824
+ int last_column_own_line_max_percent = 75)
2825
+ {
2826
+ PrintUsageImplementation::FunctionWriter<Function> write(prn);
2827
+ PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2828
+ }
2829
+
2830
+ template<typename Temporary>
2831
+ void printUsage(const Temporary& prn, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,
2832
+ int last_column_own_line_max_percent = 75)
2833
+ {
2834
+ PrintUsageImplementation::TemporaryWriter<Temporary> write(prn);
2835
+ PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2836
+ }
2837
+
2838
+ template<typename Syscall>
2839
+ void printUsage(Syscall* prn, int fd, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,
2840
+ int last_column_own_line_max_percent = 75)
2841
+ {
2842
+ PrintUsageImplementation::SyscallWriter<Syscall> write(prn, fd);
2843
+ PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2844
+ }
2845
+
2846
+ template<typename Function, typename Stream>
2847
+ void printUsage(Function* prn, Stream* stream, const Descriptor usage[], int width = 80, int last_column_min_percent =
2848
+ 50,
2849
+ int last_column_own_line_max_percent = 75)
2850
+ {
2851
+ PrintUsageImplementation::StreamWriter<Function, Stream> write(prn, stream);
2852
+ PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2853
+ }
2854
+
2855
+ }
2856
+ // namespace option
2857
+
2858
+ #endif /* OPTIONPARSER_H_ */