2
* This file is part of bino, a 3D video player.
4
* Copyright (C) 2006-2007, 2009-2011
5
* Martin Lambers <marlam@marlam.de>
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 3 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program. If not, see <http://www.gnu.org/licenses/>.
33
* \brief Command line parsing
35
* This module allows quick and easy command line parsing.
37
* A set of useful default option types is provided, and you can implement your own.
39
* The idea is to build a vector of the options you want to support,
40
* and the call the opt::parse() function to parse your command line.
44
* opt::info version("version", '\0', opt::optional);
45
* opt::flag verbose("verbose", 'v', opt::optional);
46
* opt::val<int> width("width", 'w', opt::required, 1, 100, 50);
48
* std::vector<opt::option *> options;
49
* options.push_back(&version);
50
* options.push_back(&verbose);
51
* options.push_back(&width);
53
* std::vector<std::string> arguments;
54
* opt::parse(argc, argv, options, 1, -1, arguments);
60
* \brief Option policy
62
* Policy of an option.
66
optional = 0, /** The option is optional. */
67
required = 1 /** The option is mandatory. */
71
* \brief Option interface
73
* The interface for options.\n
74
* You can implement your own options by implementing this interface.\n
75
* If the option takes arguments, you should also implement the two
76
* functions value() and values().\n
77
* The function value() should return the parsed argument of the last occurence
78
* of the option, whereas the function values() should return the parsed arguments
79
* of all occurences of the option in a vector. An empty vector indicates that
80
* the option was not given on the command line.\n
85
std::string _longname;
87
option_policy _policy;
92
* \param longname Long name of the option, or "".
93
* \param shortname Short name of the option, or '\0'.
94
* \param mandatory Whether this option is mandatory or optional.
96
option(const std::string &longname, char shortname, option_policy policy)
97
: _longname(longname), _shortname(shortname), _policy(policy)
101
const std::string &longname() const
106
char shortname() const
111
opt::option_policy policy() const
117
* \brief Argument policy
119
* Argument policy of an option.
123
no_argument = 0, /** The option takes no argument. */
124
required_argument = 1, /** The option requires an argument. */
125
optional_argument = 2 /** The option accepts an optional argument. */
129
* \brief Return the argument policy of this option.
130
* \return The argument policy.
132
virtual enum argument_policy argument_policy() const = 0;
135
* \brief Parse an argument to this option (if applicable).
136
* \param argument The argument. Empty if there is no argument.
137
* \return Success (true) or failure (false).
139
virtual bool parse_argument(const std::string &argument) = 0;
143
* \brief Parse the command line.
144
* \param argc The standard argc parameter.
145
* \param argv The standard argv parameter.
146
* \param options A vector with pointers to options.
147
* \param min_arguments Minimum number of arguments, or -1 if there is no limit.
148
* \param max_arguments Maximum number of arguments, or -1 if there is no limit.
149
* \param arguments A vector in which the arguments will be stored.
150
* \return Success (true) or failure (false).
152
* This function parses the command line. It uses GNU's getopt_long()
153
* internally and thus has the same features:\n
154
* - allows abbreviation of long options to their shortest unambiguous prefix
155
* - allows mixing of arguments and options
156
* - space between short option and argument is optional
157
* - arguments to long options can be given with an optional '=' character
158
* - the special argument '--' separates options from arguments
161
bool parse(int argc, char *argv[],
162
std::vector<option *> &options,
163
int min_arguments, int max_arguments,
164
std::vector<std::string> &arguments);
167
* \brief An option type for informational options.
169
* This option type is for options such as --help and --version. When such an
170
* option is found, the parser will not test for the presence of mandatory
171
* options or arguments, so that 'prg --help' and 'prg --version' always work.
173
* The value() function will return whether this option was seen.
175
class info : public option
181
info(const std::string &longname, char shortname, enum option_policy policy)
182
: option(longname, shortname, policy), _seen(false)
186
enum argument_policy argument_policy() const
191
bool parse_argument(const std::string &)
204
* \brief An option type for flags.
206
* This option type provides flags. A flag may have no argument, in which
207
* case a default argument is assumed, or it may have one of the arguments "true",
208
* "on", "yes" to set the flag, or "false", "off", "no" to unset the flag.
210
class flag : public option
213
const bool _default_value;
214
const bool _default_argument;
215
std::vector<bool> _values;
218
flag(const std::string &longname, char shortname, enum option_policy policy,
219
bool default_value = false, bool default_argument = true)
220
: option(longname, shortname, policy),
221
_default_value(default_value), _default_argument(default_argument)
225
enum argument_policy argument_policy() const
227
return optional_argument;
230
bool parse_argument(const std::string &argument)
232
if (argument.empty())
234
_values.push_back(_default_argument);
237
else if (argument.compare("on") == 0 || argument.compare("true") == 0 || argument.compare("yes") == 0)
239
_values.push_back(true);
242
else if (argument.compare("off") == 0 || argument.compare("false") == 0 || argument.compare("no") == 0)
244
_values.push_back(false);
255
return (_values.size() > 0 ? _values.back() : _default_value);
258
const std::vector<bool> &values() const
265
* \brief An option type for values.
267
* This option type allows to parse a value of arbitrary type.\n
268
* The number of allowed values can optionally be restricted:\n
269
* - If a lower and higher bound are given, then only values within this range
270
* are allowed. Other values will be rejected. The bounds
271
* are inclusive by default, but can be made exclusive (useful
272
* for floating point data).
273
* - If a vector of allowed values is given, only these values
274
* will be allowed, and all other values will be rejected.
276
* Note that if this option type is used with type std::string,
277
* then the string must not contain spaces. If you need to parse strings with spaces,
281
class val : public option
284
enum restriction_policy
290
const restriction_policy _restriction_policy;
291
const T _lower_bound;
292
const bool _lower_bound_inclusive;
293
const T _higher_bound;
294
const bool _higher_bound_inclusive;
295
const std::vector<T> _allowed_values;
296
const T _default_value;
297
std::vector<T> _values;
300
val(const std::string &longname, char shortname, enum option_policy policy,
301
const T &lower_bound, const T &higher_bound, const T &default_value = T())
302
: option(longname, shortname, policy),
303
_restriction_policy(bounds),
304
_lower_bound(lower_bound), _lower_bound_inclusive(true),
305
_higher_bound(higher_bound), _higher_bound_inclusive(true),
307
_default_value(default_value)
310
val(const std::string &longname, char shortname, enum option_policy policy,
311
const T &lower_bound, bool lower_bound_inclusive,
312
const T &higher_bound, bool higher_bound_inclusive,
313
const T &default_value = T())
314
: option(longname, shortname, policy),
315
_restriction_policy(bounds),
316
_lower_bound(lower_bound), _lower_bound_inclusive(lower_bound_inclusive),
317
_higher_bound(higher_bound), _higher_bound_inclusive(higher_bound_inclusive),
319
_default_value(default_value)
322
val(const std::string &longname, char shortname, enum option_policy policy,
323
const std::vector<T> &allowed_values, const T &default_value = T())
324
: option(longname, shortname, policy),
325
_restriction_policy(val::allowed_values),
326
_lower_bound(), _lower_bound_inclusive(),
327
_higher_bound(), _higher_bound_inclusive(),
328
_allowed_values(allowed_values),
329
_default_value(default_value)
332
val(const std::string &longname, char shortname, enum option_policy policy,
333
const T &default_value = T())
334
: option(longname, shortname, policy),
335
_restriction_policy(none),
336
_lower_bound(), _lower_bound_inclusive(),
337
_higher_bound(), _higher_bound_inclusive(),
339
_default_value(default_value)
343
enum argument_policy argument_policy() const
345
return required_argument;
348
bool parse_argument(const std::string &argument)
351
std::istringstream is(argument);
355
if (!is.fail() && is.eof())
357
if (_restriction_policy == allowed_values)
359
for (size_t i = 0; i < _allowed_values.size(); i++)
361
if (_allowed_values[i] <= v && _allowed_values[i] >= v)
368
else if (_restriction_policy == bounds)
370
ok = (((_lower_bound_inclusive && v >= _lower_bound)
371
|| (!_lower_bound_inclusive && v > _lower_bound))
372
&& ((_higher_bound_inclusive && v <= _higher_bound)
373
|| (!_higher_bound_inclusive && v < _higher_bound)));
375
else // _restriction_policy == none
381
_values.push_back(v);
387
const T &value() const
389
return (_values.size() > 0 ? _values.back() : _default_value);
392
const std::vector<T> &values() const
399
class tuple : public option
402
enum restriction_policy
408
const std::string _separator;
409
const bool _size_is_fixed;
410
const size_t _fixed_size;
411
const restriction_policy _restriction_policy;
412
const T _lower_bound;
413
const bool _lower_bound_inclusive;
414
const T _higher_bound;
415
const bool _higher_bound_inclusive;
416
const std::vector<T> _allowed_values;
417
const std::vector<T> _default_value;
418
std::vector<std::vector<T> > _values;
421
tuple(const std::string &longname, char shortname, enum option_policy policy,
422
const T &lower_bound, const T &higher_bound,
423
const std::vector<T> &default_value = std::vector<T>(),
424
int fixed_size = -1, const std::string &separator = ",")
425
: option(longname, shortname, policy),
426
_separator(separator), _size_is_fixed(fixed_size >= 0), _fixed_size(fixed_size),
427
_restriction_policy(bounds),
428
_lower_bound(lower_bound), _lower_bound_inclusive(true),
429
_higher_bound(higher_bound), _higher_bound_inclusive(true),
431
_default_value(default_value)
434
tuple(const std::string &longname, char shortname, enum option_policy policy,
435
const T &lower_bound, bool lower_bound_inclusive,
436
const T &higher_bound, bool higher_bound_inclusive,
437
const std::vector<T> &default_value = std::vector<T>(),
438
int fixed_size = -1, const std::string &separator = ",")
439
: option(longname, shortname, policy),
440
_separator(separator), _size_is_fixed(fixed_size >= 0), _fixed_size(fixed_size),
441
_restriction_policy(bounds),
442
_lower_bound(lower_bound), _lower_bound_inclusive(lower_bound_inclusive),
443
_higher_bound(higher_bound), _higher_bound_inclusive(higher_bound_inclusive),
445
_default_value(default_value)
448
tuple(const std::string &longname, char shortname, enum option_policy policy,
449
const std::vector<T> &allowed_values,
450
const std::vector<T> &default_value,
451
int fixed_size = -1, const std::string &separator = ",")
452
: option(longname, shortname, policy),
453
_separator(separator), _size_is_fixed(fixed_size >= 0), _fixed_size(fixed_size),
454
_restriction_policy(tuple::allowed_values),
455
_lower_bound(), _lower_bound_inclusive(),
456
_higher_bound(), _higher_bound_inclusive(),
457
_allowed_values(allowed_values),
458
_default_value(default_value)
461
tuple(const std::string &longname, char shortname, enum option_policy policy,
462
const std::vector<T> &default_value = std::vector<T>(),
463
int fixed_size = -1, const std::string &separator = ",")
464
: option(longname, shortname, policy),
465
_separator(separator), _size_is_fixed(fixed_size >= 0), _fixed_size(fixed_size),
466
_restriction_policy(none),
467
_lower_bound(), _lower_bound_inclusive(),
468
_higher_bound(), _higher_bound_inclusive(),
470
_default_value(default_value)
474
enum argument_policy argument_policy() const
476
return required_argument;
479
bool parse_argument(const std::string &argument)
481
std::istringstream is(argument);
483
if (argument.length() > 0)
496
for (size_t i = 0; i < _separator.length(); i++)
500
if (is.fail() || c != _separator[i])
509
if (_size_is_fixed && vv.size() != _fixed_size)
513
if (_restriction_policy == allowed_values)
516
for (size_t i = 0; i < _allowed_values.size(); i++)
518
for (size_t j = 0; j < vv.size(); j++)
520
if (_allowed_values[i] <= vv[j] && _allowed_values[i] >= vv[j])
536
else if (_restriction_policy == bounds)
538
for (size_t i = 0; i < vv.size(); i++)
540
if ((_lower_bound_inclusive && vv[i] < _lower_bound)
541
|| (!_lower_bound_inclusive && vv[i] <= _lower_bound)
542
|| (_higher_bound_inclusive && vv[i] > _higher_bound)
543
|| (!_higher_bound_inclusive && vv[i] >= _higher_bound))
549
_values.push_back(vv);
553
const std::vector<T> &value() const
555
return (_values.size() > 0 ? _values.back() : _default_value);
558
const std::vector<std::vector<T> > &values() const
565
* \brief An option type for strings.
567
* This option type allows to parse arbitrary strings, including spaces.
568
* Optionally, a list of allowed strings can be given, and also a list
569
* of allowed control characters. By default, the string must not contain
570
* control characters.
572
class string : public option
575
const std::string _allowed_control_chars;
576
const std::vector<std::string> _allowed_values;
577
const std::string _default_value;
578
std::vector<std::string> _values;
581
string(const std::string &longname, char shortname, enum option_policy policy,
582
const std::vector<std::string> allowed_values,
583
const std::string &default_value = "")
584
: option(longname, shortname, policy),
585
_allowed_control_chars(""),
586
_allowed_values(allowed_values),
587
_default_value(default_value)
590
string(const std::string &longname, char shortname, enum option_policy policy,
591
const std::string &allowed_control_chars,
592
const std::string &default_value)
593
: option(longname, shortname, policy),
594
_allowed_control_chars(allowed_control_chars),
596
_default_value(default_value)
599
string(const std::string &longname, char shortname, enum option_policy policy,
600
const std::string &default_value = "")
601
: option(longname, shortname, policy),
602
_allowed_control_chars(""),
604
_default_value(default_value)
608
enum argument_policy argument_policy() const
610
return required_argument;
613
bool parse_argument(const std::string &argument)
616
if (_allowed_values.size() > 0)
619
for (size_t i = 0; i < _allowed_values.size(); i++)
621
if (argument.compare(_allowed_values[i]) == 0)
631
for (size_t i = 0; i < argument.length(); i++)
633
char c = argument[i];
634
if (std::iscntrl(c) && _allowed_control_chars.find(c) == std::string::npos)
643
_values.push_back(argument);
648
const std::string &value() const
650
return (_values.size() > 0 ? _values.back() : _default_value);
653
const std::vector<std::string> &values() const
660
* \brief An option type for colors.
662
* This option type accepts colors in the format [AA]RRGGBB. If the alpha
663
* part is omitted, it is set to 255.
664
* Color values are returned in uint32_t BGRA format.
666
class color : public option
669
uint32_t _default_value;
670
std::vector<uint32_t> _values;
673
color(const std::string &longname, char shortname, option_policy policy,
674
uint32_t default_value = 0u)
675
: option(longname, shortname, policy),
676
_default_value(default_value)
680
virtual enum argument_policy argument_policy() const
682
return required_argument;
685
virtual bool parse_argument(const std::string &argument)
687
unsigned int a = 255u, r, g, b;
688
if (argument.length() != 8 && argument.length() != 6)
692
else if (argument.length() == 8 && std::sscanf(argument.c_str(), "%2x%2x%2x%2x", &a, &r, &g, &b) != 4)
696
else if (argument.length() == 6 && std::sscanf(argument.c_str(), "%2x%2x%2x", &r, &g, &b) != 3)
700
_values.push_back((a << 24u) | (r << 16u) | (g << 8u) | b);
704
uint32_t value() const
706
return (_values.size() > 0 ? _values.back() : _default_value);
709
const std::vector<uint32_t> &values() const