Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sebastian Schrader
Kea
Commits
0beffc6e
Commit
0beffc6e
authored
Mar 05, 2017
by
Francis Dupont
Committed by
Tomek Mrugalski
Mar 07, 2017
Browse files
[fdunparse2] Rebased, still reservations to do
parent
c5ceebc6
Changes
91
Hide whitespace changes
Inline
Side-by-side
configure.ac
View file @
0beffc6e
...
...
@@ -167,12 +167,11 @@ for retry in "none" "--std=c++11" "--std=c++0x" "--std=c++1x" "fail"; do
feature="final method"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[],
[class Foo {
public:
virtual ~Foo() {};
virtual void bar() final;
};])],
};]
,[]
)],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
continue])
...
...
@@ -201,6 +200,31 @@ for retry in "none" "--std=c++11" "--std=c++0x" "--std=c++1x" "fail"; do
[AC_MSG_RESULT([no])
continue])
AC_MSG_CHECKING(static_assert support)
feature="static_assert"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[static_assert(1 + 1 == 2, "");],
[])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
continue])
AC_MSG_CHECKING(template alias)
feature="template alias"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[template<int i>
class I {
public: int get() { return i; };
};
using Zero = I<0>;],
[Zero Z;
return Z.get();])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
continue])
AC_MSG_CHECKING(lambda support)
feature="lambda"
AC_COMPILE_IFELSE(
...
...
@@ -213,6 +237,19 @@ for retry in "none" "--std=c++11" "--std=c++0x" "--std=c++1x" "fail"; do
continue])
done
# Check for std::is_base_of support
AC_MSG_CHECKING([for std::is_base_of])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[#include <type_traits>
class A {};
class B : A {};]
[static_assert(std::is_base_of<A, B>::value, "");])],
[AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_IS_BASE_OF], [1],
[Define to 1 if std::is_base_of is available])],
[AC_MSG_RESULT(no)])
dnl Determine if we are using GNU sed
GNU_SED=no
$SED --version 2> /dev/null | grep GNU > /dev/null 2>&1
...
...
@@ -1415,6 +1452,31 @@ if test $enable_gtest != "no"; then
CPPFLAGS=$CPPFLAGS_SAVED
fi
# Check for CreateUnifiedDiff from gtest >= 1.8.0
if test $enable_gtest != "no"; then
AC_MSG_CHECKING([for CreateUnifiedDiff in $GTEST_INCLUDES/gtest.h])
CPPFLAGS_SAVED=$CPPFLAGS
CPPFLAGS="$CPPFLAGS $BOOST_INCLUDES $GTEST_INCLUDES"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[#include <boost/algorithm/string.hpp>
#include <gtest/gtest.h>
#include <string>
#include <vector>
std::string nodiff(std::string text) {
std::vector<std::string> lines;
boost::split(lines, text, boost::is_any_of("\n"));
using namespace testing::internal;
return (edit_distance::CreateUnifiedDiff(lines, lines));
}],
[return 0;])],
[AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_CREATE_UNIFIED_DIFF], [1],
[Define to 1 if gtest defines edit_distance::CreateUnifiedDiff])],
[AC_MSG_RESULT(no)])
CPPFLAGS=$CPPFLAGS_SAVED
fi
#
# ASIO: we extensively use it as the C++ event management module.
#
...
...
@@ -1467,11 +1529,11 @@ AC_ARG_ENABLE(generate_parser, [AC_HELP_STRING([--enable-generate-parser],
enable_generate_parser=$enableval, enable_generate_parser=no)
# Check if flex is avaible. Flex is not needed for building Kea sources,
# unless you want to regenerate grammar
in src/lib/eval
# unless you want to regenerate grammar
s
AC_PROG_LEX
# Check if bison is available. Bison is not needed for building Kea sources,
# unless you want to regenerate grammar
in src/lib/eval
# unless you want to regenerate grammar
s
AC_PROG_YACC
if test "x$enable_generate_parser" != "xno"; then
...
...
@@ -1485,7 +1547,7 @@ if test "x$enable_generate_parser" != "xno"; then
fi
# Ok, let's check if we have at least 3.0.0 version of the bison. The code used
# to generate
src/lib/eval
parser is roughly based on bison 3.0 examples.
# to generate parser
s
is roughly based on bison 3.0 examples.
cat > bisontest.y << EOF
%require "3.0.0"
%token X
...
...
@@ -1599,20 +1661,28 @@ AM_COND_IF([HAVE_OPTRESET], [AC_DEFINE([HAVE_OPTRESET], [1], [Check for optreset
AC_DEFINE([CONFIG_H_WAS_INCLUDED], [1], [config.h inclusion marker])
AC_CONFIG_FILES([compatcheck/Makefile
AC_CONFIG_FILES([Makefile
compatcheck/Makefile
dns++.pc
doc/
design/datasrc/
Makefile
doc/Makefile
doc/design/Makefile
doc/design/datasrc/Makefile
doc/guide/Makefile
doc/Makefile
doc/version.ent
ext/Makefile
ext/coroutine/Makefile
ext/gtest/Makefile
ext/Makefile
m4macros/Makefile
Makefile
src/Makefile
src/bin/Makefile
src/bin/admin/Makefile
src/bin/admin/kea-admin
src/bin/admin/tests/Makefile
src/bin/admin/tests/cql_tests.sh
src/bin/admin/tests/data/Makefile
src/bin/admin/tests/memfile_tests.sh
src/bin/admin/tests/mysql_tests.sh
src/bin/admin/tests/pgsql_tests.sh
src/bin/agent/Makefile
src/bin/agent/tests/Makefile
src/bin/agent/tests/ca_process_tests.sh
...
...
@@ -1644,15 +1714,6 @@ AC_CONFIG_FILES([compatcheck/Makefile
src/bin/perfdhcp/Makefile
src/bin/perfdhcp/tests/Makefile
src/bin/perfdhcp/tests/testdata/Makefile
src/bin/admin/Makefile
src/bin/admin/kea-admin
src/bin/admin/tests/Makefile
src/bin/admin/tests/data/Makefile
src/bin/admin/tests/memfile_tests.sh
src/bin/admin/tests/mysql_tests.sh
src/bin/admin/tests/pgsql_tests.sh
src/bin/admin/tests/cql_tests.sh
src/bin/agent/tests/test_libraries.h
src/hooks/Makefile
src/hooks/dhcp/Makefile
src/hooks/dhcp/user_chk/Makefile
...
...
@@ -1685,6 +1746,8 @@ AC_CONFIG_FILES([compatcheck/Makefile
src/lib/dns/gen-rdatacode.py
src/lib/dns/tests/Makefile
src/lib/dns/tests/testdata/Makefile
src/lib/eval/Makefile
src/lib/eval/tests/Makefile
src/lib/exceptions/Makefile
src/lib/exceptions/tests/Makefile
src/lib/hooks/Makefile
...
...
@@ -1710,10 +1773,10 @@ AC_CONFIG_FILES([compatcheck/Makefile
src/lib/process/spec_config.h.pre
src/lib/process/tests/Makefile
src/lib/process/testutils/Makefile
src/lib/testutils/Makefile
src/lib/testutils/dhcp_test_lib.sh
src/lib/stats/Makefile
src/lib/stats/tests/Makefile
src/lib/testutils/Makefile
src/lib/testutils/dhcp_test_lib.sh
src/lib/util/Makefile
src/lib/util/io/Makefile
src/lib/util/python/Makefile
...
...
@@ -1723,11 +1786,10 @@ AC_CONFIG_FILES([compatcheck/Makefile
src/lib/util/threads/Makefile
src/lib/util/threads/tests/Makefile
src/lib/util/unittests/Makefile
src/lib/eval/Makefile
src/lib/eval/tests/Makefile
src/share/Makefile
src/share/database/Makefile
src/share/database/scripts/Makefile
src/share/database/scripts/cql/Makefile
src/share/database/scripts/mysql/Makefile
src/share/database/scripts/mysql/upgrade_1.0_to_2.0.sh
src/share/database/scripts/mysql/upgrade_2.0_to_3.0.sh
...
...
@@ -1737,17 +1799,16 @@ AC_CONFIG_FILES([compatcheck/Makefile
src/share/database/scripts/pgsql/Makefile
src/share/database/scripts/pgsql/upgrade_1.0_to_2.0.sh
src/share/database/scripts/pgsql/upgrade_2.0_to_3.0.sh
src/share/database/scripts/cql/Makefile
tools/Makefile
tools/path_replacer.sh
])
AC_CONFIG_COMMANDS([permissions], [
AC_CONFIG_COMMANDS([permissions], [
chmod +x src/bin/admin/kea-admin
chmod +x src/bin/dhcp4/tests/dhcp4_process_tests.sh
chmod +x src/bin/dhcp6/tests/dhcp6_process_tests.sh
chmod +x src/bin/keactrl/keactrl
chmod +x src/bin/keactrl/tests/keactrl_tests.sh
chmod +x src/bin/admin/kea-admin
chmod +x src/lib/dns/gen-rdatacode.py
chmod +x src/lib/log/tests/console_test.sh
chmod +x src/lib/log/tests/destination_test.sh
...
...
src/bin/dhcp4/dhcp4to6_ipc.cc
View file @
0beffc6e
// Copyright (C) 2015-201
6
Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2015-201
7
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
...
...
@@ -35,7 +35,7 @@ Dhcp4to6Ipc& Dhcp4to6Ipc::instance() {
}
void
Dhcp4to6Ipc
::
open
()
{
uint
32
_t
port
=
CfgMgr
::
instance
().
getStagingCfg
()
->
getDhcp4o6Port
();
uint
16
_t
port
=
CfgMgr
::
instance
().
getStagingCfg
()
->
getDhcp4o6Port
();
if
(
port
==
0
)
{
Dhcp4o6IpcBase
::
close
();
return
;
...
...
@@ -45,8 +45,7 @@ void Dhcp4to6Ipc::open() {
}
int
old_fd
=
socket_fd_
;
socket_fd_
=
Dhcp4o6IpcBase
::
open
(
static_cast
<
uint16_t
>
(
port
),
ENDPOINT_TYPE_V4
);
socket_fd_
=
Dhcp4o6IpcBase
::
open
(
port
,
ENDPOINT_TYPE_V4
);
if
((
old_fd
==
-
1
)
&&
(
socket_fd_
!=
old_fd
))
{
IfaceMgr
::
instance
().
addExternalSocket
(
socket_fd_
,
Dhcp4to6Ipc
::
handler
);
...
...
src/bin/dhcp4/json_config_parser.cc
View file @
0beffc6e
...
...
@@ -341,24 +341,9 @@ public:
cfg
->
setDeclinePeriod
(
probation_period
);
// Set the DHCPv4-over-DHCPv6 interserver port.
// @todo Change for uint16_t
uint32_t
dhcp4o6_port
=
getUint32
(
global
,
"dhcp4o6-port"
);
uint16_t
dhcp4o6_port
=
getUint16
(
global
,
"dhcp4o6-port"
);
cfg
->
setDhcp4o6Port
(
dhcp4o6_port
);
}
private:
/// @brief Returns a value converted to uint32_t
///
/// Instantiation of getIntType() to uint32_t
///
/// @param scope specified parameter will be extracted from this scope
/// @param name name of the parameter
/// @return an uint32_t value
uint32_t
getUint32
(
isc
::
data
::
ConstElementPtr
scope
,
const
std
::
string
&
name
)
{
return
(
getIntType
<
uint32_t
>
(
scope
,
name
));
}
};
}
// anonymous namespace
...
...
src/bin/dhcp4/main.cc
View file @
0beffc6e
...
...
@@ -124,6 +124,9 @@ main(int argc, char* argv[]) {
usage
();
}
// This is the DHCPv4 server
CfgMgr
::
instance
().
setFamily
(
AF_INET
);
if
(
check_mode
)
{
try
{
...
...
src/bin/dhcp4/simple_parser4.cc
View file @
0beffc6e
...
...
@@ -45,8 +45,7 @@ const SimpleDefaults SimpleParser4::OPTION4_DEF_DEFAULTS = {
/// for those option-data declarations.
const
SimpleDefaults
SimpleParser4
::
OPTION4_DEFAULTS
=
{
{
"space"
,
Element
::
string
,
"dhcp4"
},
{
"csv-format"
,
Element
::
boolean
,
"true"
},
{
"encapsulate"
,
Element
::
string
,
""
}
{
"csv-format"
,
Element
::
boolean
,
"true"
}
};
/// @brief This table defines default global values for DHCPv4
...
...
src/bin/dhcp4/tests/config_parser_unittest.cc
View file @
0beffc6e
...
...
@@ -4557,14 +4557,6 @@ TEST_F(Dhcp4ParserTest, invalidClientClassDictionary) {
" } ]
\n
"
"}
\n
"
;
ConstElementPtr
json
;
ASSERT_NO_THROW
(
json
=
parseJSON
(
config
));
ConstElementPtr
status
;
EXPECT_NO_THROW
(
status
=
configureDhcp4Server
(
*
srv_
,
json
));
ASSERT_TRUE
(
status
);
checkResult
(
status
,
1
);
EXPECT_THROW
(
parseDHCP4
(
config
),
Dhcp4ParseError
);
}
...
...
src/bin/dhcp4/tests/simple_parser4_unittest.cc
View file @
0beffc6e
// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2016
-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
...
...
@@ -176,7 +176,6 @@ TEST_F(SimpleParser4Test, optionDataDefaults4) {
// we should have appropriate default value set. See
// SimpleParser4::OPTION4_DEFAULTS for a list of default values.
checkStringValue
(
option
,
"space"
,
"dhcp4"
);
checkStringValue
(
option
,
"encapsulate"
,
""
);
checkBoolValue
(
option
,
"csv-format"
,
true
);
}
...
...
src/bin/dhcp6/dhcp6to4_ipc.cc
View file @
0beffc6e
// Copyright (C) 2015-201
6
Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2015-201
7
Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
...
...
@@ -34,7 +34,7 @@ Dhcp6to4Ipc& Dhcp6to4Ipc::instance() {
}
void
Dhcp6to4Ipc
::
open
()
{
uint
32
_t
port
=
CfgMgr
::
instance
().
getStagingCfg
()
->
getDhcp4o6Port
();
uint
16
_t
port
=
CfgMgr
::
instance
().
getStagingCfg
()
->
getDhcp4o6Port
();
if
(
port
==
0
)
{
Dhcp4o6IpcBase
::
close
();
return
;
...
...
@@ -44,8 +44,7 @@ void Dhcp6to4Ipc::open() {
}
int
old_fd
=
socket_fd_
;
socket_fd_
=
Dhcp4o6IpcBase
::
open
(
static_cast
<
uint16_t
>
(
port
),
ENDPOINT_TYPE_V6
);
socket_fd_
=
Dhcp4o6IpcBase
::
open
(
port
,
ENDPOINT_TYPE_V6
);
if
((
old_fd
==
-
1
)
&&
(
socket_fd_
!=
old_fd
))
{
IfaceMgr
::
instance
().
addExternalSocket
(
socket_fd_
,
Dhcp6to4Ipc
::
handler
);
...
...
src/bin/dhcp6/json_config_parser.cc
View file @
0beffc6e
...
...
@@ -214,18 +214,6 @@ public:
private:
/// @brief Get an uint8_t value
///
/// Instantiation of getIntType() to uint8_t
///
/// @param scope specified parameter will be extracted from this scope
/// @param name name of the parameter
/// @return uint8_t value
/// @throw isc::dhcp::DhcpConfigError when it is not an uint8_t
uint8_t
getUint8
(
ConstElementPtr
scope
,
const
std
::
string
&
name
)
{
return
(
getIntType
<
uint8_t
>
(
scope
,
name
));
}
/// Pointer to the created pool object.
isc
::
dhcp
::
Pool6Ptr
pool_
;
...
...
@@ -547,24 +535,9 @@ public:
srv_config
->
setDeclinePeriod
(
probation_period
);
// Set the DHCPv4-over-DHCPv6 interserver port.
// @todo Change for uint16_t
uint32_t
dhcp4o6_port
=
getUint32
(
global
,
"dhcp4o6-port"
);
uint16_t
dhcp4o6_port
=
getUint16
(
global
,
"dhcp4o6-port"
);
srv_config
->
setDhcp4o6Port
(
dhcp4o6_port
);
}
private:
/// @brief Returns a value converted to uint32_t
///
/// Instantiation of getIntType() to uint32_t
///
/// @param scope specified parameter will be extracted from this scope
/// @param name name of the parameter
/// @return an uint32_t value
uint32_t
getUint32
(
isc
::
data
::
ConstElementPtr
scope
,
const
std
::
string
&
name
)
{
return
(
getIntType
<
uint32_t
>
(
scope
,
name
));
}
};
}
// anonymous namespace
...
...
src/bin/dhcp6/main.cc
View file @
0beffc6e
...
...
@@ -127,6 +127,9 @@ main(int argc, char* argv[]) {
usage
();
}
// This is the DHCPv6 server
CfgMgr
::
instance
().
setFamily
(
AF_INET6
);
if
(
check_mode
)
{
try
{
// We need to initialize logging, in case any error messages are to be printed.
...
...
src/bin/dhcp6/simple_parser6.cc
View file @
0beffc6e
...
...
@@ -45,8 +45,7 @@ const SimpleDefaults SimpleParser6::OPTION6_DEF_DEFAULTS = {
/// for those option-data declarations.
const
SimpleDefaults
SimpleParser6
::
OPTION6_DEFAULTS
=
{
{
"space"
,
Element
::
string
,
"dhcp6"
},
{
"csv-format"
,
Element
::
boolean
,
"true"
},
{
"encapsulate"
,
Element
::
string
,
""
}
{
"csv-format"
,
Element
::
boolean
,
"true"
}
};
/// @brief This table defines default global values for DHCPv6
...
...
src/bin/dhcp6/tests/config_parser_unittest.cc
View file @
0beffc6e
...
...
@@ -4969,13 +4969,6 @@ TEST_F(Dhcp6ParserTest, invalidClientClassDictionary) {
" } ]
\n
"
"}
\n
"
;
ConstElementPtr
json
=
parseJSON
(
config
);
ConstElementPtr
status
;
EXPECT_NO_THROW
(
status
=
configureDhcp6Server
(
srv_
,
json
));
ASSERT_TRUE
(
status
);
checkResult
(
status
,
1
);
EXPECT_THROW
(
parseDHCP6
(
config
),
Dhcp6ParseError
);
}
...
...
src/bin/dhcp6/tests/simple_parser6_unittest.cc
View file @
0beffc6e
// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2016
-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
...
...
@@ -159,7 +159,7 @@ TEST_F(SimpleParser6Test, subnetDefaults6) {
// This test checks if the parameters in option-data are assigned default values
// if not explicitly specified.
TEST_F
(
SimpleParser6Test
,
optionDataDefaults
4
)
{
TEST_F
(
SimpleParser6Test
,
optionDataDefaults
6
)
{
ElementPtr
global
=
parseJSON
(
"{
\"
renew-timer
\"
: 1,"
"
\"
rebind-timer
\"
: 2,"
"
\"
preferred-lifetime
\"
: 3,"
...
...
@@ -179,7 +179,6 @@ TEST_F(SimpleParser6Test, optionDataDefaults4) {
// we should have appropriate default value set. See
// SimpleParser4::OPTION4_DEFAULTS for a list of default values.
checkStringValue
(
option
,
"space"
,
"dhcp6"
);
checkStringValue
(
option
,
"encapsulate"
,
""
);
checkBoolValue
(
option
,
"csv-format"
,
true
);
}
...
...
src/lib/cc/data.cc
View file @
0beffc6e
...
...
@@ -11,6 +11,7 @@
#include <cstring>
#include <cassert>
#include <climits>
#include <list>
#include <map>
#include <cstdio>
#include <iostream>
...
...
@@ -1067,6 +1068,241 @@ merge(ElementPtr element, ConstElementPtr other) {
}
}
ElementPtr
copy
(
ConstElementPtr
from
,
int
level
)
{
if
(
isNull
(
from
))
{
isc_throw
(
BadValue
,
"copy got a null pointer"
);
}
int
from_type
=
from
->
getType
();
if
(
from_type
==
Element
::
integer
)
{
return
(
ElementPtr
(
new
IntElement
(
from
->
intValue
())));
}
else
if
(
from_type
==
Element
::
real
)
{
return
(
ElementPtr
(
new
DoubleElement
(
from
->
doubleValue
())));
}
else
if
(
from_type
==
Element
::
boolean
)
{
return
(
ElementPtr
(
new
BoolElement
(
from
->
boolValue
())));
}
else
if
(
from_type
==
Element
::
null
)
{
return
(
ElementPtr
(
new
NullElement
()));
}
else
if
(
from_type
==
Element
::
string
)
{
return
(
ElementPtr
(
new
StringElement
(
from
->
stringValue
())));
}
else
if
(
from_type
==
Element
::
list
)
{
ElementPtr
result
=
ElementPtr
(
new
ListElement
());
typedef
std
::
vector
<
ElementPtr
>
ListType
;
const
ListType
&
value
=
from
->
listValue
();
for
(
ListType
::
const_iterator
it
=
value
.
cbegin
();
it
!=
value
.
cend
();
++
it
)
{
if
(
level
==
0
)
{
result
->
add
(
*
it
);
}
else
{
result
->
add
(
copy
(
*
it
,
level
-
1
));
}
}
return
(
result
);
}
else
if
(
from_type
==
Element
::
map
)
{
ElementPtr
result
=
ElementPtr
(
new
MapElement
());
typedef
std
::
map
<
std
::
string
,
ConstElementPtr
>
MapType
;
const
MapType
&
value
=
from
->
mapValue
();
for
(
MapType
::
const_iterator
it
=
value
.
cbegin
();
it
!=
value
.
cend
();
++
it
)
{
if
(
level
==
0
)
{
result
->
set
(
it
->
first
,
it
->
second
);
}
else
{
result
->
set
(
it
->
first
,
copy
(
it
->
second
,
level
-
1
));
}
}
return
(
result
);
}
else
{
isc_throw
(
BadValue
,
"copy got an element of type: "
<<
from_type
);
}
}
namespace
{
// Helper function which blocks infinite recursion
bool
isEquivalent0
(
ConstElementPtr
a
,
ConstElementPtr
b
,
unsigned
level
)
{
// check looping forever on cycles
if
(
!
level
)
{
isc_throw
(
BadValue
,
"isEquivalent got infinite recursion: "
"arguments include cycles"
);
}
if
(
!
a
||
!
b
)
{
isc_throw
(
BadValue
,
"isEquivalent got a null pointer"
);
}
// check types
if
(
a
->
getType
()
!=
b
->
getType
())
{
return
(
false
);
}
if
(
a
->
getType
()
==
Element
::
list
)
{
// check empty
if
(
a
->
empty
())
{
return
(
b
->
empty
());
}
// check size
if
(
a
->
size
()
!=
b
->
size
())
{
return
(
false
);
}
// copy b into a list
const
size_t
s
=
a
->
size
();
typedef
std
::
list
<
ConstElementPtr
>
ListType
;
ListType
l
;
for
(
size_t
i
=
0
;
i
<
s
;
++
i
)
{
l
.
push_back
(
b
->
get
(
i
));
}
// iterate on a
for
(
size_t
i
=
0
;
i
<
s
;
++
i
)
{
ConstElementPtr
item
=
a
->
get
(
i
);
// lookup this item in the list
bool
found
=
false
;
for
(
ListType
::
iterator
it
=
l
.
begin
();
it
!=
l
.
end
();
++
it
)
{
// if found in the list remove it
if
(
isEquivalent0
(
item
,
*
it
,
level
-
1
))
{
found
=
true
;
l
.
erase
(
it
);
break
;
}
}
// if not found argument differs
if
(
!
found
)
{
return
(
false
);
}
}
// sanity check: the list must be empty
if
(
!
l
.
empty
())
{
isc_throw
(
Unexpected
,
"isEquivalent internal error"
);
}
return
(
true
);
}
else
if
(
a
->
getType
()
==
Element
::
map
)
{
// iterate on the first map
typedef
std
::
map
<
std
::
string
,
ConstElementPtr
>
MapType
;
const
MapType
&
ma
=
a
->
mapValue
();
for
(
MapType
::
const_iterator
it
=
ma
.
begin
();
it
!=
ma
.
end
()
;
++
it
)
{
// get the b value for the given keyword and recurse
ConstElementPtr
item
=
b
->
get
(
it
->
first
);
if
(
!
item
||
!
isEquivalent0
(
it
->
second
,
item
,
level
-
1
))
{
return
(
false
);
}
}
// iterate on the second map
const
MapType
&
mb
=
b
->
mapValue
();
for
(
MapType
::
const_iterator
it
=
mb
.
begin
();
it
!=
mb
.
end
()
;
++
it
)
{
// check if the keyword exists
if
(
!
a
->
contains
(
it
->
first
))
{
return
(
false
);
}
}
return
(
true
);
}
else
{
return
(
a
->
equals
(
*
b
));
}
}
}
bool
isEquivalent
(
ConstElementPtr
a
,
ConstElementPtr
b
)
{
return
(
isEquivalent0
(
a
,
b
,
100
));
}
void
prettyPrint
(
ConstElementPtr
element
,
std
::
ostream
&
out
,
unsigned
indent
,
unsigned
step
)
{
if
(
!
element
)
{
isc_throw
(
BadValue
,
"prettyPrint got a null pointer"
);
}
if
(
element
->
getType
()
==
Element
::
list
)
{
// empty list case
if
(
element
->
empty
())
{
out
<<
"[ ]"
;
return
;
}
// complex ? multiline : oneline
if
(
!
element
->
get
(
0
))
{
isc_throw
(
BadValue
,
"prettyPrint got a null pointer"
);
}
int
first_type
=
element
->
get
(
0
)
->
getType
();
bool
complex
=
false
;
if
((
first_type
==
Element
::
list
)
||
(
first_type
==
Element
::
map
))
{
complex
=
true
;
}