]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3502] Checkpoint: changed strict- by s
authorFrancis Dupont <fdupont@isc.org>
Wed, 7 Aug 2024 17:54:07 +0000 (19:54 +0200)
committerFrancis Dupont <fdupont@isc.org>
Wed, 21 Aug 2024 13:12:38 +0000 (15:12 +0200)
src/lib/eval/lexer.ll
src/lib/eval/parser.yy
src/lib/eval/tests/boolean_unittest.cc
src/lib/eval/tests/context_unittest.cc

index 719d3ff1310277161055fa5affa2aa1bd5df94b2..b948271a25f8e68eeb8fe6131a98bdd0da8e2fe7 100644 (file)
@@ -221,7 +221,7 @@ addr6 [0-9a-fA-F]*\:[0-9a-fA-F]*\:[0-9a-fA-F:.]*
 "all"          return isc::eval::EvalParser::make_ALL(loc);
 "concat"       return isc::eval::EvalParser::make_CONCAT(loc);
 "ifelse"       return isc::eval::EvalParser::make_IFELSE(loc);
-"strict-ifelse"  return isc::eval::EvalParser::make_STRICT_IFELSE(loc);
+"sifelse"      return isc::eval::EvalParser::make_SIFELSE(loc);
 "hexstring"    return isc::eval::EvalParser::make_TOHEXSTRING(loc);
 "addrtotext"   return isc::eval::EvalParser::make_ADDRTOTEXT(loc);
 "int8totext"   return isc::eval::EvalParser::make_INT8TOTEXT(loc);
@@ -232,9 +232,9 @@ addr6 [0-9a-fA-F]*\:[0-9a-fA-F]*\:[0-9a-fA-F:.]*
 "uint32totext" return isc::eval::EvalParser::make_UINT32TOTEXT(loc);
 "not"          return isc::eval::EvalParser::make_NOT(loc);
 "and"          return isc::eval::EvalParser::make_AND(loc);
-"strict-and"   return isc::eval::EvalParser::make_STRICT_AND(loc);
+"sand"         return isc::eval::EvalParser::make_SAND(loc);
 "or"           return isc::eval::EvalParser::make_OR(loc);
-"strict-or"    return isc::eval::EvalParser::make_STRICT_OR(loc);
+"sor"          return isc::eval::EvalParser::make_SOR(loc);
 "member"       return isc::eval::EvalParser::make_MEMBER(loc);
 "match"        return isc::eval::EvalParser::make_MATCH(loc);
 "."            return isc::eval::EvalParser::make_DOT(loc);
index 65573e723c2d857b4b91b7f19365846b65ea8022..59fdaa74b534ffdca6316de5b8b10988abf29ebe 100644 (file)
@@ -47,9 +47,9 @@ using namespace isc::eval;
   RPAREN  ")"
   NOT "not"
   AND "and"
-  STRICT_AND "strict-and"
+  SAND "sand"
   OR "or"
-  STRICT_OR "strict-or"
+  SOR "sor"
   EQUAL "=="
   OPTION "option"
   RELAY4 "relay4"
@@ -83,7 +83,7 @@ using namespace isc::eval;
   CONCAT "concat"
   PLUS "+"
   IFELSE "ifelse"
-  STRICT_IFELSE "strict-ifelse"
+  SIFELSE "sifelse"
   TOHEXSTRING "hexstring"
   ADDRTOTEXT "addrtotext"
   INT8TOTEXT "int8totext"
@@ -126,9 +126,9 @@ using namespace isc::eval;
 %type <TokenPkt6::FieldType> pkt6_field
 
 %left PLUS
-%left STRICT_OR
+%left SOR
 %left OR
-%left STRICT_AND
+%left SAND
 %left AND
 %precedence NOT
 
@@ -161,7 +161,7 @@ bool_expr : "(" bool_expr ")"
                     TokenPtr neg(new TokenAnd());
                     ctx.expression.push_back(neg);
                 }
-          | bool_expr STRICT_AND bool_expr
+          | bool_expr SAND bool_expr
                 {
                     TokenPtr neg(new TokenAnd());
                     ctx.expression.push_back(neg);
@@ -171,7 +171,7 @@ bool_expr : "(" bool_expr ")"
                     TokenPtr neg(new TokenOr());
                     ctx.expression.push_back(neg);
                 }
-          | bool_expr STRICT_OR bool_expr
+          | bool_expr SOR bool_expr
                 {
                     TokenPtr neg(new TokenOr());
                     ctx.expression.push_back(neg);
@@ -423,7 +423,7 @@ string_expr : STRING
                       TokenPtr cond(new TokenIfElse());
                       ctx.expression.push_back(cond);
                   }
-            | STRICT_IFELSE "(" bool_expr "," string_expr "," string_expr ")"
+            | SIFELSE "(" bool_expr "," string_expr "," string_expr ")"
                   {
                       TokenPtr cond(new TokenIfElse());
                       ctx.expression.push_back(cond);
index f620daeca45f48299369ef4d156eff1fb637eea2..8c883c155f742b1079d0a786c453176faceac690 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2024 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -34,7 +34,34 @@ public:
     }
 };
 
-// A group of tests
+// A group of tests (strict version)
+TEST_F(BooleanTest, strict) {
+    // true and (false or false)
+    check("('a' == 'a') sand (('a' == 'b') sor ('b' == 'a'))", false);
+    // (true and false) or false
+    check("(('a' == 'a') sand ('a' == 'b')) sor ('b' == 'a')", false);
+    // not true
+    check("not ('a' == 'a')", false);
+    // not false
+    check("not ('a' == 'b')", true);
+    // true and true and true and false
+    check("('a' == 'a') sand ('b' == 'b') sand ('c' == 'c') sand ('a' == 'c')",
+          false);
+    // false or false or false or true
+    check("('a' == 'b') sor ('a' == 'c') sor ('b' == 'c') sor ('b' == 'b')",
+          true);
+    // true or false or false or false
+    check("('a' == 'a') sor ('a' == 'b') sor ('a' == 'c') sor ('b' == 'c')",
+          true);
+    // not (true or false)
+    check("not (('a' == 'a') sor ('a' == 'b'))", false);
+    // not (true and false)
+    check("not (('a' == 'a') sand ('a' == 'b'))", true);
+    // (not true) and false
+    check("(not ('a' == 'a')) sand ('a' == 'b')",false);
+}
+
+// A group of tests (strict version)
 TEST_F(BooleanTest, tests) {
     // true and (false or false)
     check("('a' == 'a') and (('a' == 'b') or ('b' == 'a'))", false);
@@ -61,4 +88,4 @@ TEST_F(BooleanTest, tests) {
     check("(not ('a' == 'a')) and ('a' == 'b')",false);
 }
 
-};
+}
index ca2ce3da1e02cecba6189c0d43333709f319aa02..0bea61b772c67a61f82dce223ab00fdf7c8bde21 100644 (file)
@@ -1333,6 +1333,31 @@ TEST_F(EvalContextTest, logicalOps) {
         boost::dynamic_pointer_cast<TokenNot>(token);
     EXPECT_TRUE(tnot);
 
+    // sand
+    EvalContext evala(Option::V4);
+    EXPECT_NO_THROW(parsed_ =
+        evala.parseString("option[123].exists sand option[123].exists"));
+    EXPECT_TRUE(parsed_);
+    ASSERT_EQ(3, evala.expression.size());
+    token = evala.expression.at(2);
+    ASSERT_TRUE(token);
+    boost::shared_ptr<TokenAnd> tand =
+        boost::dynamic_pointer_cast<TokenAnd>(token);
+    EXPECT_TRUE(tand);
+
+    // sor
+    EvalContext evalo(Option::V4);
+    EXPECT_NO_THROW(parsed_ =
+        evalo.parseString("option[123].exists sor option[123].exists"));
+    EXPECT_TRUE(parsed_);
+    ASSERT_EQ(3, evalo.expression.size());
+    token = evalo.expression.at(2);
+    ASSERT_TRUE(token);
+    boost::shared_ptr<TokenOr> tor =
+        boost::dynamic_pointer_cast<TokenOr>(token);
+    EXPECT_TRUE(tor);
+
+#if notyet
     // and
     EvalContext evala(Option::V4);
     EXPECT_NO_THROW(parsed_ =
@@ -1356,10 +1381,37 @@ TEST_F(EvalContextTest, logicalOps) {
     boost::shared_ptr<TokenOr> tor =
         boost::dynamic_pointer_cast<TokenOr>(token);
     EXPECT_TRUE(tor);
+#endif
 }
 
 // Test parsing of logical operators with precedence
 TEST_F(EvalContextTest, logicalPrecedence) {
+    // not precedence > and precedence
+    EvalContext evalna(Option::V4);
+    EXPECT_NO_THROW(parsed_ =
+        evalna.parseString("not option[123].exists sand option[123].exists"));
+    EXPECT_TRUE(parsed_);
+    ASSERT_EQ(4, evalna.expression.size());
+    TokenPtr token = evalna.expression.at(3);
+    ASSERT_TRUE(token);
+    boost::shared_ptr<TokenAnd> tand =
+        boost::dynamic_pointer_cast<TokenAnd>(token);
+    EXPECT_TRUE(tand);
+
+    // and precedence > or precedence
+    EvalContext evaloa(Option::V4);
+    EXPECT_NO_THROW(parsed_ =
+        evaloa.parseString("option[123].exists sor option[123].exists "
+                           "and option[123].exists"));
+    EXPECT_TRUE(parsed_);
+    ASSERT_EQ(5, evaloa.expression.size());
+    token = evaloa.expression.at(4);
+    ASSERT_TRUE(token);
+    boost::shared_ptr<TokenOr> tor =
+        boost::dynamic_pointer_cast<TokenOr>(token);
+    EXPECT_TRUE(tor);
+
+#if notyet
     // not precedence > and precedence
     EvalContext evalna(Option::V4);
     EXPECT_NO_THROW(parsed_ =
@@ -1384,11 +1436,38 @@ TEST_F(EvalContextTest, logicalPrecedence) {
     boost::shared_ptr<TokenOr> tor =
         boost::dynamic_pointer_cast<TokenOr>(token);
     EXPECT_TRUE(tor);
+#endif
 }
 
 // Test parsing of logical operators with parentheses (same than
 // with precedence but using parentheses to overwrite precedence)
 TEST_F(EvalContextTest, logicalParentheses) {
+    // not precedence > and precedence
+    EvalContext evalna(Option::V4);
+    EXPECT_NO_THROW(parsed_ =
+        evalna.parseString("not (option[123].exists sand option[123].exists)"));
+    EXPECT_TRUE(parsed_);
+    ASSERT_EQ(4, evalna.expression.size());
+    TokenPtr token = evalna.expression.at(3);
+    ASSERT_TRUE(token);
+    boost::shared_ptr<TokenNot> tnot =
+        boost::dynamic_pointer_cast<TokenNot>(token);
+    EXPECT_TRUE(tnot);
+
+    // and precedence > or precedence
+    EvalContext evaloa(Option::V4);
+    EXPECT_NO_THROW(parsed_ =
+        evaloa.parseString("(option[123].exists sor option[123].exists) "
+                           "sand option[123].exists"));
+    EXPECT_TRUE(parsed_);
+    ASSERT_EQ(5, evaloa.expression.size());
+    token = evaloa.expression.at(4);
+    ASSERT_TRUE(token);
+    boost::shared_ptr<TokenAnd> tand =
+        boost::dynamic_pointer_cast<TokenAnd>(token);
+    EXPECT_TRUE(tand);
+
+#if notyet
     // not precedence > and precedence
     EvalContext evalna(Option::V4);
     EXPECT_NO_THROW(parsed_ =
@@ -1413,6 +1492,7 @@ TEST_F(EvalContextTest, logicalParentheses) {
     boost::shared_ptr<TokenAnd> tand =
         boost::dynamic_pointer_cast<TokenAnd>(token);
     EXPECT_TRUE(tand);
+#endif
 }
 
 // Test the parsing of a substring expression
@@ -1519,7 +1599,28 @@ TEST_F(EvalContextTest, assocRightPlus) {
     checkTokenConcat(tmp5);
 }
 
+// Test the parsing of a sifelse expression
+TEST_F(EvalContextTest, strictIfElse) {
+    EvalContext eval(Option::V4);
+
+    EXPECT_NO_THROW(parsed_ =
+        eval.parseString("sifelse('foo' == 'bar', 'us', 'them') == 'you'"));
+
+    ASSERT_EQ(8, eval.expression.size());
+
+    TokenPtr tmp1 = eval.expression.at(2);
+    TokenPtr tmp2 = eval.expression.at(3);
+    TokenPtr tmp3 = eval.expression.at(4);
+    TokenPtr tmp4 = eval.expression.at(5);
+
+    checkTokenEq(tmp1);
+    checkTokenString(tmp2, "us");
+    checkTokenString(tmp3, "them");
+    checkTokenIfElse(tmp4);
+}
+
 // Test the parsing of an ifelse expression
+#if notyet
 TEST_F(EvalContextTest, ifElse) {
     EvalContext eval(Option::V4);
 
@@ -1538,8 +1639,38 @@ TEST_F(EvalContextTest, ifElse) {
     checkTokenString(tmp3, "them");
     checkTokenIfElse(tmp4);
 }
+#endif
+
+// Test the parsing of a plus operator and sifelse expression
+TEST_F(EvalContextTest, plusStrictIfElse) {
+    EvalContext eval(Option::V4);
+
+    EXPECT_NO_THROW(parsed_ =
+        eval.parseString("'foo' + sifelse('a' == 'a', 'bar', '') == 'foobar'"));
+
+    ASSERT_EQ(10, eval.expression.size());
+
+    TokenPtr tmp1 = eval.expression.at(0);
+    TokenPtr tmp2 = eval.expression.at(1);
+    TokenPtr tmp3 = eval.expression.at(2);
+    TokenPtr tmp4 = eval.expression.at(3);
+    TokenPtr tmp5 = eval.expression.at(4);
+    TokenPtr tmp6 = eval.expression.at(5);
+    TokenPtr tmp7 = eval.expression.at(6);
+    TokenPtr tmp8 = eval.expression.at(7);
+
+    checkTokenString(tmp1, "foo");
+    checkTokenString(tmp2, "a");
+    checkTokenString(tmp3, "a");
+    checkTokenEq(tmp4);
+    checkTokenString(tmp5, "bar");
+    checkTokenString(tmp6, "");
+    checkTokenIfElse(tmp7);
+    checkTokenConcat(tmp8);
+}
 
 // Test the parsing of a plus operator and ifelse expression
+#if notyet
 TEST_F(EvalContextTest, plusIfElse) {
     EvalContext eval(Option::V4);
 
@@ -1566,6 +1697,7 @@ TEST_F(EvalContextTest, plusIfElse) {
     checkTokenIfElse(tmp7);
     checkTokenConcat(tmp8);
 }
+#endif
 
 // Test the parsing of a hexstring expression
 TEST_F(EvalContextTest, toHexString) {