Browse Source

[5017] Distribute new example files

Francis Dupont 8 years ago
parent
commit
cb935c8202

+ 3 - 0
doc/Makefile.am

@@ -10,6 +10,7 @@ nobase_dist_doc_DATA  = examples/ddns/sample1.json
 nobase_dist_doc_DATA += examples/ddns/template.json
 nobase_dist_doc_DATA += examples/ddns/template.json
 nobase_dist_doc_DATA += examples/kea4/backends.json
 nobase_dist_doc_DATA += examples/kea4/backends.json
 nobase_dist_doc_DATA += examples/kea4/classify.json
 nobase_dist_doc_DATA += examples/kea4/classify.json
+nobase_dist_doc_DATA += examples/kea4/dhcpv4-over-dhcpv6.json
 nobase_dist_doc_DATA += examples/kea4/hooks.json
 nobase_dist_doc_DATA += examples/kea4/hooks.json
 nobase_dist_doc_DATA += examples/kea4/leases-expiration.json
 nobase_dist_doc_DATA += examples/kea4/leases-expiration.json
 nobase_dist_doc_DATA += examples/kea4/multiple-options.json
 nobase_dist_doc_DATA += examples/kea4/multiple-options.json
@@ -21,6 +22,8 @@ nobase_dist_doc_DATA += examples/kea4/single-subnet.json
 nobase_dist_doc_DATA += examples/kea6/advanced.json
 nobase_dist_doc_DATA += examples/kea6/advanced.json
 nobase_dist_doc_DATA += examples/kea6/backends.json
 nobase_dist_doc_DATA += examples/kea6/backends.json
 nobase_dist_doc_DATA += examples/kea6/classify.json
 nobase_dist_doc_DATA += examples/kea6/classify.json
+nobase_dist_doc_DATA += examples/kea6/dhcpv4-over-dhcpv6.json
+nobase_dist_doc_DATA += examples/kea6/duid.json
 nobase_dist_doc_DATA += examples/kea6/hooks.json
 nobase_dist_doc_DATA += examples/kea6/hooks.json
 nobase_dist_doc_DATA += examples/kea6/leases-expiration.json
 nobase_dist_doc_DATA += examples/kea6/leases-expiration.json
 nobase_dist_doc_DATA += examples/kea6/multiple-options.json
 nobase_dist_doc_DATA += examples/kea6/multiple-options.json

+ 43 - 2
src/bin/dhcp4/dhcp4_lexer.ll

@@ -926,6 +926,7 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
     std::string decoded;
     std::string decoded;
     decoded.reserve(len);
     decoded.reserve(len);
     for (size_t pos = 0; pos < len; ++pos) {
     for (size_t pos = 0; pos < len; ++pos) {
+        int b = 0;
         char c = raw[pos];
         char c = raw[pos];
         switch (c) {
         switch (c) {
         case '"':
         case '"':
@@ -960,8 +961,42 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
                 decoded.push_back('\t');
                 decoded.push_back('\t');
                 break;
                 break;
             case 'u':
             case 'u':
-                // not yet implemented
-                driver.error(driver.loc_, "Unsupported unicode escape in \"" + raw + "\"");
+                // support only \u0000 to \u00ff
+                ++pos;
+                if (pos + 4 > len) {
+                    // impossible condition
+                    driver.error(driver.loc_,
+                                 "Overflow unicode escape in \"" + raw + "\"");
+                }
+                if ((raw[pos] != '0') || (raw[pos + 1] != '0')) {
+                    driver.error(driver.loc_, "Unsupported unicode escape in \"" + raw + "\"");
+                }
+                pos += 2;
+                c = raw[pos];
+                if ((c >= '0') && (c <= '9')) {
+                    b = (c - '0') << 4;
+                } else if ((c >= 'A') && (c <= 'F')) {
+                    b = (c - 'A' + 10) << 4;
+                } else if ((c >= 'a') && (c <= 'f')) {
+                    b = (c - 'a' + 10) << 4;
+                } else {
+                    // impossible condition
+                    driver.error(driver.loc_, "Not hexadecimal in unicode escape in \"" + raw + "\"");
+                }
+                pos++;
+                c = raw[pos];
+                if ((c >= '0') && (c <= '9')) {
+                    b |= c - '0';
+                } else if ((c >= 'A') && (c <= 'F')) {
+                    b |= c - 'A' + 10;
+                } else if ((c >= 'a') && (c <= 'f')) {
+                    b |= c - 'a' + 10;
+                } else {
+                    // impossible condition
+                    driver.error(driver.loc_, "Not hexadecimal in unicode escape in \"" + raw + "\"");
+                }
+                decoded.push_back(static_cast<char>(b & 0xff));
+                break;
             default:
             default:
                 // impossible condition
                 // impossible condition
                 driver.error(driver.loc_, "Bad escape in \"" + raw + "\"");
                 driver.error(driver.loc_, "Bad escape in \"" + raw + "\"");
@@ -1041,6 +1076,12 @@ null {
    return isc::dhcp::Dhcp4Parser::make_NULL_TYPE(driver.loc_);
    return isc::dhcp::Dhcp4Parser::make_NULL_TYPE(driver.loc_);
 }
 }
 
 
+(?i:true) driver.error (driver.loc_, "JSON true reserved keyword is lower case only");
+
+(?i:false) driver.error (driver.loc_, "JSON false reserved keyword is lower case only");
+
+(?i:null) driver.error (driver.loc_, "JSON null reserved keyword is lower case only");
+
 <*>.   driver.error (driver.loc_, "Invalid character: " + std::string(yytext));
 <*>.   driver.error (driver.loc_, "Invalid character: " + std::string(yytext));
 
 
 <<EOF>> {
 <<EOF>> {

+ 55 - 9
src/bin/dhcp4/tests/parser_unittest.cc

@@ -31,8 +31,8 @@ void testParser(const std::string& txt, Parser4Context::ParserType parser_type)
     ASSERT_NO_THROW(reference_json = Element::fromJSON(txt, true));
     ASSERT_NO_THROW(reference_json = Element::fromJSON(txt, true));
     ASSERT_NO_THROW({
     ASSERT_NO_THROW({
             try {
             try {
-        Parser4Context ctx;
-        test_json = ctx.parseString(txt, parser_type);
+                Parser4Context ctx;
+                test_json = ctx.parseString(txt, parser_type);
             } catch (const std::exception &e) {
             } catch (const std::exception &e) {
                 cout << "EXCEPTION: " << e.what() << endl;
                 cout << "EXCEPTION: " << e.what() << endl;
                 throw;
                 throw;
@@ -49,8 +49,8 @@ void testParser2(const std::string& txt, Parser4Context::ParserType parser_type)
 
 
     ASSERT_NO_THROW({
     ASSERT_NO_THROW({
             try {
             try {
-        Parser4Context ctx;
-        test_json = ctx.parseString(txt, parser_type);
+                Parser4Context ctx;
+                test_json = ctx.parseString(txt, parser_type);
             } catch (const std::exception &e) {
             } catch (const std::exception &e) {
                 cout << "EXCEPTION: " << e.what() << endl;
                 cout << "EXCEPTION: " << e.what() << endl;
                 throw;
                 throw;
@@ -323,13 +323,22 @@ TEST(ParserTest, errors) {
               Parser4Context::PARSER_JSON,
               Parser4Context::PARSER_JSON,
               "Can't open include file /foo/bar");
               "Can't open include file /foo/bar");
 
 
-    // case sensitivity
+    // JSON keywords
     testError("{ \"foo\": True }",
     testError("{ \"foo\": True }",
               Parser4Context::PARSER_JSON,
               Parser4Context::PARSER_JSON,
+              "<string>:1.10-13: JSON true reserved keyword is lower case only");
+    testError("{ \"foo\": False }",
+              Parser4Context::PARSER_JSON,
+              "<string>:1.10-14: JSON false reserved keyword is lower case only");
+    testError("{ \"foo\": NULL }",
+              Parser4Context::PARSER_JSON,
+              "<string>:1.10-13: JSON null reserved keyword is lower case only");
+    testError("{ \"foo\": Tru }",
+              Parser4Context::PARSER_JSON,
               "<string>:1.10: Invalid character: T");
               "<string>:1.10: Invalid character: T");
-    testError("{ \"foo\": NULL  }",
+    testError("{ \"foo\": nul }",
               Parser4Context::PARSER_JSON,
               Parser4Context::PARSER_JSON,
-              "<string>:1.10: Invalid character: N");
+              "<string>:1.10: Invalid character: n");
 
 
     // numbers
     // numbers
     testError("123",
     testError("123",
@@ -379,9 +388,9 @@ TEST(ParserTest, errors) {
     testError("\"a\\x01b\"",
     testError("\"a\\x01b\"",
               Parser4Context::PARSER_JSON,
               Parser4Context::PARSER_JSON,
               "<string>:1.1-8: Bad escape in \"a\\x01b\"");
               "<string>:1.1-8: Bad escape in \"a\\x01b\"");
-    testError("\"a\\u0062\"",
+    testError("\"a\\u0162\"",
               Parser4Context::PARSER_JSON,
               Parser4Context::PARSER_JSON,
-              "<string>:1.1-9: Unsupported unicode escape in \"a\\u0062\"");
+              "<string>:1.1-9: Unsupported unicode escape in \"a\\u0162\"");
     testError("\"a\\u062z\"",
     testError("\"a\\u062z\"",
               Parser4Context::PARSER_JSON,
               Parser4Context::PARSER_JSON,
               "<string>:1.1-9: Bad escape in \"a\\u062z\"");
               "<string>:1.1-9: Bad escape in \"a\\u062z\"");
@@ -469,4 +478,41 @@ TEST(ParserTest, errors) {
               "\"valid_lifetime\" in Dhcp4 map.");
               "\"valid_lifetime\" in Dhcp4 map.");
 }
 }
 
 
+// Check unicode escapes
+TEST(ParserTest, unicodeEscapes) {
+    ConstElementPtr result;
+    string json;
+
+    // check we can reread output
+    for (char c = -128; c < 127; ++c) {
+        string ins(" ");
+        ins[1] = c;
+        ConstElementPtr e(new StringElement(ins));
+        json = e->str();
+        ASSERT_NO_THROW(
+        try {
+            Parser4Context ctx;
+            result = ctx.parseString(json, Parser4Context::PARSER_JSON);
+        } catch (const std::exception &x) {
+            cout << "EXCEPTION: " << x.what() << endl;
+            throw;
+        });
+        ASSERT_EQ(Element::string, result->getType());
+        EXPECT_EQ(ins, result->stringValue());
+    }
+
+    // check the 4 possible encodings of solidus '/'
+    json = "\"/\\/\\u002f\\u002F\"";
+    ASSERT_NO_THROW(
+    try {
+        Parser4Context ctx;
+        result = ctx.parseString(json, Parser4Context::PARSER_JSON);
+    } catch (const std::exception &x) {
+        cout << "EXCEPTION: " << x.what() << endl;
+        throw;
+    });
+    ASSERT_EQ(Element::string, result->getType());
+    EXPECT_EQ("////", result->stringValue());
+}       
+
 };
 };

File diff suppressed because it is too large
+ 0 - 4019
src/bin/dhcp6/dhcp6_lexer.cc


+ 43 - 2
src/bin/dhcp6/dhcp6_lexer.ll

@@ -926,6 +926,7 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
     std::string decoded;
     std::string decoded;
     decoded.reserve(len);
     decoded.reserve(len);
     for (size_t pos = 0; pos < len; ++pos) {
     for (size_t pos = 0; pos < len; ++pos) {
+        int b = 0;
         char c = raw[pos];
         char c = raw[pos];
         switch (c) {
         switch (c) {
         case '"':
         case '"':
@@ -960,8 +961,42 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
                 decoded.push_back('\t');
                 decoded.push_back('\t');
                 break;
                 break;
             case 'u':
             case 'u':
-                // not yet implemented
-                driver.error(driver.loc_, "Unsupported unicode escape in \"" + raw + "\"");
+                // support only \u0000 to \u00ff
+                ++pos;
+                if (pos + 4 > len) {
+                    // impossible condition
+                    driver.error(driver.loc_,
+                                 "Overflow unicode escape in \"" + raw + "\"");
+                }
+                if ((raw[pos] != '0') || (raw[pos + 1] != '0')) {
+                    driver.error(driver.loc_, "Unsupported unicode escape in \"" + raw + "\"");
+                }
+                pos += 2;
+                c = raw[pos];
+                if ((c >= '0') && (c <= '9')) {
+                    b = (c - '0') << 4;
+                } else if ((c >= 'A') && (c <= 'F')) {
+                    b = (c - 'A' + 10) << 4;
+                } else if ((c >= 'a') && (c <= 'f')) {
+                    b = (c - 'a' + 10) << 4;
+                } else {
+                    // impossible condition
+                    driver.error(driver.loc_, "Not hexadecimal in unicode escape in \"" + raw + "\"");
+                }
+                pos++;
+                c = raw[pos];
+                if ((c >= '0') && (c <= '9')) {
+                    b |= c - '0';
+                } else if ((c >= 'A') && (c <= 'F')) {
+                    b |= c - 'A' + 10;
+                } else if ((c >= 'a') && (c <= 'f')) {
+                    b |= c - 'a' + 10;
+                } else {
+                    // impossible condition
+                    driver.error(driver.loc_, "Not hexadecimal in unicode escape in \"" + raw + "\"");
+                }
+                decoded.push_back(static_cast<char>(b & 0xff));
+                break;
             default:
             default:
                 // impossible condition
                 // impossible condition
                 driver.error(driver.loc_, "Bad escape in \"" + raw + "\"");
                 driver.error(driver.loc_, "Bad escape in \"" + raw + "\"");
@@ -1041,6 +1076,12 @@ null {
    return isc::dhcp::Dhcp6Parser::make_NULL_TYPE(driver.loc_);
    return isc::dhcp::Dhcp6Parser::make_NULL_TYPE(driver.loc_);
 }
 }
 
 
+(?i:true) driver.error (driver.loc_, "JSON true reserved keyword is lower case only");
+
+(?i:false) driver.error (driver.loc_, "JSON false reserved keyword is lower case only");
+
+(?i:null) driver.error (driver.loc_, "JSON null reserved keyword is lower case only");
+
 <*>.   driver.error (driver.loc_, "Invalid character: " + std::string(yytext));
 <*>.   driver.error (driver.loc_, "Invalid character: " + std::string(yytext));
 
 
 <<EOF>> {
 <<EOF>> {

+ 55 - 9
src/bin/dhcp6/tests/parser_unittest.cc

@@ -31,8 +31,8 @@ void testParser(const std::string& txt, Parser6Context::ParserType parser_type)
     ASSERT_NO_THROW(reference_json = Element::fromJSON(txt, true));
     ASSERT_NO_THROW(reference_json = Element::fromJSON(txt, true));
     ASSERT_NO_THROW({
     ASSERT_NO_THROW({
             try {
             try {
-        Parser6Context ctx;
-        test_json = ctx.parseString(txt, parser_type);
+                Parser6Context ctx;
+                test_json = ctx.parseString(txt, parser_type);
             } catch (const std::exception &e) {
             } catch (const std::exception &e) {
                 cout << "EXCEPTION: " << e.what() << endl;
                 cout << "EXCEPTION: " << e.what() << endl;
                 throw;
                 throw;
@@ -49,8 +49,8 @@ void testParser2(const std::string& txt, Parser6Context::ParserType parser_type)
 
 
     ASSERT_NO_THROW({
     ASSERT_NO_THROW({
             try {
             try {
-        Parser6Context ctx;
-        test_json = ctx.parseString(txt, parser_type);
+                Parser6Context ctx;
+                test_json = ctx.parseString(txt, parser_type);
             } catch (const std::exception &e) {
             } catch (const std::exception &e) {
                 cout << "EXCEPTION: " << e.what() << endl;
                 cout << "EXCEPTION: " << e.what() << endl;
                 throw;
                 throw;
@@ -330,13 +330,22 @@ TEST(ParserTest, errors) {
               Parser6Context::PARSER_JSON,
               Parser6Context::PARSER_JSON,
               "Can't open include file /foo/bar");
               "Can't open include file /foo/bar");
 
 
-    // case sensitivity
+    // JSON keywords
     testError("{ \"foo\": True }",
     testError("{ \"foo\": True }",
               Parser6Context::PARSER_JSON,
               Parser6Context::PARSER_JSON,
+              "<string>:1.10-13: JSON true reserved keyword is lower case only");
+    testError("{ \"foo\": False }",
+              Parser6Context::PARSER_JSON,
+              "<string>:1.10-14: JSON false reserved keyword is lower case only");
+    testError("{ \"foo\": NULL }",
+              Parser6Context::PARSER_JSON,
+              "<string>:1.10-13: JSON null reserved keyword is lower case only");
+    testError("{ \"foo\": Tru }",
+              Parser6Context::PARSER_JSON,
               "<string>:1.10: Invalid character: T");
               "<string>:1.10: Invalid character: T");
-    testError("{ \"foo\": NULL  }",
+    testError("{ \"foo\": nul }",
               Parser6Context::PARSER_JSON,
               Parser6Context::PARSER_JSON,
-              "<string>:1.10: Invalid character: N");
+              "<string>:1.10: Invalid character: n");
 
 
     // numbers
     // numbers
     testError("123",
     testError("123",
@@ -386,9 +395,9 @@ TEST(ParserTest, errors) {
     testError("\"a\\x01b\"",
     testError("\"a\\x01b\"",
               Parser6Context::PARSER_JSON,
               Parser6Context::PARSER_JSON,
               "<string>:1.1-8: Bad escape in \"a\\x01b\"");
               "<string>:1.1-8: Bad escape in \"a\\x01b\"");
-    testError("\"a\\u0062\"",
+    testError("\"a\\u0162\"",
               Parser6Context::PARSER_JSON,
               Parser6Context::PARSER_JSON,
-              "<string>:1.1-9: Unsupported unicode escape in \"a\\u0062\"");
+              "<string>:1.1-9: Unsupported unicode escape in \"a\\u0162\"");
     testError("\"a\\u062z\"",
     testError("\"a\\u062z\"",
               Parser6Context::PARSER_JSON,
               Parser6Context::PARSER_JSON,
               "<string>:1.1-9: Bad escape in \"a\\u062z\"");
               "<string>:1.1-9: Bad escape in \"a\\u062z\"");
@@ -476,4 +485,41 @@ TEST(ParserTest, errors) {
               "\"preferred_lifetime\" in Dhcp6 map.");
               "\"preferred_lifetime\" in Dhcp6 map.");
 }
 }
 
 
+// Check unicode escapes
+TEST(ParserTest, unicodeEscapes) {
+    ConstElementPtr result;
+    string json;
+
+    // check we can reread output
+    for (char c = -128; c < 127; ++c) {
+        string ins(" ");
+        ins[1] = c;
+        ConstElementPtr e(new StringElement(ins));
+        json = e->str();
+        ASSERT_NO_THROW(
+        try {
+            Parser6Context ctx;
+            result = ctx.parseString(json, Parser6Context::PARSER_JSON);
+        } catch (const std::exception &x) {
+            cout << "EXCEPTION: " << x.what() << endl;
+            throw;
+        });
+        ASSERT_EQ(Element::string, result->getType());
+        EXPECT_EQ(ins, result->stringValue());
+    }
+
+    // check the 4 possible encodings of solidus '/'
+    json = "\"/\\/\\u002f\\u002F\"";
+    ASSERT_NO_THROW(
+    try {
+        Parser6Context ctx;
+        result = ctx.parseString(json, Parser6Context::PARSER_JSON);
+    } catch (const std::exception &x) {
+        cout << "EXCEPTION: " << x.what() << endl;
+        throw;
+    });
+    ASSERT_EQ(Element::string, result->getType());
+    EXPECT_EQ("////", result->stringValue());
+}       
+
 };
 };

+ 13 - 8
src/lib/cc/data.cc

@@ -14,12 +14,12 @@
 #include <map>
 #include <map>
 #include <cstdio>
 #include <cstdio>
 #include <iostream>
 #include <iostream>
+#include <iomanip>
 #include <string>
 #include <string>
 #include <sstream>
 #include <sstream>
 #include <fstream>
 #include <fstream>
 #include <cerrno>
 #include <cerrno>
 
 
-#include <boost/algorithm/string.hpp> // for iequals
 #include <boost/lexical_cast.hpp>
 #include <boost/lexical_cast.hpp>
 
 
 #include <cmath>
 #include <cmath>
@@ -457,10 +457,10 @@ fromStringstreamBool(std::istream& in, const std::string& file,
     // This will move the pos to the end of the value.
     // This will move the pos to the end of the value.
     const std::string word = wordFromStringstream(in, pos);
     const std::string word = wordFromStringstream(in, pos);
 
 
-    if (boost::iequals(word, "True")) {
+    if (word == "true") {
         return (Element::create(true, Element::Position(file, line,
         return (Element::create(true, Element::Position(file, line,
                                                         start_pos)));
                                                         start_pos)));
-    } else if (boost::iequals(word, "False")) {
+    } else if (word == "false") {
         return (Element::create(false, Element::Position(file, line,
         return (Element::create(false, Element::Position(file, line,
                                                          start_pos)));
                                                          start_pos)));
     } else {
     } else {
@@ -479,7 +479,7 @@ fromStringstreamNull(std::istream& in, const std::string& file,
     const uint32_t start_pos = pos;
     const uint32_t start_pos = pos;
     // This will move the pos to the end of the value.
     // This will move the pos to the end of the value.
     const std::string word = wordFromStringstream(in, pos);
     const std::string word = wordFromStringstream(in, pos);
-    if (boost::iequals(word, "null")) {
+    if (word == "null") {
         return (Element::create(Element::Position(file, line, start_pos)));
         return (Element::create(Element::Position(file, line, start_pos)));
     } else {
     } else {
         throwJSONError(std::string("Bad null value: ") + word, file,
         throwJSONError(std::string("Bad null value: ") + word, file,
@@ -658,16 +658,13 @@ Element::fromJSON(std::istream& in, const std::string& file, int& line,
                 el_read = true;
                 el_read = true;
                 break;
                 break;
             case 't':
             case 't':
-            case 'T':
             case 'f':
             case 'f':
-            case 'F':
                 in.putback(c);
                 in.putback(c);
                 --pos;
                 --pos;
                 element = fromStringstreamBool(in, file, line, pos);
                 element = fromStringstreamBool(in, file, line, pos);
                 el_read = true;
                 el_read = true;
                 break;
                 break;
             case 'n':
             case 'n':
-            case 'N':
                 in.putback(c);
                 in.putback(c);
                 --pos;
                 --pos;
                 element = fromStringstreamNull(in, file, line, pos);
                 element = fromStringstreamNull(in, file, line, pos);
@@ -795,7 +792,15 @@ StringElement::toJSON(std::ostream& ss) const {
             ss << '\\' << 't';
             ss << '\\' << 't';
             break;
             break;
         default:
         default:
-            ss << c;
+            if ((c >= 0) && (c < 0x20)) {
+                ss << "\\u"
+                   << hex
+                   << setw(4)
+                   << setfill('0')
+                   << (static_cast<unsigned>(c) & 0xff);
+            } else {
+                ss << c;
+            }
         }
         }
     }
     }
     ss << "\"";
     ss << "\"";

+ 15 - 19
src/lib/cc/tests/data_unittests.cc

@@ -131,11 +131,13 @@ TEST(Element, from_and_to_json) {
     sv.push_back("{1}");
     sv.push_back("{1}");
     //ElementPtr ep = Element::fromJSON("\"aaa\nbbb\"err");
     //ElementPtr ep = Element::fromJSON("\"aaa\nbbb\"err");
     //std::cout << ep << std::endl;
     //std::cout << ep << std::endl;
-    sv.push_back("\n\nTru");
+    sv.push_back("\n\nTrue");
+    sv.push_back("\n\ntru");
     sv.push_back("{ \n \"aaa\nbbb\"err:");
     sv.push_back("{ \n \"aaa\nbbb\"err:");
-    sv.push_back("{ \t\n \"aaa\nbbb\"\t\n\n:\n True, \"\\\"");
+    sv.push_back("{ \t\n \"aaa\nbbb\"\t\n\n:\n true, \"\\\"");
     sv.push_back("{ \"a\": None}");
     sv.push_back("{ \"a\": None}");
     sv.push_back("");
     sv.push_back("");
+    sv.push_back("NULL");
     sv.push_back("nul");
     sv.push_back("nul");
     sv.push_back("hello\"foobar\"");
     sv.push_back("hello\"foobar\"");
     sv.push_back("\"foobar\"hello");
     sv.push_back("\"foobar\"hello");
@@ -178,12 +180,6 @@ TEST(Element, from_and_to_json) {
     EXPECT_EQ("0.01", Element::fromJSON("1.0e-2")->str());
     EXPECT_EQ("0.01", Element::fromJSON("1.0e-2")->str());
     EXPECT_EQ("0.012", Element::fromJSON("1.2e-2")->str());
     EXPECT_EQ("0.012", Element::fromJSON("1.2e-2")->str());
     EXPECT_EQ("0.012", Element::fromJSON("1.2E-2")->str());
     EXPECT_EQ("0.012", Element::fromJSON("1.2E-2")->str());
-    EXPECT_EQ("null", Element::fromJSON("Null")->str());
-    EXPECT_EQ("null", Element::fromJSON("NULL")->str());
-    EXPECT_EQ("false", Element::fromJSON("False")->str());
-    EXPECT_EQ("false", Element::fromJSON("FALSE")->str());
-    EXPECT_EQ("true", Element::fromJSON("True")->str());
-    EXPECT_EQ("true", Element::fromJSON("TRUE")->str());
     EXPECT_EQ("\"\"", Element::fromJSON("  \n \t \r \f \b \"\" \n \f \t \r \b")->str());
     EXPECT_EQ("\"\"", Element::fromJSON("  \n \t \r \f \b \"\" \n \f \t \r \b")->str());
     EXPECT_EQ("{  }", Element::fromJSON("{  \n  \r \t  \b \f }")->str());
     EXPECT_EQ("{  }", Element::fromJSON("{  \n  \r \t  \b \f }")->str());
     EXPECT_EQ("[  ]", Element::fromJSON("[  \n  \r \f \t  \b  ]")->str());
     EXPECT_EQ("[  ]", Element::fromJSON("[  \n  \r \f \t  \b  ]")->str());
@@ -709,35 +705,35 @@ TEST(Element, equals) {
     EXPECT_NE(*efs("1"), *efs("2"));
     EXPECT_NE(*efs("1"), *efs("2"));
     EXPECT_NE(*efs("1"), *efs("\"1\""));
     EXPECT_NE(*efs("1"), *efs("\"1\""));
     EXPECT_NE(*efs("1"), *efs("[]"));
     EXPECT_NE(*efs("1"), *efs("[]"));
-    EXPECT_NE(*efs("1"), *efs("True"));
+    EXPECT_NE(*efs("1"), *efs("true"));
     EXPECT_NE(*efs("1"), *efs("{}"));
     EXPECT_NE(*efs("1"), *efs("{}"));
 
 
     EXPECT_EQ(*efs("1.1"), *efs("1.1"));
     EXPECT_EQ(*efs("1.1"), *efs("1.1"));
     EXPECT_NE(*efs("1.0"), *efs("1"));
     EXPECT_NE(*efs("1.0"), *efs("1"));
     EXPECT_NE(*efs("1.1"), *efs("\"1\""));
     EXPECT_NE(*efs("1.1"), *efs("\"1\""));
     EXPECT_NE(*efs("1.1"), *efs("[]"));
     EXPECT_NE(*efs("1.1"), *efs("[]"));
-    EXPECT_NE(*efs("1.1"), *efs("True"));
+    EXPECT_NE(*efs("1.1"), *efs("true"));
     EXPECT_NE(*efs("1.1"), *efs("{}"));
     EXPECT_NE(*efs("1.1"), *efs("{}"));
 
 
-    EXPECT_EQ(*efs("True"), *efs("True"));
-    EXPECT_NE(*efs("True"), *efs("False"));
-    EXPECT_NE(*efs("True"), *efs("1"));
-    EXPECT_NE(*efs("True"), *efs("\"1\""));
-    EXPECT_NE(*efs("True"), *efs("[]"));
-    EXPECT_NE(*efs("True"), *efs("{}"));
+    EXPECT_EQ(*efs("true"), *efs("true"));
+    EXPECT_NE(*efs("true"), *efs("false"));
+    EXPECT_NE(*efs("true"), *efs("1"));
+    EXPECT_NE(*efs("true"), *efs("\"1\""));
+    EXPECT_NE(*efs("true"), *efs("[]"));
+    EXPECT_NE(*efs("true"), *efs("{}"));
 
 
     EXPECT_EQ(*efs("\"foo\""), *efs("\"foo\""));
     EXPECT_EQ(*efs("\"foo\""), *efs("\"foo\""));
     EXPECT_NE(*efs("\"foo\""), *efs("\"bar\""));
     EXPECT_NE(*efs("\"foo\""), *efs("\"bar\""));
     EXPECT_NE(*efs("\"foo\""), *efs("1"));
     EXPECT_NE(*efs("\"foo\""), *efs("1"));
     EXPECT_NE(*efs("\"foo\""), *efs("\"1\""));
     EXPECT_NE(*efs("\"foo\""), *efs("\"1\""));
-    EXPECT_NE(*efs("\"foo\""), *efs("True"));
+    EXPECT_NE(*efs("\"foo\""), *efs("true"));
     EXPECT_NE(*efs("\"foo\""), *efs("[]"));
     EXPECT_NE(*efs("\"foo\""), *efs("[]"));
     EXPECT_NE(*efs("\"foo\""), *efs("{}"));
     EXPECT_NE(*efs("\"foo\""), *efs("{}"));
 
 
     EXPECT_EQ(*efs("[]"), *efs("[]"));
     EXPECT_EQ(*efs("[]"), *efs("[]"));
     EXPECT_EQ(*efs("[ 1, 2, 3 ]"), *efs("[ 1, 2, 3 ]"));
     EXPECT_EQ(*efs("[ 1, 2, 3 ]"), *efs("[ 1, 2, 3 ]"));
-    EXPECT_EQ(*efs("[ \"a\", [ True, 1], 2.2 ]"), *efs("[ \"a\", [ True, 1], 2.2 ]"));
-    EXPECT_NE(*efs("[ \"a\", [ True, 1], 2.2 ]"), *efs("[ \"a\", [ True, 2], 2.2 ]"));
+    EXPECT_EQ(*efs("[ \"a\", [ true, 1], 2.2 ]"), *efs("[ \"a\", [ true, 1], 2.2 ]"));
+    EXPECT_NE(*efs("[ \"a\", [ true, 1], 2.2 ]"), *efs("[ \"a\", [ true, 2], 2.2 ]"));
     EXPECT_NE(*efs("[]"), *efs("[1]"));
     EXPECT_NE(*efs("[]"), *efs("[1]"));
     EXPECT_NE(*efs("[]"), *efs("1"));
     EXPECT_NE(*efs("[]"), *efs("1"));
     EXPECT_NE(*efs("[]"), *efs("\"1\""));
     EXPECT_NE(*efs("[]"), *efs("\"1\""));

+ 1 - 1
src/lib/config/documentation.txt

@@ -33,7 +33,7 @@ To add a simple configuration option, let's say an int, we make it the following
 "config_data" contains a list of elements of the form
 "config_data" contains a list of elements of the form
 { "item_name": "name"
 { "item_name": "name"
   "item_type": "integer|real|boolean|string|list|map"
   "item_type": "integer|real|boolean|string|list|map"
-  "item_optional": True|False
+  "item_optional": true|false
   "item_default": <depends on type>
   "item_default": <depends on type>
 }
 }
 
 

+ 3 - 3
src/lib/dhcpsrv/parsers/dhcp_parsers.cc

@@ -117,7 +117,7 @@ template<> void ValueParser<bool>::build(isc::data::ConstElementPtr value) {
     // Invoke common code for all specializations of build().
     // Invoke common code for all specializations of build().
     buildCommon(value);
     buildCommon(value);
     // The Config Manager checks if user specified a
     // The Config Manager checks if user specified a
-    // valid value for a boolean parameter: True or False.
+    // valid value for a boolean parameter: true or false.
     // We should have a boolean Element, use value directly
     // We should have a boolean Element, use value directly
     try {
     try {
         value_ = value->boolValue();
         value_ = value->boolValue();
@@ -1475,11 +1475,11 @@ D2ClientConfigParser::build(isc::data::ConstElementPtr client_config) {
         mode_str  = string_values_->getOptionalParam("replace-client-name",
         mode_str  = string_values_->getOptionalParam("replace-client-name",
                                                      D2ClientConfig::
                                                      D2ClientConfig::
                                                      DFT_REPLACE_CLIENT_NAME_MODE);
                                                      DFT_REPLACE_CLIENT_NAME_MODE);
-        if (boost::iequals(mode_str, "FALSE")) {
+        if (boost::iequals(mode_str, "false")) {
             // @todo add a debug log
             // @todo add a debug log
             replace_client_name_mode = D2ClientConfig::RCM_NEVER;
             replace_client_name_mode = D2ClientConfig::RCM_NEVER;
         }
         }
-        else if (boost::iequals(mode_str, "TRUE")) {
+        else if (boost::iequals(mode_str, "true")) {
             // @todo add a debug log
             // @todo add a debug log
             replace_client_name_mode = D2ClientConfig::RCM_WHEN_PRESENT;
             replace_client_name_mode = D2ClientConfig::RCM_WHEN_PRESENT;
         } else {
         } else {

+ 8 - 8
src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc

@@ -483,7 +483,7 @@ TEST_F(ParseConfigTest, basicOptionDefTest) {
         "      \"name\": \"foo\","
         "      \"name\": \"foo\","
         "      \"code\": 100,"
         "      \"code\": 100,"
         "      \"type\": \"ipv4-address\","
         "      \"type\": \"ipv4-address\","
-        "      \"array\": False,"
+        "      \"array\": false,"
         "      \"record-types\": \"\","
         "      \"record-types\": \"\","
         "      \"space\": \"isc\","
         "      \"space\": \"isc\","
         "      \"encapsulate\": \"\""
         "      \"encapsulate\": \"\""
@@ -604,7 +604,7 @@ TEST_F(ParseConfigTest, basicOptionDataTest) {
         "    \"space\": \"isc\","
         "    \"space\": \"isc\","
         "    \"code\": 100,"
         "    \"code\": 100,"
         "    \"data\": \"192.0.2.0\","
         "    \"data\": \"192.0.2.0\","
-        "    \"csv-format\": True"
+        "    \"csv-format\": true"
         " } ]"
         " } ]"
         "}";
         "}";
 
 
@@ -733,7 +733,7 @@ TEST_F(ParseConfigTest, optionDataCSVFormatWithOptionDef) {
         "    \"name\": \"swap-server\","
         "    \"name\": \"swap-server\","
         "    \"space\": \"dhcp4\","
         "    \"space\": \"dhcp4\","
         "    \"code\": 16,"
         "    \"code\": 16,"
-        "    \"csv-format\": True,"
+        "    \"csv-format\": true,"
         "    \"data\": \"192.0.2.0\""
         "    \"data\": \"192.0.2.0\""
         " } ]"
         " } ]"
         "}";
         "}";
@@ -753,7 +753,7 @@ TEST_F(ParseConfigTest, optionDataCSVFormatWithOptionDef) {
         "    \"name\": \"swap-server\","
         "    \"name\": \"swap-server\","
         "    \"space\": \"dhcp4\","
         "    \"space\": \"dhcp4\","
         "    \"code\": 16,"
         "    \"code\": 16,"
-        "    \"csv-format\": False,"
+        "    \"csv-format\": false,"
         "    \"data\": \"C0000200\""
         "    \"data\": \"C0000200\""
         " } ]"
         " } ]"
         "}";
         "}";
@@ -840,7 +840,7 @@ TEST_F(ParseConfigTest, optionDataCSVFormatNoOptionDef) {
         "    \"name\": \"foo-name\","
         "    \"name\": \"foo-name\","
         "    \"space\": \"dhcp6\","
         "    \"space\": \"dhcp6\","
         "    \"code\": 25000,"
         "    \"code\": 25000,"
-        "    \"csv-format\": True,"
+        "    \"csv-format\": true,"
         "    \"data\": \"0\""
         "    \"data\": \"0\""
         " } ]"
         " } ]"
         "}";
         "}";
@@ -855,7 +855,7 @@ TEST_F(ParseConfigTest, optionDataCSVFormatNoOptionDef) {
         "    \"name\": \"foo-name\","
         "    \"name\": \"foo-name\","
         "    \"space\": \"dhcp6\","
         "    \"space\": \"dhcp6\","
         "    \"code\": 25000,"
         "    \"code\": 25000,"
-        "    \"csv-format\": False,"
+        "    \"csv-format\": false,"
         "    \"data\": \"0\""
         "    \"data\": \"0\""
         " } ]"
         " } ]"
         "}";
         "}";
@@ -974,7 +974,7 @@ TEST_F(ParseConfigTest, optionDataMinimalWithOptionDef) {
         "      \"name\": \"foo-name\","
         "      \"name\": \"foo-name\","
         "      \"code\": 2345,"
         "      \"code\": 2345,"
         "      \"type\": \"ipv6-address\","
         "      \"type\": \"ipv6-address\","
-        "      \"array\": True,"
+        "      \"array\": true,"
         "      \"space\": \"dhcp6\""
         "      \"space\": \"dhcp6\""
         "  } ],"
         "  } ],"
         "  \"option-data\": [ {"
         "  \"option-data\": [ {"
@@ -1000,7 +1000,7 @@ TEST_F(ParseConfigTest, optionDataMinimalWithOptionDef) {
         "      \"name\": \"foo-name\","
         "      \"name\": \"foo-name\","
         "      \"code\": 2345,"
         "      \"code\": 2345,"
         "      \"type\": \"ipv6-address\","
         "      \"type\": \"ipv6-address\","
-        "      \"array\": True,"
+        "      \"array\": true,"
         "      \"space\": \"dhcp6\""
         "      \"space\": \"dhcp6\""
         "  } ],"
         "  } ],"
         "  \"option-data\": [ {"
         "  \"option-data\": [ {"