Merge pull request #1949 from joakim-hove/error-prepare

Error prepare
This commit is contained in:
Joakim Hove
2020-09-24 07:33:22 +02:00
committed by GitHub
15 changed files with 76 additions and 33 deletions

View File

@@ -20,10 +20,25 @@
#ifndef KEYWORD_LOCATION_HPP
#define KEYWORD_LOCATION_HPP
#include <string>
namespace Opm {
class KeywordLocation {
public:
/*
Observe that many error messages whcih should print out the name of the
problem keyword along with the location {} placeholders can be used. The
convention is:
{keyword} -> keyword
{file} -> filename
{line} -> lineno
This convention must be adhered to at the call site *creating the output
string*.
*/
std::string keyword;
std::string filename = "<memory string>";
std::size_t lineno = 0;

View File

@@ -21,7 +21,9 @@
#include <iosfwd>
#include <string>
#include <optional>
#include <opm/common/OpmLog/KeywordLocation.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/Tabdims.hpp>
#include <opm/parser/eclipse/EclipseState/EndpointScaling.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp>
@@ -106,11 +108,17 @@ public:
return this->nWMax;
}
const std::optional<KeywordLocation>& location() const {
return this->m_location;
}
bool operator==(const Welldims& data) const {
return this->maxConnPerWell() == data.maxConnPerWell() &&
this->maxWellsPerGroup() == data.maxWellsPerGroup() &&
this->maxGroupsInField() == data.maxGroupsInField() &&
this->maxWellsInField() == data.maxWellsInField();
this->maxWellsInField() == data.maxWellsInField() &&
this->location() == data.location();
}
template<class Serializer>
@@ -120,6 +128,7 @@ public:
serializer(nCWMax);
serializer(nWGMax);
serializer(nGMax);
serializer(m_location);
}
private:
@@ -127,6 +136,7 @@ private:
int nCWMax { 0 };
int nWGMax { 0 };
int nGMax { 0 };
std::optional<KeywordLocation> m_location;
};
class WellSegmentDims {

View File

@@ -123,7 +123,7 @@ namespace Opm {
SectionNameSet::const_iterator validSectionNamesBegin() const;
SectionNameSet::const_iterator validSectionNamesEnd() const;
DeckKeyword parse(const ParseContext& parseContext, ErrorGuard& errors, RawKeyword& rawKeyword, UnitSystem& active_unitsystem, UnitSystem& default_unitsystem, const std::string& filename) const;
DeckKeyword parse(const ParseContext& parseContext, ErrorGuard& errors, RawKeyword& rawKeyword, UnitSystem& active_unitsystem, UnitSystem& default_unitsystem) const;
enum ParserKeywordSizeEnum getSizeType() const;
const KeywordSize& getKeywordSize() const;
bool isDataKeyword() const;

View File

@@ -35,6 +35,7 @@ namespace Opm {
class RawRecord;
class ErrorGuard;
class UnitSystem;
class KeywordLocation;
class ParserRecord {
public:
@@ -44,7 +45,7 @@ namespace Opm {
void addDataItem( ParserItem item );
const ParserItem& get(size_t index) const;
const ParserItem& get(const std::string& itemName) const;
DeckRecord parse( const ParseContext&, ErrorGuard&, RawRecord&, UnitSystem& active_unitsystem, UnitSystem& default_unitsystem, const std::string& keyword, const std::string& filename) const;
DeckRecord parse( const ParseContext&, ErrorGuard&, RawRecord&, UnitSystem& active_unitsystem, UnitSystem& default_unitsystem, const KeywordLocation& location) const;
bool isDataRecord() const;
bool equal(const ParserRecord& other) const;
bool hasDimension() const;

View File

@@ -97,19 +97,23 @@ bool Phases::operator==(const Phases& data) const {
Welldims::Welldims(const Deck& deck)
{
if (deck.hasKeyword("WELLDIMS")) {
const auto& wd = deck.getKeyword("WELLDIMS", 0).getRecord(0);
using WD = ParserKeywords::WELLDIMS;
if (deck.hasKeyword<WD>()) {
const auto& keyword = deck.getKeyword<WD>(0);
const auto& wd = keyword.getRecord(0);
this->nCWMax = wd.getItem("MAXCONN") .get<int>(0);
this->nWGMax = wd.getItem("MAX_GROUPSIZE").get<int>(0);
this->nCWMax = wd.getItem<WD::MAXCONN>().get<int>(0);
this->nWGMax = wd.getItem<WD::MAX_GROUPSIZE>().get<int>(0);
// This is the E100 definition. E300 instead uses
//
// Max{ "MAXGROUPS", "MAXWELLS" }
//
// i.e., the maximum of item 1 and item 4 here.
this->nGMax = wd.getItem("MAXGROUPS").get<int>(0);
this->nWMax = wd.getItem("MAXWELLS").get<int>(0);
this->nGMax = wd.getItem<WD::MAXGROUPS>().get<int>(0);
this->nWMax = wd.getItem<WD::MAXWELLS>().get<int>(0);
this->m_location = keyword.location();
}
}
@@ -120,7 +124,7 @@ Welldims Welldims::serializeObject()
result.nCWMax = 2;
result.nWGMax = 3;
result.nGMax = 4;
result.m_location = KeywordLocation::serializeObject();
return result;
}

View File

@@ -56,6 +56,9 @@ GPMaint GPMaint::serializeObject() {
gpm.m_flow_target = FlowTarget::SURF_GINJ;
gpm.m_region_name = "FIPNUM";
gpm.m_region_number = 26;
gpm.m_pressure_target = 100.0;
gpm.m_prop_constant = 200.0;
gpm.m_time_constant = 300.0;
return gpm;
}

View File

@@ -67,6 +67,7 @@ Group Group::serializeObject()
result.injection_properties = {{Opm::Phase::OIL, GroupInjectionProperties::serializeObject()}};
result.production_properties = GroupProductionProperties::serializeObject();
result.m_topup_phase = {Phase::OIL, true};
result.m_gpmaint = GPMaint::serializeObject();
return result;
}

View File

@@ -919,8 +919,7 @@ bool parseState( ParserState& parserState, const Parser& parser ) {
parserState.errors,
*rawKeyword,
parserState.deck.getActiveUnitSystem(),
parserState.deck.getDefaultUnitSystem(),
filename ) );
parserState.deck.getDefaultUnitSystem()));
} catch (const std::exception& exc) {
/*
This catch-all of parsing errors is to be able to write a good

View File

@@ -551,7 +551,7 @@ void scan_item( DeckItem& deck_item, const ParserItem& parser_item, RawRecord& r
std::string_view rep = !st.hasValue()
? std::string_view{ one_star }
: std::string_view{ token.begin() + value_start, size };
record.prepend( st.count() - 1, rep );
record.push_front(rep, st.count() - 1);
return;
}

View File

@@ -532,8 +532,7 @@ void set_dimensions( ParserItem& item,
ErrorGuard& errors,
RawKeyword& rawKeyword,
UnitSystem& active_unitsystem,
UnitSystem& default_unitsystem,
const std::string& filename) const {
UnitSystem& default_unitsystem) const {
if( !rawKeyword.isFinished() )
throw std::invalid_argument("Tried to create a deck keyword from an incomplete raw keyword " + rawKeyword.getKeywordName());
@@ -555,8 +554,8 @@ void set_dimensions( ParserItem& item,
record_nr = 0;
}
else {
keyword.addRecord( this->getRecord( record_nr ).parse( parseContext, errors, rawRecord, active_unitsystem, default_unitsystem, rawKeyword.getKeywordName(), filename ) );
record_nr++;
keyword.addRecord( this->getRecord( record_nr ).parse( parseContext, errors, rawRecord, active_unitsystem, default_unitsystem, rawKeyword.location() ) );
record_nr++;
}
}
}
@@ -566,7 +565,7 @@ void set_dimensions( ParserItem& item,
if( m_records.size() == 0 && rawRecord.size() > 0 )
throw std::invalid_argument("Missing item information " + rawKeyword.getKeywordName());
keyword.addRecord( this->getRecord( record_nr ).parse( parseContext, errors, rawRecord, active_unitsystem, default_unitsystem, rawKeyword.getKeywordName(), filename ) );
keyword.addRecord( this->getRecord( record_nr ).parse( parseContext, errors, rawRecord, active_unitsystem, default_unitsystem, rawKeyword.location() ) );
record_nr++;
}
}

View File

@@ -24,6 +24,8 @@
#include <opm/parser/eclipse/Parser/ParserItem.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/common/OpmLog/KeywordLocation.hpp>
#include "raw/RawRecord.hpp"
namespace Opm {
@@ -118,14 +120,14 @@ namespace {
}
DeckRecord ParserRecord::parse(const ParseContext& parseContext , ErrorGuard& errors , RawRecord& rawRecord, UnitSystem& active_unitsystem, UnitSystem& default_unitsystem, const std::string& keyword, const std::string& filename) const {
DeckRecord ParserRecord::parse(const ParseContext& parseContext , ErrorGuard& errors , RawRecord& rawRecord, UnitSystem& active_unitsystem, UnitSystem& default_unitsystem, const KeywordLocation& location) const {
std::vector< DeckItem > items;
items.reserve( this->size() + 20 );
for( const auto& parserItem : *this )
items.emplace_back( parserItem.scan( rawRecord, active_unitsystem, default_unitsystem ) );
if (rawRecord.size() > 0) {
std::string msg = "The RawRecord for keyword \"" + keyword + "\" in file\"" + filename + "\" contained " +
std::string msg = "The RawRecord for keyword \"" + location.keyword + "\" in file\"" + location.filename + "\" contained " +
std::to_string(rawRecord.size()) +
" too many items according to the spec. RawRecord was: " + rawRecord.getRecordString();
parseContext.handleError(ParseContext::PARSE_EXTRA_DATA , msg, errors);

View File

@@ -90,17 +90,23 @@ inline bool even_quotes( const T& str ) {
throw std::invalid_argument("Input string is not a complete record string, "
"offending string: '" + std::string(singleRecordString) + "'");
}
this->m_max_size = this->m_recordItems.size();
}
RawRecord::RawRecord(const std::string_view& singleRecordString) :
RawRecord(singleRecordString, false)
{}
void RawRecord::prepend( size_t count, std::string_view tok ) {
void RawRecord::push_front( std::string_view tok, std::size_t count ) {
this->m_recordItems.insert( this->m_recordItems.begin(), count, tok );
this->m_max_size += count;
}
std::string RawRecord::getRecordString() const {
return std::string(m_sanitizedRecordString);
}
std::size_t RawRecord::max_size() const {
return this->m_max_size;
}
}

View File

@@ -39,9 +39,9 @@ namespace Opm {
inline std::string_view pop_front();
inline std::string_view front() const;
void push_front( std::string_view token );
void prepend( size_t count, std::string_view token );
void push_front( std::string_view token, std::size_t count );
inline size_t size() const;
std::size_t max_size() const;
std::string getRecordString() const;
inline std::string_view getItem(size_t index) const;
@@ -49,6 +49,7 @@ namespace Opm {
private:
std::string_view m_sanitizedRecordString;
std::deque< std::string_view > m_recordItems;
std::size_t m_max_size;
};
/*

View File

@@ -485,10 +485,11 @@ BOOST_AUTO_TEST_CASE(StringsWithSpaceOK) {
ParseContext parseContext;
ErrorGuard errors;
UnitSystem active_unitsystem(UnitSystem::UnitType::UNIT_TYPE_LAB);
KeywordLocation loc;
record1.addItem( itemString );
const auto deckRecord = record1.parse( parseContext, errors , rawRecord, active_unitsystem, active_unitsystem, "KEYWORD", "filename" );
const auto deckRecord = record1.parse( parseContext, errors , rawRecord, active_unitsystem, active_unitsystem, loc);
BOOST_CHECK_EQUAL(" VALUE " , deckRecord.getItem(0).get< std::string >(0));
}

View File

@@ -1056,7 +1056,7 @@ BOOST_AUTO_TEST_CASE(parse_validRecord_noThrow) {
ErrorGuard errors;
RawRecord raw( std::string_view( "100 443" ) );
UnitSystem unit_system;
BOOST_CHECK_NO_THROW(record.parse(parseContext, errors, raw , unit_system, unit_system, "KEYWORD", "filename") );
BOOST_CHECK_NO_THROW(record.parse(parseContext, errors, raw , unit_system, unit_system, KeywordLocation()) );
}
BOOST_AUTO_TEST_CASE(parse_validRecord_deckRecordCreated) {
@@ -1065,7 +1065,7 @@ BOOST_AUTO_TEST_CASE(parse_validRecord_deckRecordCreated) {
ParseContext parseContext;
ErrorGuard errors;
UnitSystem unit_system;
const auto deckRecord = record.parse(parseContext , errors, rawRecord, unit_system, unit_system, "KEYWORD", "filename");
const auto deckRecord = record.parse(parseContext , errors, rawRecord, unit_system, unit_system, KeywordLocation());
BOOST_CHECK_EQUAL(2U, deckRecord.size());
}
@@ -1097,7 +1097,7 @@ BOOST_AUTO_TEST_CASE(parse_validMixedRecord_noThrow) {
ParseContext parseContext;
ErrorGuard errors;
UnitSystem unit_system;
BOOST_CHECK_NO_THROW(record.parse(parseContext, errors, rawRecord, unit_system, unit_system, "KEYWORD", "filename"));
BOOST_CHECK_NO_THROW(record.parse(parseContext, errors, rawRecord, unit_system, unit_system, KeywordLocation()));
}
BOOST_AUTO_TEST_CASE(Equal_Equal_ReturnsTrue) {
@@ -1223,13 +1223,13 @@ BOOST_AUTO_TEST_CASE(Parse_RawRecordTooManyItems_Throws) {
RawRecord rawRecord( "3 3 3 " );
UnitSystem unit_system;
BOOST_CHECK_NO_THROW(parserRecord.parse(parseContext, errors, rawRecord, unit_system, unit_system, "KEYWORD", "filename"));
BOOST_CHECK_NO_THROW(parserRecord.parse(parseContext, errors, rawRecord, unit_system, unit_system, KeywordLocation()));
RawRecord rawRecordOneExtra( "3 3 3 4 " );
BOOST_CHECK_THROW(parserRecord.parse(parseContext, errors, rawRecordOneExtra, unit_system, unit_system, "KEYWORD", "filename"), std::invalid_argument);
BOOST_CHECK_THROW(parserRecord.parse(parseContext, errors, rawRecordOneExtra, unit_system, unit_system, KeywordLocation()), std::invalid_argument);
RawRecord rawRecordForgotRecordTerminator( "3 3 3 \n 4 4 4 " );
BOOST_CHECK_THROW(parserRecord.parse(parseContext, errors, rawRecordForgotRecordTerminator, unit_system, unit_system, "KEYWORD", "filename"), std::invalid_argument);
BOOST_CHECK_THROW(parserRecord.parse(parseContext, errors, rawRecordForgotRecordTerminator, unit_system, unit_system, KeywordLocation()), std::invalid_argument);
}
@@ -1248,10 +1248,11 @@ BOOST_AUTO_TEST_CASE(Parse_RawRecordTooFewItems) {
ErrorGuard errors;
RawRecord rawRecord( "3 3 " );
UnitSystem unit_system;
KeywordLocation location;
// no default specified for the third item, record can be parsed just fine but trying
// to access the data will raise an exception...;
BOOST_CHECK_NO_THROW(parserRecord.parse(parseContext, errors, rawRecord, unit_system, unit_system, "KEWYORD", "filename"));
auto record = parserRecord.parse(parseContext, errors , rawRecord, unit_system, unit_system, "KEYWORD", "filename");
BOOST_CHECK_NO_THROW(parserRecord.parse(parseContext, errors, rawRecord, unit_system, unit_system, location));
auto record = parserRecord.parse(parseContext, errors , rawRecord, unit_system, unit_system, location);
BOOST_CHECK_NO_THROW(record.getItem(2));
BOOST_CHECK_THROW(record.getItem(2).get< int >(0), std::invalid_argument);
}
@@ -1633,7 +1634,7 @@ BOOST_AUTO_TEST_CASE(ParseEmptyRecord) {
record.addItem(item);
tabdimsKeyword.addRecord( record );
const auto deckKeyword = tabdimsKeyword.parse( parseContext, errors, rawkeyword , unit_system, unit_system, "filename");
const auto deckKeyword = tabdimsKeyword.parse( parseContext, errors, rawkeyword , unit_system, unit_system);
BOOST_REQUIRE_EQUAL( 1U , deckKeyword.size());
const auto& deckRecord = deckKeyword.getRecord(0);