45 char* gettext(
const char * msgid)
50 const Descriptor empty_usage[] = { { 0, 0, 0, 0, 0, 0 } };
54 { 0, 0, 0, 0, 0, 0 } };
57 { { 0, 0,
"f",
"", Arg::Required, 0 },
58 { 0, 0, 0, 0, 0, 0 } };
61 { { 0, 0,
"f",
"", Arg::Required, gettext(
"This is a test") },
62 { 0, 0, 0, 0, 0, 0 } };
66 UNKNOWN, FOO, VERBOSE, X, ABBREVIATE, EMPTY
70 UNUSED = 0, DISABLED = 1, ENABLED = 2
75 { FOO, ENABLED,
"",
"enable-foo",
Arg::None, 0 },
76 { FOO, DISABLED,
"",
"disable-foo",
Arg::None, 0 },
77 { VERBOSE, 0,
"v",
"verbose",
Arg::None, 0 },
78 { X, 0,
"X",
"X", Arg::Required, 0 },
79 { ABBREVIATE, 0,
"",
"abbreviate-me",
Arg::None, 0 },
80 { EMPTY, 0,
"",
"emptyarg", Arg::Empty, 0 },
81 { 0, 0, 0, 0, 0, 0 } };
83 const char* empty_args[] = { 0 };
84 const char* non_options[] = {
"1",
"2",
"3", (
const char*) -1 };
85 const char* unknown_option[] = {
"--unknown",
"nonoption", 0 };
86 const char* lone_minus[] = {
"-f",
"-",
"-", 0 };
87 const char* lone_doubleminus[] = {
"--", 0 };
93 const char* multi1[] =
94 {
"--enable-foo",
"--unknown1",
"-u",
"-vX",
"xyzzy",
"--",
"--strangefilename", (
const char*) -1 };
95 const char* multi2[] = {
"-vvXfoo",
"-X",
"bar",
"-X=foobar",
"-X",
"",
"--disable-foo",
"-v", (
const char*) -1 };
96 const char* multi3[] = {
"-abbr",
"-abb",
"--emptyarg",
"-verbose",
"--emptyarg",
"",
"--emptyarg=",
"nonoption1",
97 "nonoption2", (
const char*) -1 };
99 const char* illegal[] = {
"-X", 0 };
100 const char* reorder[] = {
"-X",
"--",
"-",
"-X",
"--",
"foo",
"-v",
"--",
"bar",
"--", 0 };
101 const char* reorder2[] = {
"-X",
"--",
"-",
"-X",
"--",
"-", 0 };
103 int count(
const char** args)
105 for (
int c = 0;; ++c)
106 if (args[c] == (
const char*) -1)
110 bool eq(
const char* s1,
const char* s2)
115 if (s1 == 0 || s2 == 0)
118 while (*s1 != 0 && *s2 != 0)
130 Stats stats(empty_usage, -1, empty_args);
131 stats.add(empty_usage, 0, empty_args);
132 assert(stats.buffer_max == 1);
133 assert(stats.options_max == 1);
134 Option buffer[stats.buffer_max];
135 Option options[stats.options_max];
136 Parser parse(empty_usage, 99, empty_args, options, buffer);
137 parse.parse(empty_usage, -1, empty_args, options, buffer);
138 assert(parse.optionsCount() == 0);
139 assert(parse.nonOptionsCount() == 0);
142 assert(buffer[0].count()==0);
143 assert(parse.nonOptions()==0);
145 stats.add(empty_usage, 3, non_options);
146 assert(stats.buffer_max == 1);
147 assert(stats.options_max == 1);
148 parse.parse(empty_usage, 3, non_options, options, buffer);
149 assert(parse.optionsCount() == 0);
150 assert(parse.nonOptionsCount() == 3);
153 assert(parse.nonOptions()==&non_options[0]);
155 stats.add(minimal_usage, -1, unknown_option);
156 assert(stats.buffer_max == 1);
157 assert(stats.options_max == 2);
158 parse.parse(minimal_usage, -1, unknown_option, options, buffer);
159 assert(parse.optionsCount() == 0);
160 assert(parse.nonOptionsCount() == 1);
163 assert(parse.nonOptions()==&unknown_option[1]);
166 Stats stats(gettext_usage, -1, lone_minus);
168 stats2.
add(gettext_usage, -1, lone_minus);
169 assert(stats.buffer_max == 2);
170 assert(stats.options_max == 2);
173 Option buffer[stats.buffer_max];
174 Option options[stats.options_max];
176 parse.
parse(gettext_usage, -1, lone_minus, options, buffer);
182 assert(options[0].count()==1);
183 assert(options[0].isFirst());
184 assert(options[0].isLast());
185 assert(options[0].first() == options[0]);
186 assert(options[0].last() == options[0]);
187 assert(options[0].prevwrap() == &options[0]);
188 assert(options[0].nextwrap() == &options[0]);
189 assert(options[0].prev() == 0);
190 assert(options[0].next() == 0);
191 assert(options[0].desc == &gettext_usage[0]);
192 assert(eq(options[0].name,
"f"));
193 assert(eq(options[0].arg,
"-"));
196 Stats stats(optional_usage, -1, lone_minus);
198 stats2.
add(optional_usage, -1, lone_minus);
199 assert(stats.buffer_max == 2);
200 assert(stats.options_max == 2);
203 Option buffer[stats.buffer_max];
204 Option options[stats.options_max];
206 parse.
parse(optional_usage, -1, lone_minus, options, buffer);
212 assert(options[0].count()==1);
213 assert(options[0].isFirst());
214 assert(options[0].isLast());
215 assert(options[0].first() == options[0]);
216 assert(options[0].last() == options[0]);
217 assert(options[0].prevwrap() == &options[0]);
218 assert(options[0].nextwrap() == &options[0]);
219 assert(options[0].prev() == 0);
220 assert(options[0].next() == 0);
221 assert(options[0].desc == &optional_usage[0]);
222 assert(eq(options[0].name,
"f"));
223 assert(eq(options[0].arg,
"-"));
227 stats.
add(minimal_usage, -1, lone_doubleminus);
232 Parser parse(minimal_usage, -1, lone_doubleminus, options, buffer);
241 stats.
add(multi_usage, count(multi1), multi1, 4,
true);
244 stats.
add(multi_usage, count(multi2), multi2, 4,
true);
247 stats.
add(multi_usage, count(multi3), multi3, 4,
true);
252 assert(options[FOO].last()->type() == UNUSED);
253 assert(options[ABBREVIATE].count()==0);
255 assert(!parse.
error());
257 parse.
parse(multi_usage, count(multi1), multi1, options, buffer, 4,
true);
258 assert(!parse.
error());
261 assert(eq(parse.
nonOptions()[0],
"--strangefilename"));
262 assert(options[FOO].last()->type() == ENABLED);
263 assert(eq(options[FOO].last()->name,
"--enable-foo"));
264 assert(options[FOO].last()->arg == 0);
265 assert(options[UNKNOWN].count() == 2);
266 assert(eq(options[UNKNOWN].first()->name,
"--unknown1"));
267 assert(eq(options[UNKNOWN].last()->name,
"u"));
268 assert(options[UNKNOWN].first()->arg == 0);
269 assert(options[UNKNOWN].last()->arg == 0);
270 assert(options[VERBOSE].count()==1);
271 assert(options[VERBOSE].arg==0);
272 assert(options[VERBOSE].name[0] ==
'v' && options[VERBOSE].namelen == 1);
273 assert(eq(options[X].arg,
"xyzzy"));
274 assert(eq(options[X].name,
"X"));
276 parse.
parse(multi_usage, count(multi2), multi2, options, buffer, 4,
true);
277 assert(!parse.
error());
280 assert(eq(parse.
nonOptions()[0],
"--strangefilename"));
281 assert(options[FOO].last()->type() == DISABLED);
282 assert(options[FOO].last()->arg == 0);
283 assert(options[UNKNOWN].count() == 2);
284 assert(eq(options[UNKNOWN].first()->name,
"--unknown1"));
285 assert(eq(options[UNKNOWN].last()->name,
"u"));
286 assert(options[VERBOSE].count()==4);
287 assert(options[X].count()==5);
288 const char* Xargs[] = {
"xyzzy",
"foo",
"bar",
"foobar",
"",
"sentinel" };
289 const char** Xarg = &Xargs[0];
290 for (
Option* Xiter = options[X]; Xiter != 0; Xiter = Xiter->
next())
291 assert(eq(Xiter->arg, *Xarg++));
293 assert(!options[ABBREVIATE]);
294 parse.
parse(multi_usage, count(multi3), multi3, options, buffer, 4,
true);
295 assert(!parse.
error());
298 assert(eq(parse.
nonOptions()[0],
"nonoption1"));
299 assert(eq(parse.
nonOptions()[1],
"nonoption2"));
300 assert(options[ABBREVIATE]);
301 assert(options[EMPTY].count()==3);
302 assert(options[EMPTY].first()->arg==0);
303 assert(eq(options[EMPTY].last()->arg,
""));
304 assert(eq(options[EMPTY].last()->prev()->arg,
""));
305 assert(options[FOO].last()->type() == DISABLED);
306 assert(options[UNKNOWN].count() == 5);
307 assert(eq(options[UNKNOWN].first()->name,
"--unknown1"));
308 assert(options[UNKNOWN].first()->arg == 0);
309 assert(eq(options[UNKNOWN].last()->name,
"b"));
310 assert(options[VERBOSE].count()==5);
311 assert(options[X].count()==5);
313 for (
Option* Xiter = options[X]; Xiter != 0; Xiter = Xiter->
next())
314 assert(eq(Xiter->arg, *Xarg++));
316 for (
Option* opt = buffer[0]; *opt; ++opt)
317 if (opt->desc->check_arg != Arg::Required && opt->desc->check_arg != Arg::Empty)
318 assert(opt->arg == 0);
324 assert(!parse.
error());
325 parse.
parse(multi_usage, -1, illegal, options, buffer, 0,
false, 2);
326 assert(parse.
error());
329 Stats stats(multi_usage, count(multi3), multi3, 0,
true);
330 const int bufmax = 3;
333 assert(!options[ABBREVIATE]);
334 Parser parse(multi_usage, count(multi3), multi3, options, buffer, 4,
true, bufmax);
335 assert(!parse.
error());
338 assert(eq(parse.
nonOptions()[0],
"nonoption1"));
339 assert(eq(parse.
nonOptions()[1],
"nonoption2"));
340 assert(options[ABBREVIATE]);
341 assert(options[UNKNOWN].count() == 2);
342 assert(options[UNKNOWN].first()->name[0] ==
'a' && options[UNKNOWN].first()->namelen == 1);
343 assert(options[UNKNOWN].first()->arg == 0);
344 assert(eq(options[UNKNOWN].last()->name,
"bb"));
347 Stats stats(
true, multi_usage, -1, reorder);
350 Parser parse(
true, multi_usage, -1, reorder, options, buffer);
351 assert(!parse.
error());
359 Parser parse(
true, multi_usage, 666, reorder2, options, buffer, 0,
false, 10);
360 assert(!parse.
error());
365 fprintf(stdout,
"All tests passed.\n");
Determines the minimum lengths of the buffer and options arrays used for Parser.
This is the only file required to use The Lean Mean C++ Option Parser. Just #include it and you're se...
unsigned options_max
Number of elements needed for an options[] array to be used for parsing the same argument vectors tha...
bool error()
Returns true if an unrecoverable error occurred while parsing options.
static ArgStatus None(const Option &, bool)
For options that don't take an argument: Returns ARG_NONE.
int nonOptionsCount()
Returns the number of non-option arguments that remained at the end of the most recent parse() that a...
void add(bool gnu, const Descriptor usage[], int argc, const char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
Updates this Stats object for the given usage and argument vector. You may pass 0 for argc and/or arg...
A parsed option from the command line together with its argument if it has one.
Functions for checking the validity of option arguments.
Option * next()
Returns a pointer to the next element of the linked list or NULL if called on last().
Checks argument vectors for validity and parses them into data structures that are easier to work wit...
const char ** nonOptions()
Returns a pointer to an array of non-option arguments (only valid if nonOptionsCount() >0 )...
Describes an option, its help text (usage) and how it should be parsed.
The argument is acceptable for the option.
The namespace of The Lean Mean C++ Option Parser.
const char * arg
Pointer to this Option's argument (if any).
int optionsCount()
Returns the number of valid Option objects in buffer[].
unsigned buffer_max
Number of elements needed for a buffer[] array to be used for parsing the same argument vectors that ...
The argument is not acceptable and that's fatal.
The argument is not acceptable but that's non-fatal because the option's argument is optional...
ArgStatus
Possible results when checking if an argument is valid for a certain option.
void parse(bool gnu, const Descriptor usage[], int argc, const char **argv, Option options[], Option buffer[], int min_abbr_len=0, bool single_minus_longopt=false, int bufmax=-1)
Parses the given argument vector.