Browse Source

[4093] Use option[123].text rather than option[123] for option text.

Marcin Siodelski 9 years ago
parent
commit
b1cc5e4380
3 changed files with 49 additions and 23 deletions
  1. 2 0
      src/lib/eval/lexer.ll
  2. 34 15
      src/lib/eval/parser.yy
  3. 13 8
      src/lib/eval/tests/context_unittest.cc

+ 2 - 0
src/lib/eval/lexer.ll

@@ -122,6 +122,8 @@ blank [ \t]
 
 "=="        return isc::eval::EvalParser::make_EQUAL(loc);
 "option"    return isc::eval::EvalParser::make_OPTION(loc);
+".text"     return isc::eval::EvalParser::make_DOTTEXT(loc);
+".hex"      return isc::eval::EvalParser::make_DOTHEX(loc);
 "substring" return isc::eval::EvalParser::make_SUBSTRING(loc);
 "all"       return isc::eval::EvalParser::make_ALL(loc);
 "("         return isc::eval::EvalParser::make_LPAREN(loc);

+ 34 - 15
src/lib/eval/parser.yy

@@ -45,6 +45,8 @@ using namespace isc::eval;
   EQUAL "=="
   OPTION "option"
   SUBSTRING "substring"
+  DOTTEXT ".text"
+  DOTHEX ".hex"
   ALL "all"
   COMA ","
   LPAREN  "("
@@ -59,6 +61,35 @@ using namespace isc::eval;
 %token <std::string> TOKEN
 
 %printer { yyoutput << $$; } <*>;
+
+%code
+{
+namespace {
+
+/* Convert option code specified as string to an 16 bit unsigned
+   representation. If the option code is not within the range of
+   0..65535 an error is reported. */
+uint16_t
+convert_option_code(const std::string& option_code,
+                    const isc::eval::EvalParser::location_type& loc,
+                    EvalContext& ctx) {
+    int n = 0;
+    try {
+        n  = boost::lexical_cast<int>(option_code);
+    } catch (const boost::bad_lexical_cast &) {
+        // This can't happen...
+        ctx.error(loc, "Option code has invalid value in " + option_code);
+    }
+    if (n < 0 || n > 65535) {
+        ctx.error(loc, "Option code has invalid value in "
+                      + option_code + ". Allowed range: 0..65535");
+    }
+    return (static_cast<uint16_t>(n));
+}
+}
+
+}
+
 %%
 
 // The whole grammar starts with an expression.
@@ -86,22 +117,10 @@ string_expr : STRING
                       TokenPtr hex(new TokenHexString($1));
                       ctx.expression.push_back(hex);
                   }
-            | OPTION "[" INTEGER "]"
+            | OPTION "[" INTEGER "]" DOTTEXT
                   {
-                      int n = 0;
-                      try {
-                          n  = boost::lexical_cast<int>($3);
-                      } catch (const boost::bad_lexical_cast &) {
-                          // This can't happen...
-                          ctx.error(@3,
-                                    "Option code has invalid value in " + $3);
-                      }
-                      if (n < 0 || n > 65535) {
-                          ctx.error(@3,
-                                    "Option code has invalid value in "
-                                    + $3 + ". Allowed range: 0..65535");
-                      }
-                      TokenPtr opt(new TokenOption(static_cast<uint16_t>(n)));
+                      uint16_t numeric_code = convert_option_code($3, @3, ctx);
+                      TokenPtr opt(new TokenOption(numeric_code));
                       ctx.expression.push_back(opt);
                   }
             | SUBSTRING "(" string_expr "," start_expr "," length_expr ")"

+ 13 - 8
src/lib/eval/tests/context_unittest.cc

@@ -117,7 +117,12 @@ TEST_F(EvalContextTest, basic) {
 
     EvalContext tmp;
 
-    EXPECT_NO_THROW(parsed_ = tmp.parseString("option[123] == 'MSFT'"));
+    try {
+        tmp.parseString("option[123].text == 'MSFT'");
+    } catch (const std::exception& ex) {
+        std::cout << ex.what() << std::endl;
+    }
+    EXPECT_NO_THROW(parsed_ = tmp.parseString("option[123].text == 'MSFT'"));
     EXPECT_TRUE(parsed_);
 }
 
@@ -143,7 +148,7 @@ TEST_F(EvalContextTest, integer) {
     EvalContext eval;
 
     EXPECT_NO_THROW(parsed_ =
-        eval.parseString("substring(option[123], 0, 2) == '42'"));
+        eval.parseString("substring(option[123].text, 0, 2) == '42'"));
     EXPECT_TRUE(parsed_);
 }
 
@@ -198,7 +203,7 @@ TEST_F(EvalContextTest, equal) {
 TEST_F(EvalContextTest, option) {
     EvalContext eval;
 
-    EXPECT_NO_THROW(parsed_ = eval.parseString("option[123] == 'foo'"));
+    EXPECT_NO_THROW(parsed_ = eval.parseString("option[123].text == 'foo'"));
     EXPECT_TRUE(parsed_);
     ASSERT_EQ(3, eval.expression.size());
     checkTokenOption(eval.expression.at(0), 123);
@@ -245,16 +250,16 @@ TEST_F(EvalContextTest, scanParseErrors) {
     checkError("0abc",
                "<string>:1.1: syntax error, unexpected integer");
     checkError("===", "<string>:1.1-2: syntax error, unexpected ==");
-    checkError("option[-1]",
+    checkError("option[-1].text",
                "<string>:1.8-9: Option code has invalid "
                "value in -1. Allowed range: 0..65535");
-    checkError("option[65536]",
+    checkError("option[65536].text",
                "<string>:1.8-12: Option code has invalid "
                "value in 65536. Allowed range: 0..65535");
     checkError("option[12345678901234567890]",
                "<string>:1.8-27: Failed to convert 12345678901234567890 "
                "to an integer.");
-    checkError("option[123] < 'foo'", "<string>:1.13: Invalid character: <");
+    checkError("option[123].text < 'foo'", "<string>:1.18: Invalid character: <");
     checkError("substring('foo',12345678901234567890,1)",
                "<string>:1.17-36: Failed to convert 12345678901234567890 "
                "to an integer.");
@@ -274,11 +279,11 @@ TEST_F(EvalContextTest, parseErrors) {
     checkError("option(10) == 'ab'",
                "<string>:1.7: syntax error, "
                "unexpected (, expecting [");
-    checkError("option['ab'] == 'foo'",
+    checkError("option['ab'].text == 'foo'",
                "<string>:1.8-11: syntax error, "
                "unexpected constant string, "
                "expecting integer");
-    checkError("option[0xa] == 'ab'",
+    checkError("option[0xa].text == 'ab'",
                "<string>:1.8-10: syntax error, "
                "unexpected constant hexstring, "
                "expecting integer");