diff --git a/src/lib/eval/eval_context.cc b/src/lib/eval/eval_context.cc index b148297842..5ad51c1d35 100644 --- a/src/lib/eval/eval_context.cc +++ b/src/lib/eval/eval_context.cc @@ -6,8 +6,6 @@ EvalContext::EvalContext() : trace_scanning (false), trace_parsing (false) { - variables["one"] = 1; - variables["two"] = 2; } EvalContext::~EvalContext() diff --git a/src/lib/eval/eval_context.h b/src/lib/eval/eval_context.h index 33a370c713..64249752e9 100644 --- a/src/lib/eval/eval_context.h +++ b/src/lib/eval/eval_context.h @@ -18,7 +18,7 @@ public: EvalContext (); virtual ~EvalContext (); - std::map variables; + isc::dhcp::Expression expression; int result; diff --git a/src/lib/eval/lexer.ll b/src/lib/eval/lexer.ll index f048b49977..e79d229415 100644 --- a/src/lib/eval/lexer.ll +++ b/src/lib/eval/lexer.ll @@ -35,7 +35,7 @@ blank [ \t] {blank}+ loc.step(); [\n]+ loc.lines(yyleng); loc.step(); -\"[a-zA-Z_0-9]*\" { +\'[a-zA-Z_0-9]*\' { // This is a string, no need to do any conversions here. return isc::eval::EvalParser::make_STRING(yytext, loc); } diff --git a/src/lib/eval/parser.yy b/src/lib/eval/parser.yy index cc62168592..87468a48bb 100644 --- a/src/lib/eval/parser.yy +++ b/src/lib/eval/parser.yy @@ -11,6 +11,8 @@ #include #include class EvalContext; + +using namespace isc::dhcp; } // The parsing context. %param { EvalContext& ctx } @@ -45,12 +47,21 @@ class EvalContext; // Expression can either be a single token or a (something == something) expression expression: -token EQUAL token +token EQUAL token { + TokenPtr eq(new TokenEqual()); + ctx.expression.push_back(eq); +} | token; token: -STRING { /* push back TokenString */ } -| OPTION { /* push back TokenOption */ } +STRING { + TokenPtr str(new TokenString($1)); + ctx.expression.push_back(str); +} +| OPTION { + TokenPtr opt(new TokenOption($1)); + ctx.expression.push_back(opt); +} | SUBSTRING "(" token "," token "," token ")" { /* push back TokenSubstring */ } diff --git a/src/lib/eval/tests/context_unittest.cc b/src/lib/eval/tests/context_unittest.cc index 01f42d326a..9bb673c12f 100644 --- a/src/lib/eval/tests/context_unittest.cc +++ b/src/lib/eval/tests/context_unittest.cc @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include @@ -25,12 +27,64 @@ using namespace isc::dhcp; namespace { -TEST(EvalContextTest, basic) { +class EvalContextTest : public ::testing::Test { +public: + void checkStringToken(const TokenPtr& token, const std::string& expected) { + ASSERT_TRUE(token); + boost::shared_ptr str = boost::dynamic_pointer_cast(token); + ASSERT_TRUE(str); + + Pkt4Ptr pkt4(new Pkt4(DHCPDISCOVER, 12345)); + ValueStack values; + + EXPECT_NO_THROW(token->evaluate(*pkt4, values)); + + ASSERT_EQ(1, values.size()); + + EXPECT_EQ(expected, values.top()); + } + + void checkEqToken(const TokenPtr& token) { + ASSERT_TRUE(token); + boost::shared_ptr eq = boost::dynamic_pointer_cast(token); + EXPECT_TRUE(eq); + } + +}; + +TEST_F(EvalContextTest, basic) { EvalContext tmp; - EXPECT_NO_THROW(tmp.parseString("option[123] == \"MSFT\"")); + EXPECT_NO_THROW(tmp.parseString("option[123] == 'MSFT'")); } +TEST_F(EvalContextTest, string) { + EvalContext eval; + + EXPECT_NO_THROW(eval.parseString("'foo'")); + + ASSERT_EQ(1, eval.expression.size()); + + TokenPtr tmp = eval.expression.at(0); + + checkStringToken(tmp, "foo"); +} + +TEST_F(EvalContextTest, equal) { + EvalContext eval; + + EXPECT_NO_THROW(eval.parseString("'foo' == 'bar'")); + + ASSERT_EQ(3, eval.expression.size()); + + TokenPtr tmp1 = eval.expression.at(0); + TokenPtr tmp2 = eval.expression.at(1); + TokenPtr tmp3 = eval.expression.at(2); + + checkStringToken(tmp1, "foo"); + checkStringToken(tmp2, "bar"); + checkEqToken(tmp3); +} };