From f8f92d455c4a915a894111e00dd6f5ec1888bee5 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 20 Oct 2015 16:55:13 +0300 Subject: Add simple command line option parser and a tester for it --- tests/cmdoptions.h | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 tests/cmdoptions.h (limited to 'tests/cmdoptions.h') 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 +#include +#include +#include + +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& 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& 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& m_opts; + string m_cmd; + vector m_params; + string m_error; +}; -- cgit v1.2.3