Extends OpmInputError to support multiple KeywordLocations.

This commit is contained in:
Williham Williham Totland 2020-10-02 13:54:03 +02:00
parent 0f8dec9ac3
commit 65f45b60a8
3 changed files with 44 additions and 14 deletions

View File

@ -19,9 +19,9 @@
#ifndef OPM_ERROR_HPP #ifndef OPM_ERROR_HPP
#define OPM_ERROR_HPP #define OPM_ERROR_HPP
#include <optional>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <vector>
#include <opm/common/OpmLog/KeywordLocation.hpp> #include <opm/common/OpmLog/KeywordLocation.hpp>
@ -68,7 +68,7 @@ public:
OpmInputError(const std::string& msg_fmt, const KeywordLocation& loc) : OpmInputError(const std::string& msg_fmt, const KeywordLocation& loc) :
m_what { OpmInputError::format(msg_fmt, loc) }, m_what { OpmInputError::format(msg_fmt, loc) },
location { loc } locations { loc }
{} {}
/* /*
@ -88,11 +88,12 @@ public:
*/ */
OpmInputError(const KeywordLocation& loc, const std::exception& e) : OpmInputError(const KeywordLocation& loc, const std::exception& e) :
m_what { OpmInputError::formatException(loc, e) }, m_what { OpmInputError::formatException(loc, e) },
location { loc } locations { loc }
{} {}
OpmInputError(const std::string& msg) : OpmInputError(const std::vector<KeywordLocation>& locations, const std::string& reason)
m_what(msg) : m_what { OpmInputError::formatMultiple(reason, locations) }
, locations { locations }
{} {}
const char * what() const throw() const char * what() const throw()
@ -103,6 +104,7 @@ public:
static std::string format(const std::string& msg_format, const KeywordLocation& loc); static std::string format(const std::string& msg_format, const KeywordLocation& loc);
static std::string formatException(const KeywordLocation& loc, const std::exception& e); static std::string formatException(const KeywordLocation& loc, const std::exception& e);
static std::string formatMultiple(const std::string& reason, const std::vector<KeywordLocation>&);
private: private:
std::string m_what; std::string m_what;
@ -110,7 +112,7 @@ private:
// The location member is here for debugging; depending on the msg_fmt // The location member is here for debugging; depending on the msg_fmt
// passed in the constructor we might not have captured all the information // passed in the constructor we might not have captured all the information
// in the location argument passed to the constructor. // in the location argument passed to the constructor.
std::optional<KeywordLocation> location; std::vector<KeywordLocation> locations;
}; };
} }

View File

@ -16,6 +16,9 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <algorithm>
#include <numeric>
#include <utility> #include <utility>
#include <fmt/format.h> #include <fmt/format.h>
@ -46,4 +49,20 @@ std::string OpmInputError::format(const std::string& msg_format, const KeywordLo
); );
} }
namespace {
std::string formatSingle(const KeywordLocation& loc) {
return OpmInputError::format("\n {keyword} in {file}, line {line}", loc);
}
}
std::string OpmInputError::formatMultiple(const std::string& reason, const std::vector<KeywordLocation>& locations) {
std::vector<std::string> locationStrings;
std::transform(locations.begin(), locations.end(), std::back_inserter(locationStrings), &formatSingle);
const std::string messages { std::accumulate(locationStrings.begin(), locationStrings.end(), std::string {}) } ;
return fmt::format(R"(Problem parsing keywords {}
Parse error: {})", messages, reason);
}
} }

View File

@ -39,6 +39,7 @@
#include <opm/parser/eclipse/Parser/ParserKeywords/M.hpp> #include <opm/parser/eclipse/Parser/ParserKeywords/M.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/O.hpp> #include <opm/parser/eclipse/Parser/ParserKeywords/O.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/P.hpp> #include <opm/parser/eclipse/Parser/ParserKeywords/P.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/R.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/S.hpp> #include <opm/parser/eclipse/Parser/ParserKeywords/S.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/T.hpp> #include <opm/parser/eclipse/Parser/ParserKeywords/T.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/V.hpp> #include <opm/parser/eclipse/Parser/ParserKeywords/V.hpp>
@ -571,12 +572,20 @@ namespace Opm {
// the TEMPVD (E300) and RTEMPVD (E300 + E100) keywords are // the TEMPVD (E300) and RTEMPVD (E300 + E100) keywords are
// synonymous, but we want to provide only a single cannonical // synonymous, but we want to provide only a single cannonical
// API here, so we jump through some small hoops... // API here, so we jump through some small hoops...
if (deck.hasKeyword("TEMPVD") && deck.hasKeyword("RTEMPVD")) const bool
throw std::invalid_argument("The TEMPVD and RTEMPVD tables are mutually exclusive!"); hasTEMPVD { deck.hasKeyword<ParserKeywords::TEMPVD>() } ,
else if (deck.hasKeyword("TEMPVD")) hasRTEMPVD { deck.hasKeyword<ParserKeywords::RTEMPVD>() } ;
if (hasTEMPVD && hasRTEMPVD) {
throw OpmInputError({
deck.getKeyword<ParserKeywords::TEMPVD>().location(),
deck.getKeyword<ParserKeywords::RTEMPVD>().location(),
}, "The TEMPVD and RTEMPVD tables are mutually exclusive.");
} else if (hasTEMPVD) {
initSimpleTableContainer<RtempvdTable>(deck, "TEMPVD", "RTEMPVD", m_eqldims.getNumEquilRegions()); initSimpleTableContainer<RtempvdTable>(deck, "TEMPVD", "RTEMPVD", m_eqldims.getNumEquilRegions());
else if (deck.hasKeyword("RTEMPVD")) } else if (hasRTEMPVD) {
initSimpleTableContainer<RtempvdTable>(deck, "RTEMPVD", "RTEMPVD" , m_eqldims.getNumEquilRegions()); initSimpleTableContainer<RtempvdTable>(deck, "RTEMPVD", "RTEMPVD", m_eqldims.getNumEquilRegions());
}
} }