summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-02-04 02:04:34 +0100
committerAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-02-04 02:04:34 +0100
commita8a911a73793d42f8d39d7a1babf4eb4a9965a5e (patch)
treef99dddae207e37980bd0dabd68e5ea64a93c9022
parent835cca85ee45dd1b6722d761999c07c33fb97cc9 (diff)
Improved enum related error messages
-rw-r--r--src/core/model/Typesystem.cpp36
-rw-r--r--src/core/model/Typesystem.hpp5
-rw-r--r--testdata/xmlparser/generic.oxm3
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"/>