halapi
hierarchichalalignmentformatapi
 All Classes Namespaces Functions Pages
halCLParser.h
1 /*
2  * Copyright (C) 2012 by Glenn Hickey (hickey@soe.ucsc.edu)
3  *
4  * Released under the MIT license, see LICENSE.txt
5  */
6 
7 #ifndef _HALCLPARSER_H
8 #define _HALCLPARSER_H
9 
10 #include <string>
11 #include <map>
12 #include <vector>
13 #include <sstream>
14 #include <iostream>
15 #include "halDefs.h"
16 
17 namespace hal {
18 
30 class CLParser
31 {
32 public:
33 
34  CLParser();
35  virtual ~CLParser();
36 
39  virtual void setOptionPrefix(const std::string& prefix);
40 
45  template <typename T>
46  void addOption(const std::string& name,
47  const std::string& descritpion,
48  const T& defaultValue);
49 
52  template <typename T>
53  T getOption(const std::string& name) const;
54 
57  bool hasOption(const std::string& name) const;
58 
65  void addArgument(const std::string& name,
66  const std::string& description);
67 
70  template <typename T>
71  T getArgument(const std::string& name) const;
72 
75  bool hasArgument(const std::string& name) const;
76 
82  void addOptionFlag(const std::string& name,
83  const std::string& description,
84  bool defaultValue);
85 
88  bool getFlag(const std::string& name) const;
89 
92  bool hasFlag(const std::string& name) const;
93 
95  template <typename T>
96  T get(const std::string& name) const;
97 
99  void setDescription(const std::string& description);
100 
102  void setExample(const std::string& example);
103 
106  virtual void parseOptions(int argc, char** argv);
107 
109  virtual void printUsage(std::ostream& os) const;
110 
111 protected:
112 
113  template<typename T> T convertFromString(const std::string& token) const;
114 
115  static size_t lineWidth;
116  static std::string multiLine(const std::string& line, size_t indent);
117 
118  struct Option {
119  std::string _description;
120  std::string _defaultValue;
121  std::string _value;
122  bool _flag;
123  };
124 
125  struct Argument {
126  std::string _name;
127  std::string _description;
128  std::string _value;
129  };
130 
131  std::string _prefix;
132  std::string _exeName;
133  std::string _description;
134  std::string _example;
135  std::vector<Argument> _args;
136  std::map<std::string, Option> _options;
137  size_t _maxArgLen;
138  size_t _maxOptLen;
139 };
140 
141 template <typename T>
142 inline T CLParser::convertFromString(const std::string& token) const
143 {
144  std::stringstream ss(token);
145  T value;
146  try
147  {
148  ss << token;
149  ss >> value;
150  }
151  catch (...)
152  {
153  throw hal_exception(std::string("type conversion error parsing"
154  " token ") + token);
155  }
156  return value;
157 }
158 
159 // above function won't work on strings with spaces so we specialize!
160 template <>
161 inline std::string
162 CLParser::convertFromString<std::string>(const std::string& token) const
163 {
164  return token;
165 }
166 
167 template <typename T>
168 inline void CLParser::addOption(const std::string& name,
169  const std::string& descritpion,
170  const T& defaultValue)
171 {
172  if (hasOption(name) || hasFlag(name) || hasArgument(name))
173  {
174  throw hal_exception(std::string("name ") + name + "already present");
175  }
176  std::stringstream ss;
177  Option opt;
178  try
179  {
180  ss << defaultValue;
181  opt._description = descritpion;
182  opt._defaultValue = ss.str();
183  opt._value = opt._defaultValue;
184  opt._flag = false;
185  }
186  catch (...)
187  {
188  throw hal_exception(std::string("type conversion adding option ") + name);
189  }
190 
191  _options.insert(std::pair<std::string, Option>(name, opt));
192  _maxOptLen = std::max(_maxOptLen, name.length());
193 }
194 
195 template <typename T>
196 inline T CLParser::getOption(const std::string& name) const
197 {
198  std::map<std::string, Option>::const_iterator i = _options.find(name);
199  if (i == _options.end() || i->second._flag == true)
200  {
201  throw hal_exception(std::string("Option ") + name + " not recognized");
202  }
203  return convertFromString<T>(i->second._value);
204 }
205 
206 template <typename T>
207 inline T CLParser::getArgument(const std::string& name) const
208 {
209  for (size_t i = 0; i < _args.size(); ++i)
210  {
211  if (_args[i]._name == name)
212  {
213  return convertFromString<T>(_args[i]._value);
214  }
215  }
216  throw hal_exception(std::string("Argument ") + name + " not recognized");
217  return T();
218 }
219 
220 template <typename T>
221 inline T CLParser::get(const std::string& name) const
222 {
223  if (hasArgument(name))
224  {
225  return getArgument<T>(name);
226  }
227  else if (hasOption(name))
228  {
229  return getOption<T>(name);
230  }
231  else if (hasFlag(name))
232  {
233  return (T)getFlag(name);
234  }
235  else
236  {
237  throw hal_exception(std::string("Name ") + name + " not recognized");
238  }
239 }
240 
241 }
242 
243 #endif
void addArgument(const std::string &name, const std::string &description)
Definition: halCLParser.h:30
void addOptionFlag(const std::string &name, const std::string &description, bool defaultValue)
T get(const std::string &name) const
Definition: halCLParser.h:221
void setExample(const std::string &example)
Definition: halCLParser.h:118
virtual void setOptionPrefix(const std::string &prefix)
virtual void printUsage(std::ostream &os) const
Definition: halCLParser.h:125
void addOption(const std::string &name, const std::string &descritpion, const T &defaultValue)
Definition: halCLParser.h:168
bool hasArgument(const std::string &name) const
bool hasOption(const std::string &name) const
virtual void parseOptions(int argc, char **argv)
T getOption(const std::string &name) const
Definition: halCLParser.h:196
T getArgument(const std::string &name) const
Definition: halCLParser.h:207
bool getFlag(const std::string &name) const
void setDescription(const std::string &description)
bool hasFlag(const std::string &name) const