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;
}
values_[opt] = value;
if (option.isArray)
values_[opt].addValue(value);
else
values_[opt] = value;
return true;
}
@ -129,7 +133,7 @@ bool KeyValueParser::addOption(const char *name, OptionType type,
return false;
optionsMap_[name] = Option({ 0, type, name, argument, nullptr,
help, nullptr });
help, nullptr, false });
return true;
}
@ -339,7 +343,7 @@ std::vector<OptionValue> OptionValue::toArray() const
bool OptionsParser::addOption(int opt, OptionType type, const char *help,
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.
@ -357,16 +361,16 @@ bool OptionsParser::addOption(int opt, OptionType type, const char *help,
return false;
options_.push_back(Option({ opt, type, name, argument, argumentName,
help, nullptr }));
help, nullptr, array }));
optionsMap_[opt] = &options_.back();
return true;
}
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,
"key=value[,key=value,...]"))
"key=value[,key=value,...]", array))
return false;
options_.back().keyValueParser = parser;
@ -464,6 +468,8 @@ void OptionsParser::usage()
length += 1 + strlen(option.argumentName);
if (option.argument == ArgumentOptional)
length += 2;
if (option.isArray)
length += 4;
if (length > indent)
indent = length;
@ -497,6 +503,9 @@ void OptionsParser::usage()
argument += "]";
}
if (option.isArray)
argument += " ...";
std::cerr << std::setw(indent) << std::left << argument;
for (const char *help = option.help, *end = help; end; ) {

View file

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