Fixed handling of INCLUDE keyword

This commit is contained in:
Joakim Hove
2013-09-02 10:08:37 +02:00
parent 0580cebb33
commit 41376779f0
4 changed files with 153 additions and 20 deletions
@@ -12,6 +12,11 @@ target_link_libraries(runParseWCONHIST Parser ${Boost_LIBRARIES})
add_test(NAME runParseWCONHIST WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} COMMAND runParseWCONHIST)
add_executable(runIncludeTest IncludeTest.cpp)
target_link_libraries(runIncludeTest Parser ${Boost_LIBRARIES})
add_test(NAME runIncludeTest WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} COMMAND runIncludeTest)
add_executable(runParseEQUIL ParseEQUIL.cpp)
target_link_libraries(runParseEQUIL Parser ${Boost_LIBRARIES})
add_test(NAME runParseEQUIL
@@ -0,0 +1,117 @@
/*
Copyright 2013 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 <http://www.gnu.org/licenses/>.
*/
#define BOOST_TEST_MODULE ParserIntegrationTests
#include <boost/test/unit_test.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/filesystem.hpp>
#include <ostream>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Parser/ParserRecord.hpp>
#include <opm/parser/eclipse/Parser/ParserIntItem.hpp>
#include <opm/parser/eclipse/Parser/ParserStringItem.hpp>
#include <opm/parser/eclipse/Parser/ParserEnums.hpp>
using namespace Opm;
using namespace boost::filesystem;
void
createDeckWithInclude(path& datafile)
{
path root = unique_path("/tmp/%%%%-%%%%");
path absoluteInclude = root / "absolute.include";
path includePath = root / "include";
create_directories(root);
create_directories(includePath);
{
datafile = root / "TEST.DATA";
std::ofstream of(datafile.string().c_str());
of << "INCLUDE" << std::endl;
of << " \'relative.include\' /" << std::endl;
of << std::endl;
of << "INCLUDE" << std::endl;
of << " \'" << absoluteInclude.string() << "\' /" << std::endl;
of << std::endl;
of << "INCLUDE" << std::endl;
of << " \'include/nested.include\' /" << std::endl;
of.close();
}
{
std::ofstream of(absoluteInclude.string().c_str());
of << "DIMENS" << std::endl;
of << " 10 20 30 /" << std::endl;
of.close();
}
{
path relativeInclude = root / "relative.include";
std::ofstream of(relativeInclude.string().c_str());
of << "START" << std::endl;
of << " 10 'FEB' 2012 /" << std::endl;
of.close();
}
{
path nestedInclude = includePath / "nested.include";
path gridInclude = includePath / "grid.include";
std::ofstream of(nestedInclude.string().c_str());
of << "INCLUDE" << std::endl;
of << " \'include/grid.include\' /" << std::endl;
of.close();
std::ofstream of2(gridInclude.string().c_str());
of2 << "GRIDUNIT" << std::endl;
of2 << "/" << std::endl;
of2.close();
}
}
BOOST_AUTO_TEST_CASE(parse_fileWithWWCTKeyword_deckReturned) {
path datafile;
ParserPtr parser(new Parser());
parser->loadKeywordsFromDirectory(KEYWORD_DIRECTORY);
createDeckWithInclude (datafile);
DeckConstPtr deck = parser->parse(datafile.string());
BOOST_CHECK( deck->hasKeyword("DIMENS"));
BOOST_CHECK( deck->hasKeyword("START"));
BOOST_CHECK( deck->hasKeyword("GRIDUNIT"));
}
+30 -18
View File
@@ -39,12 +39,30 @@ namespace Opm {
return parse(dataFile, true);
}
DeckPtr Parser::parse(const std::string &dataFile, bool strictParsing) const {
/*
About INCLUDE: Observe that the ECLIPSE parser is slightly unlogical
when it comes to nested includes; the path to an included file is always
interpreted relative to the filesystem location of the DATA file, and
not the location of the file issuing the INCLUDE command. That behaviour
is retained in the current implementation.
*/
DeckPtr Parser::parse(const std::string &dataFileName, bool strictParsing) const {
DeckPtr deck(new Deck());
parseFile(deck, dataFile, strictParsing);
boost::filesystem::path dataFile(dataFileName);
boost::filesystem::path rootPath;
if (dataFile.is_absolute())
rootPath = dataFile.parent_path();
else
rootPath = boost::filesystem::current_path() / dataFile.parent_path();
parseFile(deck, dataFile, rootPath , strictParsing);
return deck;
}
size_t Parser::size() const {
return m_parserKeywords.size();
}
@@ -65,22 +83,25 @@ namespace Opm {
throw std::invalid_argument("Keyword: " + keyword + " does not exist");
}
void Parser::parseFile(DeckPtr deck, const std::string &file, bool parseStrict) const {
void Parser::parseFile(DeckPtr deck, const boost::filesystem::path& file, const boost::filesystem::path& rootPath, bool parseStrict) const {
std::ifstream inputstream;
inputstream.open(file.c_str());
inputstream.open(file.string().c_str());
if (inputstream) {
RawKeywordPtr rawKeyword;
while (tryParseKeyword(deck, inputstream, rawKeyword, parseStrict)) {
if (rawKeyword->getKeywordName() == Opm::RawConsts::include) {
boost::filesystem::path dataFolderPath = verifyValidInputPath(file);
RawRecordConstPtr firstRecord = rawKeyword->getRecord(0);
std::string includeFileString = firstRecord->getItem(0);
boost::filesystem::path pathToIncludedFile(dataFolderPath);
pathToIncludedFile /= includeFileString;
boost::filesystem::path includeFile(includeFileString);
parseFile(deck, pathToIncludedFile.string(), parseStrict);
if (includeFile.is_relative())
includeFile = rootPath / includeFile;
parseFile(deck, includeFile, rootPath , parseStrict);
} else {
if (hasKeyword(rawKeyword->getKeywordName())) {
ParserKeywordConstPtr parserKeyword = m_parserKeywords.at(rawKeyword->getKeywordName());
@@ -96,7 +117,7 @@ namespace Opm {
inputstream.close();
} else
throw std::invalid_argument("Failed to open file: " + file);
throw std::invalid_argument("Failed to open file: " + file.string());
}
void Parser::initializeFromJsonFile(const boost::filesystem::path& jsonFile) {
@@ -174,15 +195,6 @@ namespace Opm {
return false;
}
boost::filesystem::path Parser::verifyValidInputPath(const std::string& inputPath) const {
Logger::info("Verifying path: " + inputPath);
boost::filesystem::path pathToInputFile(inputPath);
if (!boost::filesystem::is_regular_file(pathToInputFile)) {
Logger::error("Unable to open file with path: " + inputPath);
throw std::invalid_argument("Given path is not a valid file-path, path: " + inputPath);
}
return pathToInputFile.parent_path();
}
bool Parser::loadKeywordFromFile(const boost::filesystem::path& configFile) {
+1 -2
View File
@@ -60,8 +60,7 @@ namespace Opm {
private:
std::map<std::string, ParserKeywordConstPtr> m_parserKeywords;
bool tryParseKeyword(const DeckConstPtr deck , std::ifstream& inputstream , RawKeywordPtr& rawKeyword, bool strictParsing) const;
void parseFile(DeckPtr deck , const std::string &file, bool strictParsing) const;
boost::filesystem::path verifyValidInputPath(const std::string& inputPath) const;
void parseFile(DeckPtr deck , const boost::filesystem::path& file, const boost::filesystem::path& rootPath, bool strictParsing) const;
void populateDefaultKeywords();
RawKeywordPtr createRawKeyword(const DeckConstPtr deck , const std::string& keywordString, bool strictParsing) const;