diff --git a/opm/parser/eclipse/CMakeLists.txt b/opm/parser/eclipse/CMakeLists.txt index 376cb462f..e30f20038 100644 --- a/opm/parser/eclipse/CMakeLists.txt +++ b/opm/parser/eclipse/CMakeLists.txt @@ -1,5 +1,8 @@ +include_directories(${PROJECT_BINARY_DIR}/generated-source/include) + add_subdirectory(OpmLog/tests) add_subdirectory(Parser/tests) +add_subdirectory(Generator/tests) add_subdirectory(RawDeck/tests) add_subdirectory(Deck/tests) add_subdirectory(IntegrationTests) @@ -53,10 +56,12 @@ Parser/ParserIntItem.cpp Parser/ParserFloatItem.cpp Parser/ParserDoubleItem.cpp Parser/ParserStringItem.cpp -${PROJECT_BINARY_DIR}/generated-source/DefaultKeywordList.cpp +${PROJECT_BINARY_DIR}/generated-source/ParserKeywords.cpp ) -SET_SOURCE_FILES_PROPERTIES(${PROJECT_BINARY_DIR}/generated-source/DefaultKeywordList.cpp PROPERTIES GENERATED TRUE) +set( generator_source +Generator/KeywordGenerator.cpp +Generator/KeywordLoader.cpp ) set( build_parser_source Parser/ParserEnums.cpp @@ -67,6 +72,7 @@ Parser/ParserIntItem.cpp Parser/ParserFloatItem.cpp Parser/ParserDoubleItem.cpp Parser/ParserStringItem.cpp +${generator_source} ) set (state_source @@ -143,7 +149,9 @@ Parser/ParserIntItem.hpp Parser/ParserFloatItem.hpp Parser/ParserDoubleItem.hpp Parser/ParserStringItem.hpp -Parser/ParserKeywords.hpp # PlaceHolder for future generated header +# +Generator/KeywordLoader.hpp +Generator/KeywordGenerator.hpp # Units/UnitSystem.hpp Units/Dimension.hpp @@ -243,7 +251,7 @@ Utility/EquilWrapper.hpp Utility/EndscaleWrapper.hpp Utility/ScalecrsWrapper.hpp) -add_library(buildParser STATIC ${rawdeck_source} ${build_parser_source} ${deck_source} ${unit_source}) +add_library(buildParser STATIC ${rawdeck_source} ${build_parser_source} ${deck_source} ${unit_source} ${generator_source}) target_link_libraries(buildParser opmjson ${Boost_LIBRARIES}) #----------------------------------------------------------------- @@ -264,19 +272,27 @@ target_link_libraries( createDefaultKeywordList buildParser opmjson ${Boost_LIBR # This target will always run - the dependency "management" is # implicitly handled in the createDefaultKeywordList application. -add_custom_target( generatedCode ALL - COMMAND createDefaultKeywordList - ${PROJECT_SOURCE_DIR}/opm/parser/share/keywords - ${PROJECT_BINARY_DIR}/generated-source/DefaultKeywordList.cpp - ${PROJECT_BINARY_DIR}/generated-source/inlineKeywordTest.cpp - ${PROJECT_BINARY_DIR}/generated-source/DefaultKeywordList.signature ) +add_custom_target( generatedCode ALL COMMAND createDefaultKeywordList + ${PROJECT_SOURCE_DIR}/opm/parser/share/keywords + ${PROJECT_BINARY_DIR}/generated-source/ParserKeywords.cpp + ${PROJECT_BINARY_DIR}/generated-source/include/opm/parser/eclipse/Parser/ParserKeywords.hpp + ${PROJECT_BINARY_DIR}/generated-source/inlineKeywordTest.cpp ) + +set_source_files_properties(${PROJECT_BINARY_DIR}/generated-source/ParserKeywords.cpp PROPERTIES GENERATED TRUE) +set_source_files_properties(${PROJECT_BINARY_DIR}/generated-source/inlcude/opm/parser/eclipse/Parser/ParserKeywords.hpp PROPERTIES GENERATED TRUE) +set_source_files_properties(${PROJECT_BINARY_DIR}/generated-source/inlineKeywordTest.cpp PROPERTIES GENERATED TRUE) + +opm_add_test( runInlineKeywordTest SOURCES ${PROJECT_BINARY_DIR}/generated-source/inlineKeywordTest.cpp + LIBRARIES opmparser ${Boost_LIBRARIES} + DEPENDS generatedCode ) #----------------------------------------------------------------- -add_library(opmparser ${rawdeck_source} ${parser_source} ${deck_source} ${state_source} ${unit_source} ${log_source}) -add_dependencies(opmparser generatedCode) +add_library(opmparser ${rawdeck_source} ${parser_source} ${deck_source} ${state_source} ${unit_source} ${log_source} ${generator_source}) +add_dependencies( opmparser generatedCode ) target_link_libraries(opmparser opmjson ${Boost_LIBRARIES} ${ERT_LIBRARIES}) include( ${PROJECT_SOURCE_DIR}/cmake/Modules/install_headers.cmake ) install_headers( "${HEADER_FILES}" "${CMAKE_INSTALL_PREFIX}" ) install( TARGETS opmparser DESTINATION ${CMAKE_INSTALL_LIBDIR} ) +install( FILES ${PROJECT_BINARY_DIR}/generated-source/include/opm/parser/eclipse/Parser/ParserKeywords.hpp DESTINATION "include/opm/parser/eclipse/Parser") diff --git a/opm/parser/eclipse/Generator/KeywordGenerator.cpp b/opm/parser/eclipse/Generator/KeywordGenerator.cpp new file mode 100644 index 000000000..2e47d39fb --- /dev/null +++ b/opm/parser/eclipse/Generator/KeywordGenerator.cpp @@ -0,0 +1,212 @@ +/* + Copyright 2015 Statoil ASA. + + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ + +#include +#include +#include + +#include +#include + +#include +#include + +namespace Opm { + + KeywordGenerator::KeywordGenerator(bool verbose) + : m_verbose( verbose ) + { + } + + + + + std::string testHeader() { + std::string header = "#define BOOST_TEST_MODULE\n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "using namespace Opm;\n" + "std::shared_ptr unitSystem( UnitSystem::newMETRIC() );\n"; + + return header; + } + + + std::string KeywordGenerator::sourceHeader() { + std::string header = "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \n\n\n" + "namespace Opm {\n" + "namespace ParserKeywords {\n\n"; + + return header; + } + + std::string KeywordGenerator::headerHeader() { + std::string header = "#ifndef PARSER_KEYWORDS_HPP\n" + "#define PARSER_KEYWORDS_HPP\n" + "#include \n" + "namespace Opm {\n" + "namespace ParserKeywords {\n\n"; + + return header; + } + + void KeywordGenerator::ensurePath( const std::string& file_name) { + boost::filesystem::path file(file_name); + if (!boost::filesystem::is_directory( file.parent_path())) + boost::filesystem::create_directories( file.parent_path()); + } + + bool KeywordGenerator::updateFile(std::stringstream& newContent , const std::string& filename) { + std::ifstream stream(filename.c_str()); + bool update = true; + + ensurePath( filename ); + if (stream.is_open()) { + std::stringstream oldContent; + oldContent << stream.rdbuf( ); + if (oldContent.str() == newContent.str()) + update = false; + } + + if (update) { + std::fstream stream(filename.c_str() , std::fstream::out); + stream << newContent.str(); + stream.close(); + } + + return update; + } + + + bool KeywordGenerator::updateSource(const KeywordLoader& loader , const std::string& sourceFile) const { + std::stringstream newSource; + + newSource << sourceHeader(); + for (auto iter = loader.keyword_begin(); iter != loader.keyword_end(); ++iter) { + std::shared_ptr keyword = (*iter).second; + newSource << keyword->createCode() << std::endl; + } + newSource << "}" << std::endl; + { + newSource << "void Parser::addDefaultKeywords() {" << std::endl; + for (auto iter = loader.keyword_begin(); iter != loader.keyword_end(); ++iter) { + std::shared_ptr keyword = (*iter).second; + newSource << " addParserKeyword( std::shared_ptr( new ParserKeywords::" << keyword->className() << "()));" << std::endl; + } + newSource << "}" << std::endl; + } + newSource << "}" << std::endl; + + { + bool update = updateFile( newSource , sourceFile ); + if (m_verbose) { + if (update) + std::cout << "Updated source file written to: " << sourceFile << std::endl; + else + std::cout << "No changes to source file: " << sourceFile << std::endl; + } + return update; + } + } + + + bool KeywordGenerator::updateHeader(const KeywordLoader& loader , const std::string& headerFile) const { + std::stringstream stream; + + stream << headerHeader(); + for (auto iter = loader.keyword_begin(); iter != loader.keyword_end(); ++iter) { + std::shared_ptr keyword = (*iter).second; + stream << keyword->createDeclaration(" ") << std::endl; + } + stream << "}" << std::endl << "}" << std::endl; + stream << "#endif" << std::endl; + + { + bool update = updateFile( stream , headerFile ); + if (m_verbose) { + if (update) + std::cout << "Updated header file written to: " << headerFile << std::endl; + else + std::cout << "No changes to header file: " << headerFile << std::endl; + } + return update; + } + } + + + std::string KeywordGenerator::startTest(const std::string& keyword_name) { + return std::string("BOOST_AUTO_TEST_CASE(TEST") + keyword_name + std::string("Keyword) {\n"); + } + + + std::string KeywordGenerator::endTest() { + return "}\n\n"; + } + + + + bool KeywordGenerator::updateTest(const KeywordLoader& loader , const std::string& testFile) const { + std::stringstream stream; + + stream << testHeader(); + for (auto iter = loader.keyword_begin(); iter != loader.keyword_end(); ++iter) { + const std::string& keywordName = (*iter).first; + std::shared_ptr keyword = (*iter).second; + stream << startTest(keywordName); + stream << " std::string jsonFile = \"" << loader.getJsonFile( keywordName) << "\";" << std::endl; + stream << " boost::filesystem::path jsonPath( jsonFile );" << std::endl; + stream << " Json::JsonObject jsonConfig( jsonPath );" << std::endl; + stream << " ParserKeyword jsonKeyword(jsonConfig);" << std::endl; + stream << " ParserKeywords::" << keywordName << " inlineKeyword;" << std::endl; + stream << " BOOST_CHECK( jsonKeyword.equal( inlineKeyword ));" << std::endl; + stream << " if (jsonKeyword.hasDimension()) {" <size(); i++){ " << std::endl; + stream << " ParserItemConstPtr item = parserRecord->get( i );" << std::endl; + stream << " for (size_t j=0; j < item->numDimensions(); j++) {" << std::endl; + stream << " std::string dimString = item->getDimension(j);" << std::endl; + stream << " BOOST_CHECK_NO_THROW( unitSystem->getNewDimension( dimString ));" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << endTest( ); + } + + return updateFile( stream , testFile ); + } +} + + diff --git a/opm/parser/eclipse/Generator/KeywordGenerator.hpp b/opm/parser/eclipse/Generator/KeywordGenerator.hpp new file mode 100644 index 000000000..e93024e41 --- /dev/null +++ b/opm/parser/eclipse/Generator/KeywordGenerator.hpp @@ -0,0 +1,53 @@ +/* + Copyright 2015 Statoil ASA. + + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ + + +#ifndef KEYWORD_GENERATOR_HPP +#define KEYWORD_GENERATOR_HPP +#include +#include +#include + +#include +#include +#include + +namespace Opm { + class KeywordGenerator { + + public: + KeywordGenerator(bool verbose); + + static void ensurePath( const std::string& file_name); + static std::string endTest(); + static std::string startTest(const std::string& test_name); + static std::string sourceHeader(); + static std::string headerHeader(); + static bool updateFile(std::stringstream& newContent , const std::string& filename); + + bool updateSource(const KeywordLoader& loader, const std::string& sourceFile) const; + bool updateHeader(const KeywordLoader& loader, const std::string& headerFile) const; + bool updateTest(const KeywordLoader& loader , const std::string& testFile) const; + + private: + bool m_verbose; + }; +} + +#endif diff --git a/opm/parser/eclipse/Generator/KeywordLoader.cpp b/opm/parser/eclipse/Generator/KeywordLoader.cpp new file mode 100644 index 000000000..db0b1b538 --- /dev/null +++ b/opm/parser/eclipse/Generator/KeywordLoader.cpp @@ -0,0 +1,172 @@ +/* + Copyright 2015 Statoil ASA. + + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ + +#include +#include +#include + +#include +#include + +#include +#include + +namespace Opm { + + KeywordLoader::KeywordLoader(bool verbose) + : m_verbose(verbose) + { + } + + + size_t KeywordLoader::size() const { + return m_keywords.size(); + } + + + bool KeywordLoader::hasKeyword(const std::string& keyword) const { + if (m_keywords.find( keyword ) == m_keywords.end()) + return false; + else + return true; + } + + + std::shared_ptr KeywordLoader::getKeyword(const std::string& keyword) const { + auto iter = m_keywords.find( keyword ); + if (iter == m_keywords.end()) + throw std::invalid_argument("Keyword " + keyword + " not loaded"); + else + return (*iter).second; + } + + + std::string KeywordLoader::getJsonFile(const std::string& keyword) const { + auto iter = m_jsonFile.find( keyword ); + if (iter == m_jsonFile.end()) + throw std::invalid_argument("Keyword " + keyword + " not loaded"); + else + return (*iter).second; + } + + + size_t KeywordLoader::loadKeywordDirectory(boost::filesystem::path& path) { + size_t loadCount = 0; + if (boost::filesystem::is_directory( path )) { + boost::filesystem::directory_iterator end_iterator; + + for (boost::filesystem::directory_iterator iter(path); iter != end_iterator; ++iter) { + boost::filesystem::path iter_path = iter->path(); + + if (boost::filesystem::is_directory( iter_path )) { + loadCount += loadKeywordDirectory( iter_path ); + } else { + std::string internalName = iter_path.filename().string(); + if (ParserKeyword::validInternalName(internalName)) { + loadKeyword( iter_path ); + loadCount += 1; + if (m_verbose) + std::cout << "Loading keyword " << internalName << " from file: " << iter_path << std::endl; + } else { + if (m_verbose) + std::cout << "Ignoring file " << iter_path << " - incorrectly formatted name." << std::endl; + } + } + } + + } else + throw std::invalid_argument("Input does not correspond to existing directory\n"); + + return loadCount; + } + + size_t KeywordLoader::loadKeywordDirectory(const std::string& directory) { + boost::filesystem::path path( directory ); + return loadKeywordDirectory( path ); + } + + void KeywordLoader::loadKeyword(boost::filesystem::path& path) { + std::shared_ptr jsonConfig = std::make_shared( path ); + std::shared_ptr parserKeyword = std::make_shared(*jsonConfig); + { + boost::filesystem::path abs_path = boost::filesystem::absolute( path ); + addKeyword( parserKeyword , abs_path.string() ); + } + } + + + size_t KeywordLoader::loadMultipleKeywordDirectories(const std::string& directory) { + std::vector directories = sortSubdirectories( directory ); + + size_t load_count = 0; + for (auto iter = directories.begin(); iter != directories.end(); ++iter) + load_count += loadKeywordDirectory(*iter); + + return load_count; + } + + + void KeywordLoader::loadKeyword(const std::string& filename) { + boost::filesystem::path path( filename ); + return loadKeyword( path ); + } + + + void KeywordLoader::addKeyword(std::shared_ptr keyword , const std::string& jsonFile) { + const std::string& name = keyword->getName(); + + if (hasKeyword(name)) { + m_keywords[name] = keyword; + m_jsonFile[name] = jsonFile; + } else { + m_keywords.insert( std::pair > (name , keyword) ); + m_jsonFile.insert( std::pair ( name , jsonFile)); + } + } + + + std::vector KeywordLoader::sortSubdirectories( const std::string& root_path) { + boost::filesystem::path root(root_path); + if (boost::filesystem::is_directory( root )) { + std::vector paths_in_root; + boost::filesystem::directory_iterator end_iterator; + + for (boost::filesystem::directory_iterator iter(root); iter != end_iterator; ++iter) { + if (boost::filesystem::is_directory( iter->path() )) + paths_in_root.push_back(iter->path().string()); + } + + std::sort(paths_in_root.begin(), paths_in_root.end()); + return paths_in_root; + } else + throw std::invalid_argument("Input argument is not a directory"); + } + + std::map >::const_iterator KeywordLoader::keyword_begin( ) const { + return m_keywords.begin( ); + } + + std::map >::const_iterator KeywordLoader::keyword_end( ) const { + return m_keywords.end( ); + } + + +} + + diff --git a/opm/parser/eclipse/Generator/KeywordLoader.hpp b/opm/parser/eclipse/Generator/KeywordLoader.hpp new file mode 100644 index 000000000..0552b0f02 --- /dev/null +++ b/opm/parser/eclipse/Generator/KeywordLoader.hpp @@ -0,0 +1,58 @@ +/* + Copyright 2015 Statoil ASA. + + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ + + +#ifndef KEYWORD_LOADER_HPP +#define KEYWORD_LOADER_HPP +#include +#include +#include + +#include +#include + +namespace Opm { + class KeywordLoader { + + public: + KeywordLoader(bool verbose); + size_t size() const; + bool hasKeyword(const std::string& keyword) const; + std::shared_ptr getKeyword(const std::string& keyword) const; + std::string getJsonFile(const std::string& keyword) const; + size_t loadKeywordDirectory(const std::string& pathname); + size_t loadKeywordDirectory(boost::filesystem::path& path); + void loadKeyword(const std::string& filename); + void loadKeyword(boost::filesystem::path& path); + + static std::vector sortSubdirectories( const std::string& directory ); + size_t loadMultipleKeywordDirectories(const std::string& directory); + + std::map >::const_iterator keyword_begin( ) const; + std::map >::const_iterator keyword_end( ) const; + private: + void addKeyword(std::shared_ptr keyword , const std::string& jsonFile); + + bool m_verbose; + std::map > m_keywords; + std::map m_jsonFile; + }; +} + +#endif diff --git a/opm/parser/eclipse/Generator/tests/CMakeLists.txt b/opm/parser/eclipse/Generator/tests/CMakeLists.txt new file mode 100644 index 000000000..24fd5d931 --- /dev/null +++ b/opm/parser/eclipse/Generator/tests/CMakeLists.txt @@ -0,0 +1,4 @@ +foreach(tapp KeywordLoaderTests) + opm_add_test(run${tapp} SOURCES ${tapp}.cpp + LIBRARIES opmparser ${Boost_LIBRARIES}) +endforeach() diff --git a/opm/parser/eclipse/Generator/tests/KeywordLoaderTests.cpp b/opm/parser/eclipse/Generator/tests/KeywordLoaderTests.cpp new file mode 100644 index 000000000..9d9606e0a --- /dev/null +++ b/opm/parser/eclipse/Generator/tests/KeywordLoaderTests.cpp @@ -0,0 +1,100 @@ +/* + Copyright 2015 Statoil ASA. + + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . + */ + +#include +#include +#include +#include + +#define BOOST_TEST_MODULE InputKeywordTests +#include +#include + + +#include + +BOOST_AUTO_TEST_CASE(EmptyKeywordLoader) { + Opm::KeywordLoader loader(false); + + BOOST_CHECK_EQUAL( false , loader.hasKeyword("NO")); + BOOST_CHECK_EQUAL( 0U , loader.size() ); + BOOST_CHECK_THROW( loader.getKeyword("NO") , std::invalid_argument); +} + + + +BOOST_AUTO_TEST_CASE(LoadKeyword) { + Opm::KeywordLoader loader(false); + + BOOST_CHECK_THROW( loader.loadKeyword("does/not/exists") , std::invalid_argument ); + BOOST_CHECK_THROW( loader.loadKeyword("testdata/parser/keyword-generator/invalid.json") , std::invalid_argument); + BOOST_CHECK_THROW( loader.loadKeyword("testdata/parser/keyword-generator/PORO-invalid") , std::invalid_argument); + + loader.loadKeyword("testdata/parser/keyword-generator/PORO.json"); + loader.loadKeyword("testdata/parser/keyword-generator/PORO.json"); + + BOOST_CHECK_EQUAL( true , loader.hasKeyword("PORO")); + BOOST_CHECK_EQUAL( 1U , loader.size() ); + + loader.getKeyword("PORO"); +} + + + +BOOST_AUTO_TEST_CASE(LoadKeywordDirectory) { + Opm::KeywordLoader loader(false); + BOOST_CHECK_THROW( loader.loadKeywordDirectory("does/not/exists") , std::invalid_argument ); + BOOST_CHECK_THROW( loader.loadKeywordDirectory("testdata/parser/keyword-generator/invalid.json") , std::invalid_argument); + + BOOST_CHECK_EQUAL( 4 , loader.loadKeywordDirectory( "testdata/parser/keyword-generator/loader/001_ECLIPSE100")); + BOOST_CHECK( loader.hasKeyword("ADDREG") ); + BOOST_CHECK( loader.hasKeyword("ACTNUM") ); + BOOST_CHECK( loader.hasKeyword("BOX") ); + BOOST_CHECK( loader.hasKeyword("BLOCK_PROBE") ); + { + auto kw = loader.getKeyword("ADDREG"); + auto record = kw->getRecord(0); + BOOST_CHECK_EQUAL( false, record->hasItem("REGION_NUMBER")); + } +} + + +BOOST_AUTO_TEST_CASE(DirectorySort) { + BOOST_CHECK_THROW( Opm::KeywordLoader::sortSubdirectories( "testdata/parser/keyword-generator/loader/ZCORN") , std::invalid_argument ); + std::vector dir_list = Opm::KeywordLoader::sortSubdirectories( "testdata/parser/keyword-generator/loader"); + + BOOST_CHECK_EQUAL( 2U , dir_list.size()); + BOOST_CHECK_EQUAL( dir_list[0] , "testdata/parser/keyword-generator/loader/001_ECLIPSE100"); + BOOST_CHECK_EQUAL( dir_list[1] , "testdata/parser/keyword-generator/loader/002_ECLIPSE300"); +} + + +BOOST_AUTO_TEST_CASE(BigLoad) { + Opm::KeywordLoader loader(false); + BOOST_CHECK_THROW( loader.loadMultipleKeywordDirectories("does/not/exists") , std::invalid_argument ); + BOOST_CHECK_THROW( loader.loadMultipleKeywordDirectories("testdata/parser/keyword-generator/invalid.json") , std::invalid_argument); + + loader.loadMultipleKeywordDirectories("testdata/parser/keyword-generator/loader"); + BOOST_CHECK( loader.hasKeyword("EQUIL")); + { + auto kw = loader.getKeyword("ADDREG"); + auto record = kw->getRecord(0); + BOOST_CHECK( record->hasItem("REGION_NUMBER")); + } +} diff --git a/opm/parser/eclipse/IntegrationTests/IntegrationTests.cpp b/opm/parser/eclipse/IntegrationTests/IntegrationTests.cpp index 1802beaac..049fa8768 100644 --- a/opm/parser/eclipse/IntegrationTests/IntegrationTests.cpp +++ b/opm/parser/eclipse/IntegrationTests/IntegrationTests.cpp @@ -32,14 +32,28 @@ using namespace Opm; +std::shared_ptr createFixedSized(const std::string& kw , size_t size) { + std::shared_ptr pkw = std::make_shared(kw); + pkw->setFixedSize( size ); + return pkw; +} + +std::shared_ptr createDynamicSized(const std::string& kw) { + std::shared_ptr pkw = std::make_shared(kw); + pkw->setSizeType(SLASH_TERMINATED); + return pkw; +} + + + static ParserPtr createWWCTParser() { - ParserKeywordPtr parserKeyword = ParserKeyword::createDynamicSized("WWCT"); + ParserKeywordPtr parserKeyword = createDynamicSized("WWCT"); { std::shared_ptr record = std::make_shared(); record->addItem( ParserStringItemConstPtr(new ParserStringItem("WELL", ALL)) ); parserKeyword->addRecord( record ); } - ParserKeywordPtr summaryKeyword = ParserKeyword::createFixedSized("SUMMARY" , (size_t) 0); + ParserKeywordPtr summaryKeyword = createFixedSized("SUMMARY" , (size_t) 0); ParserPtr parser(new Parser()); parser->addParserKeyword(parserKeyword); @@ -78,7 +92,6 @@ BOOST_AUTO_TEST_CASE(parse_streamWithWWCTKeyword_deckReturned) { " 'WELL-1' 'WELL-2' / -- Rumpelstilzchen\n" "/\n"; std::shared_ptr wwctStream(new std::istringstream(wwctString)); - ParserPtr parser = createWWCTParser(); BOOST_CHECK( parser->isRecognizedKeyword("WWCT")); BOOST_CHECK( parser->isRecognizedKeyword("SUMMARY")); @@ -125,7 +138,7 @@ BOOST_AUTO_TEST_CASE(parser_internal_name_vs_deck_name) { } static ParserPtr createBPRParser() { - ParserKeywordPtr parserKeyword = ParserKeyword::createDynamicSized("BPR"); + ParserKeywordPtr parserKeyword = createDynamicSized("BPR"); { std::shared_ptr bprRecord = std::make_shared(); bprRecord->addItem(ParserIntItemConstPtr(new ParserIntItem("I", SINGLE))); @@ -133,7 +146,7 @@ static ParserPtr createBPRParser() { bprRecord->addItem(ParserIntItemConstPtr(new ParserIntItem("K", SINGLE))); parserKeyword->addRecord( bprRecord ); } - ParserKeywordPtr summaryKeyword = ParserKeyword::createFixedSized("SUMMARY" , (size_t) 0); + ParserKeywordPtr summaryKeyword = createFixedSized("SUMMARY" , (size_t) 0); ParserPtr parser(new Parser()); parser->addParserKeyword(parserKeyword); parser->addParserKeyword(summaryKeyword); diff --git a/opm/parser/eclipse/Parser/Parser.cpp b/opm/parser/eclipse/Parser/Parser.cpp index 81e5a4bbf..66b502ff9 100644 --- a/opm/parser/eclipse/Parser/Parser.cpp +++ b/opm/parser/eclipse/Parser/Parser.cpp @@ -326,7 +326,7 @@ namespace Opm { if (jsonKeywords.is_array()) { for (size_t index = 0; index < jsonKeywords.size(); index++) { Json::JsonObject jsonKeyword = jsonKeywords.get_array_item(index); - ParserKeywordConstPtr parserKeyword = ParserKeyword::createFromJson(jsonKeyword); + ParserKeywordConstPtr parserKeyword = std::make_shared(jsonKeyword); addParserKeyword(parserKeyword); } @@ -447,7 +447,7 @@ namespace Opm { try { Json::JsonObject jsonKeyword(configFile); - ParserKeywordConstPtr parserKeyword = ParserKeyword::createFromJson(jsonKeyword); + ParserKeywordConstPtr parserKeyword = std::make_shared(jsonKeyword); addParserKeyword(parserKeyword); return true; } diff --git a/opm/parser/eclipse/Parser/ParserDoubleItem.cpp b/opm/parser/eclipse/Parser/ParserDoubleItem.cpp index 6c8a10149..53d4da023 100644 --- a/opm/parser/eclipse/Parser/ParserDoubleItem.cpp +++ b/opm/parser/eclipse/Parser/ParserDoubleItem.cpp @@ -133,12 +133,27 @@ namespace Opm return ParserItemScan(this , rawRecord); } - void ParserDoubleItem::inlineNew(std::ostream& os) const { - os << "new ParserDoubleItem(" << "\"" << name() << "\"" << "," << ParserItemSizeEnum2String( sizeType() ); + std::string ParserDoubleItem::createCode() const { + std::stringstream ss; + + ss << "new ParserDoubleItem(" << "\"" << name() << "\"" << ",Opm::" << ParserItemSizeEnum2String( sizeType() ); if (m_defaultSet) - os << "," << boost::lexical_cast(getDefault()); - os << ")"; + ss << "," << boost::lexical_cast(getDefault()); + ss << ")"; + + return ss.str(); } + + + void ParserDoubleItem::inlineClass(std::ostream& os, const std::string& indent) const { + ParserItemInlineClassDeclaration(this , os , indent , "double"); + } + + std::string ParserDoubleItem::inlineClassInit(const std::string& parentClass) const { + return ParserItemInlineClassInit(this , parentClass , "double"); + } + + } diff --git a/opm/parser/eclipse/Parser/ParserDoubleItem.hpp b/opm/parser/eclipse/Parser/ParserDoubleItem.hpp index 57e812b48..ce8665e2e 100644 --- a/opm/parser/eclipse/Parser/ParserDoubleItem.hpp +++ b/opm/parser/eclipse/Parser/ParserDoubleItem.hpp @@ -48,7 +48,10 @@ namespace Opm { DeckItemPtr scan(RawRecordPtr rawRecord) const; bool equal(const ParserItem& other) const; - void inlineNew(std::ostream& os) const; + + std::string createCode() const; + void inlineClass(std::ostream& os, const std::string& indent) const; + std::string inlineClassInit(const std::string& parentClass) const; void setDefault(double defaultValue); double getDefault() const; bool hasDefault() const; diff --git a/opm/parser/eclipse/Parser/ParserFloatItem.cpp b/opm/parser/eclipse/Parser/ParserFloatItem.cpp index 425de0f1f..2b46aea20 100644 --- a/opm/parser/eclipse/Parser/ParserFloatItem.cpp +++ b/opm/parser/eclipse/Parser/ParserFloatItem.cpp @@ -131,11 +131,25 @@ namespace Opm return ParserItemScan(this , rawRecord); } - void ParserFloatItem::inlineNew(std::ostream& os) const { - os << "new ParserFloatItem(" << "\"" << name() << "\"" << "," << ParserItemSizeEnum2String( sizeType() ); + std::string ParserFloatItem::createCode() const { + std::stringstream ss; + + ss << "new ParserFloatItem(" << "\"" << name() << "\"" << ",Opm::" << ParserItemSizeEnum2String( sizeType() ); if (m_defaultSet) - os << "," << boost::lexical_cast(getDefault()); - os << ")"; + ss << "," << boost::lexical_cast(getDefault()); + ss << ")"; + + return ss.str(); + } + + + + void ParserFloatItem::inlineClass(std::ostream& os, const std::string& indent) const { + ParserItemInlineClassDeclaration(this , os , indent , "float"); + } + + std::string ParserFloatItem::inlineClassInit(const std::string& parentClass) const { + return ParserItemInlineClassInit(this , parentClass , "Float"); } } diff --git a/opm/parser/eclipse/Parser/ParserFloatItem.hpp b/opm/parser/eclipse/Parser/ParserFloatItem.hpp index c6e35e9e9..d2a62ca88 100644 --- a/opm/parser/eclipse/Parser/ParserFloatItem.hpp +++ b/opm/parser/eclipse/Parser/ParserFloatItem.hpp @@ -49,7 +49,10 @@ namespace Opm { DeckItemPtr scan(RawRecordPtr rawRecord) const; bool equal(const ParserItem& other) const; - void inlineNew(std::ostream& os) const; + + std::string createCode() const; + void inlineClass(std::ostream& os, const std::string& indent) const; + std::string inlineClassInit(const std::string& parentClass) const; void setDefault(float defaultValue); float getDefault() const; bool hasDefault() const; diff --git a/opm/parser/eclipse/Parser/ParserIntItem.cpp b/opm/parser/eclipse/Parser/ParserIntItem.cpp index d1883d394..0a2cd3d9c 100644 --- a/opm/parser/eclipse/Parser/ParserIntItem.cpp +++ b/opm/parser/eclipse/Parser/ParserIntItem.cpp @@ -1,4 +1,5 @@ /* + Copyright 2013 Statoil ASA. This file is part of the Open Porous Media project (OPM). @@ -18,6 +19,7 @@ */ #include +#include #include #include @@ -95,10 +97,27 @@ namespace Opm { } - void ParserIntItem::inlineNew(std::ostream& os) const { - os << "new ParserIntItem(" << "\"" << name() << "\"" << "," << ParserItemSizeEnum2String( sizeType() ); + std::string ParserIntItem::createCode() const { + std::stringstream ss; + + ss << "new ParserIntItem(" << "\"" << name() << "\"" << ",Opm::" << ParserItemSizeEnum2String( sizeType() ); if (m_defaultSet) - os << "," << getDefault(); - os << ")"; + ss << "," << getDefault(); + ss << ")"; + + return ss.str(); } + + + + void ParserIntItem::inlineClass(std::ostream& os, const std::string& indent) const { + ParserItemInlineClassDeclaration(this , os , indent , "int"); + } + + + std::string ParserIntItem::inlineClassInit(const std::string& parentClass) const { + return ParserItemInlineClassInit(this , parentClass , "int"); + } + + } diff --git a/opm/parser/eclipse/Parser/ParserIntItem.hpp b/opm/parser/eclipse/Parser/ParserIntItem.hpp index 962e55275..b525572ab 100644 --- a/opm/parser/eclipse/Parser/ParserIntItem.hpp +++ b/opm/parser/eclipse/Parser/ParserIntItem.hpp @@ -43,7 +43,10 @@ namespace Opm { DeckItemPtr scan(RawRecordPtr rawRecord) const; bool equal(const ParserItem& other) const; - void inlineNew(std::ostream& os) const; + + std::string createCode() const; + void inlineClass(std::ostream& os, const std::string& indent) const; + std::string inlineClassInit(const std::string& parentClass) const; int getDefault() const; bool hasDefault() const; diff --git a/opm/parser/eclipse/Parser/ParserItem.cpp b/opm/parser/eclipse/Parser/ParserItem.cpp index 0f1281aa3..78b10c48a 100644 --- a/opm/parser/eclipse/Parser/ParserItem.cpp +++ b/opm/parser/eclipse/Parser/ParserItem.cpp @@ -79,6 +79,12 @@ namespace Opm { return m_name; } + const std::string ParserItem::className() const { + return m_name; + } + + + ParserItemSizeEnum ParserItem::sizeType() const { return m_sizeType; } diff --git a/opm/parser/eclipse/Parser/ParserItem.hpp b/opm/parser/eclipse/Parser/ParserItem.hpp index de191a03a..f9788acec 100644 --- a/opm/parser/eclipse/Parser/ParserItem.hpp +++ b/opm/parser/eclipse/Parser/ParserItem.hpp @@ -47,13 +47,16 @@ namespace Opm { virtual DeckItemPtr scan(RawRecordPtr rawRecord) const = 0; virtual bool hasDimension() const; virtual size_t numDimensions() const; + const std::string className() const; const std::string& name() const; ParserItemSizeEnum sizeType() const; std::string getDescription() const; bool scalar() const; void setDescription(std::string helpText); - virtual void inlineNew(std::ostream& /* os */) const = 0; + virtual std::string createCode() const = 0; + virtual void inlineClass(std::ostream& /* os */ , const std::string& indent) const = 0; + virtual std::string inlineClassInit(const std::string& parentClass) const = 0; virtual ~ParserItem() { } @@ -99,6 +102,45 @@ namespace Opm { typedef std::shared_ptr ParserItemConstPtr; typedef std::shared_ptr ParserItemPtr; + + + template + void ParserItemInlineClassDeclaration(const ParserItemType * self , std::ostream& os, const std::string& indent , const std::string& typeString) { + os << indent << "class " << self->className( ) << " {" << std::endl; + os << indent << "public:" << std::endl; + { + std::string local_indent = indent + " "; + os << local_indent << "static const std::string itemName;" << std::endl; + if (self->hasDefault()) + os << local_indent << "static const " << typeString << " defaultValue;" << std::endl; + } + os << indent << "};" << std::endl; + } + + + template + std::string ParserItemInlineClassInit(const ParserItemType * self , + const std::string& parentClass , + const std::string& typeString , + const std::string * defaultValue = NULL) { + + std::stringstream ss; + ss << "const std::string " << parentClass << "::" << self->className() << "::itemName = \"" << self->name() << "\";" << std::endl; + + if (self->hasDefault()) { + if (defaultValue) + ss << "const " << typeString << " " << parentClass << "::" << self->className() << "::defaultValue = " << *defaultValue << ";" << std::endl; + else + ss << "const " << typeString << " " << parentClass << "::" << self->className() << "::defaultValue = " << self->getDefault() << ";" << std::endl; + } + + return ss.str(); + } + + + + + /// Scans the rawRecords data according to the ParserItems definition. /// returns a DeckItem object. /// NOTE: data are popped from the rawRecords deque! diff --git a/opm/parser/eclipse/Parser/ParserKeyword.cpp b/opm/parser/eclipse/Parser/ParserKeyword.cpp index dc9307958..6b8bb3759 100644 --- a/opm/parser/eclipse/Parser/ParserKeyword.cpp +++ b/opm/parser/eclipse/Parser/ParserKeyword.cpp @@ -32,6 +32,20 @@ namespace Opm { + void ParserKeyword::setSizeType( ParserKeywordSizeEnum sizeType ) { + m_keywordSizeType = sizeType; + } + + void ParserKeyword::setFixedSize( size_t keywordSize) { + m_keywordSizeType = FIXED; + m_fixedSize = keywordSize; + } + + void ParserKeyword::setTableCollection(bool isTableCollection) { + m_isTableCollection = isTableCollection; + } + + void ParserKeyword::commonInit(const std::string& name, ParserKeywordSizeEnum sizeType) { m_isTableCollection = false; m_name = name; @@ -172,35 +186,8 @@ namespace Opm { } } - ParserKeywordPtr ParserKeyword::createFixedSized(const std::string& name, - size_t fixedKeywordSize) { - auto kw = std::make_shared( name ); - kw->m_keywordSizeType = FIXED; - kw->m_fixedSize = fixedKeywordSize; - return kw; - } - - ParserKeywordPtr ParserKeyword::createDynamicSized(const std::string& name, - ParserKeywordSizeEnum sizeType) { - auto kw = std::make_shared( name ); - kw->m_keywordSizeType = sizeType; - return kw; - } - - - ParserKeywordPtr ParserKeyword::createTable(const std::string& name, - const std::string& sizeKeyword, - const std::string& sizeItem, - bool isTableCollection) { - return ParserKeywordPtr(new ParserKeyword(name, sizeKeyword, sizeItem, isTableCollection)); - } - - ParserKeywordPtr ParserKeyword::createFromJson(const Json::JsonObject& jsonConfig) { - return ParserKeywordPtr(new ParserKeyword(jsonConfig)); - } - void ParserKeyword::initSizeKeyword(const std::string& sizeKeyword, const std::string& sizeItem) { m_sizeDefinitionPair = std::pair(sizeKeyword, sizeItem); m_keywordSizeType = OTHER_KEYWORD_IN_DECK; @@ -507,6 +494,9 @@ namespace Opm { } + const std::string ParserKeyword::className() const { + return getName(); + } const std::string& ParserKeyword::getName() const { return m_name; @@ -667,84 +657,135 @@ namespace Opm { } } - void ParserKeyword::inlineNew(std::ostream& os, const std::string& lhs, const std::string& indent) const { + + std::string ParserKeyword::createDeclaration(const std::string& indent) const { + std::stringstream ss; + ss << indent << "class " << className() << " : public ParserKeyword {" << std::endl; + ss << indent << "public:" << std::endl; + { + std::string local_indent = indent + " "; + ss << local_indent << className() << "();" << std::endl; + ss << local_indent << "static const std::string keywordName;" << std::endl; + if (m_records.size() > 0 ) { + for (auto iter = recordBegin(); iter != recordEnd(); ++iter) { + std::shared_ptr record = *iter; + for (size_t i = 0; i < record->size(); i++) { + ParserItemConstPtr item = record->get(i); + ss << std::endl; + item->inlineClass(ss , local_indent ); + } + } + } + } + ss << indent << "};" << std::endl << std::endl << std::endl; + return ss.str(); + } + + + std::string ParserKeyword::createDecl() const { + return className() + "::" + className() + "()"; + } + + + std::string ParserKeyword::createCode() const { + std::stringstream ss; + const std::string lhs = "keyword"; + const std::string indent = " "; + + ss << className() << "::" << className() << "( ) : ParserKeyword(\"" << m_name << "\") {" << std::endl; { const std::string sizeString(ParserKeywordSizeEnum2String(m_keywordSizeType)); + ss << indent; switch (m_keywordSizeType) { case SLASH_TERMINATED: - os << lhs << " = ParserKeyword::createDynamicSized(\"" << m_name << "\"," << sizeString << ");" << std::endl; + ss << "setSizeType(" << sizeString << ");" << std::endl; break; case UNKNOWN: - os << lhs << " = ParserKeyword::createDynamicSized(\"" << m_name << "\"," << sizeString << ");" << std::endl; + ss << "setSizeType(" << sizeString << ");" << std::endl; break; case FIXED: - os << lhs << " = ParserKeyword::createFixedSized(\"" << m_name << "\",(size_t)" << m_fixedSize << ");" << std::endl; + ss << "setFixedSize( (size_t) " << m_fixedSize << ");" << std::endl; break; case OTHER_KEYWORD_IN_DECK: - if (isTableCollection()) - os << lhs << " = ParserKeyword::createTable(\"" << m_name << "\",\"" << m_sizeDefinitionPair.first << "\",\"" << m_sizeDefinitionPair.second << "\", true);" << std::endl; - else - os << lhs << " = ParserKeyword::createTable(\"" << m_name << "\",\"" << m_sizeDefinitionPair.first << "\",\"" << m_sizeDefinitionPair.second << "\");" << std::endl; + ss << "setSizeType(" << sizeString << ");" << std::endl; + ss << indent << "initSizeKeyword(\"" << m_sizeDefinitionPair.first << "\",\"" << m_sizeDefinitionPair.second << "\");" << std::endl; + if (m_isTableCollection) + ss << "setTableCollection( true );" << std::endl; break; } } - os << indent << lhs << "->setDescription(\"" << getDescription() << "\");" << std::endl; + ss << indent << "setDescription(\"" << getDescription() << "\");" << std::endl; // add the valid sections for the keyword - os << indent << lhs << "->clearValidSectionNames();\n"; + ss << indent << "clearValidSectionNames();\n"; for (auto sectionNameIt = m_validSectionNames.begin(); sectionNameIt != m_validSectionNames.end(); ++sectionNameIt) { - os << indent << lhs << "->addValidSectionName(\"" << *sectionNameIt << "\");" << std::endl; + ss << indent << "addValidSectionName(\"" << *sectionNameIt << "\");" << std::endl; } // add the deck names - os << indent << lhs << "->clearDeckNames();\n"; + ss << indent << "clearDeckNames();\n"; for (auto deckNameIt = m_deckNames.begin(); deckNameIt != m_deckNames.end(); ++deckNameIt) { - os << indent << lhs << "->addDeckName(\"" << *deckNameIt << "\");" << std::endl; + ss << indent << "addDeckName(\"" << *deckNameIt << "\");" << std::endl; } // set the deck name match regex if (hasMatchRegex()) - os << indent << lhs << "->setMatchRegex(\"" << m_matchRegexString << "\");" << std::endl; + ss << indent << "setMatchRegex(\"" << m_matchRegexString << "\");" << std::endl; { if (m_records.size() > 0 ) { for (auto iter = recordBegin(); iter != recordEnd(); ++iter) { std::shared_ptr record = *iter; const std::string local_indent = indent + " "; - os << indent << "{" << std::endl; - os << local_indent << "std::shared_ptr record = std::make_shared();" << std::endl; + ss << indent << "{" << std::endl; + ss << local_indent << "std::shared_ptr record = std::make_shared();" << std::endl; for (size_t i = 0; i < record->size(); i++) { ParserItemConstPtr item = record->get(i); - os << local_indent << "ParserItemPtr "<name()<<"item("; - item->inlineNew(os); - os << ");" << std::endl; - os << local_indent << item->name()<<"item->setDescription(\"" << item->getDescription() << "\");" << std::endl; - for (size_t idim=0; idim < item->numDimensions(); idim++) - os << local_indent <name()<<"item->push_backDimension(\"" << item->getDimension( idim ) << "\");" << std::endl; + ss << local_indent << "{" << std::endl; { - std::string addItemMethod = "addItem"; - if (isDataKeyword()) - addItemMethod = "addDataItem"; + std::string indent3 = local_indent + " "; + ss << indent3 << "ParserItemPtr item(" << item->createCode() << ");" << std::endl; + ss << indent3 << "item->setDescription(\"" << item->getDescription() << "\");" << std::endl; + for (size_t idim=0; idim < item->numDimensions(); idim++) + ss << indent3 <<"item->push_backDimension(\"" << item->getDimension( idim ) << "\");" << std::endl; + { + std::string addItemMethod = "addItem"; + if (isDataKeyword()) + addItemMethod = "addDataItem"; - os << local_indent << "record->" << addItemMethod << "("<name()<<"item);" << std::endl; + ss << indent3 << "record->" << addItemMethod << "(item);" << std::endl; + } } + ss << local_indent << "}" << std::endl; } if (record->isDataRecord()) - os << local_indent << lhs << "->addDataRecord( record );" << std::endl; + ss << local_indent << "addDataRecord( record );" << std::endl; else - os << local_indent << lhs << "->addRecord( record );" << std::endl; + ss << local_indent << "addRecord( record );" << std::endl; - os << indent << "}" << std::endl; + ss << indent << "}" << std::endl; } } } + ss << "}" << std::endl; + + ss << "const std::string " << className() << "::keywordName = \"" << getName() << "\";" << std::endl; + for (auto iter = recordBegin(); iter != recordEnd(); ++iter) { + std::shared_ptr record = *iter; + for (size_t i = 0; i < record->size(); i++) { + ParserItemConstPtr item = record->get(i); + ss << item->inlineClassInit(className()); + } + } + ss << std::endl; + return ss.str(); } diff --git a/opm/parser/eclipse/Parser/ParserKeyword.hpp b/opm/parser/eclipse/Parser/ParserKeyword.hpp index 63d8cdc18..b7bf4a346 100644 --- a/opm/parser/eclipse/Parser/ParserKeyword.hpp +++ b/opm/parser/eclipse/Parser/ParserKeyword.hpp @@ -54,47 +54,18 @@ namespace Opm { const std::string& sizeKeyword , const std::string& sizeItem, bool isTableCollection = false); - ParserKeyword(const std::string& name); - ParserKeyword(const Json::JsonObject& jsonConfig); + explicit ParserKeyword(const std::string& name); + explicit ParserKeyword(const Json::JsonObject& jsonConfig); + + void setFixedSize( size_t keywordSize); + void setSizeType( ParserKeywordSizeEnum sizeType ); + void setTableCollection(bool isTableCollection); + void initSizeKeyword( const std::string& sizeKeyword, const std::string& sizeItem); + typedef std::set DeckNameSet; typedef std::set SectionNameSet; - /*! - * \brief Factory method to create a keyword where the number - * of items per record is defined at compile time. - * - * This are for example well specifcation keywords like WCONPROD... - */ - static ParserKeywordPtr createFixedSized(const std::string& name, - size_t fixedKeywordSize); - - /*! - * \brief Factory method to create a keyword with an per-se - * unspecified number of items per record. - * - * This are for example grid properties like PERM?... - */ - static ParserKeywordPtr createDynamicSized(const std::string& name, - ParserKeywordSizeEnum sizeType = SLASH_TERMINATED); - - /*! - * \brief Factory method to create a keyword which has a - * dynamic number of items per record. - * - * But with the number of items are specified via an item of a - * different keyword, e.g. for tables. - */ - static ParserKeywordPtr createTable(const std::string& name, - const std::string& sizeKeyword, - const std::string& sizeItem, - bool isTableCollection = false); - - /*! - * \brief Factory method to create a keyword from a JSON - * configuration object. - */ - static ParserKeywordPtr createFromJson(const Json::JsonObject& jsonConfig); static std::string getDeckName(const std::string& rawString); static bool validInternalName(const std::string& name); @@ -108,6 +79,7 @@ namespace Opm { ParserRecordPtr getRecord(size_t recordIndex) const; std::vector::const_iterator recordBegin() const; std::vector::const_iterator recordEnd() const; + const std::string className() const; const std::string& getName() const; size_t getFixedSize() const; bool hasFixedSize() const; @@ -134,7 +106,10 @@ namespace Opm { const std::pair& getSizeDefinitionPair() const; bool isDataKeyword() const; bool equal(const ParserKeyword& other) const; - void inlineNew(std::ostream& os , const std::string& lhs, const std::string& indent) const; + + std::string createDeclaration(const std::string& indent) const; + std::string createDecl() const; + std::string createCode() const; void applyUnitsToDeck(std::shared_ptr deck , std::shared_ptr deckKeyword) const; private: std::pair m_sizeDefinitionPair; @@ -159,7 +134,6 @@ namespace Opm { void initMatchRegex( const Json::JsonObject& jsonObject ); void initData( const Json::JsonObject& jsonConfig ); void initSize( const Json::JsonObject& jsonConfig ); - void initSizeKeyword( const std::string& sizeKeyword, const std::string& sizeItem); void initSizeKeyword(const Json::JsonObject& sizeObject); void commonInit(const std::string& name, ParserKeywordSizeEnum sizeType); void addItems( const Json::JsonObject& jsonConfig); diff --git a/opm/parser/eclipse/Parser/ParserKeywords.hpp b/opm/parser/eclipse/Parser/ParserKeywords.hpp deleted file mode 100644 index 0b881170d..000000000 --- a/opm/parser/eclipse/Parser/ParserKeywords.hpp +++ /dev/null @@ -1,8 +0,0 @@ -/* - This header file is purely a placeholder for a generated header - which is in the pipeline. -*/ - -#ifndef PARSERKEYWORDS_HPP -#define PARSERKEYWORDS_HPP -#endif diff --git a/opm/parser/eclipse/Parser/ParserStringItem.cpp b/opm/parser/eclipse/Parser/ParserStringItem.cpp index 15e96dbb4..2428f94bc 100644 --- a/opm/parser/eclipse/Parser/ParserStringItem.cpp +++ b/opm/parser/eclipse/Parser/ParserStringItem.cpp @@ -88,10 +88,33 @@ namespace Opm { return parserRawItemEqual(other); } - void ParserStringItem::inlineNew(std::ostream& os) const { - os << "new ParserStringItem(" << "\"" << name() << "\"" << "," << ParserItemSizeEnum2String( sizeType() ); + std::string ParserStringItem::createCode() const { + std::stringstream ss; + + ss << "new ParserStringItem(" << "\"" << name() << "\"" << ",Opm::" << ParserItemSizeEnum2String( sizeType() ); if (m_defaultSet) - os << ",\"" << getDefault() << "\""; - os << ")"; + ss << ",\"" << getDefault() << "\""; + ss << ")"; + + return ss.str(); } + + + + + void ParserStringItem::inlineClass(std::ostream& os , const std::string& indent) const { + ParserItemInlineClassDeclaration(this , os , indent , "std::string"); + } + + + std::string ParserStringItem::inlineClassInit(const std::string& parentClass) const { + if (hasDefault()) { + std::string quotedDefault = "\"" + getDefault() + "\""; + return ParserItemInlineClassInit(this , parentClass , "std::string" , "edDefault); + } else + return ParserItemInlineClassInit(this , parentClass , "std::string"); + } + + + } diff --git a/opm/parser/eclipse/Parser/ParserStringItem.hpp b/opm/parser/eclipse/Parser/ParserStringItem.hpp index 829d551ac..b093c7b55 100644 --- a/opm/parser/eclipse/Parser/ParserStringItem.hpp +++ b/opm/parser/eclipse/Parser/ParserStringItem.hpp @@ -40,7 +40,10 @@ namespace Opm { bool equal(const ParserItem& other) const; DeckItemPtr scan(RawRecordPtr rawRecord) const; - void inlineNew(std::ostream& os) const; + + std::string createCode() const; + void inlineClass(std::ostream& os, const std::string& indent) const; + std::string inlineClassInit(const std::string& parentClass) const; void setDefault(const std::string& defaultValue); std::string getDefault() const; bool hasDefault() const; diff --git a/opm/parser/eclipse/Parser/createDefaultKeywordList.cpp b/opm/parser/eclipse/Parser/createDefaultKeywordList.cpp index ef13737c3..20b036db0 100644 --- a/opm/parser/eclipse/Parser/createDefaultKeywordList.cpp +++ b/opm/parser/eclipse/Parser/createDefaultKeywordList.cpp @@ -1,350 +1,26 @@ -#include -#include -#include -#include -#include -#include - -// http://www.ridgesolutions.ie/index.php/2013/05/30/boost-link-error-undefined-reference-to-boostfilesystemdetailcopy_file/ -#define BOOST_NO_CXX11_SCOPED_ENUMS -#include - -#include -#include -#include -#include -#include -#include -#include +#include +#include -using namespace Opm; -using namespace boost::filesystem; +int main(int argc , char ** argv) { + if (argc == 5) { + const char * config_root = argv[1]; + const char * source_file_name = argv[2]; + const char * header_file_name = argv[3]; + const char * test_file_name = argv[4]; -typedef std::pair > KeywordElementType; -typedef std::map > KeywordMapType; + Opm::KeywordLoader loader(false); + Opm::KeywordGenerator generator(true); + loader.loadMultipleKeywordDirectories( config_root ); + generator.updateSource(loader , source_file_name ); + generator.updateHeader(loader , header_file_name ); + generator.updateTest(loader , test_file_name ); - -static void createHeader(std::iostream& of ) { - of << "#include " << std::endl; - of << "#include " << std::endl; - of << "#include " << std::endl; - of << "#include " << std::endl; - of << "#include " << std::endl; - of << "#include " << std::endl; - of << "#include " << std::endl; - of << "namespace Opm {" << std::endl << std::endl; -} - - - -static void createTestHeader(std::iostream& of , const std::string& test_module) { - of << "#define BOOST_TEST_MODULE " << test_module << std::endl; - of << "#include " << std::endl; - of << "#include " << std::endl; - of << "#include " << std::endl; - of << "#include " << std::endl; - of << "#include " << std::endl; - of << "#include " << std::endl; - of << "#include " << std::endl; - of << "#include " << std::endl; - of << "#include " << std::endl; - of << "#include " << std::endl; - of << "using namespace Opm;" << std::endl << std::endl; - of << "std::shared_ptr unitSystem( UnitSystem::newMETRIC() );" << std::endl; -} - - - -static void startFunction(std::iostream& of) { - of << "void Parser::addDefaultKeywords() { " << std::endl; -} - - -static void endFunction(std::iostream& of) { - of << "}" << std::endl; -} - - - -static bool areStreamsEqual( std::istream& lhs, std::istream& rhs ) -{ - for (;;) - { - char l = lhs.get(); - char r = rhs.get(); - if (!lhs || !rhs) // if either at end of file - break; - if (l != r) // false if chars differ - return false; - } - return !lhs && !rhs; // true if both end of file -} - - -static void generateKeywordSignature(std::iostream& of , KeywordMapType& keywordMap) -{ - for (auto iter=keywordMap.begin(); iter != keywordMap.end(); ++iter) { - KeywordElementType keywordElement = *iter; - const std::string& keywordName = keywordElement.first; - const std::string& fileName = keywordElement.second.first; - Json::JsonObject * jsonKeyword = new Json::JsonObject(boost::filesystem::path(fileName)); - - of << keywordName << std::endl << jsonKeyword->to_string() << std::endl; - - delete jsonKeyword; + exit(0); + } else { + std::cerr << "Error calling keyword generator: Expected arguments: " << std::endl; + exit(1); } } - -//----------------------------------------------------------------- - -static void startTest(std::iostream& of, const std::string& test_name) { - of << "BOOST_AUTO_TEST_CASE(" << test_name << ") {" << std::endl; -} - - -static void endTest(std::iostream& of) { - of << "}" << std::endl << std::endl; -} - -static void testKeyword(ParserKeywordConstPtr parserKeyword , const std::string& keywordName , const boost::filesystem::path& jsonFile , std::iostream& of) { - std::string testName("test"+keywordName+"Keyword"); - startTest(of , testName); - of << " Json::JsonObject jsonKeyword(boost::filesystem::path(" << jsonFile << "));" << std::endl; - of << " ParserKeywordConstPtr parserKeyword = ParserKeyword::createFromJson(jsonKeyword);" << std::endl; - - of << " ParserKeywordPtr "; - parserKeyword->inlineNew(of , "inlineKeyword" , " "); - - of << "BOOST_CHECK( parserKeyword->equal( *inlineKeyword));" << std::endl; - if (parserKeyword->hasDimension()) { - of << "{" << std::endl; - of << " ParserRecordConstPtr parserRecord = parserKeyword->getRecord(0);" << std::endl; - of << " for (size_t i=0; i < parserRecord->size(); i++) { " << std::endl; - of << " ParserItemConstPtr item = parserRecord->get( i );" << std::endl; - of << " for (size_t j=0; j < item->numDimensions(); j++) {" << std::endl; - of << " std::string dimString = item->getDimension(j);" << std::endl; - of << " BOOST_CHECK_NO_THROW( unitSystem->getNewDimension( dimString ));" << std::endl; - of << " }" << std::endl; - of << " }" << std::endl; - of << "}" << std::endl; - } - endTest( of ); -} - - -static void generateTestForKeyword(std::iostream& of, KeywordElementType keywordElement) { - const std::string& keywordName = keywordElement.first; - const std::string& fileName = keywordElement.second.first; - ParserKeywordConstPtr parserKeyword = keywordElement.second.second; - - testKeyword( parserKeyword , keywordName , fileName , of ); -} - - -static void generateKeywordTest(const char * test_file_name , KeywordMapType& keywordMap) { - std::fstream test_file_stream( test_file_name , std::fstream::out ); - createTestHeader( test_file_stream , "TEST_KEYWORDS"); - for (auto iter=keywordMap.begin(); iter != keywordMap.end(); ++iter) - generateTestForKeyword(test_file_stream , *iter); - - test_file_stream.close( ); -} - -//----------------------------------------------------------------- - -static void generateSourceForKeyword(std::iostream& of, KeywordElementType keywordElement) -{ - const std::string& keywordName = keywordElement.first; - ParserKeywordConstPtr parserKeyword = keywordElement.second.second; - - std::string indent(" "); - of << "{" << std::endl; - of << indent << "ParserKeywordPtr "; - parserKeyword->inlineNew(of , keywordName , indent); - of << indent << "parser->addParserKeyword( " << keywordName << ");" << std::endl; - of << "}" << std::endl << std::endl; - - std::cout << "Creating keyword: " << keywordName << std::endl; -} - -static void generateKeywordSource(const char * source_file_name , KeywordMapType& keywordMap) { - std::fstream source_file_stream( source_file_name, std::fstream::out ); - - createHeader(source_file_stream); - - for (auto iter=keywordMap.begin(); iter != keywordMap.end(); ++iter) { - // the stupid default compiler flags will cause a warning if a function is - // defined without declaring a prototype before. So let's give the compiler a - // cookie to make it happy... - source_file_stream << "void add" << iter->first << "Keyword(Opm::Parser *parser);\n"; - - source_file_stream << "void add" << iter->first << "Keyword(Opm::Parser *parser)\n"; - generateSourceForKeyword(source_file_stream , *iter); - } - - startFunction(source_file_stream); - for (auto iter=keywordMap.begin(); iter != keywordMap.end(); ++iter) - source_file_stream << " add" << iter->first << "Keyword(this);\n"; - endFunction(source_file_stream); - - source_file_stream << "} // end namespace Opm\n"; - - source_file_stream.close( ); -} - -//----------------------------------------------------------------- - -static void scanKeyword(const boost::filesystem::path& file , KeywordMapType& keywordMap) { - std::string internalName = file.filename().string(); - if (!ParserKeyword::validInternalName(internalName)) { - std::cerr << "Warning: Ignoring incorrectly named file '" << file.string() << "'.\n"; - return; - } - - KeywordMapType::iterator existingEntry = keywordMap.find(internalName); - bool alreadyExists = existingEntry != keywordMap.end(); - if (alreadyExists) { - std::cerr << "Warning: Ignoring the the keyword " << internalName << " found in '" << existingEntry->second.first << "'," << std::endl - << "\treplacing it with data from '" << file.string() << "'" << std::endl; - keywordMap.erase(existingEntry); - } - - Json::JsonObject * jsonKeyword; - try { - jsonKeyword = new Json::JsonObject(file); - } catch(const std::exception& e) { - std::cerr << "Parsing JSON keyword definition from file '" << file.string() << "' failed: " - << e.what() << "\n"; - std::exit(1); - } - - { - ParserKeywordConstPtr parserKeyword(ParserKeyword::createFromJson( *jsonKeyword )); - if (parserKeyword->getName() != boost::filesystem::basename(file)) - std::cerr << "Warning: The name '" << parserKeyword->getName() << " specified in the JSON definitions of file '" << file - << "' does not match the file's name!\n"; - std::pair elm(file.string(), parserKeyword); - std::pair > pair(parserKeyword->getName() , elm); - - keywordMap.insert(pair); - } - - delete jsonKeyword; -} - -static void scanAllKeywords(const boost::filesystem::path& directory , KeywordMapType& keywordMap) { - boost::filesystem::directory_iterator end_iterator; - for (boost::filesystem::directory_iterator iter(directory); iter != end_iterator; iter++) { - if (boost::filesystem::is_directory(*iter)) - scanAllKeywords(*iter , keywordMap); - else - scanKeyword(*iter , keywordMap); - } -} - - -//----------------------------------------------------------------- - -static void printUsage() { - std::cout << "Generates source code for populating the parser's list of known keywords." << std::endl; - std::cout << "Usage: createDefaultKeywordList []" << std::endl; - std::cout << " : Path to keyword (JSON) files, first level below this will be read in alfanumerical order. Ignoring repeated keywords." << std::endl; - std::cout << " : Path to source file to generate" << std::endl; - std::cout << " : Path to source file with keyword testing" << std::endl; - std::cout << " : Path to dump file containing state of keyword list at" << std::endl; - std::cout << " last build (used for build triggering)." << std::endl; -} - - -static void ensurePath( const char * file_name ) { - boost::filesystem::path file(file_name); - if (!boost::filesystem::is_directory( file.parent_path())) - boost::filesystem::create_directory( file.parent_path()); -} - - -static std::vector getPathsInAlfanumOrder(const char* config_root) -{ - boost::filesystem::path root(config_root); - std::vector paths_in_root; - boost::filesystem::directory_iterator end_iterator; - for (boost::filesystem::directory_iterator iter(root); iter != end_iterator; iter++) { - if (boost::filesystem::is_directory(*iter)) { - paths_in_root.push_back(iter->path().string()); - } - } - - std::sort(paths_in_root.begin(), paths_in_root.end()); - std::vector paths_in_alfanum_order; - - std::cout << "Paths will be scanned for keyword definitions in the following order, ignoring repeats:" << std::endl; - for (auto it = paths_in_root.begin(); it != paths_in_root.end(); ++it) { - std::cerr << "-- " << *it << std::endl; - paths_in_alfanum_order.push_back(boost::filesystem::path(*it)); - } - - return paths_in_alfanum_order; -} - -int main(int /* argc */, char ** argv) { - const char * config_root = argv[1]; - const char * source_file_name = argv[2]; - const char * test_file_name = argv[3]; - const char * signature_file_name = argv[4]; - - if (!argv[1]) { - printUsage(); - return 0; - } - KeywordMapType keywordMap; - - bool needToGenerate = false; - - std::stringstream signature_stream; - - ensurePath( source_file_name ); - ensurePath( test_file_name ); - ensurePath( signature_file_name ); - - std::vector paths_in_alfanum_order = getPathsInAlfanumOrder(config_root); - - for (auto it = paths_in_alfanum_order.begin(); it != paths_in_alfanum_order.end(); ++it) { - scanAllKeywords( *it , keywordMap ); - } - - generateKeywordSignature(signature_stream , keywordMap); - - if (!boost::filesystem::exists(path(source_file_name))) - needToGenerate = true; - - if (!boost::filesystem::exists(path(test_file_name))) - needToGenerate = true; - - if (!needToGenerate) { - if (boost::filesystem::exists(path(signature_file_name))) { - std::fstream signature_stream_on_disk(signature_file_name , std::fstream::in); - needToGenerate = !areStreamsEqual(signature_stream, signature_stream_on_disk); - signature_stream_on_disk.close(); - } else - needToGenerate = true; - } - - if (needToGenerate) { - std::cout << "Generating keywords:" << std::endl; - generateKeywordSource(source_file_name, keywordMap ); - generateKeywordTest(test_file_name, keywordMap ); - { - std::fstream signature_stream_on_disk(signature_file_name , std::fstream::out); - signature_stream.seekg(std::ios_base::beg); - signature_stream_on_disk << signature_stream.rdbuf(); - signature_stream_on_disk.close(); - } - } - else { - std::cout << "No keyword changes detected." << std::endl; - } - return 0; -} diff --git a/opm/parser/eclipse/Parser/tests/CMakeLists.txt b/opm/parser/eclipse/Parser/tests/CMakeLists.txt index 2e53513eb..b667ac31a 100644 --- a/opm/parser/eclipse/Parser/tests/CMakeLists.txt +++ b/opm/parser/eclipse/Parser/tests/CMakeLists.txt @@ -5,11 +5,6 @@ foreach(tapp ParserTests ParserKeywordTests ParserRecordTests endforeach() set_property(SOURCE ParserRecordTests.cpp PROPERTY COMPILE_FLAGS "-Wno-error") -set_source_files_properties( ${PROJECT_BINARY_DIR}/generated-source/inlineKeywordTest.cpp PROPERTIES GENERATED TRUE) - -opm_add_test( runInlineKeywordTest SOURCES ${PROJECT_BINARY_DIR}/generated-source/inlineKeywordTest.cpp - LIBRARIES opmparser ${Boost_LIBRARIES} - DEPENDS generatedCode ) diff --git a/opm/parser/eclipse/Parser/tests/ParserKeywordTests.cpp b/opm/parser/eclipse/Parser/tests/ParserKeywordTests.cpp index eb226eba3..30bed7990 100644 --- a/opm/parser/eclipse/Parser/tests/ParserKeywordTests.cpp +++ b/opm/parser/eclipse/Parser/tests/ParserKeywordTests.cpp @@ -31,33 +31,58 @@ using namespace Opm; + +std::shared_ptr createFixedSized(const std::string& kw , size_t size) { + std::shared_ptr pkw = std::make_shared(kw); + pkw->setFixedSize( size ); + return pkw; +} + +std::shared_ptr createDynamicSized(const std::string& kw) { + std::shared_ptr pkw = std::make_shared(kw); + pkw->setSizeType(SLASH_TERMINATED); + return pkw; +} + + +std::shared_ptr createTable(const std::string& name, + const std::string& sizeKeyword, + const std::string& sizeItem, + bool isTableCollection) { + std::shared_ptr pkw = std::make_shared(name); + pkw->initSizeKeyword(sizeKeyword , sizeItem); + pkw->setTableCollection(isTableCollection); + return pkw; +} + + BOOST_AUTO_TEST_CASE(construct_withname_nameSet) { - ParserKeywordConstPtr parserKeyword = ParserKeyword::createDynamicSized("BPR"); + ParserKeywordConstPtr parserKeyword = createDynamicSized("BPR"); BOOST_CHECK_EQUAL(parserKeyword->getName(), "BPR"); } BOOST_AUTO_TEST_CASE(NamedInit) { std::string keyword("KEYWORD"); - ParserKeywordConstPtr parserKeyword = ParserKeyword::createFixedSized(keyword, (size_t) 100); + ParserKeywordConstPtr parserKeyword = createFixedSized(keyword, (size_t) 100); BOOST_CHECK_EQUAL(parserKeyword->getName(), keyword); } BOOST_AUTO_TEST_CASE(ParserKeyword_default_SizeTypedefault) { std::string keyword("KEYWORD"); - ParserKeywordConstPtr parserKeyword = ParserKeyword::createDynamicSized(keyword); + ParserKeywordConstPtr parserKeyword = createDynamicSized(keyword); BOOST_CHECK_EQUAL(parserKeyword->getSizeType() , SLASH_TERMINATED); } BOOST_AUTO_TEST_CASE(ParserKeyword_withSize_SizeTypeFIXED) { std::string keyword("KEYWORD"); - ParserKeywordConstPtr parserKeyword = ParserKeyword::createFixedSized(keyword, (size_t) 100); + ParserKeywordConstPtr parserKeyword = createFixedSized(keyword, (size_t) 100); BOOST_CHECK_EQUAL(parserKeyword->getSizeType() , FIXED); } BOOST_AUTO_TEST_CASE(ParserKeyword_withOtherSize_SizeTypeOTHER) { std::string keyword("KEYWORD"); - ParserKeywordConstPtr parserKeyword = ParserKeyword::createTable(keyword, "EQUILDIMS" , "NTEQUIL"); + ParserKeywordConstPtr parserKeyword = createTable(keyword, "EQUILDIMS" , "NTEQUIL" , false); const std::pair& sizeKW = parserKeyword->getSizeDefinitionPair(); BOOST_CHECK_EQUAL(OTHER_KEYWORD_IN_DECK , parserKeyword->getSizeType() ); BOOST_CHECK_EQUAL("EQUILDIMS", sizeKW.first ); @@ -101,7 +126,7 @@ BOOST_AUTO_TEST_CASE(ParserKeyword_validInternalName) { } BOOST_AUTO_TEST_CASE(ParserKeywordMatches) { - ParserKeywordPtr parserKeyword = ParserKeyword::createFixedSized("HELLO", (size_t) 1); + ParserKeywordPtr parserKeyword = createFixedSized("HELLO", (size_t) 1); parserKeyword->clearDeckNames(); parserKeyword->setMatchRegex("WORLD.+"); BOOST_CHECK_EQUAL( false , parserKeyword->matches("HELLO")); @@ -112,7 +137,7 @@ BOOST_AUTO_TEST_CASE(ParserKeywordMatches) { } BOOST_AUTO_TEST_CASE(AddDataKeyword_correctlyConfigured) { - ParserKeywordPtr parserKeyword = ParserKeyword::createFixedSized("PORO", (size_t) 1); + ParserKeywordPtr parserKeyword = createFixedSized("PORO", (size_t) 1); ParserIntItemConstPtr item = ParserIntItemConstPtr(new ParserIntItem( "ACTNUM" , ALL)); std::shared_ptr record = std::make_shared(); @@ -127,7 +152,7 @@ BOOST_AUTO_TEST_CASE(AddDataKeyword_correctlyConfigured) { } BOOST_AUTO_TEST_CASE(WrongConstructor_addDataItem_throws) { - ParserKeywordPtr parserKeyword = ParserKeyword::createDynamicSized("PORO"); + ParserKeywordPtr parserKeyword = createDynamicSized("PORO"); ParserIntItemConstPtr dataItem = ParserIntItemConstPtr(new ParserIntItem( "ACTNUM" , ALL )); std::shared_ptr record = std::make_shared(); record->addDataItem( dataItem ); @@ -136,7 +161,7 @@ BOOST_AUTO_TEST_CASE(WrongConstructor_addDataItem_throws) { BOOST_AUTO_TEST_CASE(DefaultConstructur_setDescription_canReadBack) { - ParserKeywordPtr parserKeyword = ParserKeyword::createDynamicSized("BPR"); + ParserKeywordPtr parserKeyword = createDynamicSized("BPR"); std::string description("This is the description"); parserKeyword->setDescription(description); BOOST_CHECK_EQUAL( description, parserKeyword->getDescription()); @@ -146,7 +171,7 @@ BOOST_AUTO_TEST_CASE(DefaultConstructur_setDescription_canReadBack) { /* json */ BOOST_AUTO_TEST_CASE(ConstructFromJsonObject) { Json::JsonObject jsonObject("{\"name\": \"XXX\", \"sections\":[], \"size\" : 0}"); - ParserKeywordConstPtr parserKeyword = ParserKeyword::createFromJson(jsonObject); + ParserKeywordConstPtr parserKeyword = std::make_shared(jsonObject); BOOST_CHECK_EQUAL("XXX" , parserKeyword->getName()); BOOST_CHECK_EQUAL( true , parserKeyword->hasFixedSize() ); } @@ -164,7 +189,7 @@ BOOST_AUTO_TEST_CASE(ConstructMultiNameFromJsonObject) { " ]" "}"; Json::JsonObject jsonObject(jsonString); - auto parserKeyword = ParserKeyword::createFromJson(jsonObject); + auto parserKeyword = std::make_shared(jsonObject); BOOST_CHECK_EQUAL("XXX" , parserKeyword->getName()); BOOST_CHECK(parserKeyword->matches("XXA")); BOOST_CHECK(parserKeyword->matches("XXB")); @@ -177,7 +202,7 @@ BOOST_AUTO_TEST_CASE(ConstructMultiNameFromJsonObject) { BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_withSize) { Json::JsonObject jsonObject("{\"name\": \"BPR\", \"sections\":[\"SUMMARY\"], \"size\" : 100 , \"items\" :[{\"name\":\"ItemX\" , \"size_type\":\"SINGLE\" , \"value_type\" : \"DOUBLE\"}]}"); - ParserKeywordConstPtr parserKeyword = ParserKeyword::createFromJson(jsonObject); + ParserKeywordConstPtr parserKeyword = std::make_shared(jsonObject); BOOST_CHECK_EQUAL("BPR" , parserKeyword->getName()); BOOST_CHECK_EQUAL( true , parserKeyword->hasFixedSize() ); BOOST_CHECK_EQUAL( 100U , parserKeyword->getFixedSize() ); @@ -187,20 +212,20 @@ BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_withSize) { BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_missingItemThrows) { Json::JsonObject jsonObject("{\"name\": \"BPR\", \"sections\":[\"SUMMARY\"], \"size\" : 100}"); - BOOST_CHECK_THROW( ParserKeyword::createFromJson(jsonObject) , std::invalid_argument); + BOOST_CHECK_THROW( std::make_shared(jsonObject) , std::invalid_argument); } BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_nosize_notItems_OK) { Json::JsonObject jsonObject("{\"name\": \"BPR\", \"sections\":[\"SUMMARY\"]}"); - ParserKeywordConstPtr parserKeyword = ParserKeyword::createFromJson(jsonObject); + ParserKeywordConstPtr parserKeyword = std::make_shared(jsonObject); BOOST_CHECK_EQUAL( true , parserKeyword->hasFixedSize() ); BOOST_CHECK_EQUAL( 0U , parserKeyword->getFixedSize()); } BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_withSizeOther) { Json::JsonObject jsonObject("{\"name\": \"BPR\", \"sections\":[\"SUMMARY\"], \"size\" : {\"keyword\" : \"Bjarne\" , \"item\": \"BjarneIgjen\"}, \"items\" :[{\"name\":\"ItemX\" , \"value_type\" : \"DOUBLE\"}]}"); - ParserKeywordConstPtr parserKeyword = ParserKeyword::createFromJson(jsonObject); + ParserKeywordConstPtr parserKeyword = std::make_shared(jsonObject); const std::pair& sizeKW = parserKeyword->getSizeDefinitionPair(); BOOST_CHECK_EQUAL("BPR" , parserKeyword->getName()); BOOST_CHECK_EQUAL( false , parserKeyword->hasFixedSize() ); @@ -211,7 +236,7 @@ BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_withSizeOther) { BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_missingName_throws) { Json::JsonObject jsonObject("{\"nameXX\": \"BPR\", \"sections\":[\"SUMMARY\"], \"size\" : 100}"); - BOOST_CHECK_THROW(ParserKeyword::createFromJson(jsonObject) , std::invalid_argument); + BOOST_CHECK_THROW(std::make_shared(jsonObject) , std::invalid_argument); } /* @@ -219,30 +244,30 @@ BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_missingName_throws) { */ BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_invalidItems_throws) { Json::JsonObject jsonObject("{\"name\": \"BPR\", \"sections\":[\"SUMMARY\"], \"size\" : 100 , \"items\" : 100}"); - BOOST_CHECK_THROW(ParserKeyword::createFromJson(jsonObject) , std::invalid_argument); + BOOST_CHECK_THROW(std::make_shared(jsonObject) , std::invalid_argument); } BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_ItemMissingName_throws) { Json::JsonObject jsonObject("{\"name\": \"BPR\", \"sections\":[\"SUMMARY\"], \"size\" : 100 , \"items\" : [{\"nameX\" : \"I\" , \"value_type\" : \"INT\"}]}"); - BOOST_CHECK_THROW(ParserKeyword::createFromJson(jsonObject) , std::invalid_argument); + BOOST_CHECK_THROW(std::make_shared(jsonObject) , std::invalid_argument); } BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_ItemMissingValueType_throws) { Json::JsonObject jsonObject("{\"name\": \"BPR\", \"sections\":[\"SUMMARY\"], \"size\" : 100 , \"items\" : [{\"name\" : \"I\" , \"size_type\" : \"SINGLE\" , \"Xvalue_type\" : \"INT\"}]}"); - BOOST_CHECK_THROW(ParserKeyword::createFromJson(jsonObject) , std::invalid_argument); + BOOST_CHECK_THROW(std::make_shared(jsonObject) , std::invalid_argument); } BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_ItemInvalidEnum_throws) { Json::JsonObject jsonObject1("{\"name\": \"BPR\", \"sections\":[\"SUMMARY\"], \"size\" : 100 , \"items\" : [{\"name\" : \"I\" , \"size_type\" : \"XSINGLE\" , \"value_type\" : \"INT\"}]}"); Json::JsonObject jsonObject2("{\"name\": \"BPR\", \"sections\":[\"SUMMARY\"], \"size\" : 100 , \"items\" : [{\"name\" : \"I\" , \"size_type\" : \"SINGLE\" , \"value_type\" : \"INTX\"}]}"); - BOOST_CHECK_THROW(ParserKeyword::createFromJson(jsonObject1) , std::invalid_argument); - BOOST_CHECK_THROW(ParserKeyword::createFromJson(jsonObject2) , std::invalid_argument); + BOOST_CHECK_THROW(std::make_shared(jsonObject1) , std::invalid_argument); + BOOST_CHECK_THROW(std::make_shared(jsonObject2) , std::invalid_argument); } BOOST_AUTO_TEST_CASE(ConstructFromJsonObjectItemsOK) { Json::JsonObject jsonObject("{\"name\": \"BPR\", \"sections\":[\"SUMMARY\"], \"size\" : 100 , \"items\" : [{\"name\" : \"I\", \"value_type\" : \"INT\"}]}"); - ParserKeywordConstPtr parserKeyword = ParserKeyword::createFromJson(jsonObject); + ParserKeywordConstPtr parserKeyword = std::make_shared(jsonObject); ParserRecordConstPtr record = parserKeyword->getRecord(0); ParserItemConstPtr item = record->get( 0 ); BOOST_CHECK_EQUAL( 1U , record->size( ) ); @@ -252,23 +277,23 @@ BOOST_AUTO_TEST_CASE(ConstructFromJsonObjectItemsOK) { BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_sizeFromOther) { Json::JsonObject jsonConfig("{\"name\": \"EQUILX\", \"sections\":[\"PROPS\"], \"size\" : {\"keyword\":\"EQLDIMS\" , \"item\" : \"NTEQUL\"}, \"items\" :[{\"name\":\"ItemX\" ,\"value_type\" : \"DOUBLE\"}]}"); - BOOST_CHECK_NO_THROW( ParserKeyword::createFromJson(jsonConfig) ); + BOOST_CHECK_NO_THROW( std::make_shared(jsonConfig) ); } BOOST_AUTO_TEST_CASE(Default_NotData) { - ParserKeywordConstPtr parserKeyword = ParserKeyword::createDynamicSized("BPR"); + ParserKeywordConstPtr parserKeyword = createDynamicSized("BPR"); BOOST_CHECK_EQUAL( false , parserKeyword->isDataKeyword()); } BOOST_AUTO_TEST_CASE(AddDataKeywordFromJson_defaultThrows) { Json::JsonObject jsonConfig("{\"name\": \"ACTNUM\", \"sections\":[\"GRID\"], \"data\" : {\"value_type\": \"INT\" , \"default\" : 100}}"); - BOOST_CHECK_THROW( ParserKeyword::createFromJson(jsonConfig) , std::invalid_argument); + BOOST_CHECK_THROW( std::make_shared(jsonConfig) , std::invalid_argument); } BOOST_AUTO_TEST_CASE(AddDataKeywordFromJson_correctlyConfigured) { Json::JsonObject jsonConfig("{\"name\": \"ACTNUM\", \"sections\":[\"GRID\"], \"data\" : {\"value_type\": \"INT\"}}"); - ParserKeywordConstPtr parserKeyword = ParserKeyword::createFromJson(jsonConfig); + ParserKeywordConstPtr parserKeyword = std::make_shared(jsonConfig); ParserRecordConstPtr parserRecord = parserKeyword->getRecord(0); ParserItemConstPtr item = parserRecord->get(0); @@ -284,12 +309,12 @@ BOOST_AUTO_TEST_CASE(AddDataKeywordFromJson_correctlyConfigured) { BOOST_AUTO_TEST_CASE(AddkeywordFromJson_numTables_incoorect_throw) { Json::JsonObject jsonConfig("{\"name\": \"PVTG\", \"sections\":[\"PROPS\"], \"num_tables\" : 100}"); - BOOST_CHECK_THROW(ParserKeyword::createFromJson(jsonConfig) , std::invalid_argument); + BOOST_CHECK_THROW(std::make_shared(jsonConfig) , std::invalid_argument); } BOOST_AUTO_TEST_CASE(AddkeywordFromJson_isTableCollection) { Json::JsonObject jsonConfig("{\"name\": \"PVTG\", \"sections\":[\"PROPS\"], \"num_tables\" : {\"keyword\": \"TABDIMS\" , \"item\" : \"NTPVT\"} , \"items\" : [{\"name\" : \"data\", \"value_type\" : \"DOUBLE\"}]}"); - ParserKeywordConstPtr parserKeyword = ParserKeyword::createFromJson(jsonConfig); + ParserKeywordConstPtr parserKeyword = std::make_shared(jsonConfig); ParserRecordConstPtr parserRecord = parserKeyword->getRecord(0); @@ -302,28 +327,27 @@ BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_InvalidSize_throws) { Json::JsonObject jsonObject1("{\"name\": \"BPR\", \"sections\":[\"SUMMARY\"], \"size\" : \"string\" , \"items\" : [{\"name\" : \"I\" , \"size_type\" : \"SINGLE\" , \"value_type\" : \"INT\"}]}"); Json::JsonObject jsonObject2("{\"name\": \"BPR\", \"sections\":[\"SUMMARY\"], \"size\" : [1,2,3] , \"items\" : [{\"name\" : \"I\" , \"size_type\" : \"SINGLE\" , \"value_type\" : \"INT\"}]}"); - BOOST_CHECK_THROW(ParserKeyword::createFromJson(jsonObject1) , std::invalid_argument); - BOOST_CHECK_THROW(ParserKeyword::createFromJson(jsonObject2) , std::invalid_argument); - + BOOST_CHECK_THROW(std::make_shared(jsonObject1) , std::invalid_argument); + BOOST_CHECK_THROW(std::make_shared(jsonObject2) , std::invalid_argument); } BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_SizeUNKNOWN_OK) { Json::JsonObject jsonObject1("{\"name\": \"BPR\", \"sections\":[\"SUMMARY\"], \"size\" : \"UNKNOWN\" , \"items\" : [{\"name\" : \"I\" , \"size_type\" : \"SINGLE\" , \"value_type\" : \"INT\"}]}"); - ParserKeywordConstPtr parserKeyword = ParserKeyword::createFromJson(jsonObject1); + ParserKeywordConstPtr parserKeyword = std::make_shared(jsonObject1); BOOST_CHECK_EQUAL( UNKNOWN , parserKeyword->getSizeType() ); } BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_WithDescription_DescriptionPropertyShouldBePopulated) { Json::JsonObject jsonObject("{\"name\": \"BPR\", \"sections\":[\"SUMMARY\"], \"description\" : \"Description\"}"); - ParserKeywordConstPtr parserKeyword = ParserKeyword::createFromJson(jsonObject); + ParserKeywordConstPtr parserKeyword = std::make_shared(jsonObject); BOOST_CHECK_EQUAL( "Description", parserKeyword->getDescription() ); } BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_WithoutDescription_DescriptionPropertyShouldBeEmpty) { Json::JsonObject jsonObject("{\"name\": \"BPR\", \"sections\":[\"SUMMARY\"]}"); - ParserKeywordConstPtr parserKeyword = ParserKeyword::createFromJson(jsonObject); + ParserKeywordConstPtr parserKeyword = std::make_shared(jsonObject); BOOST_CHECK_EQUAL( "", parserKeyword->getDescription() ); } @@ -331,35 +355,35 @@ BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_WithoutDescription_DescriptionPrope /* */ /*****************************************************************/ BOOST_AUTO_TEST_CASE(getFixedSize_sizeObjectHasFixedSize_sizeReturned) { - ParserKeywordPtr parserKeyword = ParserKeyword::createFixedSized("JA", (size_t) 3); + ParserKeywordPtr parserKeyword = createFixedSized("JA", (size_t) 3); BOOST_CHECK_EQUAL(3U, parserKeyword->getFixedSize()); } BOOST_AUTO_TEST_CASE(getFixedSize_sizeObjectDoesNotHaveFixedSizeObjectSet_ExceptionThrown) { - ParserKeywordPtr parserKeyword = ParserKeyword::createDynamicSized("JA"); + ParserKeywordPtr parserKeyword = createDynamicSized("JA"); BOOST_CHECK_THROW(parserKeyword->getFixedSize(), std::logic_error); } BOOST_AUTO_TEST_CASE(hasFixedSize_hasFixedSizeObject_returnstrue) { - ParserKeywordPtr parserKeyword = ParserKeyword::createFixedSized("JA", (size_t) 2); + ParserKeywordPtr parserKeyword = createFixedSized("JA", (size_t) 2); BOOST_CHECK(parserKeyword->hasFixedSize()); } BOOST_AUTO_TEST_CASE(hasFixedSize_sizeObjectDoesNotHaveFixedSize_returnsfalse) { - ParserKeywordPtr parserKeyword = ParserKeyword::createDynamicSized("JA"); + ParserKeywordPtr parserKeyword = createDynamicSized("JA"); BOOST_CHECK(!parserKeyword->hasFixedSize()); } /******/ /* Tables: */ BOOST_AUTO_TEST_CASE(DefaultIsNot_TableKeyword) { - ParserKeywordPtr parserKeyword = ParserKeyword::createDynamicSized("JA"); + ParserKeywordPtr parserKeyword = createDynamicSized("JA"); BOOST_CHECK(!parserKeyword->isTableCollection()); } BOOST_AUTO_TEST_CASE(ConstructorIsTableCollection) { - ParserKeywordPtr parserKeyword = ParserKeyword::createTable("JA" , "TABDIMS" , "NTPVT" , true); + ParserKeywordPtr parserKeyword = createTable("JA" , "TABDIMS" , "NTPVT" , true); const std::pair& sizeKW = parserKeyword->getSizeDefinitionPair(); BOOST_CHECK(parserKeyword->isTableCollection()); BOOST_CHECK(!parserKeyword->hasFixedSize()); @@ -370,7 +394,7 @@ BOOST_AUTO_TEST_CASE(ConstructorIsTableCollection) { } BOOST_AUTO_TEST_CASE(ParseEmptyRecord) { - ParserKeywordPtr tabdimsKeyword = ParserKeyword::createFixedSized("TEST" , 1); + ParserKeywordPtr tabdimsKeyword = createFixedSized("TEST" , 1); std::shared_ptr record = std::make_shared(); ParserIntItemConstPtr item(new ParserIntItem(std::string("ITEM") , ALL)); RawKeywordPtr rawkeyword(new RawKeyword( tabdimsKeyword->getName() , "FILE" , 10U , 1)); @@ -395,7 +419,7 @@ BOOST_AUTO_TEST_CASE(ParseEmptyRecord) { /*****************************************************************/ /* Dimension */ BOOST_AUTO_TEST_CASE(ParseKeywordHasDimensionCorrect) { - ParserKeywordPtr parserKeyword = ParserKeyword::createDynamicSized("JA"); + ParserKeywordPtr parserKeyword = createDynamicSized("JA"); ParserIntItemConstPtr itemI(new ParserIntItem("I", SINGLE)); ParserDoubleItemPtr item2(new ParserDoubleItem("ID", SINGLE)); std::shared_ptr record = std::make_shared(); @@ -415,7 +439,7 @@ BOOST_AUTO_TEST_CASE(ParseKeywordHasDimensionCorrect) { BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_withDimension) { Json::JsonObject jsonObject("{\"name\": \"BPR\", \"sections\":[\"SUMMARY\"], \"size\" : 100 , \"items\" :[{\"name\":\"ItemX\" , \"size_type\":\"SINGLE\" , \"value_type\" : \"DOUBLE\" , \"dimension\" : \"Length*Length/Time\"}]}"); - ParserKeywordPtr parserKeyword = ParserKeyword::createFromJson(jsonObject); + ParserKeywordPtr parserKeyword = std::make_shared(jsonObject); ParserRecordConstPtr record = parserKeyword->getRecord(0); ParserItemConstPtr item = record->get("ItemX"); @@ -431,7 +455,7 @@ BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_withDimension) { BOOST_AUTO_TEST_CASE(ConstructFromJsonObject_withDimensionList) { Json::JsonObject jsonObject("{\"name\": \"BPR\", \"sections\":[\"SUMMARY\"], \"size\" : 100 , \"items\" :[{\"name\":\"ItemX\" , \"size_type\":\"ALL\" , \"value_type\" : \"DOUBLE\" , \"dimension\" : [\"Length*Length/Time\" , \"Time\", \"1\"]}]}"); - ParserKeywordPtr parserKeyword = ParserKeyword::createFromJson(jsonObject); + ParserKeywordPtr parserKeyword = std::make_shared(jsonObject); ParserRecordConstPtr record = parserKeyword->getRecord(0); ParserItemConstPtr item = record->get("ItemX"); @@ -461,8 +485,8 @@ BOOST_AUTO_TEST_CASE(ConstructFromJson_withRecords) { Json::JsonObject jsonObject1( json_string1 ); Json::JsonObject jsonObject2( json_string2 ); - ParserKeywordPtr kw1 = ParserKeyword::createFromJson( jsonObject1 ); - ParserKeywordPtr kw2 = ParserKeyword::createFromJson( jsonObject2 ); + ParserKeywordPtr kw1 = std::make_shared( jsonObject1 ); + ParserKeywordPtr kw2 = std::make_shared( jsonObject2 ); BOOST_CHECK( kw1->equal( *kw2 )); @@ -475,7 +499,7 @@ BOOST_AUTO_TEST_CASE(ConstructFromJson_withRecords_and_items_throws) { "{\"name\" : \"fault\" , \"value_type\" : \"STRING\"}," "{\"name\" : \"factor\" , \"value_type\" : \"DOUBLE\"}]}"; Json::JsonObject jsonObject( json_string ); - BOOST_CHECK_THROW( ParserKeyword::createFromJson( jsonObject ) , std::invalid_argument); + BOOST_CHECK_THROW( std::make_shared( jsonObject ) , std::invalid_argument); } diff --git a/opm/parser/eclipse/Parser/tests/ParserTests.cpp b/opm/parser/eclipse/Parser/tests/ParserTests.cpp index abe9f1ad2..00be35545 100644 --- a/opm/parser/eclipse/Parser/tests/ParserTests.cpp +++ b/opm/parser/eclipse/Parser/tests/ParserTests.cpp @@ -34,6 +34,13 @@ using namespace Opm; +std::shared_ptr createDynamicSized(const std::string& kw) { + std::shared_ptr pkw = std::make_shared(kw); + pkw->setSizeType(SLASH_TERMINATED); + return pkw; +} + + /************************Basic structural tests**********************'*/ BOOST_AUTO_TEST_CASE(Initializing) { @@ -46,7 +53,7 @@ BOOST_AUTO_TEST_CASE(Initializing) { BOOST_AUTO_TEST_CASE(addKeyword_keyword_doesntfail) { Parser parser; { - ParserKeywordPtr equilKeyword = ParserKeyword::createDynamicSized("EQUIL"); + ParserKeywordPtr equilKeyword = createDynamicSized("EQUIL"); parser.addParserKeyword(equilKeyword); } } @@ -54,21 +61,21 @@ BOOST_AUTO_TEST_CASE(addKeyword_keyword_doesntfail) { BOOST_AUTO_TEST_CASE(canParseDeckKeyword_returnstrue) { ParserPtr parser(new Parser()); - parser->addParserKeyword(ParserKeyword::createDynamicSized("FJAS")); + parser->addParserKeyword(createDynamicSized("FJAS")); BOOST_CHECK(parser->isRecognizedKeyword("FJAS")); } BOOST_AUTO_TEST_CASE(getKeyword_haskeyword_returnskeyword) { ParserPtr parser(new Parser()); - ParserKeywordConstPtr parserKeyword = ParserKeyword::createDynamicSized("FJAS"); + ParserKeywordConstPtr parserKeyword = createDynamicSized("FJAS"); parser->addParserKeyword(parserKeyword); BOOST_CHECK_EQUAL(parserKeyword, parser->getParserKeywordFromDeckName("FJAS")); } BOOST_AUTO_TEST_CASE(getKeyword_hasnotkeyword_getKeywordThrowsException) { ParserPtr parser(new Parser()); - ParserKeywordConstPtr parserKeyword = ParserKeyword::createDynamicSized("FJAS"); + ParserKeywordConstPtr parserKeyword = createDynamicSized("FJAS"); parser->addParserKeyword(parserKeyword); BOOST_CHECK_THROW(parser->getParserKeywordFromDeckName("FJASS"), std::invalid_argument); } @@ -76,9 +83,9 @@ BOOST_AUTO_TEST_CASE(getKeyword_hasnotkeyword_getKeywordThrowsException) { BOOST_AUTO_TEST_CASE(getAllDeckNames_hasTwoKeywords_returnsCompleteList) { ParserPtr parser(new Parser(false)); std::cout << parser->getAllDeckNames().size() << std::endl; - ParserKeywordConstPtr firstParserKeyword = ParserKeyword::createDynamicSized("FJAS"); + ParserKeywordConstPtr firstParserKeyword = createDynamicSized("FJAS"); parser->addParserKeyword(firstParserKeyword); - ParserKeywordConstPtr secondParserKeyword = ParserKeyword::createDynamicSized("SAJF"); + ParserKeywordConstPtr secondParserKeyword = createDynamicSized("SAJF"); parser->addParserKeyword(secondParserKeyword); BOOST_CHECK_EQUAL(2U, parser->getAllDeckNames().size()); } @@ -96,7 +103,7 @@ BOOST_AUTO_TEST_CASE(getAllDeckNames_hasNoKeywords_returnsEmptyList) { BOOST_AUTO_TEST_CASE(addParserKeywordJSON_isRecognizedKeyword_returnstrue) { ParserPtr parser(new Parser()); Json::JsonObject jsonConfig("{\"name\": \"BPR\", \"sections\":[\"SUMMARY\"], \"size\" : 100 , \"items\" :[{\"name\":\"ItemX\" , \"size_type\":\"SINGLE\" , \"value_type\" : \"DOUBLE\"}]}"); - parser->addParserKeyword(ParserKeyword::createFromJson( jsonConfig )); + parser->addParserKeyword(std::make_shared( jsonConfig )); BOOST_CHECK(parser->isRecognizedKeyword("BPR")); } @@ -104,7 +111,7 @@ BOOST_AUTO_TEST_CASE(addParserKeywordJSON_isRecognizedKeyword_returnstrue) { BOOST_AUTO_TEST_CASE(addParserKeywordJSON_size_isObject_allGood) { ParserPtr parser(new Parser()); Json::JsonObject jsonConfig("{\"name\": \"EQUIXL\", \"sections\":[], \"size\" : {\"keyword\":\"EQLDIMS\" , \"item\" : \"NTEQUL\"}, \"items\" :[{\"name\":\"ItemX\" , \"size_type\":\"SINGLE\" , \"value_type\" : \"DOUBLE\"}]}"); - parser->addParserKeyword(ParserKeyword::createFromJson( jsonConfig )); + parser->addParserKeyword(std::make_shared( jsonConfig )); BOOST_CHECK(parser->isRecognizedKeyword("EQUIXL")); } @@ -292,7 +299,7 @@ BOOST_AUTO_TEST_CASE(WildCardTest) { /***************** Simple Int parsing ********************************/ static ParserKeywordPtr __attribute__((unused)) setupParserKeywordInt(std::string name, int numberOfItems) { - ParserKeywordPtr parserKeyword = ParserKeyword::createDynamicSized(name); + ParserKeywordPtr parserKeyword = createDynamicSized(name); ParserRecordPtr parserRecord = parserKeyword->getRecord(0); for (int i = 0; i < numberOfItems; i++) { diff --git a/testdata/parser/keyword-generator/PORO-invalid b/testdata/parser/keyword-generator/PORO-invalid new file mode 100644 index 000000000..43a104a8b --- /dev/null +++ b/testdata/parser/keyword-generator/PORO-invalid @@ -0,0 +1,3 @@ +{"name" : "PORO" , "sections" : ["GRID"], "data" : {"value_type" : "DOUBLE" , "default" : "XX" , "dimension":"1"}} + + diff --git a/testdata/parser/keyword-generator/PORO.json b/testdata/parser/keyword-generator/PORO.json new file mode 100644 index 000000000..04ce37c26 --- /dev/null +++ b/testdata/parser/keyword-generator/PORO.json @@ -0,0 +1,3 @@ +{"name" : "PORO" , "sections" : ["GRID"], "data" : {"value_type" : "DOUBLE" , "default" : 0 , "dimension":"1"}} + + diff --git a/testdata/parser/keyword-generator/invalid.json b/testdata/parser/keyword-generator/invalid.json new file mode 100644 index 000000000..d534dd9ad --- /dev/null +++ b/testdata/parser/keyword-generator/invalid.json @@ -0,0 +1,3 @@ +{"name" : "PORO" , "sections" : ["GRID"], "data" : {"value_type" : "DOUBLE" , "default" : 0 , "dimension":"1"} + + diff --git a/testdata/parser/keyword-generator/loader/001_ECLIPSE100/A/2ADDREG b/testdata/parser/keyword-generator/loader/001_ECLIPSE100/A/2ADDREG new file mode 100644 index 000000000..1554bd369 --- /dev/null +++ b/testdata/parser/keyword-generator/loader/001_ECLIPSE100/A/2ADDREG @@ -0,0 +1,5 @@ +{"name" : "ADDREG" , "sections" : ["GRID","EDIT","PROPS","REGIONS","SOLUTION"], + "items" : + [{"name" : "ARRAY" , "value_type" : "STRING" , "description" : "The 3D array we will update"}, + {"name" : "SHIFT" , "value_type" : "DOUBLE" , "description" : "The value we will multiply with" , "default" : 0} , + {"name" : "REGION_NAME" , "value_type" : "STRING" , "description" : "The name of the region we are interested in" , "default" : "M"}]} diff --git a/testdata/parser/keyword-generator/loader/001_ECLIPSE100/A/ACTNUM b/testdata/parser/keyword-generator/loader/001_ECLIPSE100/A/ACTNUM new file mode 100644 index 000000000..26e958921 --- /dev/null +++ b/testdata/parser/keyword-generator/loader/001_ECLIPSE100/A/ACTNUM @@ -0,0 +1 @@ +{"name" : "ACTNUM", "sections" : ["GRID"], "data" : {"value_type" : "INT" }} diff --git a/testdata/parser/keyword-generator/loader/001_ECLIPSE100/A/ADDREG b/testdata/parser/keyword-generator/loader/001_ECLIPSE100/A/ADDREG new file mode 100644 index 000000000..1554bd369 --- /dev/null +++ b/testdata/parser/keyword-generator/loader/001_ECLIPSE100/A/ADDREG @@ -0,0 +1,5 @@ +{"name" : "ADDREG" , "sections" : ["GRID","EDIT","PROPS","REGIONS","SOLUTION"], + "items" : + [{"name" : "ARRAY" , "value_type" : "STRING" , "description" : "The 3D array we will update"}, + {"name" : "SHIFT" , "value_type" : "DOUBLE" , "description" : "The value we will multiply with" , "default" : 0} , + {"name" : "REGION_NAME" , "value_type" : "STRING" , "description" : "The name of the region we are interested in" , "default" : "M"}]} diff --git a/testdata/parser/keyword-generator/loader/001_ECLIPSE100/B/BLOCK_PROBE b/testdata/parser/keyword-generator/loader/001_ECLIPSE100/B/BLOCK_PROBE new file mode 100644 index 000000000..ba00cb3ff --- /dev/null +++ b/testdata/parser/keyword-generator/loader/001_ECLIPSE100/B/BLOCK_PROBE @@ -0,0 +1,145 @@ +{ + "name" : "BLOCK_PROBE" , + "sections" : ["SUMMARY"], + + "comment": "E100 only", + "deck_names" : [ + "BOSAT", + "BSOIL", + "BOIP", + "BOIPL", + "BOIPG", + "BPPO", + "BVOIL", + "BOVIS", + "BDENO", + "BODEN", + "BFLOOI", + "BFLOOJ", + "BFLOOK", + "BVELOI", + "BVELOJ", + "BVELOK", + "BWSAT", + "BSWAT", + "BWIP", + "BPPW", + "BVWAT", + "BWVIS", + "BDENW", + "BWDEN", + "BFLOWI", + "BVELWJ", + "BVELWK", + "BVELWI", + "BVELWJ", + "BVELWK", + "BGSAT", + "BSGAS", + "BGIP", + "BGIPL", + "BGIPG", + "BPPG", + "BVGAS", + "BGVIS", + "BDENG", + "BGDEN", + "BFLOGI", + "BFLOGJ", + "BFLOGK", + "BVELGI", + "BVELGJ", + "BVELGK", + "BPR", + "BWPR", + "BGPR", + "BRS", + "BRV", + "BPBUB", + "BPDEW", + "BRSSAT", + "BRVSAT", + "BSTATE", + "BPPC", + "BOKR", + "BWKR", + "BGKR", + "BKRO", + "BKRG", + "BKRW", + "BWPC", + "BGPC", + "BGTRP", + "BGTPD", + "BGSHY", + "BGSTRP", + "BWSHY", + "BWSMA", + "BHD", + "BHDF", + "BPR_X", + "BHD_X", + "BHDF_X", + "BSCN_X", + "BCTRA_X", + "LBPR_X", + "LBHD_X", + "LBHDF_X", + "LBSCN_X", + "LBCTRA_X", + "BRPV", + "BOPV", + "BWPV", + "BGPV", + "BHPV", + "BRTM", + "BPORVMOD", + "BPERMMOD", + "BAPI", + "BSCN", + "BSIP", + "BEWV_SAL", + "BTCNFANI", + "BTCNFCAT", + "BTRADCAT", + "BTSADCAT", + "BESALSUR", + "BESALPLY", + "BTCNFHEA", + "BTIPTHEA", + "BCGC", + "BCSC", + "BTCNFFOA", + "BTCNMFOA", + "BTIPTFOA", + "BTADSFOA", + "BTDCYFOA", + "BTMOBFOA", + "BTHLFFOA", + "BGI", + "BSIP", + "BNSAT", + "BNIP", + "BNKR", + "BTCNFSUR", + "BTIPTSUR", + "BTADSUR", + "BTCASUR", + "BTSTSUR", + "BEWV_SUR", + "BTCNFALK", + "BTADSALK", + "BTSTMALK", + "BTSADALK", + "BTPADALK" + ], + + "comment":"Some keywords need to be suffixed by a tracer name...", + "deck_name_regex":"BU.+|BTIPF.+|BTIPS.+|BTCNF.+|BTCNS.+|BTCN[1-9][0-9]*.+|BTIPT.+|BTIPF.+|BTIPS.+|BTIP[1-9][0-9]*.+|BTADS.+|BTDCY", + + "items" : [ + {"name": "I" , "value_type" : "INT"}, + {"name": "J" , "value_type" : "INT"}, + {"name": "K" , "value_type" : "INT"} + ] +} diff --git a/testdata/parser/keyword-generator/loader/001_ECLIPSE100/B/BOX b/testdata/parser/keyword-generator/loader/001_ECLIPSE100/B/BOX new file mode 100644 index 000000000..13b0a2f5a --- /dev/null +++ b/testdata/parser/keyword-generator/loader/001_ECLIPSE100/B/BOX @@ -0,0 +1,7 @@ +{"name" : "BOX" , "sections" : ["GRID", "EDIT", "PROPS", "REGIONS", "SOLUTION", "SCHEDULE"], "size" : 1 , "items" : [ + {"name" : "I1" , "value_type" : "INT"}, + {"name" : "I2" , "value_type" : "INT"}, + {"name" : "J1" , "value_type" : "INT"}, + {"name" : "J2" , "value_type" : "INT"}, + {"name" : "K1" , "value_type" : "INT"}, + {"name" : "K2" , "value_type" : "INT"}]} \ No newline at end of file diff --git a/testdata/parser/keyword-generator/loader/002_ECLIPSE300/ADDREG b/testdata/parser/keyword-generator/loader/002_ECLIPSE300/ADDREG new file mode 100644 index 000000000..4cd4ad38f --- /dev/null +++ b/testdata/parser/keyword-generator/loader/002_ECLIPSE300/ADDREG @@ -0,0 +1,6 @@ +{"name" : "ADDREG" , "sections" : ["GRID","EDIT","PROPS","REGIONS","SOLUTION"], + "items" : + [{"name" : "ARRAY" , "value_type" : "STRING" , "description" : "The 3D array we will update"}, + {"name" : "SHIFT" , "value_type" : "DOUBLE" , "description" : "The value we will multiply with" , "default" : 0} , + {"name" : "REGION_NUMBER" , "value_type" : "INT" , "description" : "The region number we are interested in"} , + {"name" : "REGION_NAME" , "value_type" : "STRING" , "description" : "The name of the region we are interested in" , "default" : "M"}]} diff --git a/testdata/parser/keyword-generator/loader/002_ECLIPSE300/EQUIL b/testdata/parser/keyword-generator/loader/002_ECLIPSE300/EQUIL new file mode 100644 index 000000000..9f3ee5e3b --- /dev/null +++ b/testdata/parser/keyword-generator/loader/002_ECLIPSE300/EQUIL @@ -0,0 +1,13 @@ +{"name" : "EQUIL" , "sections" : ["SOLUTION"], "size" : {"keyword":"EQLDIMS" , "item":"NTEQUL"}, + "description": "The EQUIL item is used when equilibrationg the model. The item should consist of one record for each PVT region", + "items" : + [{"name" : "DATUM_DEPTH" , "value_type" : "DOUBLE" , "default" : 0.0 , "dimension" : "Length"}, + {"name" : "DATUM_PRESSURE" , "value_type" : "DOUBLE" , "dimension" : "Pressure"} , + {"name" : "OWC" , "value_type" : "DOUBLE" , "default" : 0.0 , "dimension" : "Length", + "description" : "The OWC item is depth of the OIL Water contact. This should ..."} , + {"name" : "PC_OWC" , "value_type" : "DOUBLE" , "default" : 0.0 , "dimension" : "Pressure"} , + {"name" : "GOC" , "value_type" : "DOUBLE" , "default" : 0.0 , "dimension" : "Length"} , + {"name" : "PC_GOC" , "value_type" : "DOUBLE" , "default" : 0.0 , "dimension" : "Pressure"} , + {"name" : "BLACK_OIL_INIT" , "value_type" : "INT" , "default" : 0} , + {"name" : "BLACK_OIL_INIT_WG" , "value_type" : "INT" , "default" : 0} , + {"name" : "OIP_INIT" , "value_type" : "INT" , "default" : -5 , "comment":"The default is a state variable"}]} diff --git a/testdata/parser/keyword-generator/loader/ZCORN b/testdata/parser/keyword-generator/loader/ZCORN new file mode 100644 index 000000000..523ae7792 --- /dev/null +++ b/testdata/parser/keyword-generator/loader/ZCORN @@ -0,0 +1 @@ +{"name" : "ZCORN", "sections" : ["GRID"], "data" : {"value_type" : "DOUBLE", "dimension" : "Length" }}