diff --git a/opm/parser/eclipse/Deck/DeckItem.cpp b/opm/parser/eclipse/Deck/DeckItem.cpp index 989c9f13b..91b5f4438 100644 --- a/opm/parser/eclipse/Deck/DeckItem.cpp +++ b/opm/parser/eclipse/Deck/DeckItem.cpp @@ -36,8 +36,11 @@ namespace Opm { } bool DeckItem::defaultApplied(size_t index) const { - assert(m_dataPointDefaulted.size() == size()); - assertSize(index); + if (index >= m_dataPointDefaulted.size()) + throw std::out_of_range("Index must be smaller than " + + boost::lexical_cast(m_dataPointDefaulted.size()) + + " but is " + + boost::lexical_cast(index)); return m_dataPointDefaulted[index]; } diff --git a/opm/parser/eclipse/IntegrationTests/IntegrationTests.cpp b/opm/parser/eclipse/IntegrationTests/IntegrationTests.cpp index c24d0696a..46b2cedd1 100644 --- a/opm/parser/eclipse/IntegrationTests/IntegrationTests.cpp +++ b/opm/parser/eclipse/IntegrationTests/IntegrationTests.cpp @@ -215,27 +215,28 @@ BOOST_AUTO_TEST_CASE(parse_unknownkeyword_exceptionthrown) { BOOST_AUTO_TEST_CASE(parse_truncatedrecords_deckFilledWithDefaults) { ParserPtr parser(new Parser()); DeckPtr deck = parser->parseFile("testdata/integration_tests/truncated_records.data"); - BOOST_CHECK_EQUAL(4U, deck->size()); + BOOST_CHECK_EQUAL(3U, deck->size()); DeckKeywordConstPtr radfin4_0_full= deck->getKeyword("RADFIN4", 0); DeckKeywordConstPtr radfin4_1_partial= deck->getKeyword("RADFIN4", 1); - DeckKeywordConstPtr radfin4_2_nodata= deck->getKeyword("RADFIN4", 2); // Specified in datafile BOOST_CHECK_EQUAL("NAME", radfin4_0_full->getRecord(0)->getItem(0)->getString(0)); BOOST_CHECK_EQUAL("NAME", radfin4_1_partial->getRecord(0)->getItem(0)->getString(0)); - // Default string - - BOOST_CHECK_NO_THROW(radfin4_2_nodata->getRecord(0)->getItem(0)->getString(0)); - BOOST_CHECK( radfin4_2_nodata->getRecord(0)->getItem(0)->defaultApplied(0)); - // Specified in datafile BOOST_CHECK_EQUAL(213, radfin4_0_full->getRecord(0)->getItem(1)->getInt(0)); BOOST_CHECK_EQUAL(213, radfin4_1_partial->getRecord(0)->getItem(1)->getInt(0)); - // Default int - BOOST_CHECK_NO_THROW( radfin4_2_nodata->getRecord(0)->getItem(1)->getInt(0)); - BOOST_CHECK( radfin4_2_nodata->getRecord(0)->getItem(1)->defaultApplied(0)); + const auto record_0 = radfin4_0_full->getRecord(0); + const auto lastItem_0 = record_0->getItem(record_0->size() - 1); + BOOST_CHECK(!lastItem_0->defaultApplied(0)); + BOOST_CHECK_EQUAL(lastItem_0->getInt(0), 18); + + const auto record_1 = radfin4_1_partial->getRecord(0); + const auto lastItem_1 = record_1->getItem(record_1->size() - 1); + BOOST_CHECK_EQUAL(213, radfin4_1_partial->getRecord(0)->getItem(1)->getInt(0)); + BOOST_CHECK(lastItem_1->defaultApplied(0)); + BOOST_CHECK_EQUAL(lastItem_1->getInt(0), 1); ParserKeywordConstPtr parserKeyword = parser->getParserKeywordFromDeckName("RADFIN4"); ParserRecordConstPtr parserRecord = parserKeyword->getRecord(); @@ -244,6 +245,4 @@ BOOST_AUTO_TEST_CASE(parse_truncatedrecords_deckFilledWithDefaults) { BOOST_CHECK_EQUAL(18, radfin4_0_full->getRecord(0)->getItem(10)->getInt(0)); BOOST_CHECK_EQUAL(intItem->getDefault(), radfin4_1_partial->getRecord(0)->getItem(10)->getInt(0)); - BOOST_CHECK_EQUAL(intItem->getDefault(), radfin4_2_nodata->getRecord(0)->getItem(10)->getInt(0)); - } diff --git a/opm/parser/eclipse/Parser/Parser.cpp b/opm/parser/eclipse/Parser/Parser.cpp index db2a31622..2f6d8b2ec 100644 --- a/opm/parser/eclipse/Parser/Parser.cpp +++ b/opm/parser/eclipse/Parser/Parser.cpp @@ -302,8 +302,8 @@ namespace Opm { "The keyword " + parserState->rawKeyword->getKeywordName() + " is ignored - this might potentially affect the results"); } else { DeckKeywordPtr deckKeyword(new DeckKeyword(parserState->rawKeyword->getKeywordName(), false)); - deckKeyword->setLocation(parserState->rawKeyword->getFilename(), - parserState->rawKeyword->getLineNR()); + deckKeyword->setLocation(parserState->rawKeyword->getFilename(), + parserState->rawKeyword->getLineNR()); parserState->deck->addKeyword(deckKeyword); parserState->logger.addWarning(parserState->dataFile.string(), parserState->rawKeyword->getLineNR(), diff --git a/opm/parser/eclipse/Parser/ParserDoubleItem.cpp b/opm/parser/eclipse/Parser/ParserDoubleItem.cpp index 4a5e6788a..adba0ed01 100644 --- a/opm/parser/eclipse/Parser/ParserDoubleItem.cpp +++ b/opm/parser/eclipse/Parser/ParserDoubleItem.cpp @@ -39,26 +39,36 @@ namespace Opm m_default = std::numeric_limits::quiet_NaN(); } - ParserDoubleItem::ParserDoubleItem(const std::string& itemName) : ParserItem(itemName) + ParserDoubleItem::ParserDoubleItem(const std::string& itemName) + : ParserItem(itemName) { m_default = std::numeric_limits::quiet_NaN(); + m_defaultSet = false; } - ParserDoubleItem::ParserDoubleItem(const std::string& itemName, double defaultValue) : ParserItem(itemName) + ParserDoubleItem::ParserDoubleItem(const std::string& itemName, double defaultValue) + : ParserItem(itemName) { setDefault( defaultValue ); } - ParserDoubleItem::ParserDoubleItem(const std::string& itemName, ParserItemSizeEnum sizeType_, double defaultValue) : ParserItem(itemName, sizeType_) + ParserDoubleItem::ParserDoubleItem(const std::string& itemName, ParserItemSizeEnum sizeType, double defaultValue) + : ParserItem(itemName, sizeType) { setDefault( defaultValue ); } double ParserDoubleItem::getDefault() const { - return m_default; + if (hasDefault()) + return m_default; + + if (sizeType() == Opm::ALL) + return std::numeric_limits::quiet_NaN(); + + throw std::invalid_argument("No default value available for item "+name()); } @@ -67,7 +77,9 @@ namespace Opm m_defaultSet = true; } - + bool ParserDoubleItem::hasDefault() const { + return m_defaultSet; + } ParserDoubleItem::ParserDoubleItem(const Json::JsonObject& jsonConfig) : ParserItem(jsonConfig) diff --git a/opm/parser/eclipse/Parser/ParserDoubleItem.hpp b/opm/parser/eclipse/Parser/ParserDoubleItem.hpp index ee90b370c..57e812b48 100644 --- a/opm/parser/eclipse/Parser/ParserDoubleItem.hpp +++ b/opm/parser/eclipse/Parser/ParserDoubleItem.hpp @@ -51,6 +51,8 @@ namespace Opm { void inlineNew(std::ostream& os) const; void setDefault(double defaultValue); double getDefault() const; + bool hasDefault() const; + size_t dimensionSize() const; private: diff --git a/opm/parser/eclipse/Parser/ParserFloatItem.cpp b/opm/parser/eclipse/Parser/ParserFloatItem.cpp index 406488ea9..b26d0edec 100644 --- a/opm/parser/eclipse/Parser/ParserFloatItem.cpp +++ b/opm/parser/eclipse/Parser/ParserFloatItem.cpp @@ -58,9 +58,18 @@ namespace Opm float ParserFloatItem::getDefault() const { - return m_default; + if (hasDefault()) + return m_default; + + if (sizeType() == Opm::ALL) + return std::numeric_limits::quiet_NaN(); + + throw std::invalid_argument("No default value available for item "+name()); } + bool ParserFloatItem::hasDefault() const { + return m_defaultSet; + } void ParserFloatItem::setDefault(float defaultValue) { if (sizeType() == ALL) diff --git a/opm/parser/eclipse/Parser/ParserFloatItem.hpp b/opm/parser/eclipse/Parser/ParserFloatItem.hpp index 30f67be5e..c6e35e9e9 100644 --- a/opm/parser/eclipse/Parser/ParserFloatItem.hpp +++ b/opm/parser/eclipse/Parser/ParserFloatItem.hpp @@ -52,6 +52,7 @@ namespace Opm { void inlineNew(std::ostream& os) const; void setDefault(float defaultValue); float getDefault() const; + bool hasDefault() const; size_t dimensionSize() const; private: diff --git a/opm/parser/eclipse/Parser/ParserIntItem.cpp b/opm/parser/eclipse/Parser/ParserIntItem.cpp index 38b36b72d..d4b35cae5 100644 --- a/opm/parser/eclipse/Parser/ParserIntItem.cpp +++ b/opm/parser/eclipse/Parser/ParserIntItem.cpp @@ -34,11 +34,14 @@ namespace Opm { // this is usually meaningless. (Keep in mind that in the deck it can be queried // using deckItem->defaultApplied(idx) if an item was defaulted or not... m_default = -1; + m_defaultSet = false; } - ParserIntItem::ParserIntItem(const std::string& itemName, ParserItemSizeEnum sizeType_) : ParserItem(itemName, sizeType_) + ParserIntItem::ParserIntItem(const std::string& itemName, ParserItemSizeEnum sizeType) + : ParserItem(itemName, sizeType) { m_default = -1; + m_defaultSet = false; } ParserIntItem::ParserIntItem(const std::string& itemName, int defaultValue) : ParserItem(itemName) @@ -68,7 +71,17 @@ namespace Opm { } int ParserIntItem::getDefault() const { - return m_default; + if (hasDefault()) + return m_default; + + if (sizeType() == Opm::ALL) + return -1; + + throw std::invalid_argument("No default value available for item "+name()); + } + + bool ParserIntItem::hasDefault() const { + return m_defaultSet; } DeckItemPtr ParserIntItem::scan(RawRecordPtr rawRecord) const { diff --git a/opm/parser/eclipse/Parser/ParserIntItem.hpp b/opm/parser/eclipse/Parser/ParserIntItem.hpp index 11706921b..962e55275 100644 --- a/opm/parser/eclipse/Parser/ParserIntItem.hpp +++ b/opm/parser/eclipse/Parser/ParserIntItem.hpp @@ -46,6 +46,7 @@ namespace Opm { void inlineNew(std::ostream& os) const; int getDefault() const; + bool hasDefault() const; void setDefault(int defaultValue); private: int m_default; diff --git a/opm/parser/eclipse/Parser/ParserItem.cpp b/opm/parser/eclipse/Parser/ParserItem.cpp index 75a9115c4..44db10d28 100644 --- a/opm/parser/eclipse/Parser/ParserItem.cpp +++ b/opm/parser/eclipse/Parser/ParserItem.cpp @@ -25,9 +25,9 @@ namespace Opm { - ParserItem::ParserItem(const std::string& itemName, ParserItemSizeEnum sizeType_) { + ParserItem::ParserItem(const std::string& itemName, ParserItemSizeEnum sizeType) { m_name.assign(itemName); - m_sizeType = sizeType_; + m_sizeType = sizeType; m_defaultSet = false; m_description = ""; } diff --git a/opm/parser/eclipse/Parser/ParserItem.hpp b/opm/parser/eclipse/Parser/ParserItem.hpp index 4db403465..0ac94b1d8 100644 --- a/opm/parser/eclipse/Parser/ParserItem.hpp +++ b/opm/parser/eclipse/Parser/ParserItem.hpp @@ -131,8 +131,7 @@ namespace Opm { } } else { if (rawRecord->size() == 0) - // if the record was ended prematurely, use the default value for the - // item... + // if the record was ended prematurely, use the default value for the item... deckItem->push_backDefault( self->getDefault() ); else { // The '*' should be interpreted as a repetition indicator, but it must diff --git a/opm/parser/eclipse/Parser/ParserKeyword.cpp b/opm/parser/eclipse/Parser/ParserKeyword.cpp index 310e7c655..039758ed7 100644 --- a/opm/parser/eclipse/Parser/ParserKeyword.cpp +++ b/opm/parser/eclipse/Parser/ParserKeyword.cpp @@ -525,11 +525,11 @@ namespace Opm { if (rawKeyword->isFinished()) { DeckKeywordPtr keyword(new DeckKeyword(rawKeyword->getKeywordName())); keyword->setLocation(rawKeyword->getFilename(), rawKeyword->getLineNR()); + keyword->setDataKeyword( isDataKeyword() ); for (size_t i = 0; i < rawKeyword->size(); i++) { DeckRecordConstPtr deckRecord = m_record->parse(rawKeyword->getRecord(i)); keyword->addRecord(deckRecord); } - keyword->setDataKeyword( isDataKeyword() ); return keyword; } else throw std::invalid_argument("Tried to create a deck keyword from an incomplete raw keyword " + rawKeyword->getKeywordName()); diff --git a/opm/parser/eclipse/Parser/ParserStringItem.cpp b/opm/parser/eclipse/Parser/ParserStringItem.cpp index ae61f73fc..15e96dbb4 100644 --- a/opm/parser/eclipse/Parser/ParserStringItem.cpp +++ b/opm/parser/eclipse/Parser/ParserStringItem.cpp @@ -27,12 +27,14 @@ namespace Opm { ParserStringItem::ParserStringItem(const std::string& itemName) : ParserItem(itemName) { m_default = ""; + m_defaultSet = false; } ParserStringItem::ParserStringItem(const std::string& itemName, ParserItemSizeEnum sizeType_) : ParserItem(itemName, sizeType_) { m_default = ""; + m_defaultSet = false; } ParserStringItem::ParserStringItem(const std::string& itemName, ParserItemSizeEnum sizeType_, const std::string& defaultValue) : ParserItem(itemName, sizeType_) { @@ -62,10 +64,18 @@ namespace Opm { } std::string ParserStringItem::getDefault() const { - return m_default; + if (hasDefault()) + return m_default; + + if (sizeType() == Opm::ALL) + return ""; + + throw std::invalid_argument("No default value available for item "+name()); } - + bool ParserStringItem::hasDefault() const { + return m_defaultSet; + } DeckItemPtr ParserStringItem::scan(RawRecordPtr rawRecord) const { return ParserItemScan(this , rawRecord); diff --git a/opm/parser/eclipse/Parser/ParserStringItem.hpp b/opm/parser/eclipse/Parser/ParserStringItem.hpp index d501da2f3..829d551ac 100644 --- a/opm/parser/eclipse/Parser/ParserStringItem.hpp +++ b/opm/parser/eclipse/Parser/ParserStringItem.hpp @@ -43,6 +43,7 @@ namespace Opm { void inlineNew(std::ostream& os) const; void setDefault(const std::string& defaultValue); std::string getDefault() const; + bool hasDefault() const; private: std::string m_default; diff --git a/opm/parser/eclipse/Parser/tests/ParserItemTests.cpp b/opm/parser/eclipse/Parser/tests/ParserItemTests.cpp index 9984c8614..dc2c1cfa2 100644 --- a/opm/parser/eclipse/Parser/tests/ParserItemTests.cpp +++ b/opm/parser/eclipse/Parser/tests/ParserItemTests.cpp @@ -71,7 +71,9 @@ BOOST_AUTO_TEST_CASE(Initialize_DefaultSizeType) { BOOST_AUTO_TEST_CASE(Initialize_Default) { ParserIntItem item1(std::string("ITEM1")); ParserIntItem item2(std::string("ITEM1"), 88); - BOOST_CHECK(item1.getDefault() < 0); + BOOST_CHECK(!item1.hasDefault()); + BOOST_CHECK_THROW(item1.getDefault(), std::invalid_argument); + BOOST_CHECK(item2.hasDefault()); BOOST_CHECK_EQUAL(item2.getDefault(), 88); } @@ -79,37 +81,41 @@ BOOST_AUTO_TEST_CASE(Initialize_Default) { BOOST_AUTO_TEST_CASE(Initialize_Default_Double) { ParserDoubleItem item1(std::string("ITEM1")); ParserDoubleItem item2("ITEM1", 88.91); - BOOST_CHECK(!std::isfinite(item1.getDefault())); + BOOST_CHECK(!item1.hasDefault()); + BOOST_CHECK_THROW(item1.getDefault(), std::invalid_argument); BOOST_CHECK_EQUAL( 88.91 , item2.getDefault()); } BOOST_AUTO_TEST_CASE(Initialize_Default_Float) { ParserFloatItem item1(std::string("ITEM1")); ParserFloatItem item2("ITEM1", 88.91F); - BOOST_CHECK(!std::isfinite(item1.getDefault())); + + BOOST_CHECK(!item1.hasDefault()); + BOOST_CHECK_THROW(item1.getDefault(), std::invalid_argument); + + BOOST_CHECK(item2.hasDefault()); BOOST_CHECK_EQUAL( 88.91F , item2.getDefault()); } BOOST_AUTO_TEST_CASE(Initialize_Default_String) { ParserStringItem item1(std::string("ITEM1")); - BOOST_CHECK(item1.getDefault() == ""); + BOOST_CHECK(!item1.hasDefault()); + BOOST_CHECK_THROW(item1.getDefault(), std::invalid_argument); ParserStringItem item2("ITEM1", "String"); + BOOST_CHECK(item2.hasDefault()); BOOST_CHECK_EQUAL( "String" , item2.getDefault()); } BOOST_AUTO_TEST_CASE(scan_PreMatureTerminator_defaultUsed) { - ParserIntItem itemInt(std::string("ITEM2")); + ParserIntItem itemInt(std::string("ITEM2"), 123); RawRecordPtr rawRecord1(new RawRecord("/")); DeckItemConstPtr defaulted = itemInt.scan(rawRecord1); - // an item is always present even if the record was ended. If the deck specified no - // data and the item does not have a meaningful default, the item gets assigned a NaN - // (for float and double items), -1 (for integer items) and "" (for string items) - // whit the defaultApplied(0) method returning true... + BOOST_CHECK(defaulted->defaultApplied(0)); - BOOST_CHECK(defaulted->getInt(0) < 0); + BOOST_CHECK_EQUAL(defaulted->getInt(0), 123); } BOOST_AUTO_TEST_CASE(InitializeIntItem_setDescription_canReadBack) { diff --git a/opm/parser/eclipse/Parser/tests/ParserRecordTests.cpp b/opm/parser/eclipse/Parser/tests/ParserRecordTests.cpp index b8d0e7955..8b78c3f30 100644 --- a/opm/parser/eclipse/Parser/tests/ParserRecordTests.cpp +++ b/opm/parser/eclipse/Parser/tests/ParserRecordTests.cpp @@ -315,7 +315,7 @@ BOOST_AUTO_TEST_CASE(Parse_RawRecordTooManyItems_Throws) { } -BOOST_AUTO_TEST_CASE(Parse_RawRecordTooFewItems_ThrowsNot) { +BOOST_AUTO_TEST_CASE(Parse_RawRecordTooFewItems) { ParserRecordPtr parserRecord(new ParserRecord()); ParserIntItemConstPtr itemI(new ParserIntItem("I", SINGLE)); ParserIntItemConstPtr itemJ(new ParserIntItem("J", SINGLE)); @@ -326,7 +326,8 @@ BOOST_AUTO_TEST_CASE(Parse_RawRecordTooFewItems_ThrowsNot) { parserRecord->addItem(itemK); RawRecordPtr rawRecord(new RawRecord("3 3 /")); - BOOST_CHECK_NO_THROW(parserRecord->parse(rawRecord)); + // no default specified for the third item, record cannot be parsed. + BOOST_CHECK_THROW(parserRecord->parse(rawRecord), std::invalid_argument); } diff --git a/testdata/integration_tests/truncated_records.data b/testdata/integration_tests/truncated_records.data index 041302b52..781d86d63 100644 --- a/testdata/integration_tests/truncated_records.data +++ b/testdata/integration_tests/truncated_records.data @@ -5,9 +5,6 @@ RADFIN4 'NAME' 213 123 123 123 7 7 18 18 18 18 / RADFIN4 - 'NAME' 213 / - -RADFIN4 -/ + 'NAME' 213 123 123 123 7 7 18 18 18 /