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 #include <claw/claw_gettext.hpp>
00036
00037
00041 claw::arguments::arguments()
00042 : m_program_name( claw_gettext("<unknow>") )
00043 {
00044
00045 }
00046
00047
00052 claw::arguments::arguments( const std::string& prog_name )
00053 : m_program_name(prog_name)
00054 {
00055
00056 }
00057
00058
00067 claw::arguments::arguments( int& argc, char** &argv )
00068 {
00069 parse(argc, argv);
00070 }
00071
00072
00082 claw::arguments::arguments(int& argc, char** &argv,
00083 const claw::math::ordered_set<std::string>& allowed )
00084
00085 {
00086 parse(argc, argv, allowed);
00087 }
00088
00089
00097 void claw::arguments::parse( int& argc, char** &argv )
00098 {
00099 parse( argc, argv, true, claw::math::ordered_set<std::string>() );
00100 }
00101
00102
00111 void claw::arguments::parse
00112 ( int& argc, char** &argv,
00113 const claw::math::ordered_set<std::string>& allowed )
00114 {
00115 parse( argc, argv, false, allowed );
00116 }
00117
00118
00123 bool claw::arguments::has_value( const std::string& arg_name ) const
00124 {
00125 return m_pairs.find( arg_name ) != m_pairs.end();
00126 }
00127
00128
00133 bool claw::arguments::only_integer_values( const std::string& arg_name ) const
00134 {
00135 const valued_arguments_map::const_iterator itk(m_pairs.find(arg_name));
00136 bool result = true;
00137
00138 if ( itk == m_pairs.end() )
00139 result = false;
00140 else
00141 {
00142 std::list<std::string>::const_iterator it;
00143 for( it=itk->second.begin(); result && (it!=itk->second.end()); ++it )
00144 result = result && text::is_of_type<int>(*it);
00145 }
00146
00147 return result;
00148 }
00149
00150
00155 bool claw::arguments::only_real_values( const std::string& arg_name ) const
00156 {
00157 const valued_arguments_map::const_iterator itk(m_pairs.find(arg_name));
00158 bool result = true;
00159
00160 if ( itk == m_pairs.end() )
00161 result = false;
00162 else
00163 {
00164 std::list<std::string>::const_iterator it;
00165 for( it=itk->second.begin(); result && (it!=itk->second.end()); ++it )
00166 result = result && text::is_of_type<double>(*it);
00167 }
00168
00169 return result;
00170 }
00171
00172
00176 const std::string& claw::arguments::get_program_name() const
00177 {
00178 return m_program_name;
00179 }
00180
00181
00186 bool claw::arguments::get_bool( const std::string& arg_name ) const
00187 {
00188 return m_flags.find( arg_name ) != m_flags.end();
00189 }
00190
00191
00197 int claw::arguments::get_integer( const std::string& arg_name ) const
00198 {
00199 CLAW_ASSERT( has_value(arg_name),
00200 "arguments::get_integer(): argument is not set." );
00201
00202 std::istringstream iss( m_pairs.find( arg_name )->second.back() );
00203 int val;
00204 iss >> val;
00205
00206 return val;
00207 }
00208
00209
00215 double claw::arguments::get_real( const std::string& arg_name ) const
00216 {
00217 CLAW_ASSERT( has_value(arg_name),
00218 "arguments::get_real(): argument is not set." );
00219
00220 std::istringstream iss( m_pairs.find( arg_name )->second.back() );
00221 double val;
00222 iss >> val;
00223
00224 return val;
00225 }
00226
00227
00233 const std::string&
00234 claw::arguments::get_string( const std::string& arg_name ) const
00235 {
00236 CLAW_ASSERT( has_value(arg_name),
00237 "arguments::get_string(): argument is not set." );
00238
00239 return m_pairs.find( arg_name )->second.back();
00240 }
00241
00242
00247 std::list<int>
00248 claw::arguments::get_all_of_integer( const std::string& arg_name ) const
00249 {
00250 std::list<int> result;
00251 const valued_arguments_map::const_iterator itk(m_pairs.find(arg_name));
00252
00253 if ( itk != m_pairs.end() )
00254 {
00255 std::list<std::string>::const_iterator it;
00256
00257 for( it=itk->second.begin(); it!=itk->second.end(); ++it )
00258 if ( text::is_of_type<int>(*it) )
00259 {
00260 std::istringstream iss(*it);
00261 int val;
00262 iss >> val;
00263 result.push_back(val);
00264 }
00265 }
00266
00267 return result;
00268 }
00269
00270
00275 std::list<double>
00276 claw::arguments::get_all_of_real( const std::string& arg_name ) const
00277 {
00278 std::list<double> result;
00279 const valued_arguments_map::const_iterator itk(m_pairs.find(arg_name));
00280
00281 if ( itk != m_pairs.end() )
00282 {
00283 std::list<std::string>::const_iterator it;
00284
00285 for( it=itk->second.begin(); it!=itk->second.end(); ++it )
00286 if ( text::is_of_type<double>(*it) )
00287 {
00288 std::istringstream iss(*it);
00289 double val;
00290 iss >> val;
00291 result.push_back(val);
00292 }
00293 }
00294
00295 return result;
00296 }
00297
00298
00303 std::list<std::string>
00304 claw::arguments::get_all_of_string( const std::string& arg_name ) const
00305 {
00306 std::list<std::string> result;
00307 const valued_arguments_map::const_iterator itk(m_pairs.find(arg_name));
00308
00309 if ( itk != m_pairs.end() )
00310 result = itk->second;
00311
00312 return result;
00313 }
00314
00315
00325 void claw::arguments::add_argument( const std::string& arg )
00326 {
00327 CLAW_ASSERT( arg != "--", "arguments::add_argument(): arg can't be '--'" );
00328 CLAW_ASSERT( arg[0] == '-',
00329 "arguments::add_argument(): arg must begin by '-'" );
00330
00331 std::string name, value;
00332 split_argument(arg, name, value);
00333
00334 if ( value.empty() )
00335 m_flags.insert( arg );
00336 else
00337 m_pairs[name].push_back(value);
00338 }
00339
00340
00351 void claw::arguments::parse
00352 ( int& argc, char** &argv, bool always_allowed,
00353 const claw::math::ordered_set<std::string>& allowed )
00354 {
00355 bool stop = false;
00356 int base = 0;
00357
00358 if (m_program_name.empty() && (argc!=0))
00359 {
00360 m_program_name = argv[0];
00361 argv[0] = NULL;
00362 base = 1;
00363 }
00364
00365 for (int argi=base; (argi!=argc) && !stop; ++argi)
00366 {
00367 std::string arg(argv[argi]);
00368
00369 if ( !arg.empty() )
00370 if ( (arg[0] == '-') && (arg.length() > 1) )
00371 {
00372 if (arg == "--")
00373 stop = true;
00374 else
00375 {
00376 std::string name, value;
00377 split_argument( arg, name, value );
00378
00379 if ( value.empty() )
00380 process_boolean( argv[argi], always_allowed, allowed );
00381 else if ( always_allowed
00382 || (allowed.find( name ) != allowed.end()) )
00383 {
00384 add_argument( arg );
00385 argv[argi] = NULL;
00386 }
00387 }
00388 }
00389 }
00390
00391 remove_null_arguments( argc, argv );
00392 }
00393
00394
00402 void claw::arguments::split_argument( const std::string& arg, std::string& name,
00403 std::string& value ) const
00404 {
00405 CLAW_ASSERT( arg != "--", "arguments::split_argument(): arg can't be '--'" );
00406 CLAW_ASSERT( arg[0] == '-',
00407 "arguments::split_argument(): arg must begin by '-'" );
00408
00409 std::string::size_type pos = arg.find_first_of('=');
00410
00411 if ( pos == std::string::npos )
00412 {
00413 name = arg;
00414 value.clear();
00415 }
00416 else
00417 {
00418 name = arg.substr(0, pos);
00419 value = arg.substr(pos+1, arg.length() - pos - 1);
00420 }
00421 }
00422
00423
00429 void claw::arguments::remove_null_arguments( int& argc, char** &argv ) const
00430 {
00431 unsigned int c=0;
00432
00433 for (int i=0; i!=argc; ++i)
00434 if ( argv[i] != NULL )
00435 ++c;
00436 else
00437 {
00438 bool ok = false;
00439 int j=i;
00440
00441 while ( (j!=argc) && !ok )
00442 if ( argv[j] == NULL )
00443 ++j;
00444 else
00445 ok = true;
00446
00447 if (ok)
00448 {
00449 argv[i] = argv[j];
00450 argv[j] = NULL;
00451 ++c;
00452 }
00453 }
00454
00455 if ( c > 0 )
00456 if ( (std::string(argv[c-1]) == "--") )
00457 --c;
00458
00459 argc=c;
00460 }
00461
00462
00472 void claw::arguments::process_boolean
00473 ( char* &arg, bool always_allowed,
00474 const claw::math::ordered_set<std::string>& allowed )
00475 {
00476 CLAW_ASSERT( std::string(arg) != "--", "arg can't be '--'" );
00477 CLAW_ASSERT( std::string(arg).length() > 1,
00478 "arg must be at least two characters long" );
00479 CLAW_ASSERT( arg[0] == '-', "arg must begin by '-'" );
00480
00481 if ( arg[1] == '-' )
00482 {
00483 if ( always_allowed || (allowed.find(arg) != allowed.end()) )
00484 {
00485 add_argument(arg);
00486 arg = NULL;
00487 }
00488 }
00489 else
00490 {
00491 int i(1);
00492 std::string s("-?");
00493
00494 while ( arg[i] != '\0' )
00495 {
00496 s[1] = arg[i];
00497
00498 if ( always_allowed || (allowed.find(s) != allowed.end()) )
00499 {
00500 add_argument(s);
00501
00502
00503 for ( int j=i; arg[j]!='\0'; ++j )
00504 arg[j] = arg[j+1];
00505 }
00506 else
00507 ++i;
00508 }
00509
00510 if ( i==1 )
00511 arg = NULL;
00512 }
00513 }