Merged data/ -> RawDeck/ source code reorganisation

This commit is contained in:
Joakim Hove
2013-04-03 09:27:55 +02:00
14 changed files with 136 additions and 84 deletions

4
.gitignore vendored
View File

@@ -1 +1,3 @@
*~
*~
gmon.out
log.log

View File

@@ -1,4 +1,4 @@
add_library(Parser data/RawDeck.cpp data/RawKeyword.cpp data/RawRecord.cpp Parser/Parser.cpp Parser/ParserRecordSize.cpp Parser/ParserKW.cpp)
add_library(Parser RawDeck/RawDeck.cpp RawDeck/RawKeyword.cpp RawDeck/RawRecord.cpp Parser/Parser.cpp Parser/ParserRecordSize.cpp Parser/ParserKW.cpp)
add_library(Logger Logger.cpp)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})

View File

@@ -31,6 +31,7 @@ namespace Opm {
static const int INFO;
static const int ERROR;
static void initLogger();
static void setLogLevel(int logLevel);
static void setPath(const std::string& path);
static void debug(const std::string& message);
@@ -41,7 +42,6 @@ namespace Opm {
static std::string m_logFile;
static std::ofstream m_logStream;
static int m_logLevel;
static void initLogger();
static void log(const std::string& message, std::string logLevel);
static void initLoggingConstants();
};

View File

@@ -24,6 +24,8 @@ namespace Opm {
}
RawDeckPtr Parser::parse(const std::string &path) {
Logger::initLogger();
Logger::setLogLevel(Logger::DEBUG);
Logger::info("Starting parsing of file: " + path);
RawDeckPtr rawDeck(new RawDeck());
rawDeck -> readDataIntoDeck(path);

View File

@@ -24,8 +24,8 @@
#include <boost/shared_ptr.hpp>
#include <opm/parser/eclipse/Logger.hpp>
#include <opm/parser/eclipse/data/RawKeyword.hpp>
#include <opm/parser/eclipse/data/RawDeck.hpp>
#include <opm/parser/eclipse/RawDeck/RawKeyword.hpp>
#include <opm/parser/eclipse/RawDeck/RawDeck.hpp>
namespace Opm {

View File

@@ -26,6 +26,11 @@ namespace Opm {
RawDeck::RawDeck() {
}
/*
* Iterate through list of RawKeywords in search for the specified string.
* O(n), not using map or hash because the keywords are not unique,
* and the order matters. Returns first matching keyword.
*/
RawKeywordPtr RawDeck::getKeyword(const std::string& keyword) {
for(std::list<RawKeywordPtr>::iterator it = m_keywords.begin(); it != m_keywords.end(); it++) {
if ((*it)->getKeyword() == keyword) {
@@ -35,6 +40,10 @@ namespace Opm {
return RawKeywordPtr(new RawKeyword());
}
/*
* Read data into deck, from specified path.
* Throws invalid_argument exception if path not valid.
*/
void RawDeck::readDataIntoDeck(const std::string& path) {
checkInputFile(path);
std::ifstream inputstream;
@@ -55,9 +64,9 @@ namespace Opm {
inputstream.close();
}
void RawDeck::addRawRecordStringToRawKeyword(const std::string& line, RawKeywordPtr currentRawKeyword) {
if (looksLikeData(line)) {
currentRawKeyword->addRawRecordString(line);
void RawDeck::addRawRecordStringToRawKeyword(const std::string& recordCandidate, RawKeywordPtr currentRawKeyword) {
if (looksLikeData(recordCandidate)) {
currentRawKeyword->addRawRecordString(recordCandidate);
}
}

View File

@@ -30,6 +30,33 @@ namespace Opm {
setKeyword(keyword);
}
bool RawKeyword::tryParseKeyword(const std::string& keywordCandidate, std::string& result) {
result = boost::trim_right_copy(keywordCandidate.substr(0, 8));
if (isValidKeyword(result)) {
Logger::debug("KEYWORD <" + keywordCandidate + ">");
return true;
}
return false;
}
bool RawKeyword::isValidKeyword(const std::string& keywordCandidate) {
std::string keywordRegex = "^[A-Z]{1,8}$";
int status;
regex_t re;
regmatch_t rm;
if (regcomp(&re, keywordRegex.c_str(), REG_EXTENDED) != 0) {
throw std::runtime_error("Unable to compile regular expression for keyword! Expression: " + keywordRegex);
}
status = regexec(&re, keywordCandidate.c_str(), 1, &rm, 0);
regfree(&re);
if (status == 0) {
return true;
}
return false;
}
void RawKeyword::setKeyword(const std::string& keyword) {
m_keyword = boost::algorithm::trim_right_copy(keyword);
if (!isValidKeyword(m_keyword)) {
@@ -62,33 +89,6 @@ namespace Opm {
return m_keyword;
}
bool RawKeyword::tryParseKeyword(const std::string& keywordCandidate, std::string& result) {
result = boost::trim_right_copy(keywordCandidate.substr(0, 8));
if (isValidKeyword(result)) {
Logger::debug("KEYWORD <" + keywordCandidate + ">");
return true;
}
return false;
}
bool RawKeyword::isValidKeyword(const std::string& keywordCandidate) {
std::string keywordRegex = "^[A-Z]{1,8}$";
int status;
regex_t re;
regmatch_t rm;
if (regcomp(&re, keywordRegex.c_str(), REG_EXTENDED) != 0) {
throw std::runtime_error("Unable to compile regular expression for keyword! Expression: " + keywordRegex);
}
status = regexec(&re, keywordCandidate.c_str(), 1, &rm, 0);
regfree(&re);
if (status == 0) {
return true;
}
return false;
}
RawKeyword::~RawKeyword() {
}
}

View File

@@ -26,6 +26,7 @@ using namespace std;
namespace Opm {
const char RawRecord::SLASH = '/';
const char RawRecord::QUOTE = '\'';
const std::string RawRecord::SEPARATORS = "\t ";
RawRecord::RawRecord() {
}
@@ -34,6 +35,10 @@ namespace Opm {
* It is assumed that after a record is terminated, there is no quote marks
* in the subsequent comment. This is in accordance with the Eclipse user
* manual.
*
* If a "non-complete" record string is supplied, an invalid_argument
* exception is thrown.
*
*/
RawRecord::RawRecord(const std::string& singleRecordString) {
if (isCompleteRecordString(singleRecordString)) {
@@ -43,36 +48,21 @@ namespace Opm {
" offending string: " + singleRecordString);
}
std::string tokenSeparators = "\t ";
std::string quoteSeparators = "\'\"";
splitSingleRecordString();
}
void RawRecord::splitSingleRecordString() {
char currentChar;
char tokenStarter;
char tokenStartCharacter;
std::string currentToken = "";
for (unsigned i = 0; i < m_sanitizedRecordString.size(); i++) {
currentChar = m_sanitizedRecordString[i];
if (stringContains(tokenSeparators, currentChar)) {
if (stringContains(quoteSeparators, tokenStarter)) {
currentToken += currentChar;
} else {
if (currentToken.size() > 0) {
m_recordItems.push_back(currentToken);
currentToken.clear();
}
tokenStarter = currentChar;
}
} else if (stringContains(quoteSeparators, currentChar)) {
if (currentChar == tokenStarter) {
if (currentToken.size() > 0) {
m_recordItems.push_back(currentToken);
currentToken.clear();
}
tokenStarter = '\0';
} else {
tokenStarter = currentChar;
currentToken.clear();
}
if (charIsSeparator(currentChar)) {
processSeparatorCharacter(currentToken, currentChar, tokenStartCharacter);
} else if (currentChar == QUOTE) {
processQuoteCharacters(currentToken, currentChar, tokenStartCharacter);
} else {
currentToken += currentChar;
processNonSpecialCharacters(currentToken, currentChar);
}
}
if (currentToken.size() > 0) {
@@ -80,9 +70,38 @@ namespace Opm {
currentToken.clear();
}
}
void RawRecord::processSeparatorCharacter(std::string& currentToken, const char& currentChar, char& tokenStartCharacter) {
if (tokenStartCharacter == QUOTE) {
currentToken += currentChar;
} else {
if (currentToken.size() > 0) {
m_recordItems.push_back(currentToken);
currentToken.clear();
}
tokenStartCharacter = currentChar;
}
}
bool RawRecord::stringContains(std::string collection, char candidate) {
return std::string::npos != collection.find(candidate);
void RawRecord::processQuoteCharacters(std::string& currentToken, const char& currentChar, char& tokenStartCharacter) {
if (currentChar == tokenStartCharacter) {
if (currentToken.size() > 0) {
m_recordItems.push_back(currentToken);
currentToken.clear();
}
tokenStartCharacter = '\0';
} else {
tokenStartCharacter = currentChar;
currentToken.clear();
}
}
void RawRecord::processNonSpecialCharacters(std::string& currentToken, const char& currentChar) {
currentToken += currentChar;
}
bool RawRecord::charIsSeparator(char candidate) {
return std::string::npos != SEPARATORS.find(candidate);
}
void RawRecord::getRecords(std::vector<std::string>& recordItems) {
@@ -95,7 +114,10 @@ namespace Opm {
bool RawRecord::isCompleteRecordString(const std::string& candidateRecordString) {
unsigned int terminatingSlash = findTerminatingSlash(candidateRecordString);
return (terminatingSlash < candidateRecordString.size());
bool hasTerminatingSlash = (terminatingSlash < candidateRecordString.size());
int size = std::count(candidateRecordString.begin(), candidateRecordString.end(), QUOTE);
bool hasEvenNumberOfQuotes = (size % 2) == 0;
return hasTerminatingSlash && hasEvenNumberOfQuotes;
}
void RawRecord::setRecordString(const std::string& singleRecordString) {

View File

@@ -18,6 +18,8 @@ namespace Opm {
public:
static const char SLASH;
static const char QUOTE;
static const std::string SEPARATORS;
RawRecord();
RawRecord(const std::string& singleRecordString);
void getRecordString(std::string& recordString);
@@ -28,7 +30,11 @@ namespace Opm {
std::string m_sanitizedRecordString;
std::vector<std::string> m_recordItems;
void setRecordString(const std::string& singleRecordString);
bool stringContains(std::string collection, char candidate);
void splitSingleRecordString();
void processSeparatorCharacter(std::string& currentToken, const char& currentChar, char& tokenStarter);
void processQuoteCharacters(std::string& currentToken, const char& currentChar, char& tokenStarter);
void processNonSpecialCharacters(std::string& currentToken, const char& currentChar);
bool charIsSeparator(char candidate);
static unsigned int findTerminatingSlash(const std::string& singleRecordString);
};
typedef boost::shared_ptr<RawRecord> RawRecordPtr;

View File

@@ -44,6 +44,3 @@ BOOST_AUTO_TEST_CASE(FixedSize) {
BOOST_REQUIRE_EQUAL( recordSize.recordSize() , (size_t) 100 );
}

View File

@@ -27,7 +27,7 @@
#include <boost/test/unit_test.hpp>
#include "opm/parser/eclipse/Parser/Parser.hpp"
#include "opm/parser/eclipse/data/RawDeck.hpp"
#include "opm/parser/eclipse/RawDeck/RawDeck.hpp"
using namespace Opm;
BOOST_AUTO_TEST_CASE(Initializing) {

View File

@@ -20,64 +20,78 @@
#define BOOST_TEST_MODULE ParserTests
#include <stdexcept>
#include <boost/test/unit_test.hpp>
#include <opm/parser/eclipse/data/RawKeyword.hpp>
#include <opm/parser/eclipse/data/RawRecord.hpp>
#include <opm/parser/eclipse/RawDeck/RawKeyword.hpp>
#include <opm/parser/eclipse/RawDeck/RawRecord.hpp>
BOOST_AUTO_TEST_CASE(EmptyConstructorEmptyKeyword) {
BOOST_AUTO_TEST_CASE(RawKeywordEmptyConstructorEmptyKeyword) {
Opm::RawKeyword keyword;
BOOST_CHECK(keyword.getKeyword() == "");
}
BOOST_AUTO_TEST_CASE(KeywordToConstructorKeywordSet) {
BOOST_AUTO_TEST_CASE(RawKeywordGiveKeywordToConstructorKeywordSet) {
Opm::RawKeyword keyword("KEYYWORD");
BOOST_CHECK(keyword.getKeyword() == "KEYYWORD");
}
BOOST_AUTO_TEST_CASE(KeywordToConstructorTooLongThrows) {
BOOST_AUTO_TEST_CASE(RawKeywordGiveKeywordToConstructorTooLongThrows) {
BOOST_CHECK_THROW(Opm::RawKeyword keyword("KEYYYWORD"), std::invalid_argument);
}
BOOST_AUTO_TEST_CASE(SetTooLongKeywordThrows) {
BOOST_AUTO_TEST_CASE(RawKeywordSetTooLongKeywordThrows) {
Opm::RawKeyword keyword;
BOOST_CHECK_THROW(keyword.setKeyword("TESTTOOLONG"), std::invalid_argument);
}
BOOST_AUTO_TEST_CASE(SetKeywordInitialWhitespaceInKeywordThrows) {
BOOST_AUTO_TEST_CASE(RawKeywordSetKeywordInitialWhitespaceInKeywordThrows) {
Opm::RawKeyword keyword;
BOOST_CHECK_THROW(keyword.setKeyword(" TELONG"), std::invalid_argument);
}
BOOST_AUTO_TEST_CASE(SetKeywordInitialTabInKeywordThrows) {
BOOST_AUTO_TEST_CASE(RawKeywordSetKeywordInitialTabInKeywordThrows) {
Opm::RawKeyword keyword;
BOOST_CHECK_THROW(keyword.setKeyword("\tTELONG"), std::invalid_argument);
}
BOOST_AUTO_TEST_CASE(SetCorrectLenghtKeywordNoError) {
BOOST_AUTO_TEST_CASE(RawKeywordSetCorrectLenghtKeywordNoError) {
Opm::RawKeyword keyword;
keyword.setKeyword("GOODONE");
BOOST_CHECK(keyword.getKeyword() == "GOODONE");
}
BOOST_AUTO_TEST_CASE(Set8CharKeywordWithTrailingWhitespaceKeywordTrimmed) {
BOOST_AUTO_TEST_CASE(RawKeywordSet8CharKeywordWithTrailingWhitespaceKeywordTrimmed) {
Opm::RawKeyword keyword;
keyword.setKeyword("GOODONEE ");
BOOST_CHECK(keyword.getKeyword() == "GOODONEE");
}
BOOST_AUTO_TEST_CASE(RawRecordSetRecordCheckCorrectTrimAndSplit) {
BOOST_AUTO_TEST_CASE(RawRecordGetRecordStringReturnsTrimmedString) {
Opm::RawRecordPtr record(new Opm::RawRecord(" 'NODIR ' 'REVERS' 1 20 /"));
std::string recordString;
record -> getRecordString(recordString);
BOOST_REQUIRE_EQUAL("'NODIR ' 'REVERS' 1 20", recordString);
}
BOOST_AUTO_TEST_CASE(RawRecordGetRecordsCorrectElementsReturned) {
Opm::RawRecordPtr record(new Opm::RawRecord(" 'NODIR ' 'REVERS' 1 20 /"));
std::vector<std::string> recordElements;
record -> getRecords(recordElements);
BOOST_REQUIRE_EQUAL((unsigned)4, recordElements.size());
BOOST_REQUIRE_EQUAL((unsigned) 4, recordElements.size());
BOOST_REQUIRE_EQUAL("NODIR ", recordElements[0]);
BOOST_REQUIRE_EQUAL("REVERS", recordElements[1]);
BOOST_REQUIRE_EQUAL("1", recordElements[2]);
BOOST_REQUIRE_EQUAL("20", recordElements[3]);
}
BOOST_AUTO_TEST_CASE(RawRecordIsCompleteRecordCompleteRecordReturnsTrue) {
bool isComplete = Opm::RawRecord::isCompleteRecordString("'NODIR ' 'REVERS' 1 20 /");
BOOST_REQUIRE_EQUAL(true, isComplete);
}
BOOST_AUTO_TEST_CASE(RawRecordIsCompleteRecordInCompleteRecordReturnsFalse) {
bool isComplete = Opm::RawRecord::isCompleteRecordString("'NODIR ' 'REVERS' 1 20 ");
BOOST_REQUIRE_EQUAL(false, isComplete);
isComplete = Opm::RawRecord::isCompleteRecordString("'NODIR ' 'REVERS 1 20 /");
BOOST_REQUIRE_EQUAL(false, isComplete);
}