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>
28
30
31
48template <typename T>
50{
51
52public:
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
65private:
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
93template <typename T>
95{
96
97public:
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
110private:
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
134template <typename T>
135struct __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
194template <typename T>
195struct __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
277template <>
278struct __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
310template <>
311struct __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//
345template <typename T>
346TCmdOption<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
355template <typename T>
356bool TCmdOption<T>::do_set_value(const char *svalue)
357{
358 return __dispatch_opt<T>::apply(svalue, m_value);
359}
360
361template <typename T>
363{
364 return __dispatch_opt<T>::size(m_value);
365}
366
367template <typename T>
368void TCmdOption<T>::do_write_value(std::ostream& os) const
369{
370 __dispatch_opt<T>::apply( os, m_value, is_required());
371}
372
373template <typename T>
374void 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
381template <typename T>
382const std::string TCmdOption<T>::do_get_value_as_string() const
383{
384 return __dispatch_opt<T>::get_as_string(m_value);
385}
386
387
388template <typename T>
389TRepeatableCmdOption<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
399template <typename T>
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
408template <typename T>
409bool 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
421template <typename T>
423{
424 return 1;
425}
426
427template <typename T>
428void TRepeatableCmdOption<T>::do_write_value(std::ostream& os) const
429{
430 __dispatch_opt<std::vector<T>>::apply( os, m_value, is_required());
431}
432
433template <typename T>
435{
436 return __dispatch_opt<std::vector<T>>::get_as_string(m_value);
437}
438
439
457template <typename T>
458PCmdOption 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
482template <typename T>
483PCmdOption 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
The base class for all command line options.
Definition: cmdoption.hh:51
const char * long_help() const
This class implements a facade for the xml Element.
Definition: xmlinterface.hh:50
Templated version based on CCmdOptionValue for values that can be converted to and from strings by st...
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)
std::shared_ptr< CCmdOption > PCmdOption
a shared pointer definition of the Option
Definition: cmdoption.hh:181
CCmdOptionFlags
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition: defines.hh:33
#define NS_MIA_END
conveniance define to end the mia namespace
Definition: defines.hh:36
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.
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,.
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:45