summaryrefslogtreecommitdiff
path: root/src/core/common
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-02-16 11:39:03 +0100
committerAndreas Stöckel <andreas@somweyr.de>2015-02-16 11:39:03 +0100
commit0a60bc28b222451a5ed20318ceff3a93564d5d8e (patch)
tree519b07eba0db710a47a351865f93b98b4f686d09 /src/core/common
parent39fa4b6d0f6492c46b83489e16a7cbdbf279bbda (diff)
Implemented support for numeric arguments in Argument
Diffstat (limited to 'src/core/common')
-rw-r--r--src/core/common/Argument.cpp51
-rw-r--r--src/core/common/Argument.hpp11
2 files changed, 50 insertions, 12 deletions
diff --git a/src/core/common/Argument.cpp b/src/core/common/Argument.cpp
index b10fad3..ee129a3 100644
--- a/src/core/common/Argument.cpp
+++ b/src/core/common/Argument.cpp
@@ -54,7 +54,8 @@ Argument Argument::Any(std::string name)
Argument Argument::Any(std::string name, Variant defaultValue)
{
- return Argument{name, &RttiTypes::None, &RttiTypes::None, defaultValue, true};
+ return Argument{name, &RttiTypes::None, &RttiTypes::None, defaultValue,
+ true};
}
Argument Argument::Bool(std::string name)
@@ -95,7 +96,8 @@ Argument Argument::String(std::string name)
Argument Argument::String(std::string name,
const Variant::stringType &defaultValue)
{
- return Argument{name, &RttiTypes::String, Variant::fromString(defaultValue)};
+ return Argument{name, &RttiTypes::String,
+ Variant::fromString(defaultValue)};
}
Argument Argument::Object(std::string name, const Rtti *type)
@@ -158,7 +160,8 @@ Argument Argument::Map(std::string name, const Variant::mapType &defaultValue)
Argument Argument::Map(std::string name, const Rtti *innerType)
{
- return Argument(std::move(name), &RttiTypes::Map, innerType, nullptr, false);
+ return Argument(std::move(name), &RttiTypes::Map, innerType, nullptr,
+ false);
}
Argument Argument::Map(std::string name, const Rtti *innerType,
@@ -276,7 +279,7 @@ bool Arguments::validateArray(Variant::arrayType &arr, Logger &logger) const
}
bool Arguments::validateMap(Variant::mapType &map, Logger &logger,
- bool ignoreUnknown) const
+ bool ignoreUnknown, bool allowNumericIndices) const
{
// Abort if no arguments were explicitly given -- everything is valid
if (!valid) {
@@ -289,28 +292,60 @@ bool Arguments::validateMap(Variant::mapType &map, Logger &logger,
const size_t N = arguments.size();
std::vector<bool> set(N);
bool ok = true;
+ std::unordered_map<std::string, std::string> keyReplacements;
// Iterate over the map entries and search for the corresponding argument
for (auto &e : map) {
// Check whether an argument with the name of the current entry exists
- auto it = names.find(e.first);
+ const std::string &key = e.first;
+ auto it = names.find(key);
+ ssize_t idx = -1;
if (it != names.end()) {
// Fetch the corresponding index in the "arguments" array
- size_t idx = it->second;
+ idx = it->second;
+ } else if (!key.empty() && key[0] == '#' && allowNumericIndices) {
+ // Read the numeric index
+ try {
+ size_t i = stoul(key.substr(1));
+ if (i >= 0 && i < arguments.size()) {
+ idx = i;
+ keyReplacements.emplace(key, arguments[i].getName());
+ } else {
+ ok = false;
+ }
+ }
+ catch (std::exception ex) {
+ logger.error(
+ std::string("Invalid key \"") + key + std::string("\""),
+ e.second);
+ ok = false;
+ }
+ }
+
+ // If the key could be resolved to an index, validate the argument
+ if (idx >= 0) {
set[idx] = arguments[idx].validate(e.second, logger);
ok = ok && set[idx];
} else {
if (ignoreUnknown) {
logger.note(std::string("Ignoring argument \"") + e.first +
- std::string("\""), e.second);
+ std::string("\""),
+ e.second);
} else {
logger.error(std::string("Unknown argument \"") + e.first +
- std::string("\""), e.second);
+ std::string("\""),
+ e.second);
ok = false;
}
}
}
+ // Execute all the key replacements
+ for (const auto &replacement : keyReplacements) {
+ map[replacement.second] = std::move(map[replacement.first]);
+ map.erase(replacement.first);
+ }
+
// Insert all unset arguments
for (size_t a = 0; a < N; a++) {
if (!set[a]) {
diff --git a/src/core/common/Argument.hpp b/src/core/common/Argument.hpp
index 679b4a5..39b3bb6 100644
--- a/src/core/common/Argument.hpp
+++ b/src/core/common/Argument.hpp
@@ -61,13 +61,13 @@ private:
/**
* Type that should be returned by the Variant rttiType function.
*/
- Rtti const* type;
+ Rtti const *type;
/**
* Describes the inner type of the variant -- e.g. the type of the elements
* inside an array. Normally set to RttiTypes::None.
*/
- Rtti const* innerType;
+ Rtti const *innerType;
/**
* Default value. Note that a value of nullptr does not indicate that no
@@ -421,7 +421,7 @@ public:
* @return the default value that was given in the constructor (may be
* nullptr) and nullptr if no default value was given.
*/
- const Variant& getDefaultValue() const;
+ const Variant &getDefaultValue() const;
/**
* Returns true if a default value was set in the constructor.
@@ -502,10 +502,13 @@ public:
* @param ignoreUnknown if set to true, unknown map entries are ignored
* (a note is issued). This behaviour can be usefull if forward
* compatibility must be achieved (such as for XML based formats).
+ * @param allowNumericIndices if set to true, allows numeric indices in the
+ * input map (such as "#1").
* @return true if the operation was successful, false if an error occured.
*/
bool validateMap(Variant::mapType &map, Logger &logger,
- bool ignoreUnknown = false) const;
+ bool ignoreUnknown = false,
+ bool allowNumericIndices = false) const;
};
}