Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00030 #include <claw/arguments.hpp>
00031
00032 #include <sstream>
00033 #include <claw/assert.hpp>
00034 #include <claw/string_algorithm.hpp>
00035
00036
00040 claw::arguments::arguments()
00041 : m_program_name("<unknow>")
00042 {
00043
00044 }
00045
00046
00051 claw::arguments::arguments( const std::string& prog_name )
00052 : m_program_name(prog_name)
00053 {
00054
00055 }
00056
00057
00066 claw::arguments::arguments( int& argc, char** &argv )
00067 {
00068 parse(argc, argv);
00069 }
00070
00071
00081 claw::arguments::arguments(int& argc, char** &argv,
00082 const claw::math::ordered_set<std::string>& allowed )
00083
00084 {
00085 parse(argc, argv, allowed);
00086 }
00087
00088
00096 void claw::arguments::parse( int& argc, char** &argv )
00097 {
00098 parse( argc, argv, true, claw::math::ordered_set<std::string>() );
00099 }
00100
00101
00110 void claw::arguments::parse
00111 ( int& argc, char** &argv,
00112 const claw::math::ordered_set<std::string>& allowed )
00113 {
00114 parse( argc, argv, false, allowed );
00115 }
00116
00117
00122 bool claw::arguments::has_value( const std::string& arg_name ) const
00123 {
00124 return m_pairs.find( arg_name ) != m_pairs.end();
00125 }
00126
00127
00132 bool claw::arguments::only_integer_values( const std::string& arg_name ) const
00133 {
00134 const valued_arguments_map::const_iterator itk(m_pairs.find(arg_name));
00135 bool result;
00136
00137 if ( itk == m_pairs.end() )
00138 result = false;
00139 else
00140 {
00141 std::list<std::string>::const_iterator it;
00142 result = true;
00143
00144 for( it=itk->second.begin(); result && (it!=itk->second.end()); ++it )
00145 result = result && text::is_of_type<int>(*it);
00146 }
00147
00148 return result;
00149 }
00150
00151
00156 bool claw::arguments::only_real_values( const std::string& arg_name ) const
00157 {
00158 const valued_arguments_map::const_iterator itk(m_pairs.find(arg_name));
00159 bool result;
00160
00161 if ( itk == m_pairs.end() )
00162 result = false;
00163 else
00164 {
00165 std::list<std::string>::const_iterator it;
00166 result = true;
00167
00168 for( it=itk->second.begin(); result && (it!=itk->second.end()); ++it )
00169 result = result && text::is_of_type<double>(*it);
00170 }
00171
00172 return result;
00173 }
00174
00175
00179 const std::string& claw::arguments::get_program_name() const
00180 {
00181 return m_program_name;
00182 }
00183
00184
00189 bool claw::arguments::get_bool( const std::string& arg_name ) const
00190 {
00191 return m_flags.find( arg_name ) != m_flags.end();
00192 }
00193
00194
00200 int claw::arguments::get_integer( const std::string& arg_name ) const
00201 {
00202 CLAW_ASSERT( has_value(arg_name),
00203 "arguments::get_integer(): argument is not set." );
00204
00205 std::istringstream iss( m_pairs.find( arg_name )->second.back() );
00206 int val;
00207 iss >> val;
00208
00209 return val;
00210 }
00211
00212
00218 double claw::arguments::get_real( const std::string& arg_name ) const
00219 {
00220 CLAW_ASSERT( has_value(arg_name),
00221 "arguments::get_real(): argument is not set." );
00222
00223 std::istringstream iss( m_pairs.find( arg_name )->second.back() );
00224 double val;
00225 iss >> val;
00226
00227 return val;
00228 }
00229
00230
00236 const std::string&
00237 claw::arguments::get_string( const std::string& arg_name ) const
00238 {
00239 CLAW_ASSERT( has_value(arg_name),
00240 "arguments::get_string(): argument is not set." );
00241
00242 return m_pairs.find( arg_name )->second.back();
00243 }
00244
00245
00250 std::list<int>
00251 claw::arguments::get_all_of_integer( const std::string& arg_name ) const
00252 {
00253 std::list<int> result;
00254 const valued_arguments_map::const_iterator itk(m_pairs.find(arg_name));
00255
00256 if ( itk != m_pairs.end() )
00257 {
00258 std::list<std::string>::const_iterator it;
00259
00260 for( it=itk->second.begin(); it!=itk->second.end(); ++it )
00261 if ( text::is_of_type<int>(*it) )
00262 {
00263 std::istringstream iss(*it);
00264 int val;
00265 iss >> val;
00266 result.push_back(val);
00267 }
00268 }
00269
00270 return result;
00271 }
00272
00273
00278 std::list<double>
00279 claw::arguments::get_all_of_real( const std::string& arg_name ) const
00280 {
00281 std::list<double> result;
00282 const valued_arguments_map::const_iterator itk(m_pairs.find(arg_name));
00283
00284 if ( itk != m_pairs.end() )
00285 {
00286 std::list<std::string>::const_iterator it;
00287
00288 for( it=itk->second.begin(); it!=itk->second.end(); ++it )
00289 if ( text::is_of_type<double>(*it) )
00290 {
00291 std::istringstream iss(*it);
00292 double val;
00293 iss >> val;
00294 result.push_back(val);
00295 }
00296 }
00297
00298 return result;
00299 }
00300
00301
00306 std::list<std::string>
00307 claw::arguments::get_all_of_string( const std::string& arg_name ) const
00308 {
00309 std::list<std::string> result;
00310 const valued_arguments_map::const_iterator itk(m_pairs.find(arg_name));
00311
00312 if ( itk != m_pairs.end() )
00313 result = itk->second;
00314
00315 return result;
00316 }
00317
00318
00328 void claw::arguments::add_argument( const std::string& arg )
00329 {
00330 CLAW_ASSERT( arg != "--", "arguments::add_argument(): arg can't be '--'" );
00331 CLAW_ASSERT( arg[0] == '-',
00332 "arguments::add_argument(): arg must begin by '-'" );
00333
00334 std::string name, value;
00335 split_argument(arg, name, value);
00336
00337 if ( value.empty() )
00338 m_flags.insert( arg );
00339 else
00340 m_pairs[name].push_back(value);
00341 }
00342
00343
00354 void claw::arguments::parse
00355 ( int& argc, char** &argv, bool always_allowed,
00356 const claw::math::ordered_set<std::string>& allowed )
00357 {
00358 bool stop = false;
00359 int base = 0;
00360
00361 if (m_program_name.empty() && (argc!=0))
00362 {
00363 m_program_name = argv[0];
00364 argv[0] = NULL;
00365 base = 1;
00366 }
00367
00368 for (int argi=base; (argi!=argc) && !stop; ++argi)
00369 {
00370 std::string arg(argv[argi]);
00371
00372 if ( !arg.empty() )
00373 if ( (arg[0] == '-') && (arg.length() > 1) )
00374 {
00375 if (arg == "--")
00376 stop = true;
00377 else
00378 {
00379 std::string name, value;
00380 split_argument( arg, name, value );
00381
00382 if ( value.empty() )
00383 process_boolean( argv[argi], always_allowed, allowed );
00384 else if ( always_allowed
00385 || (allowed.find( name ) != allowed.end()) )
00386 {
00387 add_argument( arg );
00388 argv[argi] = NULL;
00389 }
00390 }
00391 }
00392 }
00393
00394 remove_null_arguments( argc, argv );
00395 }
00396
00397
00405 void claw::arguments::split_argument( const std::string& arg, std::string& name,
00406 std::string& value ) const
00407 {
00408 CLAW_ASSERT( arg != "--", "arguments::split_argument(): arg can't be '--'" );
00409 CLAW_ASSERT( arg[0] == '-',
00410 "arguments::split_argument(): arg must begin by '-'" );
00411
00412 std::string::size_type pos = arg.find_first_of('=');
00413
00414 if ( pos == std::string::npos )
00415 {
00416 name = arg;
00417 value.clear();
00418 }
00419 else
00420 {
00421 name = arg.substr(0, pos);
00422 value = arg.substr(pos+1, arg.length() - pos - 1);
00423 }
00424 }
00425
00426
00432 void claw::arguments::remove_null_arguments( int& argc, char** &argv ) const
00433 {
00434 unsigned int c=0;
00435
00436 for (int i=0; i!=argc; ++i)
00437 if ( argv[i] != NULL )
00438 ++c;
00439 else
00440 {
00441 bool ok = false;
00442 int j=i;
00443
00444 while ( (j!=argc) && !ok )
00445 if ( argv[j] == NULL )
00446 ++j;
00447 else
00448 ok = true;
00449
00450 if (ok)
00451 {
00452 argv[i] = argv[j];
00453 argv[j] = NULL;
00454 ++c;
00455 }
00456 }
00457
00458 if ( c > 0 )
00459 if ( (std::string(argv[c-1]) == "--") )
00460 --c;
00461
00462 argc=c;
00463 }
00464
00465
00475 void claw::arguments::process_boolean
00476 ( char* &arg, bool always_allowed,
00477 const claw::math::ordered_set<std::string>& allowed )
00478 {
00479 CLAW_ASSERT( std::string(arg) != "--", "arg can't be '--'" );
00480 CLAW_ASSERT( std::string(arg).length() > 1,
00481 "arg must be at least two characters long" );
00482 CLAW_ASSERT( arg[0] == '-', "arg must begin by '-'" );
00483
00484 if ( arg[1] == '-' )
00485 {
00486 if ( always_allowed || (allowed.find(arg) != allowed.end()) )
00487 {
00488 add_argument(arg);
00489 arg = NULL;
00490 }
00491 }
00492 else
00493 {
00494 int i(1);
00495 std::string s("-?");
00496
00497 while ( arg[i] != '\0' )
00498 {
00499 s[1] = arg[i];
00500
00501 if ( always_allowed || (allowed.find(s) != allowed.end()) )
00502 {
00503 add_argument(s);
00504
00505
00506 for ( int j=i; arg[j]!='\0'; ++j )
00507 arg[j] = arg[j+1];
00508 }
00509 else
00510 ++i;
00511 }
00512
00513 if ( i==1 )
00514 arg = NULL;
00515 }
00516 }