diff options
author | Jyri Sarha <jsarha@ti.com> | 2015-10-20 16:55:13 +0300 |
---|---|---|
committer | Jyri Sarha <jsarha@ti.com> | 2015-10-20 22:41:21 +0300 |
commit | f8f92d455c4a915a894111e00dd6f5ec1888bee5 (patch) | |
tree | ac85b9e440e93030e19525fd63cdf7100bc444fb | |
parent | 905eacc3b638e70f25958b7c25f09077b143e387 (diff) |
Add simple command line option parser and a tester for it
-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; +} |