Parcourir la source

[4088fd] Added hexstring support

Francis Dupont il y a 9 ans
Parent
commit
18906ef111
4 fichiers modifiés avec 61 ajouts et 11 suppressions
  1. 12 6
      src/lib/eval/eval.dox
  2. 8 1
      src/lib/eval/lexer.ll
  3. 12 4
      src/lib/eval/parser.yy
  4. 29 0
      src/lib/eval/tests/context_unittest.cc

+ 12 - 6
src/lib/eval/eval.dox

@@ -75,18 +75,24 @@
 09.    TokenPtr str(new TokenString($1));
 10.    ctx.expression.push_back(str);
 11.}
-12.| OPTION {
-13.    TokenPtr opt(new TokenOption($1));
-14.    ctx.expression.push_back(opt);
-15.};
+12. HEXSTRING {
+13.    TokenPtr hex(new TokenHexString($1));
+14.    ctx.expression.push_back(hex);
+15.}
+16.| OPTION {
+17.    TokenPtr opt(new TokenOption($1));
+18.    ctx.expression.push_back(opt);
+19.}
+20.;
 @endcode
 
 This code determines that the grammar starts from expression (line 1).
 The actual definition of expression (lines 3-5) may either be a
 single token or an expression "token == token" (EQUAL has been defined as
 "==" elsewhere). Token is further
-defined in lines 7-15: it may either be a string (lines 8-11) or option
-(lines 12-15). When the actual case is determined, the respective C++ action
+defined in lines 7-15: it may either be a string (lines 8-11),
+a hex string (lines 12-15) or option (lines 16-19).
+When the actual case is determined, the respective C++ action
 is executed. For example, if the token is a string, the TokenString class is
 instantiated with the appropriate value and put onto the expression vector.
 

+ 8 - 1
src/lib/eval/lexer.ll

@@ -63,8 +63,9 @@ static isc::eval::location loc;
 /* These are not token expressions yet, just convenience expressions that
    can be used during actual token definitions. */
 int   [0-9]+
+hex   [0-9a-fA-F]+
 blank [ \t]
-str [a-zA-Z_0-9]*
+str   [a-zA-Z_0-9]*
 
 %{
 // This code run each time a pattern is matched. It updates the location
@@ -100,6 +101,12 @@ str [a-zA-Z_0-9]*
     return isc::eval::EvalParser::make_STRING(tmp, loc);
 }
 
+0[xX]{hex} {
+    // A hex string has been matched. It contains the '0x' or '0X' header
+    // followed by at least one hexadecimal digit.
+    return isc::eval::EvalParser::make_HEXSTRING(yytext, loc);
+}
+
 option\[{int}\] {
     // option[123] token found. Let's see if the numeric value can be
     // converted to integer and if it has a reasonable value.

+ 12 - 4
src/lib/eval/parser.yy

@@ -53,6 +53,7 @@ using namespace isc::eval;
   RPAREN  ")"
 ;
 %token <std::string> STRING "constant string"
+%token <std::string> HEXSTRING "constant hexstring"
 %token <int> OPTION "option code"
 %printer { yyoutput << $$; } <*>;
 %%
@@ -61,25 +62,32 @@ using namespace isc::eval;
 %start expression;
 
 // Expression can either be a single token or a (something == something) expression
+
 expression:
 token EQUAL token {
     TokenPtr eq(new TokenEqual());
     ctx.expression.push_back(eq);
-}
-| token;
+  }
+| token
+;
 
 token:
 STRING {
     TokenPtr str(new TokenString($1));
     ctx.expression.push_back(str);
-}
+  }
+| HEXSTRING {
+    TokenPtr hex(new TokenHexString($1));
+    ctx.expression.push_back(hex);
+  }
 | OPTION {
     TokenPtr opt(new TokenOption($1));
     ctx.expression.push_back(opt);
-}
+  }
 | SUBSTRING "(" token "," token "," token ")" {
     /* push back TokenSubstring */
   }
+;
 
 %%
 void

+ 29 - 0
src/lib/eval/tests/context_unittest.cc

@@ -45,6 +45,23 @@ public:
         EXPECT_EQ(expected, values.top());
     }
 
+    void checkTokenHexString(const TokenPtr& token,
+			     const std::string& expected) {
+        ASSERT_TRUE(token);
+        boost::shared_ptr<TokenHexString> hex =
+            boost::dynamic_pointer_cast<TokenHexString>(token);
+        ASSERT_TRUE(hex);
+
+        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 checkTokenEq(const TokenPtr& token) {
         ASSERT_TRUE(token);
         boost::shared_ptr<TokenEqual> eq =
@@ -81,6 +98,18 @@ TEST_F(EvalContextTest, string) {
     checkTokenString(tmp, "foo");
 }
 
+TEST_F(EvalContextTest, hexstring) {
+    EvalContext eval;
+
+    EXPECT_NO_THROW(eval.parseString("0x666f6f"));
+
+    ASSERT_EQ(1, eval.expression.size());
+
+    TokenPtr tmp = eval.expression.at(0);
+
+    checkTokenHexString(tmp, "foo");
+}
+
 TEST_F(EvalContextTest, equal) {
     EvalContext eval;