Reimplmented ParseMode based on string keys.
Completely reimplemented the ParseMode class. Now the main datastructure is a map<string,action> where the possible error situations are the keys. This approach allows for a much more flexible setting/filtering/querying of the ParseMode settings.
This commit is contained in:
@@ -179,15 +179,8 @@ namespace Opm {
|
|||||||
|
|
||||||
|
|
||||||
if (unsupportedModifiers.find( keyword->name() ) != unsupportedModifiers.end()) {
|
if (unsupportedModifiers.find( keyword->name() ) != unsupportedModifiers.end()) {
|
||||||
auto action = parseMode.unsupportedScheduleGeoModifiers;
|
|
||||||
|
|
||||||
if (action != InputError::IGNORE) {
|
|
||||||
std::string msg = "OPM does not support grid property modifier " + keyword->name() + " in the Schedule section. Error at report: " + std::to_string( currentStep );
|
std::string msg = "OPM does not support grid property modifier " + keyword->name() + " in the Schedule section. Error at report: " + std::to_string( currentStep );
|
||||||
if (action == InputError::THROW_EXCEPTION)
|
parseMode.handleError( ParseMode::UNSUPPORTED_SCHEDULE_GEO_MODIFIER , msg );
|
||||||
throw std::invalid_argument( msg );
|
|
||||||
else if (action == InputError::WARN)
|
|
||||||
OpmLog::addMessage(Log::MessageType::Warning , msg );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,16 +236,8 @@ namespace Opm {
|
|||||||
for (const auto record : (*compordKeyword)) {
|
for (const auto record : (*compordKeyword)) {
|
||||||
auto methodItem = record->getItem<ParserKeywords::COMPORD::ORDER_TYPE>();
|
auto methodItem = record->getItem<ParserKeywords::COMPORD::ORDER_TYPE>();
|
||||||
if (methodItem->getString(0) != "TRACK") {
|
if (methodItem->getString(0) != "TRACK") {
|
||||||
auto action = parseMode.unsupportedCOMPORDType;
|
std::string msg = "The COMPORD keyword only handles 'TRACK' order.";
|
||||||
if (action != InputError::IGNORE) {
|
parseMode.handleError( ParseMode::UNSUPPORTED_COMPORD_TYPE , msg );
|
||||||
std::string msg = "The COMPORD keyword only handles 'TRACK' order. [ParseMode::unsupportedCOMPORDType]";
|
|
||||||
|
|
||||||
if (action == InputError::THROW_EXCEPTION)
|
|
||||||
throw std::invalid_argument(msg);
|
|
||||||
else
|
|
||||||
OpmLog::addMessage(Log::MessageType::Warning , msg );
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,14 +104,8 @@ namespace Opm {
|
|||||||
m_thresholdPressureTable[r1 + maxEqlnum*r2] = p;
|
m_thresholdPressureTable[r1 + maxEqlnum*r2] = p;
|
||||||
m_thresholdPressureTable[r2 + maxEqlnum*r1] = p;
|
m_thresholdPressureTable[r2 + maxEqlnum*r1] = p;
|
||||||
} else {
|
} else {
|
||||||
auto action = parseMode.unsupportedInitialTHPRES;
|
std::string msg = "Inferring threshold pressure from the initial state is not supported.";
|
||||||
if (action != InputError::IGNORE) {
|
parseMode.handleError( ParseMode::UNSUPPORTED_INITIAL_THPRES , msg );
|
||||||
std::string msg = "Inferring threshold pressure from the initial state is not supported. [ParseMode::unsupportedInitialTHPRES]";
|
|
||||||
if (action == InputError::THROW_EXCEPTION)
|
|
||||||
throw std::invalid_argument( msg );
|
|
||||||
else
|
|
||||||
OpmLog::addMessage(Log::MessageType::Warning , msg );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
throw std::runtime_error("Missing region data for use of the THPRES keyword");
|
throw std::runtime_error("Missing region data for use of the THPRES keyword");
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ BOOST_AUTO_TEST_CASE(ThresholdPressureThrowTest) {
|
|||||||
BOOST_CHECK_THROW(std::make_shared<ThresholdPressure>(parseMode , deck, gridPropertiesEQLNUMall0), std::runtime_error);
|
BOOST_CHECK_THROW(std::make_shared<ThresholdPressure>(parseMode , deck, gridPropertiesEQLNUMall0), std::runtime_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
parseMode.unsupportedInitialTHPRES = InputError::IGNORE;
|
parseMode.update( ParseMode::UNSUPPORTED_INITIAL_THPRES , InputError::IGNORE );
|
||||||
BOOST_CHECK_NO_THROW(ThresholdPressure(parseMode,deck_missingPressure, gridProperties));
|
BOOST_CHECK_NO_THROW(ThresholdPressure(parseMode,deck_missingPressure, gridProperties));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ using namespace Opm;
|
|||||||
BOOST_AUTO_TEST_CASE( parse_EQUIL_MISSING_DIMS ) {
|
BOOST_AUTO_TEST_CASE( parse_EQUIL_MISSING_DIMS ) {
|
||||||
Parser parser;
|
Parser parser;
|
||||||
ParseMode parseMode;
|
ParseMode parseMode;
|
||||||
parseMode.missingDIMSKeyword = InputError::IGNORE;
|
parseMode.update(ParseMode::PARSE_MISSING_DIMS_KEYWORD, InputError::IGNORE);
|
||||||
const std::string equil = "EQUIL\n"
|
const std::string equil = "EQUIL\n"
|
||||||
"2469 382.4 1705.0 0.0 500 0.0 1 1 20 /";
|
"2469 382.4 1705.0 0.0 500 0.0 1 1 20 /";
|
||||||
std::shared_ptr<const Deck> deck = parser.parseString(equil, parseMode);
|
std::shared_ptr<const Deck> deck = parser.parseString(equil, parseMode);
|
||||||
|
|||||||
@@ -33,9 +33,10 @@ using namespace Opm;
|
|||||||
BOOST_AUTO_TEST_CASE( test_parse ) {
|
BOOST_AUTO_TEST_CASE( test_parse ) {
|
||||||
Parser parser(false);
|
Parser parser(false);
|
||||||
ParseMode parseMode;
|
ParseMode parseMode;
|
||||||
parseMode.unknownKeyword = InputError::IGNORE;
|
|
||||||
parseMode.randomText = InputError::IGNORE;
|
parseMode.update( ParseMode::PARSE_UNKNOWN_KEYWORD , InputError::IGNORE );
|
||||||
parseMode.randomSlash = InputError::IGNORE;
|
parseMode.update( ParseMode::PARSE_RANDOM_TEXT , InputError::IGNORE );
|
||||||
|
parseMode.update( ParseMode::PARSE_RANDOM_SLASH , InputError::IGNORE );
|
||||||
|
|
||||||
parser.addKeyword<ParserKeywords::SPECGRID>();
|
parser.addKeyword<ParserKeywords::SPECGRID>();
|
||||||
parser.addKeyword<ParserKeywords::FAULTS>();
|
parser.addKeyword<ParserKeywords::FAULTS>();
|
||||||
@@ -50,9 +51,10 @@ BOOST_AUTO_TEST_CASE( test_parse ) {
|
|||||||
BOOST_AUTO_TEST_CASE( test_state ) {
|
BOOST_AUTO_TEST_CASE( test_state ) {
|
||||||
Parser parser(false);
|
Parser parser(false);
|
||||||
ParseMode parseMode;
|
ParseMode parseMode;
|
||||||
parseMode.unknownKeyword = InputError::IGNORE;
|
|
||||||
parseMode.randomText = InputError::IGNORE;
|
parseMode.update( ParseMode::PARSE_UNKNOWN_KEYWORD , InputError::IGNORE );
|
||||||
parseMode.randomSlash = InputError::IGNORE;
|
parseMode.update( ParseMode::PARSE_RANDOM_TEXT , InputError::IGNORE );
|
||||||
|
parseMode.update( ParseMode::PARSE_RANDOM_SLASH , InputError::IGNORE );
|
||||||
|
|
||||||
parser.addKeyword<ParserKeywords::SPECGRID>();
|
parser.addKeyword<ParserKeywords::SPECGRID>();
|
||||||
parser.addKeyword<ParserKeywords::FAULTS>();
|
parser.addKeyword<ParserKeywords::FAULTS>();
|
||||||
|
|||||||
@@ -17,22 +17,198 @@
|
|||||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <ert/util/util.h>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
|
#include <opm/parser/eclipse/OpmLog/OpmLog.hpp>
|
||||||
#include <opm/parser/eclipse/Parser/ParseMode.hpp>
|
#include <opm/parser/eclipse/Parser/ParseMode.hpp>
|
||||||
#include <opm/parser/eclipse/Parser/InputErrorAction.hpp>
|
#include <opm/parser/eclipse/Parser/InputErrorAction.hpp>
|
||||||
|
|
||||||
namespace Opm {
|
namespace Opm {
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
A set of predefined error modes are added, with the default
|
||||||
|
setting 'InputError::IGNORE, then afterwards the environment
|
||||||
|
variables 'OPM_ERRORS_EXCEPTION', 'OPM_ERRORS_WARN' and
|
||||||
|
'OPM_ERRORS_IGNORE' are consulted
|
||||||
|
*/
|
||||||
|
|
||||||
ParseMode::ParseMode() {
|
ParseMode::ParseMode() {
|
||||||
unknownKeyword = InputError::THROW_EXCEPTION;
|
initDefault();
|
||||||
randomText = InputError::THROW_EXCEPTION;
|
initEnv();
|
||||||
randomSlash = InputError::THROW_EXCEPTION;
|
}
|
||||||
missingDIMSKeyword = InputError::THROW_EXCEPTION;
|
|
||||||
|
|
||||||
unsupportedScheduleGeoModifiers = InputError::THROW_EXCEPTION;
|
/*
|
||||||
unsupportedCOMPORDType = InputError::THROW_EXCEPTION;
|
If you intend to hardwire settings you should use this
|
||||||
unsupportedInitialTHPRES = InputError::THROW_EXCEPTION;
|
constructor, as that way the environment variables are applied
|
||||||
|
after the hawrdwired settings.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ParseMode::ParseMode(const std::vector<std::pair<std::string , InputError::Action>> initial) {
|
||||||
|
initDefault();
|
||||||
|
|
||||||
|
for (const auto& pair : initial)
|
||||||
|
update( pair.first , pair.second );
|
||||||
|
|
||||||
|
initEnv();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ParseMode::initDefault() {
|
||||||
|
addKey(PARSE_UNKNOWN_KEYWORD);
|
||||||
|
addKey(PARSE_RANDOM_TEXT);
|
||||||
|
addKey(PARSE_RANDOM_SLASH);
|
||||||
|
addKey(PARSE_MISSING_DIMS_KEYWORD);
|
||||||
|
addKey(UNSUPPORTED_SCHEDULE_GEO_MODIFIER);
|
||||||
|
addKey(UNSUPPORTED_COMPORD_TYPE);
|
||||||
|
addKey(UNSUPPORTED_INITIAL_THPRES);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParseMode::initEnv() {
|
||||||
|
envUpdate( "OPM_ERRORS_EXCEPTION" , InputError::THROW_EXCEPTION );
|
||||||
|
envUpdate( "OPM_ERRORS_WARN" , InputError::WARN );
|
||||||
|
envUpdate( "OPM_ERRORS_IGNORE" , InputError::IGNORE );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ParseMode::handleError( const std::string& errorKey , const std::string& msg) const {
|
||||||
|
InputError::Action action = get( errorKey );
|
||||||
|
|
||||||
|
if (action == InputError::WARN)
|
||||||
|
OpmLog::addMessage(Log::MessageType::Warning , msg);
|
||||||
|
else if (action == InputError::THROW_EXCEPTION)
|
||||||
|
throw std::invalid_argument(errorKey + ": " + msg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string,InputError::Action>::const_iterator ParseMode::begin() const {
|
||||||
|
return m_errorModes.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::map<std::string,InputError::Action>::const_iterator ParseMode::end() const {
|
||||||
|
return m_errorModes.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ParseMode::hasKey(const std::string& key) const {
|
||||||
|
if (m_errorModes.find( key ) == m_errorModes.end())
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ParseMode::addKey(const std::string& key) {
|
||||||
|
if (key.find_first_of("|:*") != std::string::npos)
|
||||||
|
throw std::invalid_argument("The ParseMode keys can not contain '|', '*' or ':'");
|
||||||
|
|
||||||
|
if (!hasKey(key))
|
||||||
|
m_errorModes.insert( std::pair<std::string , InputError::Action>( key , InputError::THROW_EXCEPTION ));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
InputError::Action ParseMode::get(const std::string& key) const {
|
||||||
|
if (hasKey( key ))
|
||||||
|
return m_errorModes.find( key )->second;
|
||||||
|
else
|
||||||
|
throw std::invalid_argument("The errormode key: " + key + " has not been registered");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is the 'strict' update function, it will throw an exception
|
||||||
|
if the input string is not a defined error mode. This should
|
||||||
|
typically be used in a downstream module where the policy
|
||||||
|
regarding an error mode is hardcoded. When using this method the
|
||||||
|
static string constanst for the different error modes should be
|
||||||
|
used as arguments:
|
||||||
|
|
||||||
|
parseMode.updateKey( ParseMode::PARSE_RANDOM_SLASH , InputError::IGNORE )
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ParseMode::updateKey(const std::string& key , InputError::Action action) {
|
||||||
|
if (hasKey(key))
|
||||||
|
m_errorModes[key] = action;
|
||||||
|
else
|
||||||
|
throw std::invalid_argument("The errormode key: " + key + " has not been registered");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ParseMode::envUpdate( const std::string& envVariable , InputError::Action action ) {
|
||||||
|
const char * userSetting = getenv(envVariable.c_str());
|
||||||
|
if (userSetting )
|
||||||
|
update( userSetting , action);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ParseMode::update(InputError::Action action) {
|
||||||
|
for (const auto& pair : m_errorModes) {
|
||||||
|
const std::string& key = pair.first;
|
||||||
|
updateKey( key , action );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ParseMode::patternUpdate( const std::string& pattern , InputError::Action action) {
|
||||||
|
const char * c_pattern = pattern.c_str();
|
||||||
|
for (const auto& pair : m_errorModes) {
|
||||||
|
const std::string& key = pair.first;
|
||||||
|
if (util_fnmatch( c_pattern , key.c_str()) == 0)
|
||||||
|
updateKey( key , action );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is the most general update function. The input keyString is
|
||||||
|
"selector string", and all matching error modes will be set to
|
||||||
|
@action. The algorithm for decoding the @keyString is:
|
||||||
|
|
||||||
|
1. The input string is split into several tokens on occurences
|
||||||
|
of ':' or ':' - and then each element is treated
|
||||||
|
seperately.
|
||||||
|
|
||||||
|
2. For each element in the list from 1):
|
||||||
|
|
||||||
|
a) If it contains at least one '*' - update all error modes
|
||||||
|
matching the input string.
|
||||||
|
|
||||||
|
b) If it is exactly equal to recognized error mode - update
|
||||||
|
that.
|
||||||
|
|
||||||
|
c) Otherwise - silently ignore.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ParseMode::update(const std::string& keyString , InputError::Action action) {
|
||||||
|
std::vector<std::string> keys;
|
||||||
|
boost::split( keys , keyString , boost::is_any_of(":|"));
|
||||||
|
for (const auto& input_key : keys) {
|
||||||
|
std::vector<std::string> matching_keys;
|
||||||
|
size_t wildcard_pos = input_key.find("*");
|
||||||
|
|
||||||
|
if (wildcard_pos == std::string::npos) {
|
||||||
|
if (hasKey( input_key ))
|
||||||
|
updateKey( input_key , action );
|
||||||
|
} else
|
||||||
|
patternUpdate( input_key , action );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string ParseMode::PARSE_UNKNOWN_KEYWORD = "PARSE_UNKNOWN_KEYWORD";
|
||||||
|
const std::string ParseMode::PARSE_RANDOM_TEXT = "PARSE_RANDOM_TEXT";
|
||||||
|
const std::string ParseMode::PARSE_RANDOM_SLASH = "PARSE_RANDOM_SLASH";
|
||||||
|
const std::string ParseMode::PARSE_MISSING_DIMS_KEYWORD = "PARSE_MISSING_DIMS_KEYWORD";
|
||||||
|
const std::string ParseMode::UNSUPPORTED_SCHEDULE_GEO_MODIFIER = "UNSUPPORTED_SCHEDULE_GEO_MODIFIER";
|
||||||
|
const std::string ParseMode::UNSUPPORTED_COMPORD_TYPE = "UNSUPPORTED_COMPORD_TYPE";
|
||||||
|
const std::string ParseMode::UNSUPPORTED_INITIAL_THPRES = "UNSUPPORTED_INITIAL_THPRES";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,22 +21,20 @@
|
|||||||
#ifndef OPM_PARSE_MODE_HPP
|
#ifndef OPM_PARSE_MODE_HPP
|
||||||
#define OPM_PARSE_MODE_HPP
|
#define OPM_PARSE_MODE_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <opm/parser/eclipse/Parser/InputErrorAction.hpp>
|
#include <opm/parser/eclipse/Parser/InputErrorAction.hpp>
|
||||||
|
|
||||||
namespace Opm {
|
namespace Opm {
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The ParseMode struct is meant to control the behavior of the
|
The ParseMode class is meant to control the behavior of the
|
||||||
parsing and EclipseState construction phase when
|
parsing and EclipseState construction phase when
|
||||||
errors/inconsistencies/... are encountered in the input.
|
errors/inconsistencies/... are encountered in the input.
|
||||||
|
|
||||||
The ParseMode struct should be used as a simple value object,
|
|
||||||
i.e. apart from the constructor there are no methods - the
|
|
||||||
object can not 'do anything'. It is perfectly legitimate for
|
|
||||||
calling scope to manipulate the fields of a parsemode instance
|
|
||||||
directly.
|
|
||||||
|
|
||||||
For each of the possible problems encountered the possible
|
For each of the possible problems encountered the possible
|
||||||
actions are goverened by the InputError::Action enum:
|
actions are goverened by the InputError::Action enum:
|
||||||
|
|
||||||
@@ -44,11 +42,59 @@ namespace Opm {
|
|||||||
InputError::WARN
|
InputError::WARN
|
||||||
InputError::IGNORE
|
InputError::IGNORE
|
||||||
|
|
||||||
|
The internal datastructure is a map between string keys and
|
||||||
|
enum InputError::Action values. The string keys are meant to be
|
||||||
|
descriptive like:
|
||||||
|
|
||||||
|
"PARSE_RANDOMTEXT"
|
||||||
|
|
||||||
|
|
||||||
|
The constructor will consult the env variable
|
||||||
|
OPM_ERRORS_IGNORE, OPM_ERRORS_WARN and OPM_ERRORS_EXCEPTION
|
||||||
|
when initializing. The variables should be set as strings of
|
||||||
|
update syntax.
|
||||||
|
|
||||||
|
update_syntax: The main function for updating the policy of a
|
||||||
|
parseMode instance is the update() method. That takes a string
|
||||||
|
as input, and updates the matching flags. The string can
|
||||||
|
contain wildcards ('* and '?' mathced with fnmatch()) and is
|
||||||
|
split on ':' or '|' to allow multiple settings to be applied in
|
||||||
|
one go:
|
||||||
|
|
||||||
|
Just set one variable:
|
||||||
|
update("PARSE_RANDOM_SLASH" , InputError::IGNORE)
|
||||||
|
|
||||||
|
Ignore all unsupported features:
|
||||||
|
update("UNSUPPORTED_*" , InputError::IGNORE)
|
||||||
|
|
||||||
|
Set two variables:
|
||||||
|
update("UNSUPPORTED_INIITIAL_THPRES:PARSE_RANDOM_SLASH" , InputError::IGNORE)
|
||||||
|
|
||||||
|
The update function itself is quite tolerant, and will silently
|
||||||
|
ignore unknown keys. If you use the updateKey() function only
|
||||||
|
recognizd keys will be allowed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct ParseMode {
|
class ParseMode {
|
||||||
|
public:
|
||||||
ParseMode();
|
ParseMode();
|
||||||
|
ParseMode(const std::vector<std::pair<std::string , InputError::Action>> initial);
|
||||||
|
void handleError( const std::string& errorKey , const std::string& msg) const;
|
||||||
|
bool hasKey(const std::string& key) const;
|
||||||
|
void updateKey(const std::string& key , InputError::Action action);
|
||||||
|
void update(InputError::Action action);
|
||||||
|
void update(const std::string& keyString , InputError::Action action);
|
||||||
|
InputError::Action get(const std::string& key) const;
|
||||||
|
std::map<std::string,InputError::Action>::const_iterator begin() const;
|
||||||
|
std::map<std::string,InputError::Action>::const_iterator end() const;
|
||||||
|
|
||||||
|
/*
|
||||||
|
When the key is added it is inserted in 'strict mode',
|
||||||
|
i.e. with the value 'InputError::THROW_EXCEPTION. If you
|
||||||
|
want a different value you must subsequently call the update
|
||||||
|
method.
|
||||||
|
*/
|
||||||
|
void addKey(const std::string& key);
|
||||||
/*
|
/*
|
||||||
The unknownKeyword field regulates how the parser should
|
The unknownKeyword field regulates how the parser should
|
||||||
react when it encounters an unknwon keyword. Observe that
|
react when it encounters an unknwon keyword. Observe that
|
||||||
@@ -72,21 +118,20 @@ namespace Opm {
|
|||||||
subsequent piece of 'random text' might not be identified
|
subsequent piece of 'random text' might not be identified
|
||||||
correctly as such.
|
correctly as such.
|
||||||
*/
|
*/
|
||||||
InputError::Action unknownKeyword;
|
const static std::string PARSE_UNKNOWN_KEYWORD;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
With random text we mean a string in the input deck is not
|
With random text we mean a string in the input deck is not
|
||||||
correctly formatted as a keyword heading.
|
correctly formatted as a keyword heading.
|
||||||
*/
|
*/
|
||||||
InputError::Action randomText;
|
const static std::string PARSE_RANDOM_TEXT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
It turns out that random '/' - i.e. typically an extra slash
|
It turns out that random '/' - i.e. typically an extra slash
|
||||||
which is not needed - is quite common. This is therefor a
|
which is not needed - is quite common. This is therefor a
|
||||||
special case treatment of the 'randomText' behaviour.
|
special case treatment of the 'randomText' behaviour.
|
||||||
*/
|
*/
|
||||||
InputError::Action randomSlash;
|
const static std::string PARSE_RANDOM_SLASH;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -101,7 +146,7 @@ namespace Opm {
|
|||||||
Observe that a fully defaulted XXXDIMS keyword does not
|
Observe that a fully defaulted XXXDIMS keyword does not
|
||||||
trigger this behavior.
|
trigger this behavior.
|
||||||
*/
|
*/
|
||||||
InputError::Action missingDIMSKeyword;
|
const static std::string PARSE_MISSING_DIMS_KEYWORD;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Some property modfiers can be modified in the Schedule
|
Some property modfiers can be modified in the Schedule
|
||||||
@@ -112,22 +157,26 @@ namespace Opm {
|
|||||||
encountered in the Schedule section the behavior is
|
encountered in the Schedule section the behavior is
|
||||||
regulated by this setting.
|
regulated by this setting.
|
||||||
*/
|
*/
|
||||||
InputError::Action unsupportedScheduleGeoModifiers;
|
const static std::string UNSUPPORTED_SCHEDULE_GEO_MODIFIER;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In the COMPORD implementation only the 'TRACK' input mode is supported.
|
In the COMPORD implementation only the 'TRACK' input mode is supported.
|
||||||
*/
|
*/
|
||||||
InputError::Action unsupportedCOMPORDType;
|
const static std::string UNSUPPORTED_COMPORD_TYPE;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If the third item in the THPRES keyword is defaulted the
|
If the third item in the THPRES keyword is defaulted the
|
||||||
threshold pressure is inferred from the initial pressure;
|
threshold pressure is inferred from the initial pressure;
|
||||||
this currently not supported.
|
this currently not supported.
|
||||||
*/
|
*/
|
||||||
InputError::Action unsupportedInitialTHPRES;
|
const static std::string UNSUPPORTED_INITIAL_THPRES;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initDefault();
|
||||||
|
void initEnv();
|
||||||
|
void envUpdate( const std::string& envVariable , InputError::Action action );
|
||||||
|
void patternUpdate( const std::string& pattern , InputError::Action action);
|
||||||
|
std::map<std::string , InputError::Action> m_errorModes;
|
||||||
}; }
|
}; }
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -108,24 +108,19 @@ namespace Opm {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void handleRandomText(const std::string& keywordString ) const {
|
void handleRandomText(const std::string& keywordString ) const {
|
||||||
|
std::string errorKey;
|
||||||
std::stringstream msg;
|
std::stringstream msg;
|
||||||
InputError::Action action;
|
|
||||||
std::string trimmedCopy = boost::algorithm::trim_copy( keywordString );
|
std::string trimmedCopy = boost::algorithm::trim_copy( keywordString );
|
||||||
|
|
||||||
if (trimmedCopy == "/") {
|
if (trimmedCopy == "/") {
|
||||||
action = parseMode.randomSlash;
|
errorKey = ParseMode::PARSE_RANDOM_SLASH;
|
||||||
msg << "Extra '/' detected at: " << dataFile << ":" << lineNR;
|
msg << "Extra '/' detected at: " << dataFile << ":" << lineNR;
|
||||||
} else {
|
} else {
|
||||||
action = parseMode.randomText;
|
errorKey = ParseMode::PARSE_RANDOM_TEXT;
|
||||||
msg << "String \'" << keywordString << "\' not formatted/recognized as valid keyword at: " << dataFile << ":" << lineNR;
|
msg << "String \'" << keywordString << "\' not formatted/recognized as valid keyword at: " << dataFile << ":" << lineNR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action == InputError::THROW_EXCEPTION)
|
parseMode.handleError( errorKey , msg.str() );
|
||||||
throw std::invalid_argument( msg.str() );
|
|
||||||
else {
|
|
||||||
if (action == InputError::WARN)
|
|
||||||
OpmLog::addMessage(Log::MessageType::Warning , msg.str());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -405,17 +400,15 @@ namespace Opm {
|
|||||||
}
|
}
|
||||||
targetSize = sizeDefinitionItem->getInt(0);
|
targetSize = sizeDefinitionItem->getInt(0);
|
||||||
} else {
|
} else {
|
||||||
InputError::Action action = parserState->parseMode.missingDIMSKeyword;
|
std::string msg = "Expected the kewyord: " + sizeKeyword.first + " to infer the number of records in: " + keywordString;
|
||||||
if (action == InputError::THROW_EXCEPTION)
|
parserState->parseMode.handleError(ParseMode::PARSE_MISSING_DIMS_KEYWORD , msg );
|
||||||
throw std::invalid_argument("Excpeted the kewyord: " + sizeKeyword.first + " to infer the number of records in: " + keywordString);
|
|
||||||
else {
|
{
|
||||||
auto keyword = getKeyword( sizeKeyword.first );
|
auto keyword = getKeyword( sizeKeyword.first );
|
||||||
auto record = keyword->getRecord(0);
|
auto record = keyword->getRecord(0);
|
||||||
auto int_item = std::dynamic_pointer_cast<const ParserIntItem>( record->get( sizeKeyword.second ) );
|
auto int_item = std::dynamic_pointer_cast<const ParserIntItem>( record->get( sizeKeyword.second ) );
|
||||||
|
|
||||||
targetSize = int_item->getDefault( );
|
targetSize = int_item->getDefault( );
|
||||||
if (action == InputError::WARN)
|
|
||||||
OpmLog::addMessage(Log::MessageType::Warning , "Excpeted the kewyord: " + sizeKeyword.first + " to infer the number of records in: " + keywordString + " using default");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -423,14 +416,9 @@ namespace Opm {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ParserKeyword::validDeckName(keywordString)) {
|
if (ParserKeyword::validDeckName(keywordString)) {
|
||||||
InputError::Action action = parserState->parseMode.unknownKeyword;
|
std::string msg = "Keyword " + keywordString + " not recognized ";
|
||||||
if (action == InputError::THROW_EXCEPTION)
|
parserState->parseMode.handleError( ParseMode::PARSE_UNKNOWN_KEYWORD , msg );
|
||||||
throw std::invalid_argument("Keyword " + keywordString + " not recognized ");
|
|
||||||
else {
|
|
||||||
if (action == InputError::WARN)
|
|
||||||
OpmLog::addMessage(Log::MessageType::Warning , "Keyword " + keywordString + " not recognized");
|
|
||||||
return std::shared_ptr<RawKeyword>( );
|
return std::shared_ptr<RawKeyword>( );
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
parserState->handleRandomText( keywordString );
|
parserState->handleRandomText( keywordString );
|
||||||
return std::shared_ptr<RawKeyword>( );
|
return std::shared_ptr<RawKeyword>( );
|
||||||
|
|||||||
@@ -56,26 +56,26 @@ BOOST_AUTO_TEST_CASE(TestUnkownKeyword) {
|
|||||||
|
|
||||||
|
|
||||||
parser.addKeyword<ParserKeywords::DIMENS>();
|
parser.addKeyword<ParserKeywords::DIMENS>();
|
||||||
parseMode.unknownKeyword = InputError::THROW_EXCEPTION;
|
parseMode.update(ParseMode::PARSE_UNKNOWN_KEYWORD , InputError::THROW_EXCEPTION );
|
||||||
BOOST_CHECK_THROW( parser.parseString( deck1 , parseMode ) , std::invalid_argument);
|
BOOST_CHECK_THROW( parser.parseString( deck1 , parseMode ) , std::invalid_argument);
|
||||||
|
|
||||||
parseMode.unknownKeyword = InputError::IGNORE;
|
parseMode.update(ParseMode::PARSE_UNKNOWN_KEYWORD , InputError::IGNORE );
|
||||||
BOOST_CHECK_NO_THROW( parser.parseString( deck1 , parseMode ) );
|
BOOST_CHECK_NO_THROW( parser.parseString( deck1 , parseMode ) );
|
||||||
|
|
||||||
parseMode.randomText = InputError::IGNORE;
|
parseMode.update(ParseMode::PARSE_UNKNOWN_KEYWORD , InputError::THROW_EXCEPTION );
|
||||||
parseMode.unknownKeyword = InputError::THROW_EXCEPTION;
|
parseMode.update(ParseMode::PARSE_RANDOM_TEXT , InputError::IGNORE );
|
||||||
BOOST_CHECK_THROW( parser.parseString( deck2 , parseMode ) , std::invalid_argument);
|
BOOST_CHECK_THROW( parser.parseString( deck2 , parseMode ) , std::invalid_argument);
|
||||||
|
|
||||||
parseMode.randomText = InputError::IGNORE;
|
parseMode.update(ParseMode::PARSE_UNKNOWN_KEYWORD , InputError::IGNORE );
|
||||||
parseMode.unknownKeyword = InputError::IGNORE;
|
parseMode.update(ParseMode::PARSE_RANDOM_TEXT , InputError::IGNORE );
|
||||||
BOOST_CHECK_NO_THROW( parser.parseString( deck2 , parseMode ) );
|
BOOST_CHECK_NO_THROW( parser.parseString( deck2 , parseMode ) );
|
||||||
|
|
||||||
parseMode.randomText = InputError::THROW_EXCEPTION;
|
parseMode.update(ParseMode::PARSE_UNKNOWN_KEYWORD , InputError::IGNORE );
|
||||||
parseMode.unknownKeyword = InputError::IGNORE;
|
parseMode.update(ParseMode::PARSE_RANDOM_TEXT , InputError::THROW_EXCEPTION );
|
||||||
BOOST_CHECK_THROW( parser.parseString( deck2 , parseMode ) , std::invalid_argument);
|
BOOST_CHECK_THROW( parser.parseString( deck2 , parseMode ) , std::invalid_argument);
|
||||||
|
|
||||||
parseMode.randomText = InputError::IGNORE;
|
parseMode.update(ParseMode::PARSE_UNKNOWN_KEYWORD , InputError::IGNORE );
|
||||||
parseMode.unknownKeyword = InputError::IGNORE;
|
parseMode.update(ParseMode::PARSE_RANDOM_TEXT , InputError::IGNORE );
|
||||||
BOOST_CHECK_NO_THROW( parser.parseString( deck2 , parseMode ) );
|
BOOST_CHECK_NO_THROW( parser.parseString( deck2 , parseMode ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,10 +95,10 @@ BOOST_AUTO_TEST_CASE( CheckMissingSizeKeyword) {
|
|||||||
parser.addKeyword<ParserKeywords::EQLDIMS>();
|
parser.addKeyword<ParserKeywords::EQLDIMS>();
|
||||||
parser.addKeyword<ParserKeywords::SOLUTION>();
|
parser.addKeyword<ParserKeywords::SOLUTION>();
|
||||||
|
|
||||||
parseMode.missingDIMSKeyword = InputError::THROW_EXCEPTION;
|
parseMode.update( ParseMode::PARSE_MISSING_DIMS_KEYWORD , InputError::THROW_EXCEPTION );
|
||||||
BOOST_CHECK_THROW( parser.parseString( deck , parseMode ) , std::invalid_argument);
|
BOOST_CHECK_THROW( parser.parseString( deck , parseMode ) , std::invalid_argument);
|
||||||
|
|
||||||
parseMode.missingDIMSKeyword = InputError::IGNORE;
|
parseMode.update( ParseMode::PARSE_MISSING_DIMS_KEYWORD , InputError::IGNORE );
|
||||||
BOOST_CHECK_NO_THROW( parser.parseString( deck , parseMode ) );
|
BOOST_CHECK_NO_THROW( parser.parseString( deck , parseMode ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,10 +123,10 @@ BOOST_AUTO_TEST_CASE( CheckUnsoppertedInSCHEDULE ) {
|
|||||||
std::shared_ptr<EclipseGrid> grid = std::make_shared<EclipseGrid>( deck );
|
std::shared_ptr<EclipseGrid> grid = std::make_shared<EclipseGrid>( deck );
|
||||||
std::shared_ptr<IOConfig> ioconfig = std::make_shared<IOConfig>( "path" );
|
std::shared_ptr<IOConfig> ioconfig = std::make_shared<IOConfig>( "path" );
|
||||||
|
|
||||||
parseMode.unsupportedScheduleGeoModifiers = InputError::IGNORE;
|
parseMode.update( ParseMode::UNSUPPORTED_SCHEDULE_GEO_MODIFIER , InputError::IGNORE );
|
||||||
BOOST_CHECK_NO_THROW( Schedule( parseMode , grid , deck , ioconfig ));
|
BOOST_CHECK_NO_THROW( Schedule( parseMode , grid , deck , ioconfig ));
|
||||||
|
|
||||||
parseMode.unsupportedScheduleGeoModifiers = InputError::THROW_EXCEPTION;
|
parseMode.update( ParseMode::UNSUPPORTED_SCHEDULE_GEO_MODIFIER , InputError::THROW_EXCEPTION );
|
||||||
BOOST_CHECK_THROW( Schedule( parseMode , grid , deck , ioconfig ), std::invalid_argument );
|
BOOST_CHECK_THROW( Schedule( parseMode , grid , deck , ioconfig ), std::invalid_argument );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,14 +153,15 @@ BOOST_AUTO_TEST_CASE(TestRandomSlash) {
|
|||||||
|
|
||||||
parser.addKeyword<ParserKeywords::TSTEP>();
|
parser.addKeyword<ParserKeywords::TSTEP>();
|
||||||
parser.addKeyword<ParserKeywords::SCHEDULE>();
|
parser.addKeyword<ParserKeywords::SCHEDULE>();
|
||||||
parseMode.randomSlash = InputError::THROW_EXCEPTION;
|
|
||||||
parseMode.randomText = InputError::IGNORE;
|
parseMode.update(ParseMode::PARSE_RANDOM_SLASH , InputError::THROW_EXCEPTION);
|
||||||
|
parseMode.update(ParseMode::PARSE_RANDOM_TEXT , InputError::IGNORE);
|
||||||
BOOST_CHECK_THROW( parser.parseString( deck1 , parseMode ) , std::invalid_argument);
|
BOOST_CHECK_THROW( parser.parseString( deck1 , parseMode ) , std::invalid_argument);
|
||||||
BOOST_CHECK_THROW( parser.parseString( deck2 , parseMode ) , std::invalid_argument);
|
BOOST_CHECK_THROW( parser.parseString( deck2 , parseMode ) , std::invalid_argument);
|
||||||
|
|
||||||
parseMode.randomSlash = InputError::IGNORE;
|
|
||||||
parseMode.randomText = InputError::THROW_EXCEPTION;
|
|
||||||
|
|
||||||
|
parseMode.update(ParseMode::PARSE_RANDOM_SLASH , InputError::IGNORE);
|
||||||
|
parseMode.update(ParseMode::PARSE_RANDOM_TEXT , InputError::THROW_EXCEPTION);
|
||||||
BOOST_CHECK_NO_THROW( parser.parseString( deck1 , parseMode ) );
|
BOOST_CHECK_NO_THROW( parser.parseString( deck1 , parseMode ) );
|
||||||
BOOST_CHECK_NO_THROW( parser.parseString( deck2 , parseMode ) );
|
BOOST_CHECK_NO_THROW( parser.parseString( deck2 , parseMode ) );
|
||||||
}
|
}
|
||||||
@@ -186,9 +187,65 @@ BOOST_AUTO_TEST_CASE(TestCOMPORD) {
|
|||||||
std::shared_ptr<EclipseGrid> grid = std::make_shared<EclipseGrid>( deck );
|
std::shared_ptr<EclipseGrid> grid = std::make_shared<EclipseGrid>( deck );
|
||||||
std::shared_ptr<IOConfig> ioconfig = std::make_shared<IOConfig>( "path" );
|
std::shared_ptr<IOConfig> ioconfig = std::make_shared<IOConfig>( "path" );
|
||||||
|
|
||||||
parseMode.unsupportedCOMPORDType = InputError::IGNORE;
|
parseMode.update( ParseMode::UNSUPPORTED_COMPORD_TYPE , InputError::IGNORE);
|
||||||
BOOST_CHECK_NO_THROW( Schedule( parseMode , grid , deck , ioconfig ));
|
BOOST_CHECK_NO_THROW( Schedule( parseMode , grid , deck , ioconfig ));
|
||||||
|
|
||||||
parseMode.unsupportedCOMPORDType = InputError::THROW_EXCEPTION;
|
parseMode.update( ParseMode::UNSUPPORTED_COMPORD_TYPE , InputError::THROW_EXCEPTION);
|
||||||
BOOST_CHECK_THROW( Schedule( parseMode , grid , deck , ioconfig ), std::invalid_argument );
|
BOOST_CHECK_THROW( Schedule( parseMode , grid , deck , ioconfig ), std::invalid_argument );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(TestInvalidKey) {
|
||||||
|
ParseMode parseMode;
|
||||||
|
BOOST_CHECK_THROW( parseMode.addKey("KEY*") , std::invalid_argument );
|
||||||
|
BOOST_CHECK_THROW( parseMode.addKey("KEY:") , std::invalid_argument );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(TestNew) {
|
||||||
|
ParseMode parseMode;
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL( false , parseMode.hasKey("NO"));
|
||||||
|
parseMode.addKey("NEW_KEY");
|
||||||
|
BOOST_CHECK_EQUAL( true , parseMode.hasKey("NEW_KEY"));
|
||||||
|
BOOST_CHECK_THROW( parseMode.get("NO") , std::invalid_argument );
|
||||||
|
BOOST_CHECK_EQUAL( parseMode.get("NEW_KEY") , InputError::THROW_EXCEPTION );
|
||||||
|
parseMode.addKey("KEY2");
|
||||||
|
BOOST_CHECK_EQUAL( parseMode.get("NEW_KEY") , InputError::THROW_EXCEPTION );
|
||||||
|
|
||||||
|
BOOST_CHECK_THROW( parseMode.updateKey("NO" , InputError::IGNORE) , std::invalid_argument);
|
||||||
|
|
||||||
|
parseMode.updateKey("NEW_KEY" , InputError::WARN);
|
||||||
|
BOOST_CHECK_EQUAL( parseMode.get("NEW_KEY") , InputError::WARN );
|
||||||
|
|
||||||
|
BOOST_CHECK_NO_THROW( parseMode.update("KEY2:NEW_KEY" , InputError::IGNORE));
|
||||||
|
BOOST_CHECK_NO_THROW( parseMode.update("UnknownKey" , InputError::IGNORE));
|
||||||
|
BOOST_CHECK_EQUAL( parseMode.get("NEW_KEY") , InputError::IGNORE );
|
||||||
|
BOOST_CHECK_EQUAL( parseMode.get("KEY2") , InputError::IGNORE );
|
||||||
|
|
||||||
|
parseMode.addKey("SECRET_KEY");
|
||||||
|
parseMode.addKey("NEW_KEY2");
|
||||||
|
parseMode.addKey("NEW_KEY3");
|
||||||
|
parseMode.update("NEW_KEY*" , InputError::WARN);
|
||||||
|
BOOST_CHECK_EQUAL( parseMode.get("NEW_KEY") , InputError::WARN );
|
||||||
|
BOOST_CHECK_EQUAL( parseMode.get("NEW_KEY2") , InputError::WARN );
|
||||||
|
BOOST_CHECK_EQUAL( parseMode.get("NEW_KEY3") , InputError::WARN );
|
||||||
|
|
||||||
|
parseMode.update( InputError::IGNORE );
|
||||||
|
BOOST_CHECK_EQUAL( parseMode.get("NEW_KEY3") , InputError::IGNORE );
|
||||||
|
BOOST_CHECK_EQUAL( parseMode.get("SECRET_KEY") , InputError::IGNORE );
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( test_constructor_with_values) {
|
||||||
|
ParseMode parseMode( {{ParseMode::PARSE_RANDOM_SLASH , InputError::IGNORE},
|
||||||
|
{"UNSUPPORTED_*" , InputError::WARN},
|
||||||
|
{"UNKNWON-IGNORED" , InputError::WARN}});
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL( parseMode.get(ParseMode::PARSE_RANDOM_SLASH) , InputError::IGNORE );
|
||||||
|
BOOST_CHECK_EQUAL( parseMode.get(ParseMode::PARSE_RANDOM_TEXT) , InputError::THROW_EXCEPTION );
|
||||||
|
BOOST_CHECK_EQUAL( parseMode.get(ParseMode::UNSUPPORTED_INITIAL_THPRES) , InputError::WARN );
|
||||||
|
BOOST_CHECK_EQUAL( parseMode.get(ParseMode::UNSUPPORTED_COMPORD_TYPE) , InputError::WARN );
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user