Claw 1.7.3
arguments.cpp
Go to the documentation of this file.
1/*
2 CLAW - a C++ Library Absolutely Wonderful
3
4 CLAW is a free library without any particular aim but being useful to
5 anyone.
6
7 Copyright (C) 2005-2011 Julien Jorge
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
23 contact: julien.jorge@gamned.org
24*/
30#include <claw/arguments.hpp>
31
32#include <sstream>
33#include <claw/assert.hpp>
35#include <claw/claw_gettext.hpp>
36
37/*----------------------------------------------------------------------------*/
42 : m_program_name( claw_gettext("<unknow>") )
43{
44
45} // arguments::arguments()
46
47/*----------------------------------------------------------------------------*/
52claw::arguments::arguments( const std::string& prog_name )
53 : m_program_name(prog_name)
54{
55
56} // arguments::arguments()
57
58/*----------------------------------------------------------------------------*/
67claw::arguments::arguments( int& argc, char** &argv )
68{
69 parse(argc, argv);
70} // arguments::arguments()
71
72/*----------------------------------------------------------------------------*/
82claw::arguments::arguments(int& argc, char** &argv,
84
85{
86 parse(argc, argv, allowed);
87} // arguments::arguments()
88
89/*----------------------------------------------------------------------------*/
97void claw::arguments::parse( int& argc, char** &argv )
98{
99 parse( argc, argv, true, claw::math::ordered_set<std::string>() );
100} // arguments::parse()
101
102/*----------------------------------------------------------------------------*/
112( int& argc, char** &argv,
114{
115 parse( argc, argv, false, allowed );
116} // arguments::parse()
117
118/*----------------------------------------------------------------------------*/
123bool claw::arguments::has_value( const std::string& arg_name ) const
124{
125 return m_pairs.find( arg_name ) != m_pairs.end();
126} // arguments::has_value()
127
128/*----------------------------------------------------------------------------*/
133bool claw::arguments::only_integer_values( const std::string& arg_name ) const
134{
135 const valued_arguments_map::const_iterator itk(m_pairs.find(arg_name));
136 bool result = true;
137
138 if ( itk == m_pairs.end() )
139 result = false;
140 else
141 {
142 std::list<std::string>::const_iterator it;
143 for( it=itk->second.begin(); result && (it!=itk->second.end()); ++it )
144 result = result && text::is_of_type<int>(*it);
145 }
146
147 return result;
148} // arguments::only_integer_values()
149
150/*----------------------------------------------------------------------------*/
155bool claw::arguments::only_real_values( const std::string& arg_name ) const
156{
157 const valued_arguments_map::const_iterator itk(m_pairs.find(arg_name));
158 bool result = true;
159
160 if ( itk == m_pairs.end() )
161 result = false;
162 else
163 {
164 std::list<std::string>::const_iterator it;
165 for( it=itk->second.begin(); result && (it!=itk->second.end()); ++it )
166 result = result && text::is_of_type<double>(*it);
167 }
168
169 return result;
170} // arguments::only_real_values()
171
172/*----------------------------------------------------------------------------*/
176const std::string& claw::arguments::get_program_name() const
177{
178 return m_program_name;
179} // arguments::get_program_name()
180
181/*----------------------------------------------------------------------------*/
186bool claw::arguments::get_bool( const std::string& arg_name ) const
187{
188 return m_flags.find( arg_name ) != m_flags.end();
189} // arguments::get_bool()
190
191/*----------------------------------------------------------------------------*/
197int claw::arguments::get_integer( const std::string& arg_name ) const
198{
199 CLAW_ASSERT( has_value(arg_name),
200 "arguments::get_integer(): argument is not set." );
201
202 std::istringstream iss( m_pairs.find( arg_name )->second.back() );
203 int val;
204 iss >> val;
205
206 return val;
207} // arguments::get_integer()
208
209/*----------------------------------------------------------------------------*/
215double claw::arguments::get_real( const std::string& arg_name ) const
216{
217 CLAW_ASSERT( has_value(arg_name),
218 "arguments::get_real(): argument is not set." );
219
220 std::istringstream iss( m_pairs.find( arg_name )->second.back() );
221 double val;
222 iss >> val;
223
224 return val;
225} // arguments::get_real()
226
227/*----------------------------------------------------------------------------*/
233const std::string&
234claw::arguments::get_string( const std::string& arg_name ) const
235{
236 CLAW_ASSERT( has_value(arg_name),
237 "arguments::get_string(): argument is not set." );
238
239 return m_pairs.find( arg_name )->second.back();
240} // arguments::get_string()
241
242/*----------------------------------------------------------------------------*/
247std::list<int>
248claw::arguments::get_all_of_integer( const std::string& arg_name ) const
249{
250 std::list<int> result;
251 const valued_arguments_map::const_iterator itk(m_pairs.find(arg_name));
252
253 if ( itk != m_pairs.end() )
254 {
255 std::list<std::string>::const_iterator it;
256
257 for( it=itk->second.begin(); it!=itk->second.end(); ++it )
258 if ( text::is_of_type<int>(*it) )
259 {
260 std::istringstream iss(*it);
261 int val;
262 iss >> val;
263 result.push_back(val);
264 }
265 }
266
267 return result;
268} // arguments::get_all_of_integer()
269
270/*----------------------------------------------------------------------------*/
275std::list<double>
276claw::arguments::get_all_of_real( const std::string& arg_name ) const
277{
278 std::list<double> result;
279 const valued_arguments_map::const_iterator itk(m_pairs.find(arg_name));
280
281 if ( itk != m_pairs.end() )
282 {
283 std::list<std::string>::const_iterator it;
284
285 for( it=itk->second.begin(); it!=itk->second.end(); ++it )
286 if ( text::is_of_type<double>(*it) )
287 {
288 std::istringstream iss(*it);
289 double val;
290 iss >> val;
291 result.push_back(val);
292 }
293 }
294
295 return result;
296} // arguments::get_all_of_real()
297
298/*----------------------------------------------------------------------------*/
303std::list<std::string>
304claw::arguments::get_all_of_string( const std::string& arg_name ) const
305{
306 std::list<std::string> result;
307 const valued_arguments_map::const_iterator itk(m_pairs.find(arg_name));
308
309 if ( itk != m_pairs.end() )
310 result = itk->second;
311
312 return result;
313} // arguments::get_all_of_string()
314
315/*----------------------------------------------------------------------------*/
325void claw::arguments::add_argument( const std::string& arg )
326{
327 CLAW_ASSERT( arg != "--", "arguments::add_argument(): arg can't be '--'" );
328 CLAW_ASSERT( arg[0] == '-',
329 "arguments::add_argument(): arg must begin by '-'" );
330
331 std::string name, value;
332 const bool has_value = split_argument(arg, name, value);
333
334 if ( !has_value )
335 m_flags.insert( arg );
336 else
337 m_pairs[name].push_back(value);
338} // arguments::add_argument()
339
340/*----------------------------------------------------------------------------*/
353( int& argc, char** &argv, bool always_allowed,
355{
356 bool stop = false;
357 int base = 0;
358
359 if (m_program_name.empty() && (argc!=0))
360 {
361 m_program_name = argv[0];
362 argv[0] = NULL;
363 base = 1;
364 }
365
366 for (int argi=base; (argi!=argc) && !stop; ++argi)
367 {
368 std::string arg(argv[argi]);
369
370 if ( !arg.empty() )
371 if ( (arg[0] == '-') && (arg.length() > 1) )
372 {
373 if (arg == "--")
374 stop = true;
375 else
376 {
377 std::string name, value;
378 const bool has_value = split_argument( arg, name, value );
379
380 if ( !has_value )
381 process_boolean( argv[argi], always_allowed, allowed );
382 else if ( always_allowed
383 || (allowed.find( name ) != allowed.end()) )
384 {
385 add_argument( arg );
386 argv[argi] = NULL;
387 }
388 }
389 }
390 }
391
392 remove_null_arguments( argc, argv );
393} // arguments::parse()
394
395/*----------------------------------------------------------------------------*/
404bool claw::arguments::split_argument
405( const std::string& arg, std::string& name, std::string& value ) const
406{
407 CLAW_ASSERT( arg != "--", "arguments::split_argument(): arg can't be '--'" );
408 CLAW_ASSERT( arg[0] == '-',
409 "arguments::split_argument(): arg must begin by '-'" );
410
411 std::string::size_type pos = arg.find_first_of('=');
412 bool result(false);
413
414 if ( pos == std::string::npos )
415 {
416 name = arg;
417 value.clear();
418 }
419 else
420 {
421 name = arg.substr(0, pos);
422 value = arg.substr(pos+1, arg.length() - pos - 1);
423 result = true;
424 }
425
426 return result;
427} // arguments::split_argument()
428
429/*----------------------------------------------------------------------------*/
435void claw::arguments::remove_null_arguments( int& argc, char** &argv ) const
436{
437 unsigned int c=0; // number of non-NULL arguments
438
439 for (int i=0; i!=argc; ++i)
440 if ( argv[i] != NULL )
441 ++c;
442 else
443 {
444 bool ok = false;
445 int j=i;
446
447 while ( (j!=argc) && !ok )
448 if ( argv[j] == NULL )
449 ++j;
450 else
451 ok = true;
452
453 if (ok)
454 {
455 argv[i] = argv[j];
456 argv[j] = NULL;
457 ++c;
458 }
459 }
460
461 if ( c > 0 )
462 if ( (std::string(argv[c-1]) == "--") )
463 --c;
464
465 argc=c;
466} // arguments::remove_null_arguments()
467
468/*----------------------------------------------------------------------------*/
478void claw::arguments::process_boolean
479( char* &arg, bool always_allowed,
481{
482 CLAW_ASSERT( std::string(arg) != "--", "arg can't be '--'" );
483 CLAW_ASSERT( std::string(arg).length() > 1,
484 "arg must be at least two characters long" );
485 CLAW_ASSERT( arg[0] == '-', "arg must begin by '-'" );
486
487 if ( arg[1] == '-' ) // long boolean
488 {
489 if ( always_allowed || (allowed.find(arg) != allowed.end()) )
490 {
491 add_argument(arg);
492 arg = NULL;
493 }
494 }
495 else // short boolean(s)
496 {
497 int i(1);
498 std::string s("-?"); // equivalent single character argument
499
500 while ( arg[i] != '\0' )
501 {
502 s[1] = arg[i];
503
504 if ( always_allowed || (allowed.find(s) != allowed.end()) )
505 {
506 add_argument(s);
507
508 // shift remaining arguments
509 for ( int j=i; arg[j]!='\0'; ++j )
510 arg[j] = arg[j+1];
511 }
512 else
513 ++i;
514 }
515
516 if ( i==1 ) // all arguments have been accepted
517 arg = NULL;
518 }
519} // arguments::process_boolean()
A class to manage the arguments of your program.
Some assert macros to strengthen you code.
#define CLAW_ASSERT(b, s)
Print a message on std::cerr and stop the program if a condition is not true.
Definition assert.hpp:90
void add_argument(const std::string &arg)
Add an argument in our list.
void parse(int &argc, char **&argv)
Parse arguments.
Definition arguments.cpp:97
double get_real(const std::string &arg_name) const
Get the real value of an argument.
bool has_value(const std::string &arg_name) const
Tell if a value is associated to an argument.
const std::string & get_program_name() const
Get the name of the program.
arguments()
Constructor.
Definition arguments.cpp:41
bool only_integer_values(const std::string &arg_name) const
Tell if only integer values are associated to an argument.
std::list< std::string > get_all_of_string(const std::string &arg_name) const
Get all string values of an argument.
bool get_bool(const std::string &arg_name) const
Get the boolean state of an argument.
const std::string & get_string(const std::string &arg_name) const
Get the string value of an argument.
std::list< int > get_all_of_integer(const std::string &arg_name) const
Get all integer values of an argument.
std::list< double > get_all_of_real(const std::string &arg_name) const
Get all real values of an argument.
int get_integer(const std::string &arg_name) const
Get the integer value of an argument.
bool only_real_values(const std::string &arg_name) const
Tell if only real values are associated to an argument.
A class to manage sets of ordered items.
Macros to call gettext on the libclaw textdomain.
#define claw_gettext(s)
Call gettext on the default text domain used by Claw.
Generic algorithms on strings.