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-2016 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  parent.set_attribute("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  parent.set_attribute("type", __type_descr<T>::value);
376  parent.set_attribute("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,.
bool is_required() const
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.
void set_attribute(const char *name, const std::string &value)
Set an attribute of the node.
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:36
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)
CCmdOptionFlags
This class implements a facade for the xml Element.
Definition: xmlinterface.hh:42
std::shared_ptr< CCmdOption > PCmdOption
a shared pointer definition of the Option
Definition: cmdoption.hh:178
virtual void do_get_long_help(std::ostream &os) const
const char * long_help() const
#define NS_MIA_END
conveniance define to end the mia namespace
Definition: defines.hh:36