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:
Laurent Pinchart 2019-03-23 06:05:46 +02:00
parent 3f906920e4
commit f8386836df
3 changed files with 24 additions and 22 deletions

View file

@ -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;

View file

@ -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;
} }

View file

@ -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