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");
options = parser.parse(argc, argv);
if (!options.valid() || options.isSet(OptHelp)) {
if (!options.valid())
return -EINVAL;
if (options.empty() || options.isSet(OptHelp)) {
parser.usage();
return !options.valid() ? -EINVAL : -EINTR;
return options.empty() ? -EINVAL : -EINTR;
}
return 0;

View file

@ -40,10 +40,16 @@ const char *Option::typeName() const
* OptionBase<T>
*/
template<typename T>
bool OptionsBase<T>::empty() const
{
return values_.empty();
}
template<typename T>
bool OptionsBase<T>::valid() const
{
return !values_.empty();
return valid_;
}
template<typename T>
@ -105,12 +111,6 @@ bool OptionsBase<T>::parseValue(const T &opt, const Option &option,
return true;
}
template<typename T>
void OptionsBase<T>::clear()
{
values_.clear();
}
template class OptionsBase<int>;
template class OptionsBase<std::string>;
@ -170,21 +170,18 @@ KeyValueParser::Options KeyValueParser::parse(const char *arguments)
if (optionsMap_.find(key) == optionsMap_.end()) {
std::cerr << "Invalid option " << key << std::endl;
options.clear();
break;
return options;
}
OptionArgument arg = optionsMap_[key].argument;
if (value.empty() && arg == ArgumentRequired) {
std::cerr << "Option " << key << " requires an argument"
<< std::endl;
options.clear();
break;
return options;
} else if (!value.empty() && arg == ArgumentNone) {
std::cerr << "Option " << key << " takes no argument"
<< std::endl;
options.clear();
break;
return options;
}
const Option &option = optionsMap_[key];
@ -192,11 +189,11 @@ KeyValueParser::Options KeyValueParser::parse(const char *arguments)
std::cerr << "Failed to parse '" << value << "' as "
<< option.typeName() << " for option " << key
<< std::endl;
options.clear();
break;
return options;
}
}
options.valid_ = true;
return options;
}
@ -438,19 +435,18 @@ OptionsParser::Options OptionsParser::parse(int argc, char **argv)
std::cerr << argv[optind - 1] << std::endl;
usage();
options.clear();
break;
return options;
}
const Option &option = *optionsMap_[c];
if (!options.parseValue(c, option, optarg)) {
parseValueError(option);
usage();
options.clear();
break;
return options;
}
}
options.valid_ = true;
return options;
}

View file

@ -47,6 +47,9 @@ template<typename T>
class OptionsBase
{
public:
OptionsBase() : valid_(false) {}
bool empty() const;
bool valid() const;
bool isSet(const T &opt) const;
const OptionValue &operator[](const T &opt) const;
@ -56,9 +59,9 @@ private:
friend class OptionsParser;
bool parseValue(const T &opt, const Option &option, const char *value);
void clear();
std::map<T, OptionValue> values_;
bool valid_;
};
class KeyValueParser