EUDAQ
 All Classes Namespaces Files Functions Variables Pages
OptionParser.hh
1 #ifndef EUDAQ_INCLUDED_OptionParser
2 #define EUDAQ_INCLUDED_OptionParser
3 
4 #include "eudaq/Utils.hh"
5 #include <string>
6 #include <vector>
7 #include <map>
8 #include <stdexcept>
9 #include <iosfwd>
10 #include <iostream>
11 #include "Platform.hh"
12 
13 namespace eudaq {
14 
15  class OptionException : public std::runtime_error {
16  public:
17  OptionException(const std::string &msg) : std::runtime_error(msg) {}
18  };
19 
20  class MessageException : public std::runtime_error {
21  public:
22  MessageException(const std::string &msg) : std::runtime_error(msg) {}
23  };
24 
25  class OptionBase;
26 
27  class DLLEXPORT OptionParser {
28  public:
29  OptionParser(const std::string &name, const std::string &version,
30  const std::string &desc = "", int minargs = -1,
31  int maxargs = -1)
32  : m_name(name), m_ver(version), m_desc(desc), m_minargs(minargs),
33  m_maxargs(maxargs) {}
34  OptionParser &Parse(const char **args);
35  OptionParser &Parse(char **args) {
36  return Parse(const_cast<const char **>(args));
37  }
38  size_t NumArgs() const { return m_args.size(); }
39  std::string GetArg(size_t i) const { return m_args[i]; }
40  void ShowHelp(std::ostream &);
41 
42  void AddOption(OptionBase *opt);
43  void ExtraHelpText(const std::string &);
44  int HandleMainException(std::ostream &err = std::cerr,
45  std::ostream &out = std::cout);
46 
47  private:
48  void LogException(const std::string &msg, std::ostream & = std::cerr) const;
49  std::string m_name, m_ver, m_desc, m_cmd, m_extra;
50  std::vector<OptionBase *> m_options;
51  std::map<std::string, size_t> m_names;
52  std::vector<std::string> m_args;
53  size_t m_minargs, m_maxargs;
54  };
55 
56  class DLLEXPORT OptionBase {
57  public:
58  OptionBase(OptionParser &p, const std::string &shortname,
59  const std::string &longname, const std::string &deflt = "",
60  const std::string &argname = "", const std::string &desc = "")
61  : m_argname(argname), m_deflt(deflt), m_desc(desc),
62  m_hasarg(argname != ""), m_isset(false) {
63  if (shortname != "")
64  m_names.push_back("-" + shortname);
65  if (longname != "")
66  m_names.push_back("--" + longname);
67  p.AddOption(this);
68  }
69  virtual ~OptionBase() {}
70  virtual void Print(std::ostream &) const;
71  bool IsSet() const { return m_isset; }
72  // bool HasArg() const { return m_hasarg; }
73  private:
74  friend class OptionParser;
75  void ParseOption(const std::string &name, const std::string &arg) {
76  DoParsing(name, arg);
77  m_isset = true;
78  }
79  virtual void DoParsing(const std::string &name, const std::string &arg) = 0;
80 
81  std::vector<std::string> m_names;
82  std::string m_argname, m_deflt, m_desc;
83  bool m_hasarg, m_isset;
84  };
85 
86  class OptionFlag : public OptionBase {
87  public:
88  OptionFlag(OptionParser &p, const std::string &shortname,
89  const std::string &longname, const std::string &desc = "")
90  : OptionBase(p, shortname, longname, "", "", desc) {}
91  bool Value() const { return IsSet(); }
92 
93  private:
94  virtual void DoParsing(const std::string & /*name*/,
95  const std::string & /*arg*/) {}
96  };
97 
98  template <typename T> class Option : public OptionBase {
99  public:
100  Option(OptionParser &p, const std::string &shortname,
101  const std::string &longname, const T &deflt = T(),
102  const std::string &argname = "", const std::string &desc = "")
103  : OptionBase(p, shortname, longname, to_string(deflt), argname, desc),
104  m_value(deflt) {}
105  const T &Value() const { return m_value; }
106  void SetValue(const T &val) { m_value = val; }
107 
108  private:
109  virtual void DoParsing(const std::string & /*name*/,
110  const std::string &arg) {
111  m_value = from_string(arg, m_value);
112  }
113  T m_value;
114  };
115 
116  template <typename T> class Option<std::vector<T>> : public OptionBase {
117  public:
118  Option(OptionParser &p, const std::string &shortname,
119  const std::string &longname, const std::string &argname = "",
120  const std::string &sep = "", const std::string &desc = "")
121  : OptionBase(p, shortname, longname, "", argname, desc),
122  m_sep(sep.length() ? sep : ",") {}
123  const std::vector<T> &Value() const { return m_value; }
124  void SetValue(const std::vector<T> &val = std::vector<T>()) {
125  m_value = val;
126  }
127  void Resize(size_t size) { m_value.resize(size); }
128  size_t NumItems() const { return m_value.size(); }
129  const T &Item(size_t i) const { return m_value[i]; }
130 
131  private:
132  virtual void DoParsing(const std::string & /*name*/,
133  const std::string &arg) {
134  size_t i = 0;
135  do {
136  size_t start = i;
137  i = arg.find(m_sep, start);
138  // std::cout << '"' << arg << '"' << ".find(" << m_sep << ", " << start
139  // << ") = " << i << std::endl;
140  std::string valstr(arg, start,
141  (i == std::string::npos ? arg.length() : i) - start);
142  m_value.push_back(from_string(valstr, T()));
143  if (i != std::string::npos) {
144  i += m_sep.length();
145  }
146  } while (i != std::string::npos);
147  }
148  std::string m_sep;
149  std::vector<T> m_value;
150  };
151 
152  std::vector<unsigned> DLLEXPORT parsenumbers(const std::string &s);
153 }
154 
155 #endif // EUDAQ_INCLUDED_OptionParser
Definition: OptionParser.hh:86
Definition: OptionParser.hh:15
T DLLEXPORT from_string(const std::string &x, const T &def=0)
Definition: Utils.hh:115
std::string to_string(const T &x, int digits=0)
Definition: Utils.hh:54
Definition: OptionParser.hh:56
Definition: OptionParser.hh:20
Definition: OptionParser.hh:27
Definition: OptionParser.hh:98