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
#define OPM_ERROR_HPP
#include <optional>
#include <stdexcept>
#include <string>
#include <vector>
#include <opm/common/OpmLog/KeywordLocation.hpp>
@ -67,8 +67,8 @@ public:
*/
OpmInputError(const std::string& msg_fmt, const KeywordLocation& loc) :
m_what { OpmInputError::format(msg_fmt, loc) },
location { loc }
m_what { OpmInputError::format(msg_fmt, loc) },
locations { loc }
{}
/*
@ -87,12 +87,13 @@ public:
}
*/
OpmInputError(const KeywordLocation& loc, const std::exception& e) :
m_what { OpmInputError::formatException(loc, e) },
location { loc }
m_what { OpmInputError::formatException(loc, e) },
locations { loc }
{}
OpmInputError(const std::string& msg) :
m_what(msg)
OpmInputError(const std::vector<KeywordLocation>& locations, const std::string& reason)
: m_what { OpmInputError::formatMultiple(reason, locations) }
, locations { locations }
{}
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 formatException(const KeywordLocation& loc, const std::exception& e);
static std::string formatMultiple(const std::string& reason, const std::vector<KeywordLocation>&);
private:
std::string m_what;
@ -110,7 +112,7 @@ private:
// The location member is here for debugging; depending on the msg_fmt
// passed in the constructor we might not have captured all the information
// 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
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <algorithm>
#include <numeric>
#include <utility>
#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/O.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/T.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/V.hpp>
@ -571,12 +572,20 @@ namespace Opm {
// the TEMPVD (E300) and RTEMPVD (E300 + E100) keywords are
// synonymous, but we want to provide only a single cannonical
// API here, so we jump through some small hoops...
if (deck.hasKeyword("TEMPVD") && deck.hasKeyword("RTEMPVD"))
throw std::invalid_argument("The TEMPVD and RTEMPVD tables are mutually exclusive!");
else if (deck.hasKeyword("TEMPVD"))
initSimpleTableContainer<RtempvdTable>(deck, "TEMPVD", "RTEMPVD", m_eqldims.getNumEquilRegions());
else if (deck.hasKeyword("RTEMPVD"))
initSimpleTableContainer<RtempvdTable>(deck, "RTEMPVD", "RTEMPVD" , m_eqldims.getNumEquilRegions());
const bool
hasTEMPVD { deck.hasKeyword<ParserKeywords::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());
} else if (hasRTEMPVD) {
initSimpleTableContainer<RtempvdTable>(deck, "RTEMPVD", "RTEMPVD", m_eqldims.getNumEquilRegions());
}
}