diff options
-rw-r--r-- | src/core/model/Typesystem.cpp | 36 | ||||
-rw-r--r-- | src/core/model/Typesystem.hpp | 5 | ||||
-rw-r--r-- | 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<std::string> &entries, Logger &logger) +void EnumType::addEntries(const std::vector<std::string> &entries, + Logger &logger) { - for (const std::string &entry: entries) { + for (const std::string &entry : entries) { addEntry(entry, logger); } } @@ -188,6 +198,16 @@ Rooted<EnumType> EnumType::createValidated( return type; } +std::vector<std::string> EnumType::names() const +{ + std::vector<std::string> 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 @@ -461,6 +461,11 @@ public: Variant create() const override { return Variant{0}; } /** + * Returns the names of all enum entries. + */ + std::vector<std::string> 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 @@ <constant name="black" value="[zero, zero, zero]" type="color" /> <struct name="border"> - <field name="color" type="color" default="black" /> <field name="style" type="border-style"/> + <field name="color" type="color" default="black" /> </struct> <constant name="beautifulBorder" type="border" value="[color=aquamarine,style=solid]" /> + <constant name="moreBeautifulBorder" type="border" value="[dotted, azure]" /> </typesystem> <!--<domain name="color"> <struct name="bla" cardinality="{1,2}" isa="blub"/> |