cam: options: Add support for repeatable options

Add a flag to indicate if an option can be repeatable. If an option is
repeatable it must be accessed thru the array interface, even if it's
only specified once by the user.

Also update the usage generator to indicate which options are
repeatable.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
Niklas Söderlund 2019-03-21 19:28:56 +01:00
parent 2a608965f8
commit 3f906920e4
2 changed files with 18 additions and 8 deletions

View file

@ -97,7 +97,11 @@ bool OptionsBase<T>::parseValue(const T &opt, const Option &option,
break; break;
} }
values_[opt] = value; if (option.isArray)
values_[opt].addValue(value);
else
values_[opt] = value;
return true; return true;
} }
@ -129,7 +133,7 @@ bool KeyValueParser::addOption(const char *name, OptionType type,
return false; return false;
optionsMap_[name] = Option({ 0, type, name, argument, nullptr, optionsMap_[name] = Option({ 0, type, name, argument, nullptr,
help, nullptr }); help, nullptr, false });
return true; return true;
} }
@ -339,7 +343,7 @@ std::vector<OptionValue> OptionValue::toArray() const
bool OptionsParser::addOption(int opt, OptionType type, const char *help, bool OptionsParser::addOption(int opt, OptionType type, const char *help,
const char *name, OptionArgument argument, const char *name, OptionArgument argument,
const char *argumentName) const char *argumentName, bool array)
{ {
/* /*
* Options must have at least a short or long name, and a text message. * Options must have at least a short or long name, and a text message.
@ -357,16 +361,16 @@ bool OptionsParser::addOption(int opt, OptionType type, const char *help,
return false; return false;
options_.push_back(Option({ opt, type, name, argument, argumentName, options_.push_back(Option({ opt, type, name, argument, argumentName,
help, nullptr })); help, nullptr, array }));
optionsMap_[opt] = &options_.back(); optionsMap_[opt] = &options_.back();
return true; return true;
} }
bool OptionsParser::addOption(int opt, KeyValueParser *parser, const char *help, bool OptionsParser::addOption(int opt, KeyValueParser *parser, const char *help,
const char *name) const char *name, bool array)
{ {
if (!addOption(opt, OptionKeyValue, help, name, ArgumentRequired, if (!addOption(opt, OptionKeyValue, help, name, ArgumentRequired,
"key=value[,key=value,...]")) "key=value[,key=value,...]", array))
return false; return false;
options_.back().keyValueParser = parser; options_.back().keyValueParser = parser;
@ -464,6 +468,8 @@ void OptionsParser::usage()
length += 1 + strlen(option.argumentName); length += 1 + strlen(option.argumentName);
if (option.argument == ArgumentOptional) if (option.argument == ArgumentOptional)
length += 2; length += 2;
if (option.isArray)
length += 4;
if (length > indent) if (length > indent)
indent = length; indent = length;
@ -497,6 +503,9 @@ void OptionsParser::usage()
argument += "]"; argument += "]";
} }
if (option.isArray)
argument += " ...";
std::cerr << std::setw(indent) << std::left << argument; std::cerr << std::setw(indent) << std::left << argument;
for (const char *help = option.help, *end = help; end; ) { for (const char *help = option.help, *end = help; end; ) {

View file

@ -36,6 +36,7 @@ struct Option {
const char *argumentName; const char *argumentName;
const char *help; const char *help;
KeyValueParser *keyValueParser; KeyValueParser *keyValueParser;
bool isArray;
bool hasShortOption() const { return isalnum(opt); } bool hasShortOption() const { return isalnum(opt); }
bool hasLongOption() const { return name != nullptr; } bool hasLongOption() const { return name != nullptr; }
@ -126,9 +127,9 @@ public:
bool addOption(int opt, OptionType type, const char *help, bool addOption(int opt, OptionType type, const char *help,
const char *name = nullptr, const char *name = nullptr,
OptionArgument argument = ArgumentNone, OptionArgument argument = ArgumentNone,
const char *argumentName = nullptr); const char *argumentName = nullptr, bool array = false);
bool addOption(int opt, KeyValueParser *parser, const char *help, bool addOption(int opt, KeyValueParser *parser, const char *help,
const char *name = nullptr); const char *name = nullptr, bool array = false);
Options parse(int argc, char *argv[]); Options parse(int argc, char *argv[]);
void usage(); void usage();