From a8a911a73793d42f8d39d7a1babf4eb4a9965a5e Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Wed, 4 Feb 2015 02:04:34 +0100 Subject: Improved enum related error messages --- src/core/model/Typesystem.cpp | 36 ++++++++++++++++++++++++++++-------- src/core/model/Typesystem.hpp | 5 +++++ testdata/xmlparser/generic.oxm | 3 ++- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/core/model/Typesystem.cpp b/src/core/model/Typesystem.cpp index a3c5b6d..bd5e615 100644 --- a/src/core/model/Typesystem.cpp +++ b/src/core/model/Typesystem.cpp @@ -138,16 +138,25 @@ bool EnumType::doBuild(Variant &data, Logger &logger, // Throw an execption if the given string value is not found if (it == values.end()) { throw LoggableException(std::string("Unknown enum constant: \"") + - name + std::string("\""), + name + + std::string("\", expected one of ") + + Utils::join(names(), ", ", "{", "}"), data); } data = it->second; return true; } - throw LoggableException{"Expected integer or identifier", data}; + + // Throw an exception, list possible enum types + throw LoggableException{ + std::string( + "Expected integer or one of the following enum constants: ") + + Utils::join(names(), ", ", "{", "}"), + data}; } -bool EnumType::doValidate(Logger &logger) const{ +bool EnumType::doValidate(Logger &logger) const +{ bool ok = true; if (values.empty()) { logger.error("Enum type must have at least one entry", *this); @@ -165,16 +174,17 @@ void EnumType::addEntry(const std::string &entry, Logger &logger) } if (!values.emplace(entry, nextOrdinalValue).second) { - logger.error(std::string("The enumeration entry ") +entry + - std::string(" was duplicated")); - return; + logger.error(std::string("The enumeration entry ") + entry + + std::string(" was duplicated")); + return; } nextOrdinalValue++; } -void EnumType::addEntries(const std::vector &entries, Logger &logger) +void EnumType::addEntries(const std::vector &entries, + Logger &logger) { - for (const std::string &entry: entries) { + for (const std::string &entry : entries) { addEntry(entry, logger); } } @@ -188,6 +198,16 @@ Rooted EnumType::createValidated( return type; } +std::vector EnumType::names() const +{ + std::vector res; + res.reserve(values.size()); + for (const auto &v : values) { + res.emplace_back(v.first); + } + return res; +} + std::string EnumType::nameOf(Ordinal i) const { if (i >= 0 && i < (int)values.size()) { diff --git a/src/core/model/Typesystem.hpp b/src/core/model/Typesystem.hpp index 819f90d..8e3a3bc 100644 --- a/src/core/model/Typesystem.hpp +++ b/src/core/model/Typesystem.hpp @@ -460,6 +460,11 @@ public: */ Variant create() const override { return Variant{0}; } + /** + * Returns the names of all enum entries. + */ + std::vector names() const; + /** * Returns the name of the given ordinal number. Throws a LoggableException * if the ordinal number is out of range. diff --git a/testdata/xmlparser/generic.oxm b/testdata/xmlparser/generic.oxm index a23d5f8..45803c8 100644 --- a/testdata/xmlparser/generic.oxm +++ b/testdata/xmlparser/generic.oxm @@ -18,11 +18,12 @@ - + +