1 #pragma once
3 #include <cstdio>
4 #include <string>
5 #include <vector>
6 #include <map>
8 using namespace std;
10 #define NO_PARAM(h) (CmdOption(false, h))
11 #define HAS_PARAM(h) (CmdOption(true, h))
13 class CmdOption
14 {
15 public:
16 CmdOption(bool has_param, string help) :
17 m_has_param(has_param), m_help(help), m_is_set(false) { }
18 bool has_param() const { return m_has_param; }
19 const string& help() const { return m_help; }
21 void oset() { m_is_set = true; }
22 void pset(const string& p) { m_param = p; oset(); }
23 bool is_set() const { return m_is_set; }
24 const string& param() const { return m_param; }
25 private:
26 bool m_has_param;
27 string m_help;
29 bool m_is_set;
30 string m_param;
31 };
33 class CmdOptions
34 {
35 public:
36 CmdOptions(int argc, char **argv, map<string, CmdOption>& opts) :
37 m_opts(opts), m_cmd(argv[0]) {
38 for (int i = 1; i < argc; i++) {
39 if (argv[i][0] == '-') {
40 auto ii = m_opts.find(&argv[i][1]);
41 if (ii == m_opts.end()) {
42 m_error += m_cmd + ": " +
43 string(argv[i]) +
44 ": unknown option\n";
45 continue;
46 }
47 if ((*ii).second.has_param()) {
48 if (++i == argc) {
49 m_error += m_cmd + ": -" +
50 (*ii).first +
51 ": parameter missing\n";
52 continue;
53 }
54 (*ii).second.pset(argv[i]);
55 } else {
56 (*ii).second.oset();
57 }
58 } else {
59 m_params.push_back(argv[i]);
60 }
61 }
62 }
63 const string& error() const { return m_error; }
64 const string& cmd() const { return m_cmd; }
66 bool is_set(const string& name) const {
67 return m_opts.at(name).is_set();
68 }
69 const string& opt_param(const string& name) const {
70 return m_opts.at(name).param();
71 }
72 const vector<string>& params() const { return m_params; }
73 CmdOption& get_option(const string& name) { return m_opts.at(name); }
75 int num_options() const {
76 int ret(0);
77 for (const auto& p : m_opts)
78 if (p.second.is_set())
79 ret++;
80 return ret;
81 }
83 const string usage() const {
84 string ret("usage:\n");
85 for (const auto& p : m_opts)
86 ret += "-" + p.first +
87 (p.second.has_param() ? " <>: " : ": ") +
88 p.second.help() + "\n";
89 return ret;
90 }
92 private:
93 map<string, CmdOption>& m_opts;
94 string m_cmd;
95 vector<string> m_params;
96 string m_error;
97 };