diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | tests/cmdoptions.h | 97 | ||||
| -rw-r--r-- | tests/optiontester.cpp | 29 | 
3 files changed, 128 insertions, 0 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 10b269f..11eadc0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -9,3 +9,5 @@ target_link_libraries(testpat kms++ kmstest ${LIBDRM_LIBRARIES})  add_executable (kmsview kmsview.cpp)  target_link_libraries(kmsview kms++ kmstest ${LIBDRM_LIBRARIES}) + +add_executable (optiontester optiontester.cpp) diff --git a/tests/cmdoptions.h b/tests/cmdoptions.h new file mode 100644 index 0000000..843e65a --- /dev/null +++ b/tests/cmdoptions.h @@ -0,0 +1,97 @@ +#pragma once + +#include <cstdio> +#include <string> +#include <vector> +#include <map> + +using namespace std; + +#define NO_PARAM(h) (CmdOption(false, h)) +#define HAS_PARAM(h) (CmdOption(true, h)) + +class CmdOption +{ +public: +	CmdOption(bool has_param, string help) : +	        m_has_param(has_param), m_help(help), m_is_set(false) { } +        bool has_param() const { return m_has_param; } +	const string& help() const { return m_help; } + +	void oset() { m_is_set = true; } +	void pset(const string& p) { m_param = p; oset(); } +        bool is_set() const { return m_is_set; } +        const string& param() const { return m_param; } +private: +	bool m_has_param; +	string m_help; + +	bool m_is_set; +	string m_param; +}; + +class CmdOptions +{ +public: +	CmdOptions(int argc, char **argv, map<string, CmdOption>& opts) : +		m_opts(opts), m_cmd(argv[0]) { +		for (int i = 1; i < argc; i++) { +			if (argv[i][0] == '-') { +				auto ii = m_opts.find(&argv[i][1]); +				if (ii == m_opts.end()) { +					m_error += m_cmd + ": " + +						string(argv[i]) + +						": unknown option\n"; +					continue; +				} +				if ((*ii).second.has_param()) { +					if (++i == argc) { +						m_error += m_cmd + ": -" + +							(*ii).first + +							": parameter missing\n"; +						continue; +					} +					(*ii).second.pset(argv[i]); +				} else { +					(*ii).second.oset(); +				} +			} else { +				m_params.push_back(argv[i]); +			} +		} +	} +	const string& error() const { return m_error; } +	const string& cmd() const { return m_cmd; } + +	bool is_set(const string& name) const { +		return m_opts.at(name).is_set(); +	} +	const string& opt_param(const string& name) const { +		return m_opts.at(name).param(); +	} +	const vector<string>& params() const { return m_params; } +	CmdOption& get_option(const string& name) { return m_opts.at(name); } + +	int num_options() const { +		int ret(0); +		for (const auto& p : m_opts) +			if (p.second.is_set()) +				ret++; +		return ret; +	} + +	const string usage() const { +		string ret("usage:\n"); +		for (const auto& p : m_opts) +			ret += "-" + p.first + +				(p.second.has_param() ? " <>: " : ": ") + +				p.second.help() + "\n"; +		return ret; +	} + +private: +	map<string, CmdOption>& m_opts; +	string m_cmd; +	vector<string> m_params; +	string m_error; +}; diff --git a/tests/optiontester.cpp b/tests/optiontester.cpp new file mode 100644 index 0000000..ccb9579 --- /dev/null +++ b/tests/optiontester.cpp @@ -0,0 +1,29 @@ +#include <cstdio> +#include <algorithm> +#include <iostream> + +#include "cmdoptions.h" + +using namespace std; + +static map<string, CmdOption> options = { +	{ "test", NO_PARAM("test") }, +	{ "test2", HAS_PARAM("test2") }, +}; + +int main(int argc, char **argv) +{ +	CmdOptions opts(argc, argv, options); + +	if (opts.error().length()) { +		cerr << opts.error() << opts.usage(); +		return -1; +	} + +	for (auto p : options) +		printf("Option %s set %d param %s\n",  +		       p.first.c_str(), opts.is_set(p.first), +		       opts.opt_param(p.first).c_str());; + +	return 0; +}  | 
