From 743094ffc908a5554009119cebc91ebfb998ad4c Mon Sep 17 00:00:00 2001 From: James Date: Tue, 17 Dec 2019 11:07:47 -0500 Subject: [PATCH] Adding parser for arguments. --- CMake/testing/VTKmTestWrappers.cmake | 3 + vtkm/cont/testing/Testing.h | 134 ++++++++++++++++++ .../testing/UnitTestMapperVolume.cxx | 7 - 3 files changed, 137 insertions(+), 7 deletions(-) diff --git a/CMake/testing/VTKmTestWrappers.cmake b/CMake/testing/VTKmTestWrappers.cmake index 0c8f86530..2052197d4 100644 --- a/CMake/testing/VTKmTestWrappers.cmake +++ b/CMake/testing/VTKmTestWrappers.cmake @@ -105,6 +105,9 @@ function(vtkm_unit_tests) # Add the path to the data directory so tests can find and use data files for testing list(APPEND VTKm_UT_TEST_ARGS "--path=${VTKm_SOURCE_DIR}/data") + # Add the path to the location where regression test images are to be stored + list(APPEND VTKm_UT_TEST_ARGS "--images=${VTKm_SOURCE_DIR}") + if(VTKm_UT_MPI) # for MPI tests, suffix test name and add MPI_Init/MPI_Finalize calls. set(test_prog "${test_prog}_mpi") diff --git a/vtkm/cont/testing/Testing.h b/vtkm/cont/testing/Testing.h index a00a1fa69..132030cb1 100644 --- a/vtkm/cont/testing/Testing.h +++ b/vtkm/cont/testing/Testing.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -25,6 +26,8 @@ #include +namespace opt = vtkm::cont::internal::option; + namespace vtkm { namespace cont @@ -32,6 +35,66 @@ namespace cont namespace testing { +enum TestOptionsIndex +{ + UNKNOWN, + DATADIR, // base dir containing test data files + IMGDIR // base dir for saving regression test images +}; + +struct VtkmArg : public opt::Arg +{ + static opt::ArgStatus Required(const opt::Option& option, bool msg) + { + if (option.arg == nullptr) + { + if (msg) + { + VTKM_LOG_ALWAYS_S(vtkm::cont::LogLevel::Error, + "Missing argument after option '" + << std::string(option.name, static_cast(option.namelen)) + << "'.\n"); + } + return opt::ARG_ILLEGAL; + } + else + { + return opt::ARG_OK; + } + } + + // Method used for guessing whether an option that do not support (perhaps that calling + // program knows about it) has an option attached to it (which should also be ignored). + static opt::ArgStatus Unknown(const opt::Option& option, bool msg) + { + // If we don't have an arg, obviously we don't have an arg. + if (option.arg == nullptr) + { + return opt::ARG_NONE; + } + + // The opt::Arg::Optional method will return that the ARG is OK if and only if + // the argument is attached to the option (e.g. --foo=bar). If that is the case, + // then we definitely want to report that the argument is OK. + if (opt::Arg::Optional(option, msg) == opt::ARG_OK) + { + return opt::ARG_OK; + } + + // Now things get tricky. Maybe the next argument is an option or maybe it is an + // argument for this option. We will guess that if the next argument does not + // look like an option, we will treat it as such. + if (option.arg[0] == '-') + { + return opt::ARG_NONE; + } + else + { + return opt::ARG_OK; + } + } +}; + struct Testing { public: @@ -46,6 +109,77 @@ public: printf("after initialize arg :: %s\n", argv[i]); } + { // Parse test arguments + std::vector usage; + + usage.push_back( + { DATADIR, + 0, + "p", + "path", + VtkmArg::Required, + " --path, -p \tPath to the base data directory in the VTK-m src dir." }); + usage.push_back( + { IMGDIR, + 0, + "i", + "images", + VtkmArg::Required, + " --images, -i \tPath to the base dir for regression test images" }); + // Required to collect unknown arguments when help is off. + usage.push_back({ UNKNOWN, 0, "", "", VtkmArg::Unknown, "" }); + usage.push_back({ 0, 0, 0, 0, 0, 0 }); + + + // Remove argv[0] (executable name) if present: + int vtkmArgc = argc > 0 ? argc - 1 : 0; + char** vtkmArgv = vtkmArgc > 0 ? argv + 1 : argv; + + opt::Stats stats(usage.data(), vtkmArgc, vtkmArgv); + std::unique_ptr options{ new opt::Option[stats.options_max] }; + std::unique_ptr buffer{ new opt::Option[stats.buffer_max] }; + opt::Parser parse(usage.data(), vtkmArgc, vtkmArgv, options.get(), buffer.get()); + + if (parse.error()) + { + std::cerr << "Internal Initialize parser error" << std::endl; + exit(1); + } + + if (options[DATADIR]) + { + std::cerr << "found the data dir arg :: " << options[DATADIR].arg << std::endl; + } + + if (options[IMGDIR]) + { + std::cerr << "found the data image arg :: " << options[IMGDIR].arg << std::endl; + } + + for (const opt::Option* opt = options[UNKNOWN]; opt != nullptr; opt = opt->next()) + { + VTKM_LOG_S(vtkm::cont::LogLevel::Info, + "Unknown option to internal Initialize: " << opt->name << "\n"); + if ((InitializeOptions::ErrorOnBadOption) != InitializeOptions::None) + { + std::cerr << "Unknown internal option: " << opt->name << std::endl; + exit(1); + } + } + + for (int nonOpt = 0; nonOpt < parse.nonOptionsCount(); ++nonOpt) + { + VTKM_LOG_S(vtkm::cont::LogLevel::Info, + "Unknown argument to internal Initialize: " << parse.nonOption(nonOpt) << "\n"); + if ((InitializeOptions::ErrorOnBadArgument) != InitializeOptions::None) + { + std::cerr << "Unknown internal argument: " << parse.nonOption(nonOpt) << std::endl; + exit(1); + } + } + } + + try { function(); diff --git a/vtkm/rendering/testing/UnitTestMapperVolume.cxx b/vtkm/rendering/testing/UnitTestMapperVolume.cxx index 5572f6a35..35a4ff3b0 100644 --- a/vtkm/rendering/testing/UnitTestMapperVolume.cxx +++ b/vtkm/rendering/testing/UnitTestMapperVolume.cxx @@ -67,12 +67,5 @@ void RenderTests() int UnitTestMapperVolume(int argc, char* argv[]) { - std::cerr << "argc count: " << argc << std::endl; - - for (int i = 0; i < argc; i++) - { - printf("arg :: %s\n", argv[i]); - } - return vtkm::cont::testing::Testing::Run(RenderTests, argc, argv); }