My Project
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 
52 public:
62  TCmdOption(T& val, char short_opt, const char *long_opt, const char *long_help,
63  const char *short_help, CCmdOptionFlags flags = CCmdOptionFlags::none);
64 
65 private:
66  virtual void do_get_long_help_xml(std::ostream& os, CXMLElement& parent, HandlerHelpMap& handler_map) const;
67  virtual bool do_set_value(const char *str_value);
68  virtual size_t do_get_needed_args() const;
69  virtual void do_write_value(std::ostream& os) const;
70  virtual const std::string do_get_value_as_string() const;
71  T& m_value;
72 };
73 
74 
75 
93 template <typename T>
95 {
96 
97 public:
107  TRepeatableCmdOption(std::vector<T>& val, char short_opt, const char *long_opt, const char *long_help,
108  const char *short_help, CCmdOptionFlags flags = CCmdOptionFlags::none);
109 
110 private:
111  virtual void do_get_long_help_xml(std::ostream& os, CXMLElement& parent, HandlerHelpMap& handler_map) const;
112  virtual bool do_set_value(const char *str_value);
113  virtual size_t do_get_needed_args() const;
114  virtual void do_write_value(std::ostream& os) const;
115  virtual const std::string do_get_value_as_string() const;
116  std::vector<T>& m_value;
117 };
118 
119 
120 
121 
134 template <typename T>
135 struct __dispatch_opt {
139  static void init(T& /*value*/)
140  {
141  }
142 
148  static bool apply(const char *svalue, T& value)
149  {
150  std::istringstream sval(svalue);
151  sval >> value;
152 
153  while (isspace(sval.peek())) {
154  char c;
155  sval >> c;
156  }
157 
158  return sval.eof();
159  }
161  static size_t size(const T /*value*/)
162  {
163  return 1;
164  }
165 
171  static void apply(std::ostream& os, const T& value, bool /*required*/)
172  {
173  os << "=" << value << " ";
174  }
175 
181  static const std::string get_as_string(const T& value)
182  {
183  std::ostringstream os;
184  os << value;
185  return os.str();
186  }
187 };
188 
194 template <typename T>
195 struct __dispatch_opt< std::vector<T>> {
196  static void init(std::vector<T>& /*value*/)
197  {
198  }
199  static bool apply(const char *svalue, std::vector<T>& value)
200  {
201  std::string h(svalue);
202  unsigned int n = 1;
203 
204  for (std::string::iterator hb = h.begin(); hb != h.end(); ++hb)
205  if (*hb == ',') {
206  *hb = ' ';
207  ++n;
208  }
209 
210  if (!value.empty()) {
211  if (n > value.size()) {
212  throw create_exception<std::invalid_argument>("Expect only ", value.size(),
213  " coma separated values, but '",
214  svalue, "' provides ", n);
215  }
216  } else {
217  value.resize(n);
218  }
219 
220  std::istringstream sval(h);
221  auto i = value.begin();
222 
223  while (!sval.eof()) {
224  sval >> *i;
225  ++i;
226  }
227 
228  return sval.eof();
229  }
230 
231  static size_t size(const std::vector<T>& /*value*/)
232  {
233  return 1;
234  }
235 
236  static void apply(std::ostream& os, const std::vector<T>& value, bool required)
237  {
238  os << "=";
239 
240  if (value.empty() && required)
241  os << "[required] ";
242  else {
243  for (auto i = value.begin(); i != value.end(); ++i) {
244  if (i != value.begin())
245  os << ",";
246 
247  os << *i;
248  }
249 
250  os << " ";
251  }
252  }
253 
254  static const std::string get_as_string(const std::vector<T>& value)
255  {
256  std::ostringstream os;
257 
258  for (auto i = value.begin(); i != value.end(); ++i) {
259  if (i != value.begin())
260  os << ",";
261 
262  os << *i;
263  }
264 
265  return os.str();
266  }
267 };
268 
277 template <>
278 struct __dispatch_opt<bool> {
279  static void init(bool& value)
280  {
281  value = false;
282  }
283  static bool apply(const char */*svalue*/, bool& value)
284  {
285  value = true;
286  return true;
287  }
288  static size_t size(bool /*value*/)
289  {
290  return 0;
291  }
292  static void apply(std::ostream& /*os*/, bool /*value*/, bool /*required*/)
293  {
294  }
295  static const std::string get_as_string(const bool& value)
296  {
297  return value ? "true" : "false";
298  }
299 };
300 
301 
310 template <>
311 struct __dispatch_opt<std::string> {
312  static void init(std::string& /*value*/)
313  {
314  }
315  static bool apply(const char *svalue, std::string& value)
316  {
317  value = std::string(svalue);
318  return true;
319  }
320  static size_t size(std::string /*value*/)
321  {
322  return 1;
323  }
324  static void apply(std::ostream& os, const std::string& value, bool required)
325  {
326  if (value.empty())
327  if (required)
328  os << "[required] ";
329  else
330  os << "=NULL ";
331  else
332  os << "=" << value;
333  }
334  static const std::string get_as_string(const std::string& value)
335  {
336  return value;
337  }
338 };
340 
341 
342 //
343 // Implementation of the standard option that holds a value
344 //
345 template <typename T>
346 TCmdOption<T>::TCmdOption(T& val, char short_opt, const char *long_opt,
347  const char *long_help, const char *short_help,
348  CCmdOptionFlags flags):
349  CCmdOption(short_opt, long_opt, long_help, short_help, flags),
350  m_value(val)
351 {
352  __dispatch_opt<T>::init(m_value);
353 }
354 
355 template <typename T>
356 bool TCmdOption<T>::do_set_value(const char *svalue)
357 {
358  return __dispatch_opt<T>::apply(svalue, m_value);
359 }
360 
361 template <typename T>
363 {
364  return __dispatch_opt<T>::size(m_value);
365 }
366 
367 template <typename T>
368 void TCmdOption<T>::do_write_value(std::ostream& os) const
369 {
370  __dispatch_opt<T>::apply( os, m_value, is_required());
371 }
372 
373 template <typename T>
374 void TCmdOption<T>::do_get_long_help_xml(std::ostream& os, CXMLElement& parent,
375  HandlerHelpMap& /*handler_map*/) const
376 {
377  do_get_long_help(os);
378  xmlhelp_set_attribute(parent, "type", __type_descr<T>::value);
379 }
380 
381 template <typename T>
382 const std::string TCmdOption<T>::do_get_value_as_string() const
383 {
384  return __dispatch_opt<T>::get_as_string(m_value);
385 }
386 
387 
388 template <typename T>
389 TRepeatableCmdOption<T>::TRepeatableCmdOption(std::vector<T>& val, char short_opt, const char *long_opt,
390  const char *long_help,
391  const char *short_help,
392  CCmdOptionFlags flags):
393  CCmdOption(short_opt, long_opt, long_help, short_help, flags),
394  m_value(val)
395 {
396  __dispatch_opt<std::vector<T>>::init(m_value);
397 }
398 
399 template <typename T>
400 void TRepeatableCmdOption<T>::do_get_long_help_xml(std::ostream& os, CXMLElement& parent,
401  HandlerHelpMap& MIA_PARAM_UNUSED(handler_map)) const
402 {
403  do_get_long_help(os);
404  xmlhelp_set_attribute(parent, "type", __type_descr<T>::value);
405  xmlhelp_set_attribute(parent, "repeatable", "1");
406 }
407 
408 template <typename T>
409 bool TRepeatableCmdOption<T>::do_set_value(const char *str_value)
410 {
411  T value;
412  bool good = __dispatch_opt<T>::apply(str_value, value);
413 
414  if (good) {
415  m_value.push_back(value);
416  }
417 
418  return good;
419 }
420 
421 template <typename T>
423 {
424  return 1;
425 }
426 
427 template <typename T>
428 void TRepeatableCmdOption<T>::do_write_value(std::ostream& os) const
429 {
430  __dispatch_opt<std::vector<T>>::apply( os, m_value, is_required());
431 }
432 
433 template <typename T>
434 const std::string TRepeatableCmdOption<T>::do_get_value_as_string() const
435 {
436  return __dispatch_opt<std::vector<T>>::get_as_string(m_value);
437 }
438 
439 
457 template <typename T>
458 PCmdOption make_opt(std::vector<T>& value, const char *long_opt, char short_opt,
459  const char *help, CCmdOptionFlags flags = CCmdOptionFlags::none)
460 {
461  return PCmdOption(new TCmdOption<std::vector<T>>(value, short_opt, long_opt, help,
462  long_opt, flags ));
463 }
464 
465 
482 template <typename T>
483 PCmdOption make_repeatable_opt(std::vector<T>& value, const char *long_opt, char short_opt,
484  const char *help, CCmdOptionFlags flags = CCmdOptionFlags::none)
485 {
486  return PCmdOption(new TRepeatableCmdOption<T>(value, short_opt, long_opt, help,
487  long_opt, flags ));
488 }
489 
491 
492 #endif
cmdoption.hh
CCmdOption::long_help
const char * long_help() const
NS_MIA_BEGIN
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition: defines.hh:33
CCmdOptionFlags::required
@ required
typedescr.hh
paramoption.hh
handlerbase.hh
NS_MIA_END
#define NS_MIA_END
conveniance define to end the mia namespace
Definition: defines.hh:36
HandlerHelpMap
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
CXMLElement
This class implements a facade for the xml Element.
Definition: xmlinterface.hh:50
CCmdOptionFlags::none
@ none
make_opt
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,.
Definition: cmdparamoption.hh:458
CCmdOptionFlags
CCmdOptionFlags
Definition: cmdoptionflags.hh:28
std
Definition: gsl_iterator.hh:324
CCmdOption
The base class for all command line options.
Definition: cmdoption.hh:51
TRepeatableCmdOption::TRepeatableCmdOption
TRepeatableCmdOption(std::vector< T > &val, char short_opt, const char *long_opt, const char *long_help, const char *short_help, CCmdOptionFlags flags=CCmdOptionFlags::none)
Definition: cmdparamoption.hh:389
TRepeatableCmdOption
Templated version based on CCmdOptionValue for values that can be converted to and from strings by st...
Definition: cmdparamoption.hh:95
PCmdOption
std::shared_ptr< CCmdOption > PCmdOption
a shared pointer definition of the Option
Definition: cmdoption.hh:181
TCmdOption::TCmdOption
TCmdOption(T &val, char short_opt, const char *long_opt, const char *long_help, const char *short_help, CCmdOptionFlags flags=CCmdOptionFlags::none)
Definition: cmdparamoption.hh:346
TCmdOption
Templated version based on CCmdOptionValue for values that can be converted to and from strings by st...
Definition: cmdparamoption.hh:50
make_repeatable_opt
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.
Definition: cmdparamoption.hh:483