summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-01-15 00:29:11 +0100
committerAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-01-15 00:29:11 +0100
commite99a307bf76689e4e86f8ac1a4c545bcebbdb7ab (patch)
treeb0365ed915763418dbe35485ad74ceb2f3649abc
parentf7326c640690cf5cfee89340db5569ef9b44a652 (diff)
Using Arguments class in ParserStack for validation
-rw-r--r--src/core/parser/ParserStack.cpp17
-rw-r--r--src/core/parser/ParserStack.hpp30
-rw-r--r--test/core/parser/ParserStackTest.cpp82
3 files changed, 76 insertions, 53 deletions
diff --git a/src/core/parser/ParserStack.cpp b/src/core/parser/ParserStack.cpp
index ff2647d..691b9d0 100644
--- a/src/core/parser/ParserStack.cpp
+++ b/src/core/parser/ParserStack.cpp
@@ -47,17 +47,14 @@ void Handler::child(std::shared_ptr<Handler> handler)
HandlerInstance HandlerDescriptor::create(const ParserContext &ctx,
std::string name, State parentState,
bool isChild,
- const Variant &args) const
+ Variant::mapType &args) const
{
Handler *h = ctor(ctx, name, targetState, parentState, isChild);
// Canonicalize the arguments
- Variant arguments = args;
- if (argsType != nullptr) {
- argsType->build(arguments, ctx.logger);
- }
+ arguments.validateMap(args, ctx.logger, true);
- h->start(arguments);
+ h->start(args);
return HandlerInstance(h, this);
}
@@ -95,7 +92,7 @@ std::set<std::string> ParserStack::expectedCommands(State state)
return res;
}
-void ParserStack::start(std::string name, const Variant &args)
+void ParserStack::start(std::string name, Variant::mapType &args)
{
// Fetch the current handler and the current state
const HandlerInstance *h = stack.empty() ? nullptr : &stack.top();
@@ -126,6 +123,12 @@ void ParserStack::start(std::string name, const Variant &args)
stack.emplace(descr->create(ctx, name, curState, isChild, args));
}
+void ParserStack::start(std::string name, const Variant::mapType &args)
+{
+ Variant::mapType argsCopy(args);
+ start(name, argsCopy);
+}
+
void ParserStack::end()
{
// Check whether the current command could be ended
diff --git a/src/core/parser/ParserStack.hpp b/src/core/parser/ParserStack.hpp
index 93180b4..7602139 100644
--- a/src/core/parser/ParserStack.hpp
+++ b/src/core/parser/ParserStack.hpp
@@ -39,7 +39,7 @@
#include <core/common/Variant.hpp>
#include <core/common/Logger.hpp>
-#include <core/model/Typesystem.hpp>
+#include <core/common/Argument.hpp>
#include "Parser.hpp"
@@ -128,7 +128,7 @@ public:
*
* @param args is a map from strings to variants (argument name and value).
*/
- virtual void start(const Variant &args) = 0;
+ virtual void start(const Variant::mapType &args) = 0;
/**
* Called whenever the command for which this handler is defined ends.
@@ -212,10 +212,10 @@ struct HandlerDescriptor {
const bool arbitraryChildren;
/**
- * Pointer pointing at a StructType describing the layout of the given when
- * a new Handler instance is instantiated.
+ * Reference at an argument descriptor that should be used for validating
+ * the incomming arguments.
*/
- const Rooted<model::StructType> argsType;
+ const Arguments arguments;
/**
* Constructor of the HandlerDescriptor class.
@@ -228,17 +228,17 @@ struct HandlerDescriptor {
* instantiating an in instance of the described Handler instances.
* @param arbitraryChildren allows the Handler instance to handle any child
* node.
- * @param argsType is a struct type describing the arguments that can be
- * passed to the Handler or nullptr if no check should be performed.
+ * @param arguments is an optional argument descriptor used for validating
+ * the arguments that are passed to the instantiation of a handler function.
*/
HandlerDescriptor(std::set<State> parentStates, HandlerConstructor ctor,
State targetState, bool arbitraryChildren = false,
- Handle<model::StructType> argsType = nullptr)
+ Arguments arguments = Arguments::None)
: parentStates(std::move(parentStates)),
ctor(ctor),
targetState(targetState),
arbitraryChildren(arbitraryChildren),
- argsType(argsType)
+ arguments(std::move(arguments))
{
}
@@ -248,7 +248,7 @@ struct HandlerDescriptor {
*/
HandlerInstance create(const ParserContext &ctx, std::string name,
State parentState, bool isChild,
- const Variant &args) const;
+ Variant::mapType &args) const;
};
/**
@@ -338,7 +338,15 @@ public:
* @param name is the name of the command.
* @param args is a map from strings to variants (argument name and value).
*/
- void start(std::string name, const Variant &args);
+ void start(std::string name, Variant::mapType &args);
+
+ /**
+ * Function that should be called whenever a new command starts.
+ *
+ * @param name is the name of the command.
+ * @param args is a map from strings to variants (argument name and value).
+ */
+ void start(std::string name, const Variant::mapType &args);
/**
* Function called whenever a command ends.
diff --git a/test/core/parser/ParserStackTest.cpp b/test/core/parser/ParserStackTest.cpp
index a0a4033..08c0548 100644
--- a/test/core/parser/ParserStackTest.cpp
+++ b/test/core/parser/ParserStackTest.cpp
@@ -36,44 +36,35 @@ static int dataCount = 0;
static int childCount = 0;
class TestHandler : public Handler {
-
public:
using Handler::Handler;
- void start(const Variant &args) override
- {
- startCount++;
- }
-
- void end() override
- {
- endCount++;
- }
+ void start(const Variant::mapType &args) override { startCount++; }
- void data(const std::string &data, int field) override
- {
- dataCount++;
- }
+ void end() override { endCount++; }
- void child(std::shared_ptr<Handler> handler) override
- {
- childCount++;
- }
+ void data(const std::string &data, int field) override { dataCount++; }
+ void child(std::shared_ptr<Handler> handler) override { childCount++; }
};
-static Handler* createTestHandler(const ParserContext &ctx,
- std::string name, State state,
- State parentState, bool isChild)
+static Handler *createTestHandler(const ParserContext &ctx, std::string name,
+ State state, State parentState, bool isChild)
{
return new TestHandler(ctx, name, state, parentState, isChild);
}
static const std::multimap<std::string, HandlerDescriptor> TEST_HANDLERS{
- {"document", {{STATE_NONE}, createTestHandler, STATE_DOCUMENT}},
- {"body", {{STATE_DOCUMENT}, createTestHandler, STATE_BODY, true}},
- {"empty", {{STATE_DOCUMENT}, createTestHandler, STATE_EMPTY}},
- {"special", {{STATE_ALL}, createTestHandler, STATE_EMPTY}},
+ {"document", {{STATE_NONE}, createTestHandler, STATE_DOCUMENT}},
+ {"body", {{STATE_DOCUMENT}, createTestHandler, STATE_BODY, true}},
+ {"empty", {{STATE_DOCUMENT}, createTestHandler, STATE_EMPTY}},
+ {"special", {{STATE_ALL}, createTestHandler, STATE_EMPTY}},
+ {"arguments",
+ {{STATE_NONE},
+ createTestHandler,
+ STATE_EMPTY,
+ false,
+ {Argument::Int("a"), Argument::String("b")}}},
};
TEST(ParserStack, simpleTest)
@@ -89,7 +80,7 @@ TEST(ParserStack, simpleTest)
ASSERT_EQ("", s.currentName());
ASSERT_EQ(STATE_NONE, s.currentState());
- s.start("document", nullptr);
+ s.start("document", {});
s.data("test1");
ASSERT_EQ("document", s.currentName());
@@ -97,14 +88,14 @@ TEST(ParserStack, simpleTest)
ASSERT_EQ(1, startCount);
ASSERT_EQ(1, dataCount);
- s.start("body", nullptr);
+ s.start("body", {});
s.data("test2");
ASSERT_EQ("body", s.currentName());
ASSERT_EQ(STATE_BODY, s.currentState());
ASSERT_EQ(2, startCount);
ASSERT_EQ(2, dataCount);
- s.start("inner", nullptr);
+ s.start("inner", {});
ASSERT_EQ("inner", s.currentName());
ASSERT_EQ(STATE_BODY, s.currentState());
s.end();
@@ -119,7 +110,7 @@ TEST(ParserStack, simpleTest)
ASSERT_EQ("document", s.currentName());
ASSERT_EQ(STATE_DOCUMENT, s.currentState());
- s.start("body", nullptr);
+ s.start("body", {});
s.data("test3");
ASSERT_EQ("body", s.currentName());
ASSERT_EQ(STATE_BODY, s.currentState());
@@ -144,12 +135,12 @@ TEST(ParserStack, errorHandling)
StandaloneParserContext ctx;
ParserStack s{ctx, TEST_HANDLERS};
- ASSERT_THROW(s.start("body", nullptr), OusiaException);
- s.start("document", nullptr);
- ASSERT_THROW(s.start("document", nullptr), OusiaException);
- s.start("empty", nullptr);
- ASSERT_THROW(s.start("body", nullptr), OusiaException);
- s.start("special", nullptr);
+ ASSERT_THROW(s.start("body", {}), OusiaException);
+ s.start("document", {});
+ ASSERT_THROW(s.start("document", {}), OusiaException);
+ s.start("empty", {});
+ ASSERT_THROW(s.start("body", {}), OusiaException);
+ s.start("special", {});
s.end();
s.end();
s.end();
@@ -158,6 +149,27 @@ TEST(ParserStack, errorHandling)
ASSERT_THROW(s.data("test", 1), OusiaException);
}
+TEST(ParserStack, validation)
+{
+ ConcreteLogger logger;
+ StandaloneParserContext ctx(logger);
+ ParserStack s{ctx, TEST_HANDLERS};
+
+ s.start("arguments", {});
+ ASSERT_TRUE(logger.hasError());
+ logger.reset();
+ s.end();
+
+ s.start("arguments", {{"a", 5}});
+ ASSERT_TRUE(logger.hasError());
+ logger.reset();
+ s.end();
+
+ s.start("arguments", {{"a", 5}, {"b", "test"}});
+ ASSERT_FALSE(logger.hasError());
+ s.end();
+}
+
}
}