cam: Separate options valid() and empty()
An empty option list is not necessarily an error. Add a new empty() function to test the option list for emptiness, and modify the valid() function to only notify parsing errors. As a side effect this allows accessing partially parsed options, which may be useful in the future. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
This commit is contained in:
parent
3f906920e4
commit
f8386836df
3 changed files with 24 additions and 22 deletions
|
@ -67,9 +67,12 @@ static int parseOptions(int argc, char *argv[])
|
||||||
parser.addOption(OptList, OptionNone, "List all cameras", "list");
|
parser.addOption(OptList, OptionNone, "List all cameras", "list");
|
||||||
|
|
||||||
options = parser.parse(argc, argv);
|
options = parser.parse(argc, argv);
|
||||||
if (!options.valid() || options.isSet(OptHelp)) {
|
if (!options.valid())
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (options.empty() || options.isSet(OptHelp)) {
|
||||||
parser.usage();
|
parser.usage();
|
||||||
return !options.valid() ? -EINVAL : -EINTR;
|
return options.empty() ? -EINVAL : -EINTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -40,10 +40,16 @@ const char *Option::typeName() const
|
||||||
* OptionBase<T>
|
* OptionBase<T>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool OptionsBase<T>::empty() const
|
||||||
|
{
|
||||||
|
return values_.empty();
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool OptionsBase<T>::valid() const
|
bool OptionsBase<T>::valid() const
|
||||||
{
|
{
|
||||||
return !values_.empty();
|
return valid_;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -105,12 +111,6 @@ bool OptionsBase<T>::parseValue(const T &opt, const Option &option,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void OptionsBase<T>::clear()
|
|
||||||
{
|
|
||||||
values_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
template class OptionsBase<int>;
|
template class OptionsBase<int>;
|
||||||
template class OptionsBase<std::string>;
|
template class OptionsBase<std::string>;
|
||||||
|
|
||||||
|
@ -170,21 +170,18 @@ KeyValueParser::Options KeyValueParser::parse(const char *arguments)
|
||||||
|
|
||||||
if (optionsMap_.find(key) == optionsMap_.end()) {
|
if (optionsMap_.find(key) == optionsMap_.end()) {
|
||||||
std::cerr << "Invalid option " << key << std::endl;
|
std::cerr << "Invalid option " << key << std::endl;
|
||||||
options.clear();
|
return options;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionArgument arg = optionsMap_[key].argument;
|
OptionArgument arg = optionsMap_[key].argument;
|
||||||
if (value.empty() && arg == ArgumentRequired) {
|
if (value.empty() && arg == ArgumentRequired) {
|
||||||
std::cerr << "Option " << key << " requires an argument"
|
std::cerr << "Option " << key << " requires an argument"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
options.clear();
|
return options;
|
||||||
break;
|
|
||||||
} else if (!value.empty() && arg == ArgumentNone) {
|
} else if (!value.empty() && arg == ArgumentNone) {
|
||||||
std::cerr << "Option " << key << " takes no argument"
|
std::cerr << "Option " << key << " takes no argument"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
options.clear();
|
return options;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Option &option = optionsMap_[key];
|
const Option &option = optionsMap_[key];
|
||||||
|
@ -192,11 +189,11 @@ KeyValueParser::Options KeyValueParser::parse(const char *arguments)
|
||||||
std::cerr << "Failed to parse '" << value << "' as "
|
std::cerr << "Failed to parse '" << value << "' as "
|
||||||
<< option.typeName() << " for option " << key
|
<< option.typeName() << " for option " << key
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
options.clear();
|
return options;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options.valid_ = true;
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,19 +435,18 @@ OptionsParser::Options OptionsParser::parse(int argc, char **argv)
|
||||||
std::cerr << argv[optind - 1] << std::endl;
|
std::cerr << argv[optind - 1] << std::endl;
|
||||||
|
|
||||||
usage();
|
usage();
|
||||||
options.clear();
|
return options;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Option &option = *optionsMap_[c];
|
const Option &option = *optionsMap_[c];
|
||||||
if (!options.parseValue(c, option, optarg)) {
|
if (!options.parseValue(c, option, optarg)) {
|
||||||
parseValueError(option);
|
parseValueError(option);
|
||||||
usage();
|
usage();
|
||||||
options.clear();
|
return options;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options.valid_ = true;
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,9 @@ template<typename T>
|
||||||
class OptionsBase
|
class OptionsBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
OptionsBase() : valid_(false) {}
|
||||||
|
|
||||||
|
bool empty() const;
|
||||||
bool valid() const;
|
bool valid() const;
|
||||||
bool isSet(const T &opt) const;
|
bool isSet(const T &opt) const;
|
||||||
const OptionValue &operator[](const T &opt) const;
|
const OptionValue &operator[](const T &opt) const;
|
||||||
|
@ -56,9 +59,9 @@ private:
|
||||||
friend class OptionsParser;
|
friend class OptionsParser;
|
||||||
|
|
||||||
bool parseValue(const T &opt, const Option &option, const char *value);
|
bool parseValue(const T &opt, const Option &option, const char *value);
|
||||||
void clear();
|
|
||||||
|
|
||||||
std::map<T, OptionValue> values_;
|
std::map<T, OptionValue> values_;
|
||||||
|
bool valid_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class KeyValueParser
|
class KeyValueParser
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue