arguments.cpp
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 }