cmdparamoption.hh
Go to the documentation of this file.
1 /* -*- mia-c++ -*-
2  *
3  * This file is part of MIA - a toolbox for medical image analysis
4  * Copyright (c) Leipzig, Madrid 1999-2017 Gert Wollny
5  *
6  * MIA is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with MIA; if not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #ifndef mia_core_cmdparamlineparser_hh
22 #define mia_core_cmdparamlineparser_hh
23 
24 #include <mia/core/cmdoption.hh>
25 #include <mia/core/typedescr.hh>
26 #include <mia/core/paramoption.hh>
27 #include <mia/core/handlerbase.hh>
28 
30 
31 
48 template <typename T>
49 class TCmdOption: public CCmdOption{
50 
51 public:
61  TCmdOption(T& val, char short_opt, const char *long_opt, const char *long_help,
62  const char *short_help, CCmdOptionFlags flags = CCmdOptionFlags::none);
63 
64 private:
65  virtual void do_get_long_help_xml(std::ostream& os, CXMLElement& parent, HandlerHelpMap& handler_map) const;
66  virtual bool do_set_value(const char *str_value);
67  virtual size_t do_get_needed_args() const;
68  virtual void do_write_value(std::ostream& os) const;
69  virtual const std::string do_get_value_as_string() const;
70  T& m_value;
71 };
72 
73 
74 
92 template <typename T>
94 
95 public:
105  TRepeatableCmdOption(std::vector<T>& val, char short_opt, const char *long_opt, const char *long_help,
106  const char *short_help, CCmdOptionFlags flags = CCmdOptionFlags::none);
107 
108 private:
109  virtual void do_get_long_help_xml(std::ostream& os, CXMLElement& parent, HandlerHelpMap& handler_map) const;
110  virtual bool do_set_value(const char *str_value);
111  virtual size_t do_get_needed_args() const;
112  virtual void do_write_value(std::ostream& os) const;
113  virtual const std::string do_get_value_as_string() const;
114  std::vector<T>& m_value;
115 };
116 
117 
118 
119 
132 template <typename T>
133 struct __dispatch_opt {
137  static void init(T& /*value*/){
138  }
139 
145  static bool apply(const char *svalue, T& value) {
146  std::istringstream sval(svalue);
147 
148  sval >> value;
149  while (isspace(sval.peek())) {
150  char c;
151  sval >> c;
152  }
153  return sval.eof();
154  }
156  static size_t size(const T /*value*/) {
157  return 1;
158  }
159 
165  static void apply(std::ostream& os, const T& value, bool /*required*/) {
166  os << "=" << value << " ";
167  }
168 
174  static const std::string get_as_string(const T& value) {
175  std::ostringstream os;
176  os << value;
177  return os.str();
178  }
179 };
180 
186 template <typename T>
187 struct __dispatch_opt< std::vector<T> > {
188  static void init(std::vector<T>& /*value*/){
189 
190  }
191  static bool apply(const char *svalue, std::vector<T>& value) {
192  std::string h(svalue);
193  unsigned int n = 1;
194  for(std::string::iterator hb = h.begin(); hb != h.end(); ++hb)
195  if (*hb == ',') {
196  *hb = ' ';
197  ++n;
198  }
199 
200 
201  if (!value.empty()) {
202  if (n > value.size()) {
203  throw create_exception<std::invalid_argument>("Expect only ", value.size(),
204  " coma separated values, but '",
205  svalue, "' provides ", n);
206  }
207  }else{
208  value.resize(n);
209  }
210 
211  std::istringstream sval(h);
212  auto i = value.begin();
213  while (!sval.eof()) {
214  sval >> *i;
215  ++i;
216  }
217  return sval.eof();
218  }
219 
220  static size_t size(const std::vector<T>& /*value*/) {
221  return 1;
222  }
223 
224  static void apply(std::ostream& os, const std::vector<T>& value, bool required) {
225 
226  os << "=";
227  if (value.empty() && required)
228  os << "[required] ";
229  else {
230  for (auto i = value.begin(); i != value.end(); ++i) {
231  if (i != value.begin())
232  os << ",";
233  os << *i;
234  }
235  os << " ";
236  }
237  }
238 
239  static const std::string get_as_string(const std::vector<T>& value) {
240  std::ostringstream os;
241  for (auto i = value.begin(); i != value.end(); ++i) {
242  if (i != value.begin())
243  os << ",";
244  os << *i;
245  }
246  return os.str();
247  }
248 };
249 
258 template <>
259 struct __dispatch_opt<bool> {
260  static void init(bool& value) {
261  value = false;
262  }
263  static bool apply(const char */*svalue*/, bool& value) {
264  value = true;
265  return true;
266  }
267  static size_t size(bool /*value*/) {
268  return 0;
269  }
270  static void apply(std::ostream& /*os*/, bool /*value*/, bool /*required*/) {
271  }
272  static const std::string get_as_string(const bool& value) {
273  return value ? "true" : "false";
274  }
275 };
276 
277 
286 template <>
287 struct __dispatch_opt<std::string> {
288  static void init(std::string& /*value*/) {
289  }
290  static bool apply(const char *svalue, std::string& value) {
291  value = std::string(svalue);
292  return true;
293  }
294  static size_t size(std::string /*value*/) {
295  return 1;
296  }
297  static void apply(std::ostream& os, const std::string& value, bool required) {
298  if (value.empty())
299  if (required)
300  os << "[required] ";
301  else
302  os << "=NULL ";
303  else
304  os << "=" << value;
305  }
306  static const std::string get_as_string(const std::string& value) {
307  return value;
308  }
309 };
311 
312 
313 //
314 // Implementation of the standard option that holds a value
315 //
316 template <typename T>
317 TCmdOption<T>::TCmdOption(T& val, char short_opt, const char *long_opt,
318  const char *long_help, const char *short_help,
319  CCmdOptionFlags flags):
320  CCmdOption(short_opt, long_opt, long_help, short_help, flags),
321  m_value(val)
322 {
323  __dispatch_opt<T>::init(m_value);
324 }
325 
326 template <typename T>
327 bool TCmdOption<T>::do_set_value(const char *svalue)
328 {
329  return __dispatch_opt<T>::apply(svalue, m_value);
330 }
331 
332 template <typename T>
334 {
335  return __dispatch_opt<T>::size(m_value);
336 }
337 
338 template <typename T>
339 void TCmdOption<T>::do_write_value(std::ostream& os) const
340 {
341  __dispatch_opt<T>::apply( os, m_value, is_required());
342 }
343 
344 template <typename T>
345 void TCmdOption<T>::do_get_long_help_xml(std::ostream& os, CXMLElement& parent,
346  HandlerHelpMap& /*handler_map*/) const
347 {
348  do_get_long_help(os);
349  xmlhelp_set_attribute(parent, "type", __type_descr<T>::value);
350 }
351 
352 template <typename T>
353 const std::string TCmdOption<T>::do_get_value_as_string() const
354 {
355  return __dispatch_opt<T>::get_as_string(m_value);
356 }
357 
358 
359 template <typename T>
360 TRepeatableCmdOption<T>::TRepeatableCmdOption(std::vector<T>& val, char short_opt, const char *long_opt,
361  const char *long_help,
362  const char *short_help,
363  CCmdOptionFlags flags):
364  CCmdOption(short_opt, long_opt, long_help, short_help, flags),
365  m_value(val)
366 {
367  __dispatch_opt<std::vector<T>>::init(m_value);
368 }
369 
370 template <typename T>
371 void TRepeatableCmdOption<T>::do_get_long_help_xml(std::ostream& os, CXMLElement& parent,
372  HandlerHelpMap& MIA_PARAM_UNUSED(handler_map)) const
373 {
374  do_get_long_help(os);
375  xmlhelp_set_attribute(parent, "type", __type_descr<T>::value);
376  xmlhelp_set_attribute(parent, "repeatable", "1");
377 }
378 
379 template <typename T>
380 bool TRepeatableCmdOption<T>::do_set_value(const char *str_value)
381 {
382  T value;
383  bool good = __dispatch_opt<T>::apply(str_value, value);
384  if (good) {
385  m_value.push_back(value);
386  }
387  return good;
388 
389 
390 }
391 
392 template <typename T>
394 {
395  return 1;
396 }
397 
398 template <typename T>
399 void TRepeatableCmdOption<T>::do_write_value(std::ostream& os) const
400 {
401  __dispatch_opt<std::vector<T>>::apply( os, m_value, is_required());
402 }
403 
404 template <typename T>
405 const std::string TRepeatableCmdOption<T>::do_get_value_as_string() const
406 {
407  return __dispatch_opt<std::vector<T>>::get_as_string(m_value);
408 }
409 
410 
428 template <typename T>
429 PCmdOption make_opt(std::vector<T>& value, const char *long_opt, char short_opt,
430  const char *help, CCmdOptionFlags flags = CCmdOptionFlags::none)
431 {
432  return PCmdOption(new TCmdOption<std::vector<T> >(value, short_opt, long_opt, help,
433  long_opt, flags ));
434 }
435 
436 
453 template <typename T>
454 PCmdOption make_repeatable_opt(std::vector<T>& value, const char *long_opt, char short_opt,
455  const char *help, CCmdOptionFlags flags = CCmdOptionFlags::none)
456  {
457  return PCmdOption(new TRepeatableCmdOption<T>(value, short_opt, long_opt, help,
458  long_opt, flags ));
459 }
460 
462 
463 #endif
PCmdOption make_opt(std::vector< T > &value, const char *long_opt, char short_opt, const char *help, CCmdOptionFlags flags=CCmdOptionFlags::none)
Create an option to set a vector of values,.
PCmdOption make_repeatable_opt(std::vector< T > &value, const char *long_opt, char short_opt, const char *help, CCmdOptionFlags flags=CCmdOptionFlags::none)
Create a repeatable option to set a vector of values.
Templated version based on CCmdOptionValue for values that can be converted to and from strings by st...
The base class for all command line options.
Definition: cmdoption.hh:50
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition: defines.hh:33
std::map< std::string, const CPluginHandlerBase * > HandlerHelpMap
A map that is used to collect the plug-in handlers used in a program.
Definition: handlerbase.hh:35
TCmdOption(T &val, char short_opt, const char *long_opt, const char *long_help, const char *short_help, CCmdOptionFlags flags=CCmdOptionFlags::none)
Templated version based on CCmdOptionValue for values that can be converted to and from strings by st...
TRepeatableCmdOption(std::vector< T > &val, char short_opt, const char *long_opt, const char *long_help, const char *short_help, CCmdOptionFlags flags=CCmdOptionFlags::none)
const char * long_help() const
CCmdOptionFlags
This class implements a facade for the xml Element.
Definition: xmlinterface.hh:49
void xmlhelp_set_attribute(CXMLElement &node, const char *name, const std::string &value) const
std::shared_ptr< CCmdOption > PCmdOption
a shared pointer definition of the Option
Definition: cmdoption.hh:180
virtual void do_get_long_help(std::ostream &os) const
bool is_required() const
#define NS_MIA_END
conveniance define to end the mia namespace
Definition: defines.hh:36