[libcamera-devel] [RFC 1/2] cam: options: add parser for suboptions

Niklas Söderlund niklas.soderlund at ragnatech.se
Fri Jan 25 22:21:53 CET 2019


The cam utility will make use of lists of key/value pairs from the
command line arguments. This is needed so that a user can among other
things describe complex stream format descriptions, which consists of a
set of parameters.

Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
---
 src/cam/options.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++++
 src/cam/options.h   | 24 ++++++++++++++++
 2 files changed, 92 insertions(+)

diff --git a/src/cam/options.cpp b/src/cam/options.cpp
index 55c42540f92478e6..3299cdfed69703fa 100644
--- a/src/cam/options.cpp
+++ b/src/cam/options.cpp
@@ -180,3 +180,71 @@ void OptionsParser::Options::clear()
 {
 	values_.clear();
 }
+
+void SubOptionsParser::addToken(const char *name)
+{
+	if (!name)
+		return;
+
+	/* Reject duplicate options. */
+	for (const char *option : options_)
+		if (!strcmp(name, option))
+			return;
+
+	options_.push_back(name);
+}
+
+SubOptionsParser::Options SubOptionsParser::parse(const char *argc)
+{
+	const char **tokens;
+	char *dupe, *subs, *value;
+	Options options;
+
+	tokens = new const char *[options_.size() + 1]();
+	for (unsigned int i = 0; i < options_.size(); i++)
+		tokens[i] = options_.at(i);
+
+	dupe = strdup(argc);
+	subs = dupe;
+	while (*subs != '\0') {
+		int opt = getsubopt(&subs, (char *const *)tokens, &value);
+
+		if (opt == -1 || !value || value[0] == '\0') {
+			if (opt == -1)
+				std::cerr << "Invalid option " << value << std::endl;
+			else
+				std::cerr << "Missing argument for option "
+					  << tokens[opt] << std::endl;
+
+			options.clear();
+			break;
+		}
+
+		options.values_[tokens[opt]] = value;
+	}
+
+	free(dupe);
+	delete[] tokens;
+
+	return options;
+}
+
+bool SubOptionsParser::Options::valid() const
+{
+	return !values_.empty();
+}
+
+bool SubOptionsParser::Options::isSet(std::string opt) const
+{
+	return values_.find(opt) != values_.end();
+}
+
+const std::string &SubOptionsParser::Options::operator[](std::string opt) const
+{
+	return values_.find(opt)->second;
+}
+
+void SubOptionsParser::Options::clear()
+{
+	values_.clear();
+}
diff --git a/src/cam/options.h b/src/cam/options.h
index f99ea7300a71c24f..653dda0c76e52251 100644
--- a/src/cam/options.h
+++ b/src/cam/options.h
@@ -57,4 +57,28 @@ private:
 	std::map<unsigned int, Option *> optionsMap_;
 };
 
+class SubOptionsParser
+{
+public:
+	class Options
+	{
+	public:
+		bool valid() const;
+		bool isSet(std::string opt) const;
+		const std::string &operator[](std::string opt) const;
+
+	private:
+		friend class SubOptionsParser;
+		std::map<std::string, std::string> values_;
+		void clear();
+	};
+
+	void addToken(const char *token);
+
+	Options parse(const char *argc);
+
+private:
+	std::vector<const char *> options_;
+};
+
 #endif /* __CAM_OPTIONS_H__ */
-- 
2.20.1



More information about the libcamera-devel mailing list