From: Thomas Markwalder Date: Tue, 24 Jan 2017 15:45:50 +0000 (-0500) Subject: [5110] D2 now uses JSON parsing and SimpleParsers to handle D2 global scalars X-Git-Tag: trac1205_base^2~16 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9493848446c2b0cc7ec9cd4b839367ae87c1bdd7;p=thirdparty%2Fkea.git [5110] D2 now uses JSON parsing and SimpleParsers to handle D2 global scalars new files: src/bin/d2/tests/ d2_simple_parser_unittest.cc parser_unittest.cc parser_unittest.h src/bin/d2/d2_cfg_mgr.h src/bin/d2/d2_cfg_mgr.cc D2CfgMgr::parseElement() - overrides base class implementation, flag global parameters as parsed without pushing them to D2CfgContext value stores D2CfgMgr::setCfgDefaults() - overrides base class implementation, sets defaults for D2 D2CfgMgr::buildParams() - revamped to pull parameters from the given element map instead of context value stores. Removed checks that are now done by JSON parser. src/bin/d2/d2_controller.cc D2Controller::parseFile() - instead of generic JSON parsing, parse file with PARSER_DHCPDDNS context src/bin/d2/d2_lexer.ll src/bin/d2/d2_parser.yy Changed namespace from dhcp to d2 Added PARSER_SUB_DHCPDDNS and D2 global parameter parsing Added objects for forward-ddns, reverse-ddns, tsig-keys src/bin/d2/parser_context.cc src/bin/d2/parser_context.h Added PARSER_DHCPDDNS, PARSER_SUB_DHCPDDNS src/bin/d2/tests/Makefile.am Added new test source files src/bin/d2/tests/d2_cfg_mgr_unittests.cc src/bin/d2/tests/testdata/d2_cfg_tests.json TEST_F(D2CfgMgrTest, configPermutations) - revamped to test JSON parsing as well as element parsing src/bin/d2/tests/parser_unittest.h src/bin/d2/tests/parser_unittest.cc New file that tests basic JSON parsing src/lib/cc/data.h Added parens around TypeError position error text src/lib/cc/simple_parser.cc SimpleParser::setDefaults() - added logic to detect bad lexical casts when handling integers --- diff --git a/src/bin/d2/d2_cfg_mgr.cc b/src/bin/d2/d2_cfg_mgr.cc index 53d60c150d..6b2567cc6f 100644 --- a/src/bin/d2/d2_cfg_mgr.cc +++ b/src/bin/d2/d2_cfg_mgr.cc @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -197,96 +198,148 @@ D2CfgMgr::getConfigSummary(const uint32_t) { return (getD2Params()->getConfigSummary()); } -void -D2CfgMgr::buildParams(isc::data::ConstElementPtr params_config) { - // Base class build creates parses and invokes build on each parser. - // This populate the context scalar stores with all of the parameters. - DCfgMgrBase::buildParams(params_config); - - // Fetch and validate the parameters from the context to create D2Params. - // We validate them here rather than just relying on D2Param constructor - // so we can spit out config text position info with errors. +namespace { - // Fetch and validate ip_address. - D2CfgContextPtr context = getD2CfgContext(); - isc::dhcp::StringStoragePtr strings = context->getStringStorage(); - asiolink::IOAddress ip_address(D2Params::DFT_IP_ADDRESS); +template int_type +getInt(const std::string& name, isc::data::ConstElementPtr value) { + int64_t val_int = value->intValue(); + if ((val_int < std::numeric_limits::min()) || + (val_int > std::numeric_limits::max())) { + isc_throw(D2CfgError, "out of range value (" << val_int + << ") specified for parameter '" << name + << "' (" << value->getPosition() << ")"); + } + return (static_cast(val_int)); +} - std::string ip_address_str = strings->getOptionalParam("ip-address", - D2Params:: - DFT_IP_ADDRESS); +isc::asiolink::IOAddress +getIOAddress(const std::string& name, isc::data::ConstElementPtr value) { + std::string str = value->stringValue(); try { - ip_address = asiolink::IOAddress(ip_address_str); + return (isc::asiolink::IOAddress(str)); } catch (const std::exception& ex) { - isc_throw(D2CfgError, "IP address invalid : \"" - << ip_address_str << "\" (" - << strings->getPosition("ip-address") << ")"); + isc_throw(D2CfgError, "invalid address (" << str + << ") specified for parameter '" << name + << "' (" << value->getPosition() << ")"); } +} - if ((ip_address.toText() == "0.0.0.0") || (ip_address.toText() == "::")) { - isc_throw(D2CfgError, "IP address cannot be \"" << ip_address << "\" (" - << strings->getPosition("ip-address") << ")"); +dhcp_ddns::NameChangeProtocol +getProtocol(const std::string& name, isc::data::ConstElementPtr value) { + std::string str = value->stringValue(); + try { + return (dhcp_ddns::stringToNcrProtocol(str)); + } catch (const std::exception& ex) { + isc_throw(D2CfgError, + "invalid NameChangeRequest protocol (" << str + << ") specified for parameter '" << name + << "' (" << value->getPosition() << ")"); } +} - // Fetch and validate port. - isc::dhcp::Uint32StoragePtr ints = context->getUint32Storage(); - uint32_t port = ints->getOptionalParam("port", D2Params::DFT_PORT); - - if (port == 0) { - isc_throw(D2CfgError, "port cannot be 0 (" - << ints->getPosition("port") << ")"); +dhcp_ddns::NameChangeFormat +getFormat(const std::string& name, isc::data::ConstElementPtr value) { + std::string str = value->stringValue(); + try { + return (dhcp_ddns::stringToNcrFormat(str)); + } catch (const std::exception& ex) { + isc_throw(D2CfgError, + "invalid NameChangeRequest format (" << str + << ") specified for parameter '" << name + << "' (" << value->getPosition() << ")"); } +} - // Fetch and validate dns_server_timeout. - uint32_t dns_server_timeout - = ints->getOptionalParam("dns-server-timeout", - D2Params::DFT_DNS_SERVER_TIMEOUT); +} // anon - if (dns_server_timeout < 1) { - isc_throw(D2CfgError, "DNS server timeout must be larger than 0 (" - << ints->getPosition("dns-server-timeout") << ")"); - } +bool +D2CfgMgr::parseElement(const std::string& element_id, + isc::data::ConstElementPtr element) { - // Fetch and validate ncr_protocol. - dhcp_ddns::NameChangeProtocol ncr_protocol; + // Get D2 specific context. try { - ncr_protocol = dhcp_ddns:: - stringToNcrProtocol(strings-> - getOptionalParam("ncr-protocol", - D2Params:: - DFT_NCR_PROTOCOL)); + D2CfgContextPtr context = getD2CfgContext(); + if ((element_id == "ip-address") || + (element_id == "ncr-protocol") || + (element_id == "ncr-format") || + (element_id == "port") || + (element_id == "dns-server-timeout")) { + // global scalar params require nothing extra + } else { + // not something we handle here + return (false); + } } catch (const std::exception& ex) { - isc_throw(D2CfgError, "ncr-protocol : " - << ex.what() << " (" - << strings->getPosition("ncr-protocol") << ")"); + isc_throw(D2CfgError, "element: " << element_id << " : " << ex.what() + << element->getPosition()); } - if (ncr_protocol != dhcp_ddns::NCR_UDP) { - isc_throw(D2CfgError, "ncr-protocol : " - << dhcp_ddns::ncrProtocolToString(ncr_protocol) - << " is not yet supported (" - << strings->getPosition("ncr-protocol") << ")"); - } + return (true); +}; - // Fetch and validate ncr_format. - dhcp_ddns::NameChangeFormat ncr_format; - try { - ncr_format = dhcp_ddns:: - stringToNcrFormat(strings-> - getOptionalParam("ncr-format", - D2Params:: - DFT_NCR_FORMAT)); - } catch (const std::exception& ex) { - isc_throw(D2CfgError, "ncr-format : " - << ex.what() << " (" - << strings->getPosition("ncr-format") << ")"); - } +void +D2CfgMgr::setCfgDefaults(isc::data::ElementPtr mutable_config) { + D2SimpleParser::setAllDefaults(mutable_config); +} + +void +D2CfgMgr::buildParams(isc::data::ConstElementPtr params_config) { + + // Base class build creates parses and invokes build on each parser. + // This populate the context scalar stores with all of the parameters. + DCfgMgrBase::buildParams(params_config); + + // Fetch the parameters in the config, performing any logcial + // validation required. + asiolink::IOAddress ip_address(0); + uint32_t port = 0; + uint32_t dns_server_timeout = 0; + dhcp_ddns::NameChangeProtocol ncr_protocol = dhcp_ddns::NCR_UDP; + dhcp_ddns::NameChangeFormat ncr_format = dhcp_ddns::FMT_JSON; + + BOOST_FOREACH(isc::dhcp::ConfigPair param, params_config->mapValue()) { + std::string entry(param.first); + isc::data::ConstElementPtr value(param.second); + try { + if (entry == "ip-address") { + ip_address = getIOAddress(entry, value); + if ((ip_address.toText() == "0.0.0.0") || + (ip_address.toText() == "::")) { + isc_throw(D2CfgError, "IP address cannot be \"" + << ip_address << "\"" + << " (" << value->getPosition() << ")"); + } + } else if (entry == "port") { + port = getInt(entry, value); + } else if (entry == "dns-server-timeout") { + dns_server_timeout = getInt(entry, value); + } else if (entry == "ncr-protocol") { + ncr_protocol = getProtocol(entry, value); + if (ncr_protocol != dhcp_ddns::NCR_UDP) { + isc_throw(D2CfgError, "ncr-protocol : " + << dhcp_ddns::ncrProtocolToString(ncr_protocol) + << " is not yet supported " + << " (" << value->getPosition() << ")"); + } + } else if (entry == "ncr-format") { + ncr_format = getFormat(entry, value); + if (ncr_format != dhcp_ddns::FMT_JSON) { + isc_throw(D2CfgError, "NCR Format:" + << dhcp_ddns::ncrFormatToString(ncr_format) + << " is not yet supported" + << " (" << value->getPosition() << ")"); + } + } else { + isc_throw(D2CfgError, + "unsupported parameter '" << entry + << " (" << value->getPosition() << ")"); + } + } catch (const isc::data::TypeError&) { + isc_throw(D2CfgError, + "invalid value type specified for parameter '" << entry + << " (" << value->getPosition() << ")"); + } - if (ncr_format != dhcp_ddns::FMT_JSON) { - isc_throw(D2CfgError, "NCR Format:" - << dhcp_ddns::ncrFormatToString(ncr_format) - << " is not yet supported (" - << strings->getPosition("ncr-format") << ")"); } // Attempt to create the new client config. This ought to fly as @@ -294,7 +347,7 @@ D2CfgMgr::buildParams(isc::data::ConstElementPtr params_config) { D2ParamsPtr params(new D2Params(ip_address, port, dns_server_timeout, ncr_protocol, ncr_format)); - context->getD2Params() = params; + getD2CfgContext()->getD2Params() = params; } isc::dhcp::ParserPtr diff --git a/src/bin/d2/d2_cfg_mgr.h b/src/bin/d2/d2_cfg_mgr.h index c79b7dd962..980d8bda69 100644 --- a/src/bin/d2/d2_cfg_mgr.h +++ b/src/bin/d2/d2_cfg_mgr.h @@ -239,6 +239,31 @@ public: virtual std::string getConfigSummary(const uint32_t selection); protected: + + /// @brief Parses an element using alternate parsers + /// + /// Each element to be parsed is passed first into this method to allow + /// it to be processed by SimpleParser derivations if they've been + /// implemented. The method should return true if it has processed the + /// element or false if the element should be passed onto the original + /// DhcpConfigParer mechanisms. This method is invoked in both + /// @c DCfgMgrBase::buildParams() and DCfgMgrBase::buildAndCommit(). + /// + /// @param element_id name of the element as it is expected in the cfg + /// @param element value of the element as ElementPtr + /// + /// @return true if the element was parsed, false otherwise + virtual bool parseElement(const std::string& element_id, + isc::data::ConstElementPtr element); + + /// @brief Adds default values to the given config + /// + /// Adds the D2 default values to the configuration Element map. This + /// method is invoked by @c DCfgMgrBase::paserConfig(). + /// + /// @param mutable_config - configuration to which defaults should be added + virtual void setCfgDefaults(isc::data::ElementPtr mutable_config); + /// @brief Performs the parsing of the given "params" element. /// /// Iterates over the set of parameters, creating a parser based on the diff --git a/src/bin/d2/d2_controller.cc b/src/bin/d2/d2_controller.cc index acec9507c9..9e12c808d5 100644 --- a/src/bin/d2/d2_controller.cc +++ b/src/bin/d2/d2_controller.cc @@ -61,7 +61,7 @@ D2Controller::parseFile(const std::string& file_name) { // Read contents of the file and parse it as JSON D2ParserContext parser; - elements = parser.parseFile(file_name, D2ParserContext::PARSER_JSON); + elements = parser.parseFile(file_name, D2ParserContext::PARSER_DHCPDDNS); if (!elements) { isc_throw(isc::BadValue, "no configuration found in file"); } diff --git a/src/bin/d2/d2_lexer.cc b/src/bin/d2/d2_lexer.cc index 4b88c459fd..1e51ee4f27 100644 --- a/src/bin/d2/d2_lexer.cc +++ b/src/bin/d2/d2_lexer.cc @@ -524,8 +524,8 @@ static void yynoreturn yy_fatal_error ( const char* msg ); /* %% [3.0] code to copy yytext_ptr to d2_parser_text[] goes here, if %array \ */\ (yy_c_buf_p) = yy_cp; /* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */ -#define YY_NUM_RULES 43 -#define YY_END_OF_BUFFER 44 +#define YY_NUM_RULES 51 +#define YY_END_OF_BUFFER 52 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -533,31 +533,38 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static const flex_int16_t yy_accept[207] = +static const flex_int16_t yy_accept[278] = { 0, - 36, 36, 0, 0, 0, 0, 0, 0, 0, 0, - 44, 42, 10, 11, 42, 1, 36, 33, 36, 36, - 42, 35, 34, 42, 42, 42, 42, 42, 29, 30, - 42, 42, 42, 31, 32, 5, 5, 5, 42, 42, - 42, 10, 11, 0, 0, 25, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 36, - 36, 0, 35, 36, 3, 2, 6, 0, 36, 0, - 0, 0, 0, 0, 0, 4, 0, 0, 9, 0, - 26, 0, 0, 0, 0, 0, 0, 28, 0, 0, - 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, + 52, 50, 10, 11, 50, 1, 44, 41, 44, 44, + 50, 43, 42, 50, 50, 50, 50, 50, 37, 38, + 50, 50, 50, 39, 40, 5, 5, 5, 50, 50, + 50, 10, 11, 0, 0, 33, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 44, 44, 0, 43, 44, 3, 2, + 6, 0, 44, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 9, 0, 34, 0, 0, 0, 0, 0, + 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, - 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 41, 39, 0, 38, 37, 0, 0, 0, 0, - 17, 16, 0, 0, 0, 0, 0, 0, 0, 0, - 40, 37, 0, 0, 18, 0, 0, 0, 0, 0, - 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, - 0, 0, 22, 0, 0, 19, 0, 0, 20, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, - 0, 0, 0, 0, 23, 12, 15, 0, 0, 0, - - 0, 14, 0, 0, 21, 0 + 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 49, 47, 0, + 46, 45, 0, 0, 0, 0, 0, 19, 18, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 48, 45, 0, 0, 0, 0, 0, 20, + 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, + 0, 14, 0, 0, 0, 0, 0, 31, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 27, 0, 0, 0, 0, 0, 24, 0, + 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, + 29, 0, 0, 13, 17, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 21, 16, 0, 22, 0, 0, + 0, 26, 0, 0, 0, 15, 0 } ; static const YY_CHAR yy_ec[256] = @@ -567,15 +574,15 @@ static const YY_CHAR yy_ec[256] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 5, 6, 7, 5, 5, 5, 5, 5, 5, 8, 9, 10, 11, 12, 13, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 15, 5, 16, - 5, 17, 18, 5, 19, 20, 21, 22, 23, 24, - 5, 5, 5, 25, 5, 26, 5, 27, 28, 29, - 5, 30, 31, 32, 33, 5, 5, 5, 5, 5, - 34, 35, 36, 5, 37, 5, 38, 39, 40, 41, - - 42, 43, 44, 5, 45, 46, 5, 47, 48, 49, - 50, 51, 5, 52, 53, 54, 55, 56, 5, 5, - 57, 5, 58, 5, 59, 5, 5, 5, 5, 5, + 14, 15, 14, 16, 14, 14, 14, 17, 5, 18, + 5, 19, 20, 5, 21, 22, 23, 24, 25, 26, + 5, 5, 5, 27, 5, 28, 5, 29, 30, 31, + 5, 32, 33, 34, 35, 5, 5, 5, 5, 5, + 36, 37, 38, 5, 39, 5, 40, 41, 42, 43, + + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 5, 56, 57, 58, 59, 60, 61, 5, + 62, 5, 63, 5, 64, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, @@ -592,344 +599,499 @@ static const YY_CHAR yy_ec[256] = 5, 5, 5, 5, 5 } ; -static const YY_CHAR yy_meta[60] = +static const YY_CHAR yy_meta[65] = { 0, 1, 1, 2, 3, 3, 4, 3, 3, 3, 3, - 3, 3, 5, 6, 3, 3, 3, 3, 6, 6, - 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 5, 3, 3, 6, 7, 6, - 6, 6, 7, 3, 3, 3, 3, 3, 5, 3, - 3, 5, 3, 5, 5, 3, 3, 3, 3 + 3, 3, 3, 5, 5, 5, 3, 3, 3, 3, + 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, + 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3 } ; -static const flex_int16_t yy_base[220] = +static const flex_int16_t yy_base[290] = { 0, - 0, 0, 58, 61, 64, 0, 66, 75, 49, 50, - 280, 1144, 80, 268, 123, 0, 85, 1144, 89, 79, - 77, 105, 1144, 251, 121, 67, 59, 85, 1144, 1144, - 114, 83, 109, 1144, 1144, 1144, 132, 255, 209, 0, - 232, 138, 245, 140, 178, 1144, 184, 190, 196, 204, - 240, 221, 227, 241, 258, 249, 264, 271, 0, 140, - 273, 148, 274, 267, 1144, 0, 1144, 227, 221, 57, - 63, 110, 119, 124, 134, 1144, 194, 212, 1144, 177, - 1144, 156, 299, 316, 323, 330, 202, 336, 368, 344, - 361, 392, 367, 398, 411, 419, 0, 163, 162, 118, - - 201, 174, 172, 157, 1144, 0, 429, 436, 442, 456, - 197, 1144, 478, 480, 487, 502, 525, 508, 538, 546, - 178, 1144, 1144, 215, 1144, 1144, 98, 0, 552, 560, - 1144, 1144, 592, 566, 583, 601, 574, 620, 636, 643, - 1144, 1144, 110, 0, 1144, 650, 686, 656, 663, 678, - 686, 713, 731, 1144, 737, 102, 0, 743, 749, 755, - 761, 767, 773, 791, 797, 1144, 803, 809, 815, 828, - 834, 840, 1144, 846, 852, 1144, 858, 870, 1144, 877, - 883, 889, 896, 919, 926, 933, 940, 946, 1144, 954, - 961, 968, 982, 989, 1144, 1144, 1144, 996, 1003, 1009, - - 1017, 1144, 1024, 1034, 1144, 1144, 1077, 1084, 1091, 1098, - 1105, 1112, 1119, 1123, 1128, 1130, 1132, 1134, 1136 + 0, 0, 63, 66, 69, 0, 67, 71, 52, 68, + 288, 1784, 87, 281, 133, 0, 96, 1784, 129, 133, + 84, 150, 1784, 234, 109, 69, 67, 72, 1784, 1784, + 110, 71, 97, 1784, 1784, 1784, 97, 225, 179, 0, + 209, 167, 220, 146, 194, 1784, 200, 206, 212, 218, + 224, 227, 250, 256, 268, 275, 294, 305, 312, 318, + 324, 337, 0, 331, 338, 356, 371, 374, 1784, 0, + 1784, 220, 230, 123, 128, 145, 165, 171, 170, 1784, + 168, 179, 1784, 205, 1784, 363, 400, 408, 422, 429, + 438, 166, 445, 480, 451, 470, 477, 507, 528, 534, + + 540, 546, 552, 558, 566, 579, 0, 232, 222, 173, + 242, 251, 257, 112, 1784, 0, 591, 604, 618, 611, + 628, 153, 1784, 652, 648, 634, 678, 685, 697, 703, + 715, 726, 735, 743, 752, 758, 265, 1784, 1784, 273, + 1784, 1784, 96, 0, 768, 776, 796, 1784, 1784, 831, + 805, 813, 821, 861, 876, 828, 882, 888, 894, 904, + 915, 927, 1784, 1784, 103, 0, 933, 942, 948, 1784, + 955, 995, 975, 987, 966, 1026, 993, 1784, 1040, 1049, + 1055, 1784, 1064, 1070, 1077, 98, 0, 1784, 1784, 1087, + 1096, 1109, 1128, 1135, 1142, 1148, 1154, 1160, 1167, 1174, + + 1180, 1186, 1784, 1206, 1218, 1225, 1231, 1238, 1244, 1250, + 1258, 1264, 1784, 1270, 1291, 1276, 1297, 1303, 1784, 1313, + 1324, 1330, 1340, 1784, 1346, 1352, 1363, 1373, 1389, 1401, + 1784, 1411, 1418, 1426, 1433, 1439, 1450, 1458, 1465, 1784, + 1476, 1482, 1498, 1504, 1519, 1525, 1531, 1541, 1547, 1784, + 1784, 1557, 1564, 1784, 1784, 1571, 1580, 1589, 1596, 1603, + 1610, 1617, 1626, 1635, 1784, 1784, 1647, 1784, 1654, 1663, + 1672, 1784, 1679, 1687, 1693, 1784, 1784, 1745, 1750, 1755, + 1760, 1765, 1770, 1775, 1778, 133, 132, 91, 88 } ; -static const flex_int16_t yy_def[220] = +static const flex_int16_t yy_def[290] = { 0, - 206, 1, 207, 207, 1, 5, 5, 5, 5, 5, - 206, 206, 206, 206, 208, 209, 206, 206, 206, 206, - 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, - 206, 206, 206, 206, 206, 206, 206, 206, 206, 210, - 206, 206, 206, 211, 208, 206, 208, 208, 208, 208, - 212, 208, 208, 208, 208, 208, 208, 208, 209, 206, - 206, 206, 206, 206, 206, 213, 206, 206, 206, 206, - 206, 206, 206, 206, 206, 206, 206, 210, 206, 211, - 206, 214, 208, 208, 208, 208, 215, 208, 212, 208, - 208, 208, 208, 208, 208, 208, 213, 206, 206, 206, - - 206, 206, 206, 206, 206, 216, 208, 208, 208, 208, - 215, 206, 212, 208, 208, 208, 208, 208, 208, 208, - 206, 206, 206, 206, 206, 206, 206, 217, 208, 208, - 206, 206, 212, 208, 208, 208, 208, 208, 208, 208, - 206, 206, 206, 218, 206, 208, 212, 208, 208, 208, - 208, 208, 208, 206, 208, 206, 219, 208, 208, 208, - 208, 208, 208, 208, 208, 206, 208, 208, 208, 208, - 208, 208, 206, 208, 208, 206, 208, 208, 206, 208, - 208, 208, 208, 208, 208, 208, 208, 208, 206, 208, - 208, 208, 208, 208, 206, 206, 206, 208, 208, 208, - - 208, 206, 208, 208, 206, 0, 206, 206, 206, 206, - 206, 206, 206, 206, 206, 206, 206, 206, 206 + 277, 1, 278, 278, 1, 5, 5, 5, 5, 5, + 277, 277, 277, 277, 279, 280, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 281, + 277, 277, 277, 282, 279, 277, 279, 279, 279, 279, + 279, 283, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 280, 277, 277, 277, 277, 277, 277, 284, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 281, 277, 282, 277, 277, 279, 279, 279, 279, + 279, 285, 279, 283, 279, 279, 279, 279, 279, 279, + + 279, 279, 279, 279, 279, 279, 284, 277, 277, 277, + 277, 277, 277, 277, 277, 286, 279, 279, 279, 279, + 279, 285, 277, 283, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 277, 277, 277, 277, + 277, 277, 277, 287, 279, 279, 279, 277, 277, 283, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 277, 277, 277, 288, 279, 279, 279, 277, + 279, 283, 279, 279, 279, 279, 279, 277, 279, 279, + 279, 277, 279, 279, 279, 277, 289, 277, 277, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + + 279, 279, 277, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 277, 279, 279, 279, 279, 279, 277, 279, + 279, 279, 279, 277, 279, 279, 279, 279, 279, 279, + 277, 279, 279, 279, 279, 279, 279, 279, 279, 277, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 277, + 277, 279, 279, 277, 277, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 277, 277, 279, 277, 279, 279, + 279, 277, 279, 279, 279, 277, 0, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277 } ; -static const flex_int16_t yy_nxt[1204] = +static const flex_int16_t yy_nxt[1849] = { 0, 12, 13, 14, 13, 12, 15, 16, 12, 17, 18, - 19, 20, 21, 22, 23, 24, 12, 12, 12, 12, - 12, 12, 25, 26, 12, 12, 27, 12, 12, 12, - 12, 28, 12, 29, 12, 30, 12, 12, 12, 12, - 12, 25, 31, 12, 12, 12, 12, 12, 32, 12, - 12, 12, 12, 33, 12, 12, 12, 34, 35, 37, - 14, 37, 37, 14, 37, 38, 41, 41, 38, 12, - 12, 40, 12, 12, 12, 12, 12, 12, 12, 12, - 40, 42, 98, 42, 65, 70, 12, 12, 99, 66, - 12, 71, 64, 12, 12, 12, 60, 12, 61, 12, - - 60, 62, 63, 98, 70, 12, 12, 62, 39, 99, - 12, 62, 12, 71, 72, 71, 60, 12, 63, 12, - 62, 12, 12, 44, 44, 44, 62, 62, 46, 68, - 62, 68, 70, 42, 69, 42, 72, 74, 72, 42, - 123, 42, 100, 166, 98, 81, 62, 47, 48, 99, - 156, 73, 143, 64, 49, 50, 68, 51, 68, 123, - 75, 69, 62, 52, 100, 101, 100, 53, 47, 54, - 102, 55, 56, 57, 82, 58, 49, 50, 44, 44, - 44, 62, 81, 46, 44, 44, 44, 122, 103, 46, - 44, 44, 44, 121, 123, 46, 44, 44, 44, 122, - - 141, 46, 112, 127, 44, 44, 44, 112, 122, 46, - 106, 82, 51, 126, 83, 121, 85, 105, 51, 141, - 125, 44, 44, 44, 51, 86, 46, 44, 44, 44, - 51, 121, 46, 104, 69, 85, 83, 141, 51, 84, - 69, 44, 44, 44, 86, 88, 46, 43, 79, 44, - 44, 44, 45, 124, 46, 51, 142, 77, 44, 44, - 44, 51, 90, 46, 44, 44, 44, 76, 67, 46, - 43, 44, 44, 44, 45, 51, 46, 91, 45, 206, - 64, 206, 45, 51, 60, 60, 61, 63, 45, 62, - 92, 45, 51, 45, 89, 62, 62, 93, 51, 44, - - 44, 44, 206, 94, 46, 51, 206, 206, 62, 206, - 206, 206, 96, 95, 62, 62, 44, 44, 44, 206, - 206, 46, 206, 44, 44, 44, 107, 206, 46, 206, - 44, 44, 44, 51, 206, 46, 44, 44, 44, 206, - 206, 46, 206, 206, 44, 44, 44, 206, 107, 46, - 51, 109, 206, 206, 206, 206, 206, 51, 110, 108, - 206, 44, 44, 44, 51, 206, 46, 44, 44, 44, - 51, 115, 46, 109, 206, 206, 206, 206, 51, 206, - 110, 113, 114, 206, 206, 206, 113, 113, 113, 113, - 113, 113, 44, 44, 44, 51, 206, 46, 44, 44, - - 44, 51, 206, 46, 206, 113, 113, 113, 113, 113, - 113, 44, 44, 44, 206, 206, 46, 206, 117, 44, - 44, 44, 206, 206, 46, 206, 51, 206, 206, 44, - 44, 44, 51, 206, 46, 116, 44, 44, 44, 206, - 206, 46, 44, 44, 44, 51, 206, 131, 206, 206, - 206, 118, 206, 51, 206, 129, 44, 44, 44, 206, - 206, 132, 119, 51, 206, 206, 206, 206, 206, 206, - 51, 206, 206, 206, 120, 206, 51, 129, 206, 130, - 44, 44, 44, 206, 206, 46, 206, 44, 44, 44, - 51, 133, 46, 206, 206, 206, 133, 133, 133, 133, - - 133, 133, 44, 44, 44, 206, 206, 46, 44, 44, - 44, 206, 206, 46, 51, 133, 133, 133, 133, 133, - 133, 51, 206, 206, 135, 44, 44, 44, 206, 206, - 46, 206, 206, 206, 134, 137, 51, 206, 44, 44, - 44, 206, 51, 46, 206, 136, 44, 44, 44, 206, - 206, 46, 44, 44, 44, 206, 206, 145, 138, 51, - 44, 44, 44, 206, 206, 46, 44, 44, 44, 206, - 206, 46, 51, 206, 44, 44, 44, 206, 206, 46, - 51, 206, 206, 44, 44, 44, 51, 140, 46, 206, - 206, 139, 206, 206, 51, 206, 206, 206, 206, 206, - - 51, 44, 44, 44, 146, 147, 46, 206, 51, 148, - 147, 147, 147, 147, 147, 147, 151, 51, 206, 206, - 44, 44, 44, 149, 152, 46, 206, 206, 206, 147, - 147, 147, 147, 147, 147, 51, 44, 44, 44, 206, - 206, 154, 150, 44, 44, 44, 206, 206, 46, 206, - 44, 44, 44, 206, 51, 46, 44, 44, 44, 206, - 206, 46, 206, 44, 44, 44, 206, 206, 46, 206, - 51, 206, 206, 206, 153, 206, 206, 51, 44, 44, - 44, 206, 206, 46, 51, 206, 44, 44, 44, 206, - 51, 46, 206, 206, 155, 206, 206, 51, 158, 45, - - 206, 206, 159, 160, 45, 45, 45, 45, 45, 45, - 206, 206, 51, 44, 44, 44, 206, 206, 46, 206, - 51, 206, 206, 45, 45, 45, 45, 45, 45, 161, - 206, 44, 44, 44, 206, 162, 46, 44, 44, 44, - 206, 206, 46, 44, 44, 44, 206, 51, 46, 44, - 44, 44, 206, 206, 46, 44, 44, 44, 206, 206, - 46, 44, 44, 44, 163, 51, 46, 44, 44, 44, - 206, 51, 46, 44, 44, 44, 206, 51, 46, 206, - 206, 165, 206, 51, 164, 206, 167, 206, 206, 51, - 168, 44, 44, 44, 206, 51, 173, 44, 44, 44, - - 206, 51, 46, 44, 44, 44, 169, 51, 176, 44, - 44, 44, 206, 170, 46, 44, 44, 44, 171, 206, - 46, 206, 172, 206, 206, 51, 206, 174, 44, 44, - 44, 51, 206, 179, 44, 44, 44, 51, 206, 46, - 44, 44, 44, 51, 206, 46, 44, 44, 44, 51, - 175, 46, 44, 44, 44, 206, 178, 46, 44, 44, - 44, 206, 51, 46, 177, 206, 206, 206, 51, 206, - 44, 44, 44, 206, 51, 46, 206, 44, 44, 44, - 51, 180, 46, 44, 44, 44, 51, 206, 46, 44, - 44, 44, 51, 181, 46, 182, 44, 44, 44, 184, - - 206, 189, 206, 206, 51, 206, 206, 206, 183, 206, - 206, 51, 206, 206, 186, 206, 206, 51, 206, 44, - 44, 44, 185, 51, 46, 206, 44, 44, 44, 206, - 51, 46, 187, 44, 44, 44, 206, 206, 46, 188, - 44, 44, 44, 206, 206, 46, 44, 44, 44, 206, - 206, 46, 206, 51, 44, 44, 44, 206, 206, 195, - 51, 44, 44, 44, 206, 190, 196, 51, 44, 44, - 44, 206, 206, 197, 51, 206, 206, 206, 191, 193, - 51, 206, 44, 44, 44, 206, 192, 46, 51, 44, - 44, 44, 206, 206, 46, 51, 44, 44, 44, 194, - - 206, 46, 51, 44, 44, 44, 206, 206, 46, 44, - 44, 44, 206, 206, 202, 206, 51, 44, 44, 44, - 206, 206, 46, 51, 44, 44, 44, 206, 206, 46, - 51, 198, 206, 199, 44, 44, 44, 51, 206, 205, - 206, 206, 200, 51, 206, 206, 206, 206, 206, 206, - 206, 51, 201, 206, 206, 206, 206, 206, 51, 206, - 206, 206, 206, 206, 206, 203, 206, 206, 51, 206, - 206, 206, 206, 206, 206, 206, 204, 36, 36, 36, - 36, 36, 36, 36, 45, 45, 45, 45, 45, 45, - 45, 59, 206, 59, 59, 59, 59, 59, 78, 206, - - 78, 206, 78, 78, 78, 80, 80, 80, 80, 80, - 80, 80, 87, 87, 87, 87, 87, 87, 87, 97, - 206, 97, 97, 97, 97, 97, 80, 80, 206, 80, - 111, 111, 111, 111, 111, 128, 128, 144, 144, 157, - 157, 80, 80, 11, 206, 206, 206, 206, 206, 206, - 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, - 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, - 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, - 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, - 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, - - 206, 206, 206 + 19, 20, 21, 22, 22, 22, 23, 24, 12, 12, + 12, 12, 12, 12, 25, 26, 12, 12, 27, 12, + 12, 12, 12, 28, 12, 29, 12, 30, 12, 12, + 12, 12, 12, 25, 31, 12, 12, 12, 12, 12, + 12, 12, 32, 12, 12, 12, 12, 33, 12, 12, + 12, 12, 34, 35, 37, 14, 37, 37, 14, 37, + 38, 41, 40, 38, 12, 12, 40, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 41, 42, 74, + 42, 69, 84, 12, 12, 187, 70, 12, 42, 12, + + 42, 75, 12, 76, 12, 75, 12, 64, 74, 65, + 65, 65, 12, 12, 12, 12, 39, 72, 12, 72, + 66, 12, 73, 73, 73, 75, 12, 76, 76, 78, + 74, 12, 12, 44, 44, 44, 166, 144, 46, 66, + 64, 203, 67, 67, 67, 186, 68, 68, 68, 77, + 108, 85, 79, 66, 165, 109, 47, 66, 123, 48, + 49, 64, 143, 67, 67, 67, 50, 51, 42, 52, + 42, 123, 66, 108, 66, 53, 66, 54, 109, 110, + 55, 48, 86, 56, 115, 57, 58, 59, 60, 61, + 62, 51, 108, 66, 44, 44, 44, 139, 109, 46, + + 44, 44, 44, 110, 110, 46, 44, 44, 44, 114, + 85, 46, 44, 44, 44, 111, 139, 46, 44, 44, + 44, 112, 43, 46, 44, 44, 44, 83, 113, 46, + 52, 81, 93, 73, 73, 73, 52, 80, 88, 45, + 90, 86, 52, 73, 73, 73, 87, 91, 52, 138, + 44, 44, 44, 71, 52, 46, 44, 44, 44, 90, + 52, 46, 88, 45, 137, 89, 91, 45, 44, 44, + 44, 45, 138, 46, 137, 44, 44, 44, 138, 45, + 46, 139, 45, 43, 45, 94, 52, 277, 137, 163, + 277, 277, 52, 95, 44, 44, 44, 163, 140, 46, + + 142, 141, 96, 277, 52, 44, 44, 44, 163, 97, + 46, 52, 44, 44, 44, 277, 164, 46, 44, 44, + 44, 277, 98, 46, 44, 44, 44, 277, 99, 46, + 52, 277, 277, 100, 277, 101, 277, 44, 44, 44, + 277, 52, 46, 277, 68, 68, 68, 277, 52, 64, + 277, 65, 65, 65, 52, 66, 277, 277, 277, 90, + 52, 104, 66, 102, 72, 103, 72, 105, 84, 73, + 73, 73, 277, 52, 66, 84, 277, 277, 90, 277, + 277, 66, 64, 277, 67, 67, 67, 68, 68, 68, + 277, 277, 277, 106, 277, 66, 277, 277, 66, 84, + + 44, 44, 44, 84, 277, 46, 277, 84, 44, 44, + 44, 277, 277, 46, 66, 84, 277, 66, 84, 277, + 84, 116, 44, 44, 44, 277, 277, 46, 277, 44, + 44, 44, 277, 277, 46, 277, 52, 118, 44, 44, + 44, 117, 277, 46, 52, 44, 44, 44, 277, 277, + 46, 44, 44, 44, 277, 277, 46, 277, 52, 120, + 277, 118, 277, 277, 277, 52, 277, 119, 121, 277, + 44, 44, 44, 277, 52, 46, 277, 44, 44, 44, + 277, 52, 46, 120, 277, 277, 277, 52, 277, 277, + 277, 125, 121, 124, 124, 124, 277, 277, 277, 277, + + 124, 124, 124, 124, 124, 124, 52, 44, 44, 44, + 277, 277, 46, 52, 277, 277, 277, 128, 277, 124, + 124, 124, 124, 124, 124, 277, 126, 277, 44, 44, + 44, 277, 127, 46, 44, 44, 44, 277, 277, 46, + 44, 44, 44, 52, 277, 46, 44, 44, 44, 277, + 277, 46, 44, 44, 44, 277, 277, 46, 44, 44, + 44, 277, 277, 46, 52, 277, 44, 44, 44, 277, + 52, 46, 277, 129, 277, 277, 52, 277, 277, 44, + 44, 44, 52, 277, 46, 130, 277, 277, 52, 277, + 277, 44, 44, 44, 52, 131, 46, 277, 277, 277, + + 277, 277, 52, 132, 44, 44, 44, 133, 277, 46, + 277, 44, 44, 44, 277, 52, 148, 134, 44, 44, + 44, 277, 277, 46, 277, 135, 136, 52, 44, 44, + 44, 277, 146, 149, 44, 44, 44, 277, 277, 46, + 52, 277, 277, 277, 152, 145, 277, 52, 44, 44, + 44, 277, 277, 46, 52, 277, 146, 277, 277, 277, + 277, 277, 277, 147, 52, 150, 150, 150, 277, 277, + 52, 277, 150, 150, 150, 150, 150, 150, 44, 44, + 44, 277, 277, 46, 52, 44, 44, 44, 277, 277, + 46, 150, 150, 150, 150, 150, 150, 44, 44, 44, + + 277, 277, 46, 44, 44, 44, 151, 277, 46, 277, + 277, 277, 277, 277, 52, 44, 44, 44, 277, 277, + 46, 52, 277, 277, 154, 157, 44, 44, 44, 277, + 277, 46, 277, 52, 277, 44, 44, 44, 153, 52, + 46, 277, 155, 44, 44, 44, 156, 277, 46, 277, + 277, 52, 44, 44, 44, 277, 277, 46, 44, 44, + 44, 277, 52, 46, 277, 277, 277, 277, 44, 44, + 44, 52, 277, 46, 277, 277, 44, 44, 44, 52, + 158, 170, 167, 168, 277, 277, 160, 277, 52, 277, + 277, 169, 159, 277, 52, 161, 44, 44, 44, 277, + + 277, 46, 277, 162, 52, 44, 44, 44, 277, 277, + 46, 277, 52, 44, 44, 44, 277, 277, 46, 277, + 277, 44, 44, 44, 277, 277, 46, 277, 44, 44, + 44, 277, 52, 178, 277, 277, 277, 277, 277, 277, + 277, 52, 277, 171, 172, 172, 172, 277, 277, 52, + 173, 172, 172, 172, 172, 172, 172, 52, 277, 277, + 175, 44, 44, 44, 52, 277, 46, 277, 277, 174, + 172, 172, 172, 172, 172, 172, 44, 44, 44, 277, + 277, 46, 44, 44, 44, 277, 277, 46, 44, 44, + 44, 277, 277, 46, 44, 44, 44, 52, 277, 182, + + 277, 277, 277, 176, 44, 44, 44, 277, 277, 46, + 277, 277, 52, 277, 277, 44, 44, 44, 52, 177, + 46, 277, 277, 277, 52, 277, 179, 44, 44, 44, + 52, 277, 46, 44, 44, 44, 180, 185, 188, 277, + 52, 277, 44, 44, 44, 277, 181, 189, 44, 44, + 44, 52, 277, 46, 277, 44, 44, 44, 277, 183, + 46, 277, 277, 52, 277, 277, 44, 44, 44, 52, + 184, 46, 277, 277, 277, 44, 44, 44, 52, 277, + 46, 277, 277, 277, 52, 277, 277, 44, 44, 44, + 190, 52, 46, 44, 44, 44, 277, 277, 46, 277, + + 277, 277, 52, 277, 277, 277, 277, 191, 45, 45, + 45, 52, 277, 277, 277, 45, 45, 45, 45, 45, + 45, 194, 277, 52, 277, 192, 44, 44, 44, 52, + 193, 46, 277, 277, 45, 45, 45, 45, 45, 45, + 44, 44, 44, 277, 277, 46, 277, 277, 196, 44, + 44, 44, 277, 277, 46, 44, 44, 44, 277, 277, + 46, 277, 52, 277, 44, 44, 44, 277, 195, 46, + 44, 44, 44, 277, 277, 46, 52, 44, 44, 44, + 277, 277, 46, 277, 277, 52, 277, 44, 44, 44, + 277, 52, 46, 197, 277, 277, 44, 44, 44, 277, + + 52, 46, 277, 277, 198, 277, 52, 277, 277, 44, + 44, 44, 199, 52, 46, 277, 277, 201, 277, 277, + 200, 277, 277, 52, 277, 277, 202, 277, 44, 44, + 44, 277, 52, 46, 277, 44, 44, 44, 277, 204, + 46, 205, 44, 44, 44, 52, 277, 46, 44, 44, + 44, 277, 206, 46, 44, 44, 44, 277, 277, 46, + 44, 44, 44, 277, 52, 46, 277, 44, 44, 44, + 277, 52, 213, 277, 44, 44, 44, 208, 52, 46, + 44, 44, 44, 207, 52, 46, 44, 44, 44, 277, + 52, 46, 277, 277, 277, 277, 52, 209, 277, 277, + + 277, 277, 277, 52, 210, 214, 44, 44, 44, 211, + 52, 46, 277, 212, 277, 277, 52, 215, 44, 44, + 44, 277, 52, 219, 277, 44, 44, 44, 277, 217, + 46, 44, 44, 44, 277, 277, 46, 216, 44, 44, + 44, 277, 52, 46, 44, 44, 44, 277, 222, 46, + 44, 44, 44, 277, 52, 224, 277, 277, 44, 44, + 44, 52, 218, 46, 44, 44, 44, 52, 277, 46, + 44, 44, 44, 277, 52, 46, 44, 44, 44, 277, + 52, 46, 277, 277, 220, 277, 52, 223, 277, 277, + 221, 44, 44, 44, 52, 277, 46, 44, 44, 44, + + 52, 228, 46, 44, 44, 44, 52, 277, 231, 225, + 277, 277, 52, 44, 44, 44, 277, 277, 46, 277, + 277, 226, 277, 227, 44, 44, 44, 52, 277, 46, + 44, 44, 44, 52, 277, 46, 277, 229, 277, 52, + 44, 44, 44, 277, 277, 46, 44, 44, 44, 52, + 277, 46, 44, 44, 44, 277, 232, 46, 230, 277, + 52, 277, 277, 44, 44, 44, 52, 233, 46, 277, + 277, 277, 234, 44, 44, 44, 52, 277, 46, 277, + 277, 277, 52, 277, 277, 236, 277, 277, 52, 44, + 44, 44, 277, 277, 240, 277, 235, 277, 277, 52, + + 277, 44, 44, 44, 277, 237, 46, 277, 277, 52, + 277, 44, 44, 44, 277, 239, 46, 238, 44, 44, + 44, 277, 277, 46, 277, 52, 44, 44, 44, 277, + 277, 46, 277, 44, 44, 44, 277, 52, 46, 44, + 44, 44, 277, 277, 46, 277, 277, 52, 277, 277, + 44, 44, 44, 277, 52, 46, 277, 241, 44, 44, + 44, 242, 52, 46, 277, 44, 44, 44, 244, 52, + 46, 277, 277, 243, 277, 52, 44, 44, 44, 277, + 277, 250, 44, 44, 44, 277, 52, 251, 277, 245, + 277, 247, 277, 277, 52, 277, 246, 277, 44, 44, + + 44, 52, 277, 46, 44, 44, 44, 249, 252, 46, + 277, 277, 52, 277, 277, 248, 277, 277, 52, 44, + 44, 44, 277, 277, 254, 44, 44, 44, 277, 277, + 255, 44, 44, 44, 52, 277, 46, 277, 277, 277, + 52, 44, 44, 44, 277, 277, 46, 44, 44, 44, + 277, 277, 46, 277, 277, 52, 253, 44, 44, 44, + 277, 52, 46, 277, 44, 44, 44, 52, 277, 46, + 277, 44, 44, 44, 277, 277, 46, 52, 277, 277, + 44, 44, 44, 52, 256, 46, 277, 277, 257, 44, + 44, 44, 277, 52, 46, 277, 44, 44, 44, 258, + + 52, 46, 277, 44, 44, 44, 277, 52, 265, 277, + 44, 44, 44, 277, 259, 266, 52, 44, 44, 44, + 260, 261, 46, 277, 277, 52, 44, 44, 44, 277, + 277, 268, 52, 262, 277, 44, 44, 44, 277, 52, + 46, 277, 277, 264, 277, 263, 52, 44, 44, 44, + 277, 277, 46, 52, 44, 44, 44, 277, 277, 46, + 277, 277, 52, 44, 44, 44, 277, 277, 272, 267, + 277, 52, 44, 44, 44, 277, 277, 46, 277, 44, + 44, 44, 277, 52, 46, 277, 269, 44, 44, 44, + 52, 277, 46, 44, 44, 44, 277, 271, 276, 52, + + 277, 277, 277, 270, 277, 277, 277, 277, 52, 277, + 277, 277, 277, 277, 277, 52, 277, 277, 277, 277, + 277, 277, 277, 52, 277, 273, 277, 277, 277, 52, + 277, 277, 277, 277, 277, 277, 277, 274, 277, 277, + 277, 277, 277, 277, 275, 36, 36, 36, 36, 36, + 45, 45, 45, 45, 45, 63, 277, 63, 63, 63, + 82, 277, 82, 277, 82, 84, 84, 84, 84, 84, + 92, 92, 92, 92, 92, 107, 277, 107, 107, 107, + 122, 122, 122, 11, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277 } ; -static const flex_int16_t yy_chk[1204] = +static const flex_int16_t yy_chk[1849] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, - 3, 3, 4, 4, 4, 3, 9, 10, 4, 5, - 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, - 8, 13, 70, 13, 21, 26, 5, 5, 71, 21, - 5, 27, 20, 9, 10, 5, 17, 5, 17, 5, - - 19, 20, 19, 70, 26, 5, 5, 17, 5, 71, - 7, 19, 5, 27, 28, 32, 22, 5, 22, 8, - 20, 5, 5, 15, 15, 15, 17, 22, 15, 25, - 19, 25, 31, 37, 25, 37, 28, 32, 33, 42, - 100, 42, 72, 156, 73, 44, 22, 15, 15, 74, - 143, 31, 127, 60, 15, 15, 62, 15, 62, 100, - 33, 62, 60, 15, 72, 73, 75, 15, 15, 15, - 74, 15, 15, 15, 44, 15, 15, 15, 45, 45, - 45, 60, 80, 45, 47, 47, 47, 99, 75, 47, - 48, 48, 48, 98, 103, 48, 49, 49, 49, 102, - - 121, 49, 111, 104, 50, 50, 50, 87, 99, 50, - 82, 80, 45, 103, 47, 98, 49, 78, 47, 121, - 102, 52, 52, 52, 48, 50, 52, 53, 53, 53, - 49, 101, 53, 77, 69, 49, 47, 124, 50, 48, - 68, 54, 54, 54, 50, 51, 54, 43, 41, 56, - 56, 56, 51, 101, 56, 52, 124, 39, 55, 55, - 55, 53, 52, 55, 57, 57, 57, 38, 24, 57, - 14, 58, 58, 58, 51, 54, 58, 53, 51, 11, - 64, 0, 51, 56, 61, 63, 61, 63, 51, 64, - 54, 51, 55, 51, 51, 61, 63, 55, 57, 83, - - 83, 83, 0, 56, 83, 58, 0, 0, 64, 0, - 0, 0, 58, 57, 61, 63, 84, 84, 84, 0, - 0, 84, 0, 85, 85, 85, 83, 0, 85, 0, - 86, 86, 86, 83, 0, 86, 88, 88, 88, 0, - 0, 88, 0, 0, 90, 90, 90, 0, 83, 90, - 84, 85, 0, 0, 0, 0, 0, 85, 86, 84, - 0, 91, 91, 91, 86, 0, 91, 93, 93, 93, - 88, 91, 93, 85, 0, 0, 0, 0, 90, 0, - 86, 89, 90, 0, 0, 0, 89, 89, 89, 89, - 89, 89, 92, 92, 92, 91, 0, 92, 94, 94, - - 94, 93, 0, 94, 0, 89, 89, 89, 89, 89, - 89, 95, 95, 95, 0, 0, 95, 0, 93, 96, - 96, 96, 0, 0, 96, 0, 92, 0, 0, 107, - 107, 107, 94, 0, 107, 92, 108, 108, 108, 0, - 0, 108, 109, 109, 109, 95, 0, 109, 0, 0, - 0, 94, 0, 96, 0, 107, 110, 110, 110, 0, - 0, 110, 95, 107, 0, 0, 0, 0, 0, 0, - 108, 0, 0, 0, 96, 0, 109, 107, 0, 108, - 114, 114, 114, 0, 0, 114, 0, 115, 115, 115, - 110, 113, 115, 0, 0, 0, 113, 113, 113, 113, - - 113, 113, 116, 116, 116, 0, 0, 116, 118, 118, - 118, 0, 0, 118, 114, 113, 113, 113, 113, 113, - 113, 115, 0, 0, 115, 117, 117, 117, 0, 0, - 117, 0, 0, 0, 114, 117, 116, 0, 119, 119, - 119, 0, 118, 119, 0, 116, 120, 120, 120, 0, - 0, 120, 129, 129, 129, 0, 0, 129, 118, 117, - 130, 130, 130, 0, 0, 130, 134, 134, 134, 0, - 0, 134, 119, 0, 137, 137, 137, 0, 0, 137, - 120, 0, 0, 135, 135, 135, 129, 120, 135, 0, - 0, 119, 0, 0, 130, 0, 0, 0, 0, 0, - - 134, 136, 136, 136, 130, 133, 136, 0, 137, 134, - 133, 133, 133, 133, 133, 133, 137, 135, 0, 0, - 138, 138, 138, 135, 137, 138, 0, 0, 0, 133, - 133, 133, 133, 133, 133, 136, 139, 139, 139, 0, - 0, 139, 136, 140, 140, 140, 0, 0, 140, 0, - 146, 146, 146, 0, 138, 146, 148, 148, 148, 0, - 0, 148, 0, 149, 149, 149, 0, 0, 149, 0, - 139, 0, 0, 0, 138, 0, 0, 140, 150, 150, - 150, 0, 0, 150, 146, 0, 151, 151, 151, 0, - 148, 151, 0, 0, 140, 0, 0, 149, 146, 147, - - 0, 0, 148, 149, 147, 147, 147, 147, 147, 147, - 0, 0, 150, 152, 152, 152, 0, 0, 152, 0, - 151, 0, 0, 147, 147, 147, 147, 147, 147, 150, - 0, 153, 153, 153, 0, 151, 153, 155, 155, 155, - 0, 0, 155, 158, 158, 158, 0, 152, 158, 159, - 159, 159, 0, 0, 159, 160, 160, 160, 0, 0, - 160, 161, 161, 161, 152, 153, 161, 162, 162, 162, - 0, 155, 162, 163, 163, 163, 0, 158, 163, 0, - 0, 155, 0, 159, 153, 0, 158, 0, 0, 160, - 159, 164, 164, 164, 0, 161, 164, 165, 165, 165, - - 0, 162, 165, 167, 167, 167, 160, 163, 167, 168, - 168, 168, 0, 161, 168, 169, 169, 169, 162, 0, - 169, 0, 163, 0, 0, 164, 0, 164, 170, 170, - 170, 165, 0, 170, 171, 171, 171, 167, 0, 171, - 172, 172, 172, 168, 0, 172, 174, 174, 174, 169, - 165, 174, 175, 175, 175, 0, 169, 175, 177, 177, - 177, 0, 170, 177, 168, 0, 0, 0, 171, 0, - 178, 178, 178, 0, 172, 178, 0, 180, 180, 180, - 174, 171, 180, 181, 181, 181, 175, 0, 181, 182, - 182, 182, 177, 172, 182, 174, 183, 183, 183, 177, - - 0, 183, 0, 0, 178, 0, 0, 0, 175, 0, - 0, 180, 0, 0, 180, 0, 0, 181, 0, 184, - 184, 184, 178, 182, 184, 0, 185, 185, 185, 0, - 183, 185, 181, 186, 186, 186, 0, 0, 186, 182, - 187, 187, 187, 0, 0, 187, 188, 188, 188, 0, - 0, 188, 0, 184, 190, 190, 190, 0, 0, 190, - 185, 191, 191, 191, 0, 184, 191, 186, 192, 192, - 192, 0, 0, 192, 187, 0, 0, 0, 185, 187, - 188, 0, 193, 193, 193, 0, 186, 193, 190, 194, - 194, 194, 0, 0, 194, 191, 198, 198, 198, 188, - - 0, 198, 192, 199, 199, 199, 0, 0, 199, 200, - 200, 200, 0, 0, 200, 0, 193, 201, 201, 201, - 0, 0, 201, 194, 203, 203, 203, 0, 0, 203, - 198, 193, 0, 194, 204, 204, 204, 199, 0, 204, - 0, 0, 198, 200, 0, 0, 0, 0, 0, 0, - 0, 201, 199, 0, 0, 0, 0, 0, 203, 0, - 0, 0, 0, 0, 0, 201, 0, 0, 204, 0, - 0, 0, 0, 0, 0, 0, 203, 207, 207, 207, - 207, 207, 207, 207, 208, 208, 208, 208, 208, 208, - 208, 209, 0, 209, 209, 209, 209, 209, 210, 0, - - 210, 0, 210, 210, 210, 211, 211, 211, 211, 211, - 211, 211, 212, 212, 212, 212, 212, 212, 212, 213, - 0, 213, 213, 213, 213, 213, 214, 214, 0, 214, - 215, 215, 215, 215, 215, 216, 216, 217, 217, 218, - 218, 219, 219, 206, 206, 206, 206, 206, 206, 206, - 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, - 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, - 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, - 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, - 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, - - 206, 206, 206 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 3, 3, 4, 4, 4, + 3, 9, 7, 4, 5, 5, 8, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 10, 13, 26, + 13, 21, 289, 5, 5, 288, 21, 5, 37, 9, + + 37, 27, 5, 28, 5, 32, 5, 17, 26, 17, + 17, 17, 5, 5, 7, 10, 5, 25, 8, 25, + 17, 5, 25, 25, 25, 27, 5, 28, 33, 32, + 31, 5, 5, 15, 15, 15, 287, 286, 15, 17, + 19, 186, 19, 19, 19, 165, 20, 20, 20, 31, + 74, 44, 33, 19, 143, 75, 15, 20, 122, 15, + 15, 22, 114, 22, 22, 22, 15, 15, 42, 15, + 42, 92, 19, 74, 22, 15, 20, 15, 75, 76, + 15, 15, 44, 15, 82, 15, 15, 15, 15, 15, + 15, 15, 77, 22, 45, 45, 45, 110, 78, 45, + + 47, 47, 47, 76, 79, 47, 48, 48, 48, 81, + 84, 48, 49, 49, 49, 77, 110, 49, 50, 50, + 50, 78, 43, 50, 51, 51, 51, 41, 79, 51, + 45, 39, 52, 72, 72, 72, 47, 38, 48, 52, + 50, 84, 48, 73, 73, 73, 47, 51, 49, 109, + 53, 53, 53, 24, 50, 53, 54, 54, 54, 50, + 51, 54, 48, 52, 108, 49, 51, 52, 55, 55, + 55, 52, 109, 55, 111, 56, 56, 56, 112, 52, + 56, 113, 52, 14, 52, 52, 53, 11, 108, 137, + 0, 0, 54, 53, 57, 57, 57, 140, 111, 57, + + 113, 112, 53, 0, 55, 58, 58, 58, 137, 54, + 58, 56, 59, 59, 59, 0, 140, 59, 60, 60, + 60, 0, 55, 60, 61, 61, 61, 0, 56, 61, + 57, 0, 0, 57, 0, 57, 0, 62, 62, 62, + 0, 58, 62, 0, 64, 64, 64, 0, 59, 65, + 0, 65, 65, 65, 60, 64, 0, 0, 0, 62, + 61, 60, 65, 58, 66, 59, 66, 61, 86, 66, + 66, 66, 0, 62, 64, 86, 0, 0, 62, 0, + 0, 65, 67, 0, 67, 67, 67, 68, 68, 68, + 0, 0, 0, 62, 0, 67, 0, 0, 68, 86, + + 87, 87, 87, 86, 0, 87, 0, 86, 88, 88, + 88, 0, 0, 88, 67, 86, 0, 68, 86, 0, + 86, 86, 89, 89, 89, 0, 0, 89, 0, 90, + 90, 90, 0, 0, 90, 0, 87, 88, 91, 91, + 91, 87, 0, 91, 88, 93, 93, 93, 0, 0, + 93, 95, 95, 95, 0, 0, 95, 0, 89, 90, + 0, 88, 0, 0, 0, 90, 0, 89, 91, 0, + 96, 96, 96, 0, 91, 96, 0, 97, 97, 97, + 0, 93, 97, 90, 0, 0, 0, 95, 0, 0, + 0, 95, 91, 94, 94, 94, 0, 0, 0, 0, + + 94, 94, 94, 94, 94, 94, 96, 98, 98, 98, + 0, 0, 98, 97, 0, 0, 0, 98, 0, 94, + 94, 94, 94, 94, 94, 0, 96, 0, 99, 99, + 99, 0, 97, 99, 100, 100, 100, 0, 0, 100, + 101, 101, 101, 98, 0, 101, 102, 102, 102, 0, + 0, 102, 103, 103, 103, 0, 0, 103, 104, 104, + 104, 0, 0, 104, 99, 0, 105, 105, 105, 0, + 100, 105, 0, 99, 0, 0, 101, 0, 0, 106, + 106, 106, 102, 0, 106, 100, 0, 0, 103, 0, + 0, 117, 117, 117, 104, 101, 117, 0, 0, 0, + + 0, 0, 105, 102, 118, 118, 118, 103, 0, 118, + 0, 120, 120, 120, 0, 106, 120, 104, 119, 119, + 119, 0, 0, 119, 0, 105, 106, 117, 121, 121, + 121, 0, 118, 121, 126, 126, 126, 0, 0, 126, + 118, 0, 0, 0, 126, 117, 0, 120, 125, 125, + 125, 0, 0, 125, 119, 0, 118, 0, 0, 0, + 0, 0, 0, 119, 121, 124, 124, 124, 0, 0, + 126, 0, 124, 124, 124, 124, 124, 124, 127, 127, + 127, 0, 0, 127, 125, 128, 128, 128, 0, 0, + 128, 124, 124, 124, 124, 124, 124, 129, 129, 129, + + 0, 0, 129, 130, 130, 130, 125, 0, 130, 0, + 0, 0, 0, 0, 127, 131, 131, 131, 0, 0, + 131, 128, 0, 0, 128, 131, 132, 132, 132, 0, + 0, 132, 0, 129, 0, 133, 133, 133, 127, 130, + 133, 0, 129, 134, 134, 134, 130, 0, 134, 0, + 0, 131, 135, 135, 135, 0, 0, 135, 136, 136, + 136, 0, 132, 136, 0, 0, 0, 0, 145, 145, + 145, 133, 0, 145, 0, 0, 146, 146, 146, 134, + 132, 146, 145, 145, 0, 0, 134, 0, 135, 0, + 0, 145, 133, 0, 136, 135, 147, 147, 147, 0, + + 0, 147, 0, 136, 145, 151, 151, 151, 0, 0, + 151, 0, 146, 152, 152, 152, 0, 0, 152, 0, + 0, 153, 153, 153, 0, 0, 153, 0, 156, 156, + 156, 0, 147, 156, 0, 0, 0, 0, 0, 0, + 0, 151, 0, 147, 150, 150, 150, 0, 0, 152, + 151, 150, 150, 150, 150, 150, 150, 153, 0, 0, + 153, 154, 154, 154, 156, 0, 154, 0, 0, 152, + 150, 150, 150, 150, 150, 150, 155, 155, 155, 0, + 0, 155, 157, 157, 157, 0, 0, 157, 158, 158, + 158, 0, 0, 158, 159, 159, 159, 154, 0, 159, + + 0, 0, 0, 154, 160, 160, 160, 0, 0, 160, + 0, 0, 155, 0, 0, 161, 161, 161, 157, 155, + 161, 0, 0, 0, 158, 0, 157, 162, 162, 162, + 159, 0, 162, 167, 167, 167, 157, 162, 167, 0, + 160, 0, 168, 168, 168, 0, 158, 168, 169, 169, + 169, 161, 0, 169, 0, 171, 171, 171, 0, 160, + 171, 0, 0, 162, 0, 0, 175, 175, 175, 167, + 161, 175, 0, 0, 0, 173, 173, 173, 168, 0, + 173, 0, 0, 0, 169, 0, 0, 174, 174, 174, + 169, 171, 174, 177, 177, 177, 0, 0, 177, 0, + + 0, 0, 175, 0, 0, 0, 0, 171, 172, 172, + 172, 173, 0, 0, 0, 172, 172, 172, 172, 172, + 172, 175, 0, 174, 0, 173, 176, 176, 176, 177, + 174, 176, 0, 0, 172, 172, 172, 172, 172, 172, + 179, 179, 179, 0, 0, 179, 0, 0, 177, 180, + 180, 180, 0, 0, 180, 181, 181, 181, 0, 0, + 181, 0, 176, 0, 183, 183, 183, 0, 176, 183, + 184, 184, 184, 0, 0, 184, 179, 185, 185, 185, + 0, 0, 185, 0, 0, 180, 0, 190, 190, 190, + 0, 181, 190, 179, 0, 0, 191, 191, 191, 0, + + 183, 191, 0, 0, 180, 0, 184, 0, 0, 192, + 192, 192, 181, 185, 192, 0, 0, 184, 0, 0, + 183, 0, 0, 190, 0, 0, 185, 0, 193, 193, + 193, 0, 191, 193, 0, 194, 194, 194, 0, 190, + 194, 191, 195, 195, 195, 192, 0, 195, 196, 196, + 196, 0, 192, 196, 197, 197, 197, 0, 0, 197, + 198, 198, 198, 0, 193, 198, 0, 199, 199, 199, + 0, 194, 199, 0, 200, 200, 200, 194, 195, 200, + 201, 201, 201, 193, 196, 201, 202, 202, 202, 0, + 197, 202, 0, 0, 0, 0, 198, 195, 0, 0, + + 0, 0, 0, 199, 196, 199, 204, 204, 204, 197, + 200, 204, 0, 198, 0, 0, 201, 200, 205, 205, + 205, 0, 202, 205, 0, 206, 206, 206, 0, 202, + 206, 207, 207, 207, 0, 0, 207, 201, 208, 208, + 208, 0, 204, 208, 209, 209, 209, 0, 208, 209, + 210, 210, 210, 0, 205, 210, 0, 0, 211, 211, + 211, 206, 204, 211, 212, 212, 212, 207, 0, 212, + 214, 214, 214, 0, 208, 214, 216, 216, 216, 0, + 209, 216, 0, 0, 206, 0, 210, 209, 0, 0, + 207, 215, 215, 215, 211, 0, 215, 217, 217, 217, + + 212, 215, 217, 218, 218, 218, 214, 0, 218, 211, + 0, 0, 216, 220, 220, 220, 0, 0, 220, 0, + 0, 212, 0, 214, 221, 221, 221, 215, 0, 221, + 222, 222, 222, 217, 0, 222, 0, 216, 0, 218, + 223, 223, 223, 0, 0, 223, 225, 225, 225, 220, + 0, 225, 226, 226, 226, 0, 220, 226, 217, 0, + 221, 0, 0, 227, 227, 227, 222, 221, 227, 0, + 0, 0, 222, 228, 228, 228, 223, 0, 228, 0, + 0, 0, 225, 0, 0, 225, 0, 0, 226, 229, + 229, 229, 0, 0, 229, 0, 223, 0, 0, 227, + + 0, 230, 230, 230, 0, 226, 230, 0, 0, 228, + 0, 232, 232, 232, 0, 228, 232, 227, 233, 233, + 233, 0, 0, 233, 0, 229, 234, 234, 234, 0, + 0, 234, 0, 235, 235, 235, 0, 230, 235, 236, + 236, 236, 0, 0, 236, 0, 0, 232, 0, 0, + 237, 237, 237, 0, 233, 237, 0, 230, 238, 238, + 238, 232, 234, 238, 0, 239, 239, 239, 234, 235, + 239, 0, 0, 233, 0, 236, 241, 241, 241, 0, + 0, 241, 242, 242, 242, 0, 237, 242, 0, 235, + 0, 237, 0, 0, 238, 0, 236, 0, 243, 243, + + 243, 239, 0, 243, 244, 244, 244, 239, 243, 244, + 0, 0, 241, 0, 0, 238, 0, 0, 242, 245, + 245, 245, 0, 0, 245, 246, 246, 246, 0, 0, + 246, 247, 247, 247, 243, 0, 247, 0, 0, 0, + 244, 248, 248, 248, 0, 0, 248, 249, 249, 249, + 0, 0, 249, 0, 0, 245, 244, 252, 252, 252, + 0, 246, 252, 0, 253, 253, 253, 247, 0, 253, + 0, 256, 256, 256, 0, 0, 256, 248, 0, 0, + 257, 257, 257, 249, 247, 257, 0, 0, 248, 258, + 258, 258, 0, 252, 258, 0, 259, 259, 259, 249, + + 253, 259, 0, 260, 260, 260, 0, 256, 260, 0, + 261, 261, 261, 0, 252, 261, 257, 262, 262, 262, + 253, 256, 262, 0, 0, 258, 263, 263, 263, 0, + 0, 263, 259, 257, 0, 264, 264, 264, 0, 260, + 264, 0, 0, 259, 0, 258, 261, 267, 267, 267, + 0, 0, 267, 262, 269, 269, 269, 0, 0, 269, + 0, 0, 263, 270, 270, 270, 0, 0, 270, 262, + 0, 264, 271, 271, 271, 0, 0, 271, 0, 273, + 273, 273, 0, 267, 273, 0, 264, 274, 274, 274, + 269, 0, 274, 275, 275, 275, 0, 269, 275, 270, + + 0, 0, 0, 267, 0, 0, 0, 0, 271, 0, + 0, 0, 0, 0, 0, 273, 0, 0, 0, 0, + 0, 0, 0, 274, 0, 271, 0, 0, 0, 275, + 0, 0, 0, 0, 0, 0, 0, 273, 0, 0, + 0, 0, 0, 0, 274, 278, 278, 278, 278, 278, + 279, 279, 279, 279, 279, 280, 0, 280, 280, 280, + 281, 0, 281, 0, 281, 282, 282, 282, 282, 282, + 283, 283, 283, 283, 283, 284, 0, 284, 284, 284, + 285, 285, 285, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277 } ; static yy_state_type yy_last_accepting_state; @@ -938,13 +1100,13 @@ static char *yy_last_accepting_cpos; extern int d2_parser__flex_debug; int d2_parser__flex_debug = 1; -static const flex_int16_t yy_rule_linenum[43] = +static const flex_int16_t yy_rule_linenum[51] = { 0, - 115, 117, 119, 124, 125, 130, 131, 132, 144, 147, - 152, 158, 167, 176, 185, 194, 204, 214, 224, 233, - 242, 251, 260, 269, 278, 376, 381, 386, 391, 392, - 393, 394, 395, 396, 398, 416, 429, 434, 438, 440, - 442, 444 + 117, 119, 121, 126, 127, 132, 133, 134, 146, 149, + 154, 160, 169, 178, 187, 196, 205, 214, 224, 234, + 244, 253, 262, 272, 281, 290, 299, 308, 317, 326, + 335, 344, 354, 452, 457, 462, 467, 468, 469, 470, + 471, 472, 474, 492, 505, 510, 514, 516, 518, 520 } ; /* The intent behind this definition is that it'll catch @@ -982,14 +1144,14 @@ namespace { bool start_token_flag = false; -isc::dhcp::D2ParserContext::ParserType start_token_value; +isc::d2::D2ParserContext::ParserType start_token_value; unsigned int comment_start_line = 0; }; // To avoid the call to exit... oops! -#define YY_FATAL_ERROR(msg) isc::dhcp::D2ParserContext::fatal(msg) -#line 992 "d2_lexer.cc" +#define YY_FATAL_ERROR(msg) isc::d2::D2ParserContext::fatal(msg) +#line 1154 "d2_lexer.cc" /* noyywrap disables automatic rewinding for the next file to parse. Since we always parse only a single string, there's no need to do any wraps. And using yywrap requires linking with -lfl, which provides the default yywrap @@ -1015,8 +1177,8 @@ unsigned int comment_start_line = 0; // by moving it ahead by yyleng bytes. yyleng specifies the length of the // currently matched token. #define YY_USER_ACTION driver.loc_.columns(yyleng); -#line 1018 "d2_lexer.cc" -#line 1019 "d2_lexer.cc" +#line 1180 "d2_lexer.cc" +#line 1181 "d2_lexer.cc" #define INITIAL 0 #define COMMENT 1 @@ -1315,14 +1477,16 @@ YY_DECL switch (start_token_value) { case D2ParserContext::PARSER_JSON: default: - return isc::dhcp::D2Parser::make_TOPLEVEL_JSON(driver.loc_); + return isc::d2::D2Parser::make_TOPLEVEL_JSON(driver.loc_); case D2ParserContext::PARSER_DHCPDDNS: - return isc::dhcp::D2Parser::make_TOPLEVEL_DHCPDDNS(driver.loc_); + return isc::d2::D2Parser::make_TOPLEVEL_DHCPDDNS(driver.loc_); + case D2ParserContext::PARSER_SUB_DHCPDDNS: + return isc::d2::D2Parser::make_SUB_DHCPDDNS(driver.loc_); } } -#line 1325 "d2_lexer.cc" +#line 1489 "d2_lexer.cc" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { @@ -1351,13 +1515,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 207 ) + if ( yy_current_state >= 278 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; } - while ( yy_current_state != 206 ); + while ( yy_current_state != 277 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); @@ -1376,13 +1540,13 @@ do_action: /* This label is used only to access EOF actions. */ { if ( yy_act == 0 ) fprintf( stderr, "--scanner backing up\n" ); - else if ( yy_act < 43 ) + else if ( yy_act < 51 ) fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n", (long)yy_rule_linenum[yy_act], d2_parser_text ); - else if ( yy_act == 43 ) + else if ( yy_act == 51 ) fprintf( stderr, "--accepting default rule (\"%s\")\n", d2_parser_text ); - else if ( yy_act == 44 ) + else if ( yy_act == 52 ) fprintf( stderr, "--(end of buffer or a NUL)\n" ); else fprintf( stderr, "--EOF (start condition %d)\n", YY_START ); @@ -1400,17 +1564,17 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 115 "d2_lexer.ll" +#line 117 "d2_lexer.ll" ; YY_BREAK case 2: YY_RULE_SETUP -#line 117 "d2_lexer.ll" +#line 119 "d2_lexer.ll" ; YY_BREAK case 3: YY_RULE_SETUP -#line 119 "d2_lexer.ll" +#line 121 "d2_lexer.ll" { BEGIN(COMMENT); comment_start_line = driver.loc_.end.line;; @@ -1418,33 +1582,33 @@ YY_RULE_SETUP YY_BREAK case 4: YY_RULE_SETUP -#line 124 "d2_lexer.ll" +#line 126 "d2_lexer.ll" BEGIN(INITIAL); YY_BREAK case 5: YY_RULE_SETUP -#line 125 "d2_lexer.ll" +#line 127 "d2_lexer.ll" ; YY_BREAK case YY_STATE_EOF(COMMENT): -#line 126 "d2_lexer.ll" +#line 128 "d2_lexer.ll" { isc_throw(D2ParseError, "Comment not closed. (/* in line " << comment_start_line); } YY_BREAK case 6: YY_RULE_SETUP -#line 130 "d2_lexer.ll" +#line 132 "d2_lexer.ll" BEGIN(DIR_ENTER); YY_BREAK case 7: YY_RULE_SETUP -#line 131 "d2_lexer.ll" +#line 133 "d2_lexer.ll" BEGIN(DIR_INCLUDE); YY_BREAK case 8: YY_RULE_SETUP -#line 132 "d2_lexer.ll" +#line 134 "d2_lexer.ll" { // Include directive. @@ -1458,19 +1622,19 @@ YY_RULE_SETUP case YY_STATE_EOF(DIR_ENTER): case YY_STATE_EOF(DIR_INCLUDE): case YY_STATE_EOF(DIR_EXIT): -#line 141 "d2_lexer.ll" +#line 143 "d2_lexer.ll" { isc_throw(D2ParseError, "Directive not closed."); } YY_BREAK case 9: YY_RULE_SETUP -#line 144 "d2_lexer.ll" +#line 146 "d2_lexer.ll" BEGIN(INITIAL); YY_BREAK case 10: YY_RULE_SETUP -#line 147 "d2_lexer.ll" +#line 149 "d2_lexer.ll" { // Ok, we found a with space. Let's ignore it and update loc variable. driver.loc_.step(); @@ -1479,7 +1643,7 @@ YY_RULE_SETUP case 11: /* rule 11 can match eol */ YY_RULE_SETUP -#line 152 "d2_lexer.ll" +#line 154 "d2_lexer.ll" { // Newline found. Let's update the location and continue. driver.loc_.lines(yyleng); @@ -1488,76 +1652,74 @@ YY_RULE_SETUP YY_BREAK case 12: YY_RULE_SETUP -#line 158 "d2_lexer.ll" +#line 160 "d2_lexer.ll" { switch(driver.ctx_) { - case isc::dhcp::D2ParserContext::DHCPDDNS: - return isc::dhcp::D2Parser::make_IP_ADDRESS(driver.loc_); + case isc::d2::D2ParserContext::CONFIG: + return isc::d2::D2Parser::make_DHCPDDNS(driver.loc_); default: - return isc::dhcp::D2Parser::make_STRING("ip-address", driver.loc_); + return isc::d2::D2Parser::make_STRING("DhcpDdns", driver.loc_); } } YY_BREAK case 13: YY_RULE_SETUP -#line 167 "d2_lexer.ll" +#line 169 "d2_lexer.ll" { switch(driver.ctx_) { - case isc::dhcp::D2ParserContext::DHCPDDNS: - return isc::dhcp::D2Parser::make_PORT(driver.loc_); + case isc::d2::D2ParserContext::DHCPDDNS: + return isc::d2::D2Parser::make_IP_ADDRESS(driver.loc_); default: - return isc::dhcp::D2Parser::make_STRING("port", driver.loc_); + return isc::d2::D2Parser::make_STRING("ip-address", driver.loc_); } } YY_BREAK case 14: YY_RULE_SETUP -#line 176 "d2_lexer.ll" +#line 178 "d2_lexer.ll" { switch(driver.ctx_) { - case isc::dhcp::D2ParserContext::DHCPDDNS: - return isc::dhcp::D2Parser::make_NCR_PROTOCOL(driver.loc_); + case isc::d2::D2ParserContext::DHCPDDNS: + return isc::d2::D2Parser::make_PORT(driver.loc_); default: - return isc::dhcp::D2Parser::make_STRING("ncr-protocol", driver.loc_); + return isc::d2::D2Parser::make_STRING("port", driver.loc_); } } YY_BREAK case 15: YY_RULE_SETUP -#line 185 "d2_lexer.ll" +#line 187 "d2_lexer.ll" { switch(driver.ctx_) { - case isc::dhcp::D2ParserContext::DHCPDDNS: - return isc::dhcp::D2Parser::make_NCR_FORMAT(driver.loc_); + case isc::d2::D2ParserContext::DHCPDDNS: + return isc::d2::D2Parser::make_DNS_SERVER_TIMEOUT(driver.loc_); default: - return isc::dhcp::D2Parser::make_STRING("ncr-format", driver.loc_); + return isc::d2::D2Parser::make_STRING("dns-server-timeout", driver.loc_); } } YY_BREAK case 16: YY_RULE_SETUP -#line 194 "d2_lexer.ll" +#line 196 "d2_lexer.ll" { - /* dhcp-ddns value keywords are case insensitive */ - if (driver.ctx_ == isc::dhcp::D2ParserContext::NCR_PROTOCOL) { - return isc::dhcp::D2Parser::make_UDP(driver.loc_); + switch(driver.ctx_) { + case isc::d2::D2ParserContext::DHCPDDNS: + return isc::d2::D2Parser::make_NCR_PROTOCOL(driver.loc_); + default: + return isc::d2::D2Parser::make_STRING("ncr-protocol", driver.loc_); } - std::string tmp(yytext+1); - tmp.resize(tmp.size() - 1); - return isc::dhcp::D2Parser::make_STRING(tmp, driver.loc_); } YY_BREAK case 17: YY_RULE_SETUP -#line 204 "d2_lexer.ll" +#line 205 "d2_lexer.ll" { - /* dhcp-ddns value keywords are case insensitive */ - if (driver.ctx_ == isc::dhcp::D2ParserContext::NCR_PROTOCOL) { - return isc::dhcp::D2Parser::make_TCP(driver.loc_); + switch(driver.ctx_) { + case isc::d2::D2ParserContext::DHCPDDNS: + return isc::d2::D2Parser::make_NCR_FORMAT(driver.loc_); + default: + return isc::d2::D2Parser::make_STRING("ncr-format", driver.loc_); } - std::string tmp(yytext+1); - tmp.resize(tmp.size() - 1); - return isc::dhcp::D2Parser::make_STRING(tmp, driver.loc_); } YY_BREAK case 18: @@ -1565,89 +1727,187 @@ YY_RULE_SETUP #line 214 "d2_lexer.ll" { /* dhcp-ddns value keywords are case insensitive */ - if (driver.ctx_ == isc::dhcp::D2ParserContext::NCR_FORMAT) { - return isc::dhcp::D2Parser::make_JSON(driver.loc_); + if (driver.ctx_ == isc::d2::D2ParserContext::NCR_PROTOCOL) { + return isc::d2::D2Parser::make_UDP(driver.loc_); } std::string tmp(yytext+1); tmp.resize(tmp.size() - 1); - return isc::dhcp::D2Parser::make_STRING(tmp, driver.loc_); + return isc::d2::D2Parser::make_STRING(tmp, driver.loc_); } YY_BREAK case 19: YY_RULE_SETUP #line 224 "d2_lexer.ll" { - switch(driver.ctx_) { - case isc::dhcp::D2ParserContext::CONFIG: - return isc::dhcp::D2Parser::make_LOGGING(driver.loc_); - default: - return isc::dhcp::D2Parser::make_STRING("Logging", driver.loc_); + /* dhcp-ddns value keywords are case insensitive */ + if (driver.ctx_ == isc::d2::D2ParserContext::NCR_PROTOCOL) { + return isc::d2::D2Parser::make_TCP(driver.loc_); } + std::string tmp(yytext+1); + tmp.resize(tmp.size() - 1); + return isc::d2::D2Parser::make_STRING(tmp, driver.loc_); } YY_BREAK case 20: YY_RULE_SETUP -#line 233 "d2_lexer.ll" +#line 234 "d2_lexer.ll" { - switch(driver.ctx_) { - case isc::dhcp::D2ParserContext::LOGGING: - return isc::dhcp::D2Parser::make_LOGGERS(driver.loc_); - default: - return isc::dhcp::D2Parser::make_STRING("loggers", driver.loc_); + /* dhcp-ddns value keywords are case insensitive */ + if (driver.ctx_ == isc::d2::D2ParserContext::NCR_FORMAT) { + return isc::d2::D2Parser::make_JSON(driver.loc_); } + std::string tmp(yytext+1); + tmp.resize(tmp.size() - 1); + return isc::d2::D2Parser::make_STRING(tmp, driver.loc_); } YY_BREAK case 21: YY_RULE_SETUP -#line 242 "d2_lexer.ll" +#line 244 "d2_lexer.ll" { switch(driver.ctx_) { - case isc::dhcp::D2ParserContext::LOGGERS: - return isc::dhcp::D2Parser::make_OUTPUT_OPTIONS(driver.loc_); + case isc::d2::D2ParserContext::DHCPDDNS: + return isc::d2::D2Parser::make_FORWARD_DDNS(driver.loc_); default: - return isc::dhcp::D2Parser::make_STRING("output_options", driver.loc_); + return isc::d2::D2Parser::make_STRING("forward-ddns", driver.loc_); } } YY_BREAK case 22: YY_RULE_SETUP -#line 251 "d2_lexer.ll" +#line 253 "d2_lexer.ll" { switch(driver.ctx_) { - case isc::dhcp::D2ParserContext::OUTPUT_OPTIONS: - return isc::dhcp::D2Parser::make_OUTPUT(driver.loc_); + case isc::d2::D2ParserContext::DHCPDDNS: + return isc::d2::D2Parser::make_REVERSE_DDNS(driver.loc_); default: - return isc::dhcp::D2Parser::make_STRING("output", driver.loc_); + return isc::d2::D2Parser::make_STRING("reverse-ddns", driver.loc_); } } YY_BREAK case 23: YY_RULE_SETUP -#line 260 "d2_lexer.ll" +#line 262 "d2_lexer.ll" { switch(driver.ctx_) { - case isc::dhcp::D2ParserContext::LOGGERS: - return isc::dhcp::D2Parser::make_DEBUGLEVEL(driver.loc_); + case isc::d2::D2ParserContext::DHCPDDNS: + return isc::d2::D2Parser::make_TSIG_KEYS(driver.loc_); default: - return isc::dhcp::D2Parser::make_STRING("debuglevel", driver.loc_); + return isc::d2::D2Parser::make_STRING("tsig-keys", driver.loc_); } } YY_BREAK case 24: YY_RULE_SETUP -#line 269 "d2_lexer.ll" +#line 272 "d2_lexer.ll" { switch(driver.ctx_) { - case isc::dhcp::D2ParserContext::LOGGERS: - return isc::dhcp::D2Parser::make_SEVERITY(driver.loc_); + case isc::d2::D2ParserContext::CONFIG: + return isc::d2::D2Parser::make_LOGGING(driver.loc_); default: - return isc::dhcp::D2Parser::make_STRING("severity", driver.loc_); + return isc::d2::D2Parser::make_STRING("Logging", driver.loc_); } } YY_BREAK case 25: YY_RULE_SETUP -#line 278 "d2_lexer.ll" +#line 281 "d2_lexer.ll" +{ + switch(driver.ctx_) { + case isc::d2::D2ParserContext::LOGGING: + return isc::d2::D2Parser::make_LOGGERS(driver.loc_); + default: + return isc::d2::D2Parser::make_STRING("loggers", driver.loc_); + } +} + YY_BREAK +case 26: +YY_RULE_SETUP +#line 290 "d2_lexer.ll" +{ + switch(driver.ctx_) { + case isc::d2::D2ParserContext::LOGGERS: + return isc::d2::D2Parser::make_OUTPUT_OPTIONS(driver.loc_); + default: + return isc::d2::D2Parser::make_STRING("output_options", driver.loc_); + } +} + YY_BREAK +case 27: +YY_RULE_SETUP +#line 299 "d2_lexer.ll" +{ + switch(driver.ctx_) { + case isc::d2::D2ParserContext::OUTPUT_OPTIONS: + return isc::d2::D2Parser::make_OUTPUT(driver.loc_); + default: + return isc::d2::D2Parser::make_STRING("output", driver.loc_); + } +} + YY_BREAK +case 28: +YY_RULE_SETUP +#line 308 "d2_lexer.ll" +{ + switch(driver.ctx_) { + case isc::d2::D2ParserContext::LOGGERS: + return isc::d2::D2Parser::make_NAME(driver.loc_); + default: + return isc::d2::D2Parser::make_STRING("name", driver.loc_); + } +} + YY_BREAK +case 29: +YY_RULE_SETUP +#line 317 "d2_lexer.ll" +{ + switch(driver.ctx_) { + case isc::d2::D2ParserContext::LOGGERS: + return isc::d2::D2Parser::make_DEBUGLEVEL(driver.loc_); + default: + return isc::d2::D2Parser::make_STRING("debuglevel", driver.loc_); + } +} + YY_BREAK +case 30: +YY_RULE_SETUP +#line 326 "d2_lexer.ll" +{ + switch(driver.ctx_) { + case isc::d2::D2ParserContext::LOGGERS: + return isc::d2::D2Parser::make_SEVERITY(driver.loc_); + default: + return isc::d2::D2Parser::make_STRING("severity", driver.loc_); + } +} + YY_BREAK +case 31: +YY_RULE_SETUP +#line 335 "d2_lexer.ll" +{ + switch(driver.ctx_) { + case isc::d2::D2ParserContext::CONFIG: + return isc::d2::D2Parser::make_DHCP4(driver.loc_); + default: + return isc::d2::D2Parser::make_STRING("Dhcp4", driver.loc_); + } +} + YY_BREAK +case 32: +YY_RULE_SETUP +#line 344 "d2_lexer.ll" +{ + switch(driver.ctx_) { + case isc::d2::D2ParserContext::CONFIG: + return isc::d2::D2Parser::make_DHCP6(driver.loc_); + default: + return isc::d2::D2Parser::make_STRING("Dhcp6", driver.loc_); + } +} + YY_BREAK +case 33: +YY_RULE_SETUP +#line 354 "d2_lexer.ll" { // A string has been matched. It contains the actual string and single quotes. // We need to get those quotes out of the way and just use its content, e.g. @@ -1743,68 +2003,68 @@ YY_RULE_SETUP } } - return isc::dhcp::D2Parser::make_STRING(decoded, driver.loc_); + return isc::d2::D2Parser::make_STRING(decoded, driver.loc_); } YY_BREAK -case 26: -/* rule 26 can match eol */ +case 34: +/* rule 34 can match eol */ YY_RULE_SETUP -#line 376 "d2_lexer.ll" +#line 452 "d2_lexer.ll" { // Bad string with a forbidden control character inside driver.error(driver.loc_, "Invalid control in " + std::string(yytext)); } YY_BREAK -case 27: -/* rule 27 can match eol */ +case 35: +/* rule 35 can match eol */ YY_RULE_SETUP -#line 381 "d2_lexer.ll" +#line 457 "d2_lexer.ll" { // Bad string with a bad escape inside driver.error(driver.loc_, "Bad escape in " + std::string(yytext)); } YY_BREAK -case 28: +case 36: YY_RULE_SETUP -#line 386 "d2_lexer.ll" +#line 462 "d2_lexer.ll" { // Bad string with an open escape at the end driver.error(driver.loc_, "Overflow escape in " + std::string(yytext)); } YY_BREAK -case 29: +case 37: YY_RULE_SETUP -#line 391 "d2_lexer.ll" -{ return isc::dhcp::D2Parser::make_LSQUARE_BRACKET(driver.loc_); } +#line 467 "d2_lexer.ll" +{ return isc::d2::D2Parser::make_LSQUARE_BRACKET(driver.loc_); } YY_BREAK -case 30: +case 38: YY_RULE_SETUP -#line 392 "d2_lexer.ll" -{ return isc::dhcp::D2Parser::make_RSQUARE_BRACKET(driver.loc_); } +#line 468 "d2_lexer.ll" +{ return isc::d2::D2Parser::make_RSQUARE_BRACKET(driver.loc_); } YY_BREAK -case 31: +case 39: YY_RULE_SETUP -#line 393 "d2_lexer.ll" -{ return isc::dhcp::D2Parser::make_LCURLY_BRACKET(driver.loc_); } +#line 469 "d2_lexer.ll" +{ return isc::d2::D2Parser::make_LCURLY_BRACKET(driver.loc_); } YY_BREAK -case 32: +case 40: YY_RULE_SETUP -#line 394 "d2_lexer.ll" -{ return isc::dhcp::D2Parser::make_RCURLY_BRACKET(driver.loc_); } +#line 470 "d2_lexer.ll" +{ return isc::d2::D2Parser::make_RCURLY_BRACKET(driver.loc_); } YY_BREAK -case 33: +case 41: YY_RULE_SETUP -#line 395 "d2_lexer.ll" -{ return isc::dhcp::D2Parser::make_COMMA(driver.loc_); } +#line 471 "d2_lexer.ll" +{ return isc::d2::D2Parser::make_COMMA(driver.loc_); } YY_BREAK -case 34: +case 42: YY_RULE_SETUP -#line 396 "d2_lexer.ll" -{ return isc::dhcp::D2Parser::make_COLON(driver.loc_); } +#line 472 "d2_lexer.ll" +{ return isc::d2::D2Parser::make_COLON(driver.loc_); } YY_BREAK -case 35: +case 43: YY_RULE_SETUP -#line 398 "d2_lexer.ll" +#line 474 "d2_lexer.ll" { // An integer was found. std::string tmp(yytext); @@ -1820,12 +2080,12 @@ YY_RULE_SETUP } // The parser needs the string form as double conversion is no lossless - return isc::dhcp::D2Parser::make_INTEGER(integer, driver.loc_); + return isc::d2::D2Parser::make_INTEGER(integer, driver.loc_); } YY_BREAK -case 36: +case 44: YY_RULE_SETUP -#line 416 "d2_lexer.ll" +#line 492 "d2_lexer.ll" { // A floating point was found. std::string tmp(yytext); @@ -1836,49 +2096,49 @@ YY_RULE_SETUP driver.error(driver.loc_, "Failed to convert " + tmp + " to a floating point."); } - return isc::dhcp::D2Parser::make_FLOAT(fp, driver.loc_); + return isc::d2::D2Parser::make_FLOAT(fp, driver.loc_); } YY_BREAK -case 37: +case 45: YY_RULE_SETUP -#line 429 "d2_lexer.ll" +#line 505 "d2_lexer.ll" { string tmp(yytext); - return isc::dhcp::D2Parser::make_BOOLEAN(tmp == "true", driver.loc_); + return isc::d2::D2Parser::make_BOOLEAN(tmp == "true", driver.loc_); } YY_BREAK -case 38: +case 46: YY_RULE_SETUP -#line 434 "d2_lexer.ll" +#line 510 "d2_lexer.ll" { - return isc::dhcp::D2Parser::make_NULL_TYPE(driver.loc_); + return isc::d2::D2Parser::make_NULL_TYPE(driver.loc_); } YY_BREAK -case 39: +case 47: YY_RULE_SETUP -#line 438 "d2_lexer.ll" +#line 514 "d2_lexer.ll" driver.error (driver.loc_, "JSON true reserved keyword is lower case only"); YY_BREAK -case 40: +case 48: YY_RULE_SETUP -#line 440 "d2_lexer.ll" +#line 516 "d2_lexer.ll" driver.error (driver.loc_, "JSON false reserved keyword is lower case only"); YY_BREAK -case 41: +case 49: YY_RULE_SETUP -#line 442 "d2_lexer.ll" +#line 518 "d2_lexer.ll" driver.error (driver.loc_, "JSON null reserved keyword is lower case only"); YY_BREAK -case 42: +case 50: YY_RULE_SETUP -#line 444 "d2_lexer.ll" +#line 520 "d2_lexer.ll" driver.error (driver.loc_, "Invalid character: " + std::string(yytext)); YY_BREAK case YY_STATE_EOF(INITIAL): -#line 446 "d2_lexer.ll" +#line 522 "d2_lexer.ll" { if (driver.states_.empty()) { - return isc::dhcp::D2Parser::make_END(driver.loc_); + return isc::d2::D2Parser::make_END(driver.loc_); } driver.loc_ = driver.locs_.back(); driver.locs_.pop_back(); @@ -1899,12 +2159,12 @@ case YY_STATE_EOF(INITIAL): BEGIN(DIR_EXIT); } YY_BREAK -case 43: +case 51: YY_RULE_SETUP -#line 469 "d2_lexer.ll" +#line 545 "d2_lexer.ll" ECHO; YY_BREAK -#line 1907 "d2_lexer.cc" +#line 2167 "d2_lexer.cc" case YY_END_OF_BUFFER: { @@ -2219,7 +2479,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 207 ) + if ( yy_current_state >= 278 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; @@ -2252,11 +2512,11 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 207 ) + if ( yy_current_state >= 278 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - yy_is_jam = (yy_current_state == 206); + yy_is_jam = (yy_current_state == 277); return yy_is_jam ? 0 : yy_current_state; } @@ -3005,7 +3265,7 @@ void d2_parser_free (void * ptr ) /* %ok-for-header */ -#line 469 "d2_lexer.ll" +#line 545 "d2_lexer.ll" using namespace isc::dhcp; diff --git a/src/bin/d2/d2_lexer.ll b/src/bin/d2/d2_lexer.ll index feccf57f5b..b15e27667d 100644 --- a/src/bin/d2/d2_lexer.ll +++ b/src/bin/d2/d2_lexer.ll @@ -25,13 +25,13 @@ namespace { bool start_token_flag = false; -isc::dhcp::D2ParserContext::ParserType start_token_value; +isc::d2::D2ParserContext::ParserType start_token_value; unsigned int comment_start_line = 0; }; // To avoid the call to exit... oops! -#define YY_FATAL_ERROR(msg) isc::dhcp::D2ParserContext::fatal(msg) +#define YY_FATAL_ERROR(msg) isc::d2::D2ParserContext::fatal(msg) %} /* noyywrap disables automatic rewinding for the next file to parse. Since we @@ -104,9 +104,11 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} switch (start_token_value) { case D2ParserContext::PARSER_JSON: default: - return isc::dhcp::D2Parser::make_TOPLEVEL_JSON(driver.loc_); + return isc::d2::D2Parser::make_TOPLEVEL_JSON(driver.loc_); case D2ParserContext::PARSER_DHCPDDNS: - return isc::dhcp::D2Parser::make_TOPLEVEL_DHCPDDNS(driver.loc_); + return isc::d2::D2Parser::make_TOPLEVEL_DHCPDDNS(driver.loc_); + case D2ParserContext::PARSER_SUB_DHCPDDNS: + return isc::d2::D2Parser::make_SUB_DHCPDDNS(driver.loc_); } } %} @@ -154,126 +156,200 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} driver.loc_.step(); } +\"DhcpDdns\" { + switch(driver.ctx_) { + case isc::d2::D2ParserContext::CONFIG: + return isc::d2::D2Parser::make_DHCPDDNS(driver.loc_); + default: + return isc::d2::D2Parser::make_STRING("DhcpDdns", driver.loc_); + } +} + \"ip-address\" { switch(driver.ctx_) { - case isc::dhcp::D2ParserContext::DHCPDDNS: - return isc::dhcp::D2Parser::make_IP_ADDRESS(driver.loc_); + case isc::d2::D2ParserContext::DHCPDDNS: + return isc::d2::D2Parser::make_IP_ADDRESS(driver.loc_); default: - return isc::dhcp::D2Parser::make_STRING("ip-address", driver.loc_); + return isc::d2::D2Parser::make_STRING("ip-address", driver.loc_); } } \"port\" { switch(driver.ctx_) { - case isc::dhcp::D2ParserContext::DHCPDDNS: - return isc::dhcp::D2Parser::make_PORT(driver.loc_); + case isc::d2::D2ParserContext::DHCPDDNS: + return isc::d2::D2Parser::make_PORT(driver.loc_); default: - return isc::dhcp::D2Parser::make_STRING("port", driver.loc_); + return isc::d2::D2Parser::make_STRING("port", driver.loc_); + } +} + +\"dns-server-timeout\" { + switch(driver.ctx_) { + case isc::d2::D2ParserContext::DHCPDDNS: + return isc::d2::D2Parser::make_DNS_SERVER_TIMEOUT(driver.loc_); + default: + return isc::d2::D2Parser::make_STRING("dns-server-timeout", driver.loc_); } } \"ncr-protocol\" { switch(driver.ctx_) { - case isc::dhcp::D2ParserContext::DHCPDDNS: - return isc::dhcp::D2Parser::make_NCR_PROTOCOL(driver.loc_); + case isc::d2::D2ParserContext::DHCPDDNS: + return isc::d2::D2Parser::make_NCR_PROTOCOL(driver.loc_); default: - return isc::dhcp::D2Parser::make_STRING("ncr-protocol", driver.loc_); + return isc::d2::D2Parser::make_STRING("ncr-protocol", driver.loc_); } } \"ncr-format\" { switch(driver.ctx_) { - case isc::dhcp::D2ParserContext::DHCPDDNS: - return isc::dhcp::D2Parser::make_NCR_FORMAT(driver.loc_); + case isc::d2::D2ParserContext::DHCPDDNS: + return isc::d2::D2Parser::make_NCR_FORMAT(driver.loc_); default: - return isc::dhcp::D2Parser::make_STRING("ncr-format", driver.loc_); + return isc::d2::D2Parser::make_STRING("ncr-format", driver.loc_); } } (?i:\"UDP\") { /* dhcp-ddns value keywords are case insensitive */ - if (driver.ctx_ == isc::dhcp::D2ParserContext::NCR_PROTOCOL) { - return isc::dhcp::D2Parser::make_UDP(driver.loc_); + if (driver.ctx_ == isc::d2::D2ParserContext::NCR_PROTOCOL) { + return isc::d2::D2Parser::make_UDP(driver.loc_); } std::string tmp(yytext+1); tmp.resize(tmp.size() - 1); - return isc::dhcp::D2Parser::make_STRING(tmp, driver.loc_); + return isc::d2::D2Parser::make_STRING(tmp, driver.loc_); } (?i:\"TCP\") { /* dhcp-ddns value keywords are case insensitive */ - if (driver.ctx_ == isc::dhcp::D2ParserContext::NCR_PROTOCOL) { - return isc::dhcp::D2Parser::make_TCP(driver.loc_); + if (driver.ctx_ == isc::d2::D2ParserContext::NCR_PROTOCOL) { + return isc::d2::D2Parser::make_TCP(driver.loc_); } std::string tmp(yytext+1); tmp.resize(tmp.size() - 1); - return isc::dhcp::D2Parser::make_STRING(tmp, driver.loc_); + return isc::d2::D2Parser::make_STRING(tmp, driver.loc_); } (?i:\"JSON\") { /* dhcp-ddns value keywords are case insensitive */ - if (driver.ctx_ == isc::dhcp::D2ParserContext::NCR_FORMAT) { - return isc::dhcp::D2Parser::make_JSON(driver.loc_); + if (driver.ctx_ == isc::d2::D2ParserContext::NCR_FORMAT) { + return isc::d2::D2Parser::make_JSON(driver.loc_); } std::string tmp(yytext+1); tmp.resize(tmp.size() - 1); - return isc::dhcp::D2Parser::make_STRING(tmp, driver.loc_); + return isc::d2::D2Parser::make_STRING(tmp, driver.loc_); +} + +\"forward-ddns\" { + switch(driver.ctx_) { + case isc::d2::D2ParserContext::DHCPDDNS: + return isc::d2::D2Parser::make_FORWARD_DDNS(driver.loc_); + default: + return isc::d2::D2Parser::make_STRING("forward-ddns", driver.loc_); + } +} + +\"reverse-ddns\" { + switch(driver.ctx_) { + case isc::d2::D2ParserContext::DHCPDDNS: + return isc::d2::D2Parser::make_REVERSE_DDNS(driver.loc_); + default: + return isc::d2::D2Parser::make_STRING("reverse-ddns", driver.loc_); + } +} + +\"tsig-keys\" { + switch(driver.ctx_) { + case isc::d2::D2ParserContext::DHCPDDNS: + return isc::d2::D2Parser::make_TSIG_KEYS(driver.loc_); + default: + return isc::d2::D2Parser::make_STRING("tsig-keys", driver.loc_); + } } + \"Logging\" { switch(driver.ctx_) { - case isc::dhcp::D2ParserContext::CONFIG: - return isc::dhcp::D2Parser::make_LOGGING(driver.loc_); + case isc::d2::D2ParserContext::CONFIG: + return isc::d2::D2Parser::make_LOGGING(driver.loc_); default: - return isc::dhcp::D2Parser::make_STRING("Logging", driver.loc_); + return isc::d2::D2Parser::make_STRING("Logging", driver.loc_); } } \"loggers\" { switch(driver.ctx_) { - case isc::dhcp::D2ParserContext::LOGGING: - return isc::dhcp::D2Parser::make_LOGGERS(driver.loc_); + case isc::d2::D2ParserContext::LOGGING: + return isc::d2::D2Parser::make_LOGGERS(driver.loc_); default: - return isc::dhcp::D2Parser::make_STRING("loggers", driver.loc_); + return isc::d2::D2Parser::make_STRING("loggers", driver.loc_); } } \"output_options\" { switch(driver.ctx_) { - case isc::dhcp::D2ParserContext::LOGGERS: - return isc::dhcp::D2Parser::make_OUTPUT_OPTIONS(driver.loc_); + case isc::d2::D2ParserContext::LOGGERS: + return isc::d2::D2Parser::make_OUTPUT_OPTIONS(driver.loc_); default: - return isc::dhcp::D2Parser::make_STRING("output_options", driver.loc_); + return isc::d2::D2Parser::make_STRING("output_options", driver.loc_); } } \"output\" { switch(driver.ctx_) { - case isc::dhcp::D2ParserContext::OUTPUT_OPTIONS: - return isc::dhcp::D2Parser::make_OUTPUT(driver.loc_); + case isc::d2::D2ParserContext::OUTPUT_OPTIONS: + return isc::d2::D2Parser::make_OUTPUT(driver.loc_); default: - return isc::dhcp::D2Parser::make_STRING("output", driver.loc_); + return isc::d2::D2Parser::make_STRING("output", driver.loc_); + } +} + +\"name\" { + switch(driver.ctx_) { + case isc::d2::D2ParserContext::LOGGERS: + return isc::d2::D2Parser::make_NAME(driver.loc_); + default: + return isc::d2::D2Parser::make_STRING("name", driver.loc_); } } \"debuglevel\" { switch(driver.ctx_) { - case isc::dhcp::D2ParserContext::LOGGERS: - return isc::dhcp::D2Parser::make_DEBUGLEVEL(driver.loc_); + case isc::d2::D2ParserContext::LOGGERS: + return isc::d2::D2Parser::make_DEBUGLEVEL(driver.loc_); default: - return isc::dhcp::D2Parser::make_STRING("debuglevel", driver.loc_); + return isc::d2::D2Parser::make_STRING("debuglevel", driver.loc_); } } \"severity\" { switch(driver.ctx_) { - case isc::dhcp::D2ParserContext::LOGGERS: - return isc::dhcp::D2Parser::make_SEVERITY(driver.loc_); + case isc::d2::D2ParserContext::LOGGERS: + return isc::d2::D2Parser::make_SEVERITY(driver.loc_); default: - return isc::dhcp::D2Parser::make_STRING("severity", driver.loc_); + return isc::d2::D2Parser::make_STRING("severity", driver.loc_); } } +\"Dhcp4\" { + switch(driver.ctx_) { + case isc::d2::D2ParserContext::CONFIG: + return isc::d2::D2Parser::make_DHCP4(driver.loc_); + default: + return isc::d2::D2Parser::make_STRING("Dhcp4", driver.loc_); + } +} + +\"Dhcp6\" { + switch(driver.ctx_) { + case isc::d2::D2ParserContext::CONFIG: + return isc::d2::D2Parser::make_DHCP6(driver.loc_); + default: + return isc::d2::D2Parser::make_STRING("Dhcp6", driver.loc_); + } +} + + {JSONString} { // A string has been matched. It contains the actual string and single quotes. // We need to get those quotes out of the way and just use its content, e.g. @@ -369,7 +445,7 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} } } - return isc::dhcp::D2Parser::make_STRING(decoded, driver.loc_); + return isc::d2::D2Parser::make_STRING(decoded, driver.loc_); } \"{JSONStringCharacter}*{ControlCharacter}{ControlCharacterFill}*\" { @@ -387,12 +463,12 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} driver.error(driver.loc_, "Overflow escape in " + std::string(yytext)); } -"[" { return isc::dhcp::D2Parser::make_LSQUARE_BRACKET(driver.loc_); } -"]" { return isc::dhcp::D2Parser::make_RSQUARE_BRACKET(driver.loc_); } -"{" { return isc::dhcp::D2Parser::make_LCURLY_BRACKET(driver.loc_); } -"}" { return isc::dhcp::D2Parser::make_RCURLY_BRACKET(driver.loc_); } -"," { return isc::dhcp::D2Parser::make_COMMA(driver.loc_); } -":" { return isc::dhcp::D2Parser::make_COLON(driver.loc_); } +"[" { return isc::d2::D2Parser::make_LSQUARE_BRACKET(driver.loc_); } +"]" { return isc::d2::D2Parser::make_RSQUARE_BRACKET(driver.loc_); } +"{" { return isc::d2::D2Parser::make_LCURLY_BRACKET(driver.loc_); } +"}" { return isc::d2::D2Parser::make_RCURLY_BRACKET(driver.loc_); } +"," { return isc::d2::D2Parser::make_COMMA(driver.loc_); } +":" { return isc::d2::D2Parser::make_COLON(driver.loc_); } {int} { // An integer was found. @@ -409,7 +485,7 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} } // The parser needs the string form as double conversion is no lossless - return isc::dhcp::D2Parser::make_INTEGER(integer, driver.loc_); + return isc::d2::D2Parser::make_INTEGER(integer, driver.loc_); } [-+]?[0-9]*\.?[0-9]*([eE][-+]?[0-9]+)? { @@ -422,16 +498,16 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} driver.error(driver.loc_, "Failed to convert " + tmp + " to a floating point."); } - return isc::dhcp::D2Parser::make_FLOAT(fp, driver.loc_); + return isc::d2::D2Parser::make_FLOAT(fp, driver.loc_); } true|false { string tmp(yytext); - return isc::dhcp::D2Parser::make_BOOLEAN(tmp == "true", driver.loc_); + return isc::d2::D2Parser::make_BOOLEAN(tmp == "true", driver.loc_); } null { - return isc::dhcp::D2Parser::make_NULL_TYPE(driver.loc_); + return isc::d2::D2Parser::make_NULL_TYPE(driver.loc_); } (?i:true) driver.error (driver.loc_, "JSON true reserved keyword is lower case only"); @@ -444,7 +520,7 @@ null { <> { if (driver.states_.empty()) { - return isc::dhcp::D2Parser::make_END(driver.loc_); + return isc::d2::D2Parser::make_END(driver.loc_); } driver.loc_ = driver.locs_.back(); driver.locs_.pop_back(); diff --git a/src/bin/d2/d2_parser.cc b/src/bin/d2/d2_parser.cc index a711f41e5a..4352b6ba99 100644 --- a/src/bin/d2/d2_parser.cc +++ b/src/bin/d2/d2_parser.cc @@ -140,7 +140,7 @@ #define YYRECOVERING() (!!yyerrstatus_) #line 14 "d2_parser.yy" // lalr1.cc:479 -namespace isc { namespace dhcp { +namespace isc { namespace d2 { #line 145 "d2_parser.cc" // lalr1.cc:479 /* Return YYSTR after stripping away unnecessary quotes and @@ -182,7 +182,7 @@ namespace isc { namespace dhcp { /// Build a parser object. - D2Parser::D2Parser (isc::dhcp::D2ParserContext& ctx_yyarg) + D2Parser::D2Parser (isc::d2::D2ParserContext& ctx_yyarg) : #if D2_PARSER_DEBUG yydebug_ (false), @@ -253,24 +253,24 @@ namespace isc { namespace dhcp { { switch (that.type_get ()) { - case 40: // value - case 67: // ncr_protocol_value + case 43: // value + case 70: // ncr_protocol_value value.move< ElementPtr > (that.value); break; - case 34: // "boolean" + case 37: // "boolean" value.move< bool > (that.value); break; - case 33: // "floating point" + case 36: // "floating point" value.move< double > (that.value); break; - case 32: // "integer" + case 35: // "integer" value.move< int64_t > (that.value); break; - case 31: // "constant string" + case 34: // "constant string" value.move< std::string > (that.value); break; @@ -289,24 +289,24 @@ namespace isc { namespace dhcp { state = that.state; switch (that.type_get ()) { - case 40: // value - case 67: // ncr_protocol_value + case 43: // value + case 70: // ncr_protocol_value value.copy< ElementPtr > (that.value); break; - case 34: // "boolean" + case 37: // "boolean" value.copy< bool > (that.value); break; - case 33: // "floating point" + case 36: // "floating point" value.copy< double > (that.value); break; - case 32: // "integer" + case 35: // "integer" value.copy< int64_t > (that.value); break; - case 31: // "constant string" + case 34: // "constant string" value.copy< std::string > (that.value); break; @@ -346,44 +346,44 @@ namespace isc { namespace dhcp { << yysym.location << ": "; switch (yytype) { - case 31: // "constant string" + case 34: // "constant string" -#line 88 "d2_parser.yy" // lalr1.cc:636 +#line 91 "d2_parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } #line 354 "d2_parser.cc" // lalr1.cc:636 break; - case 32: // "integer" + case 35: // "integer" -#line 88 "d2_parser.yy" // lalr1.cc:636 +#line 91 "d2_parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< int64_t > (); } #line 361 "d2_parser.cc" // lalr1.cc:636 break; - case 33: // "floating point" + case 36: // "floating point" -#line 88 "d2_parser.yy" // lalr1.cc:636 +#line 91 "d2_parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< double > (); } #line 368 "d2_parser.cc" // lalr1.cc:636 break; - case 34: // "boolean" + case 37: // "boolean" -#line 88 "d2_parser.yy" // lalr1.cc:636 +#line 91 "d2_parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< bool > (); } #line 375 "d2_parser.cc" // lalr1.cc:636 break; - case 40: // value + case 43: // value -#line 88 "d2_parser.yy" // lalr1.cc:636 +#line 91 "d2_parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< ElementPtr > (); } #line 382 "d2_parser.cc" // lalr1.cc:636 break; - case 67: // ncr_protocol_value + case 70: // ncr_protocol_value -#line 88 "d2_parser.yy" // lalr1.cc:636 +#line 91 "d2_parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< ElementPtr > (); } #line 389 "d2_parser.cc" // lalr1.cc:636 break; @@ -585,24 +585,24 @@ namespace isc { namespace dhcp { when using variants. */ switch (yyr1_[yyn]) { - case 40: // value - case 67: // ncr_protocol_value + case 43: // value + case 70: // ncr_protocol_value yylhs.value.build< ElementPtr > (); break; - case 34: // "boolean" + case 37: // "boolean" yylhs.value.build< bool > (); break; - case 33: // "floating point" + case 36: // "floating point" yylhs.value.build< double > (); break; - case 32: // "integer" + case 35: // "integer" yylhs.value.build< int64_t > (); break; - case 31: // "constant string" + case 34: // "constant string" yylhs.value.build< std::string > (); break; @@ -624,67 +624,67 @@ namespace isc { namespace dhcp { switch (yyn) { case 2: -#line 97 "d2_parser.yy" // lalr1.cc:859 +#line 100 "d2_parser.yy" // lalr1.cc:859 { ctx.ctx_ = ctx.NO_KEYWORD; } #line 630 "d2_parser.cc" // lalr1.cc:859 break; case 4: -#line 98 "d2_parser.yy" // lalr1.cc:859 +#line 101 "d2_parser.yy" // lalr1.cc:859 { ctx.ctx_ = ctx.CONFIG; } #line 636 "d2_parser.cc" // lalr1.cc:859 break; case 6: -#line 99 "d2_parser.yy" // lalr1.cc:859 +#line 102 "d2_parser.yy" // lalr1.cc:859 { ctx.ctx_ = ctx.DHCPDDNS; } #line 642 "d2_parser.cc" // lalr1.cc:859 break; case 8: -#line 107 "d2_parser.yy" // lalr1.cc:859 +#line 110 "d2_parser.yy" // lalr1.cc:859 { yylhs.value.as< ElementPtr > () = ElementPtr(new IntElement(yystack_[0].value.as< int64_t > (), ctx.loc2pos(yystack_[0].location))); } #line 648 "d2_parser.cc" // lalr1.cc:859 break; case 9: -#line 108 "d2_parser.yy" // lalr1.cc:859 +#line 111 "d2_parser.yy" // lalr1.cc:859 { yylhs.value.as< ElementPtr > () = ElementPtr(new DoubleElement(yystack_[0].value.as< double > (), ctx.loc2pos(yystack_[0].location))); } #line 654 "d2_parser.cc" // lalr1.cc:859 break; case 10: -#line 109 "d2_parser.yy" // lalr1.cc:859 +#line 112 "d2_parser.yy" // lalr1.cc:859 { yylhs.value.as< ElementPtr > () = ElementPtr(new BoolElement(yystack_[0].value.as< bool > (), ctx.loc2pos(yystack_[0].location))); } #line 660 "d2_parser.cc" // lalr1.cc:859 break; case 11: -#line 110 "d2_parser.yy" // lalr1.cc:859 +#line 113 "d2_parser.yy" // lalr1.cc:859 { yylhs.value.as< ElementPtr > () = ElementPtr(new StringElement(yystack_[0].value.as< std::string > (), ctx.loc2pos(yystack_[0].location))); } #line 666 "d2_parser.cc" // lalr1.cc:859 break; case 12: -#line 111 "d2_parser.yy" // lalr1.cc:859 +#line 114 "d2_parser.yy" // lalr1.cc:859 { yylhs.value.as< ElementPtr > () = ElementPtr(new NullElement(ctx.loc2pos(yystack_[0].location))); } #line 672 "d2_parser.cc" // lalr1.cc:859 break; case 13: -#line 112 "d2_parser.yy" // lalr1.cc:859 +#line 115 "d2_parser.yy" // lalr1.cc:859 { yylhs.value.as< ElementPtr > () = ctx.stack_.back(); ctx.stack_.pop_back(); } #line 678 "d2_parser.cc" // lalr1.cc:859 break; case 14: -#line 113 "d2_parser.yy" // lalr1.cc:859 +#line 116 "d2_parser.yy" // lalr1.cc:859 { yylhs.value.as< ElementPtr > () = ctx.stack_.back(); ctx.stack_.pop_back(); } #line 684 "d2_parser.cc" // lalr1.cc:859 break; case 15: -#line 116 "d2_parser.yy" // lalr1.cc:859 +#line 119 "d2_parser.yy" // lalr1.cc:859 { // Push back the JSON value on the stack ctx.stack_.push_back(yystack_[0].value.as< ElementPtr > ()); @@ -693,7 +693,7 @@ namespace isc { namespace dhcp { break; case 16: -#line 121 "d2_parser.yy" // lalr1.cc:859 +#line 124 "d2_parser.yy" // lalr1.cc:859 { // This code is executed when we're about to start parsing // the content of the map @@ -704,7 +704,7 @@ namespace isc { namespace dhcp { break; case 17: -#line 126 "d2_parser.yy" // lalr1.cc:859 +#line 129 "d2_parser.yy" // lalr1.cc:859 { // map parsing completed. If we ever want to do any wrap up // (maybe some sanity checking), this would be the best place @@ -714,7 +714,7 @@ namespace isc { namespace dhcp { break; case 20: -#line 137 "d2_parser.yy" // lalr1.cc:859 +#line 140 "d2_parser.yy" // lalr1.cc:859 { // map containing a single entry ctx.stack_.back()->set(yystack_[2].value.as< std::string > (), yystack_[0].value.as< ElementPtr > ()); @@ -723,7 +723,7 @@ namespace isc { namespace dhcp { break; case 21: -#line 141 "d2_parser.yy" // lalr1.cc:859 +#line 144 "d2_parser.yy" // lalr1.cc:859 { // map consisting of a shorter map followed by // comma and string:value @@ -733,7 +733,7 @@ namespace isc { namespace dhcp { break; case 22: -#line 148 "d2_parser.yy" // lalr1.cc:859 +#line 151 "d2_parser.yy" // lalr1.cc:859 { ElementPtr l(new ListElement(ctx.loc2pos(yystack_[0].location))); ctx.stack_.push_back(l); @@ -742,7 +742,7 @@ namespace isc { namespace dhcp { break; case 23: -#line 151 "d2_parser.yy" // lalr1.cc:859 +#line 154 "d2_parser.yy" // lalr1.cc:859 { // list parsing complete. Put any sanity checking here } @@ -750,7 +750,7 @@ namespace isc { namespace dhcp { break; case 26: -#line 167 "d2_parser.yy" // lalr1.cc:859 +#line 170 "d2_parser.yy" // lalr1.cc:859 { // List consisting of a single element. ctx.stack_.back()->add(yystack_[0].value.as< ElementPtr > ()); @@ -759,7 +759,7 @@ namespace isc { namespace dhcp { break; case 27: -#line 171 "d2_parser.yy" // lalr1.cc:859 +#line 174 "d2_parser.yy" // lalr1.cc:859 { // List ending with , and a value. ctx.stack_.back()->add(yystack_[0].value.as< ElementPtr > ()); @@ -768,7 +768,7 @@ namespace isc { namespace dhcp { break; case 28: -#line 182 "d2_parser.yy" // lalr1.cc:859 +#line 185 "d2_parser.yy" // lalr1.cc:859 { const std::string& where = ctx.contextName(); const std::string& keyword = yystack_[1].value.as< std::string > (); @@ -779,7 +779,7 @@ namespace isc { namespace dhcp { break; case 29: -#line 192 "d2_parser.yy" // lalr1.cc:859 +#line 195 "d2_parser.yy" // lalr1.cc:859 { // This code is executed when we're about to start parsing // the content of the map @@ -790,7 +790,7 @@ namespace isc { namespace dhcp { break; case 30: -#line 197 "d2_parser.yy" // lalr1.cc:859 +#line 200 "d2_parser.yy" // lalr1.cc:859 { // map parsing completed. If we ever want to do any wrap up // (maybe some sanity checking), this would be the best place @@ -800,7 +800,7 @@ namespace isc { namespace dhcp { break; case 38: -#line 218 "d2_parser.yy" // lalr1.cc:859 +#line 221 "d2_parser.yy" // lalr1.cc:859 { ElementPtr m(new MapElement(ctx.loc2pos(yystack_[0].location))); ctx.stack_.back()->set("DhcpDdns", m); @@ -811,7 +811,7 @@ namespace isc { namespace dhcp { break; case 39: -#line 223 "d2_parser.yy" // lalr1.cc:859 +#line 226 "d2_parser.yy" // lalr1.cc:859 { ctx.stack_.pop_back(); ctx.leave(); @@ -820,7 +820,7 @@ namespace isc { namespace dhcp { break; case 40: -#line 228 "d2_parser.yy" // lalr1.cc:859 +#line 231 "d2_parser.yy" // lalr1.cc:859 { // Parse the dhcpddns map ElementPtr m(new MapElement(ctx.loc2pos(yystack_[0].location))); @@ -830,23 +830,23 @@ namespace isc { namespace dhcp { break; case 41: -#line 232 "d2_parser.yy" // lalr1.cc:859 +#line 235 "d2_parser.yy" // lalr1.cc:859 { // parsing completed } #line 838 "d2_parser.cc" // lalr1.cc:859 break; - case 50: -#line 248 "d2_parser.yy" // lalr1.cc:859 + case 53: +#line 254 "d2_parser.yy" // lalr1.cc:859 { ctx.enter(ctx.NO_KEYWORD); } #line 846 "d2_parser.cc" // lalr1.cc:859 break; - case 51: -#line 250 "d2_parser.yy" // lalr1.cc:859 + case 54: +#line 256 "d2_parser.yy" // lalr1.cc:859 { ElementPtr s(new StringElement(yystack_[0].value.as< std::string > (), ctx.loc2pos(yystack_[0].location))); ctx.stack_.back()->set("ip-address", s); @@ -855,266 +855,324 @@ namespace isc { namespace dhcp { #line 856 "d2_parser.cc" // lalr1.cc:859 break; - case 52: -#line 256 "d2_parser.yy" // lalr1.cc:859 + case 55: +#line 262 "d2_parser.yy" // lalr1.cc:859 { + if (yystack_[0].value.as< int64_t > () <= 0) { + error(yystack_[0].location, "port must be greater than zero"); + } ElementPtr i(new IntElement(yystack_[0].value.as< int64_t > (), ctx.loc2pos(yystack_[0].location))); ctx.stack_.back()->set("port", i); } -#line 865 "d2_parser.cc" // lalr1.cc:859 +#line 868 "d2_parser.cc" // lalr1.cc:859 break; - case 53: -#line 261 "d2_parser.yy" // lalr1.cc:859 + case 56: +#line 270 "d2_parser.yy" // lalr1.cc:859 { - ElementPtr i(new IntElement(yystack_[0].value.as< int64_t > (), ctx.loc2pos(yystack_[0].location))); - ctx.stack_.back()->set("dns-server-timeout", i); + if (yystack_[0].value.as< int64_t > () <= 0) { + error(yystack_[0].location, "dns-server-timeout must be greater than zero"); + } else { + ElementPtr i(new IntElement(yystack_[0].value.as< int64_t > (), ctx.loc2pos(yystack_[0].location))); + ctx.stack_.back()->set("dns-server-timeout", i); + } } -#line 874 "d2_parser.cc" // lalr1.cc:859 +#line 881 "d2_parser.cc" // lalr1.cc:859 break; - case 54: -#line 266 "d2_parser.yy" // lalr1.cc:859 + case 57: +#line 279 "d2_parser.yy" // lalr1.cc:859 { ctx.enter(ctx.NCR_PROTOCOL); } -#line 882 "d2_parser.cc" // lalr1.cc:859 +#line 889 "d2_parser.cc" // lalr1.cc:859 break; - case 55: -#line 268 "d2_parser.yy" // lalr1.cc:859 + case 58: +#line 281 "d2_parser.yy" // lalr1.cc:859 { ctx.stack_.back()->set("ncr-protocol", yystack_[0].value.as< ElementPtr > ()); ctx.leave(); } -#line 891 "d2_parser.cc" // lalr1.cc:859 +#line 898 "d2_parser.cc" // lalr1.cc:859 break; - case 56: -#line 274 "d2_parser.yy" // lalr1.cc:859 + case 59: +#line 287 "d2_parser.yy" // lalr1.cc:859 { yylhs.value.as< ElementPtr > () = ElementPtr(new StringElement("UDP", ctx.loc2pos(yystack_[0].location))); } -#line 897 "d2_parser.cc" // lalr1.cc:859 +#line 904 "d2_parser.cc" // lalr1.cc:859 break; - case 57: -#line 275 "d2_parser.yy" // lalr1.cc:859 + case 60: +#line 288 "d2_parser.yy" // lalr1.cc:859 { yylhs.value.as< ElementPtr > () = ElementPtr(new StringElement("TCP", ctx.loc2pos(yystack_[0].location))); } -#line 903 "d2_parser.cc" // lalr1.cc:859 +#line 910 "d2_parser.cc" // lalr1.cc:859 break; - case 58: -#line 278 "d2_parser.yy" // lalr1.cc:859 + case 61: +#line 291 "d2_parser.yy" // lalr1.cc:859 { ctx.enter(ctx.NCR_FORMAT); } -#line 911 "d2_parser.cc" // lalr1.cc:859 +#line 918 "d2_parser.cc" // lalr1.cc:859 break; - case 59: -#line 280 "d2_parser.yy" // lalr1.cc:859 + case 62: +#line 293 "d2_parser.yy" // lalr1.cc:859 { ElementPtr json(new StringElement("JSON", ctx.loc2pos(yystack_[0].location))); ctx.stack_.back()->set("ncr-format", json); ctx.leave(); } -#line 921 "d2_parser.cc" // lalr1.cc:859 +#line 928 "d2_parser.cc" // lalr1.cc:859 break; - case 60: -#line 286 "d2_parser.yy" // lalr1.cc:859 + case 63: +#line 299 "d2_parser.yy" // lalr1.cc:859 { ctx.enter(ctx.NO_KEYWORD); } -#line 929 "d2_parser.cc" // lalr1.cc:859 +#line 936 "d2_parser.cc" // lalr1.cc:859 break; - case 61: -#line 288 "d2_parser.yy" // lalr1.cc:859 + case 64: +#line 301 "d2_parser.yy" // lalr1.cc:859 + { + ctx.stack_.back()->set("forward-ddns", yystack_[0].value.as< ElementPtr > ()); + ctx.leave(); +} +#line 945 "d2_parser.cc" // lalr1.cc:859 + break; + + case 65: +#line 306 "d2_parser.yy" // lalr1.cc:859 + { + ctx.enter(ctx.NO_KEYWORD); +} +#line 953 "d2_parser.cc" // lalr1.cc:859 + break; + + case 66: +#line 308 "d2_parser.yy" // lalr1.cc:859 + { + ctx.stack_.back()->set("reverse-ddns", yystack_[0].value.as< ElementPtr > ()); + ctx.leave(); +} +#line 962 "d2_parser.cc" // lalr1.cc:859 + break; + + case 67: +#line 313 "d2_parser.yy" // lalr1.cc:859 + { + ctx.enter(ctx.NO_KEYWORD); +} +#line 970 "d2_parser.cc" // lalr1.cc:859 + break; + + case 68: +#line 315 "d2_parser.yy" // lalr1.cc:859 + { + ctx.stack_.back()->set("tsig-keys", yystack_[0].value.as< ElementPtr > ()); + ctx.leave(); +} +#line 979 "d2_parser.cc" // lalr1.cc:859 + break; + + case 69: +#line 320 "d2_parser.yy" // lalr1.cc:859 + { + ctx.enter(ctx.NO_KEYWORD); +} +#line 987 "d2_parser.cc" // lalr1.cc:859 + break; + + case 70: +#line 322 "d2_parser.yy" // lalr1.cc:859 { ctx.stack_.back()->set("Dhcp6", yystack_[0].value.as< ElementPtr > ()); ctx.leave(); } -#line 938 "d2_parser.cc" // lalr1.cc:859 +#line 996 "d2_parser.cc" // lalr1.cc:859 break; - case 62: -#line 293 "d2_parser.yy" // lalr1.cc:859 + case 71: +#line 327 "d2_parser.yy" // lalr1.cc:859 { ctx.enter(ctx.NO_KEYWORD); } -#line 946 "d2_parser.cc" // lalr1.cc:859 +#line 1004 "d2_parser.cc" // lalr1.cc:859 break; - case 63: -#line 295 "d2_parser.yy" // lalr1.cc:859 + case 72: +#line 329 "d2_parser.yy" // lalr1.cc:859 { ctx.stack_.back()->set("Dhcp4", yystack_[0].value.as< ElementPtr > ()); ctx.leave(); } -#line 955 "d2_parser.cc" // lalr1.cc:859 +#line 1013 "d2_parser.cc" // lalr1.cc:859 break; - case 64: -#line 305 "d2_parser.yy" // lalr1.cc:859 + case 73: +#line 339 "d2_parser.yy" // lalr1.cc:859 { ElementPtr m(new MapElement(ctx.loc2pos(yystack_[0].location))); ctx.stack_.back()->set("Logging", m); ctx.stack_.push_back(m); ctx.enter(ctx.LOGGING); } -#line 966 "d2_parser.cc" // lalr1.cc:859 +#line 1024 "d2_parser.cc" // lalr1.cc:859 break; - case 65: -#line 310 "d2_parser.yy" // lalr1.cc:859 + case 74: +#line 344 "d2_parser.yy" // lalr1.cc:859 { ctx.stack_.pop_back(); ctx.leave(); } -#line 975 "d2_parser.cc" // lalr1.cc:859 +#line 1033 "d2_parser.cc" // lalr1.cc:859 break; - case 69: -#line 327 "d2_parser.yy" // lalr1.cc:859 + case 78: +#line 361 "d2_parser.yy" // lalr1.cc:859 { ElementPtr l(new ListElement(ctx.loc2pos(yystack_[0].location))); ctx.stack_.back()->set("loggers", l); ctx.stack_.push_back(l); ctx.enter(ctx.LOGGERS); } -#line 986 "d2_parser.cc" // lalr1.cc:859 +#line 1044 "d2_parser.cc" // lalr1.cc:859 break; - case 70: -#line 332 "d2_parser.yy" // lalr1.cc:859 + case 79: +#line 366 "d2_parser.yy" // lalr1.cc:859 { ctx.stack_.pop_back(); ctx.leave(); } -#line 995 "d2_parser.cc" // lalr1.cc:859 +#line 1053 "d2_parser.cc" // lalr1.cc:859 break; - case 73: -#line 344 "d2_parser.yy" // lalr1.cc:859 + case 82: +#line 378 "d2_parser.yy" // lalr1.cc:859 { ElementPtr l(new MapElement(ctx.loc2pos(yystack_[0].location))); ctx.stack_.back()->add(l); ctx.stack_.push_back(l); } -#line 1005 "d2_parser.cc" // lalr1.cc:859 +#line 1063 "d2_parser.cc" // lalr1.cc:859 break; - case 74: -#line 348 "d2_parser.yy" // lalr1.cc:859 + case 83: +#line 382 "d2_parser.yy" // lalr1.cc:859 { ctx.stack_.pop_back(); } -#line 1013 "d2_parser.cc" // lalr1.cc:859 +#line 1071 "d2_parser.cc" // lalr1.cc:859 break; - case 82: -#line 363 "d2_parser.yy" // lalr1.cc:859 + case 91: +#line 397 "d2_parser.yy" // lalr1.cc:859 { ctx.enter(ctx.NO_KEYWORD); } -#line 1021 "d2_parser.cc" // lalr1.cc:859 +#line 1079 "d2_parser.cc" // lalr1.cc:859 break; - case 83: -#line 365 "d2_parser.yy" // lalr1.cc:859 + case 92: +#line 399 "d2_parser.yy" // lalr1.cc:859 { ElementPtr name(new StringElement(yystack_[0].value.as< std::string > (), ctx.loc2pos(yystack_[0].location))); ctx.stack_.back()->set("name", name); ctx.leave(); } -#line 1031 "d2_parser.cc" // lalr1.cc:859 +#line 1089 "d2_parser.cc" // lalr1.cc:859 break; - case 84: -#line 371 "d2_parser.yy" // lalr1.cc:859 + case 93: +#line 405 "d2_parser.yy" // lalr1.cc:859 { ElementPtr dl(new IntElement(yystack_[0].value.as< int64_t > (), ctx.loc2pos(yystack_[0].location))); ctx.stack_.back()->set("debuglevel", dl); } -#line 1040 "d2_parser.cc" // lalr1.cc:859 +#line 1098 "d2_parser.cc" // lalr1.cc:859 break; - case 85: -#line 375 "d2_parser.yy" // lalr1.cc:859 + case 94: +#line 409 "d2_parser.yy" // lalr1.cc:859 { ctx.enter(ctx.NO_KEYWORD); } -#line 1048 "d2_parser.cc" // lalr1.cc:859 +#line 1106 "d2_parser.cc" // lalr1.cc:859 break; - case 86: -#line 377 "d2_parser.yy" // lalr1.cc:859 + case 95: +#line 411 "d2_parser.yy" // lalr1.cc:859 { ElementPtr sev(new StringElement(yystack_[0].value.as< std::string > (), ctx.loc2pos(yystack_[0].location))); ctx.stack_.back()->set("severity", sev); ctx.leave(); } -#line 1058 "d2_parser.cc" // lalr1.cc:859 +#line 1116 "d2_parser.cc" // lalr1.cc:859 break; - case 87: -#line 383 "d2_parser.yy" // lalr1.cc:859 + case 96: +#line 417 "d2_parser.yy" // lalr1.cc:859 { ElementPtr l(new ListElement(ctx.loc2pos(yystack_[0].location))); ctx.stack_.back()->set("output_options", l); ctx.stack_.push_back(l); ctx.enter(ctx.OUTPUT_OPTIONS); } -#line 1069 "d2_parser.cc" // lalr1.cc:859 +#line 1127 "d2_parser.cc" // lalr1.cc:859 break; - case 88: -#line 388 "d2_parser.yy" // lalr1.cc:859 + case 97: +#line 422 "d2_parser.yy" // lalr1.cc:859 { ctx.stack_.pop_back(); ctx.leave(); } -#line 1078 "d2_parser.cc" // lalr1.cc:859 +#line 1136 "d2_parser.cc" // lalr1.cc:859 break; - case 91: -#line 397 "d2_parser.yy" // lalr1.cc:859 + case 100: +#line 431 "d2_parser.yy" // lalr1.cc:859 { ElementPtr m(new MapElement(ctx.loc2pos(yystack_[0].location))); ctx.stack_.back()->add(m); ctx.stack_.push_back(m); } -#line 1088 "d2_parser.cc" // lalr1.cc:859 +#line 1146 "d2_parser.cc" // lalr1.cc:859 break; - case 92: -#line 401 "d2_parser.yy" // lalr1.cc:859 + case 101: +#line 435 "d2_parser.yy" // lalr1.cc:859 { ctx.stack_.pop_back(); } -#line 1096 "d2_parser.cc" // lalr1.cc:859 +#line 1154 "d2_parser.cc" // lalr1.cc:859 break; - case 95: -#line 409 "d2_parser.yy" // lalr1.cc:859 + case 104: +#line 443 "d2_parser.yy" // lalr1.cc:859 { ctx.enter(ctx.NO_KEYWORD); } -#line 1104 "d2_parser.cc" // lalr1.cc:859 +#line 1162 "d2_parser.cc" // lalr1.cc:859 break; - case 96: -#line 411 "d2_parser.yy" // lalr1.cc:859 + case 105: +#line 445 "d2_parser.yy" // lalr1.cc:859 { ElementPtr sev(new StringElement(yystack_[0].value.as< std::string > (), ctx.loc2pos(yystack_[0].location))); ctx.stack_.back()->set("output", sev); ctx.leave(); } -#line 1114 "d2_parser.cc" // lalr1.cc:859 +#line 1172 "d2_parser.cc" // lalr1.cc:859 break; -#line 1118 "d2_parser.cc" // lalr1.cc:859 +#line 1176 "d2_parser.cc" // lalr1.cc:859 default: break; } @@ -1369,30 +1427,31 @@ namespace isc { namespace dhcp { } - const signed char D2Parser::yypact_ninf_ = -57; + const signed char D2Parser::yypact_ninf_ = -62; const signed char D2Parser::yytable_ninf_ = -1; const signed char D2Parser::yypact_[] = { - 22, -57, -57, -57, 5, -3, 41, 46, -57, -57, - -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, - -57, -57, -57, -57, -3, -4, 1, 2, -57, 30, - 51, 52, 47, 54, -57, -57, -57, -57, 56, -57, - 0, -57, -57, -57, -57, -57, -57, 57, 58, -57, - -57, -57, 6, -57, -57, -57, -57, -57, -57, -57, - -3, -3, -57, 33, 59, 61, 62, 63, -57, 1, - -57, 64, 38, 39, 68, 69, 2, -57, -57, -57, - 70, -3, -3, 71, 72, -57, 44, -57, -57, 29, - 60, -57, -3, -57, -57, 2, 55, -57, -57, -57, - -57, -57, -57, 16, -57, 17, -57, -57, -57, 77, - 55, -57, 78, -57, 75, -57, 4, -57, 18, 75, - -57, -57, -57, 80, -57, -57, 31, -57, -57, -57, - -57, -57, -57, 81, 82, 65, 83, 18, -57, 45, - 84, -57, 67, -57, -57, 86, -57, -57, 20, -57, - 66, 86, -57, -57, 32, -57, -57, 90, 66, -57, - 73, -57, -57 + 25, -62, -62, -62, 7, -3, 16, 22, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -3, -4, 1, 5, -62, 30, + 45, 50, 51, 57, -62, -62, -62, -62, 58, -62, + 0, -62, -62, -62, -62, -62, -62, 59, 60, -62, + -62, -62, -62, -62, -62, 2, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -3, -3, -62, 27, + 61, 62, 65, 66, -62, 1, -62, 67, 37, 38, + 70, 71, 72, 76, 78, 5, -62, -62, -62, 79, + -3, -3, 77, 80, -62, 52, -62, -62, -2, 68, + -3, -3, -3, -62, -3, -62, -62, 5, 64, -62, + -62, -62, -62, -62, -62, -62, -62, -62, 6, -62, + 14, -62, -62, -62, 81, 64, -62, 85, -62, 84, + -62, 47, -62, 11, 84, -62, -62, -62, 88, -62, + -62, 39, -62, -62, -62, -62, -62, -62, 89, 90, + 63, 91, 11, -62, 69, 92, -62, 74, -62, -62, + 93, -62, -62, 49, -62, 73, 93, -62, -62, 43, + -62, -62, 95, 73, -62, 75, -62, -62 }; const unsigned char @@ -1401,115 +1460,120 @@ namespace isc { namespace dhcp { 0, 2, 4, 6, 0, 0, 0, 0, 1, 22, 16, 12, 11, 8, 9, 10, 15, 3, 13, 14, 29, 5, 40, 7, 24, 18, 0, 0, 26, 0, - 25, 0, 0, 19, 60, 62, 38, 64, 0, 37, - 0, 31, 36, 33, 35, 34, 50, 0, 0, 54, - 58, 49, 0, 42, 44, 45, 46, 47, 48, 23, - 0, 0, 17, 0, 0, 0, 0, 0, 28, 0, - 30, 0, 0, 0, 0, 0, 0, 41, 27, 20, - 0, 0, 0, 0, 0, 32, 0, 52, 53, 0, - 0, 43, 0, 61, 63, 0, 0, 51, 56, 57, - 55, 59, 21, 0, 69, 0, 66, 68, 39, 0, - 0, 65, 0, 67, 0, 73, 0, 71, 0, 0, - 70, 82, 87, 0, 85, 81, 0, 75, 77, 79, - 80, 78, 72, 0, 0, 0, 0, 0, 74, 0, - 0, 84, 0, 76, 83, 0, 86, 91, 0, 89, - 0, 0, 88, 95, 0, 93, 90, 0, 0, 92, - 0, 94, 96 + 25, 0, 0, 19, 69, 71, 38, 73, 0, 37, + 0, 31, 36, 33, 35, 34, 53, 0, 0, 57, + 61, 63, 65, 67, 52, 0, 42, 44, 45, 46, + 47, 48, 49, 50, 51, 23, 0, 0, 17, 0, + 0, 0, 0, 0, 28, 0, 30, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 27, 20, 0, + 0, 0, 0, 0, 32, 0, 55, 56, 0, 0, + 0, 0, 0, 43, 0, 70, 72, 0, 0, 54, + 59, 60, 58, 62, 64, 66, 68, 21, 0, 78, + 0, 75, 77, 39, 0, 0, 74, 0, 76, 0, + 82, 0, 80, 0, 0, 79, 91, 96, 0, 94, + 90, 0, 84, 86, 88, 89, 87, 81, 0, 0, + 0, 0, 0, 83, 0, 0, 93, 0, 85, 92, + 0, 95, 100, 0, 98, 0, 0, 97, 104, 0, + 102, 99, 0, 0, 101, 0, 103, 105 }; const signed char D2Parser::yypgoto_[] = { - -57, -57, -57, -57, -57, -23, -57, -57, -57, -57, - -57, -57, -57, -57, -57, -26, -57, -57, -57, 19, - -57, -57, -57, -57, -5, 23, -57, -57, -57, -57, - -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, - -57, -57, -15, -57, -57, -57, -19, -57, -57, -41, - -57, -57, -57, -57, -57, -57, -57, -57, -50, -57, - -57, -56, -57 + -62, -62, -62, -62, -62, -23, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -26, -62, -62, -62, 21, + -62, -62, -62, -62, -5, 19, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -20, -62, + -62, -62, -28, -62, -62, -42, -62, -62, -62, -62, + -62, -62, -62, -62, -55, -62, -62, -61, -62 }; const short int D2Parser::yydefgoto_[] = { -1, 4, 5, 6, 7, 16, 17, 18, 25, 32, - 33, 19, 24, 29, 30, 51, 21, 26, 40, 41, - 42, 66, 23, 27, 52, 53, 54, 71, 55, 56, - 57, 74, 100, 58, 75, 43, 64, 44, 65, 45, - 67, 105, 106, 107, 109, 116, 117, 118, 126, 127, - 128, 133, 129, 130, 136, 131, 134, 148, 149, 150, - 154, 155, 157 + 33, 19, 24, 29, 30, 54, 21, 26, 40, 41, + 42, 72, 23, 27, 55, 56, 57, 77, 58, 59, + 60, 80, 112, 61, 81, 62, 82, 63, 83, 64, + 84, 43, 70, 44, 71, 45, 73, 120, 121, 122, + 124, 131, 132, 133, 141, 142, 143, 148, 144, 145, + 151, 146, 149, 163, 164, 165, 169, 170, 172 }; const unsigned char D2Parser::yytable_[] = { - 39, 28, 9, 69, 10, 8, 11, 119, 70, 76, - 120, 34, 35, 36, 77, 46, 47, 48, 49, 76, - 110, 50, 37, 151, 108, 111, 152, 31, 12, 13, - 14, 15, 38, 38, 137, 158, 59, 78, 79, 138, - 159, 121, 122, 39, 123, 124, 98, 99, 20, 38, - 1, 2, 3, 22, 60, 62, 61, 63, 93, 94, - 68, 72, 73, 81, 80, 82, 83, 84, 86, 102, - 87, 88, 89, 90, 92, 97, 144, 104, 95, 96, - 101, 112, 115, 114, 135, 139, 140, 142, 85, 145, - 103, 153, 125, 147, 160, 113, 143, 141, 146, 91, - 132, 156, 161, 0, 162, 0, 0, 0, 0, 0, - 0, 125 + 39, 28, 9, 75, 10, 85, 11, 8, 76, 85, + 86, 34, 35, 36, 123, 110, 111, 125, 46, 47, + 48, 49, 126, 20, 50, 37, 51, 52, 53, 22, + 31, 12, 13, 14, 15, 38, 65, 136, 137, 38, + 138, 139, 152, 87, 88, 38, 173, 153, 66, 39, + 134, 174, 166, 135, 67, 167, 1, 2, 3, 68, + 69, 89, 74, 78, 79, 90, 91, 105, 106, 92, + 93, 95, 96, 97, 98, 99, 100, 114, 115, 116, + 101, 117, 102, 104, 107, 127, 109, 108, 113, 119, + 129, 130, 150, 154, 155, 157, 94, 160, 156, 175, + 162, 168, 118, 159, 103, 128, 147, 140, 161, 177, + 158, 171, 176, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 140 }; const short int D2Parser::yycheck_[] = { - 26, 24, 5, 3, 7, 0, 9, 3, 8, 3, - 6, 10, 11, 12, 8, 13, 14, 15, 16, 3, - 3, 19, 21, 3, 8, 8, 6, 31, 31, 32, - 33, 34, 31, 31, 3, 3, 6, 60, 61, 8, - 8, 23, 24, 69, 26, 27, 17, 18, 7, 31, - 28, 29, 30, 7, 3, 8, 4, 3, 81, 82, - 4, 4, 4, 4, 31, 4, 4, 4, 4, 92, - 32, 32, 4, 4, 4, 31, 31, 22, 7, 7, - 20, 4, 7, 5, 4, 4, 4, 4, 69, 5, - 95, 25, 118, 7, 4, 110, 137, 32, 31, 76, - 119, 151, 158, -1, 31, -1, -1, -1, -1, -1, - -1, 137 + 26, 24, 5, 3, 7, 3, 9, 0, 8, 3, + 8, 10, 11, 12, 8, 17, 18, 3, 13, 14, + 15, 16, 8, 7, 19, 24, 21, 22, 23, 7, + 34, 34, 35, 36, 37, 34, 6, 26, 27, 34, + 29, 30, 3, 66, 67, 34, 3, 8, 3, 75, + 3, 8, 3, 6, 4, 6, 31, 32, 33, 8, + 3, 34, 4, 4, 4, 4, 4, 90, 91, 4, + 4, 4, 35, 35, 4, 4, 4, 100, 101, 102, + 4, 104, 4, 4, 7, 4, 34, 7, 20, 25, + 5, 7, 4, 4, 4, 4, 75, 5, 35, 4, + 7, 28, 107, 34, 85, 125, 134, 133, 34, 34, + 152, 166, 173, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 152 }; const unsigned char D2Parser::yystos_[] = { - 0, 28, 29, 30, 36, 37, 38, 39, 0, 5, - 7, 9, 31, 32, 33, 34, 40, 41, 42, 46, - 7, 51, 7, 57, 47, 43, 52, 58, 40, 48, - 49, 31, 44, 45, 10, 11, 12, 21, 31, 50, - 53, 54, 55, 70, 72, 74, 13, 14, 15, 16, - 19, 50, 59, 60, 61, 63, 64, 65, 68, 6, - 3, 4, 8, 3, 71, 73, 56, 75, 4, 3, - 8, 62, 4, 4, 66, 69, 3, 8, 40, 40, - 31, 4, 4, 4, 4, 54, 4, 32, 32, 4, - 4, 60, 4, 40, 40, 7, 7, 31, 17, 18, - 67, 20, 40, 59, 22, 76, 77, 78, 8, 79, - 3, 8, 4, 77, 5, 7, 80, 81, 82, 3, - 6, 23, 24, 26, 27, 50, 83, 84, 85, 87, - 88, 90, 81, 86, 91, 4, 89, 3, 8, 4, - 4, 32, 4, 84, 31, 5, 31, 7, 92, 93, - 94, 3, 6, 25, 95, 96, 93, 97, 3, 8, - 4, 96, 31 + 0, 31, 32, 33, 39, 40, 41, 42, 0, 5, + 7, 9, 34, 35, 36, 37, 43, 44, 45, 49, + 7, 54, 7, 60, 50, 46, 55, 61, 43, 51, + 52, 34, 47, 48, 10, 11, 12, 24, 34, 53, + 56, 57, 58, 79, 81, 83, 13, 14, 15, 16, + 19, 21, 22, 23, 53, 62, 63, 64, 66, 67, + 68, 71, 73, 75, 77, 6, 3, 4, 8, 3, + 80, 82, 59, 84, 4, 3, 8, 65, 4, 4, + 69, 72, 74, 76, 78, 3, 8, 43, 43, 34, + 4, 4, 4, 4, 57, 4, 35, 35, 4, 4, + 4, 4, 4, 63, 4, 43, 43, 7, 7, 34, + 17, 18, 70, 20, 43, 43, 43, 43, 62, 25, + 85, 86, 87, 8, 88, 3, 8, 4, 86, 5, + 7, 89, 90, 91, 3, 6, 26, 27, 29, 30, + 53, 92, 93, 94, 96, 97, 99, 90, 95, 100, + 4, 98, 3, 8, 4, 4, 35, 4, 93, 34, + 5, 34, 7, 101, 102, 103, 3, 6, 28, 104, + 105, 102, 106, 3, 8, 4, 105, 34 }; const unsigned char D2Parser::yyr1_[] = { - 0, 35, 37, 36, 38, 36, 39, 36, 40, 40, - 40, 40, 40, 40, 40, 41, 43, 42, 44, 44, - 45, 45, 47, 46, 48, 48, 49, 49, 50, 52, - 51, 53, 53, 54, 54, 54, 54, 54, 56, 55, - 58, 57, 59, 59, 60, 60, 60, 60, 60, 60, - 62, 61, 63, 64, 66, 65, 67, 67, 69, 68, - 71, 70, 73, 72, 75, 74, 76, 76, 77, 79, - 78, 80, 80, 82, 81, 83, 83, 84, 84, 84, - 84, 84, 86, 85, 87, 89, 88, 91, 90, 92, - 92, 94, 93, 95, 95, 97, 96 + 0, 38, 40, 39, 41, 39, 42, 39, 43, 43, + 43, 43, 43, 43, 43, 44, 46, 45, 47, 47, + 48, 48, 50, 49, 51, 51, 52, 52, 53, 55, + 54, 56, 56, 57, 57, 57, 57, 57, 59, 58, + 61, 60, 62, 62, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 65, 64, 66, 67, 69, 68, 70, + 70, 72, 71, 74, 73, 76, 75, 78, 77, 80, + 79, 82, 81, 84, 83, 85, 85, 86, 88, 87, + 89, 89, 91, 90, 92, 92, 93, 93, 93, 93, + 93, 95, 94, 96, 98, 97, 100, 99, 101, 101, + 103, 102, 104, 104, 106, 105 }; const unsigned char @@ -1520,11 +1584,12 @@ namespace isc { namespace dhcp { 3, 5, 0, 4, 0, 1, 1, 3, 2, 0, 4, 1, 3, 1, 1, 1, 1, 1, 0, 6, 0, 4, 1, 3, 1, 1, 1, 1, 1, 1, - 0, 4, 3, 3, 0, 4, 1, 1, 0, 4, - 0, 4, 0, 4, 0, 6, 1, 3, 1, 0, - 6, 1, 3, 0, 4, 1, 3, 1, 1, 1, - 1, 1, 0, 4, 3, 0, 4, 0, 6, 1, - 3, 0, 4, 1, 3, 0, 4 + 1, 1, 1, 0, 4, 3, 3, 0, 4, 1, + 1, 0, 4, 0, 4, 0, 4, 0, 4, 0, + 4, 0, 4, 0, 6, 1, 3, 1, 0, 6, + 1, 3, 0, 4, 1, 3, 1, 1, 1, 1, + 1, 0, 4, 3, 0, 4, 0, 6, 1, 3, + 0, 4, 1, 3, 0, 4 }; @@ -1538,39 +1603,42 @@ namespace isc { namespace dhcp { "\"]\"", "\"{\"", "\"}\"", "\"null\"", "\"Dhcp6\"", "\"Dhcp4\"", "\"DhcpDdns\"", "\"ip-address\"", "\"port\"", "\"dns-server-timeout\"", "\"ncr-protocol\"", "\"UDP\"", "\"TCP\"", "\"ncr-format\"", "\"JSON\"", - "\"Logging\"", "\"loggers\"", "\"name\"", "\"output_options\"", - "\"output\"", "\"debuglevel\"", "\"severity\"", "TOPLEVEL_JSON", - "TOPLEVEL_DHCPDDNS", "SUB_DHCPDDNS", "\"constant string\"", - "\"integer\"", "\"floating point\"", "\"boolean\"", "$accept", "start", - "$@1", "$@2", "$@3", "value", "sub_json", "map2", "$@4", "map_content", + "\"forward-ddns\"", "\"reverse-ddns\"", "\"tsig-keys\"", "\"Logging\"", + "\"loggers\"", "\"name\"", "\"output_options\"", "\"output\"", + "\"debuglevel\"", "\"severity\"", "TOPLEVEL_JSON", "TOPLEVEL_DHCPDDNS", + "SUB_DHCPDDNS", "\"constant string\"", "\"integer\"", + "\"floating point\"", "\"boolean\"", "$accept", "start", "$@1", "$@2", + "$@3", "value", "sub_json", "map2", "$@4", "map_content", "not_empty_map", "list_generic", "$@5", "list_content", "not_empty_list", "unknown_map_entry", "syntax_map", "$@6", "global_objects", "global_object", "dhcpddns_object", "$@7", "sub_dhcpddns", "$@8", "dhcpddns_params", "dhcpddns_param", "ip_address", "$@9", "port", "dns_server_timeout", "ncr_protocol", "$@10", "ncr_protocol_value", - "ncr_format", "$@11", "dhcp6_json_object", "$@12", "dhcp4_json_object", - "$@13", "logging_object", "$@14", "logging_params", "logging_param", - "loggers", "$@15", "loggers_entries", "logger_entry", "$@16", - "logger_params", "logger_param", "name", "$@17", "debuglevel", - "severity", "$@18", "output_options_list", "$@19", - "output_options_list_content", "output_entry", "$@20", "output_params", - "output_param", "$@21", YY_NULLPTR + "ncr_format", "$@11", "forward_ddns", "$@12", "reverse_ddns", "$@13", + "tsig_keys", "$@14", "dhcp6_json_object", "$@15", "dhcp4_json_object", + "$@16", "logging_object", "$@17", "logging_params", "logging_param", + "loggers", "$@18", "loggers_entries", "logger_entry", "$@19", + "logger_params", "logger_param", "name", "$@20", "debuglevel", + "severity", "$@21", "output_options_list", "$@22", + "output_options_list_content", "output_entry", "$@23", "output_params", + "output_param", "$@24", YY_NULLPTR }; #if D2_PARSER_DEBUG const unsigned short int D2Parser::yyrline_[] = { - 0, 97, 97, 97, 98, 98, 99, 99, 107, 108, - 109, 110, 111, 112, 113, 116, 121, 121, 133, 134, - 137, 141, 148, 148, 163, 164, 167, 171, 182, 192, - 192, 204, 205, 209, 210, 211, 212, 213, 218, 218, - 228, 228, 236, 237, 240, 241, 242, 243, 244, 245, - 248, 248, 256, 261, 266, 266, 274, 275, 278, 278, - 286, 286, 293, 293, 305, 305, 318, 319, 323, 327, - 327, 339, 340, 344, 344, 352, 353, 356, 357, 358, - 359, 360, 363, 363, 371, 375, 375, 383, 383, 393, - 394, 397, 397, 405, 406, 409, 409 + 0, 100, 100, 100, 101, 101, 102, 102, 110, 111, + 112, 113, 114, 115, 116, 119, 124, 124, 136, 137, + 140, 144, 151, 151, 166, 167, 170, 174, 185, 195, + 195, 207, 208, 212, 213, 214, 215, 216, 221, 221, + 231, 231, 239, 240, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 254, 254, 262, 270, 279, 279, 287, + 288, 291, 291, 299, 299, 306, 306, 313, 313, 320, + 320, 327, 327, 339, 339, 352, 353, 357, 361, 361, + 373, 374, 378, 378, 386, 387, 390, 391, 392, 393, + 394, 397, 397, 405, 409, 409, 417, 417, 427, 428, + 431, 431, 439, 440, 443, 443 }; // Print the state stack on the debug stream. @@ -1604,13 +1672,13 @@ namespace isc { namespace dhcp { #line 14 "d2_parser.yy" // lalr1.cc:1167 -} } // isc::dhcp -#line 1609 "d2_parser.cc" // lalr1.cc:1167 -#line 417 "d2_parser.yy" // lalr1.cc:1168 +} } // isc::d2 +#line 1677 "d2_parser.cc" // lalr1.cc:1167 +#line 451 "d2_parser.yy" // lalr1.cc:1168 void -isc::dhcp::D2Parser::error(const location_type& loc, +isc::d2::D2Parser::error(const location_type& loc, const std::string& what) { ctx.error(loc, what); diff --git a/src/bin/d2/d2_parser.h b/src/bin/d2/d2_parser.h index 5648d8a3f4..dcac797a3c 100644 --- a/src/bin/d2/d2_parser.h +++ b/src/bin/d2/d2_parser.h @@ -32,7 +32,7 @@ /** ** \file d2_parser.h - ** Define the isc::dhcp::parser class. + ** Define the isc::d2::parser class. */ // C++ LALR(1) parser skeleton written by Akim Demaille. @@ -48,7 +48,7 @@ #include #include -using namespace isc::dhcp; +using namespace isc::d2; using namespace isc::data; using namespace std; @@ -136,7 +136,7 @@ using namespace std; #endif /* ! defined D2_PARSER_DEBUG */ #line 14 "d2_parser.yy" // lalr1.cc:392 -namespace isc { namespace dhcp { +namespace isc { namespace d2 { #line 141 "d2_parser.h" // lalr1.cc:392 @@ -360,20 +360,23 @@ namespace isc { namespace dhcp { TOKEN_TCP = 273, TOKEN_NCR_FORMAT = 274, TOKEN_JSON = 275, - TOKEN_LOGGING = 276, - TOKEN_LOGGERS = 277, - TOKEN_NAME = 278, - TOKEN_OUTPUT_OPTIONS = 279, - TOKEN_OUTPUT = 280, - TOKEN_DEBUGLEVEL = 281, - TOKEN_SEVERITY = 282, - TOKEN_TOPLEVEL_JSON = 283, - TOKEN_TOPLEVEL_DHCPDDNS = 284, - TOKEN_SUB_DHCPDDNS = 285, - TOKEN_STRING = 286, - TOKEN_INTEGER = 287, - TOKEN_FLOAT = 288, - TOKEN_BOOLEAN = 289 + TOKEN_FORWARD_DDNS = 276, + TOKEN_REVERSE_DDNS = 277, + TOKEN_TSIG_KEYS = 278, + TOKEN_LOGGING = 279, + TOKEN_LOGGERS = 280, + TOKEN_NAME = 281, + TOKEN_OUTPUT_OPTIONS = 282, + TOKEN_OUTPUT = 283, + TOKEN_DEBUGLEVEL = 284, + TOKEN_SEVERITY = 285, + TOKEN_TOPLEVEL_JSON = 286, + TOKEN_TOPLEVEL_DHCPDDNS = 287, + TOKEN_SUB_DHCPDDNS = 288, + TOKEN_STRING = 289, + TOKEN_INTEGER = 290, + TOKEN_FLOAT = 291, + TOKEN_BOOLEAN = 292 }; }; @@ -564,6 +567,18 @@ namespace isc { namespace dhcp { symbol_type make_JSON (const location_type& l); + static inline + symbol_type + make_FORWARD_DDNS (const location_type& l); + + static inline + symbol_type + make_REVERSE_DDNS (const location_type& l); + + static inline + symbol_type + make_TSIG_KEYS (const location_type& l); + static inline symbol_type make_LOGGING (const location_type& l); @@ -622,7 +637,7 @@ namespace isc { namespace dhcp { /// Build a parser object. - D2Parser (isc::dhcp::D2ParserContext& ctx_yyarg); + D2Parser (isc::d2::D2ParserContext& ctx_yyarg); virtual ~D2Parser (); /// Parse. @@ -825,17 +840,17 @@ namespace isc { namespace dhcp { enum { yyeof_ = 0, - yylast_ = 111, ///< Last index in yytable_. - yynnts_ = 63, ///< Number of nonterminal symbols. + yylast_ = 126, ///< Last index in yytable_. + yynnts_ = 69, ///< Number of nonterminal symbols. yyfinal_ = 8, ///< Termination state number. yyterror_ = 1, yyerrcode_ = 256, - yyntokens_ = 35 ///< Number of tokens. + yyntokens_ = 38 ///< Number of tokens. }; // User arguments. - isc::dhcp::D2ParserContext& ctx; + isc::d2::D2ParserContext& ctx; }; // Symbol number corresponding to token number t. @@ -875,9 +890,10 @@ namespace isc { namespace dhcp { 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34 + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37 }; - const unsigned int user_token_number_max_ = 289; + const unsigned int user_token_number_max_ = 292; const token_number_type undef_token_ = 2; if (static_cast(t) <= yyeof_) @@ -910,24 +926,24 @@ namespace isc { namespace dhcp { { switch (other.type_get ()) { - case 40: // value - case 67: // ncr_protocol_value + case 43: // value + case 70: // ncr_protocol_value value.copy< ElementPtr > (other.value); break; - case 34: // "boolean" + case 37: // "boolean" value.copy< bool > (other.value); break; - case 33: // "floating point" + case 36: // "floating point" value.copy< double > (other.value); break; - case 32: // "integer" + case 35: // "integer" value.copy< int64_t > (other.value); break; - case 31: // "constant string" + case 34: // "constant string" value.copy< std::string > (other.value); break; @@ -948,24 +964,24 @@ namespace isc { namespace dhcp { (void) v; switch (this->type_get ()) { - case 40: // value - case 67: // ncr_protocol_value + case 43: // value + case 70: // ncr_protocol_value value.copy< ElementPtr > (v); break; - case 34: // "boolean" + case 37: // "boolean" value.copy< bool > (v); break; - case 33: // "floating point" + case 36: // "floating point" value.copy< double > (v); break; - case 32: // "integer" + case 35: // "integer" value.copy< int64_t > (v); break; - case 31: // "constant string" + case 34: // "constant string" value.copy< std::string > (v); break; @@ -1045,24 +1061,24 @@ namespace isc { namespace dhcp { // Type destructor. switch (yytype) { - case 40: // value - case 67: // ncr_protocol_value + case 43: // value + case 70: // ncr_protocol_value value.template destroy< ElementPtr > (); break; - case 34: // "boolean" + case 37: // "boolean" value.template destroy< bool > (); break; - case 33: // "floating point" + case 36: // "floating point" value.template destroy< double > (); break; - case 32: // "integer" + case 35: // "integer" value.template destroy< int64_t > (); break; - case 31: // "constant string" + case 34: // "constant string" value.template destroy< std::string > (); break; @@ -1089,24 +1105,24 @@ namespace isc { namespace dhcp { super_type::move(s); switch (this->type_get ()) { - case 40: // value - case 67: // ncr_protocol_value + case 43: // value + case 70: // ncr_protocol_value value.move< ElementPtr > (s.value); break; - case 34: // "boolean" + case 37: // "boolean" value.move< bool > (s.value); break; - case 33: // "floating point" + case 36: // "floating point" value.move< double > (s.value); break; - case 32: // "integer" + case 35: // "integer" value.move< int64_t > (s.value); break; - case 31: // "constant string" + case 34: // "constant string" value.move< std::string > (s.value); break; @@ -1168,7 +1184,7 @@ namespace isc { namespace dhcp { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289 + 285, 286, 287, 288, 289, 290, 291, 292 }; return static_cast (yytoken_number_[type]); } @@ -1287,6 +1303,24 @@ namespace isc { namespace dhcp { return symbol_type (token::TOKEN_JSON, l); } + D2Parser::symbol_type + D2Parser::make_FORWARD_DDNS (const location_type& l) + { + return symbol_type (token::TOKEN_FORWARD_DDNS, l); + } + + D2Parser::symbol_type + D2Parser::make_REVERSE_DDNS (const location_type& l) + { + return symbol_type (token::TOKEN_REVERSE_DDNS, l); + } + + D2Parser::symbol_type + D2Parser::make_TSIG_KEYS (const location_type& l) + { + return symbol_type (token::TOKEN_TSIG_KEYS, l); + } + D2Parser::symbol_type D2Parser::make_LOGGING (const location_type& l) { @@ -1373,8 +1407,8 @@ namespace isc { namespace dhcp { #line 14 "d2_parser.yy" // lalr1.cc:392 -} } // isc::dhcp -#line 1378 "d2_parser.h" // lalr1.cc:392 +} } // isc::d2 +#line 1412 "d2_parser.h" // lalr1.cc:392 diff --git a/src/bin/d2/d2_parser.yy b/src/bin/d2/d2_parser.yy index 35e57fca72..7b6cce7cee 100644 --- a/src/bin/d2/d2_parser.yy +++ b/src/bin/d2/d2_parser.yy @@ -11,7 +11,7 @@ %define api.prefix {d2_parser_} %define api.token.constructor %define api.value.type variant -%define api.namespace {isc::dhcp} +%define api.namespace {isc::d2} %define parse.assert %code requires { @@ -21,12 +21,12 @@ #include #include -using namespace isc::dhcp; +using namespace isc::d2; using namespace isc::data; using namespace std; } // The parsing context. -%param { isc::dhcp::D2ParserContext& ctx } +%param { isc::d2::D2ParserContext& ctx } %locations %define parse.trace %define parse.error verbose @@ -38,7 +38,7 @@ using namespace std; %define api.token.prefix {TOKEN_} // Tokens in an order which makes sense and related to the intented use. -// Actual regexps for tokens are defined in dhcp6_lexer.ll. +// Actual regexps for tokens are defined in d2_lexer.ll. %token END 0 "end of file" COMMA "," @@ -61,6 +61,9 @@ using namespace std; TCP "TCP" NCR_FORMAT "ncr-format" JSON "JSON" + FORWARD_DDNS "forward-ddns" + REVERSE_DDNS "reverse-ddns" + TSIG_KEYS "tsig-keys" LOGGING "Logging" LOGGERS "loggers" @@ -242,6 +245,9 @@ dhcpddns_param: ip_address | dns_server_timeout | ncr_protocol | ncr_format + | forward_ddns + | reverse_ddns + | tsig_keys | unknown_map_entry ; @@ -254,13 +260,20 @@ ip_address: IP_ADDRESS { }; port: PORT COLON INTEGER { + if ($3 <= 0) { + error(@3, "port must be greater than zero"); + } ElementPtr i(new IntElement($3, ctx.loc2pos(@3))); ctx.stack_.back()->set("port", i); }; dns_server_timeout: DNS_SERVER_TIMEOUT COLON INTEGER { - ElementPtr i(new IntElement($3, ctx.loc2pos(@3))); - ctx.stack_.back()->set("dns-server-timeout", i); + if ($3 <= 0) { + error(@3, "dns-server-timeout must be greater than zero"); + } else { + ElementPtr i(new IntElement($3, ctx.loc2pos(@3))); + ctx.stack_.back()->set("dns-server-timeout", i); + } }; ncr_protocol: NCR_PROTOCOL { @@ -283,6 +296,27 @@ ncr_format: NCR_FORMAT { ctx.leave(); }; +forward_ddns : FORWARD_DDNS { + ctx.enter(ctx.NO_KEYWORD); +} COLON value { + ctx.stack_.back()->set("forward-ddns", $4); + ctx.leave(); +}; + +reverse_ddns : REVERSE_DDNS { + ctx.enter(ctx.NO_KEYWORD); +} COLON value { + ctx.stack_.back()->set("reverse-ddns", $4); + ctx.leave(); +}; + +tsig_keys : TSIG_KEYS { + ctx.enter(ctx.NO_KEYWORD); +} COLON value { + ctx.stack_.back()->set("tsig-keys", $4); + ctx.leave(); +}; + dhcp6_json_object: DHCP6 { ctx.enter(ctx.NO_KEYWORD); } COLON value { @@ -417,7 +451,7 @@ output_param: OUTPUT { %% void -isc::dhcp::D2Parser::error(const location_type& loc, +isc::d2::D2Parser::error(const location_type& loc, const std::string& what) { ctx.error(loc, what); diff --git a/src/bin/d2/d2_simple_parser.cc b/src/bin/d2/d2_simple_parser.cc index 0c12ec092b..74a85b4547 100644 --- a/src/bin/d2/d2_simple_parser.cc +++ b/src/bin/d2/d2_simple_parser.cc @@ -11,7 +11,7 @@ using namespace isc::data; namespace isc { -namespace dhcp { +namespace d2 { /// @brief This sets of arrays define the default values and /// values inherited (derived) between various scopes. /// @@ -36,8 +36,8 @@ const SimpleDefaults D2SimpleParser::D2_GLOBAL_DEFAULTS = { { "ip-address", Element::string, "127.0.0.1" }, { "port", Element::integer, "53001" }, { "dns-server-timeout", Element::integer, "100" }, - { "ncr-protocol", Element::integer, "UDP" }, - { "ncr-format", Element::integer, "JSON" } + { "ncr-protocol", Element::string, "UDP" }, + { "ncr-format", Element::string, "JSON" } }; /// @} diff --git a/src/bin/d2/d2_simple_parser.h b/src/bin/d2/d2_simple_parser.h index 260c72ea16..2f58d8eebe 100644 --- a/src/bin/d2/d2_simple_parser.h +++ b/src/bin/d2/d2_simple_parser.h @@ -10,7 +10,7 @@ #include namespace isc { -namespace dhcp { +namespace d2 { /// @brief SimpleParser specialized for D2 /// diff --git a/src/bin/d2/location.hh b/src/bin/d2/location.hh index 5f420fb91b..80826e9758 100644 --- a/src/bin/d2/location.hh +++ b/src/bin/d2/location.hh @@ -32,7 +32,7 @@ /** ** \file location.hh - ** Define the isc::dhcp::location class. + ** Define the isc::d2::location class. */ #ifndef YY_D2_PARSER_LOCATION_HH_INCLUDED @@ -41,7 +41,7 @@ # include "position.hh" #line 14 "d2_parser.yy" // location.cc:337 -namespace isc { namespace dhcp { +namespace isc { namespace d2 { #line 46 "location.hh" // location.cc:337 /// Abstract a location. class location @@ -187,6 +187,6 @@ namespace isc { namespace dhcp { } #line 14 "d2_parser.yy" // location.cc:337 -} } // isc::dhcp +} } // isc::d2 #line 192 "location.hh" // location.cc:337 #endif // !YY_D2_PARSER_LOCATION_HH_INCLUDED diff --git a/src/bin/d2/parser_context.cc b/src/bin/d2/parser_context.cc index f46786d44e..6ab6d61988 100644 --- a/src/bin/d2/parser_context.cc +++ b/src/bin/d2/parser_context.cc @@ -13,7 +13,7 @@ #include namespace isc { -namespace dhcp { +namespace d2 { D2ParserContext::D2ParserContext() : ctx_(NO_KEYWORD), trace_scanning_(false), trace_parsing_(false) @@ -43,7 +43,7 @@ D2ParserContext::parseFile(const std::string& filename, ParserType parser_type) isc::data::ElementPtr D2ParserContext::parseCommon() { - isc::dhcp::D2Parser parser(*this); + isc::d2::D2Parser parser(*this); // Uncomment this to get detailed parser logs. // trace_parsing_ = true; parser.set_debug_level(trace_parsing_); @@ -68,7 +68,7 @@ D2ParserContext::parseCommon() { void -D2ParserContext::error(const isc::dhcp::location& loc, const std::string& what) +D2ParserContext::error(const isc::d2::location& loc, const std::string& what) { isc_throw(D2ParseError, loc << ": " << what); } @@ -86,7 +86,7 @@ D2ParserContext::fatal (const std::string& what) } isc::data::Element::Position -D2ParserContext::loc2pos(isc::dhcp::location& loc) +D2ParserContext::loc2pos(isc::d2::location& loc) { const std::string& file = *loc.begin.filename; const uint32_t line = loc.begin.line; diff --git a/src/bin/d2/parser_context.h b/src/bin/d2/parser_context.h index 5848f7f9be..63bd55dda8 100644 --- a/src/bin/d2/parser_context.h +++ b/src/bin/d2/parser_context.h @@ -14,13 +14,13 @@ #include // Tell Flex the lexer's prototype ... -#define YY_DECL isc::dhcp::D2Parser::symbol_type d2_parser_lex (D2ParserContext& driver) +#define YY_DECL isc::d2::D2Parser::symbol_type d2_parser_lex (D2ParserContext& driver) // ... and declare it for the parser's sake. YY_DECL; namespace isc { -namespace dhcp { +namespace d2 { /// @brief Evaluation error exception raised when trying to parse. /// @@ -49,10 +49,10 @@ public: PARSER_JSON, ///< Used while parsing top level (contains DhcpDdns, Logging, others) - PARSER_CONFIG, + PARSER_DHCPDDNS, ///< Used while parsing content of DhcpDdns. - PARSER_DHCPDDNS + PARSER_SUB_DHCPDDNS } ParserType; /// @brief Default constructor. @@ -116,7 +116,7 @@ public: /// @param loc location within the parsed file when experienced a problem. /// @param what string explaining the nature of the error. /// @throw D2ParseError - void error(const isc::dhcp::location& loc, const std::string& what); + void error(const isc::d2::location& loc, const std::string& what); /// @brief Error handler /// @@ -143,7 +143,7 @@ public: /// /// @param loc location in bison format /// @return Position in format accepted by Element - isc::data::Element::Position loc2pos(isc::dhcp::location& loc); + isc::data::Element::Position loc2pos(isc::d2::location& loc); /// @brief Defines syntactic contexts for lexical tie-ins typedef enum { @@ -183,10 +183,10 @@ public: /// /// The lexer will keep updating it. This variable will be useful /// for logging errors. - isc::dhcp::location loc_; + isc::d2::location loc_; /// @brief Location stack - std::vector locs_; + std::vector locs_; /// @brief Lexer state stack std::vector states_; diff --git a/src/bin/d2/parser_context_decl.h b/src/bin/d2/parser_context_decl.h index 474a66bc2b..a927ac1b4b 100644 --- a/src/bin/d2/parser_context_decl.h +++ b/src/bin/d2/parser_context_decl.h @@ -10,7 +10,7 @@ /// @file d2/parser_context_decl.h Forward declaration of the ParserContext class namespace isc { -namespace dhcp { +namespace d2 { class D2ParserContext; diff --git a/src/bin/d2/position.hh b/src/bin/d2/position.hh index 6d0316bbbd..41f8acd1b9 100644 --- a/src/bin/d2/position.hh +++ b/src/bin/d2/position.hh @@ -32,7 +32,7 @@ /** ** \file position.hh - ** Define the isc::dhcp::position class. + ** Define the isc::d2::position class. */ #ifndef YY_D2_PARSER_POSITION_HH_INCLUDED @@ -51,7 +51,7 @@ # endif #line 14 "d2_parser.yy" // location.cc:337 -namespace isc { namespace dhcp { +namespace isc { namespace d2 { #line 56 "position.hh" // location.cc:337 /// Abstract a position. class position @@ -175,6 +175,6 @@ namespace isc { namespace dhcp { } #line 14 "d2_parser.yy" // location.cc:337 -} } // isc::dhcp +} } // isc::d2 #line 180 "position.hh" // location.cc:337 #endif // !YY_D2_PARSER_POSITION_HH_INCLUDED diff --git a/src/bin/d2/stack.hh b/src/bin/d2/stack.hh index 0f0887c982..92c74d309e 100644 --- a/src/bin/d2/stack.hh +++ b/src/bin/d2/stack.hh @@ -32,7 +32,7 @@ /** ** \file stack.hh - ** Define the isc::dhcp::stack class. + ** Define the isc::d2::stack class. */ #ifndef YY_D2_PARSER_STACK_HH_INCLUDED @@ -41,7 +41,7 @@ # include #line 14 "d2_parser.yy" // stack.hh:151 -namespace isc { namespace dhcp { +namespace isc { namespace d2 { #line 46 "stack.hh" // stack.hh:151 template > class stack @@ -151,7 +151,7 @@ namespace isc { namespace dhcp { }; #line 14 "d2_parser.yy" // stack.hh:151 -} } // isc::dhcp +} } // isc::d2 #line 156 "stack.hh" // stack.hh:151 #endif // !YY_D2_PARSER_STACK_HH_INCLUDED diff --git a/src/bin/d2/tests/Makefile.am b/src/bin/d2/tests/Makefile.am index a28ed6e863..14b8ea06f0 100644 --- a/src/bin/d2/tests/Makefile.am +++ b/src/bin/d2/tests/Makefile.am @@ -23,6 +23,7 @@ AM_CPPFLAGS += -I$(top_srcdir)/src/bin AM_CPPFLAGS += $(BOOST_INCLUDES) AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/bin/d2/tests\" AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\" +AM_CPPFLAGS += -DCFG_EXAMPLES=\"$(abs_top_srcdir)/doc/examples/ddns\" CLEANFILES = $(builddir)/interfaces.txt $(builddir)/logger_lockfile @@ -55,6 +56,8 @@ d2_unittests_SOURCES += nc_remove_unittests.cc d2_unittests_SOURCES += nc_test_utils.cc nc_test_utils.h d2_unittests_SOURCES += nc_trans_unittests.cc d2_unittests_SOURCES += d2_controller_unittests.cc +d2_unittests_SOURCES += d2_simple_parser_unittest.cc +d2_unittests_SOURCES += parser_unittest.cc parser_unittest.h d2_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) d2_unittests_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS) @@ -76,6 +79,7 @@ d2_unittests_LDADD += $(top_builddir)/src/lib/process/libkea-process.la d2_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la d2_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/testutils/libdhcpsrvtest.la d2_unittests_LDADD += $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la +d2_unittests_LDADD += $(top_builddir)/src/lib/testutils/libkea-testutils.la d2_unittests_LDADD += $(top_builddir)/src/lib/asiodns/libkea-asiodns.la d2_unittests_LDADD += $(top_builddir)/src/lib/stats/libkea-stats.la d2_unittests_LDADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la diff --git a/src/bin/d2/tests/d2_cfg_mgr_unittests.cc b/src/bin/d2/tests/d2_cfg_mgr_unittests.cc index 3f56dd578a..3aece23cc8 100644 --- a/src/bin/d2/tests/d2_cfg_mgr_unittests.cc +++ b/src/bin/d2/tests/d2_cfg_mgr_unittests.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2016 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2013-2017 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 @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -172,7 +173,8 @@ public: return; } - FAIL() << "Parsing failed as expected but lacks position : " << *comment; + FAIL() << "Parsing failed as expected but lacks position : " << *comment + << ", filename:" << file_name; } /// @brief Pointer the D2Params most recently parsed. @@ -433,7 +435,7 @@ TEST_F(D2CfgMgrTest, defaultValues) { EXPECT_EQ(D2Params::DFT_DNS_SERVER_TIMEOUT, d2_params_->getDnsServerTimeout()); - // Check that protocol timeout gets you its default + // Check that omitting protocol gets you its default config = "{" " \"ip-address\": \"192.0.0.1\" , " @@ -449,7 +451,7 @@ TEST_F(D2CfgMgrTest, defaultValues) { EXPECT_EQ(dhcp_ddns::stringToNcrProtocol(D2Params::DFT_NCR_PROTOCOL), d2_params_->getNcrProtocol()); - // Check that format timeout gets you its default + // Check that omitting format gets you its default config = "{" " \"ip-address\": \"192.0.0.1\" , " @@ -1641,6 +1643,12 @@ TEST_F(D2CfgMgrTest, matchReverse) { } /// @brief Tests D2 config parsing against a wide range of config permutations. +/// +/// It tests for both syntax errors that the JSON parsing (D2ParserContext) +/// should detect as well as post-JSON parsing logic errors generated by +/// the Element parsers (i.e...SimpleParser/DhcpParser derivations) +/// +/// /// It iterates over all of the test configurations described in given file. /// The file content is JSON specialized to this test. The format of the file /// is: @@ -1656,12 +1664,15 @@ TEST_F(D2CfgMgrTest, matchReverse) { /// /// # Each test has: /// # 1. description - optional text description -/// # 2. should-fail - bool indicator if parsing is expected to file +/// # 2. syntax-error - text of syntax error D2Parser is expected to emit +/// # (defaults to blank = no error expected) +/// # 3. logic-error - indicator if post-parsing element logic should fail /// # (defaults to false) -/// # 3. data - configuration text to parse +/// # 4. data - configuration text to parse /// # /// "description" : "", -/// "should_fail" : , +/// "syntax-error" : ""|"" , +/// "logic_error" : , /// "data" : /// { /// # configuration elements here @@ -1695,14 +1706,18 @@ TEST_F(D2CfgMgrTest, configPermutations) { } // Read in each test For each test, read: + // // 1. description - optional text description - // 2. should-fail - bool indicator if parsing is expected to file (defaults - // to false - // 3. data - configuration text to parse + // 2. syntax-error - error text JSON parser should emit including position, + // defaults to blank (i.e. no error) + // 3. logic-error - bool indicator if post-JSON element processing should + // fail + // (defaults to false) + // 4. data - configuration text to parse // // Next attempt to parse the configuration by passing it into // D2CfgMgr::parseConfig(). Then check the parsing outcome against the - // expected outcome as given by should-fail. + // expected outcome as given by logic-error. isc::data::ConstElementPtr test; ASSERT_TRUE(tests->get("test-list")); BOOST_FOREACH(test, tests->get("test-list")->listValue()) { @@ -1714,12 +1729,20 @@ TEST_F(D2CfgMgrTest, configPermutations) { elem->getValue(description); } - // Grab the outcome flag, should-fail, defaults to false if it's + // Grab the outcome flag, logic-error, defaults to false if it's // not specified. - bool should_fail = false; - elem = test->get("should-fail"); + bool logic_error = false; + elem = test->get("logic-error"); if (elem) { - elem->getValue(should_fail); + elem->getValue(logic_error); + } + + // If the JSON parsing is expected to detect an error, the test + // should have specified the error message text. + std::string expected_syntax_error = ""; + elem = test->get("syntax-error"); + if (elem) { + elem->getValue(expected_syntax_error); } // Grab the test's configuration data. @@ -1727,12 +1750,41 @@ TEST_F(D2CfgMgrTest, configPermutations) { ASSERT_TRUE(data) << "No data for test: " << " : " << test->getPosition(); - // Attempt to parse the configuration. We verify that we get the expected - // outcome, and if it was supposed to fail if the explanation contains - // position information. + // Submit the configuration text to the D2Parser. This is somewhat + // artifical as normally the JSON parsing is invoked by @c + // DController::configFromFile(). Doing it here, explicitly, allows us + // test both syntax and logic errors without the weight of a full + // server. Currently the assumption is that the test data is the + // content permitted within a DhcpDdns element only. + try { + // First we turn the test data back into JSON text + D2ParserContext context; + stringstream os; + data->toJSON(os); + // Parse the test data + data = context.parseString(os.str(), + D2ParserContext::PARSER_SUB_DHCPDDNS); + } catch (const std::exception& ex) { + if (expected_syntax_error.empty()) { + // We have an unexpected syntax error. + ADD_FAILURE() << description << ", " + << "Unexpected syntax error:" << ex.what(); + } else { + // We expected and got a syntax error, we need to make sure + // we got the right one. + EXPECT_EQ(expected_syntax_error, ex.what()) + << description << ", syntax error mismatch"; + + // Expected or not, skip logic testing on syntax errors. + continue; + } + } + + // Attempt to Element parse the configuration. We verify that we get the + // expected outcome, and if it was supposed to fail that the explanation + // contains position information. checkAnswerWithError(cfg_mgr_->parseConfig(data), - (should_fail ? SHOULD_FAIL : SHOULD_PASS), - test_file); + (logic_error ? SHOULD_FAIL : SHOULD_PASS)); } } diff --git a/src/bin/d2/tests/d2_simple_parser_unittest.cc b/src/bin/d2/tests/d2_simple_parser_unittest.cc new file mode 100644 index 0000000000..30369f1023 --- /dev/null +++ b/src/bin/d2/tests/d2_simple_parser_unittest.cc @@ -0,0 +1,109 @@ +// Copyright (C) 2017 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 +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include + +#include + +using namespace isc; +using namespace isc::data; +using namespace isc::d2; + +namespace { + +/// @brief Text fixture class for D2SimpleParser +class D2SimpleParserTest : public ::testing::Test { +public: + /// @brief Checks if specified element matches the given integer default + /// + /// @param element defaulted element to check + /// @param deflt SimpleDefault which supplied the default valaue + void checkIntegerValue(const ConstElementPtr& element, const SimpleDefault& deflt) { + ASSERT_TRUE(element); + + // Verify it is an integer. + ASSERT_EQ(Element::integer, element->getType()); + + // Turn default value string into an int. + int64_t default_value = 0; + ASSERT_NO_THROW(default_value = boost::lexical_cast(deflt.value_)); + + // Verify it has the expected value. + EXPECT_EQ(default_value, element->intValue()); + } + + /// @brief Checks if specified element matches the given boolean default + /// + /// @param element defaulted element to check + /// @param deflt SimpleDefault which supplied the default valaue + void checkBooleanValue(const ConstElementPtr& element, const SimpleDefault& deflt) { + ASSERT_TRUE(element); + + // Verify it is a bool. + ASSERT_EQ(Element::boolean, element->getType()); + + // Turn default value string into a bool. + bool default_value = false; + ASSERT_NO_THROW(boost::lexical_cast(deflt.value_)); + + // Verify it has the expected value. + EXPECT_EQ(default_value, element->boolValue()); + } + + /// @brief Checks if specified element matches the given string default + /// + /// @param element defaulted element to check + /// @param deflt SimpleDefault which supplied the default valaue + void checkStringValue(const ConstElementPtr& element, const SimpleDefault& deflt) { + ASSERT_TRUE(element); + + // Verify it's a string + ASSERT_EQ(Element::string, element->getType()); + + // Verify it has the expected value + EXPECT_EQ(deflt.value_, element->stringValue()); + } +}; + +// This test checks if global defaults are properly set for D2. +TEST_F(D2SimpleParserTest, globalD2Defaults) { + + ElementPtr empty = isc::d2::test::parseJSON("{ }"); + size_t num = 0; + + EXPECT_NO_THROW(num = D2SimpleParser::setAllDefaults(empty)); + + // We expect 5 parameters to be inserted. + EXPECT_EQ(num, 5); + + // Let's go over all parameters we have defaults for. + BOOST_FOREACH(SimpleDefault deflt, D2SimpleParser::D2_GLOBAL_DEFAULTS) { + ConstElementPtr x; + ASSERT_NO_THROW(x = empty->get(deflt.name_)); + + EXPECT_TRUE(x); + if (x) { + if (deflt.type_ == Element::integer) { + checkIntegerValue(x, deflt); + } else if (deflt.type_ == Element::boolean) { + checkBooleanValue(x, deflt); + } else if (deflt.type_ == Element::string) { + checkStringValue(x, deflt); + } else { + // add them if we need to. Like what do you if it's a map? + ADD_FAILURE() << "default type not supported:" << deflt.name_ + << " ,type: " << deflt.type_; + } + } + } +} + +}; + diff --git a/src/bin/d2/tests/parser_unittest.cc b/src/bin/d2/tests/parser_unittest.cc new file mode 100644 index 0000000000..14691715a5 --- /dev/null +++ b/src/bin/d2/tests/parser_unittest.cc @@ -0,0 +1,586 @@ +// Copyright (C) 2017 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 +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +#include +#include +#include +#include +#include + +using namespace isc::data; +using namespace std; + +namespace isc { +namespace d2 { +namespace test { + +/// @brief compares two JSON trees +/// +/// If differences are discovered, gtest failure is reported (using EXPECT_EQ) +/// +/// @param a first to be compared +/// @param b second to be compared +void compareJSON(ConstElementPtr a, ConstElementPtr b) { + ASSERT_TRUE(a); + ASSERT_TRUE(b); + EXPECT_EQ(a->str(), b->str()); +} + +/// @brief Tests if the input string can be parsed with specific parser +/// +/// The input text will be passed to bison parser of specified type. +/// Then the same input text is passed to legacy JSON parser and outputs +/// from both parsers are compared. The legacy comparison can be disabled, +/// if the feature tested is not supported by the old parser (e.g. +/// new comment styles) +/// +/// @param txt text to be compared +/// @param parser_type bison parser type to be instantiated +/// @param compare whether to compare the output with legacy JSON parser +void testParser(const std::string& txt, D2ParserContext::ParserType parser_type, + bool compare = true) { + ConstElementPtr test_json; + + ASSERT_NO_THROW({ + try { + D2ParserContext ctx; + test_json = ctx.parseString(txt, parser_type); + } catch (const std::exception &e) { + cout << "EXCEPTION: " << e.what() << endl; + throw; + } + + }); + + if (!compare) { + return; + } + + // Now compare if both representations are the same. + ElementPtr reference_json; + ASSERT_NO_THROW(reference_json = Element::fromJSON(txt, true)); + compareJSON(reference_json, test_json); +} + +// Generic JSON parsing tests +TEST(ParserTest, mapInMap) { + string txt = "{ \"xyzzy\": { \"foo\": 123, \"baz\": 456 } }"; + testParser(txt, D2ParserContext::PARSER_JSON); +} + +TEST(ParserTest, listInList) { + string txt = "[ [ \"Britain\", \"Wales\", \"Scotland\" ], " + "[ \"Pomorze\", \"Wielkopolska\", \"Tatry\"] ]"; + testParser(txt, D2ParserContext::PARSER_JSON); +} + +TEST(ParserTest, nestedMaps) { + string txt = "{ \"europe\": { \"UK\": { \"London\": { \"street\": \"221B Baker\" }}}}"; + testParser(txt, D2ParserContext::PARSER_JSON); +} + +TEST(ParserTest, nestedLists) { + string txt = "[ \"half\", [ \"quarter\", [ \"eighth\", [ \"sixteenth\" ]]]]"; + testParser(txt, D2ParserContext::PARSER_JSON); +} + +TEST(ParserTest, listsInMaps) { + string txt = "{ \"constellations\": { \"orion\": [ \"rigel\", \"betelguese\" ], " + "\"cygnus\": [ \"deneb\", \"albireo\"] } }"; + testParser(txt, D2ParserContext::PARSER_JSON); +} + +TEST(ParserTest, mapsInLists) { + string txt = "[ { \"body\": \"earth\", \"gravity\": 1.0 }," + " { \"body\": \"mars\", \"gravity\": 0.376 } ]"; + testParser(txt, D2ParserContext::PARSER_JSON); +} + +TEST(ParserTest, types) { + string txt = "{ \"string\": \"foo\"," + "\"integer\": 42," + "\"boolean\": true," + "\"map\": { \"foo\": \"bar\" }," + "\"list\": [ 1, 2, 3 ]," + "\"null\": null }"; + testParser(txt, D2ParserContext::PARSER_JSON); +} + +TEST(ParserTest, keywordJSON) { + string txt = "{ \"name\": \"user\"," + "\"type\": \"password\"," + "\"user\": \"name\"," + "\"password\": \"type\" }"; + testParser(txt, D2ParserContext::PARSER_JSON); +} + +// PARSER_DHCPDDNS parser tests +TEST(ParserTest, keywordDhcpDdns) { + string txt = + "{ \"DhcpDdns\" : \n" + "{ \n" + " \"ip-address\": \"192.168.77.1\", \n" + " \"port\": 777 , \n " + " \"ncr-protocol\": \"UDP\", \n" + "\"tsig-keys\": [], \n" + "\"forward-ddns\" : {}, \n" + "\"reverse-ddns\" : {} \n" + "} \n" + "} \n"; + testParser(txt, D2ParserContext::PARSER_DHCPDDNS); +} + +TEST(ParserTest, keywordDhcp6) { + string txt = "{ \"Dhcp6\": { \"interfaces-config\": {" + " \"interfaces\": [ \"type\", \"htype\" ] },\n" + "\"preferred-lifetime\": 3000,\n" + "\"rebind-timer\": 2000, \n" + "\"renew-timer\": 1000, \n" + "\"subnet6\": [ { " + " \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ]," + " \"subnet\": \"2001:db8:1::/48\", " + " \"interface\": \"test\" } ],\n" + "\"valid-lifetime\": 4000 } }"; + testParser(txt, D2ParserContext::PARSER_DHCPDDNS); +} + +TEST(ParserTest, keywordDhcp4) { + string txt = "{ \"Dhcp4\": { \"interfaces-config\": {" + " \"interfaces\": [ \"type\", \"htype\" ] },\n" + "\"rebind-timer\": 2000, \n" + "\"renew-timer\": 1000, \n" + "\"subnet4\": [ { " + " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ]," + " \"subnet\": \"192.0.2.0/24\", " + " \"interface\": \"test\" } ],\n" + "\"valid-lifetime\": 4000 } }"; + testParser(txt, D2ParserContext::PARSER_DHCPDDNS); +} + +TEST(ParserTest, Logging) { + string txt = "{ \"Logging\": { \n" + " \"loggers\": [ \n" + " { \n" + " \"name\": \"kea-dhcp6\", \n" + " \"output_options\": [ \n" + " { \n" + " \"output\": \"stdout\" \n" + " } \n" + " ], \n" + " \"debuglevel\": 0, \n" + " \"severity\": \"INFO\" \n" + " } \n" + " ] }\n" + "} \n"; + testParser(txt, D2ParserContext::PARSER_DHCPDDNS); +} + + +// Tests if bash (#) comments are supported. That's the only comment type that +// was supported by the old parser. +TEST(ParserTest, bashComments) { + string txt= "{ \"Dhcp6\": { \"interfaces-config\": {" + " \"interfaces\": [ \"*\" ]" + "},\n" + "\"preferred-lifetime\": 3000,\n" + "# this is a comment\n" + "\"rebind-timer\": 2000, \n" + "# lots of comments here\n" + "# and here\n" + "\"renew-timer\": 1000, \n" + "\"subnet6\": [ { " + " \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ]," + " \"subnet\": \"2001:db8:1::/48\", " + " \"interface\": \"eth0\"" + " } ]," + "\"valid-lifetime\": 4000 } }"; + testParser(txt, D2ParserContext::PARSER_DHCPDDNS); +} + +// Tests if C++ (//) comments can start anywhere, not just in the first line. +TEST(ParserTest, cppComments) { + string txt= "{ \"Dhcp6\": { \"interfaces-config\": {" + " \"interfaces\": [ \"*\" ]" + "},\n" + "\"preferred-lifetime\": 3000, // this is a comment \n" + "\"rebind-timer\": 2000, // everything after // is ignored\n" + "\"renew-timer\": 1000, // this will be ignored, too\n" + "\"subnet6\": [ { " + " \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ]," + " \"subnet\": \"2001:db8:1::/48\", " + " \"interface\": \"eth0\"" + " } ]," + "\"valid-lifetime\": 4000 } }"; + testParser(txt, D2ParserContext::PARSER_DHCPDDNS, false); +} + +// Tests if bash (#) comments can start anywhere, not just in the first line. +TEST(ParserTest, bashCommentsInline) { + string txt= "{ \"Dhcp6\": { \"interfaces-config\": {" + " \"interfaces\": [ \"*\" ]" + "},\n" + "\"preferred-lifetime\": 3000, # this is a comment \n" + "\"rebind-timer\": 2000, # everything after # is ignored\n" + "\"renew-timer\": 1000, # this will be ignored, too\n" + "\"subnet6\": [ { " + " \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ]," + " \"subnet\": \"2001:db8:1::/48\", " + " \"interface\": \"eth0\"" + " } ]," + "\"valid-lifetime\": 4000 } }"; + testParser(txt, D2ParserContext::PARSER_DHCPDDNS, false); +} + +// Tests if multi-line C style comments are handled correctly. +TEST(ParserTest, multilineComments) { + string txt= "{ \"Dhcp6\": { \"interfaces-config\": {" + " \"interfaces\": [ \"*\" ]" + "},\n" + "\"preferred-lifetime\": 3000, /* this is a C style comment\n" + "that\n can \n span \n multiple \n lines */ \n" + "\"rebind-timer\": 2000,\n" + "\"renew-timer\": 1000, \n" + "\"subnet6\": [ { " + " \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ]," + " \"subnet\": \"2001:db8:1::/48\", " + " \"interface\": \"eth0\"" + " } ]," + "\"valid-lifetime\": 4000 } }"; + testParser(txt, D2ParserContext::PARSER_DHCPDDNS, false); +} + +/// @brief Loads specified example config file +/// +/// This test loads specified example file twice: first, using the legacy +/// JSON file and then second time using bison parser. Two created Element +/// trees are then compared. The input is decommented before it is passed +/// to legacy parser (as legacy support for comments is very limited). +/// +/// @param fname name of the file to be loaded +void testFile(const std::string& fname) { + ElementPtr reference_json; + ConstElementPtr test_json; + + string decommented = dhcp::test::decommentJSONfile(fname); + EXPECT_NO_THROW(reference_json = Element::fromJSONFile(decommented, true)); + + // remove the temporary file + EXPECT_NO_THROW(::remove(decommented.c_str())); + + EXPECT_NO_THROW( + try { + D2ParserContext ctx; + test_json = ctx.parseFile(fname, D2ParserContext::PARSER_DHCPDDNS); + } catch (const std::exception &x) { + cout << "EXCEPTION: " << x.what() << endl; + throw; + }); + + ASSERT_TRUE(reference_json); + ASSERT_TRUE(test_json); + + compareJSON(reference_json, test_json); +} + +// This test loads all available existing files. Each config is loaded +// twice: first with the existing Element::fromJSONFile() and then +// the second time with D2Parser. Both JSON trees are then compared. +TEST(ParserTest, file) { + vector configs; + configs.push_back("sample1.json"); + configs.push_back("template.json"); + + for (int i = 0; i:1.1: syntax error, unexpected end of file"); + testError(" ", D2ParserContext::PARSER_JSON, + ":1.2: syntax error, unexpected end of file"); + testError("\n", D2ParserContext::PARSER_JSON, + ":2.1: syntax error, unexpected end of file"); + testError("\t", D2ParserContext::PARSER_JSON, + ":1.2: syntax error, unexpected end of file"); + testError("\r", D2ParserContext::PARSER_JSON, + ":1.2: syntax error, unexpected end of file"); + + // comments + testError("# nothing\n", + D2ParserContext::PARSER_JSON, + ":2.1: syntax error, unexpected end of file"); + testError(" #\n", + D2ParserContext::PARSER_JSON, + ":2.1: syntax error, unexpected end of file"); + testError("// nothing\n", + D2ParserContext::PARSER_JSON, + ":2.1: syntax error, unexpected end of file"); + testError("/* nothing */\n", + D2ParserContext::PARSER_JSON, + ":2.1: syntax error, unexpected end of file"); + testError("/* no\nthing */\n", + D2ParserContext::PARSER_JSON, + ":3.1: syntax error, unexpected end of file"); + testError("/* no\nthing */\n\n", + D2ParserContext::PARSER_JSON, + ":4.1: syntax error, unexpected end of file"); + testError("/* nothing\n", + D2ParserContext::PARSER_JSON, + "Comment not closed. (/* in line 1"); + testError("\n\n\n/* nothing\n", + D2ParserContext::PARSER_JSON, + "Comment not closed. (/* in line 4"); + testError("{ /* */*/ }\n", + D2ParserContext::PARSER_JSON, + ":1.3-8: Invalid character: *"); + testError("{ /* // *// }\n", + D2ParserContext::PARSER_JSON, + ":1.3-11: Invalid character: /"); + testError("{ /* // */// }\n", + D2ParserContext::PARSER_JSON, + ":2.1: syntax error, unexpected end of file, " + "expecting }"); + + // includes + testError("/n", + D2ParserContext::PARSER_JSON, + "Can't open include file /foo/bar"); + + // JSON keywords + testError("{ \"foo\": True }", + D2ParserContext::PARSER_JSON, + ":1.10-13: JSON true reserved keyword is lower case only"); + testError("{ \"foo\": False }", + D2ParserContext::PARSER_JSON, + ":1.10-14: JSON false reserved keyword is lower case only"); + testError("{ \"foo\": NULL }", + D2ParserContext::PARSER_JSON, + ":1.10-13: JSON null reserved keyword is lower case only"); + testError("{ \"foo\": Tru }", + D2ParserContext::PARSER_JSON, + ":1.10: Invalid character: T"); + testError("{ \"foo\": nul }", + D2ParserContext::PARSER_JSON, + ":1.10: Invalid character: n"); + + // numbers + testError("123", + D2ParserContext::PARSER_DHCPDDNS, + ":1.1-3: syntax error, unexpected integer, " + "expecting {"); + testError("-456", + D2ParserContext::PARSER_DHCPDDNS, + ":1.1-4: syntax error, unexpected integer, " + "expecting {"); + testError("-0001", + D2ParserContext::PARSER_DHCPDDNS, + ":1.1-5: syntax error, unexpected integer, " + "expecting {"); + testError("1234567890123456789012345678901234567890", + D2ParserContext::PARSER_JSON, + ":1.1-40: Failed to convert " + "1234567890123456789012345678901234567890" + " to an integer."); + testError("-3.14e+0", + D2ParserContext::PARSER_DHCPDDNS, + ":1.1-8: syntax error, unexpected floating point, " + "expecting {"); + testError("1e50000", + D2ParserContext::PARSER_JSON, + ":1.1-7: Failed to convert 1e50000 " + "to a floating point."); + + // strings + testError("\"aabb\"", + D2ParserContext::PARSER_DHCPDDNS, + ":1.1-6: syntax error, unexpected constant string, " + "expecting {"); + testError("{ \"aabb\"err", + D2ParserContext::PARSER_JSON, + ":1.9: Invalid character: e"); + testError("{ err\"aabb\"", + D2ParserContext::PARSER_JSON, + ":1.3: Invalid character: e"); + testError("\"a\n\tb\"", + D2ParserContext::PARSER_JSON, + ":1.1-6: Invalid control in \"a\n\tb\""); + testError("\"a\\n\\tb\"", + D2ParserContext::PARSER_DHCPDDNS, + ":1.1-8: syntax error, unexpected constant string, " + "expecting {"); + testError("\"a\\x01b\"", + D2ParserContext::PARSER_JSON, + ":1.1-8: Bad escape in \"a\\x01b\""); + testError("\"a\\u0162\"", + D2ParserContext::PARSER_JSON, + ":1.1-9: Unsupported unicode escape in \"a\\u0162\""); + testError("\"a\\u062z\"", + D2ParserContext::PARSER_JSON, + ":1.1-9: Bad escape in \"a\\u062z\""); + testError("\"abc\\\"", + D2ParserContext::PARSER_JSON, + ":1.1-6: Overflow escape in \"abc\\\""); + + // from data_unittest.c + testError("\\a", + D2ParserContext::PARSER_JSON, + ":1.1: Invalid character: \\"); + testError("\\", + D2ParserContext::PARSER_JSON, + ":1.1: Invalid character: \\"); + testError("\\\"\\\"", + D2ParserContext::PARSER_JSON, + ":1.1: Invalid character: \\"); + + // want a map + testError("[]\n", + D2ParserContext::PARSER_DHCPDDNS, + ":1.1: syntax error, unexpected [, " + "expecting {"); + testError("[]\n", + D2ParserContext::PARSER_DHCPDDNS, + ":1.1: syntax error, unexpected [, " + "expecting {"); + testError("{ 123 }\n", + D2ParserContext::PARSER_JSON, + ":1.3-5: syntax error, unexpected integer, " + "expecting }"); + testError("{ 123 }\n", + D2ParserContext::PARSER_DHCPDDNS, + ":1.3-5: syntax error, unexpected integer"); + testError("{ \"foo\" }\n", + D2ParserContext::PARSER_JSON, + ":1.9: syntax error, unexpected }, " + "expecting :"); + testError("{ \"foo\" }\n", + D2ParserContext::PARSER_DHCPDDNS, + ":1.9: syntax error, unexpected }, expecting :"); + testError("{ \"foo\":null }\n", + D2ParserContext::PARSER_DHCPDDNS, + ":1.3-7: got unexpected keyword " + "\"foo\" in toplevel map."); + testError("{ \"Dhcp6\" }\n", + D2ParserContext::PARSER_DHCPDDNS, + ":1.11: syntax error, unexpected }, " + "expecting :"); + testError("{ \"Dhcp4\":[]\n", + D2ParserContext::PARSER_DHCPDDNS, + ":2.1: syntax error, unexpected end of file, " + "expecting \",\" or }"); + testError("{}{}\n", + D2ParserContext::PARSER_JSON, + ":1.3: syntax error, unexpected {, " + "expecting end of file"); + + // bad commas + testError("{ , }\n", + D2ParserContext::PARSER_JSON, + ":1.3: syntax error, unexpected \",\", " + "expecting }"); + testError("{ , \"foo\":true }\n", + D2ParserContext::PARSER_JSON, + ":1.3: syntax error, unexpected \",\", " + "expecting }"); + testError("{ \"foo\":true, }\n", + D2ParserContext::PARSER_JSON, + ":1.15: syntax error, unexpected }, " + "expecting constant string"); + + // bad type + testError("{ \"DhcpDdns\":{\n" + " \"dns-server-timeout\":false }}\n", + D2ParserContext::PARSER_DHCPDDNS, + ":2.24-28: syntax error, unexpected boolean, " + "expecting integer"); + + // unknown keyword + testError("{ \"DhcpDdns\":{\n" + " \"totally-bogus\":600 }}\n", + D2ParserContext::PARSER_DHCPDDNS, + ":2.2-16: got unexpected keyword " + "\"totally-bogus\" in DhcpDdns 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 { + D2ParserContext ctx; + result = ctx.parseString(json, D2ParserContext::PARSER_JSON); + } catch (const std::exception &x) { + cout << "EXCEPTION: " << x.what() << endl; + throw; + }); + ASSERT_EQ(Element::string, result->getType()); + EXPECT_EQ(ins, result->stringValue()); + } +} + +// This test checks that all representations of a slash is recognized properly. +TEST(ParserTest, unicodeSlash) { + // check the 4 possible encodings of solidus '/' + ConstElementPtr result; + string json = "\"/\\/\\u002f\\u002F\""; + ASSERT_NO_THROW( + try { + D2ParserContext ctx; + result = ctx.parseString(json, D2ParserContext::PARSER_JSON); + } catch (const std::exception &x) { + cout << "EXCEPTION: " << x.what() << endl; + throw; + }); + ASSERT_EQ(Element::string, result->getType()); + EXPECT_EQ("////", result->stringValue()); +} + +}; +}; +}; diff --git a/src/bin/d2/tests/parser_unittest.h b/src/bin/d2/tests/parser_unittest.h new file mode 100644 index 0000000000..8db80ad173 --- /dev/null +++ b/src/bin/d2/tests/parser_unittest.h @@ -0,0 +1,37 @@ +// Copyright (C) 2017 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 +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef PARSER_UNITTEST_H +#define PARSER_UNITTEST_H + +#include +#include +#include +#include + +using namespace isc::data; +using namespace std; + +namespace isc { +namespace d2 { +namespace test { + +/// @brief Runs parser in JSON mode, useful for parser testing +/// +/// @param in string to be parsed +/// @return ElementPtr structure representing parsed JSON +inline isc::data::ElementPtr +parseJSON(const std::string& in) +{ + isc::d2::D2ParserContext ctx; + return (ctx.parseString(in, isc::d2::D2ParserContext::PARSER_JSON)); +} + +}; +}; +}; + +#endif // PARSER_UNITTEST_H diff --git a/src/bin/d2/tests/testdata/d2_cfg_tests.json b/src/bin/d2/tests/testdata/d2_cfg_tests.json index 1969396f45..7e3b5b03f6 100644 --- a/src/bin/d2/tests/testdata/d2_cfg_tests.json +++ b/src/bin/d2/tests/testdata/d2_cfg_tests.json @@ -9,13 +9,16 @@ # Each test entry consists of: # # description - text describing the test (optional) -# should-fail - indicates whether parsing is expected to fail, defaults to -# false +# syntax-error - syntax error the JSON parsing should emit for this test +# defaults to "" = no error +# logic-error - indicates whether a post-JSON parsing logic error should occur +# defaults to false # data {} - Configuration text to submit for parsing. # # The vast majority of the tests in this file are invalid and are expected -# to fail. There are some that should succeed and are used more or less -# as sanity checks. +# to fail either as a syntax error caught by the JSON parser or a logic error +# caught during element processing. There are some that should succeed and are +# used more or less as sanity checks. { "test-list" : [ #----- @@ -24,7 +27,7 @@ # as well as validating this as the smallest config which makes writing # permutations easier. "description" : "D2 smallest, valid config", -"should-fail" : false, +"logic-error" : false, "data" : { "forward-ddns" : {}, @@ -36,7 +39,7 @@ #----- ,{ "description" : "D2 missing forward-ddns map", -"should-fail" : true, +"logic-error" : true, "data" : { "reverse-ddns" : {}, @@ -47,7 +50,7 @@ #----- ,{ "description" : "D2 missing reverse-ddns map", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -59,7 +62,7 @@ #----- ,{ "description" : "D2 missing tsig-keys list", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -70,7 +73,7 @@ #----- ,{ "description" : "D2 unknown scalar", -"should-fail" : true, +"syntax-error" : ":1.3-16: got unexpected keyword \"bogus-scalar\" in DhcpDdns map.", "data" : { "bogus-scalar" : true, @@ -83,7 +86,7 @@ #----- ,{ "description" : "D2 unknown map", -"should-fail" : true, +"syntax-error" : ":1.3-13: got unexpected keyword \"bogus-map\" in DhcpDdns map.", "data" : { "bogus-map" : {}, @@ -96,7 +99,7 @@ #----- ,{ "description" : "D2 unknown list", -"should-fail" : true, +"syntax-error" : ":1.3-14: got unexpected keyword \"bogus-list\" in DhcpDdns map.", "data" : { "bogus-list" : [], @@ -135,7 +138,7 @@ #----- ,{ "description" : "D2Params.ip-address invalid value", -"should-fail" : true, +"logic-error" : true, "data" : { "ip-address" : "bogus", @@ -161,7 +164,7 @@ #----- ,{ "description" : "D2Params.port can't be 0", -"should-fail" : true, +"syntax-error" : ":1.33: port must be greater than zero", "data" : { "port" : 0, @@ -174,7 +177,7 @@ #----- ,{ "description" : "D2Params.port, non numeric", -"should-fail" : true, +"syntax-error" : ":1.33-39: syntax error, unexpected constant string, expecting integer", "data" : { "port" : "bogus", @@ -199,7 +202,7 @@ #----- ,{ "description" : "D2Params.dns-server-timeout can't be 0", -"should-fail" : true, +"syntax-error" : ":1.25: dns-server-timeout must be greater than zero", "data" : { "dns-server-timeout" : 0, @@ -212,7 +215,7 @@ #----- ,{ "description" : "D2Params.dns-server-timeout, non numeric", -"should-fail" : true, +"syntax-error" : ":1.25-31: syntax error, unexpected constant string, expecting integer", "data" : { "dns-server-timeout" : "bogus", @@ -238,7 +241,7 @@ #----- ,{ "description" : "D2Params.ncr-protocol, unsupported TCP", -"should-fail" : true, +"logic-error" : true, "data" : { "ncr-protocol" : "TCP", @@ -252,7 +255,7 @@ #----- ,{ "description" : "D2Params.ncr-protocol, invalid value", -"should-fail" : true, +"syntax-error" : ":1.41-47: syntax error, unexpected constant string, expecting UDP or TCP", "data" : { "ncr-protocol" : "bogus", @@ -279,7 +282,7 @@ #----- ,{ "description" : "D2Params.ncr-format, invalid value", -"should-fail" : true, +"syntax-error" : ":1.39-45: syntax error, unexpected constant string, expecting JSON", "data" : { "ncr-format" : "bogus", @@ -313,7 +316,7 @@ #----- ,{ "description" : "D2.tsig-keys, missing key name", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -331,7 +334,7 @@ #----- ,{ "description" : "D2.tsig-keys, blank key name", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -350,7 +353,7 @@ #----- ,{ "description" : "D2.tsig-keys, duplicate key name", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -418,7 +421,7 @@ #----- D2.tsig-keys, algorithm tests ,{ "description" : "D2.tsig-keys, missing algorithm", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -436,7 +439,7 @@ #----- ,{ "description" : "D2.tsig-keys, blank algorithm", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -455,7 +458,7 @@ #----- ,{ "description" : "D2.tsig-keys, invalid algorithm", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -523,7 +526,7 @@ #----- ,{ "description" : "D2.tsig-keys, invalid digest-bits", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -543,7 +546,7 @@ #----- ,{ "description" : "D2.tsig-keys, too small truncated HMAC-MD5", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -563,7 +566,7 @@ #----- ,{ "description" : "D2.tsig-keys, too small truncated HMAC-SHA1", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -583,7 +586,7 @@ #----- ,{ "description" : "D2.tsig-keys, too small truncated HMAC-SHA224", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -603,7 +606,7 @@ #----- ,{ "description" : "D2.tsig-keys, too small truncated HMAC-SHA256", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -623,7 +626,7 @@ #----- ,{ "description" : "D2.tsig-keys, too small truncated HMAC-SHA384", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -643,7 +646,7 @@ #----- ,{ "description" : "D2.tsig-keys, too small truncated HMAC-SHA512", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -663,7 +666,7 @@ #----- D2.tsig-keys, secret tests ,{ "description" : "D2.tsig-keys, missing secret", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -681,7 +684,7 @@ #----- ,{ "description" : "D2.tsig-keys, blank secret", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -700,7 +703,7 @@ #----- ,{ "description" : "D2.tsig-keys, invalid secret", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -733,7 +736,7 @@ #------ ,{ "description" : "D2.forward-ddns, unknown parameter", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : @@ -782,7 +785,7 @@ #------ ,{ "description" : "D2.forward-ddns, duplicate domain", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : @@ -817,7 +820,7 @@ #----- D2.forward-ddns.dhcp-ddns tests ,{ "description" : "D2.forward-ddns.dhcp-ddns, unknown parameter", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : @@ -837,7 +840,7 @@ #----- D2.forward-ddns.dhcp-ddns.name tests ,{ "description" : "D2.forward-ddns.dhcp-ddns, no name", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : @@ -856,7 +859,7 @@ #----- ,{ "description" : "D2.forward-ddns.dhcp-ddns, blank name", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : @@ -876,7 +879,7 @@ #------ "D2.forward-ddns.dhcp-ddns, key-name tests ,{ "description" : "D2.forward-ddns, no matching key name", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : @@ -910,7 +913,7 @@ #----- D2.forward-ddns.dhcp-ddns.dns-servers tests ,{ "description" : "D2.forward-ddns.dhcp-ddns.dns-servers, no servers", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : @@ -931,7 +934,7 @@ #----- D2.forward-ddns.dhcp-ddns.dns-servers tests ,{ "description" : "D2.forward-ddns.dhcp-ddns.dns-servers, unknown parameter", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : @@ -957,7 +960,7 @@ #----- ,{ "description" : "D2.forward-ddns.dhcp-ddns.dns-servers.hostname unsupported", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : @@ -1033,7 +1036,7 @@ #----- ,{ "description" : "D2.forward-ddns.dhcp-ddns.dns-servers.ip-address invalid address ", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : @@ -1086,7 +1089,7 @@ #----- ,{ "description" : "D2.forward-ddns.dhcp-ddns.dns-servers.port cannot be 0 ", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : @@ -1127,7 +1130,7 @@ #------ ,{ "description" : "D2.reverse-ddns, unknown parameter", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -1176,7 +1179,7 @@ #------ ,{ "description" : "D2.reverse-ddns, duplicate domain", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -1211,7 +1214,7 @@ #----- D2.reverse-ddns.dhcp-ddns tests ,{ "description" : "D2.reverse-ddns.dhcp-ddns, unknown parameter", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -1231,7 +1234,7 @@ #----- D2.reverse-ddns.dhcp-ddns.name tests ,{ "description" : "D2.reverse-ddns.dhcp-ddns, no name", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -1250,7 +1253,7 @@ #----- ,{ "description" : "D2.reverse-ddns.dhcp-ddns, blank name", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -1270,7 +1273,7 @@ #------ "D2.reverse-ddns.dhcp-ddns, key-name tests ,{ "description" : "D2.reverse-ddns, no matching key name", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -1304,7 +1307,7 @@ #----- D2.reverse-ddns.dhcp-ddns.dns-servers tests ,{ "description" : "D2.reverse-ddns.dhcp-ddns.dns-servers, no servers", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -1325,7 +1328,7 @@ #----- D2.reverse-ddns.dhcp-ddns.dns-servers tests ,{ "description" : "D2.reverse-ddns.dhcp-ddns.dns-servers, unknown parameter", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -1351,7 +1354,7 @@ #----- ,{ "description" : "D2.reverse-ddns.dhcp-ddns.dns-servers.hostname unsupported", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -1426,7 +1429,7 @@ #----- ,{ "description" : "D2.reverse-ddns.dhcp-ddns.dns-servers.ip-address invalid value", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, @@ -1479,7 +1482,7 @@ #----- ,{ "description" : "D2.reverse-ddns.dhcp-ddns.dns-servers.port cannot be 0 ", -"should-fail" : true, +"logic-error" : true, "data" : { "forward-ddns" : {}, diff --git a/src/lib/cc/data.h b/src/lib/cc/data.h index 13e75d7a8b..95feb6adee 100644 --- a/src/lib/cc/data.h +++ b/src/lib/cc/data.h @@ -186,7 +186,7 @@ public: if ((position_.file_ != "") || \ (position_.line_ != 0) || \ (position_.pos_ != 0)) { \ - msg_ += " in " + position_.str(); \ + msg_ += " in (" + position_.str() + ")"; \ } \ isc_throw(TypeError, msg_); \ } diff --git a/src/lib/cc/simple_parser.cc b/src/lib/cc/simple_parser.cc index 6c0d74a474..91c17245cb 100644 --- a/src/lib/cc/simple_parser.cc +++ b/src/lib/cc/simple_parser.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2017 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 @@ -101,8 +101,16 @@ size_t SimpleParser::setDefaults(isc::data::ElementPtr scope, break; } case Element::integer: { - int int_value = boost::lexical_cast(def_value.value_); - x.reset(new IntElement(int_value, pos)); + try { + int int_value = boost::lexical_cast(def_value.value_); + x.reset(new IntElement(int_value, pos)); + } + catch (const std::exception& ex) { + isc_throw(BadValue, "Internal error. Integer value expected for: " + << def_value.name_ << ", value is: " + << def_value.value_ ); + } + break; } case Element::boolean: {