MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 #include "TestUtil.hpp" 00002 #include "TestRunner.hpp" 00003 #include "moab/ProgOptions.hpp" 00004 #include <limits> 00005 #include <cstdlib> 00006 #include <iterator> 00007 #ifdef MOAB_HAVE_MPI 00008 #include "moab_mpi.h" 00009 #endif 00010 00011 void test_flag_opt_short(); 00012 void test_flag_opt_long_short(); 00013 void test_flag_opt_long(); 00014 void test_flag_cancel(); 00015 void test_flag_store_false(); 00016 00017 void test_int_opt(); 00018 void test_int_arg(); 00019 00020 void test_real_opt(); 00021 void test_real_arg(); 00022 00023 void test_string_opt(); 00024 void test_string_arg(); 00025 void test_string_rank_subst(); 00026 00027 void test_int_vect_opt(); 00028 void test_int_vect_arg(); 00029 void test_optional_args(); 00030 void test_optional_arg(); 00031 void test_squashed_short(); 00032 00033 #define ARGCV( A ) ( sizeof( A ) / sizeof( ( A )[0] ) ), const_cast< char** >( A ) 00034 00035 int main( int argc, char* argv[] ) 00036 { 00037 // make ProgOptions abort() rather than exiting with an 00038 // error code for invalid options so that we can catch 00039 // the signal and continue with later tests 00040 #ifndef WIN32 00041 setenv( "MOAB_PROG_OPT_ABORT", "1", 0 ); 00042 #endif 00043 00044 REGISTER_TEST( test_flag_opt_short ); 00045 REGISTER_TEST( test_flag_opt_long_short ); 00046 REGISTER_TEST( test_flag_opt_long ); 00047 REGISTER_TEST( test_flag_cancel ); 00048 REGISTER_TEST( test_flag_store_false ); 00049 00050 REGISTER_TEST( test_int_opt ); 00051 REGISTER_TEST( test_int_arg ); 00052 REGISTER_TEST( test_real_opt ); 00053 REGISTER_TEST( test_real_arg ); 00054 00055 REGISTER_TEST( test_string_opt ); 00056 REGISTER_TEST( test_string_arg ); 00057 REGISTER_TEST( test_string_rank_subst ); 00058 00059 REGISTER_TEST( test_int_vect_opt ); 00060 REGISTER_TEST( test_int_vect_arg ); 00061 REGISTER_TEST( test_optional_args ); 00062 REGISTER_TEST( test_optional_arg ); 00063 REGISTER_TEST( test_squashed_short ); 00064 00065 #ifdef MOAB_HAVE_MPI 00066 MPI_Init( &argc, &argv ); 00067 #endif 00068 int result = RUN_TESTS( argc, argv ); 00069 #ifdef MOAB_HAVE_MPI 00070 MPI_Finalize(); 00071 #endif 00072 return result; 00073 } 00074 00075 void test_flag_opt_short() 00076 { 00077 ProgOptions opts1; 00078 bool value1 = false; 00079 opts1.addOpt< void >( ",s", "short opt", &value1 ); 00080 const char* argv1[] = { "prog", "-s" }; 00081 opts1.parseCommandLine( ARGCV( argv1 ) ); 00082 CHECK( value1 ); 00083 CHECK_EQUAL( 1, opts1.numOptSet( ",s" ) ); 00084 } 00085 00086 void test_flag_opt_long_short() 00087 { 00088 ProgOptions opts2; 00089 bool value = false; 00090 opts2.addOpt< void >( "long,l", "long opt", &value ); 00091 const char* argv2[] = { "prog", "-l", "-l" }; 00092 opts2.parseCommandLine( ARGCV( argv2 ) ); 00093 CHECK( value ); 00094 CHECK_EQUAL( 2, opts2.numOptSet( ",l" ) ); 00095 CHECK_EQUAL( 2, opts2.numOptSet( "long,l" ) ); 00096 CHECK_EQUAL( 2, opts2.numOptSet( "long" ) ); 00097 } 00098 00099 void test_flag_opt_long() 00100 { 00101 ProgOptions opts3; 00102 bool value = false; 00103 opts3.addOpt< void >( "long,l", "long opt", &value ); 00104 const char* argv3[] = { "prog", "--long", "--long" }; 00105 opts3.parseCommandLine( ARGCV( argv3 ) ); 00106 CHECK( value ); 00107 CHECK_EQUAL( 2, opts3.numOptSet( ",l" ) ); 00108 CHECK_EQUAL( 2, opts3.numOptSet( "long,l" ) ); 00109 CHECK_EQUAL( 2, opts3.numOptSet( "long" ) ); 00110 } 00111 00112 void test_flag_cancel() 00113 { 00114 ProgOptions opts1; 00115 bool value = false; 00116 opts1.addOpt< void >( "flag", "my flag", &value, ProgOptions::add_cancel_opt ); 00117 const char* argv1[] = { "test", "--flag" }; 00118 opts1.parseCommandLine( ARGCV( argv1 ) ); 00119 CHECK( value ); 00120 00121 ProgOptions opts2; 00122 value = true; 00123 opts2.addOpt< void >( "flag", "my flag", &value, ProgOptions::add_cancel_opt ); 00124 const char* argv2[] = { "test", "--flag", "--no-flag" }; 00125 opts2.parseCommandLine( ARGCV( argv2 ) ); 00126 CHECK( !value ); 00127 00128 ProgOptions opts3; 00129 value = false; 00130 opts3.addOpt< void >( "flag", "my flag", &value, ProgOptions::add_cancel_opt ); 00131 const char* argv3[] = { "test", "--flag", "--no-flag", "--flag" }; 00132 opts3.parseCommandLine( ARGCV( argv3 ) ); 00133 CHECK( value ); 00134 } 00135 00136 void test_flag_store_false() 00137 { 00138 ProgOptions opts1; 00139 bool value1 = true; 00140 opts1.addOpt< void >( ",s", "short opt", &value1, ProgOptions::store_false ); 00141 const char* argv1[] = { "prog", "-s" }; 00142 opts1.parseCommandLine( ARGCV( argv1 ) ); 00143 CHECK( !value1 ); 00144 } 00145 00146 void test_int_opt() 00147 { 00148 ProgOptions opts; 00149 int val1 = -1; 00150 opts.addOpt( "long,s", "my int opt", &val1 ); 00151 const char* argv[] = { "test", "-s", "2", "--long", "-0xA", "--long=5" }; 00152 opts.parseCommandLine( ARGCV( argv ) ); 00153 CHECK_EQUAL( 5, val1 ); 00154 int val2 = -1; 00155 CHECK( opts.getOpt( ",s", &val2 ) ); 00156 CHECK_EQUAL( 5, val2 ); 00157 val2 = -1; 00158 CHECK( opts.getOpt( "long,s", &val2 ) ); 00159 CHECK_EQUAL( 5, val2 ); 00160 val2 = -1; 00161 CHECK( opts.getOpt( "long", &val2 ) ); 00162 CHECK_EQUAL( 5, val2 ); 00163 std::vector< int > list; 00164 opts.getOptAllArgs( ",s", list ); 00165 CHECK_EQUAL( (size_t)3, list.size() ); 00166 CHECK_EQUAL( 2, list[0] ); 00167 CHECK_EQUAL( -10, list[1] ); 00168 CHECK_EQUAL( 5, list[2] ); 00169 } 00170 00171 void test_int_arg() 00172 { 00173 ProgOptions opts; 00174 int val1 = 5; 00175 opts.addRequiredArg( "arg", "my test arg", &val1 ); 00176 opts.addRequiredArg< int >( "arg2", "my other test arg" ); 00177 const char* argv[] = { "test", "--", "-1", "-010" }; 00178 opts.parseCommandLine( ARGCV( argv ) ); 00179 CHECK_EQUAL( -1, val1 ); 00180 CHECK_EQUAL( -010, opts.getReqArg< int >( "arg2" ) ); // octal -10 == decimal -8 00181 CHECK_EQUAL( -1, opts.getReqArg< int >( "arg" ) ); 00182 } 00183 00184 void test_real_opt() 00185 { 00186 const double EPS = std::numeric_limits< double >::epsilon(); 00187 ProgOptions opts; 00188 double val1 = -1; 00189 opts.addOpt( "long,s", "my real opt", &val1 ); 00190 const char* argv[] = { "test", "-s", "2", "--long", "2e5", "--long=-0.01" }; 00191 opts.parseCommandLine( ARGCV( argv ) ); 00192 CHECK_REAL_EQUAL( -0.01, val1, EPS ); 00193 double val2 = -1; 00194 CHECK( opts.getOpt( ",s", &val2 ) ); 00195 CHECK_REAL_EQUAL( -0.01, val2, EPS ); 00196 val2 = -1; 00197 CHECK( opts.getOpt( "long,s", &val2 ) ); 00198 CHECK_REAL_EQUAL( -0.01, val2, EPS ); 00199 val2 = -1; 00200 CHECK( opts.getOpt( "long", &val2 ) ); 00201 CHECK_REAL_EQUAL( -0.01, val2, EPS ); 00202 std::vector< double > list; 00203 opts.getOptAllArgs( ",s", list ); 00204 CHECK_EQUAL( (size_t)3, list.size() ); 00205 CHECK_REAL_EQUAL( 2, list[0], EPS ); 00206 CHECK_REAL_EQUAL( 2e5, list[1], EPS ); 00207 CHECK_REAL_EQUAL( -0.01, list[2], EPS ); 00208 } 00209 00210 void test_real_arg() 00211 { 00212 const double EPS = std::numeric_limits< double >::epsilon(); 00213 ProgOptions opts; 00214 double val1 = 5; 00215 opts.addRequiredArg( "arg", "my test arg", &val1 ); 00216 opts.addRequiredArg< double >( "arg2", "my other test arg" ); 00217 const char* argv[] = { "test", "--", "-1.2", "1.01e-3" }; 00218 opts.parseCommandLine( ARGCV( argv ) ); 00219 CHECK_REAL_EQUAL( -1.2, val1, EPS ); 00220 CHECK_REAL_EQUAL( 1.01e-3, opts.getReqArg< double >( "arg2" ), EPS ); 00221 CHECK_REAL_EQUAL( -1.2, opts.getReqArg< double >( "arg" ), EPS ); 00222 } 00223 00224 void test_string_opt() 00225 { 00226 ProgOptions opts; 00227 std::string val1; 00228 opts.addOpt( "long,s", "my first opt", &val1 ); 00229 opts.addOpt< std::string >( "second,2", "my second opt" ); 00230 00231 const char* argv[] = { "test", "--long", "2", "-s", "foobar", "-2", "two", "--second=testval" }; 00232 opts.parseCommandLine( ARGCV( argv ) ); 00233 00234 CHECK_EQUAL( "foobar", val1 ); 00235 std::string val2; 00236 CHECK( opts.getOpt( ",s", &val2 ) ); 00237 CHECK_EQUAL( "foobar", val2 ); 00238 val2.clear(); 00239 CHECK( opts.getOpt( "long,s", &val2 ) ); 00240 CHECK_EQUAL( "foobar", val2 ); 00241 val2.clear(); 00242 CHECK( opts.getOpt( "long", &val2 ) ); 00243 CHECK_EQUAL( "foobar", val2 ); 00244 00245 val2.clear(); 00246 CHECK( opts.getOpt( ",2", &val2 ) ); 00247 CHECK_EQUAL( "testval", val2 ); 00248 val2.clear(); 00249 CHECK( opts.getOpt( "second,2", &val2 ) ); 00250 CHECK_EQUAL( "testval", val2 ); 00251 val2.clear(); 00252 CHECK( opts.getOpt( "second", &val2 ) ); 00253 CHECK_EQUAL( "testval", val2 ); 00254 00255 std::vector< std::string > list; 00256 opts.getOptAllArgs( "long", list ); 00257 CHECK_EQUAL( (size_t)2, list.size() ); 00258 CHECK_EQUAL( "2", list[0] ); 00259 CHECK_EQUAL( "foobar", list[1] ); 00260 00261 list.clear(); 00262 opts.getOptAllArgs( ",2", list ); 00263 CHECK_EQUAL( (size_t)2, list.size() ); 00264 CHECK_EQUAL( "two", list[0] ); 00265 CHECK_EQUAL( "testval", list[1] ); 00266 } 00267 00268 void test_string_arg() 00269 { 00270 ProgOptions opts; 00271 std::string val2; 00272 opts.addRequiredArg< std::string >( "arg", "my test arg" ); 00273 opts.addRequiredArg( "arg2", "my other test arg", &val2 ); 00274 const char* argv[] = { "test", "my_string", "with spaces" }; 00275 opts.parseCommandLine( ARGCV( argv ) ); 00276 CHECK_EQUAL( "with spaces", val2 ); 00277 CHECK_EQUAL( "my_string", opts.getReqArg< std::string >( "arg" ) ); 00278 CHECK_EQUAL( "with spaces", opts.getReqArg< std::string >( "arg2" ) ); 00279 } 00280 00281 void test_string_rank_subst() 00282 { 00283 std::string exp1 = "ddd%"; 00284 std::string exp2 = "%"; 00285 std::string exp2b = "foo%bar"; 00286 std::string exp3 = "%string%"; 00287 std::string exp4 = "file.%"; 00288 00289 ProgOptions opts; 00290 std::string val1, val2, val3, val4; 00291 opts.addOpt( ",n", "no subst flag", &val1, 0 ); 00292 opts.addOpt( "dosub,s", "subst flag", &val2, ProgOptions::rank_subst ); 00293 opts.addRequiredArg( "nos", "no subst arg", &val3, 0 ); 00294 opts.addRequiredArg( "sub", "subst arg", &val4, ProgOptions::rank_subst ); 00295 std::string eqflg( "--dosub=" ); 00296 eqflg += exp2; 00297 const char* argv[] = { "test", exp3.c_str(), exp4.c_str(), "-s", exp2b.c_str(), "-n", exp1.c_str(), eqflg.c_str() }; 00298 opts.parseCommandLine( ARGCV( argv ) ); 00299 00300 #ifdef MOAB_HAVE_MPI 00301 int rank, size; 00302 MPI_Comm_rank( MPI_COMM_WORLD, &rank ); 00303 MPI_Comm_size( MPI_COMM_WORLD, &size ); 00304 char buffer[64]; 00305 int width = 1; 00306 while( size > 10 ) 00307 { 00308 width++; 00309 size /= 10; 00310 } 00311 sprintf( buffer, "%0*d", width, rank ); 00312 exp2 = buffer; 00313 exp2b = std::string( "foo" ) + buffer + "bar"; 00314 exp4 = std::string( "file." ) + buffer; 00315 #endif 00316 00317 CHECK_EQUAL( exp1, val1 ); 00318 CHECK_EQUAL( exp2, val2 ); 00319 CHECK_EQUAL( exp3, val3 ); 00320 CHECK_EQUAL( exp4, val4 ); 00321 00322 val1.clear(); 00323 val2.clear(); 00324 CHECK( opts.getOpt( ",n", &val1 ) ); 00325 CHECK( opts.getOpt( "dosub", &val2 ) ); 00326 00327 CHECK_EQUAL( exp1, val1 ); 00328 CHECK_EQUAL( exp2, val2 ); 00329 CHECK_EQUAL( exp3, opts.getReqArg< std::string >( "nos" ) ); 00330 CHECK_EQUAL( exp4, opts.getReqArg< std::string >( "sub" ) ); 00331 00332 std::vector< std::string > list; 00333 opts.getOptAllArgs( ",s", list ); 00334 CHECK_EQUAL( (size_t)2, list.size() ); 00335 CHECK_EQUAL( exp2b, list[0] ); 00336 CHECK_EQUAL( exp2, list[1] ); 00337 } 00338 00339 void test_int_vect_opt() 00340 { 00341 ProgOptions opts; 00342 std::vector< int > list1, list2; 00343 opts.addOpt( "ids,d", "id list", &list1 ); 00344 const char* argv[] = { "test", "--ids=1,2,3", "--ids", "4-10", "-d", "4-5,2" }; 00345 00346 const int exp1[] = { 1, 2, 3 }; 00347 const int exp1_len = sizeof( exp1 ) / sizeof( exp1[0] ); 00348 const int exp2[] = { 4, 5, 6, 7, 8, 9, 10 }; 00349 const int exp2_len = sizeof( exp2 ) / sizeof( exp2[0] ); 00350 const int exp3[] = { 4, 5, 2 }; 00351 const int exp3_len = sizeof( exp3 ) / sizeof( exp3[0] ); 00352 std::vector< int > all; 00353 std::copy( exp1, exp1 + exp1_len, std::back_inserter( all ) ); 00354 std::copy( exp2, exp2 + exp2_len, std::back_inserter( all ) ); 00355 std::copy( exp3, exp3 + exp3_len, std::back_inserter( all ) ); 00356 00357 opts.parseCommandLine( ARGCV( argv ) ); 00358 CHECK_EQUAL( all, list1 ); 00359 CHECK( opts.getOpt( ",d", &list2 ) ); 00360 CHECK_ARRAYS_EQUAL( exp3, exp3_len, &list2[0], list2.size() ); 00361 00362 std::vector< std::vector< int > > lists; 00363 opts.getOptAllArgs( "ids", lists ); 00364 CHECK_EQUAL( (size_t)3, lists.size() ); 00365 CHECK_ARRAYS_EQUAL( exp1, exp1_len, &lists[0][0], lists[0].size() ); 00366 CHECK_ARRAYS_EQUAL( exp2, exp2_len, &lists[1][0], lists[1].size() ); 00367 CHECK_ARRAYS_EQUAL( exp3, exp3_len, &lists[2][0], lists[2].size() ); 00368 00369 list2.clear(); 00370 opts.getOptAllArgs( "ids", list2 ); 00371 CHECK_EQUAL( all, list2 ); 00372 } 00373 00374 void test_int_vect_arg() 00375 { 00376 ProgOptions opts; 00377 std::vector< int > list1; 00378 opts.addRequiredArg( "ints", "int list", &list1 ); 00379 const char* argv[] = { "test", "5,6,-3--1,10" }; 00380 00381 const int exp1[] = { 5, 6, -3, -2, -1, 10 }; 00382 const int exp1_len = sizeof( exp1 ) / sizeof( exp1[0] ); 00383 00384 opts.parseCommandLine( ARGCV( argv ) ); 00385 CHECK_ARRAYS_EQUAL( exp1, exp1_len, &list1[0], list1.size() ); 00386 CHECK_EQUAL( list1, opts.getReqArg< std::vector< int > >( "ints" ) ); 00387 } 00388 00389 void test_optional_args() 00390 { 00391 ProgOptions opts1; 00392 std::string arg; 00393 opts1.addOptionalArgs< std::string >( 0, "opts", "optional arguments" ); 00394 opts1.addRequiredArg( "req", "required final argument", &arg ); 00395 const char* argv1[] = { "test", "arg" }; 00396 opts1.parseCommandLine( ARGCV( argv1 ) ); 00397 std::vector< std::string > list; 00398 CHECK_EQUAL( "arg", arg ); 00399 opts1.getArgs( "opts", list ); 00400 CHECK( list.empty() ); 00401 00402 ProgOptions opts2; 00403 arg.clear(); 00404 opts2.addOptionalArgs< std::string >( 0, "opts", "optional arguments" ); 00405 opts2.addRequiredArg( "req", "required final argument", &arg ); 00406 const char* argv2[] = { "test", "arg1", "arg2", "arg" }; 00407 opts2.parseCommandLine( ARGCV( argv2 ) ); 00408 CHECK_EQUAL( "arg", arg ); 00409 list.clear(); 00410 opts2.getArgs( "opts", list ); 00411 CHECK_EQUAL( (size_t)2, list.size() ); 00412 CHECK_EQUAL( "arg1", list[0] ); 00413 CHECK_EQUAL( "arg2", list[1] ); 00414 } 00415 00416 void test_optional_arg() 00417 { 00418 ProgOptions opts1; 00419 std::string init, fini; 00420 opts1.addRequiredArg( "init", "required initial argument", &init ); 00421 opts1.addOptionalArgs< std::string >( 1, "mid", "optional arguments" ); 00422 opts1.addRequiredArg( "fini", "required final argument", &fini ); 00423 const char* argv1[] = { "test", "arg1", "arg2" }; 00424 opts1.parseCommandLine( ARGCV( argv1 ) ); 00425 std::vector< std::string > list; 00426 CHECK_EQUAL( "arg1", init ); 00427 CHECK_EQUAL( "arg2", fini ); 00428 opts1.getArgs( "mid", list ); 00429 CHECK( list.empty() ); 00430 00431 ProgOptions opts2; 00432 init.clear(); 00433 fini.clear(); 00434 opts2.addRequiredArg( "init", "required initial argument", &init ); 00435 opts2.addOptionalArgs< std::string >( 1, "mid", "optional arguments" ); 00436 opts2.addRequiredArg( "fini", "required final argument", &fini ); 00437 const char* argv2[] = { "test", "arg1", "arg2", "arg3" }; 00438 opts2.parseCommandLine( ARGCV( argv2 ) ); 00439 CHECK_EQUAL( "arg1", init ); 00440 CHECK_EQUAL( "arg3", fini ); 00441 list.clear(); 00442 opts2.getArgs( "mid", list ); 00443 CHECK_EQUAL( (size_t)1, list.size() ); 00444 CHECK_EQUAL( "arg2", list[0] ); 00445 } 00446 00447 void test_squashed_short() 00448 { 00449 ProgOptions opts; 00450 int intval = 0; 00451 double realval = 0; 00452 bool flagval = false; 00453 std::string strval; 00454 opts.addOpt< void >( ",f", "flag", &flagval ); 00455 opts.addOpt( ",i", "int", &intval ); 00456 opts.addOpt( ",r", "real", &realval ); 00457 opts.addOpt( ",s", "str", &strval ); 00458 00459 const char* argv[] = { "test", "-ifsrff", "-0xBEEF", "string", "-1.0e55" }; 00460 opts.parseCommandLine( ARGCV( argv ) ); 00461 00462 CHECK_EQUAL( -0xBEEF, intval ); 00463 CHECK_REAL_EQUAL( -1.0e55, realval, 1e-6 ); 00464 CHECK_EQUAL( "string", strval ); 00465 CHECK( flagval ); 00466 CHECK_EQUAL( 3, opts.numOptSet( ",f" ) ); 00467 CHECK_EQUAL( 1, opts.numOptSet( ",i" ) ); 00468 CHECK_EQUAL( 1, opts.numOptSet( ",r" ) ); 00469 CHECK_EQUAL( 1, opts.numOptSet( ",s" ) ); 00470 }