soma-io 6.0.6
getopt.h
Go to the documentation of this file.
1/* This software and supporting documentation are distributed by
2 * Institut Federatif de Recherche 49
3 * CEA/NeuroSpin, Batiment 145,
4 * 91191 Gif-sur-Yvette cedex
5 * France
6 *
7 * This software is governed by the CeCILL-B license under
8 * French law and abiding by the rules of distribution of free software.
9 * You can use, modify and/or redistribute the software under the
10 * terms of the CeCILL-B license as circulated by CEA, CNRS
11 * and INRIA at the following URL "http://www.cecill.info".
12 *
13 * As a counterpart to the access to the source code and rights to copy,
14 * modify and redistribute granted by the license, users are provided only
15 * with a limited warranty and the software's author, the holder of the
16 * economic rights, and the successive licensors have only limited
17 * liability.
18 *
19 * In this respect, the user's attention is drawn to the risks associated
20 * with loading, using, modifying and/or developing or reproducing the
21 * software by the user in light of its specific status of free software,
22 * that may mean that it is complicated to manipulate, and that also
23 * therefore means that it is reserved for developers and experienced
24 * professionals having in-depth computer knowledge. Users are therefore
25 * encouraged to load and test the software's suitability as regards their
26 * requirements in conditions enabling the security of their systems and/or
27 * data to be ensured and, more generally, to use and operate it in the
28 * same conditions as regards security.
29 *
30 * The fact that you are presently reading this means that you have had
31 * knowledge of the CeCILL-B license and that you accept its terms.
32 */
33
34#ifndef SOMAIO_GETOPT_GETOPT_H
35#define SOMAIO_GETOPT_GETOPT_H
36
37#include <cartobase/type/types.h>
38#include <cartobase/type/string_conversion.h>
39#include <cartobase/exception/format.h>
40#include <string>
41#include <vector>
42#include <stdexcept>
43#include <algorithm>
44#include <iostream>
45
46namespace carto {
47
48
50 // missign_option //
52
53class missing_option : public std::runtime_error
54{
55public:
56
57 missing_option( const std::string &optionName );
58 inline missing_option( const std::string &message, bool ) :
59 std::runtime_error( message ) {}
60};
61
62
64 // unexpected_option //
66
67class unexpected_option : public std::runtime_error
68{
69public:
70
71 unexpected_option( const std::string &optionName );
72 inline unexpected_option( const std::string &message, bool ) :
73 std::runtime_error( message ) {}
74};
75
76
78 // unexpected_option_value //
80
81class unexpected_option_value : public std::runtime_error
82{
83public:
84
85 unexpected_option_value( const std::string &optionName,
86 const std::string &value );
87 inline unexpected_option_value( const std::string &message, bool ) :
88 std::runtime_error( message ) {}
89};
90
91
93 // OptionBase //
95
97{
98 friend class OptionsParser;
99
100protected:
101
102 std::vector<std::string> _names;
103 std::string _info;
104
105
106 virtual bool recognizeName( const std::string & ) = 0;
107 virtual bool feed( const std::string & ) = 0;
108 virtual void check() = 0;
109
110
111 OptionBase( const std::string &name, const std::string &info );
112 virtual inline ~OptionBase();
113
114 inline void addName( const std::string &name );
115 inline const std::string &name() const;
116 std::string names() const;
117 inline bool _nameInList( const std::string &name ) const;
118
119public:
120
121 virtual std::string info() const = 0;
122};
123
124//-----------------------------------------------------------------------------
126
127//-----------------------------------------------------------------------------
128inline void OptionBase::addName( const std::string &name ) {
129 _names.push_back( name );
130 }
131
132//-----------------------------------------------------------------------------
133inline const std::string &OptionBase::name() const
134{
135 return *_names.begin();
136}
137
138//-----------------------------------------------------------------------------
139inline bool OptionBase::_nameInList( const std::string &name ) const
140{
141 return find( _names.begin(), _names.end(), name ) != _names.end();
142}
143
144
146 // OptionSeries<T> //
148
149template <typename T>
150class OptionSeries : public OptionBase
151{
152 friend class OptionsParser;
153
154 OptionSeries( T &serie, const std::string &name, const std::string &info,
155 unsigned numMin, unsigned numMax );
156 virtual inline ~OptionSeries();
157
158 virtual bool recognizeName( const std::string & );
159 virtual bool feed( const std::string & );
160 virtual void check();
161 virtual std::string info() const;
162
163 T &_values;
164 unsigned _numMin, _numMax;
165 typename T::iterator _storeNextValue;
166 unsigned _numValuesStored;
167};
168
169//-----------------------------------------------------------------------------
170template <typename T>
171inline OptionSeries<T>::~OptionSeries() {}
172
173//-----------------------------------------------------------------------------
174template <typename T> inline
175OptionSeries<T>::OptionSeries( T &serie, const std::string &name,
176 const std::string &info,
177 unsigned numMin, unsigned numMax ) :
178 OptionBase( name, info ),
179 _values( serie ),
180 _numMin( numMin ),
181 _numMax( numMax ),
182 _storeNextValue( _values.begin() ),
183 _numValuesStored( 0 )
184{
185}
186
187//-----------------------------------------------------------------------------
188template <typename T> inline
189bool OptionSeries<T>::recognizeName( const std::string &name )
190{
191 if( _nameInList( name ) ) {
192 if ( _numMax && _numValuesStored >= _numMax ) {
193 throw unexpected_option( name );
194 }
195 return true;
196 }
197 return false;
198}
199
200//-----------------------------------------------------------------------------
201template <typename T> inline
202bool OptionSeries<T>::feed( const std::string &value )
203{
204 if ( _numMax == 0 || _numValuesStored < _numMax ) {
205 if ( _storeNextValue == _values.end() ) {
206 _values.push_back( typename T::value_type() );
207 stringTo< typename T::value_type >( value, *(_values.rbegin()) );
208 _storeNextValue = _values.end();
209 } else {
210 stringTo< typename T::value_type >( value, *_storeNextValue );
211 ++_storeNextValue;
212 }
213 ++_numValuesStored;
214 return true;
215 }
216 return false;
217}
218
219//-----------------------------------------------------------------------------
220template <typename T> inline
221void OptionSeries<T>::check()
222{
223 if ( _values.size() < _numMin ) throw missing_option( name() );
224}
225
226//-----------------------------------------------------------------------------
227template <typename T> inline
228std::string OptionSeries<T>::info() const
229{
230 if ( _numMin ) {
231 return names() + " <" + DataTypeCode<T>::name() + ">\n" + _info;
232 } else {
233 return std::string( "[ " ) + names() + " <"
235 + "> ]\n" + _info;
236 }
237}
238
239
240
241
243 // SingleOption<T> //
245
246template <typename T>
248{
249protected:
250
254
255public:
256
257 inline SingleOption( T &value, const std::string &name,
258 const std::string &info, bool optional );
259 virtual inline ~SingleOption();
260
261 virtual bool recognizeName( const std::string & );
262 virtual bool feed( const std::string & );
263 virtual void check();
264 std::string info() const;
265};
266
267//-----------------------------------------------------------------------------
268template <typename T>
270
271//-----------------------------------------------------------------------------
272template <typename T>
273inline SingleOption<T>::SingleOption( T &value, const std::string &name,
274 const std::string &info,
275 bool optional ) :
276 OptionBase( name, info ),
277 _value( value ),
278 _optional( optional ),
279 _valueRead( false )
280{
281}
282
283//-----------------------------------------------------------------------------
284template <typename T>
285bool SingleOption<T>::recognizeName( const std::string &n )
286{
287 if( _nameInList( n ) ) {
288 if ( _valueRead ) {
289 throw unexpected_option( n );
290 }
291 return true;
292 }
293 return false;
294}
295
296//-----------------------------------------------------------------------------
297template <typename T>
298bool SingleOption<T>::feed( const std::string &value )
299{
300 if ( _valueRead ) {
301 return false;
302 } else {
303 stringTo< T >( value, _value );
304 _valueRead = true;
305 return true;
306 }
307}
308
309//-----------------------------------------------------------------------------
310template <typename T> inline
312{
313 if ( ! _optional && ! _valueRead ) {
314 throw missing_option( name() );
315 }
316}
317
318//-----------------------------------------------------------------------------
319template <typename T> inline
320std::string SingleOption<T>::info() const
321{
322 if ( _optional ) {
323 return std::string( "[ " ) + names() + " <"
325 + "> ]\n" + _info;
326 } else {
327 return names() + " <" + DataTypeCode<T>::name() + ">\n" + _info;
328 }
329}
330
331
333 // SingleOption<bool> //
335
336//-----------------------------------------------------------------------------
337template <>
338bool SingleOption<bool>::recognizeName( const std::string &n );
339
340
341//-----------------------------------------------------------------------------
342template <>
343bool SingleOption<bool>::feed( const std::string &value );
344
345
346
348 // BoolOrNumber<T> //
350
351template <class NumberType>
353{
354public:
355
356 inline BoolOrNumber( NumberType &v ) : value( v ) {}
357 NumberType &value;
358};
359
360
361
363 // SingleOption< BoolOrNumber > //
365
366template <class NumberType>
367class SingleOption< BoolOrNumber<NumberType> > :
368 public SingleOption<NumberType>
369{
370
371public:
372
374 const std::string &name,
375 const std::string &info, bool optional );
376 virtual inline ~SingleOption();
377
378 virtual bool recognizeName( const std::string & );
379 virtual bool feed( const std::string & );
380 std::string info() const;
381};
382
383//-----------------------------------------------------------------------------
384template <typename NumberType>
386SingleOption( BoolOrNumber< NumberType > &value,
387 const std::string &name,
388 const std::string &info, bool optional ) :
389 SingleOption<NumberType>( value.value, name, info, optional ) {}
390
391//-----------------------------------------------------------------------------
392template <typename NumberType>
394
395//-----------------------------------------------------------------------------
396template <typename NumberType>
398recognizeName( const std::string &n )
399{
400 if( this->_nameInList( n ) ) {
401 if ( this->_valueRead ) {
402 throw unexpected_option( n );
403 }
404 this->_value = NumberType( 1 );
405 return true;
406 }
407 return false;
408}
409
410
411//-----------------------------------------------------------------------------
412template <typename NumberType>
413bool SingleOption< BoolOrNumber<NumberType> >::feed( const std::string &value )
414{
415 if ( this->_valueRead ) {
416 return false;
417 } else {
418 try {
419 stringTo< NumberType >( value, this->_value );
420 }
421 catch( invalid_number &e ) {
422 return false;
423 }
424 this->_valueRead = true;
425 return true;
426 }
427}
428
429//-----------------------------------------------------------------------------
430template <class NumberType> inline
432{
433 return std::string( "[ " ) + this->names() + " [ <"
435 + "> ] ]\n" + this->_info;
436}
437
438
440 // OptionsParser //
442
471{
472public:
473 typedef std::vector< std::string > CommandLineArguments;
474
475protected:
477
478 typedef std::vector< OptionBase * > OptionList;
480
483
484public:
485
486 OptionsParser( int argc, const char **argv );
488
508 template <typename T>
509 void addOption( T & param, const std::string & token,
510 const std::string & description,
511 bool optional = false );
531 template <typename T>
532 void addOptionSeries( T & param, const std::string & token,
533 const std::string & description, unsigned minnum = 0,
534 unsigned maxnum = 0 );
536 void alias( const std::string &to, const std::string &from );
541 void parse();
545 void check();
546};
547
548//-----------------------------------------------------------------------------
549template <typename T> inline
550void OptionsParser::addOption( T &value, const std::string &name,
551 const std::string &info, bool optional )
552{
553 pushOption( new SingleOption<T>( value, name, info, optional ) );
554}
555
556//-----------------------------------------------------------------------------
557template <typename T> inline
558void OptionsParser::addOptionSeries( T &values, const std::string &name,
559 const std::string &info,
560 unsigned numMin, unsigned numMax )
561{
562 pushOption( new OptionSeries<T>( values, name, info, numMin, numMax ) );
563}
564
565
567 // CartoApplication //
569
582{
583 std::string _documentation;
584 std::string _name;
585
586public:
587
588 CartoApplication( int argc, const char **argv,
589 const std::string &documentation );
596 virtual void initialize();
597};
598
599
601 // user_interruption //
603
608class user_interruption : public std::runtime_error
609{
610public:
611
613 inline user_interruption( const std::string &message ) :
614 std::runtime_error( message ) {}
615};
616
617} // namespace carto
618
619
620#endif // ifndef CARTO_GETOPT_GETOPT_H
621
NumberType & value
Definition getopt.h:357
BoolOrNumber(NumberType &v)
Definition getopt.h:356
CartoApplication(int argc, const char **argv, const std::string &documentation)
virtual void initialize()
Parse and check all parameters, and handle common options (such as the "--help" option).
std::string name()
virtual ~OptionBase()
Definition getopt.h:125
std::string names() const
OptionBase(const std::string &name, const std::string &info)
void addName(const std::string &name)
Definition getopt.h:128
friend class OptionsParser
Definition getopt.h:98
virtual bool recognizeName(const std::string &)=0
std::string _info
Definition getopt.h:103
const std::string & name() const
Definition getopt.h:133
bool _nameInList(const std::string &name) const
Definition getopt.h:139
std::vector< std::string > _names
Definition getopt.h:102
virtual void check()=0
virtual bool feed(const std::string &)=0
virtual std::string info() const =0
friend class OptionsParser
Definition getopt.h:152
std::vector< std::string > CommandLineArguments
Definition getopt.h:473
void alias(const std::string &to, const std::string &from)
Gives an alternative name (token) to to the parameter of token from.
CommandLineArguments cla
Definition getopt.h:476
void check()
Check all needed parameters are filled in, and series numbers are OK.
void pushOption(OptionBase *)
OptionList options
Definition getopt.h:479
void addOption(T &param, const std::string &token, const std::string &description, bool optional=false)
Adds a single parameter to be parsed on the commandline.
Definition getopt.h:550
void addOptionSeries(T &param, const std::string &token, const std::string &description, unsigned minnum=0, unsigned maxnum=0)
Adds a series of parameters to be parsed on the commandline.
Definition getopt.h:558
void parse()
Parses the commandline arguments (argc, argv) and fills in the registered parameters variables.
OptionsParser(int argc, const char **argv)
std::vector< OptionBase * > OptionList
Definition getopt.h:478
virtual bool feed(const std::string &)
Definition getopt.h:413
SingleOption(BoolOrNumber< NumberType > &value, const std::string &name, const std::string &info, bool optional)
Definition getopt.h:386
std::string info() const
Definition getopt.h:320
SingleOption(T &value, const std::string &name, const std::string &info, bool optional)
Definition getopt.h:273
virtual bool recognizeName(const std::string &)
Definition getopt.h:285
virtual ~SingleOption()
Definition getopt.h:269
virtual void check()
Definition getopt.h:311
virtual bool feed(const std::string &)
Definition getopt.h:298
missing_option(const std::string &message, bool)
Definition getopt.h:58
missing_option(const std::string &optionName)
unexpected_option_value(const std::string &optionName, const std::string &value)
unexpected_option_value(const std::string &message, bool)
Definition getopt.h:87
unexpected_option(const std::string &optionName)
unexpected_option(const std::string &message, bool)
Definition getopt.h:72
user_interruption(const std::string &message)
Definition getopt.h:613
void stringTo(const std::string &value, T &result)
STL namespace.