diff --git a/.gitattributes b/.gitattributes index 6afd357c2..f75097ecd 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,2 @@ .git* export-ignore -/CMakeLists.txt export-subst \ No newline at end of file +version.cmake export-subst diff --git a/CMakeLists.txt b/CMakeLists.txt index 4949c7385..7ce93d951 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, The Monero Project +# Copyright (c) 2014-2015, The Monero Project # # All rights reserved. # @@ -28,33 +28,41 @@ # # Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers -cmake_minimum_required(VERSION 2.8.6) +cmake_minimum_required(VERSION 2.8.7) -if(NOT WIN32) - string(ASCII 27 Esc) - set(ColourReset "${Esc}[m") - set(BoldRed "${Esc}[1;31m") -endif() +project(bitmonero) -set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") +function (die msg) + if (NOT WIN32) + string(ASCII 27 Esc) + set(ColourReset "${Esc}[m") + set(BoldRed "${Esc}[1;31m") + else () + set(ColourReset "") + set(BoldRed "") + endif () + + message(FATAL_ERROR "${BoldRed}${msg}${ColourReset}") +endfunction () + +list(INSERT CMAKE_MODULE_PATH 0 + "${CMAKE_SOURCE_DIR}/cmake") if (NOT DEFINED ENV{DEVELOPER_LOCAL_TOOLS}) - message(STATUS "Could not find DEVELOPER_LOCAL_TOOLS in env (not required)") - set(BOOST_IGNORE_SYSTEM_PATHS_DEFAULT OFF) -elseif ("$ENV{DEVELOPER_LOCAL_TOOLS}" EQUAL 1) - message(STATUS "Found: env DEVELOPER_LOCAL_TOOLS = 1") - set(BOOST_IGNORE_SYSTEM_PATHS_DEFAULT ON) - option(BOOST_IGNORE_SYSTEM_PATHS "Ignore boost system paths for local boost installation" ON) + message(STATUS "Could not find DEVELOPER_LOCAL_TOOLS in env (not required)") + set(BOOST_IGNORE_SYSTEM_PATHS_DEFAULT OFF) +elseif (ENV{DEVELOPER_LOCAL_TOOLS} EQUAL 1) + message(STATUS "Found: env DEVELOPER_LOCAL_TOOLS = 1") + set(BOOST_IGNORE_SYSTEM_PATHS_DEFAULT ON) else() - message(STATUS "found: env DEVELOPER_LOCAL_TOOLS = 0") - set(BOOST_IGNORE_SYSTEM_PATHS_DEFAULT OFF) + message(STATUS "Found: env DEVELOPER_LOCAL_TOOLS = 0") + set(BOOST_IGNORE_SYSTEM_PATHS_DEFAULT OFF) endif() message(STATUS "BOOST_IGNORE_SYSTEM_PATHS defaults to ${BOOST_IGNORE_SYSTEM_PATHS_DEFAULT}") -option(BOOST_IGNORE_SYSTEM_PATHS "Ignore boost system paths for local boost ins tallation" $BOOST_IGNORE_SYSTEM_PATHS_DEFAULT) +option(BOOST_IGNORE_SYSTEM_PATHS "Ignore boost system paths for local boost installation" ${BOOST_IGNORE_SYSTEM_PATHS_DEFAULT}) set_property(GLOBAL PROPERTY USE_FOLDERS ON) -set(CMAKE_CONFIGURATION_TYPES "Debug;Release") enable_testing() # Check if we're on FreeBSD so we can exclude the local miniupnpc (it should be installed from ports instead) @@ -86,15 +94,28 @@ if(MSVC OR MINGW) else() set(DEFAULT_STATIC false) endif() -set(STATIC ${DEFAULT_STATIC} CACHE BOOL "Link libraries statically") +option(STATIC "Link libraries statically" ${DEFAULT_STATIC}) -IF(STATIC) - IF(MSVC) - SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib .dll.a .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) - ELSE() - SET(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) - ENDIF() -ENDIF() +if(MINGW) + get_filename_component(msys2_install_path "[HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MSYS2 64bit;InstallLocation]" ABSOLUTE) + set(CMAKE_INCLUDE_PATH "${msys2_install_path}/mingw64/include") + # This is necessary because otherwise CMake will make Boost libraries -lfoo + # rather than a full path. Unfortunately, this makes the shared libraries get + # linked due to a bug in CMake which misses putting -static flags around the + # -lfoo arguments. + list(REMOVE_ITEM CMAKE_C_IMPLICIT_LINK_DIRECTORIES + "${msys2_install_path}/mingw64/lib") + list(REMOVE_ITEM CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES + "${msys2_install_path}/mingw64/lib") +endif() + +if(STATIC) + if(MSVC) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .dll.a .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif() +endif() if (UNIX AND NOT APPLE) # Note that at the time of this writing the -Wstrict-prototypes flag added below will make this fail @@ -113,6 +134,10 @@ endif() # Final setup for libunbound include_directories(${UNBOUND_INCLUDE}) +link_directories(${UNBOUND_LIBRARY_DIRS}) + +# Final setup for rapidjson +include_directories(external/rapidjson) if(MSVC) add_definitions("/bigobj /MP /W3 /GS- /D_CRT_SECURE_NO_WARNINGS /wd4996 /wd4345 /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN /DGTEST_HAS_TR1_TUPLE=0 /FIinline_c.h /D__SSE4_1__") @@ -126,12 +151,15 @@ if(MSVC) include_directories(SYSTEM src/platform/msc) else() set(ARCH native CACHE STRING "CPU to build for: -march value or default") - if("${ARCH}" STREQUAL "default") + if(ARCH STREQUAL "default") set(ARCH_FLAG "") else() set(ARCH_FLAG "-march=${ARCH}") endif() - set(WARNINGS "-Wall -Wextra -Wpointer-arith -Wundef -Wvla -Wwrite-strings -Werror -Wno-error=extra -Wno-error=deprecated-declarations -Wno-error=sign-compare -Wno-error=strict-aliasing -Wno-error=type-limits -Wno-unused-parameter -Wno-error=unused-variable -Wno-error=undef -Wno-error=uninitialized") + set(WARNINGS "-Wall -Wextra -Wpointer-arith -Wundef -Wvla -Wwrite-strings -Wno-error=extra -Wno-error=deprecated-declarations -Wno-error=sign-compare -Wno-error=strict-aliasing -Wno-error=type-limits -Wno-unused-parameter -Wno-error=unused-variable -Wno-error=undef -Wno-error=uninitialized") + if(NOT MINGW) + set(WARNINGS "${WARNINGS} -Werror") + endif() if(CMAKE_C_COMPILER_ID STREQUAL "Clang") set(WARNINGS "${WARNINGS} -Wno-error=mismatched-tags -Wno-error=null-conversion -Wno-overloaded-shift-op-parentheses -Wno-error=shift-count-overflow -Wno-error=tautological-constant-out-of-range-compare -Wno-error=unused-private-field -Wno-error=unneeded-internal-declaration") else() @@ -142,6 +170,8 @@ else() set(MINGW_FLAG "${MINGW_FLAG} -DWIN32_LEAN_AND_MEAN") set(Boost_THREADAPI win32) include_directories(SYSTEM src/platform/mingw) + # mingw doesn't support LTO (multiple definition errors at link time) + set(USE_LTO_DEFAULT false) endif() set(C_WARNINGS "-Waggregate-return -Wnested-externs -Wold-style-definition -Wstrict-prototypes") set(CXX_WARNINGS "-Wno-reorder -Wno-missing-field-initializers") @@ -171,7 +201,7 @@ else() # There is a clang bug that does not allow to compile code that uses AES-NI intrinsics if -flto is enabled, so explicitly disable if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - set(USE_LTO false) + set(USE_LTO false) endif() if(USE_LTO) set(RELEASE_FLAGS "${RELEASE_FLAGS} -flto") @@ -195,7 +225,7 @@ else() endif() if (BOOST_IGNORE_SYSTEM_PATHS) - set(Boost_NO_SYSTEM_PATHS TRUE) + set(Boost_NO_SYSTEM_PATHS TRUE) endif() if(STATIC) @@ -205,36 +235,27 @@ endif() find_package(Boost 1.53 QUIET REQUIRED COMPONENTS system filesystem thread date_time chrono regex serialization program_options) if(NOT Boost_FOUND) - MESSAGE(FATAL_ERROR "${BoldRed}Could not find Boost libraries, please make sure you have installed Boost or libboost-all-dev (1.53 or 1.55+) or the equivalent${ColourReset}") + die("Could not find Boost libraries, please make sure you have installed Boost or libboost-all-dev (1.53 or 1.55+) or the equivalent") endif() -if((${Boost_MAJOR_VERSION} EQUAL 1) AND (${Boost_MINOR_VERSION} EQUAL 54)) - message(FATAL_ERROR "${BoldRed}Boost version 1.54 is unsupported due to a bug (see: http://goo.gl/RrCFmA), please install Boost 1.53 or 1.55 and above${ColourReset}") +if((Boost_MAJOR_VERSION EQUAL 1) AND (Boost_MINOR_VERSION EQUAL 54)) + die("Boost version 1.54 is unsupported due to a bug (see: http://goo.gl/RrCFmA), please install Boost 1.53 or 1.55 and above") endif() include_directories(SYSTEM ${Boost_INCLUDE_DIRS}) if(MINGW) - set(EXTRA_LIBRARIES pthread;mswsock;ws2_32) + set(EXTRA_LIBRARIES mswsock;ws2_32;iphlpapi) elseif(APPLE OR FREEBSD) set(EXTRA_LIBRARIES "") elseif(NOT MSVC) find_library(RT rt) - find_library(PTHREAD pthread) - find_library(DL dl) set(EXTRA_LIBRARIES ${RT} ${PTHREAD} ${DL}) endif() -file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/version") -find_package(Git QUIET) -if(Git_FOUND OR GIT_FOUND) - message(STATUS "Found Git: ${GIT_EXECUTABLE}") - add_custom_target(version ALL "${CMAKE_COMMAND}" "-D" "GIT=${GIT_EXECUTABLE}" "-D" "TO=${CMAKE_BINARY_DIR}/version/version.h" "-P" "src/version.cmake" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}") -else() - message(STATUS "WARNING: Git was not found!") - set(VERSIONTAG "unknown") - configure_file("src/version.h.in" "version/version.h") - add_custom_target(version ALL) -endif() +include(version.cmake) add_subdirectory(src) -add_subdirectory(tests) + +if(BUILD_TESTS) + add_subdirectory(tests) +endif() diff --git a/Makefile b/Makefile index 8a4e7a75e..4e3397230 100644 --- a/Makefile +++ b/Makefile @@ -8,9 +8,12 @@ build-debug: cmake-debug cd build/debug && $(MAKE) test-debug: build-debug - cd build/debug && $(MAKE) test + mkdir -p build/debug + cd build/debug && cmake -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=Debug ../.. && $(MAKE) test -all-debug: build-debug +all-debug: + mkdir -p build/debug + cd build/debug && cmake -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=Debug ../.. && $(MAKE) cmake-release: mkdir -p build/release @@ -20,13 +23,16 @@ build-release: cmake-release cd build/release && $(MAKE) test-release: build-release - cd build/release && $(MAKE) test + mkdir -p build/release + cd build/release && cmake -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=release ../.. && $(MAKE) test -all-release: build-release +all-release: + mkdir -p build/release + cd build/release && cmake -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=release ../.. && $(MAKE) release-static: mkdir -p build/release - cd build/release && cmake -D STATIC=ON -D ARCH="x86-64" -D CMAKE_BUILD_TYPE=Release ../.. && $(MAKE) + cd build/release && cmake -D STATIC=ON -D ARCH="x86-64" -D CMAKE_BUILD_TYPE=release ../.. && $(MAKE) clean: @echo "WARNING: Back-up your wallet if it exists within ./build!" ; \ diff --git a/README.md b/README.md index b40e06b8e..bd0866002 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Monero -Copyright (c) 2014, The Monero Project +Copyright (c) 2014-2015, The Monero Project ## Development Resources @@ -30,7 +30,7 @@ Anyone is able to contribute to Monero. If you have a fix or code change, feel f ## License -Copyright (c) 2014, The Monero Project +Copyright (c) 2014-2015, The Monero Project All rights reserved. @@ -50,7 +50,7 @@ Parts of the project are originally copyright (c) 2012-2013 The Cryptonote devel ### On Unix and Linux: -Dependencies: GCC 4.7.3 or later, CMake 2.8.6 or later, libunbound 1.4.16 or later (note: Unbound is not a dependency, libunbound is), and Boost 1.53 or later (except 1.54, [more details here](http://goo.gl/RrCFmA)). +Dependencies: GCC 4.7.3 or later, CMake 2.8.6 or later, libunbound 1.4.16 or later (note: Unbound is not a dependency, libunbound is), libevent 2.0 or later, libgtest 1.5 or later, and Boost 1.53 or later (except 1.54, [more details here](http://goo.gl/RrCFmA)). Static Build Additional Dependencies: ldns 1.6.17 or later, expat 1.1 or later, bison or yacc **Basic Process:** @@ -136,4 +136,4 @@ Dependencies: Doxygen 1.8.0 or later, Graphviz 2.28 or later (optional). * To build, change to the root of the source code directory, and run `doxygen Doxyfile` * If you have installed Graphviz, you can also generate in-doc diagrams by instead running `HAVE_DOT=YES doxygen Doxyfile` -* The output will be built in doc/html/ \ No newline at end of file +* The output will be built in doc/html/ diff --git a/ReleaseNotes.txt b/ReleaseNotes.txt deleted file mode 100644 index b2a3e0081..000000000 --- a/ReleaseNotes.txt +++ /dev/null @@ -1,47 +0,0 @@ -Monero - -Release notes 0.8.8 - -- JSON RPC v2.0 compatibility -- JSON RPC over TCP added- Further optimizations -- Fixed a bug with checkpoints behavior -- UI improvements for daemon -- Fixed COIN value (10^12) -- Raised minimum fee to 5 * (10^9) -- Temporary fix for block reward DoS attack - -Release notes 0.8.7 - -- Slow hash optimizations - -Release notes 0.8.6 - -- Simplwallet can set extra for transfers -- Improvements in JSON RPC for wallet -- UX improvements in simplewallet -- Win32 compilation -- Mac OSX compilation - -Release notes 0.8.5 - -- Port mapping for daemon using UPnP -- Improvements for daemon JSON RPC API - -Release notes 0.8.4 - -- Formalization of high level API -- Improvements for wallet JSON RPC API - -Release notes 0.8.3 - -- JSON RPC for wallet -- Fixed bug with blockchain storing -- Fixed bug with correct display of transfer's change -- Bug fix in simple wallet - -Release notes 0.8.2 - -- Now wallet is still working when daemon stores blockchain and can't serve clients -- No-console option for a daemon -- Fixed problem with network synchronization -- Major bug fix in simple wallet diff --git a/cmake/FindMiniupnpc.cmake b/cmake/FindMiniupnpc.cmake index 0bf331da2..ab525b3a7 100644 --- a/cmake/FindMiniupnpc.cmake +++ b/cmake/FindMiniupnpc.cmake @@ -32,7 +32,7 @@ if (MINIUPNP_INCLUDE_DIR AND MINIUPNP_LIBRARY) # Already in cache, be silent set(MINIUPNP_FIND_QUIETLY TRUE) -endif (MINIUPNP_INCLUDE_DIR AND MINIUPNP_LIBRARY) +endif () find_path(MINIUPNP_INCLUDE_DIR miniupnpc.h PATH_SUFFIXES miniupnpc) @@ -47,7 +47,7 @@ if (MINIUPNP_FOUND) if (NOT MINIUPNP_FIND_QUIETLY) message (STATUS "Found the miniupnpc libraries at ${MINIUPNP_LIBRARY}") message (STATUS "Found the miniupnpc headers at ${MINIUPNP_INCLUDE_DIR}") - endif (NOT MINIUPNP_FIND_QUIETLY) + endif () message(STATUS "Detecting version of miniupnpc in path: ${MINIUPNP_INCLUDE_DIR}") @@ -182,4 +182,4 @@ else () endif () MARK_AS_ADVANCED(MINIUPNP_INCLUDE_DIR MINIUPNP_LIBRARY) -# --------------------------------- FindMiniupnpc End --------------------------------- \ No newline at end of file +# --------------------------------- FindMiniupnpc End --------------------------------- diff --git a/cmake/FindUnbound.cmake b/cmake/FindUnbound.cmake index 9728cd2f0..ff6de8d98 100644 --- a/cmake/FindUnbound.cmake +++ b/cmake/FindUnbound.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2014, The Monero Project +# Copyright (c) 2014-2015, The Monero Project # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, are diff --git a/contrib/epee/LICENSE.txt b/contrib/epee/LICENSE.txt index 4a6b529e5..9835c2f69 100644 --- a/contrib/epee/LICENSE.txt +++ b/contrib/epee/LICENSE.txt @@ -22,4 +22,4 @@ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/contrib/epee/README.md b/contrib/epee/README.md index a69884f57..8157d3e56 100644 --- a/contrib/epee/README.md +++ b/contrib/epee/README.md @@ -1 +1 @@ -epee - is a small library of helpers, wrappers, tools and and so on, used to make my life easier. \ No newline at end of file +epee - is a small library of helpers, wrappers, tools and and so on, used to make my life easier. diff --git a/contrib/epee/demo/generate_vc_proj.bat b/contrib/epee/demo/generate_vc_proj.bat index 111405981..7d83ced6f 100644 --- a/contrib/epee/demo/generate_vc_proj.bat +++ b/contrib/epee/demo/generate_vc_proj.bat @@ -4,4 +4,4 @@ cd build cmake "-DBoost_USE_STATIC_LIBS=TRUE" -G "Visual Studio 11 Win64" .. cd .. -pause \ No newline at end of file +pause diff --git a/contrib/epee/demo/iface/transport_defs.h b/contrib/epee/demo/iface/transport_defs.h index 8463eb903..746694aa3 100644 --- a/contrib/epee/demo/iface/transport_defs.h +++ b/contrib/epee/demo/iface/transport_defs.h @@ -218,4 +218,4 @@ namespace demo s.m_storage_entry_string = epee::serialization::storage_entry(std::string("sdsvsdvs")); return s; } -} \ No newline at end of file +} diff --git a/contrib/epee/include/copyable_atomic.h b/contrib/epee/include/copyable_atomic.h index 6b5691ab1..410b4b4ff 100644 --- a/contrib/epee/include/copyable_atomic.h +++ b/contrib/epee/include/copyable_atomic.h @@ -51,4 +51,4 @@ namespace epee return std::atomic::operator++(fake); } }; -} \ No newline at end of file +} diff --git a/contrib/epee/include/math_helper.h b/contrib/epee/include/math_helper.h index 349d6d822..9b8765e60 100644 --- a/contrib/epee/include/math_helper.h +++ b/contrib/epee/include/math_helper.h @@ -269,4 +269,4 @@ PRAGMA_WARNING_POP time_t m_interval; }; } -} \ No newline at end of file +} diff --git a/contrib/epee/include/md5_l.inl b/contrib/epee/include/md5_l.inl index c3da1a3b0..2aa881092 100644 --- a/contrib/epee/include/md5_l.inl +++ b/contrib/epee/include/md5_l.inl @@ -560,4 +560,4 @@ namespace md5 MD5Final(digest, &context); /* finish up 2nd pass */ } -} \ No newline at end of file +} diff --git a/contrib/epee/include/net/http_base.h b/contrib/epee/include/net/http_base.h index 49b0839b2..2a227cc70 100644 --- a/contrib/epee/include/net/http_base.h +++ b/contrib/epee/include/net/http_base.h @@ -181,4 +181,4 @@ namespace net_utils }; } } -} \ No newline at end of file +} diff --git a/contrib/epee/include/net/http_client.h b/contrib/epee/include/net/http_client.h index 5897a017e..66b28384c 100644 --- a/contrib/epee/include/net/http_client.h +++ b/contrib/epee/include/net/http_client.h @@ -872,4 +872,4 @@ using namespace std; } } -} \ No newline at end of file +} diff --git a/contrib/epee/include/net/http_client_base.h b/contrib/epee/include/net/http_client_base.h index 571e27f73..450d44823 100644 --- a/contrib/epee/include/net/http_client_base.h +++ b/contrib/epee/include/net/http_client_base.h @@ -70,4 +70,4 @@ namespace epee i_target_handler* m_powner_filter; }; } -} \ No newline at end of file +} diff --git a/contrib/epee/include/net/http_client_via_api_helper.h b/contrib/epee/include/net/http_client_via_api_helper.h index 45a70993b..391c44964 100644 --- a/contrib/epee/include/net/http_client_via_api_helper.h +++ b/contrib/epee/include/net/http_client_via_api_helper.h @@ -174,4 +174,4 @@ namespace net_utils return final_res; } } -} \ No newline at end of file +} diff --git a/contrib/epee/include/net/http_protocol_handler.inl b/contrib/epee/include/net/http_protocol_handler.inl index 78b46427e..2458af047 100644 --- a/contrib/epee/include/net/http_protocol_handler.inl +++ b/contrib/epee/include/net/http_protocol_handler.inl @@ -677,4 +677,4 @@ namespace net_utils //-------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------- -//-------------------------------------------------------------------------------------------- \ No newline at end of file +//-------------------------------------------------------------------------------------------- diff --git a/contrib/epee/include/net/http_server_impl_base.h b/contrib/epee/include/net/http_server_impl_base.h index c02475c34..97a7ebc56 100644 --- a/contrib/epee/include/net/http_server_impl_base.h +++ b/contrib/epee/include/net/http_server_impl_base.h @@ -109,4 +109,4 @@ namespace epee protected: net_utils::boosted_tcp_server > m_net_server; }; -} \ No newline at end of file +} diff --git a/contrib/epee/include/net/levin_client_async.h b/contrib/epee/include/net/levin_client_async.h index 9e76cd509..be5847c74 100644 --- a/contrib/epee/include/net/levin_client_async.h +++ b/contrib/epee/include/net/levin_client_async.h @@ -574,4 +574,4 @@ namespace levin }; } -} \ No newline at end of file +} diff --git a/contrib/epee/include/net/levin_helper.h b/contrib/epee/include/net/levin_helper.h index a8406103c..53b19c9fa 100644 --- a/contrib/epee/include/net/levin_helper.h +++ b/contrib/epee/include/net/levin_helper.h @@ -134,4 +134,4 @@ namespace levin return true; } } -} \ No newline at end of file +} diff --git a/contrib/epee/include/net/munin_connection_handler.h b/contrib/epee/include/net/munin_connection_handler.h index 8579339c5..ed2f59f22 100644 --- a/contrib/epee/include/net/munin_connection_handler.h +++ b/contrib/epee/include/net/munin_connection_handler.h @@ -373,4 +373,4 @@ namespace net_utils } } } -#endif//!_MUNIN_CONNECTION_HANDLER_H_ \ No newline at end of file +#endif//!_MUNIN_CONNECTION_HANDLER_H_ diff --git a/contrib/epee/include/net/munin_node_server.h b/contrib/epee/include/net/munin_node_server.h index 07637f550..e6df390cb 100644 --- a/contrib/epee/include/net/munin_node_server.h +++ b/contrib/epee/include/net/munin_node_server.h @@ -46,4 +46,4 @@ namespace net_utils } } } -#endif//!_MUNIN_NODE_SERVER_H_ \ No newline at end of file +#endif//!_MUNIN_NODE_SERVER_H_ diff --git a/contrib/epee/include/net/protocol_switcher.h b/contrib/epee/include/net/protocol_switcher.h index ca0ce6f97..3b153d19c 100644 --- a/contrib/epee/include/net/protocol_switcher.h +++ b/contrib/epee/include/net/protocol_switcher.h @@ -118,4 +118,4 @@ namespace net_utils } } } -#endif //_PROTOCOL_SWITCHER_H_ \ No newline at end of file +#endif //_PROTOCOL_SWITCHER_H_ diff --git a/contrib/epee/include/net/rpc_method_name.h b/contrib/epee/include/net/rpc_method_name.h index c226639c4..1c327bc31 100644 --- a/contrib/epee/include/net/rpc_method_name.h +++ b/contrib/epee/include/net/rpc_method_name.h @@ -28,4 +28,4 @@ #pragma once -#define RPC_METHOD_NAME(name) static inline const char* methodname(){return name;} \ No newline at end of file +#define RPC_METHOD_NAME(name) static inline const char* methodname(){return name;} diff --git a/contrib/epee/include/net/smtp.h b/contrib/epee/include/net/smtp.h index d2e8598fd..5f2b842d5 100644 --- a/contrib/epee/include/net/smtp.h +++ b/contrib/epee/include/net/smtp.h @@ -178,4 +178,4 @@ namespace net_utils } } -//#include "smtp.inl" \ No newline at end of file +//#include "smtp.inl" diff --git a/contrib/epee/include/net/smtp.inl b/contrib/epee/include/net/smtp.inl index d42c8b950..c16372c88 100644 --- a/contrib/epee/include/net/smtp.inl +++ b/contrib/epee/include/net/smtp.inl @@ -1566,4 +1566,4 @@ namespace net_utils } } -} \ No newline at end of file +} diff --git a/contrib/epee/include/net/smtp_helper.h b/contrib/epee/include/net/smtp_helper.h index b8252e1cf..7827315a2 100644 --- a/contrib/epee/include/net/smtp_helper.h +++ b/contrib/epee/include/net/smtp_helper.h @@ -85,4 +85,4 @@ namespace net_utils } } } -} \ No newline at end of file +} diff --git a/contrib/epee/include/serialization/enableable.h b/contrib/epee/include/serialization/enableable.h index ab1d799e6..e1be2a774 100644 --- a/contrib/epee/include/serialization/enableable.h +++ b/contrib/epee/include/serialization/enableable.h @@ -50,4 +50,4 @@ namespace epee { // construct from specified values } }; -} \ No newline at end of file +} diff --git a/contrib/epee/include/soci_helper.h b/contrib/epee/include/soci_helper.h index 813edc1fc..1da5aa7e2 100644 --- a/contrib/epee/include/soci_helper.h +++ b/contrib/epee/include/soci_helper.h @@ -139,4 +139,4 @@ namespace soci std::string m_connection_string; }; } -/*}*/ \ No newline at end of file +/*}*/ diff --git a/contrib/epee/include/storages/crypted_storage.h b/contrib/epee/include/storages/crypted_storage.h index d6e6edcba..163728cfc 100644 --- a/contrib/epee/include/storages/crypted_storage.h +++ b/contrib/epee/include/storages/crypted_storage.h @@ -59,4 +59,4 @@ public: }; } -#endif //_CRYPTED_STORAGE_H_ \ No newline at end of file +#endif //_CRYPTED_STORAGE_H_ diff --git a/contrib/epee/include/storages/gzipped_inmemstorage.h b/contrib/epee/include/storages/gzipped_inmemstorage.h index 5c53fffa7..229a56da6 100644 --- a/contrib/epee/include/storages/gzipped_inmemstorage.h +++ b/contrib/epee/include/storages/gzipped_inmemstorage.h @@ -65,4 +65,4 @@ namespace StorageNamed } } -#endif \ No newline at end of file +#endif diff --git a/contrib/epee/include/storages/parserse_base_utils.h b/contrib/epee/include/storages/parserse_base_utils.h index baafb5623..c809392f4 100644 --- a/contrib/epee/include/storages/parserse_base_utils.h +++ b/contrib/epee/include/storages/parserse_base_utils.h @@ -257,4 +257,4 @@ namespace misc_utils } } } -} \ No newline at end of file +} diff --git a/contrib/epee/include/storages/portable_storage_base.h b/contrib/epee/include/storages/portable_storage_base.h index 3f1637538..93132548b 100644 --- a/contrib/epee/include/storages/portable_storage_base.h +++ b/contrib/epee/include/storages/portable_storage_base.h @@ -157,4 +157,4 @@ namespace epee typedef section* hsection; typedef array_entry* harray; } -} \ No newline at end of file +} diff --git a/contrib/epee/include/storages/portable_storage_from_bin.h b/contrib/epee/include/storages/portable_storage_from_bin.h index e9b7e2e6f..bc2fb1463 100644 --- a/contrib/epee/include/storages/portable_storage_from_bin.h +++ b/contrib/epee/include/storages/portable_storage_from_bin.h @@ -278,4 +278,4 @@ namespace epee m_count -= len; } } -} \ No newline at end of file +} diff --git a/contrib/epee/include/storages/portable_storage_from_json.h b/contrib/epee/include/storages/portable_storage_from_json.h index 4e74fb7a5..41f270627 100644 --- a/contrib/epee/include/storages/portable_storage_from_json.h +++ b/contrib/epee/include/storages/portable_storage_from_json.h @@ -376,4 +376,4 @@ namespace epee } } } -} \ No newline at end of file +} diff --git a/contrib/epee/include/storages/portable_storage_template_helper.h b/contrib/epee/include/storages/portable_storage_template_helper.h index 008f44321..88515b5c3 100644 --- a/contrib/epee/include/storages/portable_storage_template_helper.h +++ b/contrib/epee/include/storages/portable_storage_template_helper.h @@ -120,4 +120,4 @@ namespace epee return std::move(binary_buff); } } -} \ No newline at end of file +} diff --git a/contrib/epee/include/storages/portable_storage_to_bin.h b/contrib/epee/include/storages/portable_storage_to_bin.h index baf90290a..5695143b0 100644 --- a/contrib/epee/include/storages/portable_storage_to_bin.h +++ b/contrib/epee/include/storages/portable_storage_to_bin.h @@ -209,4 +209,4 @@ namespace epee return true; } } -} \ No newline at end of file +} diff --git a/contrib/epee/include/storages/portable_storage_to_json.h b/contrib/epee/include/storages/portable_storage_to_json.h index e3fdcec29..43e341291 100644 --- a/contrib/epee/include/storages/portable_storage_to_json.h +++ b/contrib/epee/include/storages/portable_storage_to_json.h @@ -178,4 +178,4 @@ namespace epee strm << make_indent(indent) << "}"; } } -} \ No newline at end of file +} diff --git a/contrib/epee/include/storages/portable_storage_val_converters.h b/contrib/epee/include/storages/portable_storage_val_converters.h index 6ea505886..e9b91c82b 100644 --- a/contrib/epee/include/storages/portable_storage_val_converters.h +++ b/contrib/epee/include/storages/portable_storage_val_converters.h @@ -166,4 +166,4 @@ POP_WARNINGS convert_to_same::value>::convert(from, to); } } -} \ No newline at end of file +} diff --git a/contrib/epee/include/time_helper.h b/contrib/epee/include/time_helper.h index 958176da6..244b35800 100644 --- a/contrib/epee/include/time_helper.h +++ b/contrib/epee/include/time_helper.h @@ -156,4 +156,4 @@ PRAGMA_WARNING_POP #endif } -} \ No newline at end of file +} diff --git a/contrib/epee/include/warnings.h b/contrib/epee/include/warnings.h index 37d7a2900..df5c7d1db 100644 --- a/contrib/epee/include/warnings.h +++ b/contrib/epee/include/warnings.h @@ -27,4 +27,4 @@ #define DISABLE_GCC_AND_CLANG_WARNING(w) _Pragma(BOOST_PP_STRINGIZE(GCC diagnostic ignored BOOST_PP_STRINGIZE(-W##w))) -#endif \ No newline at end of file +#endif diff --git a/contrib/epee/tests/data/storages/invalid_storage_1.bin b/contrib/epee/tests/data/storages/invalid_storage_1.bin index fac7b3e97..f64bef38e 100644 Binary files a/contrib/epee/tests/data/storages/invalid_storage_1.bin and b/contrib/epee/tests/data/storages/invalid_storage_1.bin differ diff --git a/contrib/epee/tests/data/storages/invalid_storage_3.bin b/contrib/epee/tests/data/storages/invalid_storage_3.bin index b5c31aa05..4233bf25c 100644 --- a/contrib/epee/tests/data/storages/invalid_storage_3.bin +++ b/contrib/epee/tests/data/storages/invalid_storage_3.bin @@ -1 +1 @@ -¢IMóÙŸˆm_bo \ No newline at end of file +¢IMóÙŸˆm_bo diff --git a/contrib/epee/tests/data/storages/invalid_storage_4.bin b/contrib/epee/tests/data/storages/invalid_storage_4.bin index 4f8372d19..69017244a 100644 Binary files a/contrib/epee/tests/data/storages/invalid_storage_4.bin and b/contrib/epee/tests/data/storages/invalid_storage_4.bin differ diff --git a/contrib/epee/tests/data/storages/valid_storage.bin b/contrib/epee/tests/data/storages/valid_storage.bin index e13f780b1..2af0abf50 100644 Binary files a/contrib/epee/tests/data/storages/valid_storage.bin and b/contrib/epee/tests/data/storages/valid_storage.bin differ diff --git a/contrib/epee/tests/generate_vc_proj.bat b/contrib/epee/tests/generate_vc_proj.bat index a81bdce05..2b3fee953 100644 --- a/contrib/epee/tests/generate_vc_proj.bat +++ b/contrib/epee/tests/generate_vc_proj.bat @@ -2,4 +2,4 @@ mkdir build cd build cmake "-DBoost_USE_STATIC_LIBS=TRUE" -G "Visual Studio 11 Win64" ../src cd .. -pause \ No newline at end of file +pause diff --git a/contrib/epee/tests/src/net/test_net.h b/contrib/epee/tests/src/net/test_net.h index 0b6dc1f73..5b21036bb 100644 --- a/contrib/epee/tests/src/net/test_net.h +++ b/contrib/epee/tests/src/net/test_net.h @@ -400,4 +400,4 @@ namespace tests } } -} \ No newline at end of file +} diff --git a/contrib/epee/tests/src/storages/portable_storages_test.h b/contrib/epee/tests/src/storages/portable_storages_test.h index ecded8dad..89f217d95 100644 --- a/contrib/epee/tests/src/storages/portable_storages_test.h +++ b/contrib/epee/tests/src/storages/portable_storages_test.h @@ -229,4 +229,4 @@ namespace epee } } -} \ No newline at end of file +} diff --git a/contrib/epee/tests/src/tests.cpp b/contrib/epee/tests/src/tests.cpp index ed045d833..8d61334cc 100644 --- a/contrib/epee/tests/src/tests.cpp +++ b/contrib/epee/tests/src/tests.cpp @@ -56,4 +56,4 @@ int main(int argc, char* argv[]) tests::test_portable_storages(tests_data_path); } return 1; -} \ No newline at end of file +} diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 000c1edb2..30d79932f 100755 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, The Monero Project +# Copyright (c) 2014-2015, The Monero Project # # All rights reserved. # @@ -38,14 +38,14 @@ find_package(MiniUpnpc QUIET) # FreeBSD doesn't play well with the local copy, so default to using shared -SET(USE_SHARED_MINIUPNPC false) +set(USE_SHARED_MINIUPNPC false) # If we have the correct shared version and we're not building static, use it -IF(STATIC) - SET(USE_SHARED_MINIUPNPC false) -ELSEIF(MINIUPNP_FOUND AND MINIUPNPC_VERSION_1_7_OR_HIGHER) - SET(USE_SHARED_MINIUPNPC true) -ENDIF() +if(STATIC) + set(USE_SHARED_MINIUPNPC false) +elseif(MINIUPNP_FOUND AND MINIUPNPC_VERSION_1_7_OR_HIGHER) + set(USE_SHARED_MINIUPNPC true) +endif() if(USE_SHARED_MINIUPNPC) message(STATUS "Using shared miniupnpc found at ${MINIUPNP_INCLUDE_DIR}") @@ -59,7 +59,7 @@ else() else() message(STATUS "Using miniupnpc from local source tree (/external/miniupnpc)") endif() - + set(UPNPC_BUILD_STATIC ON CACHE BOOL "Build static library") set(UPNPC_BUILD_SHARED OFF CACHE BOOL "Build shared library") set(UPNPC_BUILD_TESTS OFF CACHE BOOL "Build test executables") @@ -78,103 +78,26 @@ endif() find_package(Unbound) -IF(!UNBOUND_INCLUDE_DIR OR STATIC) - if(STATIC) - message(STATUS "Using libunbound from local source tree for static build") - else() - message(STATUS "Using libunbound from local source tree (/external/unbound)") - endif() - - INCLUDE(ExternalProject) - - FIND_PACKAGE(OpenSSL QUIET) - IF(!OPENSSL_LIBRARIES) - MESSAGE(FATAL_ERROR "${BoldRed}Could not find the openssl library. Please make sure you have installed openssl or libssl-dev or the equivalent${ColourReset}") - ELSE() - MESSAGE(STATUS "Found openssl libraries") - ENDIF() +if(NOT UNBOUND_INCLUDE_DIR OR STATIC) + add_subdirectory(unbound) - FIND_PACKAGE(Expat QUIET) - IF(!EXPAT_LIBRARIES) - MESSAGE(FATAL_ERROR "${BoldRed}Could not find the expat library. Please make sure you have installed libexpat or libexpat-dev or the equivalent${ColourReset}") - ELSE() - MESSAGE(STATUS "Found expat libraries") - ENDIF() - - IF(MINGW) - set(ENV{USE_WINSOCK} 1) - set(ENV{CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) - set(ENV{GCC_PREFIX} ${GCC_PREFIX}) - set(ENV{CMAKE_FIND_ROOT_PATH} ${CMAKE_FIND_ROOT_PATH}) - EXTERNALPROJECT_ADD( - libunbound - PREFIX ${CMAKE_CURRENT_BINARY_DIR}/unbound - URL ${CMAKE_CURRENT_SOURCE_DIR}/unbound/ - CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/unbound/monero-config.sh - BUILD_COMMAND $(MAKE) - UPDATE_COMMAND "" - PATCH_COMMAND "" - INSTALL_COMMAND ${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build/libtool --mode=install cp ${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build/libunbound.la ${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build - LOG_DOWNLOAD 1 - LOG_UPDATE 1 - LOG_CONFIGURE 1 - LOG_BUILD 1 - LOG_TEST 1 - LOG_INSTALL 1 - ) - ELSEIF(APPLE) - execute_process(COMMAND brew --prefix OUTPUT_VARIABLE BREW_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE) - EXTERNALPROJECT_ADD( - libunbound - PREFIX ${CMAKE_CURRENT_BINARY_DIR}/unbound - URL ${CMAKE_CURRENT_SOURCE_DIR}/unbound/ - CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/unbound/configure --prefix=${BREW_PREFIX} --enable-shared --enable-static --disable-gost --disable-rpath --with-libevent=no --without-pyunbound --without-pythonmodule --without-pthreads --with-libunbound-only - BUILD_COMMAND $(MAKE) - UPDATE_COMMAND "" - PATCH_COMMAND "" - INSTALL_COMMAND ${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build/libtool --mode=install cp ${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build/libunbound.la ${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build - LOG_DOWNLOAD 1 - LOG_UPDATE 1 - LOG_CONFIGURE 1 - LOG_BUILD 1 - LOG_TEST 1 - LOG_INSTALL 1 - ) - ELSE() - EXTERNALPROJECT_ADD( - libunbound - PREFIX ${CMAKE_CURRENT_BINARY_DIR}/unbound - URL ${CMAKE_CURRENT_SOURCE_DIR}/unbound/ - CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/unbound/configure --disable-shared --enable-static --disable-gost --disable-rpath --with-libevent=no --without-pyunbound --without-pythonmodule --without-pthreads --with-libunbound-only - BUILD_COMMAND $(MAKE) - UPDATE_COMMAND "" - PATCH_COMMAND "" - INSTALL_COMMAND ${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build/libtool --mode=install cp ${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build/libunbound.la ${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build - LOG_DOWNLOAD 1 - LOG_UPDATE 1 - LOG_CONFIGURE 1 - LOG_BUILD 1 - LOG_TEST 1 - LOG_INSTALL 1 - ) - ENDIF() - set(UNBOUND_STATIC true PARENT_SCOPE) - set(UNBOUND_INCLUDE "${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build" PARENT_SCOPE) - set(UNBOUND_LIBRARY "${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build/libunbound.a;${OPENSSL_LIBRARIES}" PARENT_SCOPE) -ELSE() - MESSAGE(STATUS "Found libunbound include (unbound.h) in ${UNBOUND_INCLUDE_DIR}") - IF(UNBOUND_LIBRARIES) - MESSAGE(STATUS "Found libunbound shared library") + set(UNBOUND_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/unbound/libunbound" PARENT_SCOPE) + set(UNBOUND_LIBRARY "unbound" PARENT_SCOPE) + set(UNBOUND_LIBRARY_DIRS "${LIBEVENT2_LIBDIR}" PARENT_SCOPE) +else() + message(STATUS "Found libunbound include (unbound.h) in ${UNBOUND_INCLUDE_DIR}") + if(UNBOUND_LIBRARIES) + message(STATUS "Found libunbound shared library") set(UNBOUND_STATIC false PARENT_SCOPE) set(UNBOUND_INCLUDE ${UNBOUND_INCLUDE_DIR} PARENT_SCOPE) set(UNBOUND_LIBRARY ${UNBOUND_LIBRARIES} PARENT_SCOPE) - ELSE() - MESSAGE(FATAL_ERROR "${BoldRed}Found libunbound includes, but could not find libunbound library. Please make sure you have installed libunbound or libunbound-dev or the equivalent${ColourReset}") - ENDIF() -ENDIF() + set(UNBOUND_LIBRARY_DIRS "" PARENT_SCOPE) + else() + die("Found libunbound includes, but could not find libunbound library. Please make sure you have installed libunbound or libunbound-dev or the equivalent") + endif() +endif() set(NET_SKELETON_SRCS net_skeleton/net_skeleton.c) add_library(net_skeleton ${NET_SKELETON_SRCS}) set(NET_SKELETON_LIBRARY "${CMAKE_CURRENT_BINARY_DIR}/libnet_skeleton.a" PARENT_SCOPE) - diff --git a/external/miniupnpc/CMakeLists.txt b/external/miniupnpc/CMakeLists.txt index 5e4a90bbf..bed9a3d22 100644 --- a/external/miniupnpc/CMakeLists.txt +++ b/external/miniupnpc/CMakeLists.txt @@ -4,64 +4,27 @@ project (miniupnpc C) set (MINIUPNPC_VERSION 1.9) set (MINIUPNPC_API_VERSION 10) -if (NOT CMAKE_BUILD_TYPE) - if (WIN32) - set (DEFAULT_BUILD_TYPE MinSizeRel) - else (WIN32) - set (DEFAULT_BUILD_TYPE RelWithDebInfo) - endif(WIN32) - set (CMAKE_BUILD_TYPE ${DEFAULT_BUILD_TYPE} CACHE STRING - "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." - FORCE) -endif() - option (UPNPC_BUILD_STATIC "Build static library" TRUE) option (UPNPC_BUILD_SHARED "Build shared library" TRUE) -if (NOT WIN32) - option (UPNPC_BUILD_TESTS "Build test executables" TRUE) -endif (NOT WIN32) option (NO_GETADDRINFO "Define NO_GETADDRINFO" FALSE) mark_as_advanced (NO_GETADDRINFO) if (NO_GETADDRINFO) add_definitions (-DNO_GETADDRINFO) -endif (NO_GETADDRINFO) +endif () if (NOT WIN32) add_definitions (-DMINIUPNPC_SET_SOCKET_TIMEOUT) - add_definitions (-D_BSD_SOURCE -D_POSIX_C_SOURCE=1) -else (NOT WIN32) + add_definitions (-D_BSD_SOURCE -D_POSIX_C_SOURCE=201112) +else () add_definitions (-D_WIN32_WINNT=0x0501) # XP or higher for getnameinfo and friends -endif (NOT WIN32) +endif () if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") add_definitions (-D_DARWIN_C_SOURCE) endif () -# Set compiler specific build flags -if (CMAKE_COMPILER_IS_GNUC) - # Set our own default flags at first run. - if (NOT CONFIGURED) - - if (NOT CMAKE_SYSTEM_NAME STREQUAL "AmigaOS") - set (_PIC -fPIC) - endif (CMAKE_SYSTEM_NAME STREQUAL "AmigaOS") - - set (CMAKE_C_FLAGS "${_PIC} -Wall $ENV{CFLAGS}" # CMAKE_C_FLAGS gets appended to the other C flags - CACHE STRING "Flags used by the C compiler during normal builds." FORCE) - set (CMAKE_C_FLAGS_DEBUG "-g -DDDEBUG" - CACHE STRING "Flags used by the C compiler during debug builds." FORCE) - set (CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG" - CACHE STRING "Flags used by the C compiler during release builds." FORCE) - set (CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g -DNDEBUG" - CACHE STRING "Flags used by the C compiler during release builds." FORCE) - set (CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG" - CACHE STRING "Flags used by the C compiler during release builds." FORCE) - - endif (NOT CONFIGURED) -endif () - configure_file (miniupnpcstrings.h.cmake ${CMAKE_BINARY_DIR}/miniupnpcstrings.h) include_directories (${CMAKE_BINARY_DIR}) @@ -80,16 +43,16 @@ set (MINIUPNPC_SOURCES receivedata.c ) -if (NOT WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "AmigaOS") +if (NOT WIN32) set (MINIUPNPC_SOURCES ${MINIUPNPC_SOURCES} minissdpc.c) -endif (NOT WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "AmigaOS") +endif () if (WIN32) set_source_files_properties (${MINIUPNPC_SOURCES} PROPERTIES COMPILE_DEFINITIONS MINIUPNP_STATICLIB COMPILE_DEFINITIONS MINIUPNP_EXPORTS ) -endif (WIN32) +endif () if (WIN32) # find_library (WINSOCK2_LIBRARY NAMES ws2_32 WS2_32 Ws2_32) @@ -97,63 +60,31 @@ if (WIN32) set(WINSOCK2_LIBRARY ws2_32) set(IPHLPAPI_LIBRARY iphlpapi) set (LDLIBS ${WINSOCK2_LIBRARY} ${IPHLPAPI_LIBRARY} ${LDLIBS}) -#elseif (CMAKE_SYSTEM_NAME STREQUAL "Solaris") -# find_library (SOCKET_LIBRARY NAMES socket) -# find_library (NSL_LIBRARY NAMES nsl) -# find_library (RESOLV_LIBRARY NAMES resolv) -# set (LDLIBS ${SOCKET_LIBRARY} ${NSL_LIBRARY} ${RESOLV_LIBRARY} ${LDLIBS}) -endif (WIN32) +endif () if (NOT UPNPC_BUILD_STATIC AND NOT UPNPC_BUILD_SHARED) - message (FATAL "Both shared and static libraries are disabled!") -endif (NOT UPNPC_BUILD_STATIC AND NOT UPNPC_BUILD_SHARED) + message (FATAL "Both shared and static libraries are disabled!") +endif () if (UPNPC_BUILD_STATIC) add_library (upnpc-static STATIC ${MINIUPNPC_SOURCES}) + set_target_properties (upnpc-static PROPERTIES POSITION_INDEPENDENT_CODE TRUE) set_target_properties (upnpc-static PROPERTIES OUTPUT_NAME "miniupnpc") target_link_libraries (upnpc-static ${LDLIBS}) set (UPNPC_INSTALL_TARGETS ${UPNPC_INSTALL_TARGETS} upnpc-static) set (UPNPC_LIBRARY_TARGET upnpc-static) -endif (UPNPC_BUILD_STATIC) +endif () if (UPNPC_BUILD_SHARED) add_library (upnpc-shared SHARED ${MINIUPNPC_SOURCES}) + set_target_properties (upnpc-shared PROPERTIES POSITION_INDEPENDENT_CODE TRUE) set_target_properties (upnpc-shared PROPERTIES OUTPUT_NAME "miniupnpc") set_target_properties (upnpc-shared PROPERTIES VERSION ${MINIUPNPC_VERSION}) set_target_properties (upnpc-shared PROPERTIES SOVERSION ${MINIUPNPC_API_VERSION}) target_link_libraries (upnpc-shared ${LDLIBS}) set (UPNPC_INSTALL_TARGETS ${UPNPC_INSTALL_TARGETS} upnpc-shared) set (UPNPC_LIBRARY_TARGET upnpc-shared) -endif (UPNPC_BUILD_SHARED) - -if (UPNPC_BUILD_TESTS) - add_executable (testminixml testminixml.c minixml.c igd_desc_parse.c) - target_link_libraries (testminixml ${LDLIBS}) - - add_executable (minixmlvalid minixmlvalid.c minixml.c) - target_link_libraries (minixmlvalid ${LDLIBS}) - - add_executable (testupnpreplyparse testupnpreplyparse.c - minixml.c upnpreplyparse.c) - target_link_libraries (testupnpreplyparse ${LDLIBS}) - - add_executable (testigddescparse testigddescparse.c - igd_desc_parse.c minixml.c miniupnpc.c miniwget.c minissdpc.c - upnpcommands.c upnpreplyparse.c minisoap.c connecthostport.c - portlistingparse.c receivedata.c - ) - target_link_libraries (testigddescparse ${LDLIBS}) - - add_executable (testminiwget testminiwget.c - miniwget.c miniupnpc.c minisoap.c upnpcommands.c minissdpc.c - upnpreplyparse.c minixml.c igd_desc_parse.c connecthostport.c - portlistingparse.c receivedata.c - ) - target_link_libraries (testminiwget ${LDLIBS}) - -# set (UPNPC_INSTALL_TARGETS ${UPNPC_INSTALL_TARGETS} testminixml minixmlvalid testupnpreplyparse testigddescparse testminiwget) -endif (UPNPC_BUILD_TESTS) - +endif () install (TARGETS ${UPNPC_INSTALL_TARGETS} RUNTIME DESTINATION bin @@ -161,7 +92,7 @@ install (TARGETS ${UPNPC_INSTALL_TARGETS} ARCHIVE DESTINATION lib${LIB_SUFFIX} ) install (FILES - miniupnpc.h + miniupnpc.h miniwget.h upnpcommands.h igd_desc_parse.h @@ -173,6 +104,4 @@ install (FILES DESTINATION include/miniupnpc ) -set (CONFIGURED YES CACHE INTERNAL "") - # vim: ts=2:sw=2 diff --git a/external/rapidjson/allocators.h b/external/rapidjson/allocators.h new file mode 100644 index 000000000..c99485e50 --- /dev/null +++ b/external/rapidjson/allocators.h @@ -0,0 +1,246 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_ALLOCATORS_H_ +#define RAPIDJSON_ALLOCATORS_H_ + +#include "rapidjson.h" + +namespace rapidjson { + +/////////////////////////////////////////////////////////////////////////////// +// Allocator + +/*! \class rapidjson::Allocator + \brief Concept for allocating, resizing and freeing memory block. + + Note that Malloc() and Realloc() are non-static but Free() is static. + + So if an allocator need to support Free(), it needs to put its pointer in + the header of memory block. + +\code +concept Allocator { + static const bool kNeedFree; //!< Whether this allocator needs to call Free(). + + // Allocate a memory block. + // \param size of the memory block in bytes. + // \returns pointer to the memory block. + void* Malloc(size_t size); + + // Resize a memory block. + // \param originalPtr The pointer to current memory block. Null pointer is permitted. + // \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.) + // \param newSize the new size in bytes. + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize); + + // Free a memory block. + // \param pointer to the memory block. Null pointer is permitted. + static void Free(void *ptr); +}; +\endcode +*/ + +/////////////////////////////////////////////////////////////////////////////// +// CrtAllocator + +//! C-runtime library allocator. +/*! This class is just wrapper for standard C library memory routines. + \note implements Allocator concept +*/ +class CrtAllocator { +public: + static const bool kNeedFree = true; + void* Malloc(size_t size) { return std::malloc(size); } + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { (void)originalSize; return std::realloc(originalPtr, newSize); } + static void Free(void *ptr) { std::free(ptr); } +}; + +/////////////////////////////////////////////////////////////////////////////// +// MemoryPoolAllocator + +//! Default memory allocator used by the parser and DOM. +/*! This allocator allocate memory blocks from pre-allocated memory chunks. + + It does not free memory blocks. And Realloc() only allocate new memory. + + The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default. + + User may also supply a buffer as the first chunk. + + If the user-buffer is full then additional chunks are allocated by BaseAllocator. + + The user-buffer is not deallocated by this allocator. + + \tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator. + \note implements Allocator concept +*/ +template +class MemoryPoolAllocator { +public: + static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator) + + //! Constructor with chunkSize. + /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. + \param baseAllocator The allocator for allocating memory chunks. + */ + MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : + chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0) + { + if (!baseAllocator_) + ownBaseAllocator_ = baseAllocator_ = new BaseAllocator(); + AddChunk(chunk_capacity_); + } + + //! Constructor with user-supplied buffer. + /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size. + + The user buffer will not be deallocated when this allocator is destructed. + + \param buffer User supplied buffer. + \param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader). + \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. + \param baseAllocator The allocator for allocating memory chunks. + */ + MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : + chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0) + { + RAPIDJSON_ASSERT(buffer != 0); + RAPIDJSON_ASSERT(size > sizeof(ChunkHeader)); + chunkHead_ = reinterpret_cast(buffer); + chunkHead_->capacity = size - sizeof(ChunkHeader); + chunkHead_->size = 0; + chunkHead_->next = 0; + } + + //! Destructor. + /*! This deallocates all memory chunks, excluding the user-supplied buffer. + */ + ~MemoryPoolAllocator() { + Clear(); + delete ownBaseAllocator_; + } + + //! Deallocates all memory chunks, excluding the user-supplied buffer. + void Clear() { + while(chunkHead_ != 0 && chunkHead_ != userBuffer_) { + ChunkHeader* next = chunkHead_->next; + baseAllocator_->Free(chunkHead_); + chunkHead_ = next; + } + } + + //! Computes the total capacity of allocated memory chunks. + /*! \return total capacity in bytes. + */ + size_t Capacity() const { + size_t capacity = 0; + for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) + capacity += c->capacity; + return capacity; + } + + //! Computes the memory blocks allocated. + /*! \return total used bytes. + */ + size_t Size() const { + size_t size = 0; + for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) + size += c->size; + return size; + } + + //! Allocates a memory block. (concept Allocator) + void* Malloc(size_t size) { + size = RAPIDJSON_ALIGN(size); + if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity) + AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size); + + void *buffer = reinterpret_cast(chunkHead_ + 1) + chunkHead_->size; + chunkHead_->size += size; + return buffer; + } + + //! Resizes a memory block (concept Allocator) + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { + if (originalPtr == 0) + return Malloc(newSize); + + // Do not shrink if new size is smaller than original + if (originalSize >= newSize) + return originalPtr; + + // Simply expand it if it is the last allocation and there is sufficient space + if (originalPtr == (char *)(chunkHead_ + 1) + chunkHead_->size - originalSize) { + size_t increment = static_cast(newSize - originalSize); + increment = RAPIDJSON_ALIGN(increment); + if (chunkHead_->size + increment <= chunkHead_->capacity) { + chunkHead_->size += increment; + return originalPtr; + } + } + + // Realloc process: allocate and copy memory, do not free original buffer. + void* newBuffer = Malloc(newSize); + RAPIDJSON_ASSERT(newBuffer != 0); // Do not handle out-of-memory explicitly. + return std::memcpy(newBuffer, originalPtr, originalSize); + } + + //! Frees a memory block (concept Allocator) + static void Free(void *ptr) { (void)ptr; } // Do nothing + +private: + //! Copy constructor is not permitted. + MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */; + //! Copy assignment operator is not permitted. + MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */; + + //! Creates a new chunk. + /*! \param capacity Capacity of the chunk in bytes. + */ + void AddChunk(size_t capacity) { + ChunkHeader* chunk = reinterpret_cast(baseAllocator_->Malloc(sizeof(ChunkHeader) + capacity)); + chunk->capacity = capacity; + chunk->size = 0; + chunk->next = chunkHead_; + chunkHead_ = chunk; + } + + static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity. + + //! Chunk header for perpending to each chunk. + /*! Chunks are stored as a singly linked list. + */ + struct ChunkHeader { + size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself). + size_t size; //!< Current size of allocated memory in bytes. + ChunkHeader *next; //!< Next chunk in the linked list. + }; + + ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation. + size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated. + void *userBuffer_; //!< User supplied buffer. + BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks. + BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object. +}; + +} // namespace rapidjson + +#endif // RAPIDJSON_ENCODINGS_H_ diff --git a/external/rapidjson/document.h b/external/rapidjson/document.h new file mode 100644 index 000000000..ea161ceed --- /dev/null +++ b/external/rapidjson/document.h @@ -0,0 +1,1863 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_DOCUMENT_H_ +#define RAPIDJSON_DOCUMENT_H_ + +/*! \file document.h */ + +#include "reader.h" +#include "internal/meta.h" +#include "internal/strfunc.h" +#include "memorystream.h" +#include "encodedstream.h" +#include // placement new + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +#elif defined(__GNUC__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_HAS_STDSTRING + +#ifndef RAPIDJSON_HAS_STDSTRING +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation +#else +#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default +#endif +/*! \def RAPIDJSON_HAS_STDSTRING + \ingroup RAPIDJSON_CONFIG + \brief Enable RapidJSON support for \c std::string + + By defining this preprocessor symbol to \c 1, several convenience functions for using + \ref rapidjson::GenericValue with \c std::string are enabled, especially + for construction and comparison. + + \hideinitializer +*/ +#include +#endif // RAPIDJSON_HAS_STDSTRING + +#ifndef RAPIDJSON_NOMEMBERITERATORCLASS +#include // std::iterator, std::random_access_iterator_tag +#endif + +namespace rapidjson { + +// Forward declaration. +template +class GenericValue; + +//! Name-value pair in a JSON object value. +/*! + This class was internal to GenericValue. It used to be a inner struct. + But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct. + https://code.google.com/p/rapidjson/issues/detail?id=64 +*/ +template +struct GenericMember { + GenericValue name; //!< name of member (must be a string) + GenericValue value; //!< value of member. +}; + +/////////////////////////////////////////////////////////////////////////////// +// GenericMemberIterator + +#ifndef RAPIDJSON_NOMEMBERITERATORCLASS + +//! (Constant) member iterator for a JSON object value +/*! + \tparam Const Is this a constant iterator? + \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) + \tparam Allocator Allocator type for allocating memory of object, array and string. + + This class implements a Random Access Iterator for GenericMember elements + of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements]. + + \note This iterator implementation is mainly intended to avoid implicit + conversions from iterator values to \c NULL, + e.g. from GenericValue::FindMember. + + \note Define \c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a + pointer-based implementation, if your platform doesn't provide + the C++ header. + + \see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator + */ +template +class GenericMemberIterator + : public std::iterator >::Type> { + + friend class GenericValue; + template friend class GenericMemberIterator; + + typedef GenericMember PlainType; + typedef typename internal::MaybeAddConst::Type ValueType; + typedef std::iterator BaseType; + +public: + //! Iterator type itself + typedef GenericMemberIterator Iterator; + //! Constant iterator type + typedef GenericMemberIterator ConstIterator; + //! Non-constant iterator type + typedef GenericMemberIterator NonConstIterator; + + //! Pointer to (const) GenericMember + typedef typename BaseType::pointer Pointer; + //! Reference to (const) GenericMember + typedef typename BaseType::reference Reference; + //! Signed integer type (e.g. \c ptrdiff_t) + typedef typename BaseType::difference_type DifferenceType; + + //! Default constructor (singular value) + /*! Creates an iterator pointing to no element. + \note All operations, except for comparisons, are undefined on such values. + */ + GenericMemberIterator() : ptr_() {} + + //! Iterator conversions to more const + /*! + \param it (Non-const) iterator to copy from + + Allows the creation of an iterator from another GenericMemberIterator + that is "less const". Especially, creating a non-constant iterator + from a constant iterator are disabled: + \li const -> non-const (not ok) + \li const -> const (ok) + \li non-const -> const (ok) + \li non-const -> non-const (ok) + + \note If the \c Const template parameter is already \c false, this + constructor effectively defines a regular copy-constructor. + Otherwise, the copy constructor is implicitly defined. + */ + GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {} + + //! @name stepping + //@{ + Iterator& operator++(){ ++ptr_; return *this; } + Iterator& operator--(){ --ptr_; return *this; } + Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; } + Iterator operator--(int){ Iterator old(*this); --ptr_; return old; } + //@} + + //! @name increment/decrement + //@{ + Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); } + Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); } + + Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; } + Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; } + //@} + + //! @name relations + //@{ + bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; } + bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; } + bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; } + bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; } + bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; } + bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; } + //@} + + //! @name dereference + //@{ + Reference operator*() const { return *ptr_; } + Pointer operator->() const { return ptr_; } + Reference operator[](DifferenceType n) const { return ptr_[n]; } + //@} + + //! Distance + DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; } + +private: + //! Internal constructor from plain pointer + explicit GenericMemberIterator(Pointer p) : ptr_(p) {} + + Pointer ptr_; //!< raw pointer +}; + +#else // RAPIDJSON_NOMEMBERITERATORCLASS + +// class-based member iterator implementation disabled, use plain pointers + +template +struct GenericMemberIterator; + +//! non-const GenericMemberIterator +template +struct GenericMemberIterator { + //! use plain pointer as iterator type + typedef GenericMember* Iterator; +}; +//! const GenericMemberIterator +template +struct GenericMemberIterator { + //! use plain const pointer as iterator type + typedef const GenericMember* Iterator; +}; + +#endif // RAPIDJSON_NOMEMBERITERATORCLASS + +/////////////////////////////////////////////////////////////////////////////// +// GenericStringRef + +//! Reference to a constant string (not taking a copy) +/*! + \tparam CharType character type of the string + + This helper class is used to automatically infer constant string + references for string literals, especially from \c const \b (!) + character arrays. + + The main use is for creating JSON string values without copying the + source string via an \ref Allocator. This requires that the referenced + string pointers have a sufficient lifetime, which exceeds the lifetime + of the associated GenericValue. + + \b Example + \code + Value v("foo"); // ok, no need to copy & calculate length + const char foo[] = "foo"; + v.SetString(foo); // ok + + const char* bar = foo; + // Value x(bar); // not ok, can't rely on bar's lifetime + Value x(StringRef(bar)); // lifetime explicitly guaranteed by user + Value y(StringRef(bar, 3)); // ok, explicitly pass length + \endcode + + \see StringRef, GenericValue::SetString +*/ +template +struct GenericStringRef { + typedef CharType Ch; //!< character type of the string + + //! Create string reference from \c const character array + /*! + This constructor implicitly creates a constant string reference from + a \c const character array. It has better performance than + \ref StringRef(const CharType*) by inferring the string \ref length + from the array length, and also supports strings containing null + characters. + + \tparam N length of the string, automatically inferred + + \param str Constant character array, lifetime assumed to be longer + than the use of the string in e.g. a GenericValue + + \post \ref s == str + + \note Constant complexity. + \note There is a hidden, private overload to disallow references to + non-const character arrays to be created via this constructor. + By this, e.g. function-scope arrays used to be filled via + \c snprintf are excluded from consideration. + In such cases, the referenced string should be \b copied to the + GenericValue instead. + */ + template + GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT + : s(str), length(N-1) {} + + //! Explicitly create string reference from \c const character pointer + /*! + This constructor can be used to \b explicitly create a reference to + a constant string pointer. + + \see StringRef(const CharType*) + + \param str Constant character pointer, lifetime assumed to be longer + than the use of the string in e.g. a GenericValue + + \post \ref s == str + + \note There is a hidden, private overload to disallow references to + non-const character arrays to be created via this constructor. + By this, e.g. function-scope arrays used to be filled via + \c snprintf are excluded from consideration. + In such cases, the referenced string should be \b copied to the + GenericValue instead. + */ + explicit GenericStringRef(const CharType* str) + : s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != NULL); } + + //! Create constant string reference from pointer and length + /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \param len length of the string, excluding the trailing NULL terminator + + \post \ref s == str && \ref length == len + \note Constant complexity. + */ + GenericStringRef(const CharType* str, SizeType len) + : s(str), length(len) { RAPIDJSON_ASSERT(s != NULL); } + + //! implicit conversion to plain CharType pointer + operator const Ch *() const { return s; } + + const Ch* const s; //!< plain CharType pointer + const SizeType length; //!< length of the string (excluding the trailing NULL terminator) + +private: + //! Disallow copy-assignment + GenericStringRef operator=(const GenericStringRef&); + //! Disallow construction from non-const array + template + GenericStringRef(CharType (&str)[N]) /* = delete */; +}; + +//! Mark a character pointer as constant string +/*! Mark a plain character pointer as a "string literal". This function + can be used to avoid copying a character string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + \tparam CharType Character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \return GenericStringRef string reference object + \relatesalso GenericStringRef + + \see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember +*/ +template +inline GenericStringRef StringRef(const CharType* str) { + return GenericStringRef(str, internal::StrLen(str)); +} + +//! Mark a character pointer as constant string +/*! Mark a plain character pointer as a "string literal". This function + can be used to avoid copying a character string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + + This version has better performance with supplied length, and also + supports string containing null characters. + + \tparam CharType character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \param length The length of source string. + \return GenericStringRef string reference object + \relatesalso GenericStringRef +*/ +template +inline GenericStringRef StringRef(const CharType* str, size_t length) { + return GenericStringRef(str, SizeType(length)); +} + +#if RAPIDJSON_HAS_STDSTRING +//! Mark a string object as constant string +/*! Mark a string object (e.g. \c std::string) as a "string literal". + This function can be used to avoid copying a string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + + \tparam CharType character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \return GenericStringRef string reference object + \relatesalso GenericStringRef + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. +*/ +template +inline GenericStringRef StringRef(const std::basic_string& str) { + return GenericStringRef(str.data(), SizeType(str.size())); +} +#endif + +/////////////////////////////////////////////////////////////////////////////// +// GenericValue type traits +namespace internal { + +template +struct IsGenericValueImpl : FalseType {}; + +// select candidates according to nested encoding and allocator types +template struct IsGenericValueImpl::Type, typename Void::Type> + : IsBaseOf, T>::Type {}; + +// helper to match arbitrary GenericValue instantiations, including derived classes +template struct IsGenericValue : IsGenericValueImpl::Type {}; + +} // namespace internal + +/////////////////////////////////////////////////////////////////////////////// +// GenericValue + +//! Represents a JSON value. Use Value for UTF8 encoding and default allocator. +/*! + A JSON value can be one of 7 types. This class is a variant type supporting + these types. + + Use the Value if UTF8 and default allocator + + \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) + \tparam Allocator Allocator type for allocating memory of object, array and string. +*/ +template > +class GenericValue { +public: + //! Name-value pair in an object. + typedef GenericMember Member; + typedef Encoding EncodingType; //!< Encoding type from template parameter. + typedef Allocator AllocatorType; //!< Allocator type from template parameter. + typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. + typedef GenericStringRef StringRefType; //!< Reference to a constant string + typedef typename GenericMemberIterator::Iterator MemberIterator; //!< Member iterator for iterating in object. + typedef typename GenericMemberIterator::Iterator ConstMemberIterator; //!< Constant member iterator for iterating in object. + typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array. + typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array. + + //!@name Constructors and destructor. + //@{ + + //! Default constructor creates a null value. + GenericValue() RAPIDJSON_NOEXCEPT : data_(), flags_(kNullFlag) {} + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move constructor in C++11 + GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_), flags_(rhs.flags_) { + rhs.flags_ = kNullFlag; // give up contents + } +#endif + +private: + //! Copy constructor is not permitted. + GenericValue(const GenericValue& rhs); + +public: + + //! Constructor with JSON value type. + /*! This creates a Value of specified type with default content. + \param type Type of the value. + \note Default content for number is zero. + */ + GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_(), flags_() { + static const unsigned defaultFlags[7] = { + kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kConstStringFlag, + kNumberAnyFlag + }; + RAPIDJSON_ASSERT(type <= kNumberType); + flags_ = defaultFlags[type]; + } + + //! Explicit copy constructor (with allocator) + /*! Creates a copy of a Value by using the given Allocator + \tparam SourceAllocator allocator of \c rhs + \param rhs Value to copy from (read-only) + \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator(). + \see CopyFrom() + */ + template< typename SourceAllocator > + GenericValue(const GenericValue& rhs, Allocator & allocator); + + //! Constructor for boolean value. + /*! \param b Boolean value + \note This constructor is limited to \em real boolean values and rejects + implicitly converted types like arbitrary pointers. Use an explicit cast + to \c bool, if you want to construct a boolean JSON value in such cases. + */ +#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen + template + explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame))) RAPIDJSON_NOEXCEPT +#else + explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT +#endif + : data_(), flags_(b ? kTrueFlag : kFalseFlag) { + // safe-guard against failing SFINAE + RAPIDJSON_STATIC_ASSERT((internal::IsSame::Value)); + } + + //! Constructor for int value. + explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberIntFlag) { + data_.n.i64 = i; + if (i >= 0) + flags_ |= kUintFlag | kUint64Flag; + } + + //! Constructor for unsigned value. + explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberUintFlag) { + data_.n.u64 = u; + if (!(u & 0x80000000)) + flags_ |= kIntFlag | kInt64Flag; + } + + //! Constructor for int64_t value. + explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberInt64Flag) { + data_.n.i64 = i64; + if (i64 >= 0) { + flags_ |= kNumberUint64Flag; + if (!(static_cast(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) + flags_ |= kUintFlag; + if (!(static_cast(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + flags_ |= kIntFlag; + } + else if (i64 >= static_cast(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + flags_ |= kIntFlag; + } + + //! Constructor for uint64_t value. + explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberUint64Flag) { + data_.n.u64 = u64; + if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000))) + flags_ |= kInt64Flag; + if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) + flags_ |= kUintFlag; + if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + flags_ |= kIntFlag; + } + + //! Constructor for double value. + explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberDoubleFlag) { data_.n.d = d; } + + //! Constructor for constant string (i.e. do not make a copy of string) + GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_(), flags_() { SetStringRaw(StringRef(s, length)); } + + //! Constructor for constant string (i.e. do not make a copy of string) + explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_(), flags_() { SetStringRaw(s); } + + //! Constructor for copy-string (i.e. do make a copy of string) + GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s, length), allocator); } + + //! Constructor for copy-string (i.e. do make a copy of string) + GenericValue(const Ch*s, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s), allocator); } + +#if RAPIDJSON_HAS_STDSTRING + //! Constructor for copy-string from a string object (i.e. do make a copy of string) + /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + GenericValue(const std::basic_string& s, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s), allocator); } +#endif + + //! Destructor. + /*! Need to destruct elements of array, members of object, or copy-string. + */ + ~GenericValue() { + if (Allocator::kNeedFree) { // Shortcut by Allocator's trait + switch(flags_) { + case kArrayFlag: + for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v) + v->~GenericValue(); + Allocator::Free(data_.a.elements); + break; + + case kObjectFlag: + for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) + m->~Member(); + Allocator::Free(data_.o.members); + break; + + case kCopyStringFlag: + Allocator::Free(const_cast(data_.s.str)); + break; + + default: + break; // Do nothing for other types. + } + } + } + + //@} + + //!@name Assignment operators + //@{ + + //! Assignment with move semantics. + /*! \param rhs Source of the assignment. It will become a null value after assignment. + */ + GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT { + RAPIDJSON_ASSERT(this != &rhs); + this->~GenericValue(); + RawAssign(rhs); + return *this; + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move assignment in C++11 + GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT { + return *this = rhs.Move(); + } +#endif + + //! Assignment of constant string reference (no copy) + /*! \param str Constant string reference to be assigned + \note This overload is needed to avoid clashes with the generic primitive type assignment overload below. + \see GenericStringRef, operator=(T) + */ + GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT { + GenericValue s(str); + return *this = s; + } + + //! Assignment with primitive types. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param value The value to be assigned. + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref SetString(const Ch*, Allocator&) (for copying) or + \ref StringRef() (to explicitly mark the pointer as constant) instead. + All other pointer types would implicitly convert to \c bool, + use \ref SetBool() instead. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer), (GenericValue&)) + operator=(T value) { + GenericValue v(value); + return *this = v; + } + + //! Deep-copy assignment from Value + /*! Assigns a \b copy of the Value to the current Value object + \tparam SourceAllocator Allocator type of \c rhs + \param rhs Value to copy from (read-only) + \param allocator Allocator to use for copying + */ + template + GenericValue& CopyFrom(const GenericValue& rhs, Allocator& allocator) { + RAPIDJSON_ASSERT((void*)this != (void const*)&rhs); + this->~GenericValue(); + new (this) GenericValue(rhs, allocator); + return *this; + } + + //! Exchange the contents of this value with those of other. + /*! + \param other Another value. + \note Constant complexity. + */ + GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT { + GenericValue temp; + temp.RawAssign(*this); + RawAssign(other); + other.RawAssign(temp); + return *this; + } + + //! Prepare Value for move semantics + /*! \return *this */ + GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; } + //@} + + //!@name Equal-to and not-equal-to operators + //@{ + //! Equal-to operator + /*! + \note If an object contains duplicated named member, comparing equality with any object is always \c false. + \note Linear time complexity (number of all values in the subtree and total lengths of all strings). + */ + template + bool operator==(const GenericValue& rhs) const { + typedef GenericValue RhsType; + if (GetType() != rhs.GetType()) + return false; + + switch (GetType()) { + case kObjectType: // Warning: O(n^2) inner-loop + if (data_.o.size != rhs.data_.o.size) + return false; + for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) { + typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name); + if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value) + return false; + } + return true; + + case kArrayType: + if (data_.a.size != rhs.data_.a.size) + return false; + for (SizeType i = 0; i < data_.a.size; i++) + if ((*this)[i] != rhs[i]) + return false; + return true; + + case kStringType: + return StringEqual(rhs); + + case kNumberType: + if (IsDouble() || rhs.IsDouble()) + return GetDouble() == rhs.GetDouble(); // May convert one operand from integer to double. + else + return data_.n.u64 == rhs.data_.n.u64; + + default: // kTrueType, kFalseType, kNullType + return true; + } + } + + //! Equal-to operator with const C-string pointer + bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); } + +#if RAPIDJSON_HAS_STDSTRING + //! Equal-to operator with string object + /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + bool operator==(const std::basic_string& rhs) const { return *this == GenericValue(StringRef(rhs)); } +#endif + + //! Equal-to operator with primitive types + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false + */ + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr,internal::IsGenericValue >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); } + + //! Not-equal-to operator + /*! \return !(*this == rhs) + */ + template + bool operator!=(const GenericValue& rhs) const { return !(*this == rhs); } + + //! Not-equal-to operator with const C-string pointer + bool operator!=(const Ch* rhs) const { return !(*this == rhs); } + + //! Not-equal-to operator with arbitrary types + /*! \return !(*this == rhs) + */ + template RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); } + + //! Equal-to operator with arbitrary types (symmetric version) + /*! \return (rhs == lhs) + */ + template friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; } + + //! Not-Equal-to operator with arbitrary types (symmetric version) + /*! \return !(rhs == lhs) + */ + template friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); } + //@} + + //!@name Type + //@{ + + Type GetType() const { return static_cast(flags_ & kTypeMask); } + bool IsNull() const { return flags_ == kNullFlag; } + bool IsFalse() const { return flags_ == kFalseFlag; } + bool IsTrue() const { return flags_ == kTrueFlag; } + bool IsBool() const { return (flags_ & kBoolFlag) != 0; } + bool IsObject() const { return flags_ == kObjectFlag; } + bool IsArray() const { return flags_ == kArrayFlag; } + bool IsNumber() const { return (flags_ & kNumberFlag) != 0; } + bool IsInt() const { return (flags_ & kIntFlag) != 0; } + bool IsUint() const { return (flags_ & kUintFlag) != 0; } + bool IsInt64() const { return (flags_ & kInt64Flag) != 0; } + bool IsUint64() const { return (flags_ & kUint64Flag) != 0; } + bool IsDouble() const { return (flags_ & kDoubleFlag) != 0; } + bool IsString() const { return (flags_ & kStringFlag) != 0; } + + //@} + + //!@name Null + //@{ + + GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; } + + //@} + + //!@name Bool + //@{ + + bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return flags_ == kTrueFlag; } + //!< Set boolean value + /*! \post IsBool() == true */ + GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; } + + //@} + + //!@name Object + //@{ + + //! Set this value as an empty object. + /*! \post IsObject() == true */ + GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; } + + //! Get the number of members in the object. + SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; } + + //! Check whether the object is empty. + bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; } + + //! Get the value associated with the name. + /*! + \note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7. + Since 0.2, if the name is not correct, it will assert. + If user is unsure whether a member exists, user should use HasMember() first. + A better approach is to use FindMember(). + \note Linear time complexity. + */ + GenericValue& operator[](const Ch* name) { + GenericValue n(StringRef(name)); + return (*this)[n]; + } + const GenericValue& operator[](const Ch* name) const { return const_cast(*this)[name]; } + + // This version is faster because it does not need a StrLen(). + // It can also handle string with null character. + template + GenericValue& operator[](const GenericValue& name) { + MemberIterator member = FindMember(name); + if (member != MemberEnd()) + return member->value; + else { + RAPIDJSON_ASSERT(false); // see above note + static GenericValue NullValue; + return NullValue; + } + } + template + const GenericValue& operator[](const GenericValue& name) const { return const_cast(*this)[name]; } + + //! Const member iterator + /*! \pre IsObject() == true */ + ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(data_.o.members); } + //! Const \em past-the-end member iterator + /*! \pre IsObject() == true */ + ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(data_.o.members + data_.o.size); } + //! Member iterator + /*! \pre IsObject() == true */ + MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(data_.o.members); } + //! \em Past-the-end member iterator + /*! \pre IsObject() == true */ + MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(data_.o.members + data_.o.size); } + + //! Check whether a member exists in the object. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Whether a member with that name exists. + \note It is better to use FindMember() directly if you need the obtain the value as well. + \note Linear time complexity. + */ + bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); } + + //! Check whether a member exists in the object with GenericValue name. + /*! + This version is faster because it does not need a StrLen(). It can also handle string with null character. + \param name Member name to be searched. + \pre IsObject() == true + \return Whether a member with that name exists. + \note It is better to use FindMember() directly if you need the obtain the value as well. + \note Linear time complexity. + */ + template + bool HasMember(const GenericValue& name) const { return FindMember(name) != MemberEnd(); } + + //! Find member by name. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Iterator to member, if it exists. + Otherwise returns \ref MemberEnd(). + + \note Earlier versions of Rapidjson returned a \c NULL pointer, in case + the requested member doesn't exist. For consistency with e.g. + \c std::map, this has been changed to MemberEnd() now. + \note Linear time complexity. + */ + MemberIterator FindMember(const Ch* name) { + GenericValue n(StringRef(name)); + return FindMember(n); + } + + ConstMemberIterator FindMember(const Ch* name) const { return const_cast(*this).FindMember(name); } + + //! Find member by name. + /*! + This version is faster because it does not need a StrLen(). It can also handle string with null character. + \param name Member name to be searched. + \pre IsObject() == true + \return Iterator to member, if it exists. + Otherwise returns \ref MemberEnd(). + + \note Earlier versions of Rapidjson returned a \c NULL pointer, in case + the requested member doesn't exist. For consistency with e.g. + \c std::map, this has been changed to MemberEnd() now. + \note Linear time complexity. + */ + template + MemberIterator FindMember(const GenericValue& name) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(name.IsString()); + MemberIterator member = MemberBegin(); + for ( ; member != MemberEnd(); ++member) + if (name.StringEqual(member->name)) + break; + return member; + } + template ConstMemberIterator FindMember(const GenericValue& name) const { return const_cast(*this).FindMember(name); } + + //! Add a member (name-value pair) to the object. + /*! \param name A string value as name of member. + \param value Value of any type. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note The ownership of \c name and \c value will be transferred to this object on success. + \pre IsObject() && name.IsString() + \post name.IsNull() && value.IsNull() + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(name.IsString()); + + Object& o = data_.o; + if (o.size >= o.capacity) { + if (o.capacity == 0) { + o.capacity = kDefaultObjectCapacity; + o.members = reinterpret_cast(allocator.Malloc(o.capacity * sizeof(Member))); + } + else { + SizeType oldCapacity = o.capacity; + o.capacity += (oldCapacity + 1) / 2; // grow by factor 1.5 + o.members = reinterpret_cast(allocator.Realloc(o.members, oldCapacity * sizeof(Member), o.capacity * sizeof(Member))); + } + } + o.members[o.size].name.RawAssign(name); + o.members[o.size].value.RawAssign(value); + o.size++; + return *this; + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) { + GenericValue n(name); + return AddMember(n, value, allocator); + } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + + + //! Add a member (name-value pair) to the object. + /*! \param name A constant string reference as name of member. + \param value Value of any type. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note The ownership of \c value will be transferred to this object on success. + \pre IsObject() + \post value.IsNull() + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) { + GenericValue n(name); + return AddMember(n, value, allocator); + } + + //! Add a constant string value as member (name-value pair) to the object. + /*! \param name A constant string reference as name of member. + \param value constant string reference as value of member. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + \note This overload is needed to avoid clashes with the generic primitive type AddMember(StringRefType,T,Allocator&) overload below. + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) { + GenericValue v(value); + return AddMember(name, v, allocator); + } + + //! Add any primitive value as member (name-value pair) to the object. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param name A constant string reference as name of member. + \param value Value of primitive type \c T as value of member + \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref + AddMember(StringRefType, StringRefType, Allocator&). + All other pointer types would implicitly convert to \c bool, + use an explicit cast instead, if needed. + \note Amortized Constant time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericValue&)) + AddMember(StringRefType name, T value, Allocator& allocator) { + GenericValue n(name); + GenericValue v(value); + return AddMember(n, v, allocator); + } + + //! Remove all members in the object. + /*! This function do not deallocate memory in the object, i.e. the capacity is unchanged. + \note Linear time complexity. + */ + void RemoveAllMembers() { + RAPIDJSON_ASSERT(IsObject()); + for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) + m->~Member(); + data_.o.size = 0; + } + + //! Remove a member in object by its name. + /*! \param name Name of member to be removed. + \return Whether the member existed. + \note Removing member is implemented by moving the last member. So the ordering of members is changed. + \note Linear time complexity. + */ + bool RemoveMember(const Ch* name) { + GenericValue n(StringRef(name)); + return RemoveMember(n); + } + + template + bool RemoveMember(const GenericValue& name) { + MemberIterator m = FindMember(name); + if (m != MemberEnd()) { + RemoveMember(m); + return true; + } + else + return false; + } + + //! Remove a member in object by iterator. + /*! \param m member iterator (obtained by FindMember() or MemberBegin()). + \return the new iterator after removal. + \note Removing member is implemented by moving the last member. So the ordering of members is changed. + \note Use \ref EraseMember(ConstMemberIterator) instead, if you need to rely on a stable member ordering. + \note Constant time complexity. + */ + MemberIterator RemoveMember(MemberIterator m) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(data_.o.size > 0); + RAPIDJSON_ASSERT(data_.o.members != 0); + RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd()); + + MemberIterator last(data_.o.members + (data_.o.size - 1)); + if (data_.o.size > 1 && m != last) { + // Move the last one to this place + *m = *last; + } + else { + // Only one left, just destroy + m->~Member(); + } + --data_.o.size; + return m; + } + + //! Remove a member from an object by iterator. + /*! \param pos iterator to the member to remove + \pre IsObject() == true && \ref MemberBegin() <= \c pos < \ref MemberEnd() + \return Iterator following the removed element. + If the iterator \c pos refers to the last element, the \ref MemberEnd() iterator is returned. + \note Other than \ref RemoveMember(MemberIterator), this function preserves the ordering of the members. + \note Linear time complexity. + */ + MemberIterator EraseMember(ConstMemberIterator pos) { + return EraseMember(pos, pos +1); + } + + //! Remove members in the range [first, last) from an object. + /*! \param first iterator to the first member to remove + \param last iterator following the last member to remove + \pre IsObject() == true && \ref MemberBegin() <= \c first <= \c last <= \ref MemberEnd() + \return Iterator following the last removed element. + \note Other than \ref RemoveMember(MemberIterator), this function preserves the ordering of the members. + \note Linear time complexity. + */ + MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(data_.o.size > 0); + RAPIDJSON_ASSERT(data_.o.members != 0); + RAPIDJSON_ASSERT(first >= MemberBegin()); + RAPIDJSON_ASSERT(first <= last); + RAPIDJSON_ASSERT(last <= MemberEnd()); + + MemberIterator pos = MemberBegin() + (first - MemberBegin()); + for (MemberIterator itr = pos; itr != last; ++itr) + itr->~Member(); + std::memmove(&*pos, &*last, (MemberEnd() - last) * sizeof(Member)); + data_.o.size -= (last - first); + return pos; + } + + //@} + + //!@name Array + //@{ + + //! Set this value as an empty array. + /*! \post IsArray == true */ + GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; } + + //! Get the number of elements in array. + SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; } + + //! Get the capacity of array. + SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; } + + //! Check whether the array is empty. + bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; } + + //! Remove all elements in the array. + /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged. + \note Linear time complexity. + */ + void Clear() { + RAPIDJSON_ASSERT(IsArray()); + for (SizeType i = 0; i < data_.a.size; ++i) + data_.a.elements[i].~GenericValue(); + data_.a.size = 0; + } + + //! Get an element from array by index. + /*! \param index Zero-based index of element. +\code +Value a(kArrayType); +a.PushBack(123); +int x = a[0].GetInt(); // Error: operator[ is ambiguous, as 0 also mean a null pointer of const char* type. +int y = a[SizeType(0)].GetInt(); // Cast to SizeType will work. +int z = a[0u].GetInt(); // This works too. +\endcode + */ + GenericValue& operator[](SizeType index) { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(index < data_.a.size); + return data_.a.elements[index]; + } + const GenericValue& operator[](SizeType index) const { return const_cast(*this)[index]; } + + //! Element iterator + /*! \pre IsArray() == true */ + ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements; } + //! \em Past-the-end element iterator + /*! \pre IsArray() == true */ + ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements + data_.a.size; } + //! Constant element iterator + /*! \pre IsArray() == true */ + ConstValueIterator Begin() const { return const_cast(*this).Begin(); } + //! Constant \em past-the-end element iterator + /*! \pre IsArray() == true */ + ConstValueIterator End() const { return const_cast(*this).End(); } + + //! Request the array to have enough capacity to store elements. + /*! \param newCapacity The capacity that the array at least need to have. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note Linear time complexity. + */ + GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) { + RAPIDJSON_ASSERT(IsArray()); + if (newCapacity > data_.a.capacity) { + data_.a.elements = (GenericValue*)allocator.Realloc(data_.a.elements, data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue)); + data_.a.capacity = newCapacity; + } + return *this; + } + + //! Append a GenericValue at the end of the array. + /*! \param value Value to be appended. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \post value.IsNull() == true + \return The value itself for fluent API. + \note The ownership of \c value will be transferred to this array on success. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + \note Amortized constant time complexity. + */ + GenericValue& PushBack(GenericValue& value, Allocator& allocator) { + RAPIDJSON_ASSERT(IsArray()); + if (data_.a.size >= data_.a.capacity) + Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator); + data_.a.elements[data_.a.size++].RawAssign(value); + return *this; + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericValue& PushBack(GenericValue&& value, Allocator& allocator) { + return PushBack(value, allocator); + } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + + //! Append a constant string reference at the end of the array. + /*! \param value Constant string reference to be appended. + \param allocator Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \return The value itself for fluent API. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + \note Amortized constant time complexity. + \see GenericStringRef + */ + GenericValue& PushBack(StringRefType value, Allocator& allocator) { + return (*this).template PushBack(value, allocator); + } + + //! Append a primitive value at the end of the array. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param value Value of primitive type T to be appended. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \return The value itself for fluent API. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref PushBack(GenericValue&, Allocator&) or \ref + PushBack(StringRefType, Allocator&). + All other pointer types would implicitly convert to \c bool, + use an explicit cast instead, if needed. + \note Amortized constant time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericValue&)) + PushBack(T value, Allocator& allocator) { + GenericValue v(value); + return PushBack(v, allocator); + } + + //! Remove the last element in the array. + /*! + \note Constant time complexity. + */ + GenericValue& PopBack() { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(!Empty()); + data_.a.elements[--data_.a.size].~GenericValue(); + return *this; + } + + //! Remove an element of array by iterator. + /*! + \param pos iterator to the element to remove + \pre IsArray() == true && \ref Begin() <= \c pos < \ref End() + \return Iterator following the removed element. If the iterator pos refers to the last element, the End() iterator is returned. + \note Linear time complexity. + */ + ValueIterator Erase(ConstValueIterator pos) { + return Erase(pos, pos + 1); + } + + //! Remove elements in the range [first, last) of the array. + /*! + \param first iterator to the first element to remove + \param last iterator following the last element to remove + \pre IsArray() == true && \ref Begin() <= \c first <= \c last <= \ref End() + \return Iterator following the last removed element. + \note Linear time complexity. + */ + ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(data_.a.size > 0); + RAPIDJSON_ASSERT(data_.a.elements != 0); + RAPIDJSON_ASSERT(first >= Begin()); + RAPIDJSON_ASSERT(first <= last); + RAPIDJSON_ASSERT(last <= End()); + ValueIterator pos = Begin() + (first - Begin()); + for (ValueIterator itr = pos; itr != last; ++itr) + itr->~GenericValue(); + std::memmove(pos, last, (End() - last) * sizeof(GenericValue)); + data_.a.size -= (last - first); + return pos; + } + + //@} + + //!@name Number + //@{ + + int GetInt() const { RAPIDJSON_ASSERT(flags_ & kIntFlag); return data_.n.i.i; } + unsigned GetUint() const { RAPIDJSON_ASSERT(flags_ & kUintFlag); return data_.n.u.u; } + int64_t GetInt64() const { RAPIDJSON_ASSERT(flags_ & kInt64Flag); return data_.n.i64; } + uint64_t GetUint64() const { RAPIDJSON_ASSERT(flags_ & kUint64Flag); return data_.n.u64; } + + double GetDouble() const { + RAPIDJSON_ASSERT(IsNumber()); + if ((flags_ & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion. + if ((flags_ & kIntFlag) != 0) return data_.n.i.i; // int -> double + if ((flags_ & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double + if ((flags_ & kInt64Flag) != 0) return (double)data_.n.i64; // int64_t -> double (may lose precision) + RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0); return (double)data_.n.u64; // uint64_t -> double (may lose precision) + } + + GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; } + GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; } + GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; } + GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; } + GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; } + + //@} + + //!@name String + //@{ + + const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return ((flags_ & kInlineStrFlag) ? data_.ss.str : data_.s.str); } + + //! Get the length of string. + /*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength(). + */ + SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((flags_ & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); } + + //! Set this value as a string without copying source string. + /*! This version has better performance with supplied length, and also support string containing null character. + \param s source string pointer. + \param length The length of source string, excluding the trailing null terminator. + \return The value itself for fluent API. + \post IsString() == true && GetString() == s && GetStringLength() == length + \see SetString(StringRefType) + */ + GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); } + + //! Set this value as a string without copying source string. + /*! \param s source string reference + \return The value itself for fluent API. + \post IsString() == true && GetString() == s && GetStringLength() == s.length + */ + GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; } + + //! Set this value as a string by copying from source string. + /*! This version has better performance with supplied length, and also support string containing null character. + \param s source string. + \param length The length of source string, excluding the trailing null terminator. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length + */ + GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(StringRef(s, length), allocator); return *this; } + + //! Set this value as a string by copying from source string. + /*! \param s source string. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length + */ + GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(s, internal::StrLen(s), allocator); } + +#if RAPIDJSON_HAS_STDSTRING + //! Set this value as a string by copying from source string. + /*! \param s source string. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size() + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + GenericValue& SetString(const std::basic_string& s, Allocator& allocator) { return SetString(s.data(), s.size(), allocator); } +#endif + + //@} + + //! Generate events of this value to a Handler. + /*! This function adopts the GoF visitor pattern. + Typical usage is to output this JSON value as JSON text via Writer, which is a Handler. + It can also be used to deep clone this value via GenericDocument, which is also a Handler. + \tparam Handler type of handler. + \param handler An object implementing concept Handler. + */ + template + bool Accept(Handler& handler) const { + switch(GetType()) { + case kNullType: return handler.Null(); + case kFalseType: return handler.Bool(false); + case kTrueType: return handler.Bool(true); + + case kObjectType: + if (!handler.StartObject()) + return false; + for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) { + if (!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.flags_ & kCopyFlag) != 0)) + return false; + if (!m->value.Accept(handler)) + return false; + } + return handler.EndObject(data_.o.size); + + case kArrayType: + if (!handler.StartArray()) + return false; + for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v) + if (!v->Accept(handler)) + return false; + return handler.EndArray(data_.a.size); + + case kStringType: + return handler.String(GetString(), GetStringLength(), (flags_ & kCopyFlag) != 0); + + case kNumberType: + if (IsInt()) return handler.Int(data_.n.i.i); + else if (IsUint()) return handler.Uint(data_.n.u.u); + else if (IsInt64()) return handler.Int64(data_.n.i64); + else if (IsUint64()) return handler.Uint64(data_.n.u64); + else return handler.Double(data_.n.d); + + default: + RAPIDJSON_ASSERT(false); + } + return false; + } + +private: + template friend class GenericValue; + template friend class GenericDocument; + + enum { + kBoolFlag = 0x100, + kNumberFlag = 0x200, + kIntFlag = 0x400, + kUintFlag = 0x800, + kInt64Flag = 0x1000, + kUint64Flag = 0x2000, + kDoubleFlag = 0x4000, + kStringFlag = 0x100000, + kCopyFlag = 0x200000, + kInlineStrFlag = 0x400000, + + // Initial flags of different types. + kNullFlag = kNullType, + kTrueFlag = kTrueType | kBoolFlag, + kFalseFlag = kFalseType | kBoolFlag, + kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag, + kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag, + kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag, + kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag, + kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag, + kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag, + kConstStringFlag = kStringType | kStringFlag, + kCopyStringFlag = kStringType | kStringFlag | kCopyFlag, + kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag, + kObjectFlag = kObjectType, + kArrayFlag = kArrayType, + + kTypeMask = 0xFF // bitwise-and with mask of 0xFF can be optimized by compiler + }; + + static const SizeType kDefaultArrayCapacity = 16; + static const SizeType kDefaultObjectCapacity = 16; + + struct String { + const Ch* str; + SizeType length; + unsigned hashcode; //!< reserved + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars + // (excluding the terminating zero) and store a value to determine the length of the contained + // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string + // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as + // the string terminator as well. For getting the string length back from that value just use + // "MaxSize - str[LenPos]". + // This allows to store 11-chars strings in 32-bit mode and 15-chars strings in 64-bit mode + // inline (for `UTF8`-encoded strings). + struct ShortString { + enum { MaxChars = sizeof(String) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize }; + Ch str[MaxChars]; + + inline static bool Usable(SizeType len) { return (MaxSize >= len); } + inline void SetLength(SizeType len) { str[LenPos] = (Ch)(MaxSize - len); } + inline SizeType GetLength() const { return (SizeType)(MaxSize - str[LenPos]); } + }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + // By using proper binary layout, retrieval of different integer types do not need conversions. + union Number { +#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN + struct I { + int i; + char padding[4]; + }i; + struct U { + unsigned u; + char padding2[4]; + }u; +#else + struct I { + char padding[4]; + int i; + }i; + struct U { + char padding2[4]; + unsigned u; + }u; +#endif + int64_t i64; + uint64_t u64; + double d; + }; // 8 bytes + + struct Object { + Member* members; + SizeType size; + SizeType capacity; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + struct Array { + GenericValue* elements; + SizeType size; + SizeType capacity; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + union Data { + String s; + ShortString ss; + Number n; + Object o; + Array a; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + // Initialize this value as array with initial data, without calling destructor. + void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) { + flags_ = kArrayFlag; + data_.a.elements = (GenericValue*)allocator.Malloc(count * sizeof(GenericValue)); + std::memcpy(data_.a.elements, values, count * sizeof(GenericValue)); + data_.a.size = data_.a.capacity = count; + } + + //! Initialize this value as object with initial data, without calling destructor. + void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) { + flags_ = kObjectFlag; + data_.o.members = (Member*)allocator.Malloc(count * sizeof(Member)); + std::memcpy(data_.o.members, members, count * sizeof(Member)); + data_.o.size = data_.o.capacity = count; + } + + //! Initialize this value as constant string, without calling destructor. + void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT { + flags_ = kConstStringFlag; + data_.s.str = s; + data_.s.length = s.length; + } + + //! Initialize this value as copy string with initial data, without calling destructor. + void SetStringRaw(StringRefType s, Allocator& allocator) { + Ch* str = NULL; + if(ShortString::Usable(s.length)) { + flags_ = kShortStringFlag; + data_.ss.SetLength(s.length); + str = data_.ss.str; + } else { + flags_ = kCopyStringFlag; + data_.s.length = s.length; + str = (Ch *)allocator.Malloc((s.length + 1) * sizeof(Ch)); + data_.s.str = str; + } + std::memcpy(str, s, s.length * sizeof(Ch)); + str[s.length] = '\0'; + } + + //! Assignment without calling destructor + void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT { + data_ = rhs.data_; + flags_ = rhs.flags_; + rhs.flags_ = kNullFlag; + } + + template + bool StringEqual(const GenericValue& rhs) const { + RAPIDJSON_ASSERT(IsString()); + RAPIDJSON_ASSERT(rhs.IsString()); + + const SizeType len1 = GetStringLength(); + const SizeType len2 = rhs.GetStringLength(); + if(len1 != len2) { return false; } + + const Ch* const str1 = GetString(); + const Ch* const str2 = rhs.GetString(); + if(str1 == str2) { return true; } // fast path for constant string + + return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0); + } + + Data data_; + unsigned flags_; +}; + +//! GenericValue with UTF8 encoding +typedef GenericValue > Value; + +/////////////////////////////////////////////////////////////////////////////// +// GenericDocument + +//! A document for parsing JSON text as DOM. +/*! + \note implements Handler concept + \tparam Encoding Encoding for both parsing and string storage. + \tparam Allocator Allocator for allocating memory for the DOM + \tparam StackAllocator Allocator for allocating memory for stack during parsing. + \warning Although GenericDocument inherits from GenericValue, the API does \b not provide any virtual functions, especially no virtual destructor. To avoid memory leaks, do not \c delete a GenericDocument object via a pointer to a GenericValue. +*/ +template , typename StackAllocator = CrtAllocator> +class GenericDocument : public GenericValue { +public: + typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. + typedef GenericValue ValueType; //!< Value type of the document. + typedef Allocator AllocatorType; //!< Allocator type from template parameter. + + //! Constructor + /*! \param allocator Optional allocator for allocating memory. + \param stackCapacity Optional initial capacity of stack in bytes. + \param stackAllocator Optional allocator for allocating memory for stack. + */ + GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : + allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() + { + if (!allocator_) + ownAllocator_ = allocator_ = new Allocator(); + } + + ~GenericDocument() { + delete ownAllocator_; + } + + //!@name Parse from stream + //!@{ + + //! Parse JSON text from an input stream (with Encoding conversion) + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam SourceEncoding Encoding of input stream + \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseStream(InputStream& is) { + ValueType::SetNull(); // Remove existing root if exist + GenericReader reader(&GetAllocator()); + ClearStackOnExit scope(*this); + parseResult_ = reader.template Parse(is, *this); + if (parseResult_) { + RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object + this->RawAssign(*stack_.template Pop(1)); // Add this-> to prevent issue 13. + } + return *this; + } + + //! Parse JSON text from an input stream + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseStream(InputStream& is) { + return ParseStream(is); + } + + //! Parse JSON text from an input stream (with \ref kParseDefaultFlags) + /*! \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseStream(InputStream& is) { + return ParseStream(is); + } + //!@} + + //!@name Parse in-place from mutable string + //!@{ + + //! Parse JSON text from a mutable string (with Encoding conversion) + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam SourceEncoding Transcoding from input Encoding + \param str Mutable zero-terminated string to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseInsitu(Ch* str) { + GenericInsituStringStream s(str); + return ParseStream(s); + } + + //! Parse JSON text from a mutable string + /*! \tparam parseFlags Combination of \ref ParseFlag. + \param str Mutable zero-terminated string to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseInsitu(Ch* str) { + return ParseInsitu(str); + } + + //! Parse JSON text from a mutable string (with \ref kParseDefaultFlags) + /*! \param str Mutable zero-terminated string to be parsed. + \return The document itself for fluent API. + */ + GenericDocument& ParseInsitu(Ch* str) { + return ParseInsitu(str); + } + //!@} + + //!@name Parse from read-only string + //!@{ + + //! Parse JSON text from a read-only string (with Encoding conversion) + /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). + \tparam SourceEncoding Transcoding from input Encoding + \param str Read-only zero-terminated string to be parsed. + */ + template + GenericDocument& Parse(const Ch* str) { + RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); + GenericStringStream s(str); + return ParseStream(s); + } + + //! Parse JSON text from a read-only string + /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). + \param str Read-only zero-terminated string to be parsed. + */ + template + GenericDocument& Parse(const Ch* str) { + return Parse(str); + } + + //! Parse JSON text from a read-only string (with \ref kParseDefaultFlags) + /*! \param str Read-only zero-terminated string to be parsed. + */ + GenericDocument& Parse(const Ch* str) { + return Parse(str); + } + + GenericDocument& Parse(const Ch * str, size_t sz) { + const char* buf = (const char*) str; + size_t bufsz = sz * sizeof(Ch); + MemoryStream ms(buf, bufsz); + EncodedInputStream is(ms); + ParseStream(is); + return *this; + } + + //!@} + + //!@name Handling parse errors + //!@{ + + //! Whether a parse error has occured in the last parsing. + bool HasParseError() const { return parseResult_.IsError(); } + + //! Get the \ref ParseErrorCode of last parsing. + ParseErrorCode GetParseError() const { return parseResult_.Code(); } + + //! Get the position of last parsing error in input, 0 otherwise. + size_t GetErrorOffset() const { return parseResult_.Offset(); } + + //!@} + + //! Get the allocator of this document. + Allocator& GetAllocator() { return *allocator_; } + + //! Get the capacity of stack in bytes. + size_t GetStackCapacity() const { return stack_.GetCapacity(); } + +private: + // clear stack on any exit from ParseStream, e.g. due to exception + struct ClearStackOnExit { + explicit ClearStackOnExit(GenericDocument& d) : d_(d) {} + ~ClearStackOnExit() { d_.ClearStack(); } + private: + ClearStackOnExit(const ClearStackOnExit&); + ClearStackOnExit& operator=(const ClearStackOnExit&); + GenericDocument& d_; + }; + + // callers of the following private Handler functions + template friend class GenericReader; // for parsing + template friend class GenericValue; // for deep copying + + // Implementation of Handler + bool Null() { new (stack_.template Push()) ValueType(); return true; } + bool Bool(bool b) { new (stack_.template Push()) ValueType(b); return true; } + bool Int(int i) { new (stack_.template Push()) ValueType(i); return true; } + bool Uint(unsigned i) { new (stack_.template Push()) ValueType(i); return true; } + bool Int64(int64_t i) { new (stack_.template Push()) ValueType(i); return true; } + bool Uint64(uint64_t i) { new (stack_.template Push()) ValueType(i); return true; } + bool Double(double d) { new (stack_.template Push()) ValueType(d); return true; } + + bool String(const Ch* str, SizeType length, bool copy) { + if (copy) + new (stack_.template Push()) ValueType(str, length, GetAllocator()); + else + new (stack_.template Push()) ValueType(str, length); + return true; + } + + bool StartObject() { new (stack_.template Push()) ValueType(kObjectType); return true; } + + bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); } + + bool EndObject(SizeType memberCount) { + typename ValueType::Member* members = stack_.template Pop(memberCount); + stack_.template Top()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator()); + return true; + } + + bool StartArray() { new (stack_.template Push()) ValueType(kArrayType); return true; } + + bool EndArray(SizeType elementCount) { + ValueType* elements = stack_.template Pop(elementCount); + stack_.template Top()->SetArrayRaw(elements, elementCount, GetAllocator()); + return true; + } + +private: + //! Prohibit assignment + GenericDocument& operator=(const GenericDocument&); + + void ClearStack() { + if (Allocator::kNeedFree) + while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects) + (stack_.template Pop(1))->~ValueType(); + else + stack_.Clear(); + stack_.ShrinkToFit(); + } + + static const size_t kDefaultStackCapacity = 1024; + Allocator* allocator_; + Allocator* ownAllocator_; + internal::Stack stack_; + ParseResult parseResult_; +}; + +//! GenericDocument with UTF8 encoding +typedef GenericDocument > Document; + +// defined here due to the dependency on GenericDocument +template +template +inline +GenericValue::GenericValue(const GenericValue& rhs, Allocator& allocator) +{ + GenericDocument d(&allocator); + rhs.Accept(d); + RawAssign(*d.stack_.template Pop(1)); +} + +} // namespace rapidjson + +#if defined(_MSC_VER) || defined(__GNUC__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_DOCUMENT_H_ diff --git a/external/rapidjson/encodedstream.h b/external/rapidjson/encodedstream.h new file mode 100644 index 000000000..9dc00c7af --- /dev/null +++ b/external/rapidjson/encodedstream.h @@ -0,0 +1,290 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_ENCODEDSTREAM_H_ +#define RAPIDJSON_ENCODEDSTREAM_H_ + +#include "rapidjson.h" + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +namespace rapidjson { + +//! Input byte stream wrapper with a statically bound encoding. +/*! + \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. + \tparam InputByteStream Type of input byte stream. For example, FileReadStream. +*/ +template +class EncodedInputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); +public: + typedef typename Encoding::Ch Ch; + + EncodedInputStream(InputByteStream& is) : is_(is) { + current_ = Encoding::TakeBOM(is_); + } + + Ch Peek() const { return current_; } + Ch Take() { Ch c = current_; current_ = Encoding::Take(is_); return c; } + size_t Tell() const { return is_.Tell(); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + EncodedInputStream(const EncodedInputStream&); + EncodedInputStream& operator=(const EncodedInputStream&); + + InputByteStream& is_; + Ch current_; +}; + +//! Output byte stream wrapper with statically bound encoding. +/*! + \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. + \tparam InputByteStream Type of input byte stream. For example, FileWriteStream. +*/ +template +class EncodedOutputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); +public: + typedef typename Encoding::Ch Ch; + + EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) { + if (putBOM) + Encoding::PutBOM(os_); + } + + void Put(Ch c) { Encoding::Put(os_, c); } + void Flush() { os_.Flush(); } + + // Not implemented + Ch Peek() const { RAPIDJSON_ASSERT(false); } + Ch Take() { RAPIDJSON_ASSERT(false); } + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + EncodedOutputStream(const EncodedOutputStream&); + EncodedOutputStream& operator=(const EncodedOutputStream&); + + OutputByteStream& os_; +}; + +#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8::x, UTF16LE::x, UTF16BE::x, UTF32LE::x, UTF32BE::x + +//! Input stream wrapper with dynamically bound encoding and automatic encoding detection. +/*! + \tparam CharType Type of character for reading. + \tparam InputByteStream type of input byte stream to be wrapped. +*/ +template +class AutoUTFInputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); +public: + typedef CharType Ch; + + //! Constructor. + /*! + \param is input stream to be wrapped. + \param type UTF encoding type if it is not detected from the stream. + */ + AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) { + DetectType(); + static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) }; + takeFunc_ = f[type_]; + current_ = takeFunc_(*is_); + } + + UTFType GetType() const { return type_; } + bool HasBOM() const { return hasBOM_; } + + Ch Peek() const { return current_; } + Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; } + size_t Tell() const { return is_->Tell(); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + AutoUTFInputStream(const AutoUTFInputStream&); + AutoUTFInputStream& operator=(const AutoUTFInputStream&); + + // Detect encoding type with BOM or RFC 4627 + void DetectType() { + // BOM (Byte Order Mark): + // 00 00 FE FF UTF-32BE + // FF FE 00 00 UTF-32LE + // FE FF UTF-16BE + // FF FE UTF-16LE + // EF BB BF UTF-8 + + const unsigned char* c = (const unsigned char *)is_->Peek4(); + if (!c) + return; + + unsigned bom = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24); + hasBOM_ = false; + if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } + else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } + else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take(); } + else if ((bom & 0xFFFF) == 0xFEFF) { type_ = kUTF16LE; hasBOM_ = true; is_->Take(); is_->Take(); } + else if ((bom & 0xFFFFFF) == 0xBFBBEF) { type_ = kUTF8; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); } + + // RFC 4627: Section 3 + // "Since the first two characters of a JSON text will always be ASCII + // characters [RFC0020], it is possible to determine whether an octet + // stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking + // at the pattern of nulls in the first four octets." + // 00 00 00 xx UTF-32BE + // 00 xx 00 xx UTF-16BE + // xx 00 00 00 UTF-32LE + // xx 00 xx 00 UTF-16LE + // xx xx xx xx UTF-8 + + if (!hasBOM_) { + unsigned pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0); + switch (pattern) { + case 0x08: type_ = kUTF32BE; break; + case 0x0A: type_ = kUTF16BE; break; + case 0x01: type_ = kUTF32LE; break; + case 0x05: type_ = kUTF16LE; break; + case 0x0F: type_ = kUTF8; break; + default: break; // Use type defined by user. + } + } + + // Runtime check whether the size of character type is sufficient. It only perform checks with assertion. + switch (type_) { + case kUTF8: + // Do nothing + break; + case kUTF16LE: + case kUTF16BE: + RAPIDJSON_ASSERT(sizeof(Ch) >= 2); + break; + case kUTF32LE: + case kUTF32BE: + RAPIDJSON_ASSERT(sizeof(Ch) >= 4); + break; + default: + RAPIDJSON_ASSERT(false); // Invalid type + } + } + + typedef Ch (*TakeFunc)(InputByteStream& is); + InputByteStream* is_; + UTFType type_; + Ch current_; + TakeFunc takeFunc_; + bool hasBOM_; +}; + +//! Output stream wrapper with dynamically bound encoding and automatic encoding detection. +/*! + \tparam CharType Type of character for writing. + \tparam InputByteStream type of output byte stream to be wrapped. +*/ +template +class AutoUTFOutputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); +public: + typedef CharType Ch; + + //! Constructor. + /*! + \param os output stream to be wrapped. + \param type UTF encoding type. + \param putBOM Whether to write BOM at the beginning of the stream. + */ + AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) { + // RUntime check whether the size of character type is sufficient. It only perform checks with assertion. + switch (type_) { + case kUTF16LE: + case kUTF16BE: + RAPIDJSON_ASSERT(sizeof(Ch) >= 2); + break; + case kUTF32LE: + case kUTF32BE: + RAPIDJSON_ASSERT(sizeof(Ch) >= 4); + break; + case kUTF8: + // Do nothing + break; + default: + RAPIDJSON_ASSERT(false); // Invalid UTFType + } + + static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) }; + putFunc_ = f[type_]; + + if (putBOM) + PutBOM(); + } + + UTFType GetType() const { return type_; } + + void Put(Ch c) { putFunc_(*os_, c); } + void Flush() { os_->Flush(); } + + // Not implemented + Ch Peek() const { RAPIDJSON_ASSERT(false); } + Ch Take() { RAPIDJSON_ASSERT(false); } + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + AutoUTFOutputStream(const AutoUTFOutputStream&); + AutoUTFOutputStream& operator=(const AutoUTFOutputStream&); + + void PutBOM() { + typedef void (*PutBOMFunc)(OutputByteStream&); + static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) }; + f[type_](*os_); + } + + typedef void (*PutFunc)(OutputByteStream&, Ch); + + OutputByteStream* os_; + UTFType type_; + PutFunc putFunc_; +}; + +#undef RAPIDJSON_ENCODINGS_FUNC + +} // namespace rapidjson + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/external/rapidjson/encodings.h b/external/rapidjson/encodings.h new file mode 100644 index 000000000..5c7da3e04 --- /dev/null +++ b/external/rapidjson/encodings.h @@ -0,0 +1,630 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_ENCODINGS_H_ +#define RAPIDJSON_ENCODINGS_H_ + +#include "rapidjson.h" + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data +RAPIDJSON_DIAG_OFF(4702) // unreachable code +#elif defined(__GNUC__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +namespace rapidjson { + +/////////////////////////////////////////////////////////////////////////////// +// Encoding + +/*! \class rapidjson::Encoding + \brief Concept for encoding of Unicode characters. + +\code +concept Encoding { + typename Ch; //! Type of character. A "character" is actually a code unit in unicode's definition. + + enum { supportUnicode = 1 }; // or 0 if not supporting unicode + + //! \brief Encode a Unicode codepoint to an output stream. + //! \param os Output stream. + //! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively. + template + static void Encode(OutputStream& os, unsigned codepoint); + + //! \brief Decode a Unicode codepoint from an input stream. + //! \param is Input stream. + //! \param codepoint Output of the unicode codepoint. + //! \return true if a valid codepoint can be decoded from the stream. + template + static bool Decode(InputStream& is, unsigned* codepoint); + + //! \brief Validate one Unicode codepoint from an encoded stream. + //! \param is Input stream to obtain codepoint. + //! \param os Output for copying one codepoint. + //! \return true if it is valid. + //! \note This function just validating and copying the codepoint without actually decode it. + template + static bool Validate(InputStream& is, OutputStream& os); + + // The following functions are deal with byte streams. + + //! Take a character from input byte stream, skip BOM if exist. + template + static CharType TakeBOM(InputByteStream& is); + + //! Take a character from input byte stream. + template + static Ch Take(InputByteStream& is); + + //! Put BOM to output byte stream. + template + static void PutBOM(OutputByteStream& os); + + //! Put a character to output byte stream. + template + static void Put(OutputByteStream& os, Ch c); +}; +\endcode +*/ + +/////////////////////////////////////////////////////////////////////////////// +// UTF8 + +//! UTF-8 encoding. +/*! http://en.wikipedia.org/wiki/UTF-8 + http://tools.ietf.org/html/rfc3629 + \tparam CharType Code unit for storing 8-bit UTF-8 data. Default is char. + \note implements Encoding concept +*/ +template +struct UTF8 { + typedef CharType Ch; + + enum { supportUnicode = 1 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + if (codepoint <= 0x7F) + os.Put(static_cast(codepoint & 0xFF)); + else if (codepoint <= 0x7FF) { + os.Put(static_cast(0xC0 | ((codepoint >> 6) & 0xFF))); + os.Put(static_cast(0x80 | ((codepoint & 0x3F)))); + } + else if (codepoint <= 0xFFFF) { + os.Put(static_cast(0xE0 | ((codepoint >> 12) & 0xFF))); + os.Put(static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + os.Put(static_cast(0x80 | (codepoint & 0x3F))); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + os.Put(static_cast(0xF0 | ((codepoint >> 18) & 0xFF))); + os.Put(static_cast(0x80 | ((codepoint >> 12) & 0x3F))); + os.Put(static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + os.Put(static_cast(0x80 | (codepoint & 0x3F))); + } + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { +#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | ((unsigned char)c & 0x3Fu) +#define TRANS(mask) result &= ((GetRange((unsigned char)c) & mask) != 0) +#define TAIL() COPY(); TRANS(0x70) + Ch c = is.Take(); + if (!(c & 0x80)) { + *codepoint = (unsigned char)c; + return true; + } + + unsigned char type = GetRange((unsigned char)c); + *codepoint = (0xFF >> type) & (unsigned char)c; + bool result = true; + switch (type) { + case 2: TAIL(); return result; + case 3: TAIL(); TAIL(); return result; + case 4: COPY(); TRANS(0x50); TAIL(); return result; + case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result; + case 6: TAIL(); TAIL(); TAIL(); return result; + case 10: COPY(); TRANS(0x20); TAIL(); return result; + case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result; + default: return false; + } +#undef COPY +#undef TRANS +#undef TAIL + } + + template + static bool Validate(InputStream& is, OutputStream& os) { +#define COPY() os.Put(c = is.Take()) +#define TRANS(mask) result &= ((GetRange((unsigned char)c) & mask) != 0) +#define TAIL() COPY(); TRANS(0x70) + Ch c; + COPY(); + if (!(c & 0x80)) + return true; + + bool result = true; + switch (GetRange((unsigned char)c)) { + case 2: TAIL(); return result; + case 3: TAIL(); TAIL(); return result; + case 4: COPY(); TRANS(0x50); TAIL(); return result; + case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result; + case 6: TAIL(); TAIL(); TAIL(); return result; + case 10: COPY(); TRANS(0x20); TAIL(); return result; + case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result; + default: return false; + } +#undef COPY +#undef TRANS +#undef TAIL + } + + static unsigned char GetRange(unsigned char c) { + // Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ + // With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types. + static const unsigned char type[] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, + }; + return type[c]; + } + + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + Ch c = Take(is); + if ((unsigned char)c != 0xEFu) return c; + c = is.Take(); + if ((unsigned char)c != 0xBBu) return c; + c = is.Take(); + if ((unsigned char)c != 0xBFu) return c; + c = is.Take(); + return c; + } + + template + static Ch Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + return is.Take(); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(0xEFu); os.Put(0xBBu); os.Put(0xBFu); + } + + template + static void Put(OutputByteStream& os, Ch c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(c)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// UTF16 + +//! UTF-16 encoding. +/*! http://en.wikipedia.org/wiki/UTF-16 + http://tools.ietf.org/html/rfc2781 + \tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead. + \note implements Encoding concept + + \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. + For streaming, use UTF16LE and UTF16BE, which handle endianness. +*/ +template +struct UTF16 { + typedef CharType Ch; + RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2); + + enum { supportUnicode = 1 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); + if (codepoint <= 0xFFFF) { + RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair + os.Put(static_cast(codepoint)); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + unsigned v = codepoint - 0x10000; + os.Put(static_cast((v >> 10) | 0xD800)); + os.Put((v & 0x3FF) | 0xDC00); + } + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); + Ch c = is.Take(); + if (c < 0xD800 || c > 0xDFFF) { + *codepoint = c; + return true; + } + else if (c <= 0xDBFF) { + *codepoint = (c & 0x3FF) << 10; + c = is.Take(); + *codepoint |= (c & 0x3FF); + *codepoint += 0x10000; + return c >= 0xDC00 && c <= 0xDFFF; + } + return false; + } + + template + static bool Validate(InputStream& is, OutputStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); + Ch c; + os.Put(c = is.Take()); + if (c < 0xD800 || c > 0xDFFF) + return true; + else if (c <= 0xDBFF) { + os.Put(c = is.Take()); + return c >= 0xDC00 && c <= 0xDFFF; + } + return false; + } +}; + +//! UTF-16 little endian encoding. +template +struct UTF16LE : UTF16 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return (unsigned short)c == 0xFEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = (unsigned char)is.Take(); + c |= (unsigned char)is.Take() << 8; + return c; + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(0xFFu); os.Put(0xFEu); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(c & 0xFFu); + os.Put((c >> 8) & 0xFFu); + } +}; + +//! UTF-16 big endian encoding. +template +struct UTF16BE : UTF16 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return (unsigned short)c == 0xFEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = (unsigned char)is.Take() << 8; + c |= (unsigned char)is.Take(); + return c; + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(0xFEu); os.Put(0xFFu); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put((c >> 8) & 0xFFu); + os.Put(c & 0xFFu); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// UTF32 + +//! UTF-32 encoding. +/*! http://en.wikipedia.org/wiki/UTF-32 + \tparam CharType Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead. + \note implements Encoding concept + + \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. + For streaming, use UTF32LE and UTF32BE, which handle endianness. +*/ +template +struct UTF32 { + typedef CharType Ch; + RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4); + + enum { supportUnicode = 1 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + os.Put(codepoint); + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); + Ch c = is.Take(); + *codepoint = c; + return c <= 0x10FFFF; + } + + template + static bool Validate(InputStream& is, OutputStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); + Ch c; + os.Put(c = is.Take()); + return c <= 0x10FFFF; + } +}; + +//! UTF-32 little endian enocoding. +template +struct UTF32LE : UTF32 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return (unsigned)c == 0x0000FEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = (unsigned char)is.Take(); + c |= (unsigned char)is.Take() << 8; + c |= (unsigned char)is.Take() << 16; + c |= (unsigned char)is.Take() << 24; + return c; + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(0xFFu); os.Put(0xFEu); os.Put(0x00u); os.Put(0x00u); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(c & 0xFFu); + os.Put((c >> 8) & 0xFFu); + os.Put((c >> 16) & 0xFFu); + os.Put((c >> 24) & 0xFFu); + } +}; + +//! UTF-32 big endian encoding. +template +struct UTF32BE : UTF32 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return (unsigned)c == 0x0000FEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = (unsigned char)is.Take() << 24; + c |= (unsigned char)is.Take() << 16; + c |= (unsigned char)is.Take() << 8; + c |= (unsigned char)is.Take(); + return c; + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(0x00u); os.Put(0x00u); os.Put(0xFEu); os.Put(0xFFu); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put((c >> 24) & 0xFFu); + os.Put((c >> 16) & 0xFFu); + os.Put((c >> 8) & 0xFFu); + os.Put(c & 0xFFu); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// ASCII + +//! ASCII encoding. +/*! http://en.wikipedia.org/wiki/ASCII + \tparam CharType Code unit for storing 7-bit ASCII data. Default is char. + \note implements Encoding concept +*/ +template +struct ASCII { + typedef CharType Ch; + + enum { supportUnicode = 0 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_ASSERT(codepoint <= 0x7F); + os.Put(static_cast(codepoint & 0xFF)); + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { + unsigned char c = static_cast(is.Take()); + *codepoint = c; + return c <= 0X7F; + } + + template + static bool Validate(InputStream& is, OutputStream& os) { + unsigned char c = is.Take(); + os.Put(c); + return c <= 0x7F; + } + + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + Ch c = Take(is); + return c; + } + + template + static Ch Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + return is.Take(); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + (void)os; + } + + template + static void Put(OutputByteStream& os, Ch c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(c)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// AutoUTF + +//! Runtime-specified UTF encoding type of a stream. +enum UTFType { + kUTF8 = 0, //!< UTF-8. + kUTF16LE = 1, //!< UTF-16 little endian. + kUTF16BE = 2, //!< UTF-16 big endian. + kUTF32LE = 3, //!< UTF-32 little endian. + kUTF32BE = 4 //!< UTF-32 big endian. +}; + +//! Dynamically select encoding according to stream's runtime-specified UTF encoding type. +/*! \note This class can be used with AutoUTFInputtStream and AutoUTFOutputStream, which provides GetType(). +*/ +template +struct AutoUTF { + typedef CharType Ch; + + enum { supportUnicode = 1 }; + +#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8::x, UTF16LE::x, UTF16BE::x, UTF32LE::x, UTF32BE::x + + template + RAPIDJSON_FORCEINLINE static void Encode(OutputStream& os, unsigned codepoint) { + typedef void (*EncodeFunc)(OutputStream&, unsigned); + static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) }; + (*f[os.GetType()])(os, codepoint); + } + + template + RAPIDJSON_FORCEINLINE static bool Decode(InputStream& is, unsigned* codepoint) { + typedef bool (*DecodeFunc)(InputStream&, unsigned*); + static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) }; + return (*f[is.GetType()])(is, codepoint); + } + + template + RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { + typedef bool (*ValidateFunc)(InputStream&, OutputStream&); + static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) }; + return (*f[is.GetType()])(is, os); + } + +#undef RAPIDJSON_ENCODINGS_FUNC +}; + +/////////////////////////////////////////////////////////////////////////////// +// Transcoder + +//! Encoding conversion. +template +struct Transcoder { + //! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream. + template + RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) { + unsigned codepoint; + if (!SourceEncoding::Decode(is, &codepoint)) + return false; + TargetEncoding::Encode(os, codepoint); + return true; + } + + //! Validate one Unicode codepoint from an encoded stream. + template + RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { + return Transcode(is, os); // Since source/target encoding is different, must transcode. + } +}; + +//! Specialization of Transcoder with same source and target encoding. +template +struct Transcoder { + template + RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) { + os.Put(is.Take()); // Just copy one code unit. This semantic is different from primary template class. + return true; + } + + template + RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { + return Encoding::Validate(is, os); // source/target encoding are the same + } +}; + +} // namespace rapidjson + +#if defined(__GNUC__) || defined(_MSV_VER) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_ENCODINGS_H_ diff --git a/external/rapidjson/error/en.h b/external/rapidjson/error/en.h new file mode 100644 index 000000000..d153e04fc --- /dev/null +++ b/external/rapidjson/error/en.h @@ -0,0 +1,71 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_ERROR_EN_H__ +#define RAPIDJSON_ERROR_EN_H__ + +#include "error.h" + +namespace rapidjson { + +//! Maps error code of parsing into error message. +/*! + \ingroup RAPIDJSON_ERRORS + \param parseErrorCode Error code obtained in parsing. + \return the error message. + \note User can make a copy of this function for localization. + Using switch-case is safer for future modification of error codes. +*/ +inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) { + switch (parseErrorCode) { + case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error."); + + case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty."); + case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not follow by other values."); + + case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value."); + + case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member."); + case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member."); + case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member."); + + case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element."); + + case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string."); + case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid."); + case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string."); + case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string."); + case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string."); + + case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double."); + case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number."); + case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number."); + + case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error."); + case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error."); + + default: + return RAPIDJSON_ERROR_STRING("Unknown error."); + } +} + +} // namespace rapidjson + +#endif // RAPIDJSON_ERROR_EN_H__ diff --git a/external/rapidjson/error/error.h b/external/rapidjson/error/error.h new file mode 100644 index 000000000..146604439 --- /dev/null +++ b/external/rapidjson/error/error.h @@ -0,0 +1,150 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_ERROR_ERROR_H__ +#define RAPIDJSON_ERROR_ERROR_H__ + +/*! \file error.h */ + +/*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */ + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ERROR_CHARTYPE + +//! Character type of error messages. +/*! \ingroup RAPIDJSON_ERRORS + The default character type is \c char. + On Windows, user can define this macro as \c TCHAR for supporting both + unicode/non-unicode settings. +*/ +#ifndef RAPIDJSON_ERROR_CHARTYPE +#define RAPIDJSON_ERROR_CHARTYPE char +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ERROR_STRING + +//! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[]. +/*! \ingroup RAPIDJSON_ERRORS + By default this conversion macro does nothing. + On Windows, user can define this macro as \c _T(x) for supporting both + unicode/non-unicode settings. +*/ +#ifndef RAPIDJSON_ERROR_STRING +#define RAPIDJSON_ERROR_STRING(x) x +#endif + +namespace rapidjson { + +/////////////////////////////////////////////////////////////////////////////// +// ParseErrorCode + +//! Error code of parsing. +/*! \ingroup RAPIDJSON_ERRORS + \see GenericReader::Parse, GenericReader::GetParseErrorCode +*/ +enum ParseErrorCode { + kParseErrorNone = 0, //!< No error. + + kParseErrorDocumentEmpty, //!< The document is empty. + kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values. + + kParseErrorValueInvalid, //!< Invalid value. + + kParseErrorObjectMissName, //!< Missing a name for object member. + kParseErrorObjectMissColon, //!< Missing a colon after a name of object member. + kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member. + + kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element. + + kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string. + kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid. + kParseErrorStringEscapeInvalid, //!< Invalid escape character in string. + kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string. + kParseErrorStringInvalidEncoding, //!< Invalid encoding in string. + + kParseErrorNumberTooBig, //!< Number too big to be stored in double. + kParseErrorNumberMissFraction, //!< Miss fraction part in number. + kParseErrorNumberMissExponent, //!< Miss exponent in number. + + kParseErrorTermination, //!< Parsing was terminated. + kParseErrorUnspecificSyntaxError, //!< Unspecific syntax error. +}; + +//! Result of parsing (wraps ParseErrorCode) +/*! + \ingroup RAPIDJSON_ERRORS + \code + Document doc; + ParseResult ok = doc.Parse("[42]"); + if (!ok) { + fprintf(stderr, "JSON parse error: %s (%u)", + GetParseError_En(ok.Code()), ok.Offset()); + exit(EXIT_FAILURE); + } + \endcode + \see GenericReader::Parse, GenericDocument::Parse +*/ +struct ParseResult { + + //! Default constructor, no error. + ParseResult() : code_(kParseErrorNone), offset_(0) {} + //! Constructor to set an error. + ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {} + + //! Get the error code. + ParseErrorCode Code() const { return code_; } + //! Get the error offset, if \ref IsError(), 0 otherwise. + size_t Offset() const { return offset_; } + + //! Conversion to \c bool, returns \c true, iff !\ref IsError(). + operator bool() const { return !IsError(); } + //! Whether the result is an error. + bool IsError() const { return code_ != kParseErrorNone; } + + bool operator==(const ParseResult& that) const { return code_ == that.code_; } + bool operator==(ParseErrorCode code) const { return code_ == code; } + friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; } + + //! Reset error code. + void Clear() { Set(kParseErrorNone); } + //! Update error code and offset. + void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; } + +private: + ParseErrorCode code_; + size_t offset_; +}; + +//! Function pointer type of GetParseError(). +/*! \ingroup RAPIDJSON_ERRORS + + This is the prototype for \c GetParseError_X(), where \c X is a locale. + User can dynamically change locale in runtime, e.g.: +\code + GetParseErrorFunc GetParseError = GetParseError_En; // or whatever + const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode()); +\endcode +*/ +typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode); + +} // namespace rapidjson + +#endif // RAPIDJSON_ERROR_ERROR_H__ diff --git a/external/rapidjson/filereadstream.h b/external/rapidjson/filereadstream.h new file mode 100644 index 000000000..31c193bf9 --- /dev/null +++ b/external/rapidjson/filereadstream.h @@ -0,0 +1,94 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_FILEREADSTREAM_H_ +#define RAPIDJSON_FILEREADSTREAM_H_ + +#include "rapidjson.h" +#include + +namespace rapidjson { + +//! File byte stream for input using fread(). +/*! + \note implements Stream concept +*/ +class FileReadStream { +public: + typedef char Ch; //!< Character type (byte). + + //! Constructor. + /*! + \param fp File pointer opened for read. + \param buffer user-supplied buffer. + \param bufferSize size of buffer in bytes. Must >=4 bytes. + */ + FileReadStream(FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { + RAPIDJSON_ASSERT(fp_ != 0); + RAPIDJSON_ASSERT(bufferSize >= 4); + Read(); + } + + Ch Peek() const { return *current_; } + Ch Take() { Ch c = *current_; Read(); return c; } + size_t Tell() const { return count_ + static_cast(current_ - buffer_); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + // For encoding detection only. + const Ch* Peek4() const { + return (current_ + 4 <= bufferLast_) ? current_ : 0; + } + +private: + void Read() { + if (current_ < bufferLast_) + ++current_; + else if (!eof_) { + count_ += readCount_; + readCount_ = fread(buffer_, 1, bufferSize_, fp_); + bufferLast_ = buffer_ + readCount_ - 1; + current_ = buffer_; + + if (readCount_ < bufferSize_) { + buffer_[readCount_] = '\0'; + ++bufferLast_; + eof_ = true; + } + } + } + + FILE* fp_; + Ch *buffer_; + size_t bufferSize_; + Ch *bufferLast_; + Ch *current_; + size_t readCount_; + size_t count_; //!< Number of characters read + bool eof_; +}; + +} // namespace rapidjson + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/external/rapidjson/filestream.h b/external/rapidjson/filestream.h new file mode 100644 index 000000000..6995b3d3f --- /dev/null +++ b/external/rapidjson/filestream.h @@ -0,0 +1,73 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_FILESTREAM_H_ +#define RAPIDJSON_FILESTREAM_H_ + +#include "rapidjson.h" +#include + +namespace rapidjson { + +//! (Depreciated) Wrapper of C file stream for input or output. +/*! + This simple wrapper does not check the validity of the stream. + \note implements Stream concept + \note deprecated: This was only for basic testing in version 0.1, it is found that the performance is very low by using fgetc(). Use FileReadStream instead. +*/ +class FileStream { +public: + typedef char Ch; //!< Character type. Only support char. + + FileStream(FILE* fp) : fp_(fp), current_('\0'), count_(0) { Read(); } + char Peek() const { return current_; } + char Take() { char c = current_; Read(); return c; } + size_t Tell() const { return count_; } + void Put(char c) { fputc(c, fp_); } + void Flush() { fflush(fp_); } + + // Not implemented + char* PutBegin() { return 0; } + size_t PutEnd(char*) { return 0; } + +private: + // Prohibit copy constructor & assignment operator. + FileStream(const FileStream&); + FileStream& operator=(const FileStream&); + + void Read() { + RAPIDJSON_ASSERT(fp_ != 0); + int c = fgetc(fp_); + if (c != EOF) { + current_ = (char)c; + count_++; + } + else if (current_ != '\0') + current_ = '\0'; + } + + FILE* fp_; + char current_; + size_t count_; +}; + +} // namespace rapidjson + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/external/rapidjson/filewritestream.h b/external/rapidjson/filewritestream.h new file mode 100644 index 000000000..05c5ca090 --- /dev/null +++ b/external/rapidjson/filewritestream.h @@ -0,0 +1,97 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_FILEWRITESTREAM_H_ +#define RAPIDJSON_FILEWRITESTREAM_H_ + +#include "rapidjson.h" +#include + +namespace rapidjson { + +//! Wrapper of C file stream for input using fread(). +/*! + \note implements Stream concept +*/ +class FileWriteStream { +public: + typedef char Ch; //!< Character type. Only support char. + + FileWriteStream(FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { + RAPIDJSON_ASSERT(fp_ != 0); + } + + void Put(char c) { + if (current_ >= bufferEnd_) + Flush(); + + *current_++ = c; + } + + void PutN(char c, size_t n) { + size_t avail = static_cast(bufferEnd_ - current_); + while (n > avail) { + std::memset(current_, c, avail); + current_ += avail; + Flush(); + n -= avail; + avail = static_cast(bufferEnd_ - current_); + } + + if (n > 0) { + std::memset(current_, c, n); + current_ += n; + } + } + + void Flush() { + if (current_ != buffer_) { + fwrite(buffer_, 1, static_cast(current_ - buffer_), fp_); + current_ = buffer_; + } + } + + // Not implemented + char Peek() const { RAPIDJSON_ASSERT(false); return 0; } + char Take() { RAPIDJSON_ASSERT(false); return 0; } + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + // Prohibit copy constructor & assignment operator. + FileWriteStream(const FileWriteStream&); + FileWriteStream& operator=(const FileWriteStream&); + + FILE* fp_; + char *buffer_; + char *bufferEnd_; + char *current_; +}; + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(FileWriteStream& stream, char c, size_t n) { + stream.PutN(c, n); +} + +} // namespace rapidjson + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/external/rapidjson/internal/dtoa.h b/external/rapidjson/internal/dtoa.h new file mode 100644 index 000000000..6ae588ac4 --- /dev/null +++ b/external/rapidjson/internal/dtoa.h @@ -0,0 +1,418 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// This is a C++ header-only implementation of Grisu2 algorithm from the publication: +// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with +// integers." ACM Sigplan Notices 45.6 (2010): 233-243. + +#ifndef RAPIDJSON_DTOA_ +#define RAPIDJSON_DTOA_ + +#if defined(_MSC_VER) +#include +#if defined(_M_AMD64) +#pragma intrinsic(_BitScanReverse64) +#endif +#endif + +#include "itoa.h" // GetDigitsLut() + +namespace rapidjson { +namespace internal { + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +struct DiyFp { + DiyFp() {} + + DiyFp(uint64_t f, int e) : f(f), e(e) {} + + DiyFp(double d) { + union { + double d; + uint64_t u64; + } u = { d }; + + int biased_e = static_cast((u.u64 & kDpExponentMask) >> kDpSignificandSize); + uint64_t significand = (u.u64 & kDpSignificandMask); + if (biased_e != 0) { + f = significand + kDpHiddenBit; + e = biased_e - kDpExponentBias; + } + else { + f = significand; + e = kDpMinExponent + 1; + } + } + + DiyFp operator-(const DiyFp& rhs) const { + return DiyFp(f - rhs.f, e); + } + + DiyFp operator*(const DiyFp& rhs) const { +#if defined(_MSC_VER) && defined(_M_AMD64) + uint64_t h; + uint64_t l = _umul128(f, rhs.f, &h); + if (l & (uint64_t(1) << 63)) // rounding + h++; + return DiyFp(h, e + rhs.e + 64); +#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) + unsigned __int128 p = static_cast(f) * static_cast(rhs.f); + uint64_t h = static_cast(p >> 64); + uint64_t l = static_cast(p); + if (l & (uint64_t(1) << 63)) // rounding + h++; + return DiyFp(h, e + rhs.e + 64); +#else + const uint64_t M32 = 0xFFFFFFFF; + const uint64_t a = f >> 32; + const uint64_t b = f & M32; + const uint64_t c = rhs.f >> 32; + const uint64_t d = rhs.f & M32; + const uint64_t ac = a * c; + const uint64_t bc = b * c; + const uint64_t ad = a * d; + const uint64_t bd = b * d; + uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32); + tmp += 1U << 31; /// mult_round + return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64); +#endif + } + + DiyFp Normalize() const { +#if defined(_MSC_VER) && defined(_M_AMD64) + unsigned long index; + _BitScanReverse64(&index, f); + return DiyFp(f << (63 - index), e - (63 - index)); +#elif defined(__GNUC__) + int s = __builtin_clzll(f); + return DiyFp(f << s, e - s); +#else + DiyFp res = *this; + while (!(res.f & kDpHiddenBit)) { + res.f <<= 1; + res.e--; + } + res.f <<= (kDiySignificandSize - kDpSignificandSize - 1); + res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 1); + return res; +#endif + } + + DiyFp NormalizeBoundary() const { +#if defined(_MSC_VER) && defined(_M_AMD64) + unsigned long index; + _BitScanReverse64(&index, f); + return DiyFp (f << (63 - index), e - (63 - index)); +#else + DiyFp res = *this; + while (!(res.f & (kDpHiddenBit << 1))) { + res.f <<= 1; + res.e--; + } + res.f <<= (kDiySignificandSize - kDpSignificandSize - 2); + res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 2); + return res; +#endif + } + + void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const { + DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary(); + DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1); + mi.f <<= mi.e - pl.e; + mi.e = pl.e; + *plus = pl; + *minus = mi; + } + + static const int kDiySignificandSize = 64; + static const int kDpSignificandSize = 52; + static const int kDpExponentBias = 0x3FF + kDpSignificandSize; + static const int kDpMinExponent = -kDpExponentBias; + static const uint64_t kDpExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); + static const uint64_t kDpSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); + static const uint64_t kDpHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); + + uint64_t f; + int e; +}; + +inline DiyFp GetCachedPower(int e, int* K) { + // 10^-348, 10^-340, ..., 10^340 + static const uint64_t kCachedPowers_F[] = { + RAPIDJSON_UINT64_C2(0xfa8fd5a0, 0x081c0288), RAPIDJSON_UINT64_C2(0xbaaee17f, 0xa23ebf76), + RAPIDJSON_UINT64_C2(0x8b16fb20, 0x3055ac76), RAPIDJSON_UINT64_C2(0xcf42894a, 0x5dce35ea), + RAPIDJSON_UINT64_C2(0x9a6bb0aa, 0x55653b2d), RAPIDJSON_UINT64_C2(0xe61acf03, 0x3d1a45df), + RAPIDJSON_UINT64_C2(0xab70fe17, 0xc79ac6ca), RAPIDJSON_UINT64_C2(0xff77b1fc, 0xbebcdc4f), + RAPIDJSON_UINT64_C2(0xbe5691ef, 0x416bd60c), RAPIDJSON_UINT64_C2(0x8dd01fad, 0x907ffc3c), + RAPIDJSON_UINT64_C2(0xd3515c28, 0x31559a83), RAPIDJSON_UINT64_C2(0x9d71ac8f, 0xada6c9b5), + RAPIDJSON_UINT64_C2(0xea9c2277, 0x23ee8bcb), RAPIDJSON_UINT64_C2(0xaecc4991, 0x4078536d), + RAPIDJSON_UINT64_C2(0x823c1279, 0x5db6ce57), RAPIDJSON_UINT64_C2(0xc2109436, 0x4dfb5637), + RAPIDJSON_UINT64_C2(0x9096ea6f, 0x3848984f), RAPIDJSON_UINT64_C2(0xd77485cb, 0x25823ac7), + RAPIDJSON_UINT64_C2(0xa086cfcd, 0x97bf97f4), RAPIDJSON_UINT64_C2(0xef340a98, 0x172aace5), + RAPIDJSON_UINT64_C2(0xb23867fb, 0x2a35b28e), RAPIDJSON_UINT64_C2(0x84c8d4df, 0xd2c63f3b), + RAPIDJSON_UINT64_C2(0xc5dd4427, 0x1ad3cdba), RAPIDJSON_UINT64_C2(0x936b9fce, 0xbb25c996), + RAPIDJSON_UINT64_C2(0xdbac6c24, 0x7d62a584), RAPIDJSON_UINT64_C2(0xa3ab6658, 0x0d5fdaf6), + RAPIDJSON_UINT64_C2(0xf3e2f893, 0xdec3f126), RAPIDJSON_UINT64_C2(0xb5b5ada8, 0xaaff80b8), + RAPIDJSON_UINT64_C2(0x87625f05, 0x6c7c4a8b), RAPIDJSON_UINT64_C2(0xc9bcff60, 0x34c13053), + RAPIDJSON_UINT64_C2(0x964e858c, 0x91ba2655), RAPIDJSON_UINT64_C2(0xdff97724, 0x70297ebd), + RAPIDJSON_UINT64_C2(0xa6dfbd9f, 0xb8e5b88f), RAPIDJSON_UINT64_C2(0xf8a95fcf, 0x88747d94), + RAPIDJSON_UINT64_C2(0xb9447093, 0x8fa89bcf), RAPIDJSON_UINT64_C2(0x8a08f0f8, 0xbf0f156b), + RAPIDJSON_UINT64_C2(0xcdb02555, 0x653131b6), RAPIDJSON_UINT64_C2(0x993fe2c6, 0xd07b7fac), + RAPIDJSON_UINT64_C2(0xe45c10c4, 0x2a2b3b06), RAPIDJSON_UINT64_C2(0xaa242499, 0x697392d3), + RAPIDJSON_UINT64_C2(0xfd87b5f2, 0x8300ca0e), RAPIDJSON_UINT64_C2(0xbce50864, 0x92111aeb), + RAPIDJSON_UINT64_C2(0x8cbccc09, 0x6f5088cc), RAPIDJSON_UINT64_C2(0xd1b71758, 0xe219652c), + RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), RAPIDJSON_UINT64_C2(0xe8d4a510, 0x00000000), + RAPIDJSON_UINT64_C2(0xad78ebc5, 0xac620000), RAPIDJSON_UINT64_C2(0x813f3978, 0xf8940984), + RAPIDJSON_UINT64_C2(0xc097ce7b, 0xc90715b3), RAPIDJSON_UINT64_C2(0x8f7e32ce, 0x7bea5c70), + RAPIDJSON_UINT64_C2(0xd5d238a4, 0xabe98068), RAPIDJSON_UINT64_C2(0x9f4f2726, 0x179a2245), + RAPIDJSON_UINT64_C2(0xed63a231, 0xd4c4fb27), RAPIDJSON_UINT64_C2(0xb0de6538, 0x8cc8ada8), + RAPIDJSON_UINT64_C2(0x83c7088e, 0x1aab65db), RAPIDJSON_UINT64_C2(0xc45d1df9, 0x42711d9a), + RAPIDJSON_UINT64_C2(0x924d692c, 0xa61be758), RAPIDJSON_UINT64_C2(0xda01ee64, 0x1a708dea), + RAPIDJSON_UINT64_C2(0xa26da399, 0x9aef774a), RAPIDJSON_UINT64_C2(0xf209787b, 0xb47d6b85), + RAPIDJSON_UINT64_C2(0xb454e4a1, 0x79dd1877), RAPIDJSON_UINT64_C2(0x865b8692, 0x5b9bc5c2), + RAPIDJSON_UINT64_C2(0xc83553c5, 0xc8965d3d), RAPIDJSON_UINT64_C2(0x952ab45c, 0xfa97a0b3), + RAPIDJSON_UINT64_C2(0xde469fbd, 0x99a05fe3), RAPIDJSON_UINT64_C2(0xa59bc234, 0xdb398c25), + RAPIDJSON_UINT64_C2(0xf6c69a72, 0xa3989f5c), RAPIDJSON_UINT64_C2(0xb7dcbf53, 0x54e9bece), + RAPIDJSON_UINT64_C2(0x88fcf317, 0xf22241e2), RAPIDJSON_UINT64_C2(0xcc20ce9b, 0xd35c78a5), + RAPIDJSON_UINT64_C2(0x98165af3, 0x7b2153df), RAPIDJSON_UINT64_C2(0xe2a0b5dc, 0x971f303a), + RAPIDJSON_UINT64_C2(0xa8d9d153, 0x5ce3b396), RAPIDJSON_UINT64_C2(0xfb9b7cd9, 0xa4a7443c), + RAPIDJSON_UINT64_C2(0xbb764c4c, 0xa7a44410), RAPIDJSON_UINT64_C2(0x8bab8eef, 0xb6409c1a), + RAPIDJSON_UINT64_C2(0xd01fef10, 0xa657842c), RAPIDJSON_UINT64_C2(0x9b10a4e5, 0xe9913129), + RAPIDJSON_UINT64_C2(0xe7109bfb, 0xa19c0c9d), RAPIDJSON_UINT64_C2(0xac2820d9, 0x623bf429), + RAPIDJSON_UINT64_C2(0x80444b5e, 0x7aa7cf85), RAPIDJSON_UINT64_C2(0xbf21e440, 0x03acdd2d), + RAPIDJSON_UINT64_C2(0x8e679c2f, 0x5e44ff8f), RAPIDJSON_UINT64_C2(0xd433179d, 0x9c8cb841), + RAPIDJSON_UINT64_C2(0x9e19db92, 0xb4e31ba9), RAPIDJSON_UINT64_C2(0xeb96bf6e, 0xbadf77d9), + RAPIDJSON_UINT64_C2(0xaf87023b, 0x9bf0ee6b) + }; + static const int16_t kCachedPowers_E[] = { + -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, + -954, -927, -901, -874, -847, -821, -794, -768, -741, -715, + -688, -661, -635, -608, -582, -555, -529, -502, -475, -449, + -422, -396, -369, -343, -316, -289, -263, -236, -210, -183, + -157, -130, -103, -77, -50, -24, 3, 30, 56, 83, + 109, 136, 162, 189, 216, 242, 269, 295, 322, 348, + 375, 402, 428, 455, 481, 508, 534, 561, 588, 614, + 641, 667, 694, 720, 747, 774, 800, 827, 853, 880, + 907, 933, 960, 986, 1013, 1039, 1066 + }; + + //int k = static_cast(ceil((-61 - e) * 0.30102999566398114)) + 374; + double dk = (-61 - e) * 0.30102999566398114 + 347; // dk must be positive, so can do ceiling in positive + int k = static_cast(dk); + if (k != dk) + k++; + + unsigned index = static_cast((k >> 3) + 1); + *K = -(-348 + static_cast(index << 3)); // decimal exponent no need lookup table + + return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]); +} + +inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) { + while (rest < wp_w && delta - rest >= ten_kappa && + (rest + ten_kappa < wp_w || /// closer + wp_w - rest > rest + ten_kappa - wp_w)) { + buffer[len - 1]--; + rest += ten_kappa; + } +} + +inline unsigned CountDecimalDigit32(uint32_t n) { + // Simple pure C++ implementation was faster than __builtin_clz version in this situation. + if (n < 10) return 1; + if (n < 100) return 2; + if (n < 1000) return 3; + if (n < 10000) return 4; + if (n < 100000) return 5; + if (n < 1000000) return 6; + if (n < 10000000) return 7; + if (n < 100000000) return 8; + if (n < 1000000000) return 9; + return 10; +} + +inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) { + static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; + const DiyFp one(uint64_t(1) << -Mp.e, Mp.e); + const DiyFp wp_w = Mp - W; + uint32_t p1 = static_cast(Mp.f >> -one.e); + uint64_t p2 = Mp.f & (one.f - 1); + int kappa = CountDecimalDigit32(p1); + *len = 0; + + while (kappa > 0) { + uint32_t d; + switch (kappa) { + case 10: d = p1 / 1000000000; p1 %= 1000000000; break; + case 9: d = p1 / 100000000; p1 %= 100000000; break; + case 8: d = p1 / 10000000; p1 %= 10000000; break; + case 7: d = p1 / 1000000; p1 %= 1000000; break; + case 6: d = p1 / 100000; p1 %= 100000; break; + case 5: d = p1 / 10000; p1 %= 10000; break; + case 4: d = p1 / 1000; p1 %= 1000; break; + case 3: d = p1 / 100; p1 %= 100; break; + case 2: d = p1 / 10; p1 %= 10; break; + case 1: d = p1; p1 = 0; break; + default: +#if defined(_MSC_VER) + __assume(0); +#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + __builtin_unreachable(); +#else + d = 0; +#endif + } + if (d || *len) + buffer[(*len)++] = static_cast('0' + static_cast(d)); + kappa--; + uint64_t tmp = (static_cast(p1) << -one.e) + p2; + if (tmp <= delta) { + *K += kappa; + GrisuRound(buffer, *len, delta, tmp, static_cast(kPow10[kappa]) << -one.e, wp_w.f); + return; + } + } + + // kappa = 0 + for (;;) { + p2 *= 10; + delta *= 10; + char d = static_cast(p2 >> -one.e); + if (d || *len) + buffer[(*len)++] = static_cast('0' + d); + p2 &= one.f - 1; + kappa--; + if (p2 < delta) { + *K += kappa; + GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * kPow10[-kappa]); + return; + } + } +} + +inline void Grisu2(double value, char* buffer, int* length, int* K) { + const DiyFp v(value); + DiyFp w_m, w_p; + v.NormalizedBoundaries(&w_m, &w_p); + + const DiyFp c_mk = GetCachedPower(w_p.e, K); + const DiyFp W = v.Normalize() * c_mk; + DiyFp Wp = w_p * c_mk; + DiyFp Wm = w_m * c_mk; + Wm.f++; + Wp.f--; + DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K); +} + +inline char* WriteExponent(int K, char* buffer) { + if (K < 0) { + *buffer++ = '-'; + K = -K; + } + + if (K >= 100) { + *buffer++ = static_cast('0' + static_cast(K / 100)); + K %= 100; + const char* d = GetDigitsLut() + K * 2; + *buffer++ = d[0]; + *buffer++ = d[1]; + } + else if (K >= 10) { + const char* d = GetDigitsLut() + K * 2; + *buffer++ = d[0]; + *buffer++ = d[1]; + } + else + *buffer++ = static_cast('0' + static_cast(K)); + + return buffer; +} + +inline char* Prettify(char* buffer, int length, int k) { + const int kk = length + k; // 10^(kk-1) <= v < 10^kk + + if (length <= kk && kk <= 21) { + // 1234e7 -> 12340000000 + for (int i = length; i < kk; i++) + buffer[i] = '0'; + buffer[kk] = '.'; + buffer[kk + 1] = '0'; + return &buffer[kk + 2]; + } + else if (0 < kk && kk <= 21) { + // 1234e-2 -> 12.34 + std::memmove(&buffer[kk + 1], &buffer[kk], length - kk); + buffer[kk] = '.'; + return &buffer[length + 1]; + } + else if (-6 < kk && kk <= 0) { + // 1234e-6 -> 0.001234 + const int offset = 2 - kk; + std::memmove(&buffer[offset], &buffer[0], length); + buffer[0] = '0'; + buffer[1] = '.'; + for (int i = 2; i < offset; i++) + buffer[i] = '0'; + return &buffer[length + offset]; + } + else if (length == 1) { + // 1e30 + buffer[1] = 'e'; + return WriteExponent(kk - 1, &buffer[2]); + } + else { + // 1234e30 -> 1.234e33 + std::memmove(&buffer[2], &buffer[1], length - 1); + buffer[1] = '.'; + buffer[length + 1] = 'e'; + return WriteExponent(kk - 1, &buffer[0 + length + 2]); + } +} + +inline char* dtoa(double value, char* buffer) { + if (value == 0) { + buffer[0] = '0'; + buffer[1] = '.'; + buffer[2] = '0'; + return &buffer[3]; + } + else { + if (value < 0) { + *buffer++ = '-'; + value = -value; + } + int length, K; + Grisu2(value, buffer, &length, &K); + return Prettify(buffer, length, K); + } +} + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +} // namespace internal +} // namespace rapidjson + +#endif // RAPIDJSON_DTOA_ diff --git a/external/rapidjson/internal/itoa.h b/external/rapidjson/internal/itoa.h new file mode 100644 index 000000000..425e9830c --- /dev/null +++ b/external/rapidjson/internal/itoa.h @@ -0,0 +1,306 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_ITOA_ +#define RAPIDJSON_ITOA_ + +namespace rapidjson { +namespace internal { + +inline const char* GetDigitsLut() { + static const char cDigitsLut[200] = { + '0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9', + '1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9', + '2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9', + '3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9', + '4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9', + '5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9', + '6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9', + '7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9', + '8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9', + '9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9' + }; + return cDigitsLut; +} + +inline char* u32toa(uint32_t value, char* buffer) { + const char* cDigitsLut = GetDigitsLut(); + + if (value < 10000) { + const uint32_t d1 = (value / 100) << 1; + const uint32_t d2 = (value % 100) << 1; + + if (value >= 1000) + *buffer++ = cDigitsLut[d1]; + if (value >= 100) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 10) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + } + else if (value < 100000000) { + // value = bbbbcccc + const uint32_t b = value / 10000; + const uint32_t c = value % 10000; + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + if (value >= 10000000) + *buffer++ = cDigitsLut[d1]; + if (value >= 1000000) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 100000) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + else { + // value = aabbbbcccc in decimal + + const uint32_t a = value / 100000000; // 1 to 42 + value %= 100000000; + + if (a >= 10) { + const unsigned i = a << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else + *buffer++ = static_cast('0' + static_cast(a)); + + const uint32_t b = value / 10000; // 0 to 9999 + const uint32_t c = value % 10000; // 0 to 9999 + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + *buffer++ = cDigitsLut[d1]; + *buffer++ = cDigitsLut[d1 + 1]; + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + return buffer; +} + +inline char* i32toa(int32_t value, char* buffer) { + if (value < 0) { + *buffer++ = '-'; + value = -value; + } + + return u32toa(static_cast(value), buffer); +} + +inline char* u64toa(uint64_t value, char* buffer) { + const char* cDigitsLut = GetDigitsLut(); + const uint64_t kTen8 = 100000000; + const uint64_t kTen9 = kTen8 * 10; + const uint64_t kTen10 = kTen8 * 100; + const uint64_t kTen11 = kTen8 * 1000; + const uint64_t kTen12 = kTen8 * 10000; + const uint64_t kTen13 = kTen8 * 100000; + const uint64_t kTen14 = kTen8 * 1000000; + const uint64_t kTen15 = kTen8 * 10000000; + const uint64_t kTen16 = kTen8 * kTen8; + + if (value < kTen8) { + uint32_t v = static_cast(value); + if (v < 10000) { + const uint32_t d1 = (v / 100) << 1; + const uint32_t d2 = (v % 100) << 1; + + if (v >= 1000) + *buffer++ = cDigitsLut[d1]; + if (v >= 100) + *buffer++ = cDigitsLut[d1 + 1]; + if (v >= 10) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + } + else { + // value = bbbbcccc + const uint32_t b = v / 10000; + const uint32_t c = v % 10000; + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + if (value >= 10000000) + *buffer++ = cDigitsLut[d1]; + if (value >= 1000000) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 100000) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + } + else if (value < kTen16) { + const uint32_t v0 = static_cast(value / kTen8); + const uint32_t v1 = static_cast(value % kTen8); + + const uint32_t b0 = v0 / 10000; + const uint32_t c0 = v0 % 10000; + + const uint32_t d1 = (b0 / 100) << 1; + const uint32_t d2 = (b0 % 100) << 1; + + const uint32_t d3 = (c0 / 100) << 1; + const uint32_t d4 = (c0 % 100) << 1; + + const uint32_t b1 = v1 / 10000; + const uint32_t c1 = v1 % 10000; + + const uint32_t d5 = (b1 / 100) << 1; + const uint32_t d6 = (b1 % 100) << 1; + + const uint32_t d7 = (c1 / 100) << 1; + const uint32_t d8 = (c1 % 100) << 1; + + if (value >= kTen15) + *buffer++ = cDigitsLut[d1]; + if (value >= kTen14) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= kTen13) + *buffer++ = cDigitsLut[d2]; + if (value >= kTen12) + *buffer++ = cDigitsLut[d2 + 1]; + if (value >= kTen11) + *buffer++ = cDigitsLut[d3]; + if (value >= kTen10) + *buffer++ = cDigitsLut[d3 + 1]; + if (value >= kTen9) + *buffer++ = cDigitsLut[d4]; + if (value >= kTen8) + *buffer++ = cDigitsLut[d4 + 1]; + + *buffer++ = cDigitsLut[d5]; + *buffer++ = cDigitsLut[d5 + 1]; + *buffer++ = cDigitsLut[d6]; + *buffer++ = cDigitsLut[d6 + 1]; + *buffer++ = cDigitsLut[d7]; + *buffer++ = cDigitsLut[d7 + 1]; + *buffer++ = cDigitsLut[d8]; + *buffer++ = cDigitsLut[d8 + 1]; + } + else { + const uint32_t a = static_cast(value / kTen16); // 1 to 1844 + value %= kTen16; + + if (a < 10) + *buffer++ = static_cast('0' + static_cast(a)); + else if (a < 100) { + const uint32_t i = a << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else if (a < 1000) { + *buffer++ = static_cast('0' + static_cast(a / 100)); + + const uint32_t i = (a % 100) << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else { + const uint32_t i = (a / 100) << 1; + const uint32_t j = (a % 100) << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + *buffer++ = cDigitsLut[j]; + *buffer++ = cDigitsLut[j + 1]; + } + + const uint32_t v0 = static_cast(value / kTen8); + const uint32_t v1 = static_cast(value % kTen8); + + const uint32_t b0 = v0 / 10000; + const uint32_t c0 = v0 % 10000; + + const uint32_t d1 = (b0 / 100) << 1; + const uint32_t d2 = (b0 % 100) << 1; + + const uint32_t d3 = (c0 / 100) << 1; + const uint32_t d4 = (c0 % 100) << 1; + + const uint32_t b1 = v1 / 10000; + const uint32_t c1 = v1 % 10000; + + const uint32_t d5 = (b1 / 100) << 1; + const uint32_t d6 = (b1 % 100) << 1; + + const uint32_t d7 = (c1 / 100) << 1; + const uint32_t d8 = (c1 % 100) << 1; + + *buffer++ = cDigitsLut[d1]; + *buffer++ = cDigitsLut[d1 + 1]; + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + *buffer++ = cDigitsLut[d5]; + *buffer++ = cDigitsLut[d5 + 1]; + *buffer++ = cDigitsLut[d6]; + *buffer++ = cDigitsLut[d6 + 1]; + *buffer++ = cDigitsLut[d7]; + *buffer++ = cDigitsLut[d7 + 1]; + *buffer++ = cDigitsLut[d8]; + *buffer++ = cDigitsLut[d8 + 1]; + } + + return buffer; +} + +inline char* i64toa(int64_t value, char* buffer) { + if (value < 0) { + *buffer++ = '-'; + value = -value; + } + + return u64toa(static_cast(value), buffer); +} + +} // namespace internal +} // namespace rapidjson + +#endif // RAPIDJSON_ITOA_ diff --git a/external/rapidjson/internal/meta.h b/external/rapidjson/internal/meta.h new file mode 100644 index 000000000..dbe5450d6 --- /dev/null +++ b/external/rapidjson/internal/meta.h @@ -0,0 +1,189 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_INTERNAL_META_H_ +#define RAPIDJSON_INTERNAL_META_H_ + +#ifndef RAPIDJSON_RAPIDJSON_H_ +#error not yet included. Do not include this file directly. +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif +#if defined(_MSC_VER) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(6334) +#endif + +#if RAPIDJSON_HAS_CXX11_TYPETRAITS +#include +#endif + +//@cond RAPIDJSON_INTERNAL +namespace rapidjson { +namespace internal { + +// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching +template struct Void { typedef void Type; }; + +/////////////////////////////////////////////////////////////////////////////// +// BoolType, TrueType, FalseType +// +template struct BoolType { + static const bool Value = Cond; + typedef BoolType Type; +}; +typedef BoolType TrueType; +typedef BoolType FalseType; + + +/////////////////////////////////////////////////////////////////////////////// +// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr +// + +template struct SelectIfImpl { template struct Apply { typedef T1 Type; }; }; +template <> struct SelectIfImpl { template struct Apply { typedef T2 Type; }; }; +template struct SelectIfCond : SelectIfImpl::template Apply {}; +template struct SelectIf : SelectIfCond {}; + +template struct AndExprCond : FalseType {}; +template <> struct AndExprCond : TrueType {}; +template struct OrExprCond : TrueType {}; +template <> struct OrExprCond : FalseType {}; + +template struct BoolExpr : SelectIf::Type {}; +template struct NotExpr : SelectIf::Type {}; +template struct AndExpr : AndExprCond::Type {}; +template struct OrExpr : OrExprCond::Type {}; + + +/////////////////////////////////////////////////////////////////////////////// +// AddConst, MaybeAddConst, RemoveConst +template struct AddConst { typedef const T Type; }; +template struct MaybeAddConst : SelectIfCond {}; +template struct RemoveConst { typedef T Type; }; +template struct RemoveConst { typedef T Type; }; + + +/////////////////////////////////////////////////////////////////////////////// +// IsSame, IsConst, IsMoreConst, IsPointer +// +template struct IsSame : FalseType {}; +template struct IsSame : TrueType {}; + +template struct IsConst : FalseType {}; +template struct IsConst : TrueType {}; + +template +struct IsMoreConst + : AndExpr::Type, typename RemoveConst::Type>, + BoolType::Value >= IsConst::Value> >::Type {}; + +template struct IsPointer : FalseType {}; +template struct IsPointer : TrueType {}; + +/////////////////////////////////////////////////////////////////////////////// +// IsBaseOf +// +#if RAPIDJSON_HAS_CXX11_TYPETRAITS + +template struct IsBaseOf + : BoolType< ::std::is_base_of::value> {}; + +#else // simplified version adopted from Boost + +template struct IsBaseOfImpl { + RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0); + RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0); + + typedef char (&Yes)[1]; + typedef char (&No) [2]; + + template + static Yes Check(const D*, T); + static No Check(const B*, int); + + struct Host { + operator const B*() const; + operator const D*(); + }; + + enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) }; +}; + +template struct IsBaseOf + : OrExpr, BoolExpr > >::Type {}; + +#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS + + +////////////////////////////////////////////////////////////////////////// +// EnableIf / DisableIf +// +template struct EnableIfCond { typedef T Type; }; +template struct EnableIfCond { /* empty */ }; + +template struct DisableIfCond { typedef T Type; }; +template struct DisableIfCond { /* empty */ }; + +template +struct EnableIf : EnableIfCond {}; + +template +struct DisableIf : DisableIfCond {}; + +// SFINAE helpers +struct SfinaeTag {}; +template struct RemoveSfinaeTag; +template struct RemoveSfinaeTag { typedef T Type; }; + +#define RAPIDJSON_REMOVEFPTR_(type) \ + typename ::rapidjson::internal::RemoveSfinaeTag \ + < ::rapidjson::internal::SfinaeTag&(*) type>::Type + +#define RAPIDJSON_ENABLEIF(cond) \ + typename ::rapidjson::internal::EnableIf \ + ::Type * = NULL + +#define RAPIDJSON_DISABLEIF(cond) \ + typename ::rapidjson::internal::DisableIf \ + ::Type * = NULL + +#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \ + typename ::rapidjson::internal::EnableIf \ + ::Type + +#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \ + typename ::rapidjson::internal::DisableIf \ + ::Type + +} // namespace internal +} // namespace rapidjson +//@endcond + +#if defined(__GNUC__) || defined(_MSC_VER) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_INTERNAL_META_H_ diff --git a/external/rapidjson/internal/pow10.h b/external/rapidjson/internal/pow10.h new file mode 100644 index 000000000..72e0dac9f --- /dev/null +++ b/external/rapidjson/internal/pow10.h @@ -0,0 +1,59 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_POW10_ +#define RAPIDJSON_POW10_ + +namespace rapidjson { +namespace internal { + +//! Computes integer powers of 10 in double (10.0^n). +/*! This function uses lookup table for fast and accurate results. + \param n non-negative exponent. Must <= 308. + \return 10.0^n +*/ +inline double Pow10(int n) { + static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes + 1e+0, + 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, + 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, + 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, + 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, + 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, + 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, + 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, + 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, + 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, + 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, + 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, + 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, + 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, + 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, + 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, + 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 + }; + RAPIDJSON_ASSERT(n >= 0 && n <= 308); + return e[n]; +} + +} // namespace internal +} // namespace rapidjson + +#endif // RAPIDJSON_POW10_ diff --git a/external/rapidjson/internal/stack.h b/external/rapidjson/internal/stack.h new file mode 100644 index 000000000..d4d3c92de --- /dev/null +++ b/external/rapidjson/internal/stack.h @@ -0,0 +1,137 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_INTERNAL_STACK_H_ +#define RAPIDJSON_INTERNAL_STACK_H_ + +namespace rapidjson { +namespace internal { + +/////////////////////////////////////////////////////////////////////////////// +// Stack + +//! A type-unsafe stack for storing different types of data. +/*! \tparam Allocator Allocator for allocating stack memory. +*/ +template +class Stack { +public: + // Optimization note: Do not allocate memory for stack_ in constructor. + // Do it lazily when first Push() -> Expand() -> Resize(). + Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) { + RAPIDJSON_ASSERT(stackCapacity > 0); + if (!allocator_) + ownAllocator = allocator_ = new Allocator(); + } + + ~Stack() { + Allocator::Free(stack_); + delete ownAllocator; // Only delete if it is owned by the stack + } + + void Clear() { stackTop_ = stack_; } + + void ShrinkToFit() { + if (Empty()) { + // If the stack is empty, completely deallocate the memory. + Allocator::Free(stack_); + stack_ = 0; + stackTop_ = 0; + stackEnd_ = 0; + } + else + Resize(GetSize()); + } + + // Optimization note: try to minimize the size of this function for force inline. + // Expansion is run very infrequently, so it is moved to another (probably non-inline) function. + template + RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) { + // Expand the stack if needed + if (stackTop_ + sizeof(T) * count >= stackEnd_) + Expand(count); + + T* ret = reinterpret_cast(stackTop_); + stackTop_ += sizeof(T) * count; + return ret; + } + + template + T* Pop(size_t count) { + RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T)); + stackTop_ -= count * sizeof(T); + return reinterpret_cast(stackTop_); + } + + template + T* Top() { + RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); + return reinterpret_cast(stackTop_ - sizeof(T)); + } + + template + T* Bottom() { return (T*)stack_; } + + Allocator& GetAllocator() { return *allocator_; } + bool Empty() const { return stackTop_ == stack_; } + size_t GetSize() const { return static_cast(stackTop_ - stack_); } + size_t GetCapacity() const { return static_cast(stackEnd_ - stack_); } + +private: + template + void Expand(size_t count) { + // Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity. + size_t newCapacity; + if (stack_ == 0) + newCapacity = initialCapacity_; + else { + newCapacity = GetCapacity(); + newCapacity += (newCapacity + 1) / 2; + } + size_t newSize = GetSize() + sizeof(T) * count; + if (newCapacity < newSize) + newCapacity = newSize; + + Resize(newCapacity); + } + + void Resize(size_t newCapacity) { + const size_t size = GetSize(); // Backup the current size + stack_ = (char*)allocator_->Realloc(stack_, GetCapacity(), newCapacity); + stackTop_ = stack_ + size; + stackEnd_ = stack_ + newCapacity; + } + + // Prohibit copy constructor & assignment operator. + Stack(const Stack&); + Stack& operator=(const Stack&); + + Allocator* allocator_; + Allocator* ownAllocator; + char *stack_; + char *stackTop_; + char *stackEnd_; + size_t initialCapacity_; +}; + +} // namespace internal +} // namespace rapidjson + +#endif // RAPIDJSON_STACK_H_ diff --git a/external/rapidjson/internal/strfunc.h b/external/rapidjson/internal/strfunc.h new file mode 100644 index 000000000..80adcb6b7 --- /dev/null +++ b/external/rapidjson/internal/strfunc.h @@ -0,0 +1,43 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_ +#define RAPIDJSON_INTERNAL_STRFUNC_H_ + +namespace rapidjson { +namespace internal { + +//! Custom strlen() which works on different character types. +/*! \tparam Ch Character type (e.g. char, wchar_t, short) + \param s Null-terminated input string. + \return Number of characters in the string. + \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. +*/ +template +inline SizeType StrLen(const Ch* s) { + const Ch* p = s; + while (*p) ++p; + return SizeType(p - s); +} + +} // namespace internal +} // namespace rapidjson + +#endif // RAPIDJSON_INTERNAL_STRFUNC_H_ diff --git a/external/rapidjson/memorybuffer.h b/external/rapidjson/memorybuffer.h new file mode 100644 index 000000000..ef15c4678 --- /dev/null +++ b/external/rapidjson/memorybuffer.h @@ -0,0 +1,76 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_MEMORYBUFFER_H_ +#define RAPIDJSON_MEMORYBUFFER_H_ + +#include "rapidjson.h" +#include "internal/stack.h" + +namespace rapidjson { + +//! Represents an in-memory output byte stream. +/*! + This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream. + + It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file. + + Differences between MemoryBuffer and StringBuffer: + 1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer. + 2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator. + + \tparam Allocator type for allocating memory buffer. + \note implements Stream concept +*/ +template +struct GenericMemoryBuffer { + typedef char Ch; // byte + + GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} + + void Put(Ch c) { *stack_.template Push() = c; } + void Flush() {} + + void Clear() { stack_.Clear(); } + void ShrinkToFit() { stack_.ShrinkToFit(); } + Ch* Push(size_t count) { return stack_.template Push(count); } + void Pop(size_t count) { stack_.template Pop(count); } + + const Ch* GetBuffer() const { + return stack_.template Bottom(); + } + + size_t GetSize() const { return stack_.GetSize(); } + + static const size_t kDefaultCapacity = 256; + mutable internal::Stack stack_; +}; + +typedef GenericMemoryBuffer<> MemoryBuffer; + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) { + std::memset(memoryBuffer.stack_.Push(n), c, n * sizeof(c)); +} + +} // namespace rapidjson + +#endif // RAPIDJSON_MEMORYBUFFER_H_ diff --git a/external/rapidjson/memorystream.h b/external/rapidjson/memorystream.h new file mode 100644 index 000000000..8701c33c5 --- /dev/null +++ b/external/rapidjson/memorystream.h @@ -0,0 +1,67 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_MEMORYSTREAM_H_ +#define RAPIDJSON_MEMORYSTREAM_H_ + +#include "rapidjson.h" + +namespace rapidjson { + +//! Represents an in-memory input byte stream. +/*! + This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream. + + It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file. + + Differences between MemoryStream and StringStream: + 1. StringStream has encoding but MemoryStream is a byte stream. + 2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source. + 3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4(). + \note implements Stream concept +*/ +struct MemoryStream { + typedef char Ch; // byte + + MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {} + + Ch Peek() const { return *src_; } + Ch Take() { return (src_ == end_) ? '\0' : *src_++; } + size_t Tell() const { return static_cast(src_ - begin_); } + + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + // For encoding detection only. + const Ch* Peek4() const { + return Tell() + 4 <= size_ ? src_ : 0; + } + + const Ch* src_; //!< Current read position. + const Ch* begin_; //!< Original head of the string. + const Ch* end_; //!< End of stream. + size_t size_; //!< Size of the stream. +}; + +} // namespace rapidjson + +#endif // RAPIDJSON_MEMORYBUFFER_H_ diff --git a/external/rapidjson/msinttypes/inttypes.h b/external/rapidjson/msinttypes/inttypes.h new file mode 100644 index 000000000..ac7e32b6e --- /dev/null +++ b/external/rapidjson/msinttypes/inttypes.h @@ -0,0 +1,306 @@ +// ISO C9x compliant inttypes.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2013 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the product nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_INTTYPES_H_ // [ +#define _MSC_INTTYPES_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include "stdint.h" + +// 7.8 Format conversion of integer types + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +// 7.8.1 Macros for format specifiers + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 + +// The fprintf macros for signed integers are: +#define PRId8 "d" +#define PRIi8 "i" +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIdLEAST16 "hd" +#define PRIiLEAST16 "hi" +#define PRIdFAST16 "hd" +#define PRIiFAST16 "hi" + +#define PRId32 "I32d" +#define PRIi32 "I32i" +#define PRIdLEAST32 "I32d" +#define PRIiLEAST32 "I32i" +#define PRIdFAST32 "I32d" +#define PRIiFAST32 "I32i" + +#define PRId64 "I64d" +#define PRIi64 "I64i" +#define PRIdLEAST64 "I64d" +#define PRIiLEAST64 "I64i" +#define PRIdFAST64 "I64d" +#define PRIiFAST64 "I64i" + +#define PRIdMAX "I64d" +#define PRIiMAX "I64i" + +#define PRIdPTR "Id" +#define PRIiPTR "Ii" + +// The fprintf macros for unsigned integers are: +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" + +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" +#define PRIoLEAST16 "ho" +#define PRIuLEAST16 "hu" +#define PRIxLEAST16 "hx" +#define PRIXLEAST16 "hX" +#define PRIoFAST16 "ho" +#define PRIuFAST16 "hu" +#define PRIxFAST16 "hx" +#define PRIXFAST16 "hX" + +#define PRIo32 "I32o" +#define PRIu32 "I32u" +#define PRIx32 "I32x" +#define PRIX32 "I32X" +#define PRIoLEAST32 "I32o" +#define PRIuLEAST32 "I32u" +#define PRIxLEAST32 "I32x" +#define PRIXLEAST32 "I32X" +#define PRIoFAST32 "I32o" +#define PRIuFAST32 "I32u" +#define PRIxFAST32 "I32x" +#define PRIXFAST32 "I32X" + +#define PRIo64 "I64o" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#define PRIX64 "I64X" +#define PRIoLEAST64 "I64o" +#define PRIuLEAST64 "I64u" +#define PRIxLEAST64 "I64x" +#define PRIXLEAST64 "I64X" +#define PRIoFAST64 "I64o" +#define PRIuFAST64 "I64u" +#define PRIxFAST64 "I64x" +#define PRIXFAST64 "I64X" + +#define PRIoMAX "I64o" +#define PRIuMAX "I64u" +#define PRIxMAX "I64x" +#define PRIXMAX "I64X" + +#define PRIoPTR "Io" +#define PRIuPTR "Iu" +#define PRIxPTR "Ix" +#define PRIXPTR "IX" + +// The fscanf macros for signed integers are: +#define SCNd8 "d" +#define SCNi8 "i" +#define SCNdLEAST8 "d" +#define SCNiLEAST8 "i" +#define SCNdFAST8 "d" +#define SCNiFAST8 "i" + +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNdLEAST16 "hd" +#define SCNiLEAST16 "hi" +#define SCNdFAST16 "hd" +#define SCNiFAST16 "hi" + +#define SCNd32 "ld" +#define SCNi32 "li" +#define SCNdLEAST32 "ld" +#define SCNiLEAST32 "li" +#define SCNdFAST32 "ld" +#define SCNiFAST32 "li" + +#define SCNd64 "I64d" +#define SCNi64 "I64i" +#define SCNdLEAST64 "I64d" +#define SCNiLEAST64 "I64i" +#define SCNdFAST64 "I64d" +#define SCNiFAST64 "I64i" + +#define SCNdMAX "I64d" +#define SCNiMAX "I64i" + +#ifdef _WIN64 // [ +# define SCNdPTR "I64d" +# define SCNiPTR "I64i" +#else // _WIN64 ][ +# define SCNdPTR "ld" +# define SCNiPTR "li" +#endif // _WIN64 ] + +// The fscanf macros for unsigned integers are: +#define SCNo8 "o" +#define SCNu8 "u" +#define SCNx8 "x" +#define SCNX8 "X" +#define SCNoLEAST8 "o" +#define SCNuLEAST8 "u" +#define SCNxLEAST8 "x" +#define SCNXLEAST8 "X" +#define SCNoFAST8 "o" +#define SCNuFAST8 "u" +#define SCNxFAST8 "x" +#define SCNXFAST8 "X" + +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" +#define SCNX16 "hX" +#define SCNoLEAST16 "ho" +#define SCNuLEAST16 "hu" +#define SCNxLEAST16 "hx" +#define SCNXLEAST16 "hX" +#define SCNoFAST16 "ho" +#define SCNuFAST16 "hu" +#define SCNxFAST16 "hx" +#define SCNXFAST16 "hX" + +#define SCNo32 "lo" +#define SCNu32 "lu" +#define SCNx32 "lx" +#define SCNX32 "lX" +#define SCNoLEAST32 "lo" +#define SCNuLEAST32 "lu" +#define SCNxLEAST32 "lx" +#define SCNXLEAST32 "lX" +#define SCNoFAST32 "lo" +#define SCNuFAST32 "lu" +#define SCNxFAST32 "lx" +#define SCNXFAST32 "lX" + +#define SCNo64 "I64o" +#define SCNu64 "I64u" +#define SCNx64 "I64x" +#define SCNX64 "I64X" +#define SCNoLEAST64 "I64o" +#define SCNuLEAST64 "I64u" +#define SCNxLEAST64 "I64x" +#define SCNXLEAST64 "I64X" +#define SCNoFAST64 "I64o" +#define SCNuFAST64 "I64u" +#define SCNxFAST64 "I64x" +#define SCNXFAST64 "I64X" + +#define SCNoMAX "I64o" +#define SCNuMAX "I64u" +#define SCNxMAX "I64x" +#define SCNXMAX "I64X" + +#ifdef _WIN64 // [ +# define SCNoPTR "I64o" +# define SCNuPTR "I64u" +# define SCNxPTR "I64x" +# define SCNXPTR "I64X" +#else // _WIN64 ][ +# define SCNoPTR "lo" +# define SCNuPTR "lu" +# define SCNxPTR "lx" +# define SCNXPTR "lX" +#endif // _WIN64 ] + +#endif // __STDC_FORMAT_MACROS ] + +// 7.8.2 Functions for greatest-width integer types + +// 7.8.2.1 The imaxabs function +#define imaxabs _abs64 + +// 7.8.2.2 The imaxdiv function + +// This is modified version of div() function from Microsoft's div.c found +// in %MSVC.NET%\crt\src\div.c +#ifdef STATIC_IMAXDIV // [ +static +#else // STATIC_IMAXDIV ][ +_inline +#endif // STATIC_IMAXDIV ] +imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) +{ + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } + + return result; +} + +// 7.8.2.3 The strtoimax and strtoumax functions +#define strtoimax _strtoi64 +#define strtoumax _strtoui64 + +// 7.8.2.4 The wcstoimax and wcstoumax functions +#define wcstoimax _wcstoi64 +#define wcstoumax _wcstoui64 + + +#endif // _MSC_INTTYPES_H_ ] diff --git a/external/rapidjson/msinttypes/stdint.h b/external/rapidjson/msinttypes/stdint.h new file mode 100644 index 000000000..bbad95af1 --- /dev/null +++ b/external/rapidjson/msinttypes/stdint.h @@ -0,0 +1,296 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2013 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the product nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +// miloyip: Originally Visual Studio 2010 uses its own stdint.h. However it generates warning with INT64_C(), so change to use this file for vs2010. +#if _MSC_VER >= 1600 // [ +#include + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +#undef INT8_C +#undef INT16_C +#undef INT32_C +#undef INT64_C +#undef UINT8_C +#undef UINT16_C +#undef UINT32_C +#undef UINT64_C + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +// These #ifndef's are needed to prevent collisions with . +// Check out Issue 9 for the details. +#ifndef INTMAX_C // [ +# define INTMAX_C INT64_C +#endif // INTMAX_C ] +#ifndef UINTMAX_C // [ +# define UINTMAX_C UINT64_C +#endif // UINTMAX_C ] + +#endif // __STDC_CONSTANT_MACROS ] + +#else // ] _MSC_VER >= 1700 [ + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +// These #ifndef's are needed to prevent collisions with . +// Check out Issue 9 for the details. +#ifndef INTMAX_C // [ +# define INTMAX_C INT64_C +#endif // INTMAX_C ] +#ifndef UINTMAX_C // [ +# define UINTMAX_C UINT64_C +#endif // UINTMAX_C ] + +#endif // __STDC_CONSTANT_MACROS ] + +#endif // _MSC_VER >= 1600 ] + +#endif // _MSC_STDINT_H_ ] diff --git a/external/rapidjson/prettywriter.h b/external/rapidjson/prettywriter.h new file mode 100644 index 000000000..4eac8d76f --- /dev/null +++ b/external/rapidjson/prettywriter.h @@ -0,0 +1,205 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_PRETTYWRITER_H_ +#define RAPIDJSON_PRETTYWRITER_H_ + +#include "writer.h" + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +namespace rapidjson { + +//! Writer with indentation and spacing. +/*! + \tparam OutputStream Type of ouptut os. + \tparam SourceEncoding Encoding of source string. + \tparam TargetEncoding Encoding of output stream. + \tparam StackAllocator Type of allocator for allocating memory of stack. +*/ +template, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator> +class PrettyWriter : public Writer { +public: + typedef Writer Base; + typedef typename Base::Ch Ch; + + //! Constructor + /*! \param os Output stream. + \param allocator User supplied allocator. If it is null, it will create a private one. + \param levelDepth Initial capacity of stack. + */ + PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : + Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {} + + //! Set custom indentation. + /*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r'). + \param indentCharCount Number of indent characters for each indentation level. + \note The default indentation is 4 spaces. + */ + PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) { + RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r'); + indentChar_ = indentChar; + indentCharCount_ = indentCharCount; + return *this; + } + + /*! @name Implementation of Handler + \see Handler + */ + //@{ + + bool Null() { PrettyPrefix(kNullType); return Base::WriteNull(); } + bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); } + bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteInt(i); } + bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::WriteUint(u); } + bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); } + bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::WriteUint64(u64); } + bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteDouble(d); } + + bool String(const Ch* str, SizeType length, bool copy = false) { + (void)copy; + PrettyPrefix(kStringType); + return Base::WriteString(str, length); + } + + bool StartObject() { + PrettyPrefix(kObjectType); + new (Base::level_stack_.template Push()) typename Base::Level(false); + return Base::WriteStartObject(); + } + + bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } + + bool EndObject(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); + RAPIDJSON_ASSERT(!Base::level_stack_.template Top()->inArray); + bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; + + if (!empty) { + Base::os_->Put('\n'); + WriteIndent(); + } + if (!Base::WriteEndObject()) + return false; + if (Base::level_stack_.Empty()) // end of json text + Base::os_->Flush(); + return true; + } + + bool StartArray() { + PrettyPrefix(kArrayType); + new (Base::level_stack_.template Push()) typename Base::Level(true); + return Base::WriteStartArray(); + } + + bool EndArray(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); + RAPIDJSON_ASSERT(Base::level_stack_.template Top()->inArray); + bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; + + if (!empty) { + Base::os_->Put('\n'); + WriteIndent(); + } + if (!Base::WriteEndArray()) + return false; + if (Base::level_stack_.Empty()) // end of json text + Base::os_->Flush(); + return true; + } + + //@} + + /*! @name Convenience extensions */ + //@{ + + //! Simpler but slower overload. + bool String(const Ch* str) { return String(str, internal::StrLen(str)); } + bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); } + + //@} +protected: + void PrettyPrefix(Type type) { + (void)type; + if (Base::level_stack_.GetSize() != 0) { // this value is not at root + typename Base::Level* level = Base::level_stack_.template Top(); + + if (level->inArray) { + if (level->valueCount > 0) { + Base::os_->Put(','); // add comma if it is not the first element in array + Base::os_->Put('\n'); + } + else + Base::os_->Put('\n'); + WriteIndent(); + } + else { // in object + if (level->valueCount > 0) { + if (level->valueCount % 2 == 0) { + Base::os_->Put(','); + Base::os_->Put('\n'); + } + else { + Base::os_->Put(':'); + Base::os_->Put(' '); + } + } + else + Base::os_->Put('\n'); + + if (level->valueCount % 2 == 0) + WriteIndent(); + } + if (!level->inArray && level->valueCount % 2 == 0) + RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name + level->valueCount++; + } + else { + RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root. + Base::hasRoot_ = true; + } + } + + void WriteIndent() { + size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_; + PutN(*Base::os_, indentChar_, count); + } + + Ch indentChar_; + unsigned indentCharCount_; + +private: + // Prohibit copy constructor & assignment operator. + PrettyWriter(const PrettyWriter&); + PrettyWriter& operator=(const PrettyWriter&); +}; + +} // namespace rapidjson + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/external/rapidjson/rapidjson.h b/external/rapidjson/rapidjson.h new file mode 100644 index 000000000..3f743234d --- /dev/null +++ b/external/rapidjson/rapidjson.h @@ -0,0 +1,567 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_RAPIDJSON_H_ +#define RAPIDJSON_RAPIDJSON_H_ + +// Copyright (c) 2011 Milo Yip (miloyip@gmail.com) +// Version 0.1 + +/*!\file rapidjson.h + \brief common definitions and configuration + + \see RAPIDJSON_CONFIG + */ + +/*! \defgroup RAPIDJSON_CONFIG RapidJSON configuration + \brief Configuration macros for library features + + Some RapidJSON features are configurable to adapt the library to a wide + variety of platforms, environments and usage scenarios. Most of the + features can be configured in terms of overriden or predefined + preprocessor macros at compile-time. + + Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs. + + \note These macros should be given on the compiler command-line + (where applicable) to avoid inconsistent values when compiling + different translation units of a single application. + */ + +#include // malloc(), realloc(), free(), size_t +#include // memset(), memcpy(), memmove(), memcmp() + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NO_INT64DEFINE + +/*! \def RAPIDJSON_NO_INT64DEFINE + \ingroup RAPIDJSON_CONFIG + \brief Use external 64-bit integer types. + + RapidJSON requires the 64-bit integer types \c int64_t and \c uint64_t types + to be available at global scope. + + If users have their own definition, define RAPIDJSON_NO_INT64DEFINE to + prevent RapidJSON from defining its own types. +*/ +#ifndef RAPIDJSON_NO_INT64DEFINE +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#ifdef _MSC_VER +#include "msinttypes/stdint.h" +#include "msinttypes/inttypes.h" +#else +// Other compilers should have this. +#include +#include +#endif +//!@endcond +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_NO_INT64DEFINE +#endif +#endif // RAPIDJSON_NO_INT64TYPEDEF + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_FORCEINLINE + +#ifndef RAPIDJSON_FORCEINLINE +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#ifdef _MSC_VER +#define RAPIDJSON_FORCEINLINE __forceinline +#elif defined(__GNUC__) && __GNUC__ >= 4 +#define RAPIDJSON_FORCEINLINE __attribute__((always_inline)) +#else +#define RAPIDJSON_FORCEINLINE +#endif +//!@endcond +#endif // RAPIDJSON_FORCEINLINE + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ENDIAN +#define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine +#define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine + +//! Endianness of the machine. +/*! + \def RAPIDJSON_ENDIAN + \ingroup RAPIDJSON_CONFIG + + GCC 4.6 provided macro for detecting endianness of the target machine. But other + compilers may not have this. User can define RAPIDJSON_ENDIAN to either + \ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN. + + Default detection implemented with reference to + \li https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html + \li http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp +*/ +#ifndef RAPIDJSON_ENDIAN +// Detect with GCC 4.6's macro +# ifdef __BYTE_ORDER__ +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# else +# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. +# endif // __BYTE_ORDER__ +// Detect with GLIBC's endian.h +# elif defined(__GLIBC__) +# include +# if (__BYTE_ORDER == __LITTLE_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif (__BYTE_ORDER == __BIG_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# else +# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. +# endif // __GLIBC__ +// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro +# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +// Detect with architecture macros +# elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif defined(RAPIDJSON_DOXYGEN_RUNNING) +# define RAPIDJSON_ENDIAN +# else +# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. +# endif +#endif // RAPIDJSON_ENDIAN + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_64BIT + +//! Whether using 64-bit architecture +#ifndef RAPIDJSON_64BIT +#if defined(__LP64__) || defined(_WIN64) +#define RAPIDJSON_64BIT 1 +#else +#define RAPIDJSON_64BIT 0 +#endif +#endif // RAPIDJSON_64BIT + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ALIGN + +//! Data alignment of the machine. +/*! \ingroup RAPIDJSON_CONFIG + \param x pointer to align + + Some machines require strict data alignment. Currently the default uses 4 bytes + alignment. User can customize by defining the RAPIDJSON_ALIGN function macro., +*/ +#ifndef RAPIDJSON_ALIGN +#define RAPIDJSON_ALIGN(x) ((x + 3u) & ~3u) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_UINT64_C2 + +//! Construct a 64-bit literal by a pair of 32-bit integer. +/*! + 64-bit literal with or without ULL suffix is prone to compiler warnings. + UINT64_C() is C macro which cause compilation problems. + Use this macro to define 64-bit constants by a pair of 32-bit integer. +*/ +#ifndef RAPIDJSON_UINT64_C2 +#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast(high32) << 32) | static_cast(low32)) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD + +/*! \def RAPIDJSON_SIMD + \ingroup RAPIDJSON_CONFIG + \brief Enable SSE2/SSE4.2 optimization. + + RapidJSON supports optimized implementations for some parsing operations + based on the SSE2 or SSE4.2 SIMD extensions on modern Intel-compatible + processors. + + To enable these optimizations, two different symbols can be defined; + \code + // Enable SSE2 optimization. + #define RAPIDJSON_SSE2 + + // Enable SSE4.2 optimization. + #define RAPIDJSON_SSE42 + \endcode + + \c RAPIDJSON_SSE42 takes precedence, if both are defined. + + If any of these symbols is defined, RapidJSON defines the macro + \c RAPIDJSON_SIMD to indicate the availability of the optimized code. +*/ +#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \ + || defined(RAPIDJSON_DOXYGEN_RUNNING) +#define RAPIDJSON_SIMD +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NO_SIZETYPEDEFINE + +#ifndef RAPIDJSON_NO_SIZETYPEDEFINE +/*! \def RAPIDJSON_NO_SIZETYPEDEFINE + \ingroup RAPIDJSON_CONFIG + \brief User-provided \c SizeType definition. + + In order to avoid using 32-bit size types for indexing strings and arrays, + define this preprocessor symbol and provide the type rapidjson::SizeType + before including RapidJSON: + \code + #define RAPIDJSON_NO_SIZETYPEDEFINE + namespace rapidjson { typedef ::std::size_t SizeType; } + #include "rapidjson/..." + \endcode + + \see rapidjson::SizeType +*/ +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_NO_SIZETYPEDEFINE +#endif +namespace rapidjson { +//! Size type (for string lengths, array sizes, etc.) +/*! RapidJSON uses 32-bit array/string indices even on 64-bit platforms, + instead of using \c size_t. Users may override the SizeType by defining + \ref RAPIDJSON_NO_SIZETYPEDEFINE. +*/ +typedef unsigned SizeType; +} // namespace rapidjson +#endif + +// always import std::size_t to rapidjson namespace +namespace rapidjson { +using std::size_t; +} // namespace rapidjson + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ASSERT + +//! Assertion. +/*! \ingroup RAPIDJSON_CONFIG + By default, rapidjson uses C \c assert() for internal assertions. + User can override it by defining RAPIDJSON_ASSERT(x) macro. + + \note Parsing errors are handled and can be customized by the + \ref RAPIDJSON_ERRORS APIs. +*/ +#ifndef RAPIDJSON_ASSERT +#include +#define RAPIDJSON_ASSERT(x) assert(x) +#endif // RAPIDJSON_ASSERT + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_STATIC_ASSERT + +// Adopt from boost +#ifndef RAPIDJSON_STATIC_ASSERT +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +namespace rapidjson { + +template struct STATIC_ASSERTION_FAILURE; +template <> struct STATIC_ASSERTION_FAILURE { enum { value = 1 }; }; +template struct StaticAssertTest {}; +} // namespace rapidjson + +#define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y) +#define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y) +#define RAPIDJSON_DO_JOIN2(X, Y) X##Y + +#if defined(__GNUC__) +#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused)) +#else +#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE +#endif +//!@endcond + +/*! \def RAPIDJSON_STATIC_ASSERT + \brief (Internal) macro to check for conditions at compile-time + \param x compile-time condition + \hideinitializer + */ +#define RAPIDJSON_STATIC_ASSERT(x) typedef ::rapidjson::StaticAssertTest<\ + sizeof(::rapidjson::STATIC_ASSERTION_FAILURE)>\ + RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Helpers + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN + +#define RAPIDJSON_MULTILINEMACRO_BEGIN do { +#define RAPIDJSON_MULTILINEMACRO_END \ +} while((void)0, 0) + +// adopted from Boost +#define RAPIDJSON_VERSION_CODE(x,y,z) \ + (((x)*100000) + ((y)*100) + (z)) + +// token stringification +#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x) +#define RAPIDJSON_DO_STRINGIFY(x) #x + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF + +#if defined(__GNUC__) +#define RAPIDJSON_GNUC \ + RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) +#endif + +#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,2,0)) + +#define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x)) +#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x) +#define RAPIDJSON_DIAG_OFF(x) \ + RAPIDJSON_DIAG_PRAGMA(ignored RAPIDJSON_STRINGIFY(RAPIDJSON_JOIN(-W,x))) + +// push/pop support in Clang and GCC>=4.6 +#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) +#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) +#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) +#else // GCC >= 4.2, < 4.6 +#define RAPIDJSON_DIAG_PUSH /* ignored */ +#define RAPIDJSON_DIAG_POP /* ignored */ +#endif + +#elif defined(_MSC_VER) + +// pragma (MSVC specific) +#define RAPIDJSON_PRAGMA(x) __pragma(x) +#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x)) + +#define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x) +#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) +#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) + +#else + +#define RAPIDJSON_DIAG_OFF(x) /* ignored */ +#define RAPIDJSON_DIAG_PUSH /* ignored */ +#define RAPIDJSON_DIAG_POP /* ignored */ + +#endif // RAPIDJSON_DIAG_* + +/////////////////////////////////////////////////////////////////////////////// +// C++11 features + +#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS +#if defined(__clang__) +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS __has_feature(cxx_rvalue_references) +#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ + (defined(_MSC_VER) && _MSC_VER >= 1600) + +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 +#else +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 +#endif +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + +#ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT +#if defined(__clang__) +#define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept) +#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) +// (defined(_MSC_VER) && _MSC_VER >= ????) // not yet supported +#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1 +#else +#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0 +#endif +#endif +#if RAPIDJSON_HAS_CXX11_NOEXCEPT +#define RAPIDJSON_NOEXCEPT noexcept +#else +#define RAPIDJSON_NOEXCEPT /* noexcept */ +#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT + +// no automatic detection, yet +#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS +#define RAPIDJSON_HAS_CXX11_TYPETRAITS 0 +#endif + +//!@endcond + +/////////////////////////////////////////////////////////////////////////////// +// Allocators and Encodings + +#include "allocators.h" +#include "encodings.h" + +//! main RapidJSON namespace +namespace rapidjson { + +/////////////////////////////////////////////////////////////////////////////// +// Stream + +/*! \class rapidjson::Stream + \brief Concept for reading and writing characters. + + For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd(). + + For write-only stream, only need to implement Put() and Flush(). + +\code +concept Stream { + typename Ch; //!< Character type of the stream. + + //! Read the current character from stream without moving the read cursor. + Ch Peek() const; + + //! Read the current character from stream and moving the read cursor to next character. + Ch Take(); + + //! Get the current read cursor. + //! \return Number of characters read from start. + size_t Tell(); + + //! Begin writing operation at the current read pointer. + //! \return The begin writer pointer. + Ch* PutBegin(); + + //! Write a character. + void Put(Ch c); + + //! Flush the buffer. + void Flush(); + + //! End the writing operation. + //! \param begin The begin write pointer returned by PutBegin(). + //! \return Number of characters written. + size_t PutEnd(Ch* begin); +} +\endcode +*/ + +//! Provides additional information for stream. +/*! + By using traits pattern, this type provides a default configuration for stream. + For custom stream, this type can be specialized for other configuration. + See TEST(Reader, CustomStringStream) in readertest.cpp for example. +*/ +template +struct StreamTraits { + //! Whether to make local copy of stream for optimization during parsing. + /*! + By default, for safety, streams do not use local copy optimization. + Stream that can be copied fast should specialize this, like StreamTraits. + */ + enum { copyOptimization = 0 }; +}; + +//! Put N copies of a character to a stream. +template +inline void PutN(Stream& stream, Ch c, size_t n) { + for (size_t i = 0; i < n; i++) + stream.Put(c); +} + +/////////////////////////////////////////////////////////////////////////////// +// StringStream + +//! Read-only string stream. +/*! \note implements Stream concept +*/ +template +struct GenericStringStream { + typedef typename Encoding::Ch Ch; + + GenericStringStream(const Ch *src) : src_(src), head_(src) {} + + Ch Peek() const { return *src_; } + Ch Take() { return *src_++; } + size_t Tell() const { return static_cast(src_ - head_); } + + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + const Ch* src_; //!< Current read position. + const Ch* head_; //!< Original head of the string. +}; + +template +struct StreamTraits > { + enum { copyOptimization = 1 }; +}; + +//! String stream with UTF8 encoding. +typedef GenericStringStream > StringStream; + +/////////////////////////////////////////////////////////////////////////////// +// InsituStringStream + +//! A read-write string stream. +/*! This string stream is particularly designed for in-situ parsing. + \note implements Stream concept +*/ +template +struct GenericInsituStringStream { + typedef typename Encoding::Ch Ch; + + GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {} + + // Read + Ch Peek() { return *src_; } + Ch Take() { return *src_++; } + size_t Tell() { return static_cast(src_ - head_); } + + // Write + void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; } + + Ch* PutBegin() { return dst_ = src_; } + size_t PutEnd(Ch* begin) { return static_cast(dst_ - begin); } + void Flush() {} + + Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; } + void Pop(size_t count) { dst_ -= count; } + + Ch* src_; + Ch* dst_; + Ch* head_; +}; + +template +struct StreamTraits > { + enum { copyOptimization = 1 }; +}; + +//! Insitu string stream with UTF8 encoding. +typedef GenericInsituStringStream > InsituStringStream; + +/////////////////////////////////////////////////////////////////////////////// +// Type + +//! Type of JSON value +enum Type { + kNullType = 0, //!< null + kFalseType = 1, //!< false + kTrueType = 2, //!< true + kObjectType = 3, //!< object + kArrayType = 4, //!< array + kStringType = 5, //!< string + kNumberType = 6 //!< number +}; + +} // namespace rapidjson + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/external/rapidjson/reader.h b/external/rapidjson/reader.h new file mode 100644 index 000000000..f41ba2fd7 --- /dev/null +++ b/external/rapidjson/reader.h @@ -0,0 +1,1369 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_READER_H_ +#define RAPIDJSON_READER_H_ + +/*! \file reader.h */ + +#include "rapidjson.h" +#include "encodings.h" +#include "internal/meta.h" +#include "internal/pow10.h" +#include "internal/stack.h" + +#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER) +#include +#pragma intrinsic(_BitScanForward) +#endif +#ifdef RAPIDJSON_SSE42 +#include +#elif defined(RAPIDJSON_SSE2) +#include +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +RAPIDJSON_DIAG_OFF(4702) // unreachable code +#endif + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define RAPIDJSON_NOTHING /* deliberately empty */ +#ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN +#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + if (HasParseError()) { return value; } \ + RAPIDJSON_MULTILINEMACRO_END +#endif +#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \ + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING) +//!@endcond + +/*! \def RAPIDJSON_PARSE_ERROR_NORETURN + \ingroup RAPIDJSON_ERRORS + \brief Macro to indicate a parse error. + \param parseErrorCode \ref rapidjson::ParseErrorCode of the error + \param offset position of the error in JSON input (\c size_t) + + This macros can be used as a customization point for the internal + error handling mechanism of RapidJSON. + + A common usage model is to throw an exception instead of requiring the + caller to explicitly check the \ref rapidjson::GenericReader::Parse's + return value: + + \code + #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode,offset) \ + throw ParseException(parseErrorCode, #parseErrorCode, offset) + + #include // std::runtime_error + #include "rapidjson/error/error.h" // rapidjson::ParseResult + + struct ParseException : std::runtime_error, rapidjson::ParseResult { + ParseException(rapidjson::ParseErrorCode code, const char* msg, size_t offset) + : std::runtime_error(msg), ParseResult(code, offset) {} + }; + + #include "rapidjson/reader.h" + \endcode + + \see RAPIDJSON_PARSE_ERROR, rapidjson::GenericReader::Parse + */ +#ifndef RAPIDJSON_PARSE_ERROR_NORETURN +#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \ + SetParseError(parseErrorCode, offset); \ + RAPIDJSON_MULTILINEMACRO_END +#endif + +/*! \def RAPIDJSON_PARSE_ERROR + \ingroup RAPIDJSON_ERRORS + \brief (Internal) macro to indicate and handle a parse error. + \param parseErrorCode \ref rapidjson::ParseErrorCode of the error + \param offset position of the error in JSON input (\c size_t) + + Invokes RAPIDJSON_PARSE_ERROR_NORETURN and stops the parsing. + + \see RAPIDJSON_PARSE_ERROR_NORETURN + \hideinitializer + */ +#ifndef RAPIDJSON_PARSE_ERROR +#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \ + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \ + RAPIDJSON_MULTILINEMACRO_END +#endif + +#include "error/error.h" // ParseErrorCode, ParseResult + +namespace rapidjson { + +/////////////////////////////////////////////////////////////////////////////// +// ParseFlag + +//! Combination of parseFlags +/*! \see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream + */ +enum ParseFlag { + kParseDefaultFlags = 0, //!< Default parse flags. Non-destructive parsing. Text strings are decoded into allocated buffer. + kParseInsituFlag = 1, //!< In-situ(destructive) parsing. + kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings. + kParseIterativeFlag = 4, //!< Iterative(constant complexity in terms of function call stack size) parsing. + kParseStopWhenDoneFlag = 8 //!< After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate kParseErrorDocumentRootNotSingular error. +}; + +/////////////////////////////////////////////////////////////////////////////// +// Handler + +/*! \class rapidjson::Handler + \brief Concept for receiving events from GenericReader upon parsing. + The functions return true if no error occurs. If they return false, + the event publisher should terminate the process. +\code +concept Handler { + typename Ch; + + bool Null(); + bool Bool(bool b); + bool Int(int i); + bool Uint(unsigned i); + bool Int64(int64_t i); + bool Uint64(uint64_t i); + bool Double(double d); + bool String(const Ch* str, SizeType length, bool copy); + bool StartObject(); + bool Key(const Ch* str, SizeType length, bool copy); + bool EndObject(SizeType memberCount); + bool StartArray(); + bool EndArray(SizeType elementCount); +}; +\endcode +*/ +/////////////////////////////////////////////////////////////////////////////// +// BaseReaderHandler + +//! Default implementation of Handler. +/*! This can be used as base class of any reader handler. + \note implements Handler concept +*/ +template, typename Derived = void> +struct BaseReaderHandler { + typedef typename Encoding::Ch Ch; + + typedef typename internal::SelectIf, BaseReaderHandler, Derived>::Type Override; + + bool Default() { return true; } + bool Null() { return static_cast(*this).Default(); } + bool Bool(bool) { return static_cast(*this).Default(); } + bool Int(int) { return static_cast(*this).Default(); } + bool Uint(unsigned) { return static_cast(*this).Default(); } + bool Int64(int64_t) { return static_cast(*this).Default(); } + bool Uint64(uint64_t) { return static_cast(*this).Default(); } + bool Double(double) { return static_cast(*this).Default(); } + bool String(const Ch*, SizeType, bool) { return static_cast(*this).Default(); } + bool StartObject() { return static_cast(*this).Default(); } + bool Key(const Ch* str, SizeType len, bool copy) { return static_cast(*this).String(str, len, copy); } + bool EndObject(SizeType) { return static_cast(*this).Default(); } + bool StartArray() { return static_cast(*this).Default(); } + bool EndArray(SizeType) { return static_cast(*this).Default(); } +}; + +/////////////////////////////////////////////////////////////////////////////// +// StreamLocalCopy + +namespace internal { + +template::copyOptimization> +class StreamLocalCopy; + +//! Do copy optimization. +template +class StreamLocalCopy { +public: + StreamLocalCopy(Stream& original) : s(original), original_(original) {} + ~StreamLocalCopy() { original_ = s; } + + Stream s; + +private: + StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */; + + Stream& original_; +}; + +//! Keep reference. +template +class StreamLocalCopy { +public: + StreamLocalCopy(Stream& original) : s(original) {} + + Stream& s; + +private: + StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */; +}; + +} // namespace internal + +/////////////////////////////////////////////////////////////////////////////// +// SkipWhitespace + +//! Skip the JSON white spaces in a stream. +/*! \param is A input stream for skipping white spaces. + \note This function has SSE2/SSE4.2 specialization. +*/ +template +void SkipWhitespace(InputStream& is) { + internal::StreamLocalCopy copy(is); + InputStream& s(copy.s); + + while (s.Peek() == ' ' || s.Peek() == '\n' || s.Peek() == '\r' || s.Peek() == '\t') + s.Take(); +} + +#ifdef RAPIDJSON_SSE42 +//! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once. +inline const char *SkipWhitespace_SIMD(const char* p) { + // Fast return for single non-whitespace + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // 16-byte align to the next boundary + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & ~15); + while (p != nextAligned) + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // The rest of string using SIMD + static const char whitespace[16] = " \n\r\t"; + const __m128i w = _mm_loadu_si128((const __m128i *)&whitespace[0]); + + for (;; p += 16) { + const __m128i s = _mm_load_si128((const __m128i *)p); + const unsigned r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY)); + if (r != 0) { // some of characters is non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + _BitScanForward(&offset, r); + return p + offset; +#else + return p + __builtin_ffs(r) - 1; +#endif + } + } +} + +#elif defined(RAPIDJSON_SSE2) + +//! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once. +inline const char *SkipWhitespace_SIMD(const char* p) { + // Fast return for single non-whitespace + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // 16-byte align to the next boundary + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & ~15); + while (p != nextAligned) + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // The rest of string + static const char whitespaces[4][17] = { + " ", + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", + "\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r", + "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"}; + + const __m128i w0 = _mm_loadu_si128((const __m128i *)&whitespaces[0][0]); + const __m128i w1 = _mm_loadu_si128((const __m128i *)&whitespaces[1][0]); + const __m128i w2 = _mm_loadu_si128((const __m128i *)&whitespaces[2][0]); + const __m128i w3 = _mm_loadu_si128((const __m128i *)&whitespaces[3][0]); + + for (;; p += 16) { + const __m128i s = _mm_load_si128((const __m128i *)p); + __m128i x = _mm_cmpeq_epi8(s, w0); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); + unsigned short r = (unsigned short)~_mm_movemask_epi8(x); + if (r != 0) { // some of characters may be non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + _BitScanForward(&offset, r); + return p + offset; +#else + return p + __builtin_ffs(r) - 1; +#endif + } + } +} + +#endif // RAPIDJSON_SSE2 + +#ifdef RAPIDJSON_SIMD +//! Template function specialization for InsituStringStream +template<> inline void SkipWhitespace(InsituStringStream& is) { + is.src_ = const_cast(SkipWhitespace_SIMD(is.src_)); +} + +//! Template function specialization for StringStream +template<> inline void SkipWhitespace(StringStream& is) { + is.src_ = SkipWhitespace_SIMD(is.src_); +} +#endif // RAPIDJSON_SIMD + +/////////////////////////////////////////////////////////////////////////////// +// GenericReader + +//! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator. +/*! GenericReader parses JSON text from a stream, and send events synchronously to an + object implementing Handler concept. + + It needs to allocate a stack for storing a single decoded string during + non-destructive parsing. + + For in-situ parsing, the decoded string is directly written to the source + text string, no temporary buffer is required. + + A GenericReader object can be reused for parsing multiple JSON text. + + \tparam SourceEncoding Encoding of the input stream. + \tparam TargetEncoding Encoding of the parse output. + \tparam StackAllocator Allocator type for stack. +*/ +template +class GenericReader { +public: + typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type + + //! Constructor. + /*! \param allocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing) + \param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing) + */ + GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(stackAllocator, stackCapacity), parseResult_() {} + + //! Parse JSON text. + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam InputStream Type of input stream, implementing Stream concept. + \tparam Handler Type of handler, implementing Handler concept. + \param is Input stream to be parsed. + \param handler The handler to receive events. + \return Whether the parsing is successful. + */ + template + ParseResult Parse(InputStream& is, Handler& handler) { + if (parseFlags & kParseIterativeFlag) + return IterativeParse(is, handler); + + parseResult_.Clear(); + + ClearStackOnExit scope(*this); + + SkipWhitespace(is); + + if (is.Peek() == '\0') { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell()); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + } + else { + ParseValue(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + + if (!(parseFlags & kParseStopWhenDoneFlag)) { + SkipWhitespace(is); + + if (is.Peek() != '\0') { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell()); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + } + } + } + + return parseResult_; + } + + //! Parse JSON text (with \ref kParseDefaultFlags) + /*! \tparam InputStream Type of input stream, implementing Stream concept + \tparam Handler Type of handler, implementing Handler concept. + \param is Input stream to be parsed. + \param handler The handler to receive events. + \return Whether the parsing is successful. + */ + template + ParseResult Parse(InputStream& is, Handler& handler) { + return Parse(is, handler); + } + + //! Whether a parse error has occured in the last parsing. + bool HasParseError() const { return parseResult_.IsError(); } + + //! Get the \ref ParseErrorCode of last parsing. + ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); } + + //! Get the position of last parsing error in input, 0 otherwise. + size_t GetErrorOffset() const { return parseResult_.Offset(); } + +protected: + void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); } + +private: + // Prohibit copy constructor & assignment operator. + GenericReader(const GenericReader&); + GenericReader& operator=(const GenericReader&); + + void ClearStack() { stack_.Clear(); } + + // clear stack on any exit from ParseStream, e.g. due to exception + struct ClearStackOnExit { + explicit ClearStackOnExit(GenericReader& r) : r_(r) {} + ~ClearStackOnExit() { r_.ClearStack(); } + private: + GenericReader& r_; + ClearStackOnExit(const ClearStackOnExit&); + ClearStackOnExit& operator=(const ClearStackOnExit&); + }; + + // Parse object: { string : value, ... } + template + void ParseObject(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == '{'); + is.Take(); // Skip '{' + + if (!handler.StartObject()) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + + SkipWhitespace(is); + + if (is.Peek() == '}') { + is.Take(); + if (!handler.EndObject(0)) // empty object + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + } + + for (SizeType memberCount = 0;;) { + if (is.Peek() != '"') + RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); + + ParseString(is, handler, true); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + SkipWhitespace(is); + + if (is.Take() != ':') + RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); + + SkipWhitespace(is); + + ParseValue(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + SkipWhitespace(is); + + ++memberCount; + + switch (is.Take()) { + case ',': SkipWhitespace(is); break; + case '}': + if (!handler.EndObject(memberCount)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + else + return; + default: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); + } + } + } + + // Parse array: [ value, ... ] + template + void ParseArray(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == '['); + is.Take(); // Skip '[' + + if (!handler.StartArray()) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + + SkipWhitespace(is); + + if (is.Peek() == ']') { + is.Take(); + if (!handler.EndArray(0)) // empty array + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + } + + for (SizeType elementCount = 0;;) { + ParseValue(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + ++elementCount; + SkipWhitespace(is); + + switch (is.Take()) { + case ',': SkipWhitespace(is); break; + case ']': + if (!handler.EndArray(elementCount)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + else + return; + default: RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); + } + } + } + + template + void ParseNull(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 'n'); + is.Take(); + + if (is.Take() == 'u' && is.Take() == 'l' && is.Take() == 'l') { + if (!handler.Null()) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell() - 1); + } + + template + void ParseTrue(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 't'); + is.Take(); + + if (is.Take() == 'r' && is.Take() == 'u' && is.Take() == 'e') { + if (!handler.Bool(true)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell() - 1); + } + + template + void ParseFalse(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 'f'); + is.Take(); + + if (is.Take() == 'a' && is.Take() == 'l' && is.Take() == 's' && is.Take() == 'e') { + if (!handler.Bool(false)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell() - 1); + } + + // Helper function to parse four hexidecimal digits in \uXXXX in ParseString(). + template + unsigned ParseHex4(InputStream& is) { + unsigned codepoint = 0; + for (int i = 0; i < 4; i++) { + Ch c = is.Take(); + codepoint <<= 4; + codepoint += static_cast(c); + if (c >= '0' && c <= '9') + codepoint -= '0'; + else if (c >= 'A' && c <= 'F') + codepoint -= 'A' - 10; + else if (c >= 'a' && c <= 'f') + codepoint -= 'a' - 10; + else { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, is.Tell() - 1); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0); + } + } + return codepoint; + } + + class StackStream { + public: + typedef typename TargetEncoding::Ch Ch; + + StackStream(internal::Stack& stack) : stack_(stack), length_(0) {} + RAPIDJSON_FORCEINLINE void Put(Ch c) { + *stack_.template Push() = c; + ++length_; + } + internal::Stack& stack_; + SizeType length_; + + private: + StackStream(const StackStream&); + StackStream& operator=(const StackStream&); + }; + + // Parse string and generate String event. Different code paths for kParseInsituFlag. + template + void ParseString(InputStream& is, Handler& handler, bool isKey = false) { + internal::StreamLocalCopy copy(is); + InputStream& s(copy.s); + + bool success = false; + if (parseFlags & kParseInsituFlag) { + typename InputStream::Ch *head = s.PutBegin(); + ParseStringToStream(s, s); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + size_t length = s.PutEnd(head) - 1; + RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); + const typename TargetEncoding::Ch* const str = (typename TargetEncoding::Ch*)head; + success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false)); + } + else { + StackStream stackStream(stack_); + ParseStringToStream(s, stackStream); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + const typename TargetEncoding::Ch* const str = stack_.template Pop(stackStream.length_); + success = (isKey ? handler.Key(str, stackStream.length_ - 1, true) : handler.String(str, stackStream.length_ - 1, true)); + } + if (!success) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell()); + } + + // Parse string to an output is + // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation. + template + RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) { +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + static const char escape[256] = { + Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/', + Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, + 0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0, + 0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 + }; +#undef Z16 +//!@endcond + + RAPIDJSON_ASSERT(is.Peek() == '\"'); + is.Take(); // Skip '\"' + + for (;;) { + Ch c = is.Peek(); + if (c == '\\') { // Escape + is.Take(); + Ch e = is.Take(); + if ((sizeof(Ch) == 1 || unsigned(e) < 256) && escape[(unsigned char)e]) { + os.Put(escape[(unsigned char)e]); + } + else if (e == 'u') { // Unicode + unsigned codepoint = ParseHex4(is); + if (codepoint >= 0xD800 && codepoint <= 0xDBFF) { + // Handle UTF-16 surrogate pair + if (is.Take() != '\\' || is.Take() != 'u') + RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, is.Tell() - 2); + unsigned codepoint2 = ParseHex4(is); + if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF) + RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, is.Tell() - 2); + codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000; + } + TEncoding::Encode(os, codepoint); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell() - 1); + } + else if (c == '"') { // Closing double quote + is.Take(); + os.Put('\0'); // null-terminate the string + return; + } + else if (c == '\0') + RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell() - 1); + else if ((unsigned)c < 0x20) // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF + RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell() - 1); + else { + if (parseFlags & kParseValidateEncodingFlag ? + !Transcoder::Validate(is, os) : + !Transcoder::Transcode(is, os)) + RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, is.Tell()); + } + } + } + + inline double StrtodFastPath(double significand, int exp) { + // Fast path only works on limited range of values. + // But for simplicity and performance, currently only implement this. + // see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ + if (exp < -308) + return 0.0; + else if (exp >= 0) + return significand * internal::Pow10(exp); + else + return significand / internal::Pow10(-exp); + } + + template + void ParseNumber(InputStream& is, Handler& handler) { + internal::StreamLocalCopy copy(is); + InputStream& s(copy.s); + + // Parse minus + bool minus = false; + if (s.Peek() == '-') { + minus = true; + s.Take(); + } + + // Parse int: zero / ( digit1-9 *DIGIT ) + unsigned i = 0; + uint64_t i64 = 0; + bool use64bit = false; + if (s.Peek() == '0') { + i = 0; + s.Take(); + } + else if (s.Peek() >= '1' && s.Peek() <= '9') { + i = static_cast(s.Take() - '0'); + + if (minus) + while (s.Peek() >= '0' && s.Peek() <= '9') { + if (i >= 214748364) { // 2^31 = 2147483648 + if (i != 214748364 || s.Peek() > '8') { + i64 = i; + use64bit = true; + break; + } + } + i = i * 10 + static_cast(s.Take() - '0'); + } + else + while (s.Peek() >= '0' && s.Peek() <= '9') { + if (i >= 429496729) { // 2^32 - 1 = 4294967295 + if (i != 429496729 || s.Peek() > '5') { + i64 = i; + use64bit = true; + break; + } + } + i = i * 10 + static_cast(s.Take() - '0'); + } + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); + + // Parse 64bit int + double d = 0.0; + bool useDouble = false; + if (use64bit) { + if (minus) + while (s.Peek() >= '0' && s.Peek() <= '9') { + if (i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC)) // 2^63 = 9223372036854775808 + if (i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8') { + d = (double)i64; + useDouble = true; + break; + } + i64 = i64 * 10 + static_cast(s.Take() - '0'); + } + else + while (s.Peek() >= '0' && s.Peek() <= '9') { + if (i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999)) // 2^64 - 1 = 18446744073709551615 + if (i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5') { + d = (double)i64; + useDouble = true; + break; + } + i64 = i64 * 10 + static_cast(s.Take() - '0'); + } + } + + // Force double for big integer + if (useDouble) { + while (s.Peek() >= '0' && s.Peek() <= '9') { + if (d >= 1.7976931348623157e307) // DBL_MAX / 10.0 + RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, s.Tell()); + d = d * 10 + (s.Take() - '0'); + } + } + + // Parse frac = decimal-point 1*DIGIT + int expFrac = 0; + if (s.Peek() == '.') { + s.Take(); + +#if RAPIDJSON_64BIT + // Use i64 to store significand in 64-bit architecture + if (!useDouble) { + if (!use64bit) + i64 = i; + + while (s.Peek() >= '0' && s.Peek() <= '9') { + if (i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999)) + break; + else { + i64 = i64 * 10 + static_cast(s.Take() - '0'); + --expFrac; + } + } + + d = (double)i64; + } +#else + // Use double to store significand in 32-bit architecture + if (!useDouble) + d = use64bit ? (double)i64 : (double)i; +#endif + useDouble = true; + + while (s.Peek() >= '0' && s.Peek() <= '9') { + d = d * 10 + (s.Take() - '0'); + --expFrac; + } + + if (expFrac == 0) + RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell()); + } + + // Parse exp = e [ minus / plus ] 1*DIGIT + int exp = 0; + if (s.Peek() == 'e' || s.Peek() == 'E') { + if (!useDouble) { + d = use64bit ? (double)i64 : (double)i; + useDouble = true; + } + s.Take(); + + bool expMinus = false; + if (s.Peek() == '+') + s.Take(); + else if (s.Peek() == '-') { + s.Take(); + expMinus = true; + } + + if (s.Peek() >= '0' && s.Peek() <= '9') { + exp = s.Take() - '0'; + while (s.Peek() >= '0' && s.Peek() <= '9') { + exp = exp * 10 + (s.Take() - '0'); + if (exp > 308 && !expMinus) // exp > 308 should be rare, so it should be checked first. + RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, s.Tell()); + } + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell()); + + if (expMinus) + exp = -exp; + } + + // Finish parsing, call event according to the type of number. + bool cont = true; + if (useDouble) { + int expSum = exp + expFrac; + if (expSum < -308) { + // Prevent expSum < -308, making Pow10(expSum) = 0 + d = StrtodFastPath(d, exp); + d = StrtodFastPath(d, expFrac); + } + else + d = StrtodFastPath(d, expSum); + + cont = handler.Double(minus ? -d : d); + } + else { + if (use64bit) { + if (minus) + cont = handler.Int64(-(int64_t)i64); + else + cont = handler.Uint64(i64); + } + else { + if (minus) + cont = handler.Int(-(int)i); + else + cont = handler.Uint(i); + } + } + if (!cont) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell()); + } + + // Parse any JSON value + template + void ParseValue(InputStream& is, Handler& handler) { + switch (is.Peek()) { + case 'n': ParseNull (is, handler); break; + case 't': ParseTrue (is, handler); break; + case 'f': ParseFalse (is, handler); break; + case '"': ParseString(is, handler); break; + case '{': ParseObject(is, handler); break; + case '[': ParseArray (is, handler); break; + default : ParseNumber(is, handler); + } + } + + // Iterative Parsing + + // States + enum IterativeParsingState { + IterativeParsingStartState = 0, + IterativeParsingFinishState, + IterativeParsingErrorState, + + // Object states + IterativeParsingObjectInitialState, + IterativeParsingMemberKeyState, + IterativeParsingKeyValueDelimiterState, + IterativeParsingMemberValueState, + IterativeParsingMemberDelimiterState, + IterativeParsingObjectFinishState, + + // Array states + IterativeParsingArrayInitialState, + IterativeParsingElementState, + IterativeParsingElementDelimiterState, + IterativeParsingArrayFinishState, + + // Single value state + IterativeParsingValueState, + + cIterativeParsingStateCount + }; + + // Tokens + enum Token { + LeftBracketToken = 0, + RightBracketToken, + + LeftCurlyBracketToken, + RightCurlyBracketToken, + + CommaToken, + ColonToken, + + StringToken, + FalseToken, + TrueToken, + NullToken, + NumberToken, + + kTokenCount + }; + + RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) { + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define N NumberToken +#define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N + // Maps from ASCII to Token + static const unsigned char tokenMap[256] = { + N16, // 00~0F + N16, // 10~1F + N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F + N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F + N16, // 40~4F + N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F + N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F + N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F + N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF + }; +#undef N +#undef N16 +//!@endcond + + if (sizeof(Ch) == 1 || unsigned(c) < 256) + return (Token)tokenMap[(unsigned char)c]; + else + return NumberToken; + } + + RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) { + // current state x one lookahead token -> new state + static const char G[cIterativeParsingStateCount][kTokenCount] = { + // Start + { + IterativeParsingArrayInitialState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingValueState, // String + IterativeParsingValueState, // False + IterativeParsingValueState, // True + IterativeParsingValueState, // Null + IterativeParsingValueState // Number + }, + // Finish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // Error(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // ObjectInitial + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberKeyState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // MemberKey + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingKeyValueDelimiterState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // KeyValueDelimiter + { + IterativeParsingArrayInitialState, // Left bracket(push MemberValue state) + IterativeParsingErrorState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberValueState, // String + IterativeParsingMemberValueState, // False + IterativeParsingMemberValueState, // True + IterativeParsingMemberValueState, // Null + IterativeParsingMemberValueState // Number + }, + // MemberValue + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingMemberDelimiterState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // MemberDelimiter + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberKeyState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // ObjectFinish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // ArrayInitial + { + IterativeParsingArrayInitialState, // Left bracket(push Element state) + IterativeParsingArrayFinishState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push Element state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingElementState, // String + IterativeParsingElementState, // False + IterativeParsingElementState, // True + IterativeParsingElementState, // Null + IterativeParsingElementState // Number + }, + // Element + { + IterativeParsingErrorState, // Left bracket + IterativeParsingArrayFinishState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingElementDelimiterState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // ElementDelimiter + { + IterativeParsingArrayInitialState, // Left bracket(push Element state) + IterativeParsingErrorState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push Element state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingElementState, // String + IterativeParsingElementState, // False + IterativeParsingElementState, // True + IterativeParsingElementState, // Null + IterativeParsingElementState // Number + }, + // ArrayFinish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // Single Value (sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + } + }; // End of G + + return (IterativeParsingState)G[state][token]; + } + + // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit(). + // May return a new state on state pop. + template + RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) { + switch (dst) { + case IterativeParsingStartState: + RAPIDJSON_ASSERT(false); + return IterativeParsingErrorState; + + case IterativeParsingFinishState: + return dst; + + case IterativeParsingErrorState: + return dst; + + case IterativeParsingObjectInitialState: + case IterativeParsingArrayInitialState: + { + // Push the state(Element or MemeberValue) if we are nested in another array or value of member. + // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop. + IterativeParsingState n = src; + if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState) + n = IterativeParsingElementState; + else if (src == IterativeParsingKeyValueDelimiterState) + n = IterativeParsingMemberValueState; + // Push current state. + *stack_.template Push(1) = n; + // Initialize and push the member/element count. + *stack_.template Push(1) = 0; + // Call handler + bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray(); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return dst; + } + } + + case IterativeParsingMemberKeyState: + ParseString(is, handler, true); + if (HasParseError()) + return IterativeParsingErrorState; + else + return dst; + + case IterativeParsingKeyValueDelimiterState: + if (token == ColonToken) { + is.Take(); + return dst; + } + else + return IterativeParsingErrorState; + + case IterativeParsingMemberValueState: + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return dst; + + case IterativeParsingElementState: + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return dst; + + case IterativeParsingMemberDelimiterState: + case IterativeParsingElementDelimiterState: + is.Take(); + // Update member/element count. + *stack_.template Top() = *stack_.template Top() + 1; + return dst; + + case IterativeParsingObjectFinishState: + { + // Get member count. + SizeType c = *stack_.template Pop(1); + // If the object is not empty, count the last member. + if (src == IterativeParsingMemberValueState) + ++c; + // Restore the state. + IterativeParsingState n = static_cast(*stack_.template Pop(1)); + // Transit to Finish state if this is the topmost scope. + if (n == IterativeParsingStartState) + n = IterativeParsingFinishState; + // Call handler + bool hr = handler.EndObject(c); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return n; + } + } + + case IterativeParsingArrayFinishState: + { + // Get element count. + SizeType c = *stack_.template Pop(1); + // If the array is not empty, count the last element. + if (src == IterativeParsingElementState) + ++c; + // Restore the state. + IterativeParsingState n = static_cast(*stack_.template Pop(1)); + // Transit to Finish state if this is the topmost scope. + if (n == IterativeParsingStartState) + n = IterativeParsingFinishState; + // Call handler + bool hr = handler.EndArray(c); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return n; + } + } + + case IterativeParsingValueState: + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return IterativeParsingFinishState; + + default: + RAPIDJSON_ASSERT(false); + return IterativeParsingErrorState; + } + } + + template + void HandleError(IterativeParsingState src, InputStream& is) { + if (HasParseError()) { + // Error flag has been set. + return; + } + + switch (src) { + case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); + case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); + case IterativeParsingObjectInitialState: + case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); + case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); + case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); + case IterativeParsingElementState: RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); + default: RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); + } + } + + template + ParseResult IterativeParse(InputStream& is, Handler& handler) { + parseResult_.Clear(); + ClearStackOnExit scope(*this); + IterativeParsingState state = IterativeParsingStartState; + + SkipWhitespace(is); + while (is.Peek() != '\0') { + Token t = Tokenize(is.Peek()); + IterativeParsingState n = Predict(state, t); + IterativeParsingState d = Transit(state, t, n, is, handler); + + if (d == IterativeParsingErrorState) { + HandleError(state, is); + break; + } + + state = d; + + // Do not further consume streams if a root JSON has been parsed. + if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState) + break; + + SkipWhitespace(is); + } + + // Handle the end of file. + if (state != IterativeParsingFinishState) + HandleError(state, is); + + return parseResult_; + } + + static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string. + internal::Stack stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing. + ParseResult parseResult_; +}; // class GenericReader + +//! Reader with UTF8 encoding and default allocator. +typedef GenericReader, UTF8<> > Reader; + +} // namespace rapidjson + +#ifdef _MSC_VER +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_READER_H_ diff --git a/external/rapidjson/stringbuffer.h b/external/rapidjson/stringbuffer.h new file mode 100644 index 000000000..55124f117 --- /dev/null +++ b/external/rapidjson/stringbuffer.h @@ -0,0 +1,79 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_STRINGBUFFER_H_ +#define RAPIDJSON_STRINGBUFFER_H_ + +#include "rapidjson.h" +#include "internal/stack.h" + +namespace rapidjson { + +//! Represents an in-memory output stream. +/*! + \tparam Encoding Encoding of the stream. + \tparam Allocator type for allocating memory buffer. + \note implements Stream concept +*/ +template +struct GenericStringBuffer { + typedef typename Encoding::Ch Ch; + + GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} + + void Put(Ch c) { *stack_.template Push() = c; } + void Flush() {} + + void Clear() { stack_.Clear(); } + void ShrinkToFit() { + // Push and pop a null terminator. This is safe. + *stack_.template Push() = '\0'; + stack_.ShrinkToFit(); + stack_.template Pop(1); + } + Ch* Push(size_t count) { return stack_.template Push(count); } + void Pop(size_t count) { stack_.template Pop(count); } + + const Ch* GetString() const { + // Push and pop a null terminator. This is safe. + *stack_.template Push() = '\0'; + stack_.template Pop(1); + + return stack_.template Bottom(); + } + + size_t GetSize() const { return stack_.GetSize(); } + + static const size_t kDefaultCapacity = 256; + mutable internal::Stack stack_; +}; + +//! String buffer with UTF8 encoding +typedef GenericStringBuffer > StringBuffer; + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(GenericStringBuffer >& stream, char c, size_t n) { + std::memset(stream.stack_.Push(n), c, n * sizeof(c)); +} + +} // namespace rapidjson + +#endif // RAPIDJSON_STRINGBUFFER_H_ diff --git a/external/rapidjson/writer.h b/external/rapidjson/writer.h new file mode 100644 index 000000000..fb6601ef9 --- /dev/null +++ b/external/rapidjson/writer.h @@ -0,0 +1,389 @@ +// Copyright (C) 2011 Milo Yip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef RAPIDJSON_WRITER_H_ +#define RAPIDJSON_WRITER_H_ + +#include "rapidjson.h" +#include "internal/stack.h" +#include "internal/strfunc.h" +#include "internal/dtoa.h" +#include "internal/itoa.h" +#include "stringbuffer.h" +#include // placement new + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +#endif + +namespace rapidjson { + +//! JSON writer +/*! Writer implements the concept Handler. + It generates JSON text by events to an output os. + + User may programmatically calls the functions of a writer to generate JSON text. + + On the other side, a writer can also be passed to objects that generates events, + + for example Reader::Parse() and Document::Accept(). + + \tparam OutputStream Type of output stream. + \tparam SourceEncoding Encoding of source string. + \tparam TargetEncoding Encoding of output stream. + \tparam StackAllocator Type of allocator for allocating memory of stack. + \note implements Handler concept +*/ +template, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator> +class Writer { +public: + typedef typename SourceEncoding::Ch Ch; + + //! Constructor + /*! \param os Output stream. + \param allocator User supplied allocator. If it is null, it will create a private one. + \param levelDepth Initial capacity of stack. + */ + Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) : + os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), hasRoot_(false) {} + + Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : + os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), hasRoot_(false) {} + + //! Reset the writer with a new stream. + /*! + This function reset the writer with a new stream and default settings, + in order to make a Writer object reusable for output multiple JSONs. + + \param os New output stream. + \code + Writer writer(os1); + writer.StartObject(); + // ... + writer.EndObject(); + + writer.Reset(os2); + writer.StartObject(); + // ... + writer.EndObject(); + \endcode + */ + void Reset(OutputStream& os) { + os_ = &os; + hasRoot_ = false; + level_stack_.Clear(); + } + + //! Checks whether the output is a complete JSON. + /*! + A complete JSON has a complete root object or array. + */ + bool IsComplete() const { + return hasRoot_ && level_stack_.Empty(); + } + + /*!@name Implementation of Handler + \see Handler + */ + //@{ + + bool Null() { Prefix(kNullType); return WriteNull(); } + bool Bool(bool b) { Prefix(b ? kTrueType : kFalseType); return WriteBool(b); } + bool Int(int i) { Prefix(kNumberType); return WriteInt(i); } + bool Uint(unsigned u) { Prefix(kNumberType); return WriteUint(u); } + bool Int64(int64_t i64) { Prefix(kNumberType); return WriteInt64(i64); } + bool Uint64(uint64_t u64) { Prefix(kNumberType); return WriteUint64(u64); } + + //! Writes the given \c double value to the stream + /*! + \param d The value to be written. + \return Whether it is succeed. + */ + bool Double(double d) { Prefix(kNumberType); return WriteDouble(d); } + + bool String(const Ch* str, SizeType length, bool copy = false) { + (void)copy; + Prefix(kStringType); + return WriteString(str, length); + } + + bool StartObject() { + Prefix(kObjectType); + new (level_stack_.template Push()) Level(false); + return WriteStartObject(); + } + + bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } + + bool EndObject(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); + RAPIDJSON_ASSERT(!level_stack_.template Top()->inArray); + level_stack_.template Pop(1); + bool ret = WriteEndObject(); + if (level_stack_.Empty()) // end of json text + os_->Flush(); + return ret; + } + + bool StartArray() { + Prefix(kArrayType); + new (level_stack_.template Push()) Level(true); + return WriteStartArray(); + } + + bool EndArray(SizeType elementCount = 0) { + (void)elementCount; + RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); + RAPIDJSON_ASSERT(level_stack_.template Top()->inArray); + level_stack_.template Pop(1); + bool ret = WriteEndArray(); + if (level_stack_.Empty()) // end of json text + os_->Flush(); + return ret; + } + //@} + + /*! @name Convenience extensions */ + //@{ + + //! Simpler but slower overload. + bool String(const Ch* str) { return String(str, internal::StrLen(str)); } + bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); } + + //@} + +protected: + //! Information for each nested level + struct Level { + Level(bool inArray_) : valueCount(0), inArray(inArray_) {} + size_t valueCount; //!< number of values in this level + bool inArray; //!< true if in array, otherwise in object + }; + + static const size_t kDefaultLevelDepth = 32; + + bool WriteNull() { + os_->Put('n'); os_->Put('u'); os_->Put('l'); os_->Put('l'); return true; + } + + bool WriteBool(bool b) { + if (b) { + os_->Put('t'); os_->Put('r'); os_->Put('u'); os_->Put('e'); + } + else { + os_->Put('f'); os_->Put('a'); os_->Put('l'); os_->Put('s'); os_->Put('e'); + } + return true; + } + + bool WriteInt(int i) { + char buffer[11]; + const char* end = internal::i32toa(i, buffer); + for (const char* p = buffer; p != end; ++p) + os_->Put(*p); + return true; + } + + bool WriteUint(unsigned u) { + char buffer[10]; + const char* end = internal::u32toa(u, buffer); + for (const char* p = buffer; p != end; ++p) + os_->Put(*p); + return true; + } + + bool WriteInt64(int64_t i64) { + char buffer[21]; + const char* end = internal::i64toa(i64, buffer); + for (const char* p = buffer; p != end; ++p) + os_->Put(*p); + return true; + } + + bool WriteUint64(uint64_t u64) { + char buffer[20]; + char* end = internal::u64toa(u64, buffer); + for (char* p = buffer; p != end; ++p) + os_->Put(*p); + return true; + } + + bool WriteDouble(double d) { + char buffer[25]; + char* end = internal::dtoa(d, buffer); + for (char* p = buffer; p != end; ++p) + os_->Put(*p); + return true; + } + + bool WriteString(const Ch* str, SizeType length) { + static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + static const char escape[256] = { +#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + //0 1 2 3 4 5 6 7 8 9 A B C D E F + 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00 + 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10 + 0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 + Z16, Z16, // 30~4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50 + Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF +#undef Z16 + }; + + os_->Put('\"'); + GenericStringStream is(str); + while (is.Tell() < length) { + const Ch c = is.Peek(); + if (!TargetEncoding::supportUnicode && (unsigned)c >= 0x80) { + // Unicode escaping + unsigned codepoint; + if (!SourceEncoding::Decode(is, &codepoint)) + return false; + os_->Put('\\'); + os_->Put('u'); + if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) { + os_->Put(hexDigits[(codepoint >> 12) & 15]); + os_->Put(hexDigits[(codepoint >> 8) & 15]); + os_->Put(hexDigits[(codepoint >> 4) & 15]); + os_->Put(hexDigits[(codepoint ) & 15]); + } + else if (codepoint >= 0x010000 && codepoint <= 0x10FFFF) { + // Surrogate pair + unsigned s = codepoint - 0x010000; + unsigned lead = (s >> 10) + 0xD800; + unsigned trail = (s & 0x3FF) + 0xDC00; + os_->Put(hexDigits[(lead >> 12) & 15]); + os_->Put(hexDigits[(lead >> 8) & 15]); + os_->Put(hexDigits[(lead >> 4) & 15]); + os_->Put(hexDigits[(lead ) & 15]); + os_->Put('\\'); + os_->Put('u'); + os_->Put(hexDigits[(trail >> 12) & 15]); + os_->Put(hexDigits[(trail >> 8) & 15]); + os_->Put(hexDigits[(trail >> 4) & 15]); + os_->Put(hexDigits[(trail ) & 15]); + } + else + return false; // invalid code point + } + else if ((sizeof(Ch) == 1 || (unsigned)c < 256) && escape[(unsigned char)c]) { + is.Take(); + os_->Put('\\'); + os_->Put(escape[(unsigned char)c]); + if (escape[(unsigned char)c] == 'u') { + os_->Put('0'); + os_->Put('0'); + os_->Put(hexDigits[(unsigned char)c >> 4]); + os_->Put(hexDigits[(unsigned char)c & 0xF]); + } + } + else + Transcoder::Transcode(is, *os_); + } + os_->Put('\"'); + return true; + } + + bool WriteStartObject() { os_->Put('{'); return true; } + bool WriteEndObject() { os_->Put('}'); return true; } + bool WriteStartArray() { os_->Put('['); return true; } + bool WriteEndArray() { os_->Put(']'); return true; } + + void Prefix(Type type) { + (void)type; + if (level_stack_.GetSize() != 0) { // this value is not at root + Level* level = level_stack_.template Top(); + if (level->valueCount > 0) { + if (level->inArray) + os_->Put(','); // add comma if it is not the first element in array + else // in object + os_->Put((level->valueCount % 2 == 0) ? ',' : ':'); + } + if (!level->inArray && level->valueCount % 2 == 0) + RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name + level->valueCount++; + } + else { + RAPIDJSON_ASSERT(!hasRoot_); // Should only has one and only one root. + hasRoot_ = true; + } + } + + OutputStream* os_; + internal::Stack level_stack_; + bool hasRoot_; + +private: + // Prohibit copy constructor & assignment operator. + Writer(const Writer&); + Writer& operator=(const Writer&); +}; + +// Full specialization for StringStream to prevent memory copying + +template<> +inline bool Writer::WriteInt(int i) { + char *buffer = os_->Push(11); + const char* end = internal::i32toa(i, buffer); + os_->Pop(11 - (end - buffer)); + return true; +} + +template<> +inline bool Writer::WriteUint(unsigned u) { + char *buffer = os_->Push(10); + const char* end = internal::u32toa(u, buffer); + os_->Pop(10 - (end - buffer)); + return true; +} + +template<> +inline bool Writer::WriteInt64(int64_t i64) { + char *buffer = os_->Push(21); + const char* end = internal::i64toa(i64, buffer); + os_->Pop(21 - (end - buffer)); + return true; +} + +template<> +inline bool Writer::WriteUint64(uint64_t u) { + char *buffer = os_->Push(20); + const char* end = internal::u64toa(u, buffer); + os_->Pop(20 - (end - buffer)); + return true; +} + +template<> +inline bool Writer::WriteDouble(double d) { + char *buffer = os_->Push(25); + char* end = internal::dtoa(d, buffer); + os_->Pop(25 - (end - buffer)); + return true; +} + +} // namespace rapidjson + +#ifdef _MSC_VER +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/external/unbound/CMakeLists.txt b/external/unbound/CMakeLists.txt new file mode 100644 index 000000000..fdfa0a0fe --- /dev/null +++ b/external/unbound/CMakeLists.txt @@ -0,0 +1,201 @@ +cmake_minimum_required(VERSION 2.8.7) + +project(unbound C) + +find_package(OpenSSL REQUIRED) +find_package(Threads) + +include(configure_checks.cmake) + +if (WIN32) + set(USE_MINI_EVENT 1) + set(USE_WINSOCK 1) +else () + find_package(PkgConfig REQUIRED) + pkg_check_modules(LIBEVENT2 REQUIRED libevent) +endif () + +set(RETSIGTYPE void) + +add_definitions(-D_GNU_SOURCE) + +option(USE_ECDSA "Use ECDSA algorithms" ON) +option(USE_SHA2 "Enable SHA2 support" ON) +set(ENABLE_DNSTAP 0) +set(HAVE_SSL 1) +if (CMAKE_USE_PTHREADS_INIT AND NOT CMAKE_USE_WIN32_THREADS_INIT) + set(HAVE_PTHREAD 1) +else () + set(HAVE_PTHREAD 0) +endif () +if (CMAKE_USE_WIN32_THREADS_INIT) + set(HAVE_WINDOWS_THREADS 1) +else () + set(HAVE_WINDOWS_THREADS 0) +endif () +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/config.h") +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/dnstap/dnstap_config.h.in" + "${CMAKE_CURRENT_BINARY_DIR}/dnstap/dnstap_config.h") + +set(common_src + services/cache/dns.c + services/cache/infra.c + services/cache/rrset.c + util/data/dname.c + util/data/msgencode.c + util/data/msgparse.c + util/data/msgreply.c + util/data/packed_rrset.c + iterator/iterator.c + iterator/iter_delegpt.c + iterator/iter_donotq.c + iterator/iter_fwd.c + iterator/iter_hints.c + iterator/iter_priv.c + iterator/iter_resptype.c + iterator/iter_scrub.c + iterator/iter_utils.c + services/listen_dnsport.c + services/localzone.c + services/mesh.c + services/modstack.c + services/outbound_list.c + services/outside_network.c + util/alloc.c + util/config_file.c + util/configlexer.c + util/configparser.c + util/fptr_wlist.c + util/locks.c + util/log.c + util/mini_event.c + util/module.c + util/netevent.c + util/net_help.c + util/random.c + util/rbtree.c + util/regional.c + util/rtt.c + util/storage/dnstree.c + util/storage/lookup3.c + util/storage/lruhash.c + util/storage/slabhash.c + util/timehist.c + util/tube.c + util/winsock_event.c + validator/autotrust.c + validator/val_anchor.c + validator/validator.c + validator/val_kcache.c + validator/val_kentry.c + validator/val_neg.c + validator/val_nsec3.c + validator/val_nsec.c + validator/val_secalgo.c + validator/val_sigcrypt.c + validator/val_utils.c + dns64/dns64.c + + #$(CHECKLOCK_SRC) + testcode/checklocks.c) + +set(compat_src) + +foreach (symbol IN ITEMS ctime_r gmtime_r inet_aton inet_ntop inet_pton malloc memcmp memmove snprintf strlcat strlcpy strptime explicit_bzero arc4random arc4random_uniform sha512) + string(TOUPPER "${symbol}" upper_sym) + if (NOT HAVE_${upper_sym}) + list(APPEND compat_src + compat/${symbol}.c) + endif () +endforeach () + +if (NOT HAVE_ARC4RANDOM) + list(APPEND compat_src + compat/arc4_lock.c) +endif () + +if (CMAKE_SYSTEM_NAME MATCHES "Linux") + list(APPEND compat_src + compat/getentropy_linux.c) +elseif (APPLE) + list(APPEND compat_src + compat/getentropy_osx.c) +#elseif (SunOS) +# list(APPEND compat_src +# compat/getentropy_solaris.c) +elseif (WIN32) + list(APPEND compat_src + compat/getentropy_win.c) +endif () + +if (NOT HAVE_GETADDRINFO) + list(APPEND compat_src + compat/fake-rfc2553.c) +endif () + +set(sldns_src + ldns/keyraw.c + ldns/sbuffer.c + ldns/wire2str.c + ldns/parse.c + ldns/parseutil.c + ldns/rrdef.c + ldns/str2wire.c) + +set(libunbound_src + libunbound/context.c + libunbound/libunbound.c + libunbound/libworker.c) + +include_directories("${CMAKE_CURRENT_SOURCE_DIR}") +include_directories("${CMAKE_CURRENT_BINARY_DIR}") +include_directories(SYSTEM ${OPENSSL_INCLUDE_DIR}) +if (LIBEVENT2_FOUND) + include_directories(SYSTEM ${LIBEVENT2_INCLUDE_DIRS}) + link_directories(${LIBEVENT2_LIBRARY_DIRS}) +endif () +add_library(unbound + ${common_src} + ${sldns_src} + ${compat_src} + ${libunbound_src}) +target_link_libraries(unbound + LINK_PRIVATE + ${OPENSSL_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT}) +if (LIBEVENT2_FOUND) + target_link_libraries(unbound + LINK_PRIVATE + ${LIBEVENT2_LIBRARIES}) +endif () + +if (WIN32) + target_link_libraries(unbound + LINK_PRIVATE + iphlpapi + ws2_32) +endif () + +# XXX: Hack for static builds. +set(LIBEVENT2_LIBDIR + "${LIBEVENT2_LIBDIR}" + PARENT_SCOPE) + +if (MINGW) + # There is no variable for this (probably due to the fact that the pthread + # library is implicit with a link in msys). + find_library(win32pthread + NAMES libwinpthread-1.dll) + foreach (input IN LISTS win32pthread OPENSSL_LIBRARIES) + # Copy shared libraries into the build tree so that no PATH manipulation is + # necessary. + get_filename_component(name "${input}" NAME) + configure_file( + "${input}" + "${CMAKE_BINARY_DIR}/bin/${name}" + COPYONLY) + endforeach () +endif () diff --git a/external/unbound/Makefile.in b/external/unbound/Makefile.in index 7300b3e34..02532a951 100644 --- a/external/unbound/Makefile.in +++ b/external/unbound/Makefile.in @@ -80,7 +80,7 @@ LINTFLAGS+="-Dsigset_t=long" # FreeBSD LINTFLAGS+="-D__uint16_t=uint16_t" "-DEVP_PKEY_ASN1_METHOD=int" "-D_RuneLocale=int" "-D__va_list=va_list" -INSTALL=$(srcdir)/install-sh +INSTALL=$(SHELL) $(srcdir)/install-sh #pythonmod.c is not here, it is mentioned by itself in its own rules, #makedepend fails on missing interface.h otherwise. @@ -397,7 +397,7 @@ libunbound/python/libunbound_wrap.c: $(srcdir)/libunbound/python/libunbound.i un # Pyunbound python unbound wrapper _unbound.la: libunbound_wrap.lo libunbound.la - $(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -module -version-info @LIBUNBOUND_CURRENT@:@LIBUNBOUND_REVISION@:@LIBUNBOUND_AGE@ -no-undefined -o $@ libunbound_wrap.lo -rpath $(PYTHON_SITE_PKG) L. -L.libs -lunbound $(LIBS) + $(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -module -avoid-version -no-undefined -shared -o $@ libunbound_wrap.lo -rpath $(PYTHON_SITE_PKG) L. -L.libs -lunbound util/config_file.c: util/configparser.h util/configlexer.c: $(srcdir)/util/configlexer.lex util/configparser.h diff --git a/external/unbound/compat/arc4_lock.c b/external/unbound/compat/arc4_lock.c index ce8bb4168..faa743d15 100644 --- a/external/unbound/compat/arc4_lock.c +++ b/external/unbound/compat/arc4_lock.c @@ -53,8 +53,10 @@ static int arc4lockinit = 0; void _ARC4_LOCK(void) { - if(!arc4lockinit) + if(!arc4lockinit) { + arc4lockinit = 1; lock_quick_init(&arc4lock); + } lock_quick_lock(&arc4lock); } diff --git a/external/unbound/compat/getentropy_linux.c b/external/unbound/compat/getentropy_linux.c index d51d7952d..32d58a7cd 100644 --- a/external/unbound/compat/getentropy_linux.c +++ b/external/unbound/compat/getentropy_linux.c @@ -48,6 +48,7 @@ #include #include +#include #include #include #ifdef HAVE_GETAUXVAL @@ -77,7 +78,7 @@ extern int main(int, char *argv[]); #endif static int gotdata(char *buf, size_t len); static int getentropy_urandom(void *buf, size_t len); -#ifdef CTL_MAXNAME +#ifdef SYS__sysctl static int getentropy_sysctl(void *buf, size_t len); #endif static int getentropy_fallback(void *buf, size_t len); @@ -102,7 +103,7 @@ getentropy(void *buf, size_t len) if (ret != -1) return (ret); -#ifdef CTL_MAXNAME +#ifdef SYS__sysctl /* * Try to use sysctl CTL_KERN, KERN_RANDOM, RANDOM_UUID. * sysctl is a failsafe API, so it guarantees a result. This @@ -124,7 +125,7 @@ getentropy(void *buf, size_t len) ret = getentropy_sysctl(buf, len); if (ret != -1) return (ret); -#endif /* CTL_MAXNAME */ +#endif /* SYS__sysctl */ /* * Entropy collection via /dev/urandom and sysctl have failed. @@ -235,7 +236,7 @@ nodevrandom: return -1; } -#ifdef CTL_MAXNAME +#ifdef SYS__sysctl static int getentropy_sysctl(void *buf, size_t len) { @@ -265,7 +266,7 @@ sysctlfailed: errno = EIO; return -1; } -#endif /* CTL_MAXNAME */ +#endif /* SYS__sysctl */ static int cl[] = { CLOCK_REALTIME, diff --git a/external/unbound/compat/getentropy_win.c b/external/unbound/compat/getentropy_win.c index 9dc55891e..71fb955e7 100644 --- a/external/unbound/compat/getentropy_win.c +++ b/external/unbound/compat/getentropy_win.c @@ -41,9 +41,9 @@ getentropy(void *buf, size_t len) } if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT) != 0) + CRYPT_VERIFYCONTEXT) == 0) goto fail; - if (CryptGenRandom(provider, len, buf) != 0) { + if (CryptGenRandom(provider, len, buf) == 0) { CryptReleaseContext(provider, 0); goto fail; } diff --git a/external/unbound/compat/inet_aton.c b/external/unbound/compat/inet_aton.c index 33c323d99..e93fe8d73 100644 --- a/external/unbound/compat/inet_aton.c +++ b/external/unbound/compat/inet_aton.c @@ -103,7 +103,7 @@ inet_aton(const char *cp, struct in_addr *addr) * Values are specified as for C: * 0x=hex, 0=octal, isdigit=decimal. */ - if (!isdigit(c)) + if (!isdigit((unsigned char)c)) return (0); val = 0; base = 10; if (c == '0') { @@ -114,12 +114,12 @@ inet_aton(const char *cp, struct in_addr *addr) base = 8; } for (;;) { - if (isascii(c) && isdigit(c)) { + if (isascii((unsigned char)c) && isdigit((unsigned char)c)) { val = (val * base) + (c - '0'); c = *++cp; - } else if (base == 16 && isascii(c) && isxdigit(c)) { + } else if (base == 16 && isascii((unsigned char)c) && isxdigit((unsigned char)c)) { val = (val << 4) | - (c + 10 - (islower(c) ? 'a' : 'A')); + (c + 10 - (islower((unsigned char)c) ? 'a' : 'A')); c = *++cp; } else break; @@ -141,7 +141,7 @@ inet_aton(const char *cp, struct in_addr *addr) /* * Check for trailing characters. */ - if (c != '\0' && (!isascii(c) || !isspace(c))) + if (c != '\0' && (!isascii((unsigned char)c) || !isspace((unsigned char)c))) return (0); /* * Concoct the address according to diff --git a/external/unbound/compat/memmove.c b/external/unbound/compat/memmove.c index 0035bbf75..fe319bb49 100644 --- a/external/unbound/compat/memmove.c +++ b/external/unbound/compat/memmove.c @@ -28,7 +28,7 @@ void *memmove(void *dest, const void *src, size_t n) to[i] = from[i]; return dest; } - if (from > to && from-to < (int)n) { + if (from > to && from-to < (int)n) { /* to overlaps with from */ /* */ /* */ diff --git a/external/unbound/compat/strptime.c b/external/unbound/compat/strptime.c index 9a0caa535..10ec31574 100644 --- a/external/unbound/compat/strptime.c +++ b/external/unbound/compat/strptime.c @@ -89,7 +89,7 @@ str2int(const char **buf, int max) { int ret=0, count=0; - while (*buf[0] != '\0' && isdigit(*buf[0]) && count header file. */ +#cmakedefine HAVE_ARPA_INET_H + +/* Whether the C compiler accepts the "format" attribute */ +#cmakedefine HAVE_ATTR_FORMAT + +/* Whether the C compiler accepts the "unused" attribute */ +#cmakedefine HAVE_ATTR_UNUSED + +/* Define to 1 if your system has a working `chown' function. */ +#cmakedefine HAVE_CHOWN + +/* Define to 1 if you have the `chroot' function. */ +#cmakedefine HAVE_CHROOT + +/* Define to 1 if you have the `ctime_r' function. */ +#cmakedefine HAVE_CTIME_R + +/* Define to 1 if you have the `daemon' function. */ +#cmakedefine HAVE_DAEMON + +/* Define to 1 if you have the declaration of `arc4random', and to 0 if you + don't. */ +#cmakedefine HAVE_DECL_ARC4RANDOM + +/* Define to 1 if you have the declaration of `arc4random_uniform', and to 0 + if you don't. */ +#cmakedefine HAVE_DECL_ARC4RANDOM_UNIFORM + +/* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you + don't. */ +#cmakedefine HAVE_DECL_NID_SECP384R1 + +/* Define to 1 if you have the declaration of `NID_X9_62_prime256v1', and to 0 + if you don't. */ +#cmakedefine HAVE_DECL_NID_X9_62_PRIME256V1 + +/* Define to 1 if you have the declaration of `sk_SSL_COMP_pop_free', and to 0 + if you don't. */ +#cmakedefine HAVE_DECL_SK_SSL_COMP_POP_FREE + +/* Define to 1 if you have the declaration of + `SSL_COMP_get_compression_methods', and to 0 if you don't. */ +#cmakedefine HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS + +/* Define to 1 if you have the declaration of `strlcat', and to 0 if you + don't. */ +#cmakedefine HAVE_DECL_STRLCAT + +/* Define to 1 if you have the declaration of `strlcpy', and to 0 if you + don't. */ +#cmakedefine HAVE_DECL_STRLCPY + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ENDIAN_H + +/* Define to 1 if you have the `endprotoent' function. */ +#cmakedefine HAVE_ENDPROTOENT + +/* Define to 1 if you have the `endservent' function. */ +#cmakedefine HAVE_ENDSERVENT + +/* Define to 1 if you have the `event_base_free' function. */ +#cmakedefine HAVE_EVENT_BASE_FREE + +/* Define to 1 if you have the `event_base_get_method' function. */ +#cmakedefine HAVE_EVENT_BASE_GET_METHOD + +/* Define to 1 if you have the `event_base_new' function. */ +#cmakedefine HAVE_EVENT_BASE_NEW + +/* Define to 1 if you have the `event_base_once' function. */ +#cmakedefine HAVE_EVENT_BASE_ONCE + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_EVENT_H + +/* Define to 1 if you have the `EVP_sha1' function. */ +#cmakedefine HAVE_EVP_SHA1 + +/* Define to 1 if you have the `EVP_sha256' function. */ +#cmakedefine HAVE_EVP_SHA256 + +/* Define to 1 if you have the `EVP_sha512' function. */ +#cmakedefine HAVE_EVP_SHA512 + +/* Define to 1 if you have the `ev_default_loop' function. */ +#cmakedefine HAVE_EV_DEFAULT_LOOP + +/* Define to 1 if you have the `ev_loop' function. */ +#cmakedefine HAVE_EV_LOOP + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_EXPAT_H + +/* Define to 1 if you have the `fcntl' function. */ +#cmakedefine HAVE_FCNTL + +/* Define to 1 if you have the `FIPS_mode' function. */ +#cmakedefine HAVE_FIPS_MODE + +/* Define to 1 if you have the `fork' function. */ +#cmakedefine HAVE_FORK + +/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ +#cmakedefine HAVE_FSEEKO + +/* Whether getaddrinfo is available */ +#cmakedefine HAVE_GETADDRINFO + +/* Define to 1 if you have the `getentropy' function. */ +#cmakedefine HAVE_GETENTROPY + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_GETOPT_H + +/* Define to 1 if you have the `getpwnam' function. */ +#cmakedefine HAVE_GETPWNAM + +/* Define to 1 if you have the `getrlimit' function. */ +#cmakedefine HAVE_GETRLIMIT + +/* Define to 1 if you have the `glob' function. */ +#cmakedefine HAVE_GLOB + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_GLOB_H + +/* Define to 1 if you have the `gmtime_r' function. */ +#cmakedefine HAVE_GMTIME_R + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_GRP_H + +/* If you have HMAC_CTX_init */ +#cmakedefine HAVE_HMAC_CTX_INIT + +/* Define to 1 if you have the `inet_aton' function. */ +#cmakedefine HAVE_INET_ATON + +/* Define to 1 if you have the `inet_ntop' function. */ +#cmakedefine HAVE_INET_NTOP + +/* Define to 1 if you have the `inet_pton' function. */ +#cmakedefine HAVE_INET_PTON + +/* Define to 1 if you have the `initgroups' function. */ +#cmakedefine HAVE_INITGROUPS + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_INTTYPES_H + +/* if the function 'ioctlsocket' is available */ +#cmakedefine HAVE_IOCTLSOCKET + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_IPHLPAPI_H + +/* Define to 1 if you have the `kill' function. */ +#cmakedefine HAVE_KILL + +/* Define if we have LibreSSL */ +#cmakedefine HAVE_LIBRESSL + +/* Define to 1 if you have the `localtime_r' function. */ +#cmakedefine HAVE_LOCALTIME_R + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_LOGIN_CAP_H + +/* If have GNU libc compatible malloc */ +#cmakedefine HAVE_MALLOC + +/* Define to 1 if you have the `memmove' function. */ +#cmakedefine HAVE_MEMMOVE + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NETDB_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NETINET_IN_H + +/* Use libnss for crypto */ +#cmakedefine HAVE_NSS + +/* Define to 1 if you have the `OPENSSL_config' function. */ +#cmakedefine HAVE_OPENSSL_CONFIG + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_CONF_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_ENGINE_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_ERR_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_RAND_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_SSL_H + +/* Define if you have POSIX threads libraries and header files. */ +#cmakedefine HAVE_PTHREAD + +/* Have PTHREAD_PRIO_INHERIT. */ +#cmakedefine HAVE_PTHREAD_PRIO_INHERIT + +/* Define to 1 if the system has the type `pthread_rwlock_t'. */ +#cmakedefine HAVE_PTHREAD_RWLOCK_T + +/* Define to 1 if the system has the type `pthread_spinlock_t'. */ +#cmakedefine HAVE_PTHREAD_SPINLOCK_T + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_PWD_H + +/* Define if you have Python libraries and header files. */ +#cmakedefine HAVE_PYTHON + +/* Define to 1 if you have the `random' function. */ +#cmakedefine HAVE_RANDOM + +/* Define to 1 if you have the `recvmsg' function. */ +#cmakedefine HAVE_RECVMSG + +/* Define to 1 if you have the `sbrk' function. */ +#cmakedefine HAVE_SBRK + +/* Define to 1 if you have the `sendmsg' function. */ +#cmakedefine HAVE_SENDMSG + +/* Define to 1 if you have the `setregid' function. */ +#cmakedefine HAVE_SETREGID + +/* Define to 1 if you have the `setresgid' function. */ +#cmakedefine HAVE_SETRESGID + +/* Define to 1 if you have the `setresuid' function. */ +#cmakedefine HAVE_SETRESUID + +/* Define to 1 if you have the `setreuid' function. */ +#cmakedefine HAVE_SETREUID + +/* Define to 1 if you have the `setrlimit' function. */ +#cmakedefine HAVE_SETRLIMIT + +/* Define to 1 if you have the `setsid' function. */ +#cmakedefine HAVE_SETSID + +/* Define to 1 if you have the `setusercontext' function. */ +#cmakedefine HAVE_SETUSERCONTEXT + +/* Define to 1 if you have the `SHA512_Update' function. */ +#cmakedefine HAVE_SHA512_UPDATE + +/* Define to 1 if you have the `sigprocmask' function. */ +#cmakedefine HAVE_SIGPROCMASK + +/* Define to 1 if you have the `sleep' function. */ +#cmakedefine HAVE_SLEEP + +/* Define to 1 if you have the `snprintf' function. */ +#cmakedefine HAVE_SNPRINTF + +/* Define to 1 if you have the `socketpair' function. */ +#cmakedefine HAVE_SOCKETPAIR + +/* Using Solaris threads */ +#cmakedefine HAVE_SOLARIS_THREADS + +/* Define to 1 if you have the `srandom' function. */ +#cmakedefine HAVE_SRANDOM + +/* Define if you have the SSL libraries installed. */ +#cmakedefine HAVE_SSL + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDARG_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDBOOL_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDLIB_H + +/* Define to 1 if you have the `strftime' function. */ +#cmakedefine HAVE_STRFTIME + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRING_H + +/* Define to 1 if you have the `strlcat' function. */ +#cmakedefine HAVE_STRLCAT + +/* Define to 1 if you have the `strlcpy' function. */ +#cmakedefine HAVE_STRLCPY + +/* Define to 1 if you have the `strptime' function. */ +#cmakedefine HAVE_STRPTIME + +/* Define to 1 if `ipi_spec_dst' is a member of `struct in_pktinfo'. */ +#cmakedefine HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST + +/* Define if you have Swig libraries and header files. */ +#cmakedefine HAVE_SWIG + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYSLOG_H + +/* Define to 1 if you have the header file. */ +#cmakedefine01 HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_RESOURCE_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_SHA2_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_SYSCTL_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_UIO_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_WAIT_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_TIME_H + +/* Define to 1 if you have the `tzset' function. */ +#cmakedefine HAVE_TZSET + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UNISTD_H + +/* Define to 1 if you have the `usleep' function. */ +#cmakedefine HAVE_USLEEP + +/* Define to 1 if you have the `vfork' function. */ +#cmakedefine HAVE_VFORK + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_VFORK_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_WINDOWS_H + +/* Using Windows threads */ +#cmakedefine HAVE_WINDOWS_THREADS + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_WINSOCK2_H + +/* Define to 1 if `fork' works. */ +#cmakedefine HAVE_WORKING_FORK + +/* Define to 1 if `vfork' works. */ +#cmakedefine HAVE_WORKING_VFORK + +/* Define to 1 if you have the `writev' function. */ +#cmakedefine HAVE_WRITEV + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_WS2TCPIP_H + +/* Define to 1 if you have the `_beginthreadex' function. */ +#cmakedefine HAVE__BEGINTHREADEX + +/* if lex has yylex_destroy */ +#cmakedefine LEX_HAS_YYLEX_DESTROY + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Define to the maximum message length to pass to syslog. */ +#define MAXSYSLOGMSGLEN @MAXSYSLOGMSGLEN@ + +/* Define if memcmp() does not compare unsigned bytes */ +#cmakedefine MEMCMP_IS_BROKEN + +/* Define if mkdir has one argument. */ +#cmakedefine MKDIR_HAS_ONE_ARG + +/* Define if the network stack does not fully support nonblocking io (causes + lower performance). */ +#cmakedefine NONBLOCKING_IS_BROKEN + +/* Put -D_ALL_SOURCE define in config.h */ +#cmakedefine OMITTED__D_ALL_SOURCE + +/* Put -D_BSD_SOURCE define in config.h */ +#cmakedefine OMITTED__D_BSD_SOURCE + +/* Put -D_GNU_SOURCE define in config.h */ +#cmakedefine OMITTED__D_GNU_SOURCE + +/* Put -D_LARGEFILE_SOURCE=1 define in config.h */ +#cmakedefine OMITTED__D_LARGEFILE_SOURCE_1 + +/* Put -D_POSIX_C_SOURCE=200112 define in config.h */ +#cmakedefine OMITTED__D_POSIX_C_SOURCE_200112 + +/* Put -D_XOPEN_SOURCE=600 define in config.h */ +#cmakedefine OMITTED__D_XOPEN_SOURCE_600 + +/* Put -D_XOPEN_SOURCE_EXTENDED=1 define in config.h */ +#cmakedefine OMITTED__D_XOPEN_SOURCE_EXTENDED_1 + +/* Put -D__EXTENSIONS__ define in config.h */ +#cmakedefine OMITTED__D__EXTENSIONS__ + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "@PACKAGE_NAME@" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "@PACKAGE_STRING@" + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "@PACKAGE_VERSION@" + +/* default pidfile location */ +#define PIDFILE "@UNBOUND_PIDFILE@" + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +#undef PTHREAD_CREATE_JOINABLE + +/* Define as the return type of signal handlers (`int' or `void'). */ +#cmakedefine RETSIGTYPE @RETSIGTYPE@ + +/* default rootkey location */ +#undef ROOT_ANCHOR_FILE + +/* default rootcert location */ +#undef ROOT_CERT_FILE + +/* version number for resource files */ +#undef RSRC_PACKAGE_VERSION + +/* Directory to chdir to */ +#define RUN_DIR "@UNBOUND_RUN_DIR@" + +/* Shared data */ +#define SHARE_DIR "@UNBOUND_SHARE_DIR@" + +/* The size of `time_t', as computed by sizeof. */ +#undef SIZEOF_TIME_T + +/* Define to 1 if you have the ANSI C header files. */ +#cmakedefine STDC_HEADERS + +/* use default strptime. */ +#cmakedefine STRPTIME_WORKS + +/* Use win32 resources and API */ +#cmakedefine UB_ON_WINDOWS + +/* default username */ +#define UB_USERNAME "@UNBOUND_USERNAME@" + +/* use to enable lightweight alloc assertions, for debug use */ +#cmakedefine UNBOUND_ALLOC_LITE + +/* use malloc not regions, for debug use */ +#cmakedefine UNBOUND_ALLOC_NONREGIONAL + +/* use statistics for allocs and frees, for debug use */ +#cmakedefine UNBOUND_ALLOC_STATS + +/* define this to enable debug checks. */ +#cmakedefine UNBOUND_DEBUG + +/* Define to 1 to enable dnstap support */ +#cmakedefine USE_DNSTAP + +/* Define this to enable ECDSA support. */ +#cmakedefine USE_ECDSA + +/* Define this to enable an EVP workaround for older openssl */ +#cmakedefine USE_ECDSA_EVP_WORKAROUND + +/* Define this to enable GOST support. */ +#cmakedefine USE_GOST + +/* Define if you want to use internal select based events */ +#cmakedefine USE_MINI_EVENT + +/* Define this to enable SHA256 and SHA512 support. */ +#cmakedefine USE_SHA2 + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# define _ALL_SOURCE 1 +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# define _POSIX_PTHREAD_SEMANTICS 1 +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# define _TANDEM_SOURCE 1 +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# define __EXTENSIONS__ 1 +#endif + + +/* Whether the windows socket API is used */ +#cmakedefine USE_WINSOCK + +/* the version of the windows API enabled */ +#define WINVER @WINVER@ + +/* Define if you want Python module. */ +#cmakedefine WITH_PYTHONMODULE + +/* Define if you want PyUnbound. */ +#cmakedefine WITH_PYUNBOUND + +/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a + `char[]'. */ +#undef YYTEXT_POINTER + +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ +#cmakedefine _LARGEFILE_SOURCE + +/* Define for large files, on AIX-style hosts. */ +#cmakedefine _LARGE_FILES + +/* Define to 1 if on MINIX. */ +#cmakedefine _MINIX + +/* Enable for compile on Minix */ +#cmakedefine _NETBSD_SOURCE + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#cmakedefine _POSIX_1_SOURCE + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +#cmakedefine _POSIX_SOURCE + +/* Define to empty if `const' does not conform to ANSI C. */ +#cmakedefine const + +/* Define to `int' if doesn't define. */ +#cmakedefine gid_t @gid_t@ + +/* in_addr_t */ +#cmakedefine in_addr_t @in_addr_t@ + +/* in_port_t */ +#cmakedefine in_port_t @in_port_t@ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#cmakedefine inline @inline@ +#endif + +/* Define to `short' if does not define. */ +#cmakedefine int16_t @int16_t@ + +/* Define to `int' if does not define. */ +#cmakedefine int32_t @int32_t@ + +/* Define to `long long' if does not define. */ +#cmakedefine int64_t @int64_t@ + +/* Define to `signed char' if does not define. */ +#cmakedefine int8_t @int8_t@ + +/* Define if replacement function should be used. */ +#cmakedefine malloc + +/* Define to `long int' if does not define. */ +#cmakedefine off_t + +/* Define to `int' if does not define. */ +#cmakedefine pid_t @pid_t@ + +/* Define to 'int' if not defined */ +#cmakedefine rlim_t @rlim_t@ + +/* Define to `unsigned int' if does not define. */ +#cmakedefine size_t + +/* Define to 'int' if not defined */ +#cmakedefine socklen_t + +/* Define to `int' if does not define. */ +#cmakedefine ssize_t @ssize_t@ + +/* Define to 'unsigned char if not defined */ +#cmakedefine u_char + +/* Define to `int' if doesn't define. */ +#cmakedefine uid_t @uid_t@ + +/* Define to `unsigned short' if does not define. */ +#cmakedefine uint16_t @uint16_t@ + +/* Define to `unsigned int' if does not define. */ +#cmakedefine uint32_t @uint32_t@ + +/* Define to `unsigned long long' if does not define. */ +#cmakedefine uint64_t @uint64_t@ + +/* Define to `unsigned char' if does not define. */ +#cmakedefine uint8_t @uint8_t@ + +/* Define as `fork' if `vfork' does not work. */ +#cmakedefine vfork @vfork@ + +#cmakedefine __func__ @__func__@ + +#if defined(OMITTED__D_GNU_SOURCE) && !defined(_GNU_SOURCE) +#define _GNU_SOURCE 1 +#endif + +#if defined(OMITTED__D_BSD_SOURCE) && !defined(_BSD_SOURCE) +#define _BSD_SOURCE 1 +#endif + +#if defined(OMITTED__D__EXTENSIONS__) && !defined(__EXTENSIONS__) +#define __EXTENSIONS__ 1 +#endif + +#if defined(OMITTED__D_POSIX_C_SOURCE_200112) && !defined(_POSIX_C_SOURCE) +#define _POSIX_C_SOURCE 200112 +#endif + +#if defined(OMITTED__D_XOPEN_SOURCE_600) && !defined(_XOPEN_SOURCE) +#define _XOPEN_SOURCE 600 +#endif + +#if defined(OMITTED__D_XOPEN_SOURCE_EXTENDED_1) && !defined(_XOPEN_SOURCE_EXTENDED) +#define _XOPEN_SOURCE_EXTENDED 1 +#endif + +#if defined(OMITTED__D_ALL_SOURCE) && !defined(_ALL_SOURCE) +#define _ALL_SOURCE 1 +#endif + +#if defined(OMITTED__D_LARGEFILE_SOURCE_1) && !defined(_LARGEFILE_SOURCE) +#define _LARGEFILE_SOURCE 1 +#endif + + + + +#ifndef UNBOUND_DEBUG +# define NDEBUG +#endif + +/** Use small-ldns codebase */ +#define USE_SLDNS 1 +#ifdef HAVE_SSL +# define LDNS_BUILD_CONFIG_HAVE_SSL 1 +#endif + +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include + +#if STDC_HEADERS +#include +#include +#endif + +#ifdef HAVE_STDARG_H +#include +#endif + +#ifdef HAVE_STDINT_H +#include +#endif + +#include + +#if HAVE_SYS_PARAM_H +#include +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#ifdef HAVE_SYS_UIO_H +#include +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#ifdef HAVE_ARPA_INET_H +#include +#endif + +#ifdef HAVE_WINSOCK2_H +#include +#endif + +#ifdef HAVE_WS2TCPIP_H +#include +#endif + +#ifndef USE_WINSOCK +#define ARG_LL "%ll" +#else +#define ARG_LL "%I64" +#endif + + + +#ifdef HAVE_ATTR_FORMAT +# define ATTR_FORMAT(archetype, string_index, first_to_check) \ + __attribute__ ((format (archetype, string_index, first_to_check))) +#else /* !HAVE_ATTR_FORMAT */ +# define ATTR_FORMAT(archetype, string_index, first_to_check) /* empty */ +#endif /* !HAVE_ATTR_FORMAT */ + + +#if defined(DOXYGEN) +# define ATTR_UNUSED(x) x +#elif defined(__cplusplus) +# define ATTR_UNUSED(x) +#elif defined(HAVE_ATTR_UNUSED) +# define ATTR_UNUSED(x) x __attribute__((unused)) +#else /* !HAVE_ATTR_UNUSED */ +# define ATTR_UNUSED(x) x +#endif /* !HAVE_ATTR_UNUSED */ + + +#ifndef HAVE_FSEEKO +#define fseeko fseek +#define ftello ftell +#endif /* HAVE_FSEEKO */ + + +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 256 +#endif + + +#ifndef HAVE_SNPRINTF +#define snprintf snprintf_unbound +#define vsnprintf vsnprintf_unbound +#include +int snprintf (char *str, size_t count, const char *fmt, ...); +int vsnprintf (char *str, size_t count, const char *fmt, va_list arg); +#endif /* HAVE_SNPRINTF */ + + +#ifndef HAVE_INET_PTON +#define inet_pton inet_pton_unbound +int inet_pton(int af, const char* src, void* dst); +#endif /* HAVE_INET_PTON */ + + +#ifndef HAVE_INET_NTOP +#define inet_ntop inet_ntop_unbound +const char *inet_ntop(int af, const void *src, char *dst, size_t size); +#endif + + +#ifndef HAVE_INET_ATON +#define inet_aton inet_aton_unbound +int inet_aton(const char *cp, struct in_addr *addr); +#endif + + +#ifndef HAVE_MEMMOVE +#define memmove memmove_unbound +void *memmove(void *dest, const void *src, size_t n); +#endif + + +#ifndef HAVE_STRLCAT +#define strlcat strlcat_unbound +size_t strlcat(char *dst, const char *src, size_t siz); +#endif + + +#ifndef HAVE_STRLCPY +#define strlcpy strlcpy_unbound +size_t strlcpy(char *dst, const char *src, size_t siz); +#endif + + +#ifndef HAVE_GMTIME_R +#define gmtime_r gmtime_r_unbound +struct tm *gmtime_r(const time_t *timep, struct tm *result); +#endif + + +#if !defined(HAVE_SLEEP) || defined(HAVE_WINDOWS_H) +#define sleep(x) Sleep((x)*1000) /* on win32 */ +#endif /* HAVE_SLEEP */ + + +#ifndef HAVE_USLEEP +#define usleep(x) Sleep((x)/1000 + 1) /* on win32 */ +#endif /* HAVE_USLEEP */ + + +#ifndef HAVE_RANDOM +#define random rand /* on win32, for tests only (bad random) */ +#endif /* HAVE_RANDOM */ + + +#ifndef HAVE_SRANDOM +#define srandom(x) srand(x) /* on win32, for tests only (bad random) */ +#endif /* HAVE_SRANDOM */ + + +/* detect if we need to cast to unsigned int for FD_SET to avoid warnings */ +#ifdef HAVE_WINSOCK2_H +#define FD_SET_T (u_int) +#else +#define FD_SET_T +#endif + + +#ifndef IPV6_MIN_MTU +#define IPV6_MIN_MTU 1280 +#endif /* IPV6_MIN_MTU */ + + +#ifdef MEMCMP_IS_BROKEN +#include "compat/memcmp.h" +#define memcmp memcmp_unbound +int memcmp(const void *x, const void *y, size_t n); +#endif + + + +#ifndef HAVE_CTIME_R +#define ctime_r unbound_ctime_r +char *ctime_r(const time_t *timep, char *buf); +#endif + +#if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS) +#define strptime unbound_strptime +struct tm; +char *strptime(const char *s, const char *format, struct tm *tm); +#endif + +#ifdef HAVE_LIBRESSL +# if !HAVE_DECL_STRLCPY +size_t strlcpy(char *dst, const char *src, size_t siz); +# endif +# if !HAVE_DECL_STRLCAT +size_t strlcat(char *dst, const char *src, size_t siz); +# endif +# if !HAVE_DECL_ARC4RANDOM && defined(HAVE_ARC4RANDOM) +uint32_t arc4random(void); +# endif +# if !HAVE_DECL_ARC4RANDOM_UNIFORM && defined(HAVE_ARC4RANDOM_UNIFORM) +uint32_t arc4random_uniform(uint32_t upper_bound); +# endif +#endif /* HAVE_LIBRESSL */ +#ifndef HAVE_ARC4RANDOM +void explicit_bzero(void* buf, size_t len); +int getentropy(void* buf, size_t len); +uint32_t arc4random(void); +void arc4random_buf(void* buf, size_t n); +void _ARC4_LOCK(void); +void _ARC4_UNLOCK(void); +#endif +#ifndef HAVE_ARC4RANDOM_UNIFORM +uint32_t arc4random_uniform(uint32_t upper_bound); +#endif +#ifdef COMPAT_SHA512 +#ifndef SHA512_DIGEST_LENGTH +#define SHA512_BLOCK_LENGTH 128 +#define SHA512_DIGEST_LENGTH 64 +#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) +typedef struct _SHA512_CTX { + uint64_t state[8]; + uint64_t bitcount[2]; + uint8_t buffer[SHA512_BLOCK_LENGTH]; +} SHA512_CTX; +#endif /* SHA512_DIGEST_LENGTH */ +void SHA512_Init(SHA512_CTX*); +void SHA512_Update(SHA512_CTX*, void*, size_t); +void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); +unsigned char *SHA512(void* data, unsigned int data_len, unsigned char *digest); +#endif /* COMPAT_SHA512 */ + + + +#if defined(HAVE_EVENT_H) && !defined(HAVE_EVENT_BASE_ONCE) && !(defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)) && (defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS)) + /* using version of libevent that is not threadsafe. */ +# define LIBEVENT_SIGNAL_PROBLEM 1 +#endif + +#ifndef CHECKED_INET6 +# define CHECKED_INET6 +# ifdef AF_INET6 +# define INET6 +# else +# define AF_INET6 28 +# endif +#endif /* CHECKED_INET6 */ + +#ifndef HAVE_GETADDRINFO +struct sockaddr_storage; +#include "compat/fake-rfc2553.h" +#endif + +#ifdef UNBOUND_ALLOC_STATS +# define malloc(s) unbound_stat_malloc_log(s, __FILE__, __LINE__, __func__) +# define calloc(n,s) unbound_stat_calloc_log(n, s, __FILE__, __LINE__, __func__) +# define free(p) unbound_stat_free_log(p, __FILE__, __LINE__, __func__) +# define realloc(p,s) unbound_stat_realloc_log(p, s, __FILE__, __LINE__, __func__) +void *unbound_stat_malloc(size_t size); +void *unbound_stat_calloc(size_t nmemb, size_t size); +void unbound_stat_free(void *ptr); +void *unbound_stat_realloc(void *ptr, size_t size); +void *unbound_stat_malloc_log(size_t size, const char* file, int line, + const char* func); +void *unbound_stat_calloc_log(size_t nmemb, size_t size, const char* file, + int line, const char* func); +void unbound_stat_free_log(void *ptr, const char* file, int line, + const char* func); +void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file, + int line, const char* func); +#elif defined(UNBOUND_ALLOC_LITE) +# include "util/alloc.h" +#endif /* UNBOUND_ALLOC_LITE and UNBOUND_ALLOC_STATS */ + +/** default port for DNS traffic. */ +#define UNBOUND_DNS_PORT 53 +/** default port for unbound control traffic, registered port with IANA, + ub-dns-control 8953/tcp unbound dns nameserver control */ +#define UNBOUND_CONTROL_PORT 8953 +/** the version of unbound-control that this software implements */ +#define UNBOUND_CONTROL_VERSION 1 + + diff --git a/external/unbound/config.h.in b/external/unbound/config.h.in index 5f8f8a992..2b7770b5c 100644 --- a/external/unbound/config.h.in +++ b/external/unbound/config.h.in @@ -1,8 +1,5 @@ /* config.h.in. Generated from configure.ac by autoheader. */ -/* define if a library can reference the 'main' symbol */ -#undef CAN_REFERENCE_MAIN - /* Directory to chroot to */ #undef CHROOT_DIR diff --git a/external/unbound/configure b/external/unbound/configure index 40829514c..bdfc14f22 100755 --- a/external/unbound/configure +++ b/external/unbound/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for unbound 1.4.23. +# Generated by GNU Autoconf 2.69 for unbound 1.5.1. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='unbound' PACKAGE_TARNAME='unbound' -PACKAGE_VERSION='1.4.23' -PACKAGE_STRING='unbound 1.4.23' +PACKAGE_VERSION='1.5.1' +PACKAGE_STRING='unbound 1.5.1' PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl' PACKAGE_URL='' @@ -632,6 +632,8 @@ ac_includes_default="\ #endif" ac_subst_vars='LTLIBOBJS +date +version INSTALLTARGET ALLTARGET SOURCEFILE @@ -1385,7 +1387,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures unbound 1.4.23 to adapt to many kinds of systems. +\`configure' configures unbound 1.5.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1450,7 +1452,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of unbound 1.4.23:";; + short | recursive ) echo "Configuration of unbound 1.5.1:";; esac cat <<\_ACEOF @@ -1536,7 +1538,7 @@ Optional Packages: --with-dnstap-socket-path=pathname set default dnstap socket path --with-protobuf-c=path Path where protobuf-c is installed, for dnstap - --with-libfstrm=path Path where libfstrm in installed, for dnstap + --with-libfstrm=path Path where libfstrm is installed, for dnstap --with-libunbound-only do not build daemon and tool programs Some influential environment variables: @@ -1625,7 +1627,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -unbound configure 1.4.23 +unbound configure 1.5.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2334,7 +2336,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by unbound $as_me 1.4.23, which was +It was created by unbound $as_me 1.5.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2684,14 +2686,14 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu UNBOUND_VERSION_MAJOR=1 -UNBOUND_VERSION_MINOR=4 +UNBOUND_VERSION_MINOR=5 -UNBOUND_VERSION_MICRO=23 +UNBOUND_VERSION_MICRO=1 -LIBUNBOUND_CURRENT=4 +LIBUNBOUND_CURRENT=5 LIBUNBOUND_REVISION=3 -LIBUNBOUND_AGE=2 +LIBUNBOUND_AGE=3 # 1.0.0 had 0:12:0 # 1.0.1 had 0:13:0 # 1.0.2 had 0:14:0 @@ -2729,7 +2731,8 @@ LIBUNBOUND_AGE=2 # 1.4.20 had 4:0:2 # adds libunbound.ttl # but shipped 3:5:1 # 1.4.21 had 4:1:2 # 1.4.22 had 4:1:2 -# 1.4.23 had 4:3:2 +# 1.5.0 had 5:3:3 # adds ub_ctx_add_ta_autr +# 1.5.1 had 5:4:3 # Current -- the number of the binary API that we're implementing # Revision -- which iteration of the implementation of the binary @@ -18310,1411 +18313,6 @@ fi ;; esac - # generate libtool to test if linking main - # from a dynamic library works. - : ${CONFIG_LT=./config.lt} -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_LT" >&5 -$as_echo "$as_me: creating $CONFIG_LT" >&6;} -as_write_fail=0 -cat >"$CONFIG_LT" <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate a libtool stub with the current configuration. -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>"$CONFIG_LT" <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## --------------------------------- ## -## Main body of "$CONFIG_LT" script. ## -## --------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x "$CONFIG_LT" - -cat >>"$CONFIG_LT" <<\_LTEOF -lt_cl_silent=false -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX -} >&5 - -lt_cl_help="\ -\`$as_me' creates a local libtool stub from the current configuration, -for use in further configure time tests before the real libtool is -generated. - -Usage: $0 [OPTIONS] - - -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - -Report bugs to ." - -lt_cl_version="\ -unbound config.lt 1.4.23 -configured by $0, generated by GNU Autoconf 2.69. - -Copyright (C) 2011 Free Software Foundation, Inc. -This config.lt script is free software; the Free Software Foundation -gives unlimited permision to copy, distribute and modify it." - -while test $# != 0 -do - case $1 in - --version | --v* | -V ) - echo "$lt_cl_version"; exit 0 ;; - --help | --h* | -h ) - echo "$lt_cl_help"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --quiet | --q* | --silent | --s* | -q ) - lt_cl_silent=: ;; - - -*) as_fn_error $? "unrecognized option: $1 -Try \`$0 --help' for more information." "$LINENO" 5 ;; - - *) as_fn_error $? "unrecognized argument: $1 -Try \`$0 --help' for more information." "$LINENO" 5 ;; - esac - shift -done - -if $lt_cl_silent; then - exec 6>/dev/null -fi -_LTEOF - -cat >>"$CONFIG_LT" <<_LTEOF - - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' -macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' -enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' -enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' -pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' -enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' -SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' -ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' -PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' -host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' -host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' -host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' -build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' -build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' -build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' -SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' -Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' -GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' -EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' -FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' -LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' -NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' -LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' -max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' -ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' -exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' -lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' -lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' -lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' -lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' -lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' -reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' -reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' -OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' -deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' -file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' -file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' -want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' -DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' -sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' -AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' -AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' -archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' -STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' -RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' -old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' -old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' -old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' -lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' -CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' -CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' -compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' -GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' -nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' -lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' -objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' -MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' -lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' -need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' -MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' -DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' -NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' -LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' -OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' -OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' -libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' -shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' -extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' -archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' -enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' -export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' -whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' -compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' -old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' -old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' -archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' -archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' -module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' -module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' -with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' -allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' -no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' -hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' -hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' -hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' -hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' -hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' -inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' -link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' -always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' -export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' -exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' -include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' -prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' -postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' -file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' -variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' -need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' -need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' -version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' -runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' -shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' -shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' -libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' -library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' -soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' -install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' -postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' -postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' -finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' -finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' -hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' -sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' -sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' -hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' -enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' -enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' -enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' -old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' -striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' - -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$1 -_LTECHO_EOF' -} - -# Quote evaled strings. -for var in SHELL \ -ECHO \ -PATH_SEPARATOR \ -SED \ -GREP \ -EGREP \ -FGREP \ -LD \ -NM \ -LN_S \ -lt_SP2NL \ -lt_NL2SP \ -reload_flag \ -OBJDUMP \ -deplibs_check_method \ -file_magic_cmd \ -file_magic_glob \ -want_nocaseglob \ -DLLTOOL \ -sharedlib_from_linklib_cmd \ -AR \ -AR_FLAGS \ -archiver_list_spec \ -STRIP \ -RANLIB \ -CC \ -CFLAGS \ -compiler \ -lt_cv_sys_global_symbol_pipe \ -lt_cv_sys_global_symbol_to_cdecl \ -lt_cv_sys_global_symbol_to_c_name_address \ -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ -nm_file_list_spec \ -lt_prog_compiler_no_builtin_flag \ -lt_prog_compiler_pic \ -lt_prog_compiler_wl \ -lt_prog_compiler_static \ -lt_cv_prog_compiler_c_o \ -need_locks \ -MANIFEST_TOOL \ -DSYMUTIL \ -NMEDIT \ -LIPO \ -OTOOL \ -OTOOL64 \ -shrext_cmds \ -export_dynamic_flag_spec \ -whole_archive_flag_spec \ -compiler_needs_object \ -with_gnu_ld \ -allow_undefined_flag \ -no_undefined_flag \ -hardcode_libdir_flag_spec \ -hardcode_libdir_separator \ -exclude_expsyms \ -include_expsyms \ -file_list_spec \ -variables_saved_for_relink \ -libname_spec \ -library_names_spec \ -soname_spec \ -install_override_mode \ -finish_eval \ -old_striplib \ -striplib; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in reload_cmds \ -old_postinstall_cmds \ -old_postuninstall_cmds \ -old_archive_cmds \ -extract_expsyms_cmds \ -old_archive_from_new_cmds \ -old_archive_from_expsyms_cmds \ -archive_cmds \ -archive_expsym_cmds \ -module_cmds \ -module_expsym_cmds \ -export_symbols_cmds \ -prelink_cmds \ -postlink_cmds \ -postinstall_cmds \ -postuninstall_cmds \ -finish_cmds \ -sys_lib_search_path_spec \ -sys_lib_dlsearch_path_spec; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -ac_aux_dir='$ac_aux_dir' -xsi_shell='$xsi_shell' -lt_shell_append='$lt_shell_append' - -# See if we are running on zsh, and set the options which allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - - - PACKAGE='$PACKAGE' - VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' - RM='$RM' - ofile='$ofile' - - - -_LTEOF - -cat >>"$CONFIG_LT" <<\_LTEOF -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $ofile" >&5 -$as_echo "$as_me: creating $ofile" >&6;} - - - # See if we are running on zsh, and set the options which allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - - cfgfile="${ofile}T" - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL - -# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is part of GNU Libtool. -# -# GNU Libtool is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or -# obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - -# The names of the tagged configurations supported by this script. -available_tags="" - -# ### BEGIN LIBTOOL CONFIG - -# Which release of libtool.m4 was used? -macro_version=$macro_version -macro_revision=$macro_revision - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# What type of objects to build. -pic_mode=$pic_mode - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# An echo program that protects backslashes. -ECHO=$lt_ECHO - -# The PATH separator for the build system. -PATH_SEPARATOR=$lt_PATH_SEPARATOR - -# The host system. -host_alias=$host_alias -host=$host -host_os=$host_os - -# The build system. -build_alias=$build_alias -build=$build -build_os=$build_os - -# A sed program that does not truncate output. -SED=$lt_SED - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="\$SED -e 1s/^X//" - -# A grep program that handles long lines. -GREP=$lt_GREP - -# An ERE matcher. -EGREP=$lt_EGREP - -# A literal string matcher. -FGREP=$lt_FGREP - -# A BSD- or MS-compatible name lister. -NM=$lt_NM - -# Whether we need soft or hard links. -LN_S=$lt_LN_S - -# What is the maximum length of a command? -max_cmd_len=$max_cmd_len - -# Object file suffix (normally "o"). -objext=$ac_objext - -# Executable file suffix (normally ""). -exeext=$exeext - -# whether the shell understands "unset". -lt_unset=$lt_unset - -# turn spaces into newlines. -SP2NL=$lt_lt_SP2NL - -# turn newlines into spaces. -NL2SP=$lt_lt_NL2SP - -# convert \$build file names to \$host format. -to_host_file_cmd=$lt_cv_to_host_file_cmd - -# convert \$build files to toolchain format. -to_tool_file_cmd=$lt_cv_to_tool_file_cmd - -# An object symbol dumper. -OBJDUMP=$lt_OBJDUMP - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method = "file_magic". -file_magic_cmd=$lt_file_magic_cmd - -# How to find potential files when deplibs_check_method = "file_magic". -file_magic_glob=$lt_file_magic_glob - -# Find potential files using nocaseglob when deplibs_check_method = "file_magic". -want_nocaseglob=$lt_want_nocaseglob - -# DLL creation program. -DLLTOOL=$lt_DLLTOOL - -# Command to associate shared and link libraries. -sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd - -# The archiver. -AR=$lt_AR - -# Flags to create an archive. -AR_FLAGS=$lt_AR_FLAGS - -# How to feed a file listing to the archiver. -archiver_list_spec=$lt_archiver_list_spec - -# A symbol stripping program. -STRIP=$lt_STRIP - -# Commands used to install an old-style archive. -RANLIB=$lt_RANLIB -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Whether to use a lock for old archive extraction. -lock_old_archive_extraction=$lock_old_archive_extraction - -# A C compiler. -LTCC=$lt_CC - -# LTCC compiler flags. -LTCFLAGS=$lt_CFLAGS - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration. -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair. -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# Transform the output of nm in a C name address pair when lib prefix is needed. -global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix - -# Specify filename containing input files for \$NM. -nm_file_list_spec=$lt_nm_file_list_spec - -# The root where to search for dependent libraries,and in which our libraries should be installed. -lt_sysroot=$lt_sysroot - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# Used to examine libraries when file_magic_cmd begins with "file". -MAGIC_CMD=$MAGIC_CMD - -# Must we lock files when doing compilation? -need_locks=$lt_need_locks - -# Manifest tool. -MANIFEST_TOOL=$lt_MANIFEST_TOOL - -# Tool to manipulate archived DWARF debug symbol files on Mac OS X. -DSYMUTIL=$lt_DSYMUTIL - -# Tool to change global to local symbols on Mac OS X. -NMEDIT=$lt_NMEDIT - -# Tool to manipulate fat objects and archives on Mac OS X. -LIPO=$lt_LIPO - -# ldd/readelf like tool for Mach-O binaries on Mac OS X. -OTOOL=$lt_OTOOL - -# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. -OTOOL64=$lt_OTOOL64 - -# Old archive suffix (normally "a"). -libext=$libext - -# Shared library suffix (normally ".so"). -shrext_cmds=$lt_shrext_cmds - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at link time. -variables_saved_for_relink=$lt_variables_saved_for_relink - -# Do we need the "lib" prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Library versioning type. -version_type=$version_type - -# Shared library runtime path variable. -runpath_var=$runpath_var - -# Shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Permission mode override for installation of shared libraries. -install_override_mode=$lt_install_override_mode - -# Command to use after installation of a shared archive. -postinstall_cmds=$lt_postinstall_cmds - -# Command to use after uninstallation of a shared archive. -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# As "finish_cmds", except a single script fragment to be evaled but -# not shown. -finish_eval=$lt_finish_eval - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Compile-time system search path for libraries. -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries. -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - - -# The linker used to build libraries. -LD=$lt_LD - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# Commands used to build an old-style archive. -old_archive_cmds=$lt_old_archive_cmds - -# A language specific compiler. -CC=$lt_compiler - -# Is the compiler the GNU compiler? -with_gcc=$GCC - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc - -# Whether or not to disallow shared libs when runtime libs are static. -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec - -# Whether the compiler copes with passing no objects directly. -compiler_needs_object=$lt_compiler_needs_object - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds - -# Commands used to build a shared archive. -archive_cmds=$lt_archive_cmds -archive_expsym_cmds=$lt_archive_expsym_cmds - -# Commands used to build a loadable module if different from building -# a shared archive. -module_cmds=$lt_module_cmds -module_expsym_cmds=$lt_module_expsym_cmds - -# Whether we are building with GNU ld or not. -with_gnu_ld=$lt_with_gnu_ld - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag - -# Flag that enforces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec - -# Whether we need a single "-rpath" flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator - -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes -# DIR into the resulting binary. -hardcode_direct=$hardcode_direct - -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes -# DIR into the resulting binary and the resulting library dependency is -# "absolute",i.e impossible to change by setting \${shlibpath_var} if the -# library is relocated. -hardcode_direct_absolute=$hardcode_direct_absolute - -# Set to "yes" if using the -LDIR flag during linking hardcodes DIR -# into the resulting binary. -hardcode_minus_L=$hardcode_minus_L - -# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR -# into the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var - -# Set to "yes" if building a shared library automatically hardcodes DIR -# into the library and all subsequent libraries and executables linked -# against it. -hardcode_automatic=$hardcode_automatic - -# Set to yes if linker adds runtime paths of dependent libraries -# to runtime path list. -inherit_rpath=$inherit_rpath - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs - -# Set to "yes" if exported symbols are required. -always_export_symbols=$always_export_symbols - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms - -# Commands necessary for linking programs (against libraries) with templates. -prelink_cmds=$lt_prelink_cmds - -# Commands necessary for finishing linking programs. -postlink_cmds=$lt_postlink_cmds - -# Specify filename containing input files. -file_list_spec=$lt_file_list_spec - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action - -# ### END LIBTOOL CONFIG - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - -ltmain="$ac_aux_dir/ltmain.sh" - - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - if test x"$xsi_shell" = xyes; then - sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ -func_dirname ()\ -{\ -\ case ${1} in\ -\ */*) func_dirname_result="${1%/*}${2}" ;;\ -\ * ) func_dirname_result="${3}" ;;\ -\ esac\ -} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_basename ()$/,/^} # func_basename /c\ -func_basename ()\ -{\ -\ func_basename_result="${1##*/}"\ -} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ -func_dirname_and_basename ()\ -{\ -\ case ${1} in\ -\ */*) func_dirname_result="${1%/*}${2}" ;;\ -\ * ) func_dirname_result="${3}" ;;\ -\ esac\ -\ func_basename_result="${1##*/}"\ -} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ -func_stripname ()\ -{\ -\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ -\ # positional parameters, so assign one to ordinary parameter first.\ -\ func_stripname_result=${3}\ -\ func_stripname_result=${func_stripname_result#"${1}"}\ -\ func_stripname_result=${func_stripname_result%"${2}"}\ -} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ -func_split_long_opt ()\ -{\ -\ func_split_long_opt_name=${1%%=*}\ -\ func_split_long_opt_arg=${1#*=}\ -} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ -func_split_short_opt ()\ -{\ -\ func_split_short_opt_arg=${1#??}\ -\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ -} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ -func_lo2o ()\ -{\ -\ case ${1} in\ -\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ -\ *) func_lo2o_result=${1} ;;\ -\ esac\ -} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_xform ()$/,/^} # func_xform /c\ -func_xform ()\ -{\ - func_xform_result=${1%.*}.lo\ -} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_arith ()$/,/^} # func_arith /c\ -func_arith ()\ -{\ - func_arith_result=$(( $* ))\ -} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_len ()$/,/^} # func_len /c\ -func_len ()\ -{\ - func_len_result=${#1}\ -} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - -fi - -if test x"$lt_shell_append" = xyes; then - sed -e '/^func_append ()$/,/^} # func_append /c\ -func_append ()\ -{\ - eval "${1}+=\\${2}"\ -} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ -func_append_quoted ()\ -{\ -\ func_quote_for_eval "${2}"\ -\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ -} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - # Save a `func_append' function call where possible by direct use of '+=' - sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -else - # Save a `func_append' function call even when '+=' is not available - sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -fi - -if test x"$_lt_function_replace_fail" = x":"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 -$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} -fi - - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" - - -as_fn_exit 0 -_LTEOF -chmod +x "$CONFIG_LT" - -# configure is writing to config.log, but config.lt does its own redirection, -# appending to config.log, which fails on DOS, as config.log is still kept -# open by configure. Here we exec the FD to /dev/null, effectively closing -# config.log, so it can be properly (re)opened and appended to by config.lt. -lt_cl_success=: -test "$silent" = yes && - lt_config_lt_args="$lt_config_lt_args --quiet" -exec 5>/dev/null -$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false -exec 5>>config.log -$lt_cl_success || as_fn_exit 1 - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if dynamic lib can refer to main" >&5 -$as_echo_n "checking if dynamic lib can refer to main... " >&6; } - cat >tmp.$$.def <tmp.$$.c </dev/null 2>&1 - if test $? = 0; then myok=yes; else myok=no; fi - if test "$myok" = "yes"; then - $mylibtool --quiet --tag=CC --mode=link $CC $CFLAGS -version-info 1:0:0 -no-undefined -export-symbols tmp.$$.def -o libtmp$$.la tmp.$$.lo $LDFLAGS -rpath $mylibdir $LIBS >/dev/null 2>&1 - if test $? = 0; then myok=yes; else myok=no; fi - fi - if test "$myok" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -$as_echo "#define CAN_REFERENCE_MAIN 1" >>confdefs.h - - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - $mylibtool --quiet --mode=clean rm -rf libtmp$$.la tmp.$$.lo - rm -f tmp.$$.def tmp.$$.c libtmp$$.la tmp.$$.lo tmp.$$.o - fi fi @@ -19844,7 +18442,7 @@ fi # Check whether --with-protobuf-c was given. if test "${with_protobuf_c+set}" = set; then : withval=$with_protobuf_c; - # workaround for protobuf includes at old dir before protobuf-1.0.0 + # workaround for protobuf-c includes at old dir before protobuf-c-1.0.0 if test -f $withval/include/google/protobuf-c/protobuf-c.h; then CFLAGS="$CFLAGS -I$withval/include/google" else @@ -19854,7 +18452,7 @@ if test "${with_protobuf_c+set}" = set; then : else - # workaround for protobuf includes at old dir before protobuf-1.0.0 + # workaround for protobuf-c includes at old dir before protobuf-c-1.0.0 if test -f /usr/include/google/protobuf-c/protobuf-c.h; then CFLAGS="$CFLAGS -I/usr/include/google" else @@ -19875,9 +18473,9 @@ if test "${with_libfstrm+set}" = set; then : fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing fstrm_io_init" >&5 -$as_echo_n "checking for library containing fstrm_io_init... " >&6; } -if ${ac_cv_search_fstrm_io_init+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing fstrm_iothr_init" >&5 +$as_echo_n "checking for library containing fstrm_iothr_init... " >&6; } +if ${ac_cv_search_fstrm_iothr_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS @@ -19890,11 +18488,11 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char fstrm_io_init (); +char fstrm_iothr_init (); int main () { -return fstrm_io_init (); +return fstrm_iothr_init (); ; return 0; } @@ -19907,28 +18505,30 @@ for ac_lib in '' fstrm; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_fstrm_io_init=$ac_res + ac_cv_search_fstrm_iothr_init=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext - if ${ac_cv_search_fstrm_io_init+:} false; then : + if ${ac_cv_search_fstrm_iothr_init+:} false; then : break fi done -if ${ac_cv_search_fstrm_io_init+:} false; then : +if ${ac_cv_search_fstrm_iothr_init+:} false; then : else - ac_cv_search_fstrm_io_init=no + ac_cv_search_fstrm_iothr_init=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_fstrm_io_init" >&5 -$as_echo "$ac_cv_search_fstrm_io_init" >&6; } -ac_res=$ac_cv_search_fstrm_io_init +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_fstrm_iothr_init" >&5 +$as_echo "$ac_cv_search_fstrm_iothr_init" >&6; } +ac_res=$ac_cv_search_fstrm_iothr_init if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" +else + as_fn_error $? "The fstrm library was not found. Please install fstrm!" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing protobuf_c_message_pack" >&5 @@ -19985,6 +18585,8 @@ ac_res=$ac_cv_search_protobuf_c_message_pack if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" +else + as_fn_error $? "The protobuf-c library was not found. Please install protobuf-c!" "$LINENO" 5 fi @@ -20150,6 +18752,11 @@ _ACEOF +version=1.5.1 + +date=`date +'%b %e, %Y'` + + ac_config_files="$ac_config_files Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h" ac_config_headers="$ac_config_headers config.h" @@ -20660,7 +19267,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by unbound $as_me 1.4.23, which was +This file was extended by unbound $as_me 1.5.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -20726,7 +19333,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -unbound config.status 1.4.23 +unbound config.status 1.5.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -21118,7 +19725,6 @@ fi RM='$RM' ofile='$ofile' -ac_aux_dir='$ac_aux_dir' diff --git a/external/unbound/configure.ac b/external/unbound/configure.ac index a22ddc90c..7e5da1a9f 100644 --- a/external/unbound/configure.ac +++ b/external/unbound/configure.ac @@ -9,16 +9,16 @@ sinclude(dnstap/dnstap.m4) # must be numbers. ac_defun because of later processing m4_define([VERSION_MAJOR],[1]) -m4_define([VERSION_MINOR],[4]) -m4_define([VERSION_MICRO],[23]) +m4_define([VERSION_MINOR],[5]) +m4_define([VERSION_MICRO],[1]) AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl, unbound) AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR]) AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR]) AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO]) -LIBUNBOUND_CURRENT=4 +LIBUNBOUND_CURRENT=5 LIBUNBOUND_REVISION=3 -LIBUNBOUND_AGE=2 +LIBUNBOUND_AGE=3 # 1.0.0 had 0:12:0 # 1.0.1 had 0:13:0 # 1.0.2 had 0:14:0 @@ -56,7 +56,8 @@ LIBUNBOUND_AGE=2 # 1.4.20 had 4:0:2 # adds libunbound.ttl # but shipped 3:5:1 # 1.4.21 had 4:1:2 # 1.4.22 had 4:1:2 -# 1.4.23 had 4:3:2 +# 1.5.0 had 5:3:3 # adds ub_ctx_add_ta_autr +# 1.5.1 had 5:4:3 # Current -- the number of the binary API that we're implementing # Revision -- which iteration of the implementation of the binary @@ -1022,39 +1023,6 @@ if test "$USE_NSS" = "no"; then AC_SEARCH_LIBS([clock_gettime], [rt]) ;; esac - # generate libtool to test if linking main - # from a dynamic library works. - LT_OUTPUT - AC_MSG_CHECKING([if dynamic lib can refer to main]) - cat >tmp.$$.def <tmp.$$.c </dev/null 2>&1 - if test $? = 0; then myok=yes; else myok=no; fi - if test "$myok" = "yes"; then - $mylibtool --quiet --tag=CC --mode=link $CC $CFLAGS -version-info 1:0:0 -no-undefined -export-symbols tmp.$$.def -o libtmp$$.la tmp.$$.lo $LDFLAGS -rpath $mylibdir $LIBS >/dev/null 2>&1 - if test $? = 0; then myok=yes; else myok=no; fi - fi - if test "$myok" = "yes"; then - AC_MSG_RESULT(yes) - AC_DEFINE(CAN_REFERENCE_MAIN, [1], [define if a library can reference the 'main' symbol]) - else - AC_MSG_RESULT(no) - fi - $mylibtool --quiet --mode=clean rm -rf libtmp$$.la tmp.$$.lo - rm -f tmp.$$.def tmp.$$.c libtmp$$.la tmp.$$.lo tmp.$$.o - fi ]) fi @@ -1365,6 +1333,11 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file, ]) +dnl if we build from source tree, the man pages need @date@ and @version@ +dnl if this is a distro tarball, that was already done by makedist.sh +AC_SUBST(version, [VERSION_MAJOR.VERSION_MINOR.VERSION_MICRO]) +AC_SUBST(date, [`date +'%b %e, %Y'`]) + AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h]) AC_CONFIG_HEADER([config.h]) AC_OUTPUT diff --git a/external/unbound/configure_checks.cmake b/external/unbound/configure_checks.cmake new file mode 100644 index 000000000..ead51e98f --- /dev/null +++ b/external/unbound/configure_checks.cmake @@ -0,0 +1,218 @@ +include(CheckIncludeFile) +include(CheckFunctionExists) +include(CheckSymbolExists) +include(CheckTypeSize) + +# Need expat. + +check_include_file(arpa/inet.h HAVE_ARPA_INET_H) +check_include_file(endian.h HAVE_ENDIAN_H) +check_include_file(dlfcn.h HAVE_DLFCN_H) +check_include_file(event.h HAVE_EVENT_H) +check_include_file(getopt.h HAVE_GETOPT_H) +check_include_file(glob.h HAVE_GLOB_H) +check_include_file(grp.h HAVE_GRP_H) +check_include_file(inttypes.h HAVE_INTTYPES_H) +check_include_file(iphlpapi.h HAVE_IPHLPAPI_H) +check_include_file(login_cap.h HAVE_LOGIN_CAP_H) +check_include_file(memory.h HAVE_MEMORY_H) +check_include_file(netdb.h HAVE_NETDB_H) +check_include_file(netinet/in.h HAVE_NETINET_IN_H) +check_include_file(pwd.h HAVE_PWD_H) +check_include_file(stdarg.h HAVE_STDARG_H) +check_include_file(stdbool.h HAVE_STDBOOL_H) +check_include_file(stdint.h HAVE_STDINT_H) +check_include_file(stdlib.h HAVE_STDLIB_H) +check_include_file(strings.h HAVE_STRINGS_H) +check_include_file(string.h HAVE_STRING_H) +check_include_file(sys/param.h HAVE_SYS_PARAM_H) +check_include_file(sys/resource.h HAVE_SYS_RESOURCE_H) +check_include_file(sys/sha2.h HAVE_SYS_SHA2_H) +check_include_file(sys/socket.h HAVE_SYS_SOCKET_H) +check_include_file(sys/stat.h HAVE_SYS_STAT_H) +check_include_file(sys/sysctl.h HAVE_SYS_SYSCTL_H) +check_include_file(sys/types.h HAVE_SYS_TYPES_H) +check_include_file(sys/uio.h HAVE_SYS_UIO_H) +check_include_file(sys/wait.h HAVE_SYS_WAIT_H) +check_include_file(syslog.h HAVE_SYSLOG_H) +check_include_file(time.h HAVE_TIME_H) +check_include_file(unistd.h HAVE_UNISTD_H) +check_include_file(vfork.h HAVE_VFORK_H) +check_include_file(windows.h HAVE_WINDOWS_H) +check_include_file(winsock2.h HAVE_WINSOCK2_H) +check_include_file(ws2tcpip.h HAVE_WS2TCPIP_H) + +if (WIN32) + set(CMAKE_REQUIRED_LIBRARIES + iphlpapi + ws2_32) +endif () + +check_function_exists(arc4random HAVE_ARC4RANDOM) +check_function_exists(arc4random_uniform HAVE_ARC4RANDOM_UNIFORM) +check_function_exists(chown HAVE_CHOWN) +check_function_exists(chroot HAVE_CHROOT) +check_function_exists(ctime_r HAVE_CTIME_R) +check_function_exists(daemon HAVE_DAEMON) +check_function_exists(endprotoent HAVE_ENDPROTOENT) +check_function_exists(endservent HAVE_ENDSERVENT) +check_function_exists(fnctl HAVE_FNCTL) +check_function_exists(fork HAVE_FORK) +check_function_exists(fseeko HAVE_FSEEKO) +check_function_exists(getentropy HAVE_GETENTROPY) +check_function_exists(getpwnam HAVE_GETPWNAM) +check_function_exists(getrlimit HAVE_GETRLIMIT) +check_function_exists(glob HAVE_GLOB) +check_function_exists(gmtime_r HAVE_GMTIME_R) +check_function_exists(inet_aton HAVE_INET_ATON) +check_function_exists(inet_ntop HAVE_INET_NTOP) +check_function_exists(inet_pton HAVE_INET_PTON) +check_function_exists(initgroups HAVE_INITGROUPS) +check_function_exists(ioctlsocket HAVE_IOCTLSOCKET) +check_function_exists(kill HAVE_KILL) +check_function_exists(localtime_r HAVE_LOCALTIME_R) +check_function_exists(malloc HAVE_MALLOC) +check_function_exists(memmove HAVE_MEMMOVE) +check_function_exists(random HAVE_RANDOM) +check_function_exists(recvmsg HAVE_RECVMSG) +check_function_exists(sbrk HAVE_SBRK) +check_function_exists(sendmsg HAVE_SENDMSG) +check_function_exists(setregid HAVE_SETREGID) +check_function_exists(setresgid HAVE_SETRESGID) +check_function_exists(setresuid HAVE_SETRESUID) +check_function_exists(setreuid HAVE_SETREUID) +check_function_exists(setrlimit HAVE_SETRLIMIT) +check_function_exists(setsid HAVE_SETSID) +check_function_exists(setusercontent HAVE_SETUSERCONTENT) +check_function_exists(sigprocmask HAVE_SIGPROCMASK) +check_function_exists(sleep HAVE_SLEEP) +check_function_exists(snprintf HAVE_SNPRINTF) +check_function_exists(socketpair HAVE_SOCKETPAIR) +check_function_exists(srandom HAVE_SRANDOM) +check_function_exists(strftime HAVE_STRFTIME) +check_function_exists(strlcat HAVE_STRLCAT) +check_function_exists(strlcpy HAVE_STRLCPY) +check_function_exists(strptime HAVE_STRPTIME) +check_function_exists(strlcpy HAVE_STRLCPY) +check_function_exists(tzset HAVE_TZSET) +check_function_exists(usleep HAVE_USLEEP) +check_function_exists(writev HAVE_WRITEV) +check_function_exists(_beginthreadex HAVE__BEGINTHREADEX) + +set(getaddrinfo_headers) +if (HAVE_NETDB_H) + list(APPEND getaddrinfo_headers "netdb.h") +endif () +if (HAVE_WS2TCPIP_H) + list(APPEND getaddrinfo_headers "ws2tcpip.h") +endif () +check_symbol_exists(getaddrinfo "${getaddrinfo_headers}" HAVE_GETADDRINFO) + +check_function_exists(getaddrinfo HAVE_GETADDRINFO) + +function (check_type_exists type variable header default) + set(CMAKE_EXTRA_INCLUDE_FILES "${header}") + check_type_size("${type}" "${variable}") + + if (NOT HAVE_${type}) + set("${variable}" "${default}" PARENT_SCOPE) + else () + set("${variable}" "FALSE" PARENT_SCOPE) + endif () +endfunction () + +set(CMAKE_EXTRA_INCLUDE_FILES "time.h") +check_type_size(time_t SIZEOF_TIME_T) +set(CMAKE_EXTRA_INCLUDE_FILES) + +check_type_exists(gid_t gid_t "sys/types.h" int) +check_type_exists(in_addr_t in_addr_t "netinet/in.h" uint32_t) +check_type_exists(in_port_t in_port_t "netinet/in.h" uint16_t) +check_type_exists(int16_t int16_t "sys/types.h" short) +check_type_exists(int32_t int32_t "sys/types.h" int) +check_type_exists(int64_t int64_t "sys/types.h" __int64) +check_type_exists(int8_t int8_t "sys/types.h" char) +check_type_exists(pid_t pid_t "sys/types.h" int) +check_type_exists(rlim_t rlim_t "sys/resource.h" "unsigned long") +check_type_exists(ssize_t ssize_t "sys/types.h" int) +check_type_exists(uid_t uid_t "sys/types.h" int) +check_type_exists(uint16_t uint16_t "sys/types.h" "unsigned short") +check_type_exists(uint32_t uint32_t "sys/types.h" "unsigned int") +check_type_exists(uint64_t uint64_t "sys/types.h" "unsigned long long") +check_type_exists(uint8_t uint8_t "sys/types.h" "unsigned char") + +if (WIN32) + set(UB_ON_WINDOWS 1) +endif () + +if (MSVC) + set(inline __inline) + set(__func__ __FUNCTION__) +endif () + +if (NOT HAVE_VFORK) + set(vfork fork) +endif () + +# XXX: Check for broken malloc()? +# XXX: Check for broken memcmp()? +# XXX: Check for broken vfork()? +# XXX: Check for one-arg mkdir? + +check_symbol_exists(PTHREAD_PRIO_INHERIT "pthread.h" HAVE_PTHREAD_PRIO_INHERIT) +check_symbol_exists(pthread_rwlock_t "pthread.h" HAVE_PTHREAD_RWLOCK_T) +check_symbol_exists(pthread_spinlock_t "pthread.h" HAVE_PTHREAD_SPINLOCK_T) + +# openssl +set(CMAKE_REQUIRED_INCLUDES + ${OPENSSL_INCLUDE_DIR}) + +check_include_file(openssl/conf.h HAVE_OPENSSL_CONF_H) +check_include_file(openssl/engine.h HAVE_OPENSSL_ENGINE_H) +check_include_file(openssl/err.h HAVE_OPENSSL_ERR_H) +check_include_file(openssl/rand.h HAVE_OPENSSL_RAND_H) +check_include_file(openssl/ssl.h HAVE_OPENSSL_SSL_H) + +set(CMAKE_REQUIRED_INCLUDES) + +check_symbol_exists(NID_secp384r1 "openssl/evp.h" HAVE_DECL_NID_SECP384R1) +check_symbol_exists(NID_X9_62_prime256v1 "openssl/evp.h" HAVE_DECL_NID_X9_62_PRIME256V1) +check_symbol_exists(sk_SSL_COMP_pop_free "openssl/ssl.h" HAVE_DECL_SK_SSL_COMP_POP_FREE) +check_symbol_exists(SSL_COMP_get_compression_methods "openssl/ssl.h" HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS) + +set(CMAKE_REQUIRED_LIBRARIES + ${OPENSSL_LIBRARIES}) + +check_function_exists(EVP_sha1 HAVE_EVP_SHA1) +check_function_exists(EVP_sha256 HAVE_EVP_SHA256) +check_function_exists(EVP_sha512 HAVE_EVP_SHA512) +check_function_exists(FIPS_mode HAVE_FIPS_MODE) +check_function_exists(HMAC_CTX_init HAVE_HMAC_CTX_INIT) +check_function_exists(OPENSSL_config HAVE_OPENSSL_CONFIG) +check_function_exists(SHA512_Update HAVE_SHA512_UPDATE) + +set(CMAKE_REQUIRED_LIBRARIES) + +set(UNBOUND_CONFIGFILE "${CMAKE_INSTALL_PREFIX}/etc/unbound/unbound.conf" + CACHE STRING "default configuration file") +set(UNBOUND_USERNAME "unbound" + CACHE STRING "default user that unbound changes to") +set(UNBOUND_CHROOT_DIR "${CMAKE_INSTALL_PREFIX}/etc/unbound" + CACHE STRING "default directory to chroot to") +set(UNBOUND_RUN_DIR "${CMAKE_INSTALL_PREFIX}/etc/unbound" + CACHE STRING "default directory to chroot to") +set(UNBOUND_SHARE_DIR "${CMAKE_INSTALL_PREFIX}/etc/unbound" + CACHE STRING "default directory with shared data") +set(UNBOUND_PIDFILE "${CMAKE_INSTALL_PREFIX}/etc/unbound/unbound.pid" + CACHE STRING "default pathname to the pidfile") + +# Copied from configure.ac. +set(WINVER 0x0502) +set(PACKAGE_VERSION "1.4.23") +set(PACKAGE_NAME "${PROJECT_NAME}") +set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") +set(MAXSYSLOGMSGLEN 10240) + +# Make assumptions. +set(HAVE_WORKING_FORK ${HAVE_FORK}) +set(HAVE_WORKING_VFORK ${HAVE_VFORK}) diff --git a/external/unbound/contrib/README b/external/unbound/contrib/README index efbffbd0c..49dee02e5 100644 --- a/external/unbound/contrib/README +++ b/external/unbound/contrib/README @@ -25,4 +25,8 @@ distribution but may be helpful. * unbound_cache.cmd: windows script to save and load the cache. * warmup.sh: shell script to warm up DNS cache by your own MRU domains. * warmup.cmd: windows script to warm up DNS cache by your own MRU domains. +* aaaa-filter-iterator.patch: adds config option aaaa-filter: yes that + works like the BIND feature (removes AAAA records unless AAAA-only domain). + Useful for certain 'broken IPv6 default route' scenarios. + Patch from Stephane Lapie for ASAHI Net. diff --git a/external/unbound/contrib/aaaa-filter-iterator.patch b/external/unbound/contrib/aaaa-filter-iterator.patch new file mode 100644 index 000000000..8e03d7c99 --- /dev/null +++ b/external/unbound/contrib/aaaa-filter-iterator.patch @@ -0,0 +1,394 @@ +--- unbound-1.4.17.orig/doc/unbound.conf.5.in ++++ unbound-1.4.17/doc/unbound.conf.5.in +@@ -519,6 +519,13 @@ authority servers and checks if the repl + Disabled by default. + This feature is an experimental implementation of draft dns\-0x20. + .TP ++.B aaaa\-filter: \fI ++Activate behavior similar to BIND's AAAA-filter. ++This forces the dropping of all AAAA records, unless in the case of ++explicit AAAA queries, when no A records have been confirmed. ++This also causes an additional A query to be sent for each AAAA query. ++This breaks DNSSEC! ++.TP + .B private\-address: \fI + Give IPv4 of IPv6 addresses or classless subnets. These are addresses + on your private network, and are not allowed to be returned for public +--- unbound-1.4.17.orig/util/config_file.c ++++ unbound-1.4.17/util/config_file.c +@@ -160,6 +160,7 @@ config_create(void) + cfg->harden_below_nxdomain = 0; + cfg->harden_referral_path = 0; + cfg->use_caps_bits_for_id = 0; ++ cfg->aaaa_filter = 0; /* ASN: default is disabled */ + cfg->private_address = NULL; + cfg->private_domain = NULL; + cfg->unwanted_threshold = 0; +--- unbound-1.4.17.orig/iterator/iter_scrub.c ++++ unbound-1.4.17/iterator/iter_scrub.c +@@ -580,6 +580,32 @@ static int sanitize_nsec_is_overreach(st + } + + /** ++ * ASN: Lookup A records from rrset cache. ++ * @param qinfo: the question originally asked. ++ * @param env: module environment with config and cache. ++ * @param ie: iterator environment with private address data. ++ * @return 0 if no A record found, 1 if A record found. ++ */ ++static int ++asn_lookup_a_record_from_cache(struct query_info* qinfo, ++ struct module_env* env, struct iter_env* ie) ++{ ++ struct ub_packed_rrset_key* akey; ++ ++ /* get cached A records for queried name */ ++ akey = rrset_cache_lookup(env->rrset_cache, qinfo->qname, ++ qinfo->qname_len, LDNS_RR_TYPE_A, qinfo->qclass, ++ 0, *env->now, 0); ++ if(akey) { /* we had some. */ ++ log_rrset_key(VERB_ALGO, "ASN-AAAA-filter: found A record", ++ akey); ++ lock_rw_unlock(&akey->entry.lock); ++ return 1; ++ } ++ return 0; ++} ++ ++/** + * Given a response event, remove suspect RRsets from the response. + * "Suspect" rrsets are potentially poison. Note that this routine expects + * the response to be in a "normalized" state -- that is, all "irrelevant" +@@ -598,6 +625,7 @@ scrub_sanitize(ldns_buffer* pkt, struct + struct query_info* qinfo, uint8_t* zonename, struct module_env* env, + struct iter_env* ie) + { ++ int found_a_record = 0; /* ASN: do we have a A record? */ + int del_addi = 0; /* if additional-holding rrsets are deleted, we + do not trust the normalized additional-A-AAAA any more */ + struct rrset_parse* rrset, *prev; +@@ -633,6 +661,13 @@ scrub_sanitize(ldns_buffer* pkt, struct + rrset = rrset->rrset_all_next; + } + ++ /* ASN: Locate any A record we can find */ ++ if((ie->aaaa_filter) && (qinfo->qtype == LDNS_RR_TYPE_AAAA)) { ++ found_a_record = asn_lookup_a_record_from_cache(qinfo, ++ env, ie); ++ } ++ /* ASN: End of added code */ ++ + /* At this point, we brutally remove ALL rrsets that aren't + * children of the originating zone. The idea here is that, + * as far as we know, the server that we contacted is ONLY +@@ -644,6 +679,24 @@ scrub_sanitize(ldns_buffer* pkt, struct + rrset = msg->rrset_first; + while(rrset) { + ++ /* ASN: For AAAA records only... */ ++ if((ie->aaaa_filter) && (rrset->type == LDNS_RR_TYPE_AAAA)) { ++ /* ASN: If this is not a AAAA query, then remove AAAA ++ * records, no questions asked. If this IS a AAAA query ++ * then remove AAAA records if we have an A record. ++ * Otherwise, leave things be. */ ++ if((qinfo->qtype != LDNS_RR_TYPE_AAAA) || ++ (found_a_record)) { ++ remove_rrset("ASN-AAAA-filter: removing AAAA " ++ "for record", pkt, msg, prev, &rrset); ++ continue; ++ } ++ log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: " ++ "keep AAAA for", zonename, ++ LDNS_RR_TYPE_AAAA, qinfo->qclass); ++ } ++ /* ASN: End of added code */ ++ + /* remove private addresses */ + if( (rrset->type == LDNS_RR_TYPE_A || + rrset->type == LDNS_RR_TYPE_AAAA) && +--- unbound-1.4.17.orig/iterator/iterator.c ++++ unbound-1.4.17/iterator/iterator.c +@@ -1579,6 +1579,53 @@ processDSNSFind(struct module_qstate* qs + + return 0; + } ++ ++/** ++ * ASN: This event state was added as an intermediary step between ++ * QUERYTARGETS_STATE and the next step, in order to cast a subquery for the ++ * purpose of caching A records for the queried name. ++ * ++ * @param qstate: query state. ++ * @param iq: iterator query state. ++ * @param ie: iterator shared global environment. ++ * @param id: module id. ++ * @return true if the event requires more request processing immediately, ++ * false if not. This state only returns true when it is generating ++ * a SERVFAIL response because the query has hit a dead end. ++ */ ++static int ++asn_processQueryAAAA(struct module_qstate* qstate, struct iter_qstate* iq, ++ struct iter_env* ie, int id) ++{ ++ struct module_qstate* subq = NULL; ++ ++ log_assert(iq->fetch_a_for_aaaa == 0); ++ ++ /* flag the query properly in order to not loop */ ++ iq->fetch_a_for_aaaa = 1; ++ ++ /* re-throw same query, but with a different type */ ++ if(!generate_sub_request(iq->qchase.qname, ++ iq->qchase.qname_len, LDNS_RR_TYPE_A, ++ iq->qchase.qclass, qstate, id, iq, ++ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) { ++ log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: failed " ++ "preloading of A record for", ++ iq->qchase.qname, LDNS_RR_TYPE_A, ++ iq->qchase.qclass); ++ return error_response(qstate, id, LDNS_RCODE_SERVFAIL); ++ } ++ log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: " ++ "preloading records in cache for", ++ iq->qchase.qname, LDNS_RR_TYPE_A, ++ iq->qchase.qclass); ++ ++ /* set this query as waiting */ ++ qstate->ext_state[id] = module_wait_subquery; ++ /* at this point break loop */ ++ return 0; ++} ++/* ASN: End of added code */ + + /** + * This is the request event state where the request will be sent to one of +@@ -1626,6 +1673,13 @@ processQueryTargets(struct module_qstate + return error_response(qstate, id, LDNS_RCODE_SERVFAIL); + } + ++ /* ASN: If we have a AAAA query, then also query for A records */ ++ if((ie->aaaa_filter) && (iq->qchase.qtype == LDNS_RR_TYPE_AAAA) && ++ (iq->fetch_a_for_aaaa == 0)) { ++ return next_state(iq, ASN_FETCH_A_FOR_AAAA_STATE); ++ } ++ /* ASN: End of added code */ ++ + /* Make sure we have a delegation point, otherwise priming failed + * or another failure occurred */ + if(!iq->dp) { +@@ -2568,6 +2622,62 @@ processFinished(struct module_qstate* qs + return 0; + } + ++/** ++ * ASN: Do final processing on responses to A queries originated from AAAA ++ * queries. Events reach this state after the iterative resolution algorithm ++ * terminates. ++ * This is required down the road to decide whether to scrub AAAA records ++ * from the results or not. ++ * ++ * @param qstate: query state. ++ * @param id: module id. ++ * @param forq: super query state. ++ */ ++static void ++asn_processAAAAResponse(struct module_qstate* qstate, int id, ++ struct module_qstate* super) ++{ ++ struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id]; ++ struct iter_qstate* super_iq = (struct iter_qstate*)super->minfo[id]; ++ struct ub_packed_rrset_key* rrset; ++ struct delegpt_ns* dpns = NULL; ++ int error = (qstate->return_rcode != LDNS_RCODE_NOERROR); ++ ++ log_assert(super_iq->fetch_a_for_aaaa > 0); ++ ++ /* let super go to evaluation of targets after this */ ++ super_iq->state = QUERYTARGETS_STATE; ++ ++ log_query_info(VERB_ALGO, "ASN-AAAA-filter: processAAAAResponse", ++ &qstate->qinfo); ++ log_query_info(VERB_ALGO, "ASN-AAAA-filter: processAAAAResponse super", ++ &super->qinfo); ++ ++ if(super_iq->dp) ++ dpns = delegpt_find_ns(super_iq->dp, ++ qstate->qinfo.qname, qstate->qinfo.qname_len); ++ if (!dpns) { ++ /* not interested */ ++ verbose(VERB_ALGO, "ASN-AAAA-filter: subq: %s, but parent not " ++ "interested%s", (error ? "error, but" : "success"), ++ (super_iq->dp ? "anymore" : " (was reset)")); ++ log_query_info(VERB_ALGO, "ASN-AAAA-filter: superq", &super->qinfo); ++ if(super_iq->dp && error) ++ delegpt_log(VERB_ALGO, super_iq->dp); ++ return; ++ } else if (error) { ++ verbose(VERB_ALGO, "ASN-AAAA-filter: mark as failed, " ++ "and go to target query."); ++ /* see if the failure did get (parent-lame) info */ ++ if(!cache_fill_missing(super->env, ++ super_iq->qchase.qclass, super->region, ++ super_iq->dp)) ++ log_err("ASN-AAAA-filter: out of memory adding missing"); ++ dpns->resolved = 1; /* mark as failed */ ++ } ++} ++/* ASN: End of added code */ ++ + /* + * Return priming query results to interestes super querystates. + * +@@ -2587,6 +2697,9 @@ iter_inform_super(struct module_qstate* + else if(super->qinfo.qtype == LDNS_RR_TYPE_DS && ((struct iter_qstate*) + super->minfo[id])->state == DSNS_FIND_STATE) + processDSNSResponse(qstate, id, super); ++ else if (super->qinfo.qtype == LDNS_RR_TYPE_AAAA && ((struct iter_qstate*) ++ super->minfo[id])->state == ASN_FETCH_A_FOR_AAAA_STATE) ++ asn_processAAAAResponse(qstate, id, super); + else if(qstate->return_rcode != LDNS_RCODE_NOERROR) + error_supers(qstate, id, super); + else if(qstate->is_priming) +@@ -2624,6 +2737,9 @@ iter_handle(struct module_qstate* qstate + case INIT_REQUEST_3_STATE: + cont = processInitRequest3(qstate, iq, id); + break; ++ case ASN_FETCH_A_FOR_AAAA_STATE: ++ cont = asn_processQueryAAAA(qstate, iq, ie, id); ++ break; + case QUERYTARGETS_STATE: + cont = processQueryTargets(qstate, iq, ie, id); + break; +@@ -2863,6 +2979,8 @@ iter_state_to_string(enum iter_state sta + return "INIT REQUEST STATE (stage 2)"; + case INIT_REQUEST_3_STATE: + return "INIT REQUEST STATE (stage 3)"; ++ case ASN_FETCH_A_FOR_AAAA_STATE: ++ return "ASN_FETCH_A_FOR_AAAA_STATE"; + case QUERYTARGETS_STATE : + return "QUERY TARGETS STATE"; + case PRIME_RESP_STATE : +@@ -2887,6 +3005,7 @@ iter_state_is_responsestate(enum iter_st + case INIT_REQUEST_STATE : + case INIT_REQUEST_2_STATE : + case INIT_REQUEST_3_STATE : ++ case ASN_FETCH_A_FOR_AAAA_STATE : + case QUERYTARGETS_STATE : + case COLLECT_CLASS_STATE : + return 0; +--- unbound-1.4.17.orig/iterator/iter_utils.c ++++ unbound-1.4.17/iterator/iter_utils.c +@@ -128,6 +128,7 @@ iter_apply_cfg(struct iter_env* iter_env + } + iter_env->supports_ipv6 = cfg->do_ip6; + iter_env->supports_ipv4 = cfg->do_ip4; ++ iter_env->aaaa_filter = cfg->aaaa_filter; + return 1; + } + +--- unbound-1.4.17.orig/iterator/iterator.h ++++ unbound-1.4.17/iterator/iterator.h +@@ -110,6 +110,9 @@ struct iter_env { + * array of max_dependency_depth+1 size. + */ + int* target_fetch_policy; ++ ++ /** ASN: AAAA-filter flag */ ++ int aaaa_filter; + }; + + /** +@@ -135,6 +138,14 @@ enum iter_state { + INIT_REQUEST_3_STATE, + + /** ++ * This state is responsible for intercepting AAAA queries, ++ * and launch a A subquery on the same target, to populate the ++ * cache with A records, so the AAAA filter scrubbing logic can ++ * work. ++ */ ++ ASN_FETCH_A_FOR_AAAA_STATE, ++ ++ /** + * Each time a delegation point changes for a given query or a + * query times out and/or wakes up, this state is (re)visited. + * This state is reponsible for iterating through a list of +@@ -309,6 +320,13 @@ struct iter_qstate { + */ + int refetch_glue; + ++ /** ++ * ASN: This is a flag that, if true, means that this query is ++ * for fetching A records to populate cache and determine if we must ++ * return AAAA records or not. ++ */ ++ int fetch_a_for_aaaa; ++ + /** list of pending queries to authoritative servers. */ + struct outbound_list outlist; + }; +--- unbound-1.4.17.orig/util/config_file.h ++++ unbound-1.4.17/util/config_file.h +@@ -169,6 +169,8 @@ struct config_file { + int harden_referral_path; + /** use 0x20 bits in query as random ID bits */ + int use_caps_bits_for_id; ++ /** ASN: enable AAAA filter? */ ++ int aaaa_filter; + /** strip away these private addrs from answers, no DNS Rebinding */ + struct config_strlist* private_address; + /** allow domain (and subdomains) to use private address space */ +--- unbound-1.4.17.orig/util/configlexer.lex ++++ unbound-1.4.17/util/configlexer.lex +@@ -177,6 +177,7 @@ harden-below-nxdomain{COLON} { YDVAR(1, + harden-referral-path{COLON} { YDVAR(1, VAR_HARDEN_REFERRAL_PATH) } + use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) } + unwanted-reply-threshold{COLON} { YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) } ++aaaa-filter{COLON} { YDVAR(1, VAR_AAAA_FILTER) } + private-address{COLON} { YDVAR(1, VAR_PRIVATE_ADDRESS) } + private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) } + prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) } +--- unbound-1.4.17.orig/util/configparser.y ++++ unbound-1.4.17/util/configparser.y +@@ -92,6 +92,7 @@ extern struct config_parser_state* cfg_p + %token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT + %token VAR_OUTGOING_PORT_AVOID VAR_DLV_ANCHOR_FILE VAR_DLV_ANCHOR + %token VAR_NEG_CACHE_SIZE VAR_HARDEN_REFERRAL_PATH VAR_PRIVATE_ADDRESS ++%token VAR_AAAA_FILTER + %token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE + %token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE + %token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE +@@ -151,6 +152,7 @@ content_server: server_num_threads | ser + server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size | + server_harden_referral_path | server_private_address | + server_private_domain | server_extended_statistics | ++ server_aaaa_filter | + server_local_data_ptr | server_jostle_timeout | + server_unwanted_reply_threshold | server_log_time_ascii | + server_domain_insecure | server_val_sig_skew_min | +@@ -802,6 +803,15 @@ server_use_caps_for_id: VAR_USE_CAPS_FOR + free($2); + } + ; ++server_aaaa_filter: VAR_AAAA_FILTER STRING_ARG ++ { ++ OUTYY(("P(server_aaaa_filter:%s)\n", $2)); ++ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) ++ yyerror("expected yes or no."); ++ else cfg_parser->cfg->aaaa_filter = (strcmp($2, "yes")==0); ++ free($2); ++ } ++ ; + server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG + { + OUTYY(("P(server_private_address:%s)\n", $2)); +--- unbound-1.4.17.orig/pythonmod/interface.i ++++ unbound-1.4.17/pythonmod/interface.i +@@ -626,6 +626,7 @@ struct config_file { + int harden_dnssec_stripped; + int harden_referral_path; + int use_caps_bits_for_id; ++ int aaaa_filter; /* ASN */ + struct config_strlist* private_address; + struct config_strlist* private_domain; + size_t unwanted_threshold; diff --git a/external/unbound/contrib/create_unbound_ad_servers.sh b/external/unbound/contrib/create_unbound_ad_servers.sh index d31f078b3..c3b05c60c 100644 --- a/external/unbound/contrib/create_unbound_ad_servers.sh +++ b/external/unbound/contrib/create_unbound_ad_servers.sh @@ -36,4 +36,4 @@ echo "Done." # the unbound_ad_servers file: # # include: $dst_dir/unbound_ad_servers -# \ No newline at end of file +# diff --git a/external/unbound/contrib/unbound_cache.sh b/external/unbound/contrib/unbound_cache.sh index c3dd9c3a2..238d90e39 100644 --- a/external/unbound/contrib/unbound_cache.sh +++ b/external/unbound/contrib/unbound_cache.sh @@ -132,4 +132,4 @@ else done fi -exit 0 \ No newline at end of file +exit 0 diff --git a/external/unbound/contrib/unbound_cacti.tar.gz b/external/unbound/contrib/unbound_cacti.tar.gz index 36bbdecd7..cc29476c6 100644 Binary files a/external/unbound/contrib/unbound_cacti.tar.gz and b/external/unbound/contrib/unbound_cacti.tar.gz differ diff --git a/external/unbound/daemon/cachedump.c b/external/unbound/daemon/cachedump.c index cf5b1a12c..20a46ae4d 100644 --- a/external/unbound/daemon/cachedump.c +++ b/external/unbound/daemon/cachedump.c @@ -664,7 +664,7 @@ load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker) if(!go_on) return 1; /* skip this one, not all references satisfied */ - if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL)) { + if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL, flags)) { log_warn("error out of memory"); return 0; } diff --git a/external/unbound/daemon/remote.c b/external/unbound/daemon/remote.c index 100aa8be1..ff3d769d4 100644 --- a/external/unbound/daemon/remote.c +++ b/external/unbound/daemon/remote.c @@ -38,8 +38,8 @@ * * This file contains the remote control functionality for the daemon. * The remote control can be performed using either the commandline - * unbound-control tool, or a SSLv3/TLS capable web browser. - * The channel is secured using SSLv3 or TLSv1, and certificates. + * unbound-control tool, or a TLS capable web browser. + * The channel is secured using TLSv1, and certificates. * Both the server and the client(control tool) have their own keys. */ #include "config.h" @@ -154,12 +154,17 @@ daemon_remote_create(struct config_file* cfg) free(rc); return NULL; } - /* no SSLv2 because has defects */ + /* no SSLv2, SSLv3 because has defects */ if(!(SSL_CTX_set_options(rc->ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)){ log_crypto_err("could not set SSL_OP_NO_SSLv2"); daemon_remote_delete(rc); return NULL; } + if(!(SSL_CTX_set_options(rc->ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)){ + log_crypto_err("could not set SSL_OP_NO_SSLv3"); + daemon_remote_delete(rc); + return NULL; + } s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1); s_key = fname_after_chroot(cfg->server_key_file, cfg, 1); if(!s_cert || !s_key) { @@ -558,7 +563,7 @@ static char* skipwhite(char* str) { /* EOS \0 is not a space */ - while( isspace(*str) ) + while( isspace((unsigned char)*str) ) str++; return str; } @@ -849,7 +854,8 @@ print_ext(SSL* ssl, struct stats_info* s) /* RCODE */ for(i=0; isvr.ans_rcode[i] == 0) + /* Always include RCODEs 0-5 */ + if(inhibit_zero && i > LDNS_RCODE_REFUSED && s->svr.ans_rcode[i] == 0) continue; lt = sldns_lookup_by_id(sldns_rcodes, i); if(lt && lt->name) { @@ -1089,8 +1095,13 @@ do_cache_remove(struct worker* worker, uint8_t* nm, size_t nmlen, k.qname_len = nmlen; k.qtype = t; k.qclass = c; - h = query_info_hash(&k); + h = query_info_hash(&k, 0); slabhash_remove(worker->env.msg_cache, h, &k); + if(t == LDNS_RR_TYPE_AAAA) { + /* for AAAA also flush dns64 bit_cd packet */ + h = query_info_hash(&k, BIT_CD); + slabhash_remove(worker->env.msg_cache, h, &k); + } } /** flush a type */ diff --git a/external/unbound/daemon/unbound.c b/external/unbound/daemon/unbound.c index a53fe954d..5ded5a964 100644 --- a/external/unbound/daemon/unbound.c +++ b/external/unbound/daemon/unbound.c @@ -287,7 +287,7 @@ checkrlimits(struct config_file* cfg) #ifdef HAVE_SETRLIMIT } #endif - log_warn("increased limit(open files) from %u to %u", + verbose(VERB_ALGO, "increased limit(open files) from %u to %u", (unsigned)avail, (unsigned)total+10); } #else diff --git a/external/unbound/daemon/worker.c b/external/unbound/daemon/worker.c index f90676213..59ae9dfce 100644 --- a/external/unbound/daemon/worker.c +++ b/external/unbound/daemon/worker.c @@ -935,7 +935,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error, &repinfo->addr, repinfo->addrlen); goto send_reply; } - h = query_info_hash(&qinfo); + h = query_info_hash(&qinfo, sldns_buffer_read_u16_at(c->buffer, 2)); if((e=slabhash_lookup(worker->env.msg_cache, h, &qinfo, 0))) { /* answer from cache - we have acquired a readlock on it */ if(answer_from_cache(worker, &qinfo, diff --git a/external/unbound/dns64/dns64.c b/external/unbound/dns64/dns64.c index 963e727fe..eaaa26f7c 100644 --- a/external/unbound/dns64/dns64.c +++ b/external/unbound/dns64/dns64.c @@ -399,7 +399,7 @@ handle_ipv6_ptr(struct module_qstate* qstate, int id) /* Create the new sub-query. */ fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); - if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0, + if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0, 0, &subq)) return module_error; if (subq) { @@ -451,7 +451,7 @@ generate_type_A_query(struct module_qstate* qstate, int id) /* Start the sub-query. */ fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0, - &subq)) + 0, &subq)) { verbose(VERB_ALGO, "dns64: sub-query creation failed"); return module_error; @@ -520,11 +520,13 @@ handle_event_moddone(struct module_qstate* qstate, int id) * * - An internal query. * - A query for a record type other than AAAA. + * - CD FLAG was set on querier * - An AAAA query for which an error was returned. * - A successful AAAA query with an answer. */ if ( (enum dns64_qstate)qstate->minfo[id] == DNS64_INTERNAL_QUERY || qstate->qinfo.qtype != LDNS_RR_TYPE_AAAA + || (qstate->query_flags & BIT_CD) || qstate->return_rcode != LDNS_RCODE_NOERROR || (qstate->return_msg && qstate->return_msg->rep && @@ -813,7 +815,7 @@ dns64_inform_super(struct module_qstate* qstate, int id, /* Store the generated response in cache. */ if (!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep, - 0, 0, 0, NULL)) + 0, 0, 0, NULL, super->query_flags)) log_err("out of memory"); } diff --git a/external/unbound/dnstap/dnstap.c b/external/unbound/dnstap/dnstap.c index d999ffd50..b2dc053bd 100644 --- a/external/unbound/dnstap/dnstap.c +++ b/external/unbound/dnstap/dnstap.c @@ -37,6 +37,7 @@ #ifdef USE_DNSTAP #include "config.h" +#include #include #include "ldns/sbuffer.h" #include "util/config_file.h" @@ -65,6 +66,7 @@ dt_pack(const Dnstap__Dnstap *d, void **buf, size_t *sz) { ProtobufCBufferSimple sbuf; + memset(&sbuf, 0, sizeof(sbuf)); sbuf.base.append = protobuf_c_buffer_simple_append; sbuf.len = 0; sbuf.alloced = DNSTAP_INITIAL_BUF_SIZE; @@ -87,9 +89,9 @@ dt_send(const struct dt_env *env, void *buf, size_t len_buf) fstrm_res res; if (!buf) return; - res = fstrm_io_submit(env->fio, env->fq, buf, len_buf, - fstrm_free_wrapper, NULL); - if (res != FSTRM_RES_SUCCESS) + res = fstrm_iothr_submit(env->iothr, env->ioq, buf, len_buf, + fstrm_free_wrapper, NULL); + if (res != fstrm_res_success) free(buf); } @@ -119,10 +121,12 @@ dt_msg_init(const struct dt_env *env, struct dt_env * dt_create(const char *socket_path, unsigned num_workers) { - char *fio_err; + fstrm_res res; struct dt_env *env; - struct fstrm_io_options *fopt; + struct fstrm_iothr_options *fopt; struct fstrm_unix_writer_options *fuwopt; + struct fstrm_writer *fw; + struct fstrm_writer_options *fwopt; verbose(VERB_OPS, "opening dnstap socket %s", socket_path); log_assert(socket_path != NULL); @@ -132,24 +136,29 @@ dt_create(const char *socket_path, unsigned num_workers) if (!env) return NULL; + fwopt = fstrm_writer_options_init(); + res = fstrm_writer_options_add_content_type(fwopt, + DNSTAP_CONTENT_TYPE, sizeof(DNSTAP_CONTENT_TYPE) - 1); + log_assert(res == fstrm_res_success); + fuwopt = fstrm_unix_writer_options_init(); fstrm_unix_writer_options_set_socket_path(fuwopt, socket_path); - fopt = fstrm_io_options_init(); - fstrm_io_options_set_content_type(fopt, - DNSTAP_CONTENT_TYPE, - sizeof(DNSTAP_CONTENT_TYPE) - 1); - fstrm_io_options_set_num_queues(fopt, num_workers); - fstrm_io_options_set_writer(fopt, fstrm_unix_writer, fuwopt); - env->fio = fstrm_io_init(fopt, &fio_err); - if (env->fio == NULL) { - verbose(VERB_DETAIL, "dt_create: fstrm_io_init() failed: %s", - fio_err); - free(fio_err); + + fw = fstrm_unix_writer_init(fuwopt, fwopt); + log_assert(fw != NULL); + + fopt = fstrm_iothr_options_init(); + fstrm_iothr_options_set_num_input_queues(fopt, num_workers); + env->iothr = fstrm_iothr_init(fopt, &fw); + if (env->iothr == NULL) { + verbose(VERB_DETAIL, "dt_create: fstrm_iothr_init() failed"); + fstrm_writer_destroy(&fw); free(env); env = NULL; } - fstrm_io_options_destroy(&fopt); + fstrm_iothr_options_destroy(&fopt); fstrm_unix_writer_options_destroy(&fuwopt); + fstrm_writer_options_destroy(&fwopt); return env; } @@ -238,8 +247,8 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg) int dt_init(struct dt_env *env) { - env->fq = fstrm_io_get_queue(env->fio); - if (env->fq == NULL) + env->ioq = fstrm_iothr_get_input_queue(env->iothr); + if (env->ioq == NULL) return 0; return 1; } @@ -250,7 +259,7 @@ dt_delete(struct dt_env *env) if (!env) return; verbose(VERB_OPS, "closing dnstap socket"); - fstrm_io_destroy(&env->fio); + fstrm_iothr_destroy(&env->iothr); free(env->identity); free(env->version); free(env); diff --git a/external/unbound/dnstap/dnstap.h b/external/unbound/dnstap/dnstap.h index d9121df7d..0103c1c0e 100644 --- a/external/unbound/dnstap/dnstap.h +++ b/external/unbound/dnstap/dnstap.h @@ -45,11 +45,11 @@ struct fstrm_queue; struct sldns_buffer; struct dt_env { - /** dnstap I/O socket */ - struct fstrm_io *fio; + /** dnstap I/O thread */ + struct fstrm_iothr *iothr; - /** dnstap I/O queue */ - struct fstrm_queue *fq; + /** dnstap I/O thread input queue */ + struct fstrm_iothr_queue *ioq; /** dnstap "identity" field, NULL if disabled */ char *identity; diff --git a/external/unbound/dnstap/dnstap.m4 b/external/unbound/dnstap/dnstap.m4 index de63256dc..5b78b3e26 100644 --- a/external/unbound/dnstap/dnstap.m4 +++ b/external/unbound/dnstap/dnstap.m4 @@ -22,7 +22,7 @@ AC_DEFUN([dt_DNSTAP], fi AC_ARG_WITH([protobuf-c], AC_HELP_STRING([--with-protobuf-c=path], [Path where protobuf-c is installed, for dnstap]), [ - # workaround for protobuf includes at old dir before protobuf-1.0.0 + # workaround for protobuf-c includes at old dir before protobuf-c-1.0.0 if test -f $withval/include/google/protobuf-c/protobuf-c.h; then CFLAGS="$CFLAGS -I$withval/include/google" else @@ -30,7 +30,7 @@ AC_DEFUN([dt_DNSTAP], fi LDFLAGS="$LDFLAGS -L$withval/lib" ], [ - # workaround for protobuf includes at old dir before protobuf-1.0.0 + # workaround for protobuf-c includes at old dir before protobuf-c-1.0.0 if test -f /usr/include/google/protobuf-c/protobuf-c.h; then CFLAGS="$CFLAGS -I/usr/include/google" else @@ -41,12 +41,14 @@ AC_DEFUN([dt_DNSTAP], fi ]) AC_ARG_WITH([libfstrm], AC_HELP_STRING([--with-libfstrm=path], - [Path where libfstrm in installed, for dnstap]), [ + [Path where libfstrm is installed, for dnstap]), [ CFLAGS="$CFLAGS -I$withval/include" LDFLAGS="$LDFLAGS -L$withval/lib" ]) - AC_SEARCH_LIBS([fstrm_io_init], [fstrm]) - AC_SEARCH_LIBS([protobuf_c_message_pack], [protobuf-c]) + AC_SEARCH_LIBS([fstrm_iothr_init], [fstrm], [], + AC_MSG_ERROR([The fstrm library was not found. Please install fstrm!])) + AC_SEARCH_LIBS([protobuf_c_message_pack], [protobuf-c], [], + AC_MSG_ERROR([The protobuf-c library was not found. Please install protobuf-c!])) $2 else $3 diff --git a/external/unbound/dnstap/dnstap.pb-c.c b/external/unbound/dnstap/dnstap.pb-c.c deleted file mode 100644 index 51100eb56..000000000 --- a/external/unbound/dnstap/dnstap.pb-c.c +++ /dev/null @@ -1,518 +0,0 @@ -/* Generated by the protocol buffer compiler. DO NOT EDIT! */ - -/* Do not generate deprecated warnings for self */ -#ifndef PROTOBUF_C_NO_DEPRECATED -#define PROTOBUF_C_NO_DEPRECATED -#endif - -#include "dnstap/dnstap.pb-c.h" -void dnstap__dnstap__init - (Dnstap__Dnstap *message) -{ - static Dnstap__Dnstap init_value = DNSTAP__DNSTAP__INIT; - *message = init_value; -} -size_t dnstap__dnstap__get_packed_size - (const Dnstap__Dnstap *message) -{ - PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__dnstap__descriptor); - return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); -} -size_t dnstap__dnstap__pack - (const Dnstap__Dnstap *message, - uint8_t *out) -{ - PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__dnstap__descriptor); - return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); -} -size_t dnstap__dnstap__pack_to_buffer - (const Dnstap__Dnstap *message, - ProtobufCBuffer *buffer) -{ - PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__dnstap__descriptor); - return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); -} -Dnstap__Dnstap * - dnstap__dnstap__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data) -{ - return (Dnstap__Dnstap *) - protobuf_c_message_unpack (&dnstap__dnstap__descriptor, - allocator, len, data); -} -void dnstap__dnstap__free_unpacked - (Dnstap__Dnstap *message, - ProtobufCAllocator *allocator) -{ - PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__dnstap__descriptor); - protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); -} -void dnstap__message__init - (Dnstap__Message *message) -{ - static Dnstap__Message init_value = DNSTAP__MESSAGE__INIT; - *message = init_value; -} -size_t dnstap__message__get_packed_size - (const Dnstap__Message *message) -{ - PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__message__descriptor); - return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); -} -size_t dnstap__message__pack - (const Dnstap__Message *message, - uint8_t *out) -{ - PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__message__descriptor); - return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); -} -size_t dnstap__message__pack_to_buffer - (const Dnstap__Message *message, - ProtobufCBuffer *buffer) -{ - PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__message__descriptor); - return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); -} -Dnstap__Message * - dnstap__message__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data) -{ - return (Dnstap__Message *) - protobuf_c_message_unpack (&dnstap__message__descriptor, - allocator, len, data); -} -void dnstap__message__free_unpacked - (Dnstap__Message *message, - ProtobufCAllocator *allocator) -{ - PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__message__descriptor); - protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); -} -const ProtobufCEnumValue dnstap__dnstap__type__enum_values_by_number[1] = -{ - { "MESSAGE", "DNSTAP__DNSTAP__TYPE__MESSAGE", 1 }, -}; -static const ProtobufCIntRange dnstap__dnstap__type__value_ranges[] = { -{1, 0},{0, 1} -}; -const ProtobufCEnumValueIndex dnstap__dnstap__type__enum_values_by_name[1] = -{ - { "MESSAGE", 0 }, -}; -const ProtobufCEnumDescriptor dnstap__dnstap__type__descriptor = -{ - PROTOBUF_C_ENUM_DESCRIPTOR_MAGIC, - "dnstap.Dnstap.Type", - "Type", - "Dnstap__Dnstap__Type", - "dnstap", - 1, - dnstap__dnstap__type__enum_values_by_number, - 1, - dnstap__dnstap__type__enum_values_by_name, - 1, - dnstap__dnstap__type__value_ranges, - NULL,NULL,NULL,NULL /* reserved[1234] */ -}; -static const ProtobufCFieldDescriptor dnstap__dnstap__field_descriptors[5] = -{ - { - "identity", - 1, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_BYTES, - PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, has_identity), - PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, identity), - NULL, - NULL, - 0, /* packed */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "version", - 2, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_BYTES, - PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, has_version), - PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, version), - NULL, - NULL, - 0, /* packed */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "extra", - 3, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_BYTES, - PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, has_extra), - PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, extra), - NULL, - NULL, - 0, /* packed */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "message", - 14, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_MESSAGE, - 0, /* quantifier_offset */ - PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, message), - &dnstap__message__descriptor, - NULL, - 0, /* packed */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "type", - 15, - PROTOBUF_C_LABEL_REQUIRED, - PROTOBUF_C_TYPE_ENUM, - 0, /* quantifier_offset */ - PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, type), - &dnstap__dnstap__type__descriptor, - NULL, - 0, /* packed */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, -}; -static const unsigned dnstap__dnstap__field_indices_by_name[] = { - 2, /* field[2] = extra */ - 0, /* field[0] = identity */ - 3, /* field[3] = message */ - 4, /* field[4] = type */ - 1, /* field[1] = version */ -}; -static const ProtobufCIntRange dnstap__dnstap__number_ranges[2 + 1] = -{ - { 1, 0 }, - { 14, 3 }, - { 0, 5 } -}; -const ProtobufCMessageDescriptor dnstap__dnstap__descriptor = -{ - PROTOBUF_C_MESSAGE_DESCRIPTOR_MAGIC, - "dnstap.Dnstap", - "Dnstap", - "Dnstap__Dnstap", - "dnstap", - sizeof(Dnstap__Dnstap), - 5, - dnstap__dnstap__field_descriptors, - dnstap__dnstap__field_indices_by_name, - 2, dnstap__dnstap__number_ranges, - (ProtobufCMessageInit) dnstap__dnstap__init, - NULL,NULL,NULL /* reserved[123] */ -}; -const ProtobufCEnumValue dnstap__message__type__enum_values_by_number[10] = -{ - { "AUTH_QUERY", "DNSTAP__MESSAGE__TYPE__AUTH_QUERY", 1 }, - { "AUTH_RESPONSE", "DNSTAP__MESSAGE__TYPE__AUTH_RESPONSE", 2 }, - { "RESOLVER_QUERY", "DNSTAP__MESSAGE__TYPE__RESOLVER_QUERY", 3 }, - { "RESOLVER_RESPONSE", "DNSTAP__MESSAGE__TYPE__RESOLVER_RESPONSE", 4 }, - { "CLIENT_QUERY", "DNSTAP__MESSAGE__TYPE__CLIENT_QUERY", 5 }, - { "CLIENT_RESPONSE", "DNSTAP__MESSAGE__TYPE__CLIENT_RESPONSE", 6 }, - { "FORWARDER_QUERY", "DNSTAP__MESSAGE__TYPE__FORWARDER_QUERY", 7 }, - { "FORWARDER_RESPONSE", "DNSTAP__MESSAGE__TYPE__FORWARDER_RESPONSE", 8 }, - { "STUB_QUERY", "DNSTAP__MESSAGE__TYPE__STUB_QUERY", 9 }, - { "STUB_RESPONSE", "DNSTAP__MESSAGE__TYPE__STUB_RESPONSE", 10 }, -}; -static const ProtobufCIntRange dnstap__message__type__value_ranges[] = { -{1, 0},{0, 10} -}; -const ProtobufCEnumValueIndex dnstap__message__type__enum_values_by_name[10] = -{ - { "AUTH_QUERY", 0 }, - { "AUTH_RESPONSE", 1 }, - { "CLIENT_QUERY", 4 }, - { "CLIENT_RESPONSE", 5 }, - { "FORWARDER_QUERY", 6 }, - { "FORWARDER_RESPONSE", 7 }, - { "RESOLVER_QUERY", 2 }, - { "RESOLVER_RESPONSE", 3 }, - { "STUB_QUERY", 8 }, - { "STUB_RESPONSE", 9 }, -}; -const ProtobufCEnumDescriptor dnstap__message__type__descriptor = -{ - PROTOBUF_C_ENUM_DESCRIPTOR_MAGIC, - "dnstap.Message.Type", - "Type", - "Dnstap__Message__Type", - "dnstap", - 10, - dnstap__message__type__enum_values_by_number, - 10, - dnstap__message__type__enum_values_by_name, - 1, - dnstap__message__type__value_ranges, - NULL,NULL,NULL,NULL /* reserved[1234] */ -}; -static const ProtobufCFieldDescriptor dnstap__message__field_descriptors[14] = -{ - { - "type", - 1, - PROTOBUF_C_LABEL_REQUIRED, - PROTOBUF_C_TYPE_ENUM, - 0, /* quantifier_offset */ - PROTOBUF_C_OFFSETOF(Dnstap__Message, type), - &dnstap__message__type__descriptor, - NULL, - 0, /* packed */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "socket_family", - 2, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_ENUM, - PROTOBUF_C_OFFSETOF(Dnstap__Message, has_socket_family), - PROTOBUF_C_OFFSETOF(Dnstap__Message, socket_family), - &dnstap__socket_family__descriptor, - NULL, - 0, /* packed */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "socket_protocol", - 3, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_ENUM, - PROTOBUF_C_OFFSETOF(Dnstap__Message, has_socket_protocol), - PROTOBUF_C_OFFSETOF(Dnstap__Message, socket_protocol), - &dnstap__socket_protocol__descriptor, - NULL, - 0, /* packed */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "query_address", - 4, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_BYTES, - PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_address), - PROTOBUF_C_OFFSETOF(Dnstap__Message, query_address), - NULL, - NULL, - 0, /* packed */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "response_address", - 5, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_BYTES, - PROTOBUF_C_OFFSETOF(Dnstap__Message, has_response_address), - PROTOBUF_C_OFFSETOF(Dnstap__Message, response_address), - NULL, - NULL, - 0, /* packed */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "query_port", - 6, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_UINT32, - PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_port), - PROTOBUF_C_OFFSETOF(Dnstap__Message, query_port), - NULL, - NULL, - 0, /* packed */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "response_port", - 7, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_UINT32, - PROTOBUF_C_OFFSETOF(Dnstap__Message, has_response_port), - PROTOBUF_C_OFFSETOF(Dnstap__Message, response_port), - NULL, - NULL, - 0, /* packed */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "query_time_sec", - 8, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_UINT64, - PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_time_sec), - PROTOBUF_C_OFFSETOF(Dnstap__Message, query_time_sec), - NULL, - NULL, - 0, /* packed */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "query_time_nsec", - 9, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_FIXED32, - PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_time_nsec), - PROTOBUF_C_OFFSETOF(Dnstap__Message, query_time_nsec), - NULL, - NULL, - 0, /* packed */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "query_message", - 10, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_BYTES, - PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_message), - PROTOBUF_C_OFFSETOF(Dnstap__Message, query_message), - NULL, - NULL, - 0, /* packed */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "query_zone", - 11, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_BYTES, - PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_zone), - PROTOBUF_C_OFFSETOF(Dnstap__Message, query_zone), - NULL, - NULL, - 0, /* packed */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "response_time_sec", - 12, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_UINT64, - PROTOBUF_C_OFFSETOF(Dnstap__Message, has_response_time_sec), - PROTOBUF_C_OFFSETOF(Dnstap__Message, response_time_sec), - NULL, - NULL, - 0, /* packed */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "response_time_nsec", - 13, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_FIXED32, - PROTOBUF_C_OFFSETOF(Dnstap__Message, has_response_time_nsec), - PROTOBUF_C_OFFSETOF(Dnstap__Message, response_time_nsec), - NULL, - NULL, - 0, /* packed */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "response_message", - 14, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_BYTES, - PROTOBUF_C_OFFSETOF(Dnstap__Message, has_response_message), - PROTOBUF_C_OFFSETOF(Dnstap__Message, response_message), - NULL, - NULL, - 0, /* packed */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, -}; -static const unsigned dnstap__message__field_indices_by_name[] = { - 3, /* field[3] = query_address */ - 9, /* field[9] = query_message */ - 5, /* field[5] = query_port */ - 8, /* field[8] = query_time_nsec */ - 7, /* field[7] = query_time_sec */ - 10, /* field[10] = query_zone */ - 4, /* field[4] = response_address */ - 13, /* field[13] = response_message */ - 6, /* field[6] = response_port */ - 12, /* field[12] = response_time_nsec */ - 11, /* field[11] = response_time_sec */ - 1, /* field[1] = socket_family */ - 2, /* field[2] = socket_protocol */ - 0, /* field[0] = type */ -}; -static const ProtobufCIntRange dnstap__message__number_ranges[1 + 1] = -{ - { 1, 0 }, - { 0, 14 } -}; -const ProtobufCMessageDescriptor dnstap__message__descriptor = -{ - PROTOBUF_C_MESSAGE_DESCRIPTOR_MAGIC, - "dnstap.Message", - "Message", - "Dnstap__Message", - "dnstap", - sizeof(Dnstap__Message), - 14, - dnstap__message__field_descriptors, - dnstap__message__field_indices_by_name, - 1, dnstap__message__number_ranges, - (ProtobufCMessageInit) dnstap__message__init, - NULL,NULL,NULL /* reserved[123] */ -}; -const ProtobufCEnumValue dnstap__socket_family__enum_values_by_number[2] = -{ - { "INET", "DNSTAP__SOCKET_FAMILY__INET", 1 }, - { "INET6", "DNSTAP__SOCKET_FAMILY__INET6", 2 }, -}; -static const ProtobufCIntRange dnstap__socket_family__value_ranges[] = { -{1, 0},{0, 2} -}; -const ProtobufCEnumValueIndex dnstap__socket_family__enum_values_by_name[2] = -{ - { "INET", 0 }, - { "INET6", 1 }, -}; -const ProtobufCEnumDescriptor dnstap__socket_family__descriptor = -{ - PROTOBUF_C_ENUM_DESCRIPTOR_MAGIC, - "dnstap.SocketFamily", - "SocketFamily", - "Dnstap__SocketFamily", - "dnstap", - 2, - dnstap__socket_family__enum_values_by_number, - 2, - dnstap__socket_family__enum_values_by_name, - 1, - dnstap__socket_family__value_ranges, - NULL,NULL,NULL,NULL /* reserved[1234] */ -}; -const ProtobufCEnumValue dnstap__socket_protocol__enum_values_by_number[2] = -{ - { "UDP", "DNSTAP__SOCKET_PROTOCOL__UDP", 1 }, - { "TCP", "DNSTAP__SOCKET_PROTOCOL__TCP", 2 }, -}; -static const ProtobufCIntRange dnstap__socket_protocol__value_ranges[] = { -{1, 0},{0, 2} -}; -const ProtobufCEnumValueIndex dnstap__socket_protocol__enum_values_by_name[2] = -{ - { "TCP", 1 }, - { "UDP", 0 }, -}; -const ProtobufCEnumDescriptor dnstap__socket_protocol__descriptor = -{ - PROTOBUF_C_ENUM_DESCRIPTOR_MAGIC, - "dnstap.SocketProtocol", - "SocketProtocol", - "Dnstap__SocketProtocol", - "dnstap", - 2, - dnstap__socket_protocol__enum_values_by_number, - 2, - dnstap__socket_protocol__enum_values_by_name, - 1, - dnstap__socket_protocol__value_ranges, - NULL,NULL,NULL,NULL /* reserved[1234] */ -}; diff --git a/external/unbound/dnstap/dnstap.pb-c.h b/external/unbound/dnstap/dnstap.pb-c.h deleted file mode 100644 index d85e77715..000000000 --- a/external/unbound/dnstap/dnstap.pb-c.h +++ /dev/null @@ -1,158 +0,0 @@ -/* Generated by the protocol buffer compiler. DO NOT EDIT! */ - -#ifndef PROTOBUF_C_dnstap_2fdnstap_2eproto__INCLUDED -#define PROTOBUF_C_dnstap_2fdnstap_2eproto__INCLUDED - -#include - -PROTOBUF_C_BEGIN_DECLS - - -typedef struct _Dnstap__Dnstap Dnstap__Dnstap; -typedef struct _Dnstap__Message Dnstap__Message; - - -/* --- enums --- */ - -typedef enum _Dnstap__Dnstap__Type { - DNSTAP__DNSTAP__TYPE__MESSAGE = 1 -} Dnstap__Dnstap__Type; -typedef enum _Dnstap__Message__Type { - DNSTAP__MESSAGE__TYPE__AUTH_QUERY = 1, - DNSTAP__MESSAGE__TYPE__AUTH_RESPONSE = 2, - DNSTAP__MESSAGE__TYPE__RESOLVER_QUERY = 3, - DNSTAP__MESSAGE__TYPE__RESOLVER_RESPONSE = 4, - DNSTAP__MESSAGE__TYPE__CLIENT_QUERY = 5, - DNSTAP__MESSAGE__TYPE__CLIENT_RESPONSE = 6, - DNSTAP__MESSAGE__TYPE__FORWARDER_QUERY = 7, - DNSTAP__MESSAGE__TYPE__FORWARDER_RESPONSE = 8, - DNSTAP__MESSAGE__TYPE__STUB_QUERY = 9, - DNSTAP__MESSAGE__TYPE__STUB_RESPONSE = 10 -} Dnstap__Message__Type; -typedef enum _Dnstap__SocketFamily { - DNSTAP__SOCKET_FAMILY__INET = 1, - DNSTAP__SOCKET_FAMILY__INET6 = 2 -} Dnstap__SocketFamily; -typedef enum _Dnstap__SocketProtocol { - DNSTAP__SOCKET_PROTOCOL__UDP = 1, - DNSTAP__SOCKET_PROTOCOL__TCP = 2 -} Dnstap__SocketProtocol; - -/* --- messages --- */ - -struct _Dnstap__Dnstap -{ - ProtobufCMessage base; - protobuf_c_boolean has_identity; - ProtobufCBinaryData identity; - protobuf_c_boolean has_version; - ProtobufCBinaryData version; - protobuf_c_boolean has_extra; - ProtobufCBinaryData extra; - Dnstap__Dnstap__Type type; - Dnstap__Message *message; -}; -#define DNSTAP__DNSTAP__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&dnstap__dnstap__descriptor) \ - , 0,{0,NULL}, 0,{0,NULL}, 0,{0,NULL}, 0, NULL } - - -struct _Dnstap__Message -{ - ProtobufCMessage base; - Dnstap__Message__Type type; - protobuf_c_boolean has_socket_family; - Dnstap__SocketFamily socket_family; - protobuf_c_boolean has_socket_protocol; - Dnstap__SocketProtocol socket_protocol; - protobuf_c_boolean has_query_address; - ProtobufCBinaryData query_address; - protobuf_c_boolean has_response_address; - ProtobufCBinaryData response_address; - protobuf_c_boolean has_query_port; - uint32_t query_port; - protobuf_c_boolean has_response_port; - uint32_t response_port; - protobuf_c_boolean has_query_time_sec; - uint64_t query_time_sec; - protobuf_c_boolean has_query_time_nsec; - uint32_t query_time_nsec; - protobuf_c_boolean has_query_message; - ProtobufCBinaryData query_message; - protobuf_c_boolean has_query_zone; - ProtobufCBinaryData query_zone; - protobuf_c_boolean has_response_time_sec; - uint64_t response_time_sec; - protobuf_c_boolean has_response_time_nsec; - uint32_t response_time_nsec; - protobuf_c_boolean has_response_message; - ProtobufCBinaryData response_message; -}; -#define DNSTAP__MESSAGE__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&dnstap__message__descriptor) \ - , 0, 0,0, 0,0, 0,{0,NULL}, 0,{0,NULL}, 0,0, 0,0, 0,0, 0,0, 0,{0,NULL}, 0,{0,NULL}, 0,0, 0,0, 0,{0,NULL} } - - -/* Dnstap__Dnstap methods */ -void dnstap__dnstap__init - (Dnstap__Dnstap *message); -size_t dnstap__dnstap__get_packed_size - (const Dnstap__Dnstap *message); -size_t dnstap__dnstap__pack - (const Dnstap__Dnstap *message, - uint8_t *out); -size_t dnstap__dnstap__pack_to_buffer - (const Dnstap__Dnstap *message, - ProtobufCBuffer *buffer); -Dnstap__Dnstap * - dnstap__dnstap__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void dnstap__dnstap__free_unpacked - (Dnstap__Dnstap *message, - ProtobufCAllocator *allocator); -/* Dnstap__Message methods */ -void dnstap__message__init - (Dnstap__Message *message); -size_t dnstap__message__get_packed_size - (const Dnstap__Message *message); -size_t dnstap__message__pack - (const Dnstap__Message *message, - uint8_t *out); -size_t dnstap__message__pack_to_buffer - (const Dnstap__Message *message, - ProtobufCBuffer *buffer); -Dnstap__Message * - dnstap__message__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void dnstap__message__free_unpacked - (Dnstap__Message *message, - ProtobufCAllocator *allocator); -/* --- per-message closures --- */ - -typedef void (*Dnstap__Dnstap_Closure) - (const Dnstap__Dnstap *message, - void *closure_data); -typedef void (*Dnstap__Message_Closure) - (const Dnstap__Message *message, - void *closure_data); - -/* --- services --- */ - - -/* --- descriptors --- */ - -extern const ProtobufCEnumDescriptor dnstap__socket_family__descriptor; -extern const ProtobufCEnumDescriptor dnstap__socket_protocol__descriptor; -extern const ProtobufCMessageDescriptor dnstap__dnstap__descriptor; -extern const ProtobufCEnumDescriptor dnstap__dnstap__type__descriptor; -extern const ProtobufCMessageDescriptor dnstap__message__descriptor; -extern const ProtobufCEnumDescriptor dnstap__message__type__descriptor; - -PROTOBUF_C_END_DECLS - - -#endif /* PROTOBUF_dnstap_2fdnstap_2eproto__INCLUDED */ diff --git a/external/unbound/doc/Changelog b/external/unbound/doc/Changelog index d2f223530..c82ae8ade 100644 --- a/external/unbound/doc/Changelog +++ b/external/unbound/doc/Changelog @@ -1,3 +1,102 @@ +1 December 2014: Wouter + - Fix bug#632: unbound fails to build on AArch64, protects + getentropy compat code from calling sysctl if it is has been removed. + +29 November 2014: Wouter + - Add include to getentropy_linux.c, hopefully fixing debian build. + +28 November 2014: Wouter + - Fix makefile for build from noexec source tree. + +26 November 2014: Wouter + - Fix libunbound undefined symbol errors for main. + Referencing main does not seem to be possible for libunbound. + +24 November 2014: Wouter + - Fix log at high verbosity and memory allocation failure. + - iana portlist update. + +21 November 2014: Wouter + - Fix crash on multiple thread random usage on systems without + arc4random. + +20 November 2014: Wouter + - fix compat/getentropy_win.c check if CryptGenRandom works and no + immediate exit on windows. + +19 November 2014: Wouter + - Fix cdflag dns64 processing. + +18 November 2014: Wouter + - Fix that CD flag disables DNS64 processing, returning the DNSSEC + signed AAAA denial. + - iana portlist update. + +17 November 2014: Wouter + - Fix #627: SSL_CTX_load_verify_locations return code not properly + checked. + +14 November 2014: Wouter + - parser with bison 2.7 + +13 November 2014: Wouter + - Patch from Stephane Lapie for ASAHI Net that implements aaaa-filter, + added to contrib/aaaa-filter-iterator.patch. + +12 November 2014: Wouter + - trunk has 1.5.1 in development. + - Patch from Robert Edmonds to build pyunbound python module + differently. No versioninfo, with -shared and without $(LIBS). + - Patch from Robert Edmonds fixes hyphens in unbound-anchor man page. + - Removed 'increased limit open files' log message that is written + to console. It is only written on verbosity 4 and higher. + This keeps system bootup console cleaner. + - Patch from James Raftery, always print stats for rcodes 0..5. + +11 November 2014: Wouter + - iana portlist update. + - Fix bug where forward or stub addresses with same address but + different port number were not tried. + - version number in svn trunk is 1.5.0 + - tag 1.5.0rc1 + - review fix from Ralph. + +7 November 2014: Wouter + - dnstap fixes by Robert Edmonds: + dnstap/dnstap.m4: cosmetic fixes + dnstap/: Remove compiled protoc-c output files + dnstap/dnstap.m4: Error out if required libraries are not found + dnstap: Fix ProtobufCBufferSimple usage that is incorrect as of + protobuf-c 1.0.0 + dnstap/: Adapt to API changes in latest libfstrm (>= 0.2.0) + +4 November 2014: Wouter + - Add ub_ctx_add_ta_autr function to add a RFC5011 automatically + tracked trust anchor to libunbound. + - Redefine internal minievent symbols to unique symbols that helps + linking on platforms where the linker leaks names across modules. + +27 October 2014: Wouter + - Disabled use of SSLv3 in remote-control and ssl-upstream. + - iana portlist update. + +16 October 2014: Wouter + - Documented dns64 configuration in unbound.conf man page. + +13 October 2014: Wouter + - Fix #617: in ldns in unbound, lowercase WKS services. + - Fix ctype invocation casts. + +10 October 2014: Wouter + - Fix unbound-checkconf check for module config with dns64 module. + - Fix unbound capsforid fallback, it ignores TTLs in comparison. + +6 October 2014: Wouter + - Fix #614: man page variable substitution bug. +6 October 2014: Willem + - Whitespaces after $ORIGIN are not part of the origin dname (ldns). + - $TTL's value starts at position 5 (ldns). + 1 October 2014: Wouter - fix #613: Allow tab ws in var length last rdfs (in ldns str2wire). diff --git a/external/unbound/doc/ietf67-design-02.odp b/external/unbound/doc/ietf67-design-02.odp index 4be2c7d4e..8321b556f 100644 Binary files a/external/unbound/doc/ietf67-design-02.odp and b/external/unbound/doc/ietf67-design-02.odp differ diff --git a/external/unbound/doc/libunbound.3.in b/external/unbound/doc/libunbound.3.in index 14e2a059f..7f693e950 100644 --- a/external/unbound/doc/libunbound.3.in +++ b/external/unbound/doc/libunbound.3.in @@ -22,6 +22,7 @@ .B ub_ctx_resolvconf, .B ub_ctx_hosts, .B ub_ctx_add_ta, +.B ub_ctx_add_ta_autr, .B ub_ctx_add_ta_file, .B ub_ctx_trustedkeys, .B ub_ctx_debugout, @@ -73,6 +74,9 @@ \fBub_ctx_add_ta\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR ta); .LP \fIint\fR +\fBub_ctx_add_ta_autr\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname); +.LP +\fIint\fR \fBub_ctx_add_ta_file\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname); .LP \fIint\fR @@ -231,6 +235,15 @@ first resolve is done. The format is a string, similar to the zone\-file format, [domainname] [type] [rdata contents]. Both DS and DNSKEY records are accepted. .TP +.B ub_ctx_add_ta_autr +Add filename with automatically tracked trust anchor to the given context. +Pass name of a file with the managed trust anchor. You can create this +file with \fIunbound\-anchor\fR(8) for the root anchor. You can also +create it with an initial file with one line with a DNSKEY or DS record. +If the file is writable, it is updated when the trust anchor changes. +At this time it is only possible to add trusted keys before the +first resolve is done. +.TP .B ub_ctx_add_ta_file Add trust anchors to the given context. Pass name of a file with DS and DNSKEY records in zone file format. diff --git a/external/unbound/doc/unbound-anchor.8.in b/external/unbound/doc/unbound-anchor.8.in index 0c0e9e142..3d743a734 100644 --- a/external/unbound/doc/unbound-anchor.8.in +++ b/external/unbound/doc/unbound-anchor.8.in @@ -24,14 +24,14 @@ Suggested usage: .nf # in the init scripts. # provide or update the root anchor (if necessary) - unbound-anchor -a "@UNBOUND_ROOTKEY_FILE@" + unbound-anchor \-a "@UNBOUND_ROOTKEY_FILE@" # Please note usage of this root anchor is at your own risk # and under the terms of our LICENSE (see source). # # start validating resolver # the unbound.conf contains: # auto-trust-anchor-file: "@UNBOUND_ROOTKEY_FILE@" - unbound -c unbound.conf + unbound \-c unbound.conf .fi .P This tool provides builtin default contents for the root anchor and root @@ -138,7 +138,7 @@ tracking, or if an error occurred. .P You can check the exit value in this manner: .nf - unbound-anchor -a "root.key" || logger "Please check root.key" + unbound-anchor \-a "root.key" || logger "Please check root.key" .fi Or something more suitable for your operational environment. .SH "TRUST" diff --git a/external/unbound/doc/unbound.conf.5.in b/external/unbound/doc/unbound.conf.5.in index 11c77fdfe..67ff89b0c 100644 --- a/external/unbound/doc/unbound.conf.5.in +++ b/external/unbound/doc/unbound.conf.5.in @@ -1082,6 +1082,19 @@ and the word "python" has to be put in the \fBmodule\-config:\fR option .TP .B python\-script: \fI\fR The script file to load. +.SS "DNS64 Module Options" +.LP +The dns64 module must be configured in the \fBmodule\-config:\fR "dns64 +validator iterator" directive and be compiled into the daemon to be +enabled. These settings go in the \fBserver:\fR section. +.TP +.B dns64\-prefix: \fI\fR +This sets the DNS64 prefix to use to synthesize AAAA records with. +It must be /96 or shorter. The default prefix is 64:ff9b::/96. +.TP +.B dns64\-synthall: \fI\fR +Debug option, default no. If enabled, synthesize all AAAA records +despite the presence of actual AAAA records. .SH "MEMORY CONTROL EXAMPLE" In the example config settings below memory usage is reduced. Some service levels are lower, notable very large data and a high TCP load are no longer diff --git a/external/unbound/iterator/iter_delegpt.c b/external/unbound/iterator/iter_delegpt.c index 1d84280d2..b212ec077 100644 --- a/external/unbound/iterator/iter_delegpt.c +++ b/external/unbound/iterator/iter_delegpt.c @@ -147,7 +147,9 @@ delegpt_find_addr(struct delegpt* dp, struct sockaddr_storage* addr, { struct delegpt_addr* p = dp->target_list; while(p) { - if(sockaddr_cmp_addr(addr, addrlen, &p->addr, p->addrlen)==0) { + if(sockaddr_cmp_addr(addr, addrlen, &p->addr, p->addrlen)==0 + && ((struct sockaddr_in*)addr)->sin_port == + ((struct sockaddr_in*)&p->addr)->sin_port) { return p; } p = p->next_target; diff --git a/external/unbound/iterator/iter_utils.c b/external/unbound/iterator/iter_utils.c index 5d55b623e..9d0aa698f 100644 --- a/external/unbound/iterator/iter_utils.c +++ b/external/unbound/iterator/iter_utils.c @@ -425,10 +425,10 @@ dns_copy_msg(struct dns_msg* from, struct regional* region) void iter_dns_store(struct module_env* env, struct query_info* msgqinf, struct reply_info* msgrep, int is_referral, time_t leeway, int pside, - struct regional* region) + struct regional* region, uint16_t flags) { if(!dns_cache_store(env, msgqinf, msgrep, is_referral, leeway, - pside, region)) + pside, region, flags)) log_err("out of memory: cannot store data in cache"); } @@ -457,7 +457,8 @@ causes_cycle(struct module_qstate* qstate, uint8_t* name, size_t namelen, fptr_ok(fptr_whitelist_modenv_detect_cycle( qstate->env->detect_cycle)); return (*qstate->env->detect_cycle)(qstate, &qinf, - (uint16_t)(BIT_RD|BIT_CD), qstate->is_priming); + (uint16_t)(BIT_RD|BIT_CD), qstate->is_priming, + qstate->is_valrec); } void @@ -666,7 +667,7 @@ rrset_equal(struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2) k1->rk.rrset_class != k2->rk.rrset_class || query_dname_compare(k1->rk.dname, k2->rk.dname) != 0) return 0; - if(d1->ttl != d2->ttl || + if( /* do not check ttl: d1->ttl != d2->ttl || */ d1->count != d2->count || d1->rrsig_count != d2->rrsig_count || d1->trust != d2->trust || @@ -675,7 +676,7 @@ rrset_equal(struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2) t = d1->count + d1->rrsig_count; for(i=0; irr_len[i] != d2->rr_len[i] || - d1->rr_ttl[i] != d2->rr_ttl[i] || + /* no ttl check: d1->rr_ttl[i] != d2->rr_ttl[i] ||*/ memcmp(d1->rr_data[i], d2->rr_data[i], d1->rr_len[i]) != 0) return 0; @@ -689,8 +690,11 @@ reply_equal(struct reply_info* p, struct reply_info* q, struct regional* region) size_t i; if(p->flags != q->flags || p->qdcount != q->qdcount || + /* do not check TTL, this may differ */ + /* p->ttl != q->ttl || p->prefetch_ttl != q->prefetch_ttl || + */ p->security != q->security || p->an_numrrsets != q->an_numrrsets || p->ns_numrrsets != q->ns_numrrsets || diff --git a/external/unbound/iterator/iter_utils.h b/external/unbound/iterator/iter_utils.h index abdc68f3c..d7c2b68af 100644 --- a/external/unbound/iterator/iter_utils.h +++ b/external/unbound/iterator/iter_utils.h @@ -124,6 +124,7 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional); * @param pside: true if dp is parentside, thus message is 'fresh' and NS * can be prefetch-updates. * @param region: to copy modified (cache is better) rrs back to. + * @param flags: with BIT_CD for dns64 AAAA translated queries. * @return void, because we are not interested in alloc errors, * the iterator and validator can operate on the results in their * scratch space (the qstate.region) and are not dependent on the cache. @@ -132,7 +133,7 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional); */ void iter_dns_store(struct module_env* env, struct query_info* qinf, struct reply_info* rep, int is_referral, time_t leeway, int pside, - struct regional* region); + struct regional* region, uint16_t flags); /** * Select randomly with n/m probability. diff --git a/external/unbound/iterator/iterator.c b/external/unbound/iterator/iterator.c index df5f645cc..843948a2e 100644 --- a/external/unbound/iterator/iterator.c +++ b/external/unbound/iterator/iterator.c @@ -257,7 +257,7 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode) verbose(VERB_ALGO, "error response for prefetch in cache"); /* attempt to adjust the cache entry prefetch */ if(dns_cache_prefetch_adjust(qstate->env, &qstate->qinfo, - NORR_TTL)) + NORR_TTL, qstate->query_flags)) return error_response(qstate, id, rcode); /* if that fails (not in cache), fall through to store err */ } @@ -270,7 +270,8 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode) /* do not waste time trying to validate this servfail */ err.security = sec_status_indeterminate; verbose(VERB_ALGO, "store error response in message cache"); - iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL); + iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL, + qstate->query_flags); return error_response(qstate, id, rcode); } @@ -486,6 +487,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qflags = 0; /* OPCODE QUERY, no flags */ struct query_info qinf; int prime = (finalstate == PRIME_RESP_STATE)?1:0; + int valrec = 0; qinf.qname = qname; qinf.qname_len = qnamelen; qinf.qtype = qtype; @@ -499,12 +501,15 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype, * the resolution chain, which might have a validator. We are * uninterested in validating things not on the direct resolution * path. */ - if(!v) + if(!v) { qflags |= BIT_CD; + valrec = 1; + } /* attach subquery, lookup existing or make a new one */ fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); - if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, &subq)) { + if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec, + &subq)) { return 0; } *subq_ret = subq; @@ -938,7 +943,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq, } else { msg = dns_cache_lookup(qstate->env, iq->qchase.qname, iq->qchase.qname_len, iq->qchase.qtype, - iq->qchase.qclass, qstate->region, qstate->env->scratch); + iq->qchase.qclass, qstate->query_flags, + qstate->region, qstate->env->scratch); if(!msg && qstate->env->neg_cache) { /* lookup in negative cache; may result in * NOERROR/NODATA or NXDOMAIN answers that need validation */ @@ -1991,7 +1997,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, iter_dns_store(qstate->env, &iq->response->qinfo, iq->response->rep, 0, qstate->prefetch_leeway, iq->dp&&iq->dp->has_parent_side_NS, - qstate->region); + qstate->region, qstate->query_flags); /* close down outstanding requests to be discarded */ outbound_list_clear(&iq->outlist); iq->num_current_queries = 0; @@ -2029,7 +2035,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, /* Store the referral under the current query */ /* no prefetch-leeway, since its not the answer */ iter_dns_store(qstate->env, &iq->response->qinfo, - iq->response->rep, 1, 0, 0, NULL); + iq->response->rep, 1, 0, 0, NULL, 0); if(iq->store_parent_NS) iter_store_parentside_NS(qstate->env, iq->response->rep); @@ -2128,7 +2134,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, /* prefetchleeway applied because this updates answer parts */ iter_dns_store(qstate->env, &iq->response->qinfo, iq->response->rep, 1, qstate->prefetch_leeway, - iq->dp&&iq->dp->has_parent_side_NS, NULL); + iq->dp&&iq->dp->has_parent_side_NS, NULL, + qstate->query_flags); /* set the current request's qname to the new value. */ iq->qchase.qname = sname; iq->qchase.qname_len = snamelen; @@ -2209,7 +2216,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, } /** - * Return priming query results to interestes super querystates. + * Return priming query results to interested super querystates. * * Sets the delegation point and delegation message (not nonRD queries). * This is a callback from walk_supers. @@ -2640,7 +2647,7 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq, iter_dns_store(qstate->env, &qstate->qinfo, iq->response->rep, 0, qstate->prefetch_leeway, iq->dp&&iq->dp->has_parent_side_NS, - qstate->region); + qstate->region, qstate->query_flags); } } qstate->return_rcode = LDNS_RCODE_NOERROR; diff --git a/external/unbound/ldns/keyraw.c b/external/unbound/ldns/keyraw.c index fe650aada..1ff07742b 100644 --- a/external/unbound/ldns/keyraw.c +++ b/external/unbound/ldns/keyraw.c @@ -324,8 +324,10 @@ sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo) ec = EC_KEY_new_by_curve_name(NID_secp384r1); } else ec = NULL; if(!ec) return NULL; - if(keylen+1 > sizeof(buf)) - return NULL; /* sanity check */ + if(keylen+1 > sizeof(buf)) { /* sanity check */ + EC_KEY_free(ec); + return NULL; + } /* prepend the 0x02 (from docs) (or actually 0x04 from implementation * of openssl) for uncompressed data */ buf[0] = POINT_CONVERSION_UNCOMPRESSED; diff --git a/external/unbound/ldns/parseutil.c b/external/unbound/ldns/parseutil.c index 55e3a5b1a..28b344ede 100644 --- a/external/unbound/ldns/parseutil.c +++ b/external/unbound/ldns/parseutil.c @@ -288,9 +288,9 @@ sldns_parse_escape(uint8_t *ch_p, const char** str_p) { uint16_t val; - if ((*str_p)[0] && isdigit((*str_p)[0]) && - (*str_p)[1] && isdigit((*str_p)[1]) && - (*str_p)[2] && isdigit((*str_p)[2])) { + if ((*str_p)[0] && isdigit((unsigned char)(*str_p)[0]) && + (*str_p)[1] && isdigit((unsigned char)(*str_p)[1]) && + (*str_p)[2] && isdigit((unsigned char)(*str_p)[2])) { val = (uint16_t)(((*str_p)[0] - '0') * 100 + ((*str_p)[1] - '0') * 10 + @@ -303,7 +303,7 @@ sldns_parse_escape(uint8_t *ch_p, const char** str_p) *str_p += 3; return 1; - } else if ((*str_p)[0] && !isdigit((*str_p)[0])) { + } else if ((*str_p)[0] && !isdigit((unsigned char)(*str_p)[0])) { *ch_p = (uint8_t)*(*str_p)++; return 1; @@ -467,7 +467,7 @@ sldns_b32_pton_base(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz, ch = *src++; --src_sz; - } while (isspace(ch) && src_sz > 0); + } while (isspace((unsigned char)ch) && src_sz > 0); if (ch == '=' || ch == '\0') break; @@ -572,7 +572,7 @@ sldns_b32_pton_base(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz, ch = *src++; src_sz--; - } while (isspace(ch)); + } while (isspace((unsigned char)ch)); if (ch != '=') return -1; diff --git a/external/unbound/ldns/sbuffer.h b/external/unbound/ldns/sbuffer.h index 2436763d3..3ce874fc7 100644 --- a/external/unbound/ldns/sbuffer.h +++ b/external/unbound/ldns/sbuffer.h @@ -35,9 +35,9 @@ INLINE uint16_t sldns_read_uint16(const void *src) { #ifdef ALLOW_UNALIGNED_ACCESSES - return ntohs(*(uint16_t *) src); + return ntohs(*(const uint16_t *) src); #else - uint8_t *p = (uint8_t *) src; + const uint8_t *p = (const uint8_t *) src; return ((uint16_t) p[0] << 8) | (uint16_t) p[1]; #endif } @@ -46,9 +46,9 @@ INLINE uint32_t sldns_read_uint32(const void *src) { #ifdef ALLOW_UNALIGNED_ACCESSES - return ntohl(*(uint32_t *) src); + return ntohl(*(const uint32_t *) src); #else - uint8_t *p = (uint8_t *) src; + const uint8_t *p = (const uint8_t *) src; return ( ((uint32_t) p[0] << 24) | ((uint32_t) p[1] << 16) | ((uint32_t) p[2] << 8) diff --git a/external/unbound/ldns/str2wire.c b/external/unbound/ldns/str2wire.c index 0597b03bf..931e28f84 100644 --- a/external/unbound/ldns/str2wire.c +++ b/external/unbound/ldns/str2wire.c @@ -245,7 +245,7 @@ rrinternal_get_ttl(sldns_buffer* strbuf, char* token, size_t token_len, } *ttl = (uint32_t) sldns_str2period(token, &endptr); - if (strlen(token) > 0 && !isdigit((int)token[0])) { + if (strlen(token) > 0 && !isdigit((unsigned char)token[0])) { *not_there = 1; /* ah, it's not there or something */ if (default_ttl == 0) { @@ -384,11 +384,11 @@ rrinternal_spool_hex(char* token, uint8_t* rr, size_t rr_len, { char* p = token; while(*p) { - if(isspace(*p)) { + if(isspace((unsigned char)*p)) { p++; continue; } - if(!isxdigit(*p)) + if(!isxdigit((unsigned char)*p)) return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_RDATA, p-token); if(*cur_hex_data_size >= hex_data_size) @@ -827,6 +827,20 @@ const char* sldns_get_errorstr_parse(int e) return lt?lt->name:"unknown error"; } +/* Strip whitespace from the start and the end of . */ +static char * +sldns_strip_ws(char *line) +{ + char *s = line, *e; + + for (s = line; *s && isspace((unsigned char)*s); s++) + ; + for (e = strchr(s, 0); e > s+2 && isspace((unsigned char)e[-1]) && e[-2] != '\\'; e--) + ; + *e = 0; + return s; +} + int sldns_fp2wire_rr_buf(FILE* in, uint8_t* rr, size_t* len, size_t* dname_len, struct sldns_file_parse_state* parse_state) { @@ -852,28 +866,23 @@ int sldns_fp2wire_rr_buf(FILE* in, uint8_t* rr, size_t* len, size_t* dname_len, return LDNS_WIREPARSE_ERR_OK; } - if(strncmp(line, "$ORIGIN", 7) == 0 && isspace(line[7])) { - size_t off = 8; + if(strncmp(line, "$ORIGIN", 7) == 0 && isspace((unsigned char)line[7])) { int s; *len = 0; *dname_len = 0; if(!parse_state) return LDNS_WIREPARSE_ERR_OK; - while(isspace(line[off])) - off++; parse_state->origin_len = sizeof(parse_state->origin); - s = sldns_str2wire_dname_buf(line+off, parse_state->origin, - &parse_state->origin_len); + s = sldns_str2wire_dname_buf(sldns_strip_ws(line+8), + parse_state->origin, &parse_state->origin_len); if(s) parse_state->origin_len = 0; return s; - } else if(strncmp(line, "$TTL", 4) == 0 && isspace(line[4])) { + } else if(strncmp(line, "$TTL", 4) == 0 && isspace((unsigned char)line[4])) { const char* end = NULL; - size_t off = 8; *len = 0; *dname_len = 0; if(!parse_state) return LDNS_WIREPARSE_ERR_OK; - while(isspace(line[off])) - off++; - parse_state->default_ttl = sldns_str2period(line+off, &end); + parse_state->default_ttl = sldns_str2period( + sldns_strip_ws(line+5), &end); } else if (strncmp(line, "$INCLUDE", 8) == 0) { *len = 0; *dname_len = 0; @@ -1188,11 +1197,11 @@ int sldns_str2wire_hex_buf(const char* str, uint8_t* rd, size_t* len) const char* s = str; size_t dlen = 0; /* number of hexdigits parsed */ while(*s) { - if(isspace(*s)) { + if(isspace((unsigned char)*s)) { s++; continue; } - if(!isxdigit(*s)) + if(!isxdigit((unsigned char)*s)) return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_HEX, s-str); if(*len < dlen/2 + 1) return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, @@ -1392,7 +1401,7 @@ static int loc_parse_cm(char* my_str, char** endstr, uint8_t* m, uint8_t* e) { uint32_t meters = 0, cm = 0, val; - while (isblank(*my_str)) { + while (isblank((unsigned char)*my_str)) { my_str++; } meters = (uint32_t)strtol(my_str, &my_str, 10); @@ -1443,17 +1452,17 @@ int sldns_str2wire_loc_buf(const char* str, uint8_t* rd, size_t* len) char *my_str = (char *) str; - if (isdigit((int) *my_str)) { + if (isdigit((unsigned char) *my_str)) { h = (uint32_t) strtol(my_str, &my_str, 10); } else { return LDNS_WIREPARSE_ERR_INVALID_STR; } - while (isblank((int) *my_str)) { + while (isblank((unsigned char) *my_str)) { my_str++; } - if (isdigit((int) *my_str)) { + if (isdigit((unsigned char) *my_str)) { m = (uint32_t) strtol(my_str, &my_str, 10); } else if (*my_str == 'N' || *my_str == 'S') { goto north; @@ -1461,16 +1470,16 @@ int sldns_str2wire_loc_buf(const char* str, uint8_t* rd, size_t* len) return LDNS_WIREPARSE_ERR_INVALID_STR; } - while (isblank((int) *my_str)) { + while (isblank((unsigned char) *my_str)) { my_str++; } - if (isdigit((int) *my_str)) { + if (isdigit((unsigned char) *my_str)) { s = strtod(my_str, &my_str); } /* skip blanks before norterness */ - while (isblank((int) *my_str)) { + while (isblank((unsigned char) *my_str)) { my_str++; } @@ -1497,21 +1506,21 @@ north: } else { latitude = equator - latitude; } - while (isblank(*my_str)) { + while (isblank((unsigned char)*my_str)) { my_str++; } - if (isdigit((int) *my_str)) { + if (isdigit((unsigned char) *my_str)) { h = (uint32_t) strtol(my_str, &my_str, 10); } else { return LDNS_WIREPARSE_ERR_INVALID_STR; } - while (isblank((int) *my_str)) { + while (isblank((unsigned char) *my_str)) { my_str++; } - if (isdigit((int) *my_str)) { + if (isdigit((unsigned char) *my_str)) { m = (uint32_t) strtol(my_str, &my_str, 10); } else if (*my_str == 'E' || *my_str == 'W') { goto east; @@ -1519,16 +1528,16 @@ north: return LDNS_WIREPARSE_ERR_INVALID_STR; } - while (isblank(*my_str)) { + while (isblank((unsigned char)*my_str)) { my_str++; } - if (isdigit((int) *my_str)) { + if (isdigit((unsigned char) *my_str)) { s = strtod(my_str, &my_str); } /* skip blanks before easterness */ - while (isblank(*my_str)) { + while (isblank((unsigned char)*my_str)) { my_str++; } @@ -1591,6 +1600,17 @@ east: return LDNS_WIREPARSE_ERR_OK; } +static void +ldns_tolower_str(char* s) +{ + if(s) { + while(*s) { + *s = (char)tolower((unsigned char)*s); + s++; + } + } +} + int sldns_str2wire_wks_buf(const char* str, uint8_t* rd, size_t* len) { int rd_len = 1; @@ -1605,6 +1625,7 @@ int sldns_str2wire_wks_buf(const char* str, uint8_t* rd, size_t* len) return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL; while(sldns_bget_token(&strbuf, token, "\t\n ", sizeof(token)) > 0) { + ldns_tolower_str(token); if(!have_proto) { struct protoent *p = getprotobyname(token); have_proto = 1; @@ -1682,11 +1703,11 @@ int sldns_str2wire_nsap_buf(const char* str, uint8_t* rd, size_t* len) if(slen > LDNS_MAX_RDFLEN*2) return LDNS_WIREPARSE_ERR_LABEL_OVERFLOW; while(*s) { - if(isspace(*s) || *s == '.') { + if(isspace((unsigned char)*s) || *s == '.') { s++; continue; } - if(!isxdigit(*s)) + if(!isxdigit((unsigned char)*s)) return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_HEX, s-str); if(*len < dlen/2 + 1) return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, @@ -1713,11 +1734,11 @@ int sldns_str2wire_atma_buf(const char* str, uint8_t* rd, size_t* len) if(slen > LDNS_MAX_RDFLEN*2) return LDNS_WIREPARSE_ERR_LABEL_OVERFLOW; while(*s) { - if(isspace(*s) || *s == '.') { + if(isspace((unsigned char)*s) || *s == '.') { s++; continue; } - if(!isxdigit(*s)) + if(!isxdigit((unsigned char)*s)) return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_HEX, s-str); if(*len < dlen/2 + 1) return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, @@ -1820,7 +1841,8 @@ int sldns_str2wire_nsec3_salt_buf(const char* str, uint8_t* rd, size_t* len) return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL; rd[0] = (uint8_t) (salt_length_str / 2); for (i = 0; i < salt_length_str; i += 2) { - if (isxdigit((int)str[i]) && isxdigit((int)str[i+1])) { + if (isxdigit((unsigned char)str[i]) && + isxdigit((unsigned char)str[i+1])) { rd[1+i/2] = (uint8_t)(sldns_hexdigit_to_int(str[i])*16 + sldns_hexdigit_to_int(str[i+1])); } else { @@ -1907,7 +1929,7 @@ int sldns_str2wire_tag_buf(const char* str, uint8_t* rd, size_t* len) if(*len < slen+1) return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL; for (ptr = str; *ptr; ptr++) { - if(!isalnum(*ptr)) + if(!isalnum((unsigned char)*ptr)) return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_TAG, ptr-str); } rd[0] = slen; diff --git a/external/unbound/ldns/wire2str.c b/external/unbound/ldns/wire2str.c index c2a1850ef..81e173c78 100644 --- a/external/unbound/ldns/wire2str.c +++ b/external/unbound/ldns/wire2str.c @@ -722,7 +722,7 @@ static int dname_char_print(char** s, size_t* slen, uint8_t c) { if(c == '.' || c == ';' || c == '(' || c == ')' || c == '\\') return sldns_str_print(s, slen, "\\%c", c); - else if(!(isascii((int)c) && isgraph((int)c))) + else if(!(isascii((unsigned char)c) && isgraph((unsigned char)c))) return sldns_str_print(s, slen, "\\%03u", (unsigned)c); /* plain printout */ if(*slen) { @@ -1064,7 +1064,7 @@ int sldns_wire2str_aaaa_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) /** printout escaped TYPE_STR character */ static int str_char_print(char** s, size_t* sl, uint8_t c) { - if(isprint((int)c) || c == '\t') { + if(isprint((unsigned char)c) || c == '\t') { if(c == '\"' || c == '\\') return sldns_str_print(s, sl, "\\%c", c); if(*sl) { @@ -1625,7 +1625,7 @@ int sldns_wire2str_tag_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) if(*dl < 1+n) return -1; for(i=0; icfglock); + if(ctx->finalized) { + lock_basic_unlock(&ctx->cfglock); + free(dup); + return UB_AFTERFINAL; + } + if(!cfg_strlist_insert(&ctx->env->cfg->auto_trust_anchor_file_list, + dup)) { + lock_basic_unlock(&ctx->cfglock); + free(dup); + return UB_NOMEM; + } + lock_basic_unlock(&ctx->cfglock); + return UB_NOERROR; +} + int ub_ctx_trustedkeys(struct ub_ctx* ctx, const char* fname) { @@ -959,7 +979,7 @@ ub_ctx_resolvconf(struct ub_ctx* ctx, const char* fname) parse++; addr = parse; /* skip [0-9a-fA-F.:]*, i.e. IP4 and IP6 address */ - while(isxdigit(*parse) || *parse=='.' || *parse==':') + while(isxdigit((unsigned char)*parse) || *parse=='.' || *parse==':') parse++; /* terminate after the address, remove newline */ *parse = 0; @@ -1031,7 +1051,7 @@ ub_ctx_hosts(struct ub_ctx* ctx, const char* fname) /* format: spaces spaces ... */ addr = parse; /* skip addr */ - while(isxdigit(*parse) || *parse == '.' || *parse == ':') + while(isxdigit((unsigned char)*parse) || *parse == '.' || *parse == ':') parse++; if(*parse == '\n' || *parse == 0) continue; diff --git a/external/unbound/libunbound/ubsyms.def b/external/unbound/libunbound/ubsyms.def index 866c1764c..ff3d9587b 100644 --- a/external/unbound/libunbound/ubsyms.def +++ b/external/unbound/libunbound/ubsyms.def @@ -8,6 +8,7 @@ ub_ctx_set_fwd ub_ctx_resolvconf ub_ctx_hosts ub_ctx_add_ta +ub_ctx_add_ta_autr ub_ctx_add_ta_file ub_ctx_trustedkeys ub_ctx_debugout diff --git a/external/unbound/libunbound/unbound.h b/external/unbound/libunbound/unbound.h index 86bd3bfb4..fe903d0c5 100644 --- a/external/unbound/libunbound/unbound.h +++ b/external/unbound/libunbound/unbound.h @@ -356,6 +356,21 @@ int ub_ctx_add_ta(struct ub_ctx* ctx, const char* ta); */ int ub_ctx_add_ta_file(struct ub_ctx* ctx, const char* fname); +/** + * Add trust anchor to the given context that is tracked with RFC5011 + * automated trust anchor maintenance. The file is written to when the + * trust anchor is changed. + * Pass the name of a file that was output from eg. unbound-anchor, + * or you can start it by providing a trusted DNSKEY or DS record on one + * line in the file. + * @param ctx: context. + * At this time it is only possible to add trusted keys before the + * first resolve is done. + * @param fname: filename of file with trust anchor. + * @return 0 if OK, else error. + */ +int ub_ctx_add_ta_autr(struct ub_ctx* ctx, const char* fname); + /** * Add trust anchors to the given context. * Pass the name of a bind-style config file with trusted-keys{}. @@ -508,7 +523,7 @@ void ub_resolve_free(struct ub_result* result); /** * Convert error value to a human readable string. - * @param err: error code from one of the ub_val* functions. + * @param err: error code from one of the libunbound functions. * @return pointer to constant text string, zero terminated. */ const char* ub_strerror(int err); diff --git a/external/unbound/monero-config.sh b/external/unbound/monero-config.sh deleted file mode 100755 index cfdc7e04b..000000000 --- a/external/unbound/monero-config.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -./configure --prefix=${CMAKE_FIND_ROOT_PATH} --build=${GCC_PREFIX} --host=${GCC_PREFIX} --disable-shared --enable-static --sysconfdir=${CMAKE_FIND_ROOT_PATH}/etc --localstatedir=${CMAKE_FIND_ROOT_PATH}/var --sbindir=${CMAKE_FIND_ROOT_PATH}/bin --disable-gost --disable-rpath --with-libevent=no --with-libexpat=${CMAKE_FIND_ROOT_PATH} --without-pyunbound --without-pythonmodule --with-ssl=${CMAKE_FIND_ROOT_PATH} --without-pthreads --with-libunbound-only diff --git a/external/unbound/pythonmod/pythonmod_utils.c b/external/unbound/pythonmod/pythonmod_utils.c index 2f3848008..1091dcf10 100644 --- a/external/unbound/pythonmod/pythonmod_utils.c +++ b/external/unbound/pythonmod/pythonmod_utils.c @@ -67,7 +67,7 @@ int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, st } return dns_cache_store(qstate->env, qinfo, msgrep, is_referral, - qstate->prefetch_leeway, 0, NULL); + qstate->prefetch_leeway, 0, NULL, qstate->query_flags); } /* Invalidate the message associated with query_info stored in message cache */ @@ -78,7 +78,7 @@ void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qin struct reply_info *r; size_t i, j; - h = query_info_hash(qinfo); + h = query_info_hash(qinfo, qstate->query_flags); if ((e=slabhash_lookup(qstate->env->msg_cache, h, qinfo, 0))) { r = (struct reply_info*)(e->data); diff --git a/external/unbound/services/cache/dns.c b/external/unbound/services/cache/dns.c index c663b8e8b..4692744a1 100644 --- a/external/unbound/services/cache/dns.c +++ b/external/unbound/services/cache/dns.c @@ -184,7 +184,7 @@ addr_to_additional(struct ub_packed_rrset_key* rrset, struct regional* region, /** lookup message in message cache */ static struct msgreply_entry* msg_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen, - uint16_t qtype, uint16_t qclass, time_t now, int wr) + uint16_t qtype, uint16_t qclass, uint16_t flags, time_t now, int wr) { struct lruhash_entry* e; struct query_info k; @@ -194,7 +194,7 @@ msg_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen, k.qname_len = qnamelen; k.qtype = qtype; k.qclass = qclass; - h = query_info_hash(&k); + h = query_info_hash(&k, flags); e = slabhash_lookup(env->msg_cache, h, &k, wr); if(!e) return NULL; @@ -226,8 +226,10 @@ find_add_addrs(struct module_env* env, uint16_t qclass, addr_to_additional(akey, region, *msg, now); lock_rw_unlock(&akey->entry.lock); } else { + /* BIT_CD on false because delegpt lookup does + * not use dns64 translation */ neg = msg_cache_lookup(env, ns->name, ns->namelen, - LDNS_RR_TYPE_A, qclass, now, 0); + LDNS_RR_TYPE_A, qclass, 0, now, 0); if(neg) { delegpt_add_neg_msg(dp, neg); lock_rw_unlock(&neg->entry.lock); @@ -244,8 +246,10 @@ find_add_addrs(struct module_env* env, uint16_t qclass, addr_to_additional(akey, region, *msg, now); lock_rw_unlock(&akey->entry.lock); } else { + /* BIT_CD on false because delegpt lookup does + * not use dns64 translation */ neg = msg_cache_lookup(env, ns->name, ns->namelen, - LDNS_RR_TYPE_AAAA, qclass, now, 0); + LDNS_RR_TYPE_AAAA, qclass, 0, now, 0); if(neg) { delegpt_add_neg_msg(dp, neg); lock_rw_unlock(&neg->entry.lock); @@ -276,8 +280,10 @@ cache_fill_missing(struct module_env* env, uint16_t qclass, ns->name, LDNS_RR_TYPE_A, qclass); lock_rw_unlock(&akey->entry.lock); } else { + /* BIT_CD on false because delegpt lookup does + * not use dns64 translation */ neg = msg_cache_lookup(env, ns->name, ns->namelen, - LDNS_RR_TYPE_A, qclass, now, 0); + LDNS_RR_TYPE_A, qclass, 0, now, 0); if(neg) { delegpt_add_neg_msg(dp, neg); lock_rw_unlock(&neg->entry.lock); @@ -294,8 +300,10 @@ cache_fill_missing(struct module_env* env, uint16_t qclass, ns->name, LDNS_RR_TYPE_AAAA, qclass); lock_rw_unlock(&akey->entry.lock); } else { + /* BIT_CD on false because delegpt lookup does + * not use dns64 translation */ neg = msg_cache_lookup(env, ns->name, ns->namelen, - LDNS_RR_TYPE_AAAA, qclass, now, 0); + LDNS_RR_TYPE_AAAA, qclass, 0, now, 0); if(neg) { delegpt_add_neg_msg(dp, neg); lock_rw_unlock(&neg->entry.lock); @@ -626,7 +634,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region, struct dns_msg* dns_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, - struct regional* region, struct regional* scratch) + uint16_t flags, struct regional* region, struct regional* scratch) { struct lruhash_entry* e; struct query_info k; @@ -639,7 +647,7 @@ dns_cache_lookup(struct module_env* env, k.qname_len = qnamelen; k.qtype = qtype; k.qclass = qclass; - h = query_info_hash(&k); + h = query_info_hash(&k, flags); e = slabhash_lookup(env->msg_cache, h, &k, 0); if(e) { struct msgreply_entry* key = (struct msgreply_entry*)e->key; @@ -716,7 +724,7 @@ dns_cache_lookup(struct module_env* env, if(env->cfg->harden_below_nxdomain) while(!dname_is_root(k.qname)) { dname_remove_label(&k.qname, &k.qname_len); - h = query_info_hash(&k); + h = query_info_hash(&k, flags); e = slabhash_lookup(env->msg_cache, h, &k, 0); if(e) { struct reply_info* data = (struct reply_info*)e->data; @@ -741,7 +749,7 @@ dns_cache_lookup(struct module_env* env, int dns_cache_store(struct module_env* env, struct query_info* msgqinf, struct reply_info* msgrep, int is_referral, time_t leeway, int pside, - struct regional* region) + struct regional* region, uint16_t flags) { struct reply_info* rep = NULL; /* alloc, malloc properly (not in region, like msg is) */ @@ -786,7 +794,7 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf, * Not AA from cache. Not CD in cache (depends on client bit). */ rep->flags |= (BIT_RA | BIT_QR); rep->flags &= ~(BIT_AA | BIT_CD); - h = query_info_hash(&qinf); + h = query_info_hash(&qinf, flags); dns_cache_store_msg(env, &qinf, h, rep, leeway, pside, msgrep, region); /* qname is used inside query_info_entrysetup, and set to @@ -798,11 +806,11 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf, int dns_cache_prefetch_adjust(struct module_env* env, struct query_info* qinfo, - time_t adjust) + time_t adjust, uint16_t flags) { struct msgreply_entry* msg; msg = msg_cache_lookup(env, qinfo->qname, qinfo->qname_len, - qinfo->qtype, qinfo->qclass, *env->now, 1); + qinfo->qtype, qinfo->qclass, flags, *env->now, 1); if(msg) { struct reply_info* rep = (struct reply_info*)msg->entry.data; if(rep) { diff --git a/external/unbound/services/cache/dns.h b/external/unbound/services/cache/dns.h index 05a3e6296..69796c2eb 100644 --- a/external/unbound/services/cache/dns.h +++ b/external/unbound/services/cache/dns.h @@ -79,11 +79,12 @@ struct dns_msg { * can be updated to full TTL even in prefetch situations. * @param region: region to allocate better entries from cache into. * (used when is_referral is false). + * @param flags: flags with BIT_CD for AAAA queries in dns64 translation. * @return 0 on alloc error (out of memory). */ int dns_cache_store(struct module_env* env, struct query_info* qinf, struct reply_info* rep, int is_referral, time_t leeway, int pside, - struct regional* region); + struct regional* region, uint16_t flags); /** * Store message in the cache. Stores in message cache and rrset cache. @@ -132,6 +133,7 @@ struct delegpt* dns_cache_find_delegation(struct module_env* env, * @param qnamelen: length of qname. * @param qtype: query type. * @param qclass: query class. + * @param flags: flags with BIT_CD for AAAA queries in dns64 translation. * @param region: where to allocate result. * @param scratch: where to allocate temporary data. * @return new response message (alloced in region, rrsets do not have IDs). @@ -140,7 +142,7 @@ struct delegpt* dns_cache_find_delegation(struct module_env* env, */ struct dns_msg* dns_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, - struct regional* region, struct regional* scratch); + uint16_t flags, struct regional* region, struct regional* scratch); /** * find and add A and AAAA records for missing nameservers in delegpt @@ -186,9 +188,10 @@ int dns_msg_authadd(struct dns_msg* msg, struct regional* region, * @param env: module environment with caches and time. * @param qinfo: query info for the query that needs adjustment. * @param adjust: time in seconds to add to the prefetch_leeway. + * @param flags: flags with BIT_CD for AAAA queries in dns64 translation. * @return false if not in cache. true if added. */ int dns_cache_prefetch_adjust(struct module_env* env, struct query_info* qinfo, - time_t adjust); + time_t adjust, uint16_t flags); #endif /* SERVICES_CACHE_DNS_H */ diff --git a/external/unbound/services/mesh.c b/external/unbound/services/mesh.c index bc711d9b3..a69aced22 100644 --- a/external/unbound/services/mesh.c +++ b/external/unbound/services/mesh.c @@ -132,6 +132,11 @@ mesh_state_compare(const void* ap, const void* bp) if(!a->s.is_priming && b->s.is_priming) return 1; + if(a->s.is_valrec && !b->s.is_valrec) + return -1; + if(!a->s.is_valrec && b->s.is_valrec) + return 1; + if((a->s.query_flags&BIT_RD) && !(b->s.query_flags&BIT_RD)) return -1; if(!(a->s.query_flags&BIT_RD) && (b->s.query_flags&BIT_RD)) @@ -277,11 +282,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo, uint16_t qflags, struct edns_data* edns, struct comm_reply* rep, uint16_t qid) { - /* do not use CD flag from user for mesh state, we want the CD-query - * to receive validation anyway, to protect out cache contents and - * avoid bad-data in this cache that a downstream validator cannot - * remove from this cache */ - struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0); + struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0); int was_detached = 0; int was_noreply = 0; int added = 0; @@ -311,7 +312,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo, #ifdef UNBOUND_DEBUG struct rbnode_t* n; #endif - s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0); + s = mesh_state_create(mesh->env, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0); if(!s) { log_err("mesh_state_create: out of memory; SERVFAIL"); error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL, @@ -375,7 +376,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo, uint16_t qflags, struct edns_data* edns, sldns_buffer* buf, uint16_t qid, mesh_cb_func_t cb, void* cb_arg) { - struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0); + struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0); int was_detached = 0; int was_noreply = 0; int added = 0; @@ -386,7 +387,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo, #ifdef UNBOUND_DEBUG struct rbnode_t* n; #endif - s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0); + s = mesh_state_create(mesh->env, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0); if(!s) { return 0; } @@ -428,7 +429,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo, void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo, uint16_t qflags, time_t leeway) { - struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0); + struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0); #ifdef UNBOUND_DEBUG struct rbnode_t* n; #endif @@ -447,7 +448,7 @@ void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo, mesh->stats_dropped ++; return; } - s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0); + s = mesh_state_create(mesh->env, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0); if(!s) { log_err("prefetch mesh_state_create: out of memory"); return; @@ -496,7 +497,7 @@ void mesh_report_reply(struct mesh_area* mesh, struct outbound_entry* e, struct mesh_state* mesh_state_create(struct module_env* env, struct query_info* qinfo, - uint16_t qflags, int prime) + uint16_t qflags, int prime, int valrec) { struct regional* region = alloc_reg_obtain(env->alloc); struct mesh_state* mstate; @@ -533,6 +534,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo, /* remove all weird bits from qflags */ mstate->s.query_flags = (qflags & (BIT_RD|BIT_CD)); mstate->s.is_priming = prime; + mstate->s.is_valrec = valrec; mstate->s.reply = NULL; mstate->s.region = region; mstate->s.curmod = 0; @@ -679,11 +681,12 @@ void mesh_detach_subs(struct module_qstate* qstate) } int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo, - uint16_t qflags, int prime, struct module_qstate** newq) + uint16_t qflags, int prime, int valrec, struct module_qstate** newq) { /* find it, if not, create it */ struct mesh_area* mesh = qstate->env->mesh; - struct mesh_state* sub = mesh_area_find(mesh, qinfo, qflags, prime); + struct mesh_state* sub = mesh_area_find(mesh, qinfo, qflags, prime, + valrec); int was_detached; if(mesh_detect_cycle_found(qstate, sub)) { verbose(VERB_ALGO, "attach failed, cycle detected"); @@ -694,7 +697,8 @@ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo, struct rbnode_t* n; #endif /* create a new one */ - sub = mesh_state_create(qstate->env, qinfo, qflags, prime); + sub = mesh_state_create(qstate->env, qinfo, qflags, prime, + valrec); if(!sub) { log_err("mesh_attach_sub: out of memory"); return 0; @@ -941,13 +945,14 @@ void mesh_walk_supers(struct mesh_area* mesh, struct mesh_state* mstate) } struct mesh_state* mesh_area_find(struct mesh_area* mesh, - struct query_info* qinfo, uint16_t qflags, int prime) + struct query_info* qinfo, uint16_t qflags, int prime, int valrec) { struct mesh_state key; struct mesh_state* result; key.node.key = &key; key.s.is_priming = prime; + key.s.is_valrec = valrec; key.s.qinfo = *qinfo; key.s.query_flags = qflags; @@ -1107,8 +1112,9 @@ mesh_log_list(struct mesh_area* mesh) struct mesh_state* m; int num = 0; RBTREE_FOR(m, struct mesh_state*, &mesh->all) { - snprintf(buf, sizeof(buf), "%d%s%s%s%s%s mod%d %s%s", + snprintf(buf, sizeof(buf), "%d%s%s%s%s%s%s mod%d %s%s", num++, (m->s.is_priming)?"p":"", /* prime */ + (m->s.is_valrec)?"v":"", /* prime */ (m->s.query_flags&BIT_RD)?"RD":"", (m->s.query_flags&BIT_CD)?"CD":"", (m->super_set.count==0)?"d":"", /* detached */ @@ -1178,10 +1184,11 @@ mesh_get_mem(struct mesh_area* mesh) int mesh_detect_cycle(struct module_qstate* qstate, struct query_info* qinfo, - uint16_t flags, int prime) + uint16_t flags, int prime, int valrec) { struct mesh_area* mesh = qstate->env->mesh; - struct mesh_state* dep_m = mesh_area_find(mesh, qinfo, flags, prime); + struct mesh_state* dep_m = mesh_area_find(mesh, qinfo, flags, prime, + valrec); return mesh_detect_cycle_found(qstate, dep_m); } diff --git a/external/unbound/services/mesh.h b/external/unbound/services/mesh.h index fbfbbcb4a..086e39094 100644 --- a/external/unbound/services/mesh.h +++ b/external/unbound/services/mesh.h @@ -353,12 +353,13 @@ void mesh_detach_subs(struct module_qstate* qstate); * @param qinfo: what to query for (copied). * @param qflags: what flags to use (RD / CD flag or not). * @param prime: if it is a (stub) priming query. + * @param valrec: if it is a validation recursion query (lookup of key, DS). * @param newq: If the new subquery needs initialisation, it is returned, * otherwise NULL is returned. * @return: false on error, true if success (and init may be needed). */ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo, - uint16_t qflags, int prime, struct module_qstate** newq); + uint16_t qflags, int prime, int valrec, struct module_qstate** newq); /** * Query state is done, send messages to reply entries. @@ -406,10 +407,12 @@ void mesh_state_delete(struct module_qstate* qstate); * @param qinfo: query info that the mesh is for. * @param qflags: flags for query (RD / CD flag). * @param prime: if true, it is a priming query, set is_priming on mesh state. + * @param valrec: if true, it is a validation recursion query, and sets + * is_valrec on the mesh state. * @return: new mesh state or NULL on allocation error. */ struct mesh_state* mesh_state_create(struct module_env* env, - struct query_info* qinfo, uint16_t qflags, int prime); + struct query_info* qinfo, uint16_t qflags, int prime, int valrec); /** * Cleanup a mesh state and its query state. Does not do rbtree or @@ -432,10 +435,11 @@ void mesh_delete_all(struct mesh_area* mesh); * @param qinfo: what query * @param qflags: if RD / CD bit is set or not. * @param prime: if it is a priming query. + * @param valrec: if it is a validation-recursion query. * @return: mesh state or NULL if not found. */ struct mesh_state* mesh_area_find(struct mesh_area* mesh, - struct query_info* qinfo, uint16_t qflags, int prime); + struct query_info* qinfo, uint16_t qflags, int prime, int valrec); /** * Setup attachment super/sub relation between super and sub mesh state. @@ -523,13 +527,14 @@ size_t mesh_get_mem(struct mesh_area* mesh); * @param qinfo: query info for dependency. * @param flags: query flags of dependency. * @param prime: if dependency is a priming query or not. + * @param valrec: if it is a validation recursion query (lookup of key, DS). * @return true if the name,type,class exists and the given qstate mesh exists * as a dependency of that name. Thus if qstate becomes dependent on * name,type,class then a cycle is created, this is return value 1. * Too large to search is value 2 (also true). */ int mesh_detect_cycle(struct module_qstate* qstate, struct query_info* qinfo, - uint16_t flags, int prime); + uint16_t flags, int prime, int valrec); /** compare two mesh_states */ int mesh_state_compare(const void* ap, const void* bp); diff --git a/external/unbound/services/modstack.c b/external/unbound/services/modstack.c index a99030bc3..49bb2fd15 100644 --- a/external/unbound/services/modstack.c +++ b/external/unbound/services/modstack.c @@ -60,12 +60,12 @@ count_modules(const char* s) return 0; while(*s) { /* skip whitespace */ - while(*s && isspace((int)*s)) + while(*s && isspace((unsigned char)*s)) s++; - if(*s && !isspace((int)*s)) { + if(*s && !isspace((unsigned char)*s)) { /* skip identifier */ num++; - while(*s && !isspace((int)*s)) + while(*s && !isspace((unsigned char)*s)) s++; } } @@ -152,7 +152,7 @@ module_func_block* module_factory(const char** str) const char* s = *str; const char** names = module_list_avail(); fbgetfunctype* fb = module_funcs_avail(); - while(*s && isspace((int)*s)) + while(*s && isspace((unsigned char)*s)) s++; while(names[i]) { if(strncmp(names[i], s, strlen(names[i])) == 0) { diff --git a/external/unbound/services/outside_network.c b/external/unbound/services/outside_network.c index 986c53dd8..5bb52ff9f 100644 --- a/external/unbound/services/outside_network.c +++ b/external/unbound/services/outside_network.c @@ -1334,16 +1334,16 @@ serviced_perturb_qname(struct ub_randstate* rnd, uint8_t* qbuf, size_t len) while(lablen) { while(lablen--) { /* only perturb A-Z, a-z */ - if(isalpha((int)*d)) { + if(isalpha((unsigned char)*d)) { /* get a random bit */ if(bits == 0) { random = ub_random(rnd); bits = 30; } if(random & 0x1) { - *d = (uint8_t)toupper((int)*d); + *d = (uint8_t)toupper((unsigned char)*d); } else { - *d = (uint8_t)tolower((int)*d); + *d = (uint8_t)tolower((unsigned char)*d); } random >>= 1; bits--; diff --git a/external/unbound/smallapp/unbound-checkconf.c b/external/unbound/smallapp/unbound-checkconf.c index e26ae91c4..e83867f26 100644 --- a/external/unbound/smallapp/unbound-checkconf.c +++ b/external/unbound/smallapp/unbound-checkconf.c @@ -392,10 +392,17 @@ morechecks(struct config_file* cfg, const char* fname) if(strcmp(cfg->module_conf, "iterator") != 0 && strcmp(cfg->module_conf, "validator iterator") != 0 + && strcmp(cfg->module_conf, "dns64 validator iterator") != 0 + && strcmp(cfg->module_conf, "dns64 iterator") != 0 #ifdef WITH_PYTHONMODULE && strcmp(cfg->module_conf, "python iterator") != 0 && strcmp(cfg->module_conf, "python validator iterator") != 0 && strcmp(cfg->module_conf, "validator python iterator") != 0 + && strcmp(cfg->module_conf, "dns64 python iterator") != 0 + && strcmp(cfg->module_conf, "dns64 python validator iterator") != 0 + && strcmp(cfg->module_conf, "dns64 validator python iterator") != 0 + && strcmp(cfg->module_conf, "python dns64 iterator") != 0 + && strcmp(cfg->module_conf, "python dns64 validator iterator") != 0 #endif ) { fatal_exit("module conf '%s' is not known to work", diff --git a/external/unbound/smallapp/unbound-control.c b/external/unbound/smallapp/unbound-control.c index 9b78cef94..ff86184a8 100644 --- a/external/unbound/smallapp/unbound-control.c +++ b/external/unbound/smallapp/unbound-control.c @@ -149,6 +149,8 @@ setup_ctx(struct config_file* cfg) ssl_err("could not allocate SSL_CTX pointer"); if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)) ssl_err("could not set SSL_OP_NO_SSLv2"); + if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)) + ssl_err("could not set SSL_OP_NO_SSLv3"); if(!SSL_CTX_use_certificate_file(ctx,c_cert,SSL_FILETYPE_PEM) || !SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM) || !SSL_CTX_check_private_key(ctx)) diff --git a/external/unbound/smallapp/unbound-host.c b/external/unbound/smallapp/unbound-host.c index 8020ad8c8..959734109 100644 --- a/external/unbound/smallapp/unbound-host.c +++ b/external/unbound/smallapp/unbound-host.c @@ -409,7 +409,7 @@ extern int optind; /** getopt global, in case header files fail to declare it. */ extern char* optarg; -/** Main routine for checkconf */ +/** Main routine for unbound-host */ int main(int argc, char* argv[]) { int c; diff --git a/external/unbound/testcode/petal.c b/external/unbound/testcode/petal.c index 0bdcc4190..964735b39 100644 --- a/external/unbound/testcode/petal.c +++ b/external/unbound/testcode/petal.c @@ -235,6 +235,7 @@ setup_ctx(char* key, char* cert) SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method()); if(!ctx) print_exit("out of memory"); (void)SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); + (void)SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3); if(!SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM)) print_exit("cannot read cert"); if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)) diff --git a/external/unbound/testcode/readhex.c b/external/unbound/testcode/readhex.c index b986efdeb..d9aba09b7 100644 --- a/external/unbound/testcode/readhex.c +++ b/external/unbound/testcode/readhex.c @@ -49,7 +49,7 @@ static void skip_whites(const char** p) { while(1) { - while(isspace((int)**p)) + while(isspace((unsigned char)**p)) (*p)++; if(**p == ';') { /* comment, skip until newline */ @@ -71,11 +71,11 @@ void hex_to_buf(sldns_buffer* pkt, const char* hex) skip_whites(&p); if(sldns_buffer_position(pkt) == sldns_buffer_limit(pkt)) fatal_exit("hex_to_buf: buffer too small"); - if(!isalnum((int)*p)) + if(!isalnum((unsigned char)*p)) break; val = sldns_hexdigit_to_int(*p++) << 4; skip_whites(&p); - log_assert(*p && isalnum((int)*p)); + log_assert(*p && isalnum((unsigned char)*p)); val |= sldns_hexdigit_to_int(*p++); sldns_buffer_write_u8(pkt, (uint8_t)val); skip_whites(&p); diff --git a/external/unbound/testcode/replay.c b/external/unbound/testcode/replay.c index ee87b1a88..5c1197146 100644 --- a/external/unbound/testcode/replay.c +++ b/external/unbound/testcode/replay.c @@ -130,7 +130,7 @@ strip_end_white(char* p) { size_t i; for(i = strlen(p); i > 0; i--) { - if(isspace((int)p[i-1])) + if(isspace((unsigned char)p[i-1])) p[i-1] = 0; else return; } @@ -170,14 +170,14 @@ replay_range_read(char* remain, FILE* in, const char* name, while(fgets(line, MAX_LINE_LEN-1, in)) { pstate->lineno++; parse = line; - while(isspace((int)*parse)) + while(isspace((unsigned char)*parse)) parse++; if(!*parse || *parse == ';') { pos = ftello(in); continue; } if(parse_keyword(&parse, "ADDRESS")) { - while(isspace((int)*parse)) + while(isspace((unsigned char)*parse)) parse++; strip_end_white(parse); if(!extstrtoaddr(parse, &rng->addr, &rng->addrlen)) { @@ -281,7 +281,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, return NULL; } remain += skip; - while(isspace((int)*remain)) + while(isspace((unsigned char)*remain)) remain++; if(parse_keyword(&remain, "NOTHING")) { mom->evt_type = repevt_nothing; @@ -303,10 +303,10 @@ replay_moment_read(char* remain, FILE* in, const char* name, mom->evt_type = repevt_timeout; } else if(parse_keyword(&remain, "TIME_PASSES")) { mom->evt_type = repevt_time_passes; - while(isspace((int)*remain)) + while(isspace((unsigned char)*remain)) remain++; if(parse_keyword(&remain, "EVAL")) { - while(isspace((int)*remain)) + while(isspace((unsigned char)*remain)) remain++; mom->string = strdup(remain); if(!mom->string) fatal_exit("out of memory"); @@ -316,7 +316,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, } } else if(parse_keyword(&remain, "CHECK_AUTOTRUST")) { mom->evt_type = repevt_autotrust_check; - while(isspace((int)*remain)) + while(isspace((unsigned char)*remain)) remain++; if(strlen(remain)>0 && remain[strlen(remain)-1]=='\n') remain[strlen(remain)-1] = 0; @@ -333,20 +333,20 @@ replay_moment_read(char* remain, FILE* in, const char* name, } else if(parse_keyword(&remain, "INFRA_RTT")) { char *s, *m; mom->evt_type = repevt_infra_rtt; - while(isspace((int)*remain)) + while(isspace((unsigned char)*remain)) remain++; s = remain; remain = strchr(s, ' '); if(!remain) fatal_exit("expected three args for INFRA_RTT"); remain[0] = 0; remain++; - while(isspace((int)*remain)) + while(isspace((unsigned char)*remain)) remain++; m = strchr(remain, ' '); if(!m) fatal_exit("expected three args for INFRA_RTT"); m[0] = 0; m++; - while(isspace((int)*m)) + while(isspace((unsigned char)*m)) m++; if(!extstrtoaddr(s, &mom->addr, &mom->addrlen)) fatal_exit("bad infra_rtt address %s", s); @@ -361,10 +361,10 @@ replay_moment_read(char* remain, FILE* in, const char* name, free(mom); return NULL; } - while(isspace((int)*remain)) + while(isspace((unsigned char)*remain)) remain++; if(parse_keyword(&remain, "ADDRESS")) { - while(isspace((int)*remain)) + while(isspace((unsigned char)*remain)) remain++; if(strlen(remain) > 0) /* remove \n */ remain[strlen(remain)-1] = 0; @@ -408,7 +408,7 @@ static struct replay_scenario* make_scenario(char* line) { struct replay_scenario* scen; - while(isspace((int)*line)) + while(isspace((unsigned char)*line)) line++; if(!*line) { log_err("scenario: no title given"); @@ -442,7 +442,7 @@ replay_scenario_read(FILE* in, const char* name, int* lineno) parse=line; pstate.lineno++; (*lineno)++; - while(isspace((int)*parse)) + while(isspace((unsigned char)*parse)) parse++; if(!*parse) continue; /* empty line */ @@ -651,7 +651,7 @@ do_macro_variable(rbtree_t* store, char* buf, size_t remain) char sv; if(at[0]==0) return NULL; /* no variable name after $ */ - while(*at && (isalnum((int)*at) || *at=='_')) { + while(*at && (isalnum((unsigned char)*at) || *at=='_')) { at++; } /* terminator, we are working in macro_expand() buffer */ @@ -724,7 +724,7 @@ do_macro_arith(char* orig, size_t remain, char** arithstart) /* remember start pos of expr, skip the first number */ at = orig; *arithstart = at; - while(*at && (isdigit((int)*at) || *at == '.')) + while(*at && (isdigit((unsigned char)*at) || *at == '.')) at++; return at; } @@ -737,7 +737,7 @@ do_macro_arith(char* orig, size_t remain, char** arithstart) *arithstart = NULL; return do_macro_arith(orig, remain, arithstart); } - if(isdigit((int)operator)) { + if(isdigit((unsigned char)operator)) { *arithstart = orig; return at+skip; /* do nothing, but setup for later number */ } @@ -820,13 +820,13 @@ macro_expand(rbtree_t* store, struct replay_runtime* runtime, char** text) at = do_macro_recursion(store, runtime, at, remain); } else if(*at == '$') { at = do_macro_variable(store, at, remain); - } else if(isdigit((int)*at)) { + } else if(isdigit((unsigned char)*at)) { at = do_macro_arith(at, remain, &arithstart); } else { /* copy until whitespace or operator */ - if(*at && (isalnum((int)*at) || *at=='_')) { + if(*at && (isalnum((unsigned char)*at) || *at=='_')) { at++; - while(*at && (isalnum((int)*at) || *at=='_')) + while(*at && (isalnum((unsigned char)*at) || *at=='_')) at++; } else at++; } diff --git a/external/unbound/testcode/testbound.c b/external/unbound/testcode/testbound.c index b994b8f7e..daf8ddd41 100644 --- a/external/unbound/testcode/testbound.c +++ b/external/unbound/testcode/testbound.c @@ -97,7 +97,7 @@ add_opts(const char* args, int* pass_argc, char* pass_argv[]) { const char *p = args, *np; size_t len; - while(p && isspace((int)*p)) + while(p && isspace((unsigned char)*p)) p++; while(p && *p) { /* find location of next string and length of this one */ @@ -115,7 +115,7 @@ add_opts(const char* args, int* pass_argc, char* pass_argv[]) (*pass_argc)++; /* go to next option */ p = np; - while(p && isspace((int)*p)) + while(p && isspace((unsigned char)*p)) p++; } } @@ -140,7 +140,7 @@ spool_auto_file(FILE* in, int* lineno, FILE* cfg, char* id) char* parse; FILE* spool; /* find filename for new file */ - while(isspace((int)*id)) + while(isspace((unsigned char)*id)) id++; if(strlen(id)==0) fatal_exit("AUTROTRUST_FILE must have id, line %d", *lineno); @@ -158,7 +158,7 @@ spool_auto_file(FILE* in, int* lineno, FILE* cfg, char* id) while(fgets(line, MAX_LINE_LEN-1, in)) { parse = line; (*lineno)++; - while(isspace((int)*parse)) + while(isspace((unsigned char)*parse)) parse++; if(strncmp(parse, "AUTOTRUST_END", 13) == 0) { fclose(spool); @@ -197,7 +197,7 @@ setup_config(FILE* in, int* lineno, int* pass_argc, char* pass_argv[]) while(fgets(line, MAX_LINE_LEN-1, in)) { parse = line; (*lineno)++; - while(isspace((int)*parse)) + while(isspace((unsigned char)*parse)) parse++; if(!*parse || parse[0] == ';') continue; diff --git a/external/unbound/testcode/testpkts.c b/external/unbound/testcode/testpkts.c index c5aa24453..a494d9f01 100644 --- a/external/unbound/testcode/testpkts.c +++ b/external/unbound/testcode/testpkts.c @@ -81,7 +81,7 @@ static int str_keyword(char** str, const char* keyword) if(strncmp(*str, keyword, len) != 0) return 0; *str += len; - while(isspace((int)**str)) + while(isspace((unsigned char)**str)) (*str)++; return 1; } @@ -138,7 +138,7 @@ static void matchline(char* line, struct entry* e) error("expected = or : in MATCH: %s", line); parse++; e->ixfr_soa_serial = (uint32_t)strtol(parse, (char**)&parse, 10); - while(isspace((int)*parse)) + while(isspace((unsigned char)*parse)) parse++; } else { error("could not parse MATCH: '%s'", parse); @@ -226,11 +226,11 @@ static void adjustline(char* line, struct entry* e, e->copy_query = 1; } else if(str_keyword(&parse, "sleep=")) { e->sleeptime = (unsigned int) strtol(parse, (char**)&parse, 10); - while(isspace((int)*parse)) + while(isspace((unsigned char)*parse)) parse++; } else if(str_keyword(&parse, "packet_sleep=")) { pkt->packet_sleep = (unsigned int) strtol(parse, (char**)&parse, 10); - while(isspace((int)*parse)) + while(isspace((unsigned char)*parse)) parse++; } else { error("could not parse ADJUST: '%s'", parse); @@ -344,7 +344,7 @@ hex_buffer2wire(sldns_buffer *data_buffer) for (data_buf_pos = 0; data_buf_pos < sldns_buffer_position(data_buffer); data_buf_pos++) { c = (int) data_wire[data_buf_pos]; - if (state < 2 && !isascii(c)) { + if (state < 2 && !isascii((unsigned char)c)) { /*verbose("non ascii character found in file: (%d) switching to raw mode\n", c);*/ state = 2; } @@ -422,7 +422,7 @@ get_origin(const char* name, struct sldns_file_parse_state* pstate, char* parse) int status; end=parse; - while(!isspace((int)*end) && !isendline(*end)) + while(!isspace((unsigned char)*end) && !isendline(*end)) end++; store = *end; *end = 0; @@ -518,7 +518,7 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate, parse = line; pstate->lineno++; - while(isspace((int)*parse)) + while(isspace((unsigned char)*parse)) parse++; /* test for keywords */ if(isendline(*parse)) diff --git a/external/unbound/util/config_file.c b/external/unbound/util/config_file.c index 96ec2f11d..35bc6452a 100644 --- a/external/unbound/util/config_file.c +++ b/external/unbound/util/config_file.c @@ -1105,7 +1105,7 @@ cfg_count_numbers(const char* s) /* sp ::= (space|tab)* */ int num = 0; while(*s) { - while(*s && isspace((int)*s)) + while(*s && isspace((unsigned char)*s)) s++; if(!*s) /* end of string */ break; @@ -1113,9 +1113,9 @@ cfg_count_numbers(const char* s) s++; if(!*s) /* only - not allowed */ return 0; - if(!isdigit((int)*s)) /* bad character */ + if(!isdigit((unsigned char)*s)) /* bad character */ return 0; - while(*s && isdigit((int)*s)) + while(*s && isdigit((unsigned char)*s)) s++; num++; } @@ -1127,7 +1127,7 @@ static int isalldigit(const char* str, size_t l) { size_t i; for(i=0; i 1 && str[len-1] == 'B') len--; - if(len > 1 && tolower(str[len-1]) == 'g') + if(len > 1 && tolower((unsigned char)str[len-1]) == 'g') mult = 1024*1024*1024; - else if(len > 1 && tolower(str[len-1]) == 'm') + else if(len > 1 && tolower((unsigned char)str[len-1]) == 'm') mult = 1024*1024; - else if(len > 1 && tolower(str[len-1]) == 'k') + else if(len > 1 && tolower((unsigned char)str[len-1]) == 'k') mult = 1024; - else if(len > 0 && isdigit(str[len-1])) + else if(len > 0 && isdigit((unsigned char)str[len-1])) mult = 1; else { log_err("unknown size specifier: '%s'", str); @@ -1322,7 +1322,7 @@ cfg_parse_local_zone(struct config_file* cfg, const char* val) /* parse it as: [zone_name] [between stuff] [zone_type] */ name = val; - while(*name && isspace(*name)) + while(*name && isspace((unsigned char)*name)) name++; if(!*name) { log_err("syntax error: too short: %s", val); @@ -1341,7 +1341,7 @@ cfg_parse_local_zone(struct config_file* cfg, const char* val) buf[name_end-name] = '\0'; type = last_space_pos(name_end); - while(type && *type && isspace(*type)) + while(type && *type && isspace((unsigned char)*type)) type++; if(!type || !*type) { log_err("syntax error: expected zone type: %s", val); @@ -1368,7 +1368,7 @@ char* cfg_ptr_reverse(char* str) /* parse it as: [IP] [between stuff] [name] */ ip = str; - while(*ip && isspace(*ip)) + while(*ip && isspace((unsigned char)*ip)) ip++; if(!*ip) { log_err("syntax error: too short: %s", str); @@ -1423,7 +1423,7 @@ char* cfg_ptr_reverse(char* str) } /* printed the reverse address, now the between goop and name on end */ - while(*ip_end && isspace(*ip_end)) + while(*ip_end && isspace((unsigned char)*ip_end)) ip_end++; if(name>ip_end) { snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%.*s", diff --git a/external/unbound/util/configlexer.c b/external/unbound/util/configlexer.c index f1336a256..4a0380e6a 100644 --- a/external/unbound/util/configlexer.c +++ b/external/unbound/util/configlexer.c @@ -10,7 +10,7 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 36 +#define YY_FLEX_SUBMINOR_VERSION 37 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -3787,7 +3787,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len YY_BUFFER_STATE b; char *buf; yy_size_t n; - int i; + yy_size_t i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; diff --git a/external/unbound/util/configparser.c b/external/unbound/util/configparser.c index 089d675d9..6285e3f6f 100644 --- a/external/unbound/util/configparser.c +++ b/external/unbound/util/configparser.c @@ -1,4 +1,4 @@ -/* A Bison parser, made by GNU Bison 2.6.1. */ +/* A Bison parser, made by GNU Bison 2.7. */ /* Bison implementation for Yacc-like parsers in C @@ -44,7 +44,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.6.1" +#define YYBISON_VERSION "2.7" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -62,7 +62,7 @@ /* Copy the first part of user declarations. */ -/* Line 336 of yacc.c */ +/* Line 371 of yacc.c */ #line 38 "./util/configparser.y" #include "config.h" @@ -90,7 +90,7 @@ extern struct config_parser_state* cfg_parser; #endif -/* Line 336 of yacc.c */ +/* Line 371 of yacc.c */ #line 95 "util/configparser.c" # ifndef YY_NULL @@ -111,8 +111,8 @@ extern struct config_parser_state* cfg_parser; /* In a future release of Bison, this section will be replaced by #include "configparser.h". */ -#ifndef YY_UTIL_CONFIGPARSER_H -# define YY_UTIL_CONFIGPARSER_H +#ifndef YY_YY_UTIL_CONFIGPARSER_H_INCLUDED +# define YY_YY_UTIL_CONFIGPARSER_H_INCLUDED /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -428,13 +428,13 @@ extern int yydebug; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE { -/* Line 350 of yacc.c */ +/* Line 387 of yacc.c */ #line 64 "./util/configparser.y" char* str; -/* Line 350 of yacc.c */ +/* Line 387 of yacc.c */ #line 439 "util/configparser.c" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 @@ -458,11 +458,11 @@ int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ -#endif /* !YY_UTIL_CONFIGPARSER_H */ +#endif /* !YY_YY_UTIL_CONFIGPARSER_H_INCLUDED */ /* Copy the second part of user declarations. */ -/* Line 353 of yacc.c */ +/* Line 390 of yacc.c */ #line 467 "util/configparser.c" #ifdef short @@ -516,24 +516,24 @@ typedef short int yytype_int16; # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ -# define YY_(msgid) msgid +# define YY_(Msgid) Msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) +# define YYUSE(E) ((void) (E)) #else -# define YYUSE(e) /* empty */ +# define YYUSE(E) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint -# define YYID(n) (n) +# define YYID(N) (N) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) @@ -1289,10 +1289,10 @@ static const yytype_uint16 yytable[] = 422, 423, 424, 425, 426, 427, 428 }; -#define yypact_value_is_default(yystate) \ - ((yystate) == (-123)) +#define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-123))) -#define yytable_value_is_error(yytable_value) \ +#define yytable_value_is_error(Yytable_value) \ YYID (0) static const yytype_int16 yycheck[] = @@ -1420,47 +1420,18 @@ do \ } \ while (YYID (0)) - +/* Error token number */ #define YYTERROR 1 #define YYERRCODE 256 -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) - - /* This macro is provided for backward compatibility. */ - #ifndef YY_LOCATION_PRINT # define YY_LOCATION_PRINT(File, Loc) ((void) 0) #endif /* YYLEX -- calling `yylex' with the right arguments. */ - #ifdef YYLEX_PARAM # define YYLEX yylex (YYLEX_PARAM) #else @@ -1523,7 +1494,7 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep) switch (yytype) { default: - break; + break; } } @@ -1765,7 +1736,6 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, { YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ const char *yyformat = YY_NULL; @@ -1828,11 +1798,13 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, break; } yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; + { + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } } } } @@ -1852,10 +1824,12 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, # undef YYCASE_ } - yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } if (*yymsg_alloc < yysize) { @@ -1915,7 +1889,7 @@ yydestruct (yymsg, yytype, yyvaluep) { default: - break; + break; } } @@ -1925,8 +1899,17 @@ yydestruct (yymsg, yytype, yyvaluep) /* The lookahead symbol. */ int yychar; + +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + /* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; +YYSTYPE yylval YY_INITIAL_VALUE(yyval_default); /* Number of syntax errors so far. */ int yynerrs; @@ -1984,7 +1967,7 @@ yyparse () int yyn; int yyresult; /* Lookahead token as an internal (translated) token number. */ - int yytoken; + int yytoken = 0; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; @@ -2002,9 +1985,8 @@ yyparse () Keep to zero when no symbol should be popped. */ int yylen = 0; - yytoken = 0; - yyss = yyssa; - yyvs = yyvsa; + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); @@ -2013,13 +1995,6 @@ yyparse () yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - yyssp = yyss; - yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. @@ -2160,7 +2135,9 @@ yybackup: yychar = YYEMPTY; yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END goto yynewstate; @@ -2197,7 +2174,7 @@ yyreduce: switch (yyn) { case 10: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 129 "./util/configparser.y" { OUTYY(("\nP(server:)\n")); @@ -2205,7 +2182,7 @@ yyreduce: break; case 117: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 180 "./util/configparser.y" { struct config_stub* s; @@ -2220,7 +2197,7 @@ yyreduce: break; case 125: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 196 "./util/configparser.y" { struct config_stub* s; @@ -2235,7 +2212,7 @@ yyreduce: break; case 132: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 212 "./util/configparser.y" { OUTYY(("P(server_num_threads:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2247,7 +2224,7 @@ yyreduce: break; case 133: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 221 "./util/configparser.y" { OUTYY(("P(server_verbosity:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2259,7 +2236,7 @@ yyreduce: break; case 134: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 230 "./util/configparser.y" { OUTYY(("P(server_statistics_interval:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2273,7 +2250,7 @@ yyreduce: break; case 135: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 241 "./util/configparser.y" { OUTYY(("P(server_statistics_cumulative:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2285,7 +2262,7 @@ yyreduce: break; case 136: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 250 "./util/configparser.y" { OUTYY(("P(server_extended_statistics:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2297,7 +2274,7 @@ yyreduce: break; case 137: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 259 "./util/configparser.y" { OUTYY(("P(server_port:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2309,7 +2286,7 @@ yyreduce: break; case 138: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 268 "./util/configparser.y" { OUTYY(("P(server_interface:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2325,7 +2302,7 @@ yyreduce: break; case 139: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 281 "./util/configparser.y" { OUTYY(("P(server_outgoing_interface:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2343,7 +2320,7 @@ yyreduce: break; case 140: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 296 "./util/configparser.y" { OUTYY(("P(server_outgoing_range:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2355,7 +2332,7 @@ yyreduce: break; case 141: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 305 "./util/configparser.y" { OUTYY(("P(server_outgoing_port_permit:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2367,7 +2344,7 @@ yyreduce: break; case 142: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 314 "./util/configparser.y" { OUTYY(("P(server_outgoing_port_avoid:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2379,7 +2356,7 @@ yyreduce: break; case 143: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 323 "./util/configparser.y" { OUTYY(("P(server_outgoing_num_tcp:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2391,7 +2368,7 @@ yyreduce: break; case 144: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 332 "./util/configparser.y" { OUTYY(("P(server_incoming_num_tcp:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2403,7 +2380,7 @@ yyreduce: break; case 145: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 341 "./util/configparser.y" { OUTYY(("P(server_interface_automatic:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2415,7 +2392,7 @@ yyreduce: break; case 146: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 350 "./util/configparser.y" { OUTYY(("P(server_do_ip4:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2427,7 +2404,7 @@ yyreduce: break; case 147: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 359 "./util/configparser.y" { OUTYY(("P(server_do_ip6:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2439,7 +2416,7 @@ yyreduce: break; case 148: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 368 "./util/configparser.y" { OUTYY(("P(server_do_udp:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2451,7 +2428,7 @@ yyreduce: break; case 149: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 377 "./util/configparser.y" { OUTYY(("P(server_do_tcp:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2463,7 +2440,7 @@ yyreduce: break; case 150: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 386 "./util/configparser.y" { OUTYY(("P(server_tcp_upstream:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2475,7 +2452,7 @@ yyreduce: break; case 151: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 395 "./util/configparser.y" { OUTYY(("P(server_ssl_upstream:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2487,7 +2464,7 @@ yyreduce: break; case 152: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 404 "./util/configparser.y" { OUTYY(("P(server_ssl_service_key:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2497,7 +2474,7 @@ yyreduce: break; case 153: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 411 "./util/configparser.y" { OUTYY(("P(server_ssl_service_pem:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2507,7 +2484,7 @@ yyreduce: break; case 154: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 418 "./util/configparser.y" { OUTYY(("P(server_ssl_port:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2519,7 +2496,7 @@ yyreduce: break; case 155: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 427 "./util/configparser.y" { OUTYY(("P(server_do_daemonize:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2531,7 +2508,7 @@ yyreduce: break; case 156: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 436 "./util/configparser.y" { OUTYY(("P(server_use_syslog:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2548,7 +2525,7 @@ yyreduce: break; case 157: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 450 "./util/configparser.y" { OUTYY(("P(server_log_time_ascii:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2560,7 +2537,7 @@ yyreduce: break; case 158: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 459 "./util/configparser.y" { OUTYY(("P(server_log_queries:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2572,7 +2549,7 @@ yyreduce: break; case 159: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 468 "./util/configparser.y" { OUTYY(("P(server_chroot:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2582,7 +2559,7 @@ yyreduce: break; case 160: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 475 "./util/configparser.y" { OUTYY(("P(server_username:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2592,7 +2569,7 @@ yyreduce: break; case 161: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 482 "./util/configparser.y" { OUTYY(("P(server_directory:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2602,7 +2579,7 @@ yyreduce: break; case 162: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 489 "./util/configparser.y" { OUTYY(("P(server_logfile:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2613,7 +2590,7 @@ yyreduce: break; case 163: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 497 "./util/configparser.y" { OUTYY(("P(server_pidfile:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2623,7 +2600,7 @@ yyreduce: break; case 164: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 504 "./util/configparser.y" { OUTYY(("P(server_root_hints:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2633,7 +2610,7 @@ yyreduce: break; case 165: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 511 "./util/configparser.y" { OUTYY(("P(server_dlv_anchor_file:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2643,7 +2620,7 @@ yyreduce: break; case 166: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 518 "./util/configparser.y" { OUTYY(("P(server_dlv_anchor:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2653,7 +2630,7 @@ yyreduce: break; case 167: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 525 "./util/configparser.y" { OUTYY(("P(server_auto_trust_anchor_file:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2664,7 +2641,7 @@ yyreduce: break; case 168: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 533 "./util/configparser.y" { OUTYY(("P(server_trust_anchor_file:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2675,7 +2652,7 @@ yyreduce: break; case 169: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 541 "./util/configparser.y" { OUTYY(("P(server_trusted_keys_file:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2686,7 +2663,7 @@ yyreduce: break; case 170: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 549 "./util/configparser.y" { OUTYY(("P(server_trust_anchor:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2696,7 +2673,7 @@ yyreduce: break; case 171: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 556 "./util/configparser.y" { OUTYY(("P(server_domain_insecure:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2706,7 +2683,7 @@ yyreduce: break; case 172: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 563 "./util/configparser.y" { OUTYY(("P(server_hide_identity:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2718,7 +2695,7 @@ yyreduce: break; case 173: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 572 "./util/configparser.y" { OUTYY(("P(server_hide_version:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2730,7 +2707,7 @@ yyreduce: break; case 174: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 581 "./util/configparser.y" { OUTYY(("P(server_identity:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2740,7 +2717,7 @@ yyreduce: break; case 175: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 588 "./util/configparser.y" { OUTYY(("P(server_version:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2750,7 +2727,7 @@ yyreduce: break; case 176: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 595 "./util/configparser.y" { OUTYY(("P(server_so_rcvbuf:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2761,7 +2738,7 @@ yyreduce: break; case 177: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 603 "./util/configparser.y" { OUTYY(("P(server_so_sndbuf:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2772,7 +2749,7 @@ yyreduce: break; case 178: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 611 "./util/configparser.y" { OUTYY(("P(server_so_reuseport:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2785,7 +2762,7 @@ yyreduce: break; case 179: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 621 "./util/configparser.y" { OUTYY(("P(server_edns_buffer_size:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2801,7 +2778,7 @@ yyreduce: break; case 180: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 634 "./util/configparser.y" { OUTYY(("P(server_msg_buffer_size:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2815,7 +2792,7 @@ yyreduce: break; case 181: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 645 "./util/configparser.y" { OUTYY(("P(server_msg_cache_size:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2826,7 +2803,7 @@ yyreduce: break; case 182: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 653 "./util/configparser.y" { OUTYY(("P(server_msg_cache_slabs:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2842,7 +2819,7 @@ yyreduce: break; case 183: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 666 "./util/configparser.y" { OUTYY(("P(server_num_queries_per_thread:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2854,7 +2831,7 @@ yyreduce: break; case 184: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 675 "./util/configparser.y" { OUTYY(("P(server_jostle_timeout:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2866,7 +2843,7 @@ yyreduce: break; case 185: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 684 "./util/configparser.y" { OUTYY(("P(server_delay_close:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2878,7 +2855,7 @@ yyreduce: break; case 186: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 693 "./util/configparser.y" { OUTYY(("P(server_unblock_lan_zones:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2891,7 +2868,7 @@ yyreduce: break; case 187: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 703 "./util/configparser.y" { OUTYY(("P(server_rrset_cache_size:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2902,7 +2879,7 @@ yyreduce: break; case 188: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 711 "./util/configparser.y" { OUTYY(("P(server_rrset_cache_slabs:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2918,7 +2895,7 @@ yyreduce: break; case 189: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 724 "./util/configparser.y" { OUTYY(("P(server_infra_host_ttl:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2930,7 +2907,7 @@ yyreduce: break; case 190: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 733 "./util/configparser.y" { OUTYY(("P(server_infra_lame_ttl:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2941,7 +2918,7 @@ yyreduce: break; case 191: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 741 "./util/configparser.y" { OUTYY(("P(server_infra_cache_numhosts:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2953,7 +2930,7 @@ yyreduce: break; case 192: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 750 "./util/configparser.y" { OUTYY(("P(server_infra_cache_lame_size:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2964,7 +2941,7 @@ yyreduce: break; case 193: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 758 "./util/configparser.y" { OUTYY(("P(server_infra_cache_slabs:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2980,7 +2957,7 @@ yyreduce: break; case 194: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 771 "./util/configparser.y" { OUTYY(("P(server_target_fetch_policy:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2990,7 +2967,7 @@ yyreduce: break; case 195: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 778 "./util/configparser.y" { OUTYY(("P(server_harden_short_bufsize:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3003,7 +2980,7 @@ yyreduce: break; case 196: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 788 "./util/configparser.y" { OUTYY(("P(server_harden_large_queries:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3016,7 +2993,7 @@ yyreduce: break; case 197: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 798 "./util/configparser.y" { OUTYY(("P(server_harden_glue:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3029,7 +3006,7 @@ yyreduce: break; case 198: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 808 "./util/configparser.y" { OUTYY(("P(server_harden_dnssec_stripped:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3042,7 +3019,7 @@ yyreduce: break; case 199: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 818 "./util/configparser.y" { OUTYY(("P(server_harden_below_nxdomain:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3055,7 +3032,7 @@ yyreduce: break; case 200: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 828 "./util/configparser.y" { OUTYY(("P(server_harden_referral_path:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3068,7 +3045,7 @@ yyreduce: break; case 201: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 838 "./util/configparser.y" { OUTYY(("P(server_use_caps_for_id:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3081,7 +3058,7 @@ yyreduce: break; case 202: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 848 "./util/configparser.y" { OUTYY(("P(server_private_address:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3091,7 +3068,7 @@ yyreduce: break; case 203: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 855 "./util/configparser.y" { OUTYY(("P(server_private_domain:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3101,7 +3078,7 @@ yyreduce: break; case 204: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 862 "./util/configparser.y" { OUTYY(("P(server_prefetch:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3113,7 +3090,7 @@ yyreduce: break; case 205: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 871 "./util/configparser.y" { OUTYY(("P(server_prefetch_key:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3125,7 +3102,7 @@ yyreduce: break; case 206: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 880 "./util/configparser.y" { OUTYY(("P(server_unwanted_reply_threshold:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3137,7 +3114,7 @@ yyreduce: break; case 207: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 889 "./util/configparser.y" { OUTYY(("P(server_do_not_query_address:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3147,7 +3124,7 @@ yyreduce: break; case 208: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 896 "./util/configparser.y" { OUTYY(("P(server_do_not_query_localhost:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3160,7 +3137,7 @@ yyreduce: break; case 209: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 906 "./util/configparser.y" { OUTYY(("P(server_access_control:%s %s)\n", (yyvsp[(2) - (3)].str), (yyvsp[(3) - (3)].str))); @@ -3180,7 +3157,7 @@ yyreduce: break; case 210: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 923 "./util/configparser.y" { OUTYY(("P(server_module_conf:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3190,7 +3167,7 @@ yyreduce: break; case 211: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 930 "./util/configparser.y" { OUTYY(("P(server_val_override_date:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3211,7 +3188,7 @@ yyreduce: break; case 212: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 948 "./util/configparser.y" { OUTYY(("P(server_val_sig_skew_min:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3227,7 +3204,7 @@ yyreduce: break; case 213: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 961 "./util/configparser.y" { OUTYY(("P(server_val_sig_skew_max:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3243,7 +3220,7 @@ yyreduce: break; case 214: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 974 "./util/configparser.y" { OUTYY(("P(server_cache_max_ttl:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3255,7 +3232,7 @@ yyreduce: break; case 215: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 983 "./util/configparser.y" { OUTYY(("P(server_cache_min_ttl:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3267,7 +3244,7 @@ yyreduce: break; case 216: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 992 "./util/configparser.y" { OUTYY(("P(server_bogus_ttl:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3279,7 +3256,7 @@ yyreduce: break; case 217: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1001 "./util/configparser.y" { OUTYY(("P(server_val_clean_additional:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3292,7 +3269,7 @@ yyreduce: break; case 218: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1011 "./util/configparser.y" { OUTYY(("P(server_val_permissive_mode:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3305,7 +3282,7 @@ yyreduce: break; case 219: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1021 "./util/configparser.y" { OUTYY(("P(server_ignore_cd_flag:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3317,7 +3294,7 @@ yyreduce: break; case 220: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1030 "./util/configparser.y" { OUTYY(("P(server_val_log_level:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3329,7 +3306,7 @@ yyreduce: break; case 221: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1039 "./util/configparser.y" { OUTYY(("P(server_val_nsec3_keysize_iterations:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3339,7 +3316,7 @@ yyreduce: break; case 222: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1046 "./util/configparser.y" { OUTYY(("P(server_add_holddown:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3351,7 +3328,7 @@ yyreduce: break; case 223: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1055 "./util/configparser.y" { OUTYY(("P(server_del_holddown:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3363,7 +3340,7 @@ yyreduce: break; case 224: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1064 "./util/configparser.y" { OUTYY(("P(server_keep_missing:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3375,7 +3352,7 @@ yyreduce: break; case 225: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1073 "./util/configparser.y" { OUTYY(("P(server_key_cache_size:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3386,7 +3363,7 @@ yyreduce: break; case 226: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1081 "./util/configparser.y" { OUTYY(("P(server_key_cache_slabs:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3402,7 +3379,7 @@ yyreduce: break; case 227: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1094 "./util/configparser.y" { OUTYY(("P(server_neg_cache_size:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3413,7 +3390,7 @@ yyreduce: break; case 228: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1102 "./util/configparser.y" { OUTYY(("P(server_local_zone:%s %s)\n", (yyvsp[(2) - (3)].str), (yyvsp[(3) - (3)].str))); @@ -3438,7 +3415,7 @@ yyreduce: break; case 229: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1124 "./util/configparser.y" { OUTYY(("P(server_local_data:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3448,7 +3425,7 @@ yyreduce: break; case 230: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1131 "./util/configparser.y" { char* ptr; @@ -3466,7 +3443,7 @@ yyreduce: break; case 231: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1146 "./util/configparser.y" { OUTYY(("P(server_minimal_responses:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3479,7 +3456,7 @@ yyreduce: break; case 232: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1156 "./util/configparser.y" { OUTYY(("P(server_rrset_roundrobin:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3492,7 +3469,7 @@ yyreduce: break; case 233: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1166 "./util/configparser.y" { OUTYY(("P(server_max_udp_size:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3502,7 +3479,7 @@ yyreduce: break; case 234: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1173 "./util/configparser.y" { OUTYY(("P(dns64_prefix:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3512,7 +3489,7 @@ yyreduce: break; case 235: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1180 "./util/configparser.y" { OUTYY(("P(server_dns64_synthall:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3524,7 +3501,7 @@ yyreduce: break; case 236: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1189 "./util/configparser.y" { OUTYY(("P(name:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3537,7 +3514,7 @@ yyreduce: break; case 237: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1199 "./util/configparser.y" { OUTYY(("P(stub-host:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3547,7 +3524,7 @@ yyreduce: break; case 238: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1206 "./util/configparser.y" { OUTYY(("P(stub-addr:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3557,7 +3534,7 @@ yyreduce: break; case 239: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1213 "./util/configparser.y" { OUTYY(("P(stub-first:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3569,7 +3546,7 @@ yyreduce: break; case 240: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1222 "./util/configparser.y" { OUTYY(("P(stub-prime:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3582,7 +3559,7 @@ yyreduce: break; case 241: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1232 "./util/configparser.y" { OUTYY(("P(name:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3595,7 +3572,7 @@ yyreduce: break; case 242: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1242 "./util/configparser.y" { OUTYY(("P(forward-host:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3605,7 +3582,7 @@ yyreduce: break; case 243: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1249 "./util/configparser.y" { OUTYY(("P(forward-addr:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3615,7 +3592,7 @@ yyreduce: break; case 244: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1256 "./util/configparser.y" { OUTYY(("P(forward-first:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3627,7 +3604,7 @@ yyreduce: break; case 245: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1265 "./util/configparser.y" { OUTYY(("\nP(remote-control:)\n")); @@ -3635,7 +3612,7 @@ yyreduce: break; case 255: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1276 "./util/configparser.y" { OUTYY(("P(control_enable:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3648,7 +3625,7 @@ yyreduce: break; case 256: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1286 "./util/configparser.y" { OUTYY(("P(control_port:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3660,7 +3637,7 @@ yyreduce: break; case 257: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1295 "./util/configparser.y" { OUTYY(("P(control_interface:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3670,7 +3647,7 @@ yyreduce: break; case 258: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1302 "./util/configparser.y" { OUTYY(("P(rc_server_key_file:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3680,7 +3657,7 @@ yyreduce: break; case 259: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1309 "./util/configparser.y" { OUTYY(("P(rc_server_cert_file:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3690,7 +3667,7 @@ yyreduce: break; case 260: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1316 "./util/configparser.y" { OUTYY(("P(rc_control_key_file:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3700,7 +3677,7 @@ yyreduce: break; case 261: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1323 "./util/configparser.y" { OUTYY(("P(rc_control_cert_file:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3710,7 +3687,7 @@ yyreduce: break; case 262: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1330 "./util/configparser.y" { OUTYY(("\nP(dnstap:)\n")); @@ -3718,7 +3695,7 @@ yyreduce: break; case 277: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1347 "./util/configparser.y" { OUTYY(("P(dt_dnstap_enable:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3729,7 +3706,7 @@ yyreduce: break; case 278: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1355 "./util/configparser.y" { OUTYY(("P(dt_dnstap_socket_path:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3739,7 +3716,7 @@ yyreduce: break; case 279: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1362 "./util/configparser.y" { OUTYY(("P(dt_dnstap_send_identity:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3750,7 +3727,7 @@ yyreduce: break; case 280: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1370 "./util/configparser.y" { OUTYY(("P(dt_dnstap_send_version:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3761,7 +3738,7 @@ yyreduce: break; case 281: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1378 "./util/configparser.y" { OUTYY(("P(dt_dnstap_identity:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3771,7 +3748,7 @@ yyreduce: break; case 282: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1385 "./util/configparser.y" { OUTYY(("P(dt_dnstap_version:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3781,7 +3758,7 @@ yyreduce: break; case 283: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1392 "./util/configparser.y" { OUTYY(("P(dt_dnstap_log_resolver_query_messages:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3793,7 +3770,7 @@ yyreduce: break; case 284: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1401 "./util/configparser.y" { OUTYY(("P(dt_dnstap_log_resolver_response_messages:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3805,7 +3782,7 @@ yyreduce: break; case 285: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1410 "./util/configparser.y" { OUTYY(("P(dt_dnstap_log_client_query_messages:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3817,7 +3794,7 @@ yyreduce: break; case 286: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1419 "./util/configparser.y" { OUTYY(("P(dt_dnstap_log_client_response_messages:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3829,7 +3806,7 @@ yyreduce: break; case 287: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1428 "./util/configparser.y" { OUTYY(("P(dt_dnstap_log_forwarder_query_messages:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3841,7 +3818,7 @@ yyreduce: break; case 288: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1437 "./util/configparser.y" { OUTYY(("P(dt_dnstap_log_forwarder_response_messages:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3853,7 +3830,7 @@ yyreduce: break; case 289: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1446 "./util/configparser.y" { OUTYY(("\nP(python:)\n")); @@ -3861,7 +3838,7 @@ yyreduce: break; case 293: -/* Line 1787 of yacc.c */ +/* Line 1792 of yacc.c */ #line 1455 "./util/configparser.y" { OUTYY(("P(python-script:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3871,8 +3848,8 @@ yyreduce: break; -/* Line 1787 of yacc.c */ -#line 3876 "util/configparser.c" +/* Line 1792 of yacc.c */ +#line 3853 "util/configparser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -4035,7 +4012,9 @@ yyerrlab1: YY_STACK_PRINT (yyss, yyssp); } + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END /* Shift the error token. */ @@ -4101,9 +4080,8 @@ yyreturn: } -/* Line 2048 of yacc.c */ +/* Line 2055 of yacc.c */ #line 1460 "./util/configparser.y" /* parse helper routines could be here */ - diff --git a/external/unbound/util/configparser.h b/external/unbound/util/configparser.h index b0e07227b..0ee72661d 100644 --- a/external/unbound/util/configparser.h +++ b/external/unbound/util/configparser.h @@ -1,4 +1,4 @@ -/* A Bison parser, made by GNU Bison 2.6.1. */ +/* A Bison parser, made by GNU Bison 2.7. */ /* Bison interface for Yacc-like parsers in C @@ -30,8 +30,8 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ -#ifndef YY_UTIL_CONFIGPARSER_H -# define YY_UTIL_CONFIGPARSER_H +#ifndef YY_YY_UTIL_CONFIGPARSER_H_INCLUDED +# define YY_YY_UTIL_CONFIGPARSER_H_INCLUDED /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -347,13 +347,13 @@ extern int yydebug; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE { -/* Line 2049 of yacc.c */ +/* Line 2058 of yacc.c */ #line 64 "./util/configparser.y" char* str; -/* Line 2049 of yacc.c */ +/* Line 2058 of yacc.c */ #line 358 "util/configparser.h" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 @@ -377,4 +377,4 @@ int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ -#endif /* !YY_UTIL_CONFIGPARSER_H */ +#endif /* !YY_YY_UTIL_CONFIGPARSER_H_INCLUDED */ diff --git a/external/unbound/util/data/dname.c b/external/unbound/util/data/dname.c index 76f2e6458..d43bbf6d2 100644 --- a/external/unbound/util/data/dname.c +++ b/external/unbound/util/data/dname.c @@ -114,8 +114,8 @@ query_dname_compare(register uint8_t* d1, register uint8_t* d2) while(lab1--) { /* compare bytes first for speed */ if(*d1 != *d2 && - tolower((int)*d1) != tolower((int)*d2)) { - if(tolower((int)*d1) < tolower((int)*d2)) + tolower((unsigned char)*d1) != tolower((unsigned char)*d2)) { + if(tolower((unsigned char)*d1) < tolower((unsigned char)*d2)) return -1; return 1; } @@ -138,7 +138,7 @@ query_dname_tolower(uint8_t* dname) while(labellen) { dname++; while(labellen--) { - *dname = (uint8_t)tolower((int)*dname); + *dname = (uint8_t)tolower((unsigned char)*dname); dname++; } labellen = *dname; @@ -167,7 +167,7 @@ pkt_dname_tolower(sldns_buffer* pkt, uint8_t* dname) if(dname+lablen >= sldns_buffer_end(pkt)) return; while(lablen--) { - *dname = (uint8_t)tolower((int)*dname); + *dname = (uint8_t)tolower((unsigned char)*dname); dname++; } if(dname >= sldns_buffer_end(pkt)) @@ -256,8 +256,8 @@ dname_pkt_compare(sldns_buffer* pkt, uint8_t* d1, uint8_t* d2) log_assert(len1 == len2 && len1 != 0); /* compare labels */ while(len1--) { - if(tolower((int)*d1++) != tolower((int)*d2++)) { - if(tolower((int)d1[-1]) < tolower((int)d2[-1])) + if(tolower((unsigned char)*d1++) != tolower((unsigned char)*d2++)) { + if(tolower((unsigned char)d1[-1]) < tolower((unsigned char)d2[-1])) return -1; return 1; } @@ -282,7 +282,7 @@ dname_query_hash(uint8_t* dname, hashvalue_t h) labuf[0] = lablen; i=0; while(lablen--) - labuf[++i] = (uint8_t)tolower((int)*dname++); + labuf[++i] = (uint8_t)tolower((unsigned char)*dname++); h = hashlittle(labuf, labuf[0] + 1, h); lablen = *dname++; } @@ -310,7 +310,7 @@ dname_pkt_hash(sldns_buffer* pkt, uint8_t* dname, hashvalue_t h) labuf[0] = lablen; i=0; while(lablen--) - labuf[++i] = (uint8_t)tolower((int)*dname++); + labuf[++i] = (uint8_t)tolower((unsigned char)*dname++); h = hashlittle(labuf, labuf[0] + 1, h); lablen = *dname++; } @@ -423,8 +423,8 @@ static int memlowercmp(uint8_t* p1, uint8_t* p2, uint8_t len) { while(len--) { - if(*p1 != *p2 && tolower((int)*p1) != tolower((int)*p2)) { - if(tolower((int)*p1) < tolower((int)*p2)) + if(*p1 != *p2 && tolower((unsigned char)*p1) != tolower((unsigned char)*p2)) { + if(tolower((unsigned char)*p1) < tolower((unsigned char)*p2)) return -1; return 1; } @@ -480,10 +480,10 @@ dname_lab_cmp(uint8_t* d1, int labs1, uint8_t* d2, int labs2, int* mlabs) * lastdiff = c; * lastmlabs = atlabel; } apart from d1++,d2++ */ while(len1) { - if(*d1 != *d2 && tolower((int)*d1) - != tolower((int)*d2)) { - if(tolower((int)*d1) < - tolower((int)*d2)) { + if(*d1 != *d2 && tolower((unsigned char)*d1) + != tolower((unsigned char)*d2)) { + if(tolower((unsigned char)*d1) < + tolower((unsigned char)*d2)) { lastdiff = -1; lastmlabs = atlabel; d1 += len1; @@ -561,7 +561,7 @@ void dname_str(uint8_t* dname, char* str) return; } while(lablen--) { - if(isalnum((int)*dname) + if(isalnum((unsigned char)*dname) || *dname == '-' || *dname == '_' || *dname == '*') *s++ = *(char*)dname++; diff --git a/external/unbound/util/data/msgreply.c b/external/unbound/util/data/msgreply.c index 126e7bef4..68bcfd09e 100644 --- a/external/unbound/util/data/msgreply.c +++ b/external/unbound/util/data/msgreply.c @@ -576,10 +576,12 @@ reply_info_delete(void* d, void* ATTR_UNUSED(arg)) } hashvalue_t -query_info_hash(struct query_info *q) +query_info_hash(struct query_info *q, uint16_t flags) { hashvalue_t h = 0xab; h = hashlittle(&q->qtype, sizeof(q->qtype), h); + if(q->qtype == LDNS_RR_TYPE_AAAA && (flags&BIT_CD)) + h++; h = hashlittle(&q->qclass, sizeof(q->qclass), h); h = dname_query_hash(q->qname, h); return h; @@ -771,15 +773,14 @@ log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep) region, 65535, 1)) { log_info("%s: log_dns_msg: out of memory", str); } else { - char* str = sldns_wire2str_pkt(sldns_buffer_begin(buf), + char* s = sldns_wire2str_pkt(sldns_buffer_begin(buf), sldns_buffer_limit(buf)); - if(!str) { + if(!s) { log_info("%s: log_dns_msg: ldns tostr failed", str); } else { - log_info("%s %s", - str, (char*)sldns_buffer_begin(buf)); + log_info("%s %s", str, s); } - free(str); + free(s); } sldns_buffer_free(buf); regional_destroy(region); diff --git a/external/unbound/util/data/msgreply.h b/external/unbound/util/data/msgreply.h index ccbd0d748..e8d6d762e 100644 --- a/external/unbound/util/data/msgreply.h +++ b/external/unbound/util/data/msgreply.h @@ -305,8 +305,9 @@ void query_entry_delete(void *q, void* arg); /** delete reply_info data structure */ void reply_info_delete(void* d, void* arg); -/** calculate hash value of query_info, lowercases the qname */ -hashvalue_t query_info_hash(struct query_info *q); +/** calculate hash value of query_info, lowercases the qname, + * uses CD flag for AAAA qtype */ +hashvalue_t query_info_hash(struct query_info *q, uint16_t flags); /** * Setup query info entry diff --git a/external/unbound/util/fptr_wlist.c b/external/unbound/util/fptr_wlist.c index 3a5fc5f06..5a77432c7 100644 --- a/external/unbound/util/fptr_wlist.c +++ b/external/unbound/util/fptr_wlist.c @@ -280,7 +280,7 @@ fptr_whitelist_modenv_detach_subs(void (*fptr)( int fptr_whitelist_modenv_attach_sub(int (*fptr)( struct module_qstate* qstate, struct query_info* qinfo, - uint16_t qflags, int prime, struct module_qstate** newq)) + uint16_t qflags, int prime, int valrec, struct module_qstate** newq)) { if(fptr == &mesh_attach_sub) return 1; return 0; @@ -296,7 +296,7 @@ fptr_whitelist_modenv_kill_sub(void (*fptr)(struct module_qstate* newq)) int fptr_whitelist_modenv_detect_cycle(int (*fptr)( struct module_qstate* qstate, struct query_info* qinfo, - uint16_t flags, int prime)) + uint16_t flags, int prime, int valrec)) { if(fptr == &mesh_detect_cycle) return 1; return 0; diff --git a/external/unbound/util/fptr_wlist.h b/external/unbound/util/fptr_wlist.h index 62692ba8b..10de5d816 100644 --- a/external/unbound/util/fptr_wlist.h +++ b/external/unbound/util/fptr_wlist.h @@ -233,7 +233,7 @@ int fptr_whitelist_modenv_detach_subs(void (*fptr)( */ int fptr_whitelist_modenv_attach_sub(int (*fptr)( struct module_qstate* qstate, struct query_info* qinfo, - uint16_t qflags, int prime, struct module_qstate** newq)); + uint16_t qflags, int prime, int valrec, struct module_qstate** newq)); /** * Check function pointer whitelist for module_env kill_sub callback values. @@ -251,7 +251,7 @@ int fptr_whitelist_modenv_kill_sub(void (*fptr)(struct module_qstate* newq)); */ int fptr_whitelist_modenv_detect_cycle(int (*fptr)( struct module_qstate* qstate, struct query_info* qinfo, - uint16_t flags, int prime)); + uint16_t flags, int prime, int valrec)); /** * Check function pointer whitelist for module init call values. diff --git a/external/unbound/util/iana_ports.inc b/external/unbound/util/iana_ports.inc index 6754521b3..d318477e5 100644 --- a/external/unbound/util/iana_ports.inc +++ b/external/unbound/util/iana_ports.inc @@ -2061,6 +2061,7 @@ 2423, 2424, 2425, +2426, 2427, 2428, 2429, @@ -3964,6 +3965,7 @@ 4785, 4789, 4790, +4791, 4800, 4801, 4802, @@ -4225,6 +4227,7 @@ 5463, 5464, 5465, +5474, 5500, 5501, 5502, @@ -5351,9 +5354,11 @@ 35004, 35355, 36001, +36411, 36865, 37475, 37654, +38002, 38201, 38202, 38203, diff --git a/external/unbound/util/mini_event.h b/external/unbound/util/mini_event.h index 58bbc8073..1a5bcb445 100644 --- a/external/unbound/util/mini_event.h +++ b/external/unbound/util/mini_event.h @@ -58,6 +58,21 @@ #define HAVE_EVENT_BASE_FREE #endif +/* redefine to use our own namespace so that on platforms where + * linkers crosslink library-private symbols with other symbols, it works */ +#define event_init minievent_init +#define event_get_version minievent_get_version +#define event_get_method minievent_get_method +#define event_base_dispatch minievent_base_dispatch +#define event_base_loopexit minievent_base_loopexit +#define event_base_free minievent_base_free +#define event_set minievent_set +#define event_base_set minievent_base_set +#define event_add minievent_add +#define event_del minievent_del +#define signal_add minisignal_add +#define signal_del minisignal_del + /** event timeout */ #define EV_TIMEOUT 0x01 /** event fd readable */ diff --git a/external/unbound/util/module.h b/external/unbound/util/module.h index f95ff6dc8..b9dde36e2 100644 --- a/external/unbound/util/module.h +++ b/external/unbound/util/module.h @@ -256,13 +256,14 @@ struct module_env { * @param qinfo: what to query for (copied). * @param qflags: what flags to use (RD, CD flag or not). * @param prime: if it is a (stub) priming query. + * @param valrec: validation lookup recursion, does not need validation * @param newq: If the new subquery needs initialisation, it is * returned, otherwise NULL is returned. * @return: false on error, true if success (and init may be needed). */ int (*attach_sub)(struct module_qstate* qstate, struct query_info* qinfo, uint16_t qflags, int prime, - struct module_qstate** newq); + int valrec, struct module_qstate** newq); /** * Kill newly attached sub. If attach_sub returns newq for @@ -280,13 +281,15 @@ struct module_env { * @param qinfo: query info for dependency. * @param flags: query flags of dependency, RD/CD flags. * @param prime: if dependency is a priming query or not. + * @param valrec: validation lookup recursion, does not need validation * @return true if the name,type,class exists and the given * qstate mesh exists as a dependency of that name. Thus * if qstate becomes dependent on name,type,class then a * cycle is created. */ int (*detect_cycle)(struct module_qstate* qstate, - struct query_info* qinfo, uint16_t flags, int prime); + struct query_info* qinfo, uint16_t flags, int prime, + int valrec); /** region for temporary usage. May be cleared after operate() call. */ struct regional* scratch; @@ -397,6 +400,9 @@ struct module_qstate { uint16_t query_flags; /** if this is a (stub or root) priming query (with hints) */ int is_priming; + /** if this is a validation recursion query that does not get + * validation itself */ + int is_valrec; /** comm_reply contains server replies */ struct comm_reply* reply; diff --git a/external/unbound/util/net_help.c b/external/unbound/util/net_help.c index 30d543e00..8c2bac737 100644 --- a/external/unbound/util/net_help.c +++ b/external/unbound/util/net_help.c @@ -613,12 +613,17 @@ void* listen_sslctx_create(char* key, char* pem, char* verifypem) log_crypto_err("could not SSL_CTX_new"); return NULL; } - /* no SSLv2 because has defects */ + /* no SSLv2, SSLv3 because has defects */ if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)){ log_crypto_err("could not set SSL_OP_NO_SSLv2"); SSL_CTX_free(ctx); return NULL; } + if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)){ + log_crypto_err("could not set SSL_OP_NO_SSLv3"); + SSL_CTX_free(ctx); + return NULL; + } if(!SSL_CTX_use_certificate_file(ctx, pem, SSL_FILETYPE_PEM)) { log_err("error for cert file: %s", pem); log_crypto_err("error in SSL_CTX use_certificate_file"); @@ -668,6 +673,11 @@ void* connect_sslctx_create(char* key, char* pem, char* verifypem) SSL_CTX_free(ctx); return NULL; } + if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)) { + log_crypto_err("could not set SSL_OP_NO_SSLv3"); + SSL_CTX_free(ctx); + return NULL; + } if(key && key[0]) { if(!SSL_CTX_use_certificate_file(ctx, pem, SSL_FILETYPE_PEM)) { log_err("error in client certificate %s", pem); @@ -689,7 +699,7 @@ void* connect_sslctx_create(char* key, char* pem, char* verifypem) } } if(verifypem && verifypem[0]) { - if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL) != 1) { + if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) { log_crypto_err("error in SSL_CTX verify"); SSL_CTX_free(ctx); return NULL; diff --git a/external/unbound/util/winsock_event.h b/external/unbound/util/winsock_event.h index 40892c14b..f64265743 100644 --- a/external/unbound/util/winsock_event.h +++ b/external/unbound/util/winsock_event.h @@ -90,6 +90,21 @@ #define HAVE_EVENT_BASE_FREE #endif +/* redefine the calls to different names so that there is no name + * collision with other code that uses libevent names. (that uses libunbound)*/ +#define event_init winsockevent_init +#define event_get_version winsockevent_get_version +#define event_get_method winsockevent_get_method +#define event_base_dispatch winsockevent_base_dispatch +#define event_base_loopexit winsockevent_base_loopexit +#define event_base_free winsockevent_base_free +#define event_set winsockevent_set +#define event_base_set winsockevent_base_set +#define event_add winsockevent_add +#define event_del winsockevent_del +#define signal_add winsocksignal_add +#define signal_del winsocksignal_del + /** event timeout */ #define EV_TIMEOUT 0x01 /** event fd readable */ diff --git a/external/unbound/validator/autotrust.c b/external/unbound/validator/autotrust.c index a59763382..5e1dc4ef3 100644 --- a/external/unbound/validator/autotrust.c +++ b/external/unbound/validator/autotrust.c @@ -902,13 +902,13 @@ static int handle_origin(char* line, uint8_t** origin, size_t* origin_len) { size_t len = 0; - while(isspace((int)*line)) + while(isspace((unsigned char)*line)) line++; if(strncmp(line, "$ORIGIN", 7) != 0) return 0; free(*origin); line += 7; - while(isspace((int)*line)) + while(isspace((unsigned char)*line)) line++; *origin = sldns_str2wire_dname(line, &len); *origin_len = len; diff --git a/external/unbound/validator/val_anchor.c b/external/unbound/validator/val_anchor.c index a4adfe2d9..3a67fff45 100644 --- a/external/unbound/validator/val_anchor.c +++ b/external/unbound/validator/val_anchor.c @@ -563,7 +563,7 @@ readkeyword_bindfile(FILE* in, sldns_buffer* buf, int* line, int comments) /* not a comment, complete the keyword */ if(numdone > 0) { /* check same type */ - if(isspace(c)) { + if(isspace((unsigned char)c)) { ungetc(c, in); return numdone; } @@ -582,12 +582,12 @@ readkeyword_bindfile(FILE* in, sldns_buffer* buf, int* line, int comments) } sldns_buffer_write_u8(buf, (uint8_t)c); numdone++; - if(isspace(c)) { + if(isspace((unsigned char)c)) { /* collate whitespace into ' ' */ while((c = getc(in)) != EOF ) { if(c == '\n') (*line)++; - if(!isspace(c)) { + if(!isspace((unsigned char)c)) { ungetc(c, in); break; } @@ -607,7 +607,7 @@ skip_to_special(FILE* in, sldns_buffer* buf, int* line, int spec) int rdlen; sldns_buffer_clear(buf); while((rdlen=readkeyword_bindfile(in, buf, line, 1))) { - if(rdlen == 1 && isspace((int)*sldns_buffer_begin(buf))) { + if(rdlen == 1 && isspace((unsigned char)*sldns_buffer_begin(buf))) { sldns_buffer_clear(buf); continue; } @@ -648,7 +648,7 @@ process_bind_contents(struct val_anchors* anchors, sldns_buffer* buf, sldns_buffer_clear(buf); while((rdlen=readkeyword_bindfile(in, buf, line, comments))) { if(rdlen == 1 && sldns_buffer_position(buf) == 1 - && isspace((int)*sldns_buffer_begin(buf))) { + && isspace((unsigned char)*sldns_buffer_begin(buf))) { /* starting whitespace is removed */ sldns_buffer_clear(buf); continue; @@ -703,7 +703,7 @@ process_bind_contents(struct val_anchors* anchors, sldns_buffer* buf, } return 1; } else if(rdlen == 1 && - isspace((int)sldns_buffer_current(buf)[-1])) { + isspace((unsigned char)sldns_buffer_current(buf)[-1])) { /* leave whitespace here */ } else { /* not space or whatnot, so actual content */ diff --git a/external/unbound/validator/val_nsec3.c b/external/unbound/validator/val_nsec3.c index fe5091c0a..548daf2bf 100644 --- a/external/unbound/validator/val_nsec3.c +++ b/external/unbound/validator/val_nsec3.c @@ -731,8 +731,8 @@ label_compare_lower(uint8_t* lab1, uint8_t* lab2, size_t lablen) { size_t i; for(i=0; iquery_flags & BIT_CD) { verbose(VERB_ALGO, "not validating response due to CD bit"); return 0; } + */ + if(qstate->is_valrec) { + verbose(VERB_ALGO, "not validating response, is valrec" + "(validation recursion lookup)"); + return 0; + } if(ret_rc != LDNS_RCODE_NOERROR || !ret_msg) rcode = ret_rc; @@ -351,14 +364,20 @@ generate_request(struct module_qstate* qstate, int id, uint8_t* name, struct val_qstate* vq = (struct val_qstate*)qstate->minfo[id]; struct module_qstate* newq; struct query_info ask; + int valrec; ask.qname = name; ask.qname_len = namelen; ask.qtype = qtype; ask.qclass = qclass; log_query_info(VERB_ALGO, "generate request", &ask); fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); + /* enable valrec flag to avoid recursion to the same validation + * routine, this lookup is simply a lookup. DLVs need validation */ + if(qtype == LDNS_RR_TYPE_DLV) + valrec = 0; + else valrec = 1; if(!(*qstate->env->attach_sub)(qstate, &ask, - (uint16_t)(BIT_RD|flags), 0, &newq)){ + (uint16_t)(BIT_RD|flags), 0, valrec, &newq)){ log_err("Could not generate request: out of memory"); return 0; } @@ -2005,14 +2024,16 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq, /* if secure, this will override cache anyway, no need * to check if from parentNS */ if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo, - vq->orig_msg->rep, 0, qstate->prefetch_leeway, 0, NULL)) { + vq->orig_msg->rep, 0, qstate->prefetch_leeway, 0, NULL, + qstate->query_flags)) { log_err("out of memory caching validator results"); } } else { /* for a referral, store the verified RRsets */ /* and this does not get prefetched, so no leeway */ if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo, - vq->orig_msg->rep, 1, 0, 0, NULL)) { + vq->orig_msg->rep, 1, 0, 0, NULL, + qstate->query_flags)) { log_err("out of memory caching validator results"); } } diff --git a/external/unbound/winrc/combined.ico b/external/unbound/winrc/combined.ico index aa65d11e2..b0a4f4d16 100644 Binary files a/external/unbound/winrc/combined.ico and b/external/unbound/winrc/combined.ico differ diff --git a/external/unbound/winrc/gen_msg.bin b/external/unbound/winrc/gen_msg.bin index 6e560057c..ed8f79e63 100644 Binary files a/external/unbound/winrc/gen_msg.bin and b/external/unbound/winrc/gen_msg.bin differ diff --git a/external/unbound/winrc/setup_left.bmp b/external/unbound/winrc/setup_left.bmp index ddc17d079..a013276a9 100644 Binary files a/external/unbound/winrc/setup_left.bmp and b/external/unbound/winrc/setup_left.bmp differ diff --git a/external/unbound/winrc/setup_top.bmp b/external/unbound/winrc/setup_top.bmp index 79998ec64..a7404c836 100644 Binary files a/external/unbound/winrc/setup_top.bmp and b/external/unbound/winrc/setup_top.bmp differ diff --git a/external/unbound/winrc/unbound16.ico b/external/unbound/winrc/unbound16.ico index e62634b70..06d82e571 100644 Binary files a/external/unbound/winrc/unbound16.ico and b/external/unbound/winrc/unbound16.ico differ diff --git a/external/unbound/winrc/unbound32.ico b/external/unbound/winrc/unbound32.ico index 64272eed4..7e5b3a725 100644 Binary files a/external/unbound/winrc/unbound32.ico and b/external/unbound/winrc/unbound32.ico differ diff --git a/external/unbound/winrc/unbound48.ico b/external/unbound/winrc/unbound48.ico index 074d12ebc..cb7291469 100644 Binary files a/external/unbound/winrc/unbound48.ico and b/external/unbound/winrc/unbound48.ico differ diff --git a/external/unbound/winrc/unbound64.ico b/external/unbound/winrc/unbound64.ico index c02f68f0a..ca2362e5d 100644 Binary files a/external/unbound/winrc/unbound64.ico and b/external/unbound/winrc/unbound64.ico differ diff --git a/external/unbound/winrc/unbound64.png b/external/unbound/winrc/unbound64.png index b37bf3f11..78d831565 100644 Binary files a/external/unbound/winrc/unbound64.png and b/external/unbound/winrc/unbound64.png differ diff --git a/include/INode.h b/include/INode.h index d9ab27fc1..c7c559d63 100644 --- a/include/INode.h +++ b/include/INode.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/include/IWallet.h b/include/IWallet.h index 5c4925d55..bb8ac0607 100644 --- a/include/IWallet.h +++ b/include/IWallet.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 00283aba3..a80dfe378 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, The Monero Project +# Copyright (c) 2014-2015, The Monero Project # # All rights reserved. # @@ -28,59 +28,72 @@ # # Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers -add_definitions(-DSTATICLIB) -# miniupnp changed their static define -add_definitions(-DMINIUPNP_STATICLIB) +if (WIN32 OR STATIC) + add_definitions(-DSTATICLIB) + # miniupnp changed their static define + add_definitions(-DMINIUPNP_STATICLIB) +endif () -file(GLOB COMMON common/*) -file(GLOB_RECURSE CRYPTO crypto/*) -file(GLOB_RECURSE CRYPTONOTE_CORE cryptonote_core/*) -file(GLOB_RECURSE CRYPTONOTE_PROTOCOL cryptonote_protocol/*) -file(GLOB_RECURSE DAEMON daemon/*) -file(GLOB_RECURSE P2P p2p/*) -file(GLOB_RECURSE RPC rpc/*) -file(GLOB_RECURSE SIMPLEWALLET simplewallet/*) -file(GLOB_RECURSE CONN_TOOL connectivity_tool/*) -file(GLOB_RECURSE WALLET wallet/*) -file(GLOB_RECURSE MINER miner/*) -file(GLOB MNEMONICS mnemonics/*) +function (bitmonero_private_headers group) + source_group("${group}\\Private" + FILES + ${ARGN}) +endfunction () -source_group(common FILES ${COMMON}) -source_group(crypto FILES ${CRYPTO}) -source_group(cryptonote_core FILES ${CRYPTONOTE_CORE}) -source_group(cryptonote_protocol FILES ${CRYPTONOTE_PROTOCOL}) -source_group(daemon FILES ${DAEMON}) -source_group(p2p FILES ${P2P}) -source_group(rpc FILES ${RPC}) -source_group(simplewallet FILES ${SIMPLEWALLET}) -source_group(connectivity-tool FILES ${CONN_TOOL}) -source_group(wallet FILES ${WALLET}) -source_group(simpleminer FILES ${MINER}) -source_group(mnemonics FILES ${MNEMONICS}) +function (bitmonero_install_headers subdir) + install( + FILES ${ARGN} + DESTINATION "include/${subdir}" + COMPONENT development) +endfunction () -add_library(common ${COMMON}) -add_library(crypto ${CRYPTO}) -add_library(cryptonote_core ${CRYPTONOTE_CORE}) -add_library(mnemonics ${MNEMONICS}) -add_executable(daemon ${DAEMON} ${P2P} ${CRYPTONOTE_PROTOCOL}) -add_executable(connectivity_tool ${CONN_TOOL}) -add_executable(simpleminer ${MINER}) -target_link_libraries(daemon rpc cryptonote_core crypto common ${UNBOUND_LIBRARY} ${UPNP_LIBRARIES} ${NET_SKELETON_LIBRARY} ${Boost_LIBRARIES} ${EXTRA_LIBRARIES}) -target_link_libraries(connectivity_tool cryptonote_core crypto common ${UNBOUND_LIBRARY} ${Boost_LIBRARIES} ${EXTRA_LIBRARIES}) -target_link_libraries(simpleminer cryptonote_core crypto common ${UNBOUND_LIBRARY} ${Boost_LIBRARIES} ${EXTRA_LIBRARIES}) -add_library(rpc ${RPC}) -add_library(wallet ${WALLET}) -target_link_libraries(wallet mnemonics) -add_executable(simplewallet ${SIMPLEWALLET} ) -target_link_libraries(simplewallet wallet rpc cryptonote_core crypto common mnemonics ${UNBOUND_LIBRARY} ${UPNP_LIBRARIES} ${NET_SKELETON_LIBRARY} ${Boost_LIBRARIES} ${EXTRA_LIBRARIES}) -add_dependencies(daemon version) -add_dependencies(rpc version) -add_dependencies(simplewallet version) +function (bitmonero_add_executable name) + source_group("${name}" + FILES + ${ARGN}) -set_property(TARGET common crypto cryptonote_core rpc wallet PROPERTY FOLDER "libs") -set_property(TARGET daemon simplewallet connectivity_tool simpleminer PROPERTY FOLDER "prog") -if (STATIC) - set_property(TARGET daemon simplewallet connectivity_tool simpleminer PROPERTY LINK_SEARCH_START_STATIC 1) - set_property(TARGET daemon simplewallet connectivity_tool simpleminer PROPERTY LINK_SEARCH_END_STATIC 1) -endif() -set_property(TARGET daemon PROPERTY OUTPUT_NAME "bitmonerod") + add_executable("${name}" + ${ARGN}) + target_link_libraries("${name}" + LINK_PRIVATE + ${EXTRA_LIBRARIES}) + set_property(TARGET "${name}" + PROPERTY + FOLDER "prog") + set_property(TARGET "${name}" + PROPERTY + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") + + if (STATIC) + set_property(TARGET "${name}" + PROPERTY + LINK_SEARCH_START_STATIC 1) + set_property(TARGET "${name}" + PROPERTY + LINK_SEARCH_END_STATIC 1) + endif () +endfunction () + +function (bitmonero_add_library name) + source_group("${name}" + FILES + ${ARGN}) + + add_library("${name}" + ${ARGN}) + set_property(TARGET "${name}" + PROPERTY + FOLDER "libs") +endfunction () + +add_subdirectory(common) +add_subdirectory(crypto) +add_subdirectory(cryptonote_core) +add_subdirectory(mnemonics) +add_subdirectory(rpc) +add_subdirectory(wallet) + +add_subdirectory(connectivity_tool) +add_subdirectory(miner) +add_subdirectory(simplewallet) +add_subdirectory(daemon) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt new file mode 100644 index 000000000..16c4b0ae3 --- /dev/null +++ b/src/common/CMakeLists.txt @@ -0,0 +1,64 @@ +# Copyright (c) 2014-2015, The Monero Project +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other +# materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be +# used to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set(common_sources + base58.cpp + command_line.cpp + dns_utils.cpp + util.cpp) + +set(common_headers) + +set(common_private_headers + base58.h + boost_serialization_helper.h + command_line.h + dns_utils.h + int-util.h + pod-class.h + unordered_containers_boost_serialization.h + util.h + varint.h) + +bitmonero_private_headers(common + ${common_private_headers}) +bitmonero_add_library(common + ${common_sources} + ${common_headers} + ${common_private_headers}) +target_link_libraries(common + LINK_PRIVATE + crypto + ${UNBOUND_LIBRARY} + ${Boost_DATE_TIME_LIBRARY} + ${Boost_FILESYSTEM_LIBRARY} + ${Boost_SYSTEM_LIBRARY} + ${EXTRA_LIBRARIES}) + +#bitmonero_install_headers(common +# ${common_headers}) diff --git a/src/common/base58.cpp b/src/common/base58.cpp index 9ea6ba1ba..6adc46ca7 100644 --- a/src/common/base58.cpp +++ b/src/common/base58.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/common/base58.h b/src/common/base58.h index ad4f146a4..1a9ad1a77 100644 --- a/src/common/base58.h +++ b/src/common/base58.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/common/boost_serialization_helper.h b/src/common/boost_serialization_helper.h index 7c5529cc2..c108c52e1 100644 --- a/src/common/boost_serialization_helper.h +++ b/src/common/boost_serialization_helper.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/common/command_line.cpp b/src/common/command_line.cpp index a2e7faf9f..36d9905b8 100644 --- a/src/common/command_line.cpp +++ b/src/common/command_line.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/common/command_line.h b/src/common/command_line.h index 09ae877d3..5176f0f67 100644 --- a/src/common/command_line.h +++ b/src/common/command_line.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/common/dns_utils.cpp b/src/common/dns_utils.cpp index d21b538a6..3e50b6af8 100644 --- a/src/common/dns_utils.cpp +++ b/src/common/dns_utils.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/common/dns_utils.h b/src/common/dns_utils.h index 9958e4ca2..a16c7eff7 100644 --- a/src/common/dns_utils.h +++ b/src/common/dns_utils.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/common/int-util.h b/src/common/int-util.h index 40ac2eb64..cd6e65460 100644 --- a/src/common/int-util.h +++ b/src/common/int-util.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/common/pod-class.h b/src/common/pod-class.h index 8c7e4c2e9..ebe919203 100644 --- a/src/common/pod-class.h +++ b/src/common/pod-class.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/common/unordered_containers_boost_serialization.h b/src/common/unordered_containers_boost_serialization.h index f432a8cbd..563023624 100644 --- a/src/common/unordered_containers_boost_serialization.h +++ b/src/common/unordered_containers_boost_serialization.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/common/util.cpp b/src/common/util.cpp index 0ad1f0791..907a87cee 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/common/util.h b/src/common/util.h index 51f0dad90..0d23135b0 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/common/varint.h b/src/common/varint.h index 5a73c2746..cd88e12a7 100644 --- a/src/common/varint.h +++ b/src/common/varint.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/connectivity_tool/CMakeLists.txt b/src/connectivity_tool/CMakeLists.txt new file mode 100644 index 000000000..f36963d23 --- /dev/null +++ b/src/connectivity_tool/CMakeLists.txt @@ -0,0 +1,45 @@ +# Copyright (c) 2014-2015, The Monero Project +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other +# materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be +# used to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set(connectivity_tool_sources + conn_tool.cpp) + +set(connectivity_tool_private_headers) + +bitmonero_add_executable(connectivity_tool + ${connectivity_tool_sources} + ${connectivity_tool_private_headers}) +target_link_libraries(connectivity_tool + LINK_PRIVATE + cryptonote_core + crypto + common + ${CMAKE_THREAD_LIBS_INIT} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${Boost_REGEX_LIBRARY} + ${Boost_SYSTEM_LIBRARY}) diff --git a/src/connectivity_tool/conn_tool.cpp b/src/connectivity_tool/conn_tool.cpp index abddd5245..e658d2706 100644 --- a/src/connectivity_tool/conn_tool.cpp +++ b/src/connectivity_tool/conn_tool.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt new file mode 100644 index 000000000..54dd99e26 --- /dev/null +++ b/src/crypto/CMakeLists.txt @@ -0,0 +1,76 @@ +# Copyright (c) 2014-2015, The Monero Project +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other +# materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be +# used to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set(crypto_sources + aesb.c + blake256.c + chacha8.c + crypto-ops-data.c + crypto-ops.c + crypto.cpp + groestl.c + hash-extra-blake.c + hash-extra-groestl.c + hash-extra-jh.c + hash-extra-skein.c + hash.c + jh.c + keccak.c + oaes_lib.c + random.c + skein.c + slow-hash.c + tree-hash.c) + +set(crypto_headers) + +set(crypto_private_headers + blake256.h + chacha8.h + crypto-ops.h + crypto.h + generic-ops.h + groestl.h + groestl_tables.h + hash-ops.h + hash.h + initializer.h + jh.h + keccak.h + oaes_config.h + oaes_lib.h + random.h + skein.h + skein_port.h) + +bitmonero_private_headers(crypto + ${crypto_private_headers}) +bitmonero_add_library(crypto + ${crypto_sources} + ${crypto_headers} + ${crypto_private_headers}) diff --git a/src/crypto/blake256.c b/src/crypto/blake256.c index b6c1bd2f5..63163b51b 100644 --- a/src/crypto/blake256.c +++ b/src/crypto/blake256.c @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/blake256.h b/src/crypto/blake256.h index b6edbad9c..1545b2a9d 100644 --- a/src/crypto/blake256.h +++ b/src/crypto/blake256.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/chacha8.h b/src/crypto/chacha8.h index 0ce130834..9527e4016 100644 --- a/src/crypto/chacha8.h +++ b/src/crypto/chacha8.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/crypto-ops-data.c b/src/crypto/crypto-ops-data.c index 298399308..c26abacca 100644 --- a/src/crypto/crypto-ops-data.c +++ b/src/crypto/crypto-ops-data.c @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/crypto-ops.c b/src/crypto/crypto-ops.c index 1a7bc8f45..e3b48fbb2 100644 --- a/src/crypto/crypto-ops.c +++ b/src/crypto/crypto-ops.c @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/crypto-ops.h b/src/crypto/crypto-ops.h index 8ee75d2fe..0bd1f9f9b 100644 --- a/src/crypto/crypto-ops.h +++ b/src/crypto/crypto-ops.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/crypto.cpp b/src/crypto/crypto.cpp index fa0199f20..01e35f399 100644 --- a/src/crypto/crypto.cpp +++ b/src/crypto/crypto.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index f72a03f98..afbc9732e 100644 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/generic-ops.h b/src/crypto/generic-ops.h index a08f60dd4..a860a2076 100644 --- a/src/crypto/generic-ops.h +++ b/src/crypto/generic-ops.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/groestl.c b/src/crypto/groestl.c index 00bf987c9..e1c89cc3b 100644 --- a/src/crypto/groestl.c +++ b/src/crypto/groestl.c @@ -357,4 +357,4 @@ static int crypto_hash(unsigned char *out, return 0; } -*/ \ No newline at end of file +*/ diff --git a/src/crypto/groestl.h b/src/crypto/groestl.h index e2c6d2174..a9c907a19 100644 --- a/src/crypto/groestl.h +++ b/src/crypto/groestl.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/groestl_tables.h b/src/crypto/groestl_tables.h index 79e350bf3..d080a53db 100644 --- a/src/crypto/groestl_tables.h +++ b/src/crypto/groestl_tables.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/hash-extra-blake.c b/src/crypto/hash-extra-blake.c index e9007b5d8..d8a7b7e22 100644 --- a/src/crypto/hash-extra-blake.c +++ b/src/crypto/hash-extra-blake.c @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/hash-extra-groestl.c b/src/crypto/hash-extra-groestl.c index 2b8a77965..6503a0624 100644 --- a/src/crypto/hash-extra-groestl.c +++ b/src/crypto/hash-extra-groestl.c @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/hash-extra-jh.c b/src/crypto/hash-extra-jh.c index d18ef3993..aaa80ca0f 100644 --- a/src/crypto/hash-extra-jh.c +++ b/src/crypto/hash-extra-jh.c @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/hash-extra-skein.c b/src/crypto/hash-extra-skein.c index 8818815af..6f18a300e 100644 --- a/src/crypto/hash-extra-skein.c +++ b/src/crypto/hash-extra-skein.c @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/hash-ops.h b/src/crypto/hash-ops.h index ad5a3407a..5e2790a0c 100644 --- a/src/crypto/hash-ops.h +++ b/src/crypto/hash-ops.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/hash.c b/src/crypto/hash.c index 9a628d0bd..d357ae93f 100644 --- a/src/crypto/hash.c +++ b/src/crypto/hash.c @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/hash.h b/src/crypto/hash.h index 7b380c29d..2f91a5358 100644 --- a/src/crypto/hash.h +++ b/src/crypto/hash.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/initializer.h b/src/crypto/initializer.h index 61f75cecd..1d4b77be5 100644 --- a/src/crypto/initializer.h +++ b/src/crypto/initializer.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/random.c b/src/crypto/random.c index 727659e82..6cffda2c0 100644 --- a/src/crypto/random.c +++ b/src/crypto/random.c @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/random.h b/src/crypto/random.h index 85e55fd7d..0f5d8c9b1 100644 --- a/src/crypto/random.h +++ b/src/crypto/random.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/skein_port.h b/src/crypto/skein_port.h index a2a8c45aa..6d25c0a93 100644 --- a/src/crypto/skein_port.h +++ b/src/crypto/skein_port.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/slow-hash.c b/src/crypto/slow-hash.c index 787545830..9b9eecba3 100644 --- a/src/crypto/slow-hash.c +++ b/src/crypto/slow-hash.c @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/crypto/tree-hash.c b/src/crypto/tree-hash.c index 5a84c8688..a75f91b80 100644 --- a/src/crypto/tree-hash.c +++ b/src/crypto/tree-hash.c @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index 1ac8ab328..e26945086 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // @@ -33,6 +33,8 @@ #include #include +#define CRYPTONOTE_DNS_TIMEOUT_MS 20000 + #define CRYPTONOTE_MAX_BLOCK_NUMBER 500000000 #define CRYPTONOTE_MAX_BLOCK_SIZE 500000000 // block header blob limit, never used! #define CRYPTONOTE_GETBLOCKTEMPLATE_MAX_BLOCK_SIZE 196608 //size of block (bytes) that is the maximum that miners will produce @@ -56,8 +58,11 @@ #define CRYPTONOTE_DISPLAY_DECIMAL_POINT 12 // COIN - number of smallest units in one coin #define COIN ((uint64_t)1000000000000) // pow(10, 12) -#define DEFAULT_FEE ((uint64_t)100000000000) // 5 * pow(10, 11) +#define FEE_PER_KB ((uint64_t)10000000000) // pow(10, 10) + +// temporarily to allow backward compatibility during the switch to per-kb +//#define MINING_ALLOWED_LEGACY_FEE ((uint64_t)100000000000) // pow(10, 11) #define ORPHANED_BLOCKS_MAX_COUNT 100 @@ -114,7 +119,7 @@ namespace config { uint64_t const DEFAULT_FEE_ATOMIC_XMR_PER_KB = 500; // Just a placeholder! Change me! uint8_t const FEE_CALCULATION_MAX_RETRIES = 10; - uint64_t const DEFAULT_DUST_THRESHOLD = 5000000000; // 5 * 10^9 + uint64_t const DEFAULT_DUST_THRESHOLD = ((uint64_t)10000000000); // pow(10, 10) std::string const P2P_REMOTE_DEBUG_TRUSTED_PUB_KEY = "0000000000000000000000000000000000000000000000000000000000000000"; uint64_t const CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX = 18; diff --git a/src/cryptonote_core/CMakeLists.txt b/src/cryptonote_core/CMakeLists.txt new file mode 100644 index 000000000..3abf93f3c --- /dev/null +++ b/src/cryptonote_core/CMakeLists.txt @@ -0,0 +1,80 @@ +# Copyright (c) 2014-2015, The Monero Project +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other +# materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be +# used to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set(cryptonote_core_sources + account.cpp + blockchain_storage.cpp + checkpoints.cpp + checkpoints_create.cpp + cryptonote_basic_impl.cpp + cryptonote_core.cpp + cryptonote_format_utils.cpp + difficulty.cpp + miner.cpp + tx_pool.cpp) + +set(cryptonote_core_headers) + +set(cryptonote_core_private_headers + account.h + account_boost_serialization.h + blockchain_storage.h + blockchain_storage_boost_serialization.h + checkpoints.h + checkpoints_create.h + connection_context.h + cryptonote_basic.h + cryptonote_basic_impl.h + cryptonote_boost_serialization.h + cryptonote_core.h + cryptonote_format_utils.h + cryptonote_stat_info.h + difficulty.h + miner.h + tx_extra.h + tx_pool.h + verification_context.h) + +bitmonero_private_headers(cryptonote_core + ${crypto_private_headers}) +bitmonero_add_library(cryptonote_core + ${cryptonote_core_sources} + ${cryptonote_core_headers} + ${cryptonote_core_private_headers}) +target_link_libraries(cryptonote_core + LINK_PUBLIC + common + crypto + ${Boost_DATE_TIME_LIBRARY} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${Boost_SERIALIZATION_LIBRARY} + LINK_PRIVATE + ${Boost_FILESYSTEM_LIBRARY} + ${Boost_SYSTEM_LIBRARY} + ${Boost_THREAD_LIBRARY} + ${EXTRA_LIBRARIES}) diff --git a/src/cryptonote_core/account.cpp b/src/cryptonote_core/account.cpp index 36043238d..a4de8fb25 100644 --- a/src/cryptonote_core/account.cpp +++ b/src/cryptonote_core/account.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // @@ -65,7 +65,7 @@ DISABLE_VS_WARNINGS(4244 4345) // rng for generating second set of keys is hash of first rng. means only one set of electrum-style words needed for recovery crypto::secret_key second; - keccak((uint8_t *)&first, sizeof(crypto::secret_key), (uint8_t *)&second, sizeof(crypto::secret_key)); + keccak((uint8_t *)&m_keys.m_spend_secret_key, sizeof(crypto::secret_key), (uint8_t *)&second, sizeof(crypto::secret_key)); generate_keys(m_keys.m_account_address.m_view_public_key, m_keys.m_view_secret_key, second, two_random ? false : true); diff --git a/src/cryptonote_core/account.h b/src/cryptonote_core/account.h index dd6618542..46f14fcbb 100644 --- a/src/cryptonote_core/account.h +++ b/src/cryptonote_core/account.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/account_boost_serialization.h b/src/cryptonote_core/account_boost_serialization.h index f9ecea895..cddc05e36 100644 --- a/src/cryptonote_core/account_boost_serialization.h +++ b/src/cryptonote_core/account_boost_serialization.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/blockchain_storage.cpp b/src/cryptonote_core/blockchain_storage.cpp index 4cca878db..e2b6f2326 100644 --- a/src/cryptonote_core/blockchain_storage.cpp +++ b/src/cryptonote_core/blockchain_storage.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/blockchain_storage.h b/src/cryptonote_core/blockchain_storage.h index 08c007a4a..1bfdf7bd0 100644 --- a/src/cryptonote_core/blockchain_storage.h +++ b/src/cryptonote_core/blockchain_storage.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/blockchain_storage_boost_serialization.h b/src/cryptonote_core/blockchain_storage_boost_serialization.h index c64ce8e0c..28c06ece1 100644 --- a/src/cryptonote_core/blockchain_storage_boost_serialization.h +++ b/src/cryptonote_core/blockchain_storage_boost_serialization.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/checkpoints.cpp b/src/cryptonote_core/checkpoints.cpp index 6a86302b6..73668ab36 100644 --- a/src/cryptonote_core/checkpoints.cpp +++ b/src/cryptonote_core/checkpoints.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/checkpoints.h b/src/cryptonote_core/checkpoints.h index 132917228..a39ce1964 100644 --- a/src/cryptonote_core/checkpoints.h +++ b/src/cryptonote_core/checkpoints.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/checkpoints_create.cpp b/src/cryptonote_core/checkpoints_create.cpp index 9ad0a27e8..31ae9655b 100644 --- a/src/cryptonote_core/checkpoints_create.cpp +++ b/src/cryptonote_core/checkpoints_create.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/checkpoints_create.h b/src/cryptonote_core/checkpoints_create.h index 92a970e9f..569d437cf 100644 --- a/src/cryptonote_core/checkpoints_create.h +++ b/src/cryptonote_core/checkpoints_create.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/connection_context.h b/src/cryptonote_core/connection_context.h index 6574e92e6..7d40bc2e9 100644 --- a/src/cryptonote_core/connection_context.h +++ b/src/cryptonote_core/connection_context.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/cryptonote_basic.h b/src/cryptonote_core/cryptonote_basic.h index dfdfa03e5..f50a19f9e 100644 --- a/src/cryptonote_core/cryptonote_basic.h +++ b/src/cryptonote_core/cryptonote_basic.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/cryptonote_basic_impl.cpp b/src/cryptonote_core/cryptonote_basic_impl.cpp index 9cec666f2..a7416a7e4 100644 --- a/src/cryptonote_core/cryptonote_basic_impl.cpp +++ b/src/cryptonote_core/cryptonote_basic_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/cryptonote_basic_impl.h b/src/cryptonote_core/cryptonote_basic_impl.h index ddef677cb..5c773c4e1 100644 --- a/src/cryptonote_core/cryptonote_basic_impl.h +++ b/src/cryptonote_core/cryptonote_basic_impl.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/cryptonote_boost_serialization.h b/src/cryptonote_core/cryptonote_boost_serialization.h index e3ccb7c32..17face4bd 100644 --- a/src/cryptonote_core/cryptonote_boost_serialization.h +++ b/src/cryptonote_core/cryptonote_boost_serialization.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index d9d8a7faf..b8b5dc008 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index 10522451c..748f2b665 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/cryptonote_format_utils.cpp b/src/cryptonote_core/cryptonote_format_utils.cpp index 33cad30c4..1b21894a0 100644 --- a/src/cryptonote_core/cryptonote_format_utils.cpp +++ b/src/cryptonote_core/cryptonote_format_utils.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // @@ -107,7 +107,7 @@ namespace cryptonote block_reward += fee; std::vector out_amounts; - decompose_amount_into_digits(block_reward, DEFAULT_FEE, + decompose_amount_into_digits(block_reward, ::config::DEFAULT_DUST_THRESHOLD, [&out_amounts](uint64_t a_chunk) { out_amounts.push_back(a_chunk); }, [&out_amounts](uint64_t a_dust) { out_amounts.push_back(a_dust); }); diff --git a/src/cryptonote_core/cryptonote_format_utils.h b/src/cryptonote_core/cryptonote_format_utils.h index 9fa7f0545..fd785aafd 100644 --- a/src/cryptonote_core/cryptonote_format_utils.h +++ b/src/cryptonote_core/cryptonote_format_utils.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/cryptonote_stat_info.h b/src/cryptonote_core/cryptonote_stat_info.h index 5d0d1769d..20bbe382e 100644 --- a/src/cryptonote_core/cryptonote_stat_info.h +++ b/src/cryptonote_core/cryptonote_stat_info.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/difficulty.cpp b/src/cryptonote_core/difficulty.cpp index d4d733e69..106520440 100644 --- a/src/cryptonote_core/difficulty.cpp +++ b/src/cryptonote_core/difficulty.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/difficulty.h b/src/cryptonote_core/difficulty.h index 99c9228f0..42d2df500 100644 --- a/src/cryptonote_core/difficulty.h +++ b/src/cryptonote_core/difficulty.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/miner.cpp b/src/cryptonote_core/miner.cpp index b2adfe39c..b99113d9e 100644 --- a/src/cryptonote_core/miner.cpp +++ b/src/cryptonote_core/miner.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/miner.h b/src/cryptonote_core/miner.h index 44844428c..7ada8171f 100644 --- a/src/cryptonote_core/miner.h +++ b/src/cryptonote_core/miner.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/tx_extra.h b/src/cryptonote_core/tx_extra.h index af91deca5..ccfe4d1d9 100644 --- a/src/cryptonote_core/tx_extra.h +++ b/src/cryptonote_core/tx_extra.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index 81f932014..691d16492 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // @@ -86,9 +86,12 @@ namespace cryptonote } uint64_t fee = inputs_amount - outputs_amount; - if (!kept_by_block && fee < DEFAULT_FEE) + uint64_t needed_fee = blob_size / 1024; + needed_fee += (blob_size % 1024) ? 1 : 0; + needed_fee *= FEE_PER_KB; + if (!kept_by_block && fee < needed_fee /*&& fee < MINING_ALLOWED_LEGACY_FEE*/) { - LOG_PRINT_L1("transaction fee is not enough: " << print_money(fee) << ", minumim fee: " << print_money(DEFAULT_FEE)); + LOG_PRINT_L1("transaction fee is not enough: " << print_money(fee) << ", minumim fee: " << print_money(needed_fee)); tvc.m_verifivation_failed = true; return false; } diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h index 7617765cc..9c1c2b1aa 100644 --- a/src/cryptonote_core/tx_pool.h +++ b/src/cryptonote_core/tx_pool.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_core/verification_context.h b/src/cryptonote_core/verification_context.h index 3be45907b..c467d35f3 100644 --- a/src/cryptonote_core/verification_context.h +++ b/src/cryptonote_core/verification_context.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_protocol/blobdatatype.h b/src/cryptonote_protocol/blobdatatype.h index 7cde6bdb3..063f08ef0 100644 --- a/src/cryptonote_protocol/blobdatatype.h +++ b/src/cryptonote_protocol/blobdatatype.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_protocol/cryptonote_protocol_defs.h b/src/cryptonote_protocol/cryptonote_protocol_defs.h index 66fa43dd2..f761274c5 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_defs.h +++ b/src/cryptonote_protocol/cryptonote_protocol_defs.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.h b/src/cryptonote_protocol/cryptonote_protocol_handler.h index 0e1a6f1b3..a3b79856e 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.h +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index 19ad74368..2754eb73c 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler_common.h b/src/cryptonote_protocol/cryptonote_protocol_handler_common.h index 4532645ce..9ccf6aa56 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler_common.h +++ b/src/cryptonote_protocol/cryptonote_protocol_handler_common.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt new file mode 100644 index 000000000..03fdf84be --- /dev/null +++ b/src/daemon/CMakeLists.txt @@ -0,0 +1,79 @@ +# Copyright (c) 2014-2015, The Monero Project +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other +# materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be +# used to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set(daemon_sources + daemon.cpp) + +set(daemon_headers) + +set(daemon_private_headers + daemon_commands_handler.h + + # cryptonote_protocol + ../cryptonote_protocol/blobdatatype.h + ../cryptonote_protocol/cryptonote_protocol_defs.h + ../cryptonote_protocol/cryptonote_protocol_handler.h + ../cryptonote_protocol/cryptonote_protocol_handler.inl + ../cryptonote_protocol/cryptonote_protocol_handler_common.h + + # p2p + ../p2p/net_node.h + ../p2p/net_node.inl + ../p2p/net_node_common.h + ../p2p/net_peerlist.h + ../p2p/net_peerlist_boost_serialization.h + ../p2p/p2p_protocol_defs.h + ../p2p/stdafx.h) + +bitmonero_private_headers(daemon + ${daemon_private_headers}) +bitmonero_add_executable(daemon + ${daemon_sources} + ${daemon_headers} + ${daemon_private_headers}) +target_link_libraries(daemon + LINK_PRIVATE + rpc + cryptonote_core + crypto + common + ${Boost_CHRONO_LIBRARY} + ${Boost_FILESYSTEM_LIBRARY} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${Boost_REGEX_LIBRARY} + ${Boost_SYSTEM_LIBRARY} + ${Boost_THREAD_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${UPNP_LIBRARIES} + ${EXTRA_LIBRARIES} + ${NET_SKELETON_LIBRARY}) +add_dependencies(daemon + version) +set_property(TARGET daemon + PROPERTY + OUTPUT_NAME "bitmonerod") diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index 7a72bd7ad..8fc1b5874 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/daemon/daemon_commands_handler.h b/src/daemon/daemon_commands_handler.h index 869c2adf7..10a07cf89 100644 --- a/src/daemon/daemon_commands_handler.h +++ b/src/daemon/daemon_commands_handler.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/miner/CMakeLists.txt b/src/miner/CMakeLists.txt new file mode 100644 index 000000000..2a55c88f7 --- /dev/null +++ b/src/miner/CMakeLists.txt @@ -0,0 +1,55 @@ +# Copyright (c) 2014-2015, The Monero Project +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other +# materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be +# used to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set(simpleminer_sources + simpleminer.cpp) + +set(simpleminer_headers) + +set(simpleminer_private_headers + simpleminer.h + simpleminer_protocol_defs.h + target_helper.h) + +bitmonero_private_headers(simpleminer + ${simpleminer_private_headers}) +bitmonero_add_executable(simpleminer + ${simpleminer_sources} + ${simpleminer_headers} + ${simpleminer_private_headers}) +target_link_libraries(simpleminer + LINK_PRIVATE + cryptonote_core + common + ${Boost_FILESYSTEM_LIBRARY} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${Boost_REGEX_LIBRARY} + ${Boost_SYSTEM_LIBRARY} + ${Boost_THREAD_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${EXTRA_LIBRARIES}) diff --git a/src/miner/simpleminer.cpp b/src/miner/simpleminer.cpp index 3223bdd50..fafe6b3f3 100644 --- a/src/miner/simpleminer.cpp +++ b/src/miner/simpleminer.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/miner/simpleminer.h b/src/miner/simpleminer.h index f6897e20e..9b8e84b3e 100644 --- a/src/miner/simpleminer.h +++ b/src/miner/simpleminer.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/miner/simpleminer_protocol_defs.h b/src/miner/simpleminer_protocol_defs.h index 22ea958e7..c63246578 100644 --- a/src/miner/simpleminer_protocol_defs.h +++ b/src/miner/simpleminer_protocol_defs.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/miner/target_helper.h b/src/miner/target_helper.h index 723d61a3c..0214b8038 100644 --- a/src/miner/target_helper.h +++ b/src/miner/target_helper.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/mnemonics/CMakeLists.txt b/src/mnemonics/CMakeLists.txt new file mode 100644 index 000000000..ce9520956 --- /dev/null +++ b/src/mnemonics/CMakeLists.txt @@ -0,0 +1,52 @@ +# Copyright (c) 2014-2015, The Monero Project +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other +# materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be +# used to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set(mnemonics_sources + electrum-words.cpp) + +set(mnemonics_headers) + +set(mnemonics_private_headers + electrum-words.h + english.h + japanese.h + language_base.h + old_english.h + portuguese.h + singleton.h + spanish.h) + +bitmonero_private_headers(mnemonics + ${mnemonics_private_headers}) +bitmonero_add_library(mnemonics + ${mnemonics_sources} + ${mnemonics_headers} + ${mnemonics_private_headers}) +target_link_libraries(mnemonics + LINK_PRIVATE + ${Boost_SYSTEM_LIBRARY}) diff --git a/src/mnemonics/electrum-words.cpp b/src/mnemonics/electrum-words.cpp index ffa82b21e..590320550 100644 --- a/src/mnemonics/electrum-words.cpp +++ b/src/mnemonics/electrum-words.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // @@ -255,7 +255,7 @@ namespace crypto std::string wlist_copy = words; if (seed.size() == seed_length/2) { - memcpy(dst.data, dst.data + 16, 16); // if electrum 12-word seed, duplicate + memcpy(dst.data+16, dst.data, 16); // if electrum 12-word seed, duplicate wlist_copy += ' '; wlist_copy += words; } @@ -328,7 +328,7 @@ namespace crypto words.pop_back(); words += (' ' + words_store[create_checksum_index(words_store, language->get_unique_prefix_length())]); - return false; + return true; } /*! diff --git a/src/mnemonics/electrum-words.h b/src/mnemonics/electrum-words.h index b75de30e9..5cde7fb02 100644 --- a/src/mnemonics/electrum-words.h +++ b/src/mnemonics/electrum-words.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/mnemonics/english.h b/src/mnemonics/english.h index 8ca0a3fe3..e70849fda 100644 --- a/src/mnemonics/english.h +++ b/src/mnemonics/english.h @@ -1,6 +1,6 @@ // Word list originally created as part of the Electrum project, Copyright (C) 2014 Thomas Voegtlin // -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/mnemonics/japanese.h b/src/mnemonics/japanese.h index fc3d1ee74..5f7adce18 100644 --- a/src/mnemonics/japanese.h +++ b/src/mnemonics/japanese.h @@ -1,6 +1,6 @@ // Word list originally created by dabura667 // -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/mnemonics/language_base.h b/src/mnemonics/language_base.h index 06815e39d..0e7d60a02 100644 --- a/src/mnemonics/language_base.h +++ b/src/mnemonics/language_base.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/mnemonics/old_english.h b/src/mnemonics/old_english.h index b91a593b6..f7974f4d5 100644 --- a/src/mnemonics/old_english.h +++ b/src/mnemonics/old_english.h @@ -1,6 +1,6 @@ // Word list originally created as part of the Electrum project, Copyright (C) 2014 Thomas Voegtlin // -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/mnemonics/portuguese.h b/src/mnemonics/portuguese.h index 6a90659e0..f60991a4d 100644 --- a/src/mnemonics/portuguese.h +++ b/src/mnemonics/portuguese.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/mnemonics/singleton.h b/src/mnemonics/singleton.h index 74e121e4e..ab4e95cf2 100644 --- a/src/mnemonics/singleton.h +++ b/src/mnemonics/singleton.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/mnemonics/spanish.h b/src/mnemonics/spanish.h index f71627086..b638ec1b0 100644 --- a/src/mnemonics/spanish.h +++ b/src/mnemonics/spanish.h @@ -1,6 +1,6 @@ // Word list originally created as part of the Electrum project, Copyright (C) 2014 Thomas Voegtlin // -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // @@ -1690,4 +1690,4 @@ namespace Language }; } -#endif \ No newline at end of file +#endif diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h index 53a13f327..97fcd56c8 100644 --- a/src/p2p/net_node.h +++ b/src/p2p/net_node.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 01fbaa497..3454e112c 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // @@ -31,6 +31,9 @@ #pragma once #include +#include +#include +#include #include "version.h" #include "string_tools.h" @@ -46,13 +49,13 @@ // We have to look for miniupnpc headers in different places, dependent on if its compiled or external #ifdef UPNP_STATIC - #include - #include - #include + #include + #include + #include #else - #include "miniupnpc.h" - #include "upnpcommands.h" - #include "upnperrors.h" + #include "miniupnpc.h" + #include "upnpcommands.h" + #include "upnperrors.h" #endif #define NET_MAKE_IP(b1,b2,b3,b4) ((LPARAM)(((DWORD)(b1)<<24)+((DWORD)(b2)<<16)+((DWORD)(b3)<<8)+((DWORD)(b4)))) @@ -252,19 +255,62 @@ namespace nodetool // add the result addresses as seed nodes // TODO: at some point add IPv6 support, but that won't be relevant // for some time yet. + + std::vector> dns_results; + dns_results.resize(m_seed_nodes_list.size()); + + std::unique_ptr dns_finished(new std::atomic_flag[m_seed_nodes_list.size()]); + + // set each flag, thread will release when finished + for (uint64_t i = 0; i < m_seed_nodes_list.size(); ++i) + dns_finished[i].test_and_set(); + + uint64_t result_index = 0; for (const std::string& addr_str : m_seed_nodes_list) { - // TODO: care about dnssec avail/valid - bool avail, valid; - std::vector addr_list = tools::DNSResolver::instance().get_ipv4(addr_str, avail, valid); - for (const std::string& a : addr_list) + + uint64_t result_index_capture = result_index++; + boost::thread t([&] { - append_net_address(m_seed_nodes, a + ":18080"); + // TODO: care about dnssec avail/valid + bool avail, valid; + std::vector addr_list = tools::DNSResolver().get_ipv4(addr_str, avail, valid); + + dns_results[result_index_capture] = addr_list; + dns_finished[result_index_capture].clear(); + }); + + } + + uint64_t sleep_count = 0; + uint64_t sleep_interval_ms = 100; + while (sleep_count++ * sleep_interval_ms < CRYPTONOTE_DNS_TIMEOUT_MS) + { + boost::this_thread::sleep(boost::posix_time::milliseconds(sleep_interval_ms)); + bool all_done = false; + for (uint64_t i = 0; i < m_seed_nodes_list.size(); ++i) + { + if (dns_finished[i].test_and_set()) + break; + else + dns_finished[i].clear(); + all_done = true; + } + if (all_done) + break; + } + + for (const auto& result : dns_results) + { + for (const auto& addr_string : result) + { + append_net_address(m_seed_nodes, addr_string + ":18080"); } } if (!m_seed_nodes.size()) { + LOG_PRINT_L0("DNS seed node lookup either timed out or failed, falling back to defaults"); append_net_address(m_seed_nodes, "62.210.78.186:18080"); append_net_address(m_seed_nodes, "195.12.60.154:18080"); append_net_address(m_seed_nodes, "54.241.246.125:18080"); diff --git a/src/p2p/net_node_common.h b/src/p2p/net_node_common.h index 6559963e0..a7b8bf6f3 100644 --- a/src/p2p/net_node_common.h +++ b/src/p2p/net_node_common.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/p2p/net_peerlist.h b/src/p2p/net_peerlist.h index e3e387bbc..9407e7bce 100644 --- a/src/p2p/net_peerlist.h +++ b/src/p2p/net_peerlist.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/p2p/net_peerlist_boost_serialization.h b/src/p2p/net_peerlist_boost_serialization.h index 17525e8fe..d0bd44ef0 100644 --- a/src/p2p/net_peerlist_boost_serialization.h +++ b/src/p2p/net_peerlist_boost_serialization.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/p2p/p2p_protocol_defs.h b/src/p2p/p2p_protocol_defs.h index 44b8c5b50..e157f3188 100644 --- a/src/p2p/p2p_protocol_defs.h +++ b/src/p2p/p2p_protocol_defs.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/p2p/stdafx.h b/src/p2p/stdafx.h index ede53d517..da1216924 100644 --- a/src/p2p/stdafx.h +++ b/src/p2p/stdafx.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/platform/mingw/alloca.h b/src/platform/mingw/alloca.h index 32589db06..868db1af4 100644 --- a/src/platform/mingw/alloca.h +++ b/src/platform/mingw/alloca.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/platform/msc/alloca.h b/src/platform/msc/alloca.h index 82186553b..c212d64b9 100644 --- a/src/platform/msc/alloca.h +++ b/src/platform/msc/alloca.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/platform/msc/inline_c.h b/src/platform/msc/inline_c.h index a016b783e..fa4fd48f3 100644 --- a/src/platform/msc/inline_c.h +++ b/src/platform/msc/inline_c.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/platform/msc/stdbool.h b/src/platform/msc/stdbool.h index 1044d2539..e3c932ccf 100644 --- a/src/platform/msc/stdbool.h +++ b/src/platform/msc/stdbool.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/platform/msc/sys/param.h b/src/platform/msc/sys/param.h index 07a036a6e..0db360ab0 100644 --- a/src/platform/msc/sys/param.h +++ b/src/platform/msc/sys/param.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/rpc/CMakeLists.txt b/src/rpc/CMakeLists.txt new file mode 100644 index 000000000..cc4422fc8 --- /dev/null +++ b/src/rpc/CMakeLists.txt @@ -0,0 +1,56 @@ +# Copyright (c) 2014-2015, The Monero Project +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other +# materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be +# used to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set(rpc_sources + core_rpc_server.cpp + json_rpc_http_server.cpp + daemon_json_rpc_handlers.cpp) + +set(rpc_headers) + +set(rpc_private_headers + core_rpc_server.h + core_rpc_server_commands_defs.h + core_rpc_server_error_codes.h) + +bitmonero_private_headers(rpc + ${rpc_private_headers}) +bitmonero_add_library(rpc + ${rpc_sources} + ${rpc_headers} + ${rpc_private_headers}) +target_link_libraries(rpc + LINK_PRIVATE + cryptonote_core + ${Boost_CHRONO_LIBRARY} + ${Boost_REGEX_LIBRARY} + ${Boost_SYSTEM_LIBRARY} + ${Boost_THREAD_LIBRARY} + ${EXTRA_LIBRARIES}) +add_dependencies(rpc + version) diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 4d089f2f7..02bdb26e9 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // @@ -474,6 +474,7 @@ namespace cryptonote LOG_ERROR("Failed to calculate offset for "); return false; } + res.prev_hash = string_tools::pod_to_hex(b.prev_id); res.blocktemplate_blob = string_tools::buff_to_hex_nodelimer(block_blob); res.status = CORE_RPC_STATUS_OK; return true; diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index 02bc533c9..cd9a0f162 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index d711e1732..9fea933cb 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // @@ -383,6 +383,7 @@ namespace cryptonote uint64_t difficulty; uint64_t height; uint64_t reserved_offset; + std::string prev_hash; blobdata blocktemplate_blob; std::string status; @@ -390,6 +391,7 @@ namespace cryptonote KV_SERIALIZE(difficulty) KV_SERIALIZE(height) KV_SERIALIZE(reserved_offset) + KV_SERIALIZE(prev_hash) KV_SERIALIZE(blocktemplate_blob) KV_SERIALIZE(status) END_KV_SERIALIZE_MAP() diff --git a/src/rpc/core_rpc_server_error_codes.h b/src/rpc/core_rpc_server_error_codes.h index ab6ca9aef..91659eb2a 100644 --- a/src/rpc/core_rpc_server_error_codes.h +++ b/src/rpc/core_rpc_server_error_codes.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/serialization/binary_archive.h b/src/serialization/binary_archive.h index 56c94684e..6e00ad664 100644 --- a/src/serialization/binary_archive.h +++ b/src/serialization/binary_archive.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/serialization/binary_utils.h b/src/serialization/binary_utils.h index f2cfadd4e..4fe782326 100644 --- a/src/serialization/binary_utils.h +++ b/src/serialization/binary_utils.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/serialization/crypto.h b/src/serialization/crypto.h index 8986d8081..f18e85b12 100644 --- a/src/serialization/crypto.h +++ b/src/serialization/crypto.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/serialization/debug_archive.h b/src/serialization/debug_archive.h index 127e57ed6..4d697c14c 100644 --- a/src/serialization/debug_archive.h +++ b/src/serialization/debug_archive.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/serialization/json_archive.h b/src/serialization/json_archive.h index bd8b16130..49bbf95b6 100644 --- a/src/serialization/json_archive.h +++ b/src/serialization/json_archive.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/serialization/json_utils.h b/src/serialization/json_utils.h index 64f9f946f..462d1f8e7 100644 --- a/src/serialization/json_utils.h +++ b/src/serialization/json_utils.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/serialization/serialization.h b/src/serialization/serialization.h index 9e534cbc6..c94c99336 100644 --- a/src/serialization/serialization.h +++ b/src/serialization/serialization.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/serialization/string.h b/src/serialization/string.h index 077f657d2..0f1b0d4e0 100644 --- a/src/serialization/string.h +++ b/src/serialization/string.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/serialization/variant.h b/src/serialization/variant.h index 9b5d54237..9efa9c346 100644 --- a/src/serialization/variant.h +++ b/src/serialization/variant.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/serialization/vector.h b/src/serialization/vector.h index a099ce070..3787f00e6 100644 --- a/src/serialization/vector.h +++ b/src/serialization/vector.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/simplewallet/CMakeLists.txt b/src/simplewallet/CMakeLists.txt new file mode 100644 index 000000000..9df23c3cf --- /dev/null +++ b/src/simplewallet/CMakeLists.txt @@ -0,0 +1,59 @@ +# Copyright (c) 2014-2015, The Monero Project +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other +# materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be +# used to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set(simplewallet_sources + simplewallet.cpp + password_container.cpp) + +set(simplewallet_headers) + +set(simplewallet_private_headers + simplewallet.h + password_container.h) + +bitmonero_private_headers(simplewallet + ${simplewallet_private_headers}) +bitmonero_add_executable(simplewallet + ${simplewallet_sources} + ${simplewallet_headers} + ${simplewallet_private_headers}) +target_link_libraries(simplewallet + LINK_PRIVATE + wallet + rpc + cryptonote_core + crypto + common + mnemonics + ${UNBOUND_LIBRARY} + ${UPNP_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} + ${EXTRA_LIBRARIES} + ${NET_SKELETON_LIBRARY}) +add_dependencies(simplewallet + version) diff --git a/src/simplewallet/password_container.cpp b/src/simplewallet/password_container.cpp index 1c4aee453..e5fb933bb 100644 --- a/src/simplewallet/password_container.cpp +++ b/src/simplewallet/password_container.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/simplewallet/password_container.h b/src/simplewallet/password_container.h index b39fa1fe4..8a4191c7a 100644 --- a/src/simplewallet/password_container.h +++ b/src/simplewallet/password_container.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 7ce2b647f..af018afb5 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // @@ -208,23 +208,61 @@ bool simple_wallet::viewkey(const std::vector &args/* = std::vector bool simple_wallet::seed(const std::vector &args/* = std::vector()*/) { + bool success = false; std::string electrum_words; - bool success = m_wallet->get_seed(electrum_words); - + + if (m_wallet->is_deterministic()) + { + if (m_wallet->get_seed_language().empty()) + { + std::string mnemonic_language = get_mnemonic_language(); + m_wallet->set_seed_language(mnemonic_language); + } + + success = m_wallet->get_seed(electrum_words); + } + if (success) { - success_msg_writer(true) << "\nPLEASE NOTE: the following 25 words can be used to recover access to your wallet. Please write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control.\n"; - boost::replace_nth(electrum_words, " ", 15, "\n"); - boost::replace_nth(electrum_words, " ", 7, "\n"); - std::cout << electrum_words << std::endl; + print_seed(electrum_words); } else { - fail_msg_writer() << "The wallet is non-deterministic. Cannot display seed."; + fail_msg_writer() << "The wallet is non-deterministic. Cannot display seed."; } return true; } +bool simple_wallet::seed_set_language(const std::vector &args/* = std::vector()*/) +{ + bool success = false; + if (!m_wallet->is_deterministic()) + { + fail_msg_writer() << "This wallet is non-deterministic and doesn't have a seed."; + return true; + } + tools::password_container pwd_container; + success = pwd_container.read_password(); + if (!success) + { + fail_msg_writer() << "failed to read wallet password"; + return true; + } + + /* verify password before using so user doesn't accidentally set a new password for rewritten wallet */ + success = m_wallet->verify_password(pwd_container.password()); + if (!success) + { + fail_msg_writer() << "invalid password"; + return true; + } + + std::string mnemonic_language = get_mnemonic_language(); + m_wallet->set_seed_language(mnemonic_language); + m_wallet->rewrite(m_wallet_file, pwd_container.password()); + return true; +} + bool simple_wallet::help(const std::vector &args/* = std::vector()*/) { success_msg_writer() << get_commands_str(); @@ -249,9 +287,39 @@ simple_wallet::simple_wallet() m_cmd_binder.set_handler("save", boost::bind(&simple_wallet::save, this, _1), "Save wallet synchronized data"); m_cmd_binder.set_handler("viewkey", boost::bind(&simple_wallet::viewkey, this, _1), "Get viewkey"); m_cmd_binder.set_handler("seed", boost::bind(&simple_wallet::seed, this, _1), "Get deterministic seed"); + m_cmd_binder.set_handler("set", boost::bind(&simple_wallet::set_variable, this, _1), "available options: seed language - Set wallet seed langage"); m_cmd_binder.set_handler("help", boost::bind(&simple_wallet::help, this, _1), "Show this help"); } //---------------------------------------------------------------------------------------------------- +bool simple_wallet::set_variable(const std::vector &args) +{ + if (args.empty()) + { + fail_msg_writer() << "set: needs an argument. available options: seed"; + return true; + } + else + { + if (args[0] == "seed") + { + if (args.size() == 1) + { + fail_msg_writer() << "set seed: needs an argument. available options: language"; + return true; + } + else if (args[1] == "language") + { + std::vector local_args = args; + local_args.erase(local_args.begin(), local_args.begin()+2); + seed_set_language(local_args); + return true; + } + } + } + fail_msg_writer() << "set: unrecognized argument(s)"; + return true; +} +//---------------------------------------------------------------------------------------------------- bool simple_wallet::set_log(const std::vector &args) { if(args.size() != 1) @@ -279,14 +347,28 @@ bool simple_wallet::ask_wallet_create_if_needed() { std::string wallet_path; - wallet_path = command_line::input_line( - "Specify wallet file name (e.g., wallet.bin). If the wallet doesn't exist, it will be created.\n" - "Wallet file name: " - ); + bool valid_path = false; + do { + wallet_path = command_line::input_line( + "Specify wallet file name (e.g., wallet.bin). If the wallet doesn't exist, it will be created.\n" + "Wallet file name: " + ); + valid_path = tools::wallet2::wallet_valid_path_format(wallet_path); + if (!valid_path) + { + fail_msg_writer() << "wallet file path not valid: " << wallet_path; + } + } + while (!valid_path); bool keys_file_exists; bool wallet_file_exists; tools::wallet2::wallet_exists(wallet_path, keys_file_exists, wallet_file_exists); + LOG_PRINT_L3("wallet_path: " << wallet_path << ""); + LOG_PRINT_L3("keys_file_exists: " << std::boolalpha << keys_file_exists << std::noboolalpha + << " wallet_file_exists: " << std::boolalpha << wallet_file_exists << std::noboolalpha); + + LOG_PRINT_L1("Loading wallet..."); // add logic to error out if new wallet requested but named wallet file exists if (keys_file_exists || wallet_file_exists) @@ -319,6 +401,21 @@ bool simple_wallet::ask_wallet_create_if_needed() return r; } + +/*! + * \brief Prints the seed with a nice message + * \param seed seed to print + */ +void simple_wallet::print_seed(std::string seed) +{ + success_msg_writer(true) << "\nPLEASE NOTE: the following 25 words can be used to recover access to your wallet. " << + "Please write them down and store them somewhere safe and secure. Please do not store them in " << + "your email or on file storage services outside of your immediate control.\n"; + boost::replace_nth(seed, " ", 15, "\n"); + boost::replace_nth(seed, " ", 7, "\n"); + std::cout << seed << std::endl; +} + //---------------------------------------------------------------------------------------------------- bool simple_wallet::init(const boost::program_options::variables_map& vm) { @@ -487,10 +584,30 @@ std::string simple_wallet::get_mnemonic_language() bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string& password, const crypto::secret_key& recovery_key, bool recover, bool two_random, bool testnet, const std::string &old_language) { + bool was_deprecated_wallet = m_restore_deterministic_wallet && ((old_language == crypto::ElectrumWords::old_language_name) || + crypto::ElectrumWords::get_is_old_style_seed(m_electrum_seed)); + + std::string mnemonic_language = old_language; + // Ask for seed language if: + // it's a deterministic wallet AND + // (it is not a wallet restore OR if it was a deprecated wallet + // that was earlier used before this restore) + if ((!two_random) && (!m_restore_deterministic_wallet || was_deprecated_wallet)) + { + if (was_deprecated_wallet) + { + // The user had used an older version of the wallet with old style mnemonics. + message_writer(epee::log_space::console_color_green, false) << "\nYou had been using " << + "a deprecated version of the wallet. Please use the new seed that we provide.\n"; + } + mnemonic_language = get_mnemonic_language(); + } + m_wallet_file = wallet_file; m_wallet.reset(new tools::wallet2(testnet)); m_wallet->callback(this); + m_wallet->set_seed_language(mnemonic_language); crypto::secret_key recovery_val; try @@ -511,27 +628,7 @@ bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string // convert rng value to electrum-style word list std::string electrum_words; - bool was_deprecated_wallet = (old_language == crypto::ElectrumWords::old_language_name) || - crypto::ElectrumWords::get_is_old_style_seed(m_electrum_seed); - - std::string mnemonic_language = old_language; - // Ask for seed language if it is not a wallet restore or if it was a deprecated wallet - // that was earlier used before this restore. - if (!m_restore_deterministic_wallet || was_deprecated_wallet) - { - if (was_deprecated_wallet) - { - // The user had used an older version of the wallet with old style mnemonics. - message_writer(epee::log_space::console_color_green, false) << "\nYou had been using " << - "a deprecated version of the wallet. Please use the new seed that we provide.\n"; - } - mnemonic_language = get_mnemonic_language(); - } crypto::ElectrumWords::bytes_to_words(recovery_val, electrum_words, mnemonic_language); - m_wallet->set_seed_language(mnemonic_language); - - std::string print_electrum = ""; - success_msg_writer() << "**********************************************************************\n" << @@ -545,10 +642,7 @@ bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string if (!two_random) { - success_msg_writer(true) << "\nPLEASE NOTE: the following 25 words can be used to recover access to your wallet. Please write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control.\n"; - boost::replace_nth(electrum_words, " ", 15, "\n"); - boost::replace_nth(electrum_words, " ", 7, "\n"); - std::cout << electrum_words << std::endl; + print_seed(electrum_words); } success_msg_writer() << "**********************************************************************"; @@ -557,6 +651,12 @@ bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string //---------------------------------------------------------------------------------------------------- bool simple_wallet::open_wallet(const string &wallet_file, const std::string& password, bool testnet) { + if (!tools::wallet2::wallet_valid_path_format(wallet_file)) + { + fail_msg_writer() << "wallet file path not valid: " << wallet_file; + return false; + } + m_wallet_file = wallet_file; m_wallet.reset(new tools::wallet2(testnet)); m_wallet->callback(this); @@ -566,6 +666,31 @@ bool simple_wallet::open_wallet(const string &wallet_file, const std::string& pa m_wallet->load(m_wallet_file, password); message_writer(epee::log_space::console_color_white, true) << "Opened wallet: " << m_wallet->get_account().get_public_address_str(m_wallet->testnet()); + // If the wallet file is deprecated, we should ask for mnemonic language again and store + // everything in the new format. + // NOTE: this is_deprecated() refers to the wallet file format before becoming JSON. It does not refer to the "old english" seed words form of "deprecated" used elsewhere. + if (m_wallet->is_deprecated()) + { + if (m_wallet->is_deterministic()) + { + message_writer(epee::log_space::console_color_green, false) << "\nYou had been using " << + "a deprecated version of the wallet. Please proceed to upgrade your wallet.\n"; + std::string mnemonic_language = get_mnemonic_language(); + m_wallet->set_seed_language(mnemonic_language); + m_wallet->rewrite(m_wallet_file, password); + + // Display the seed + std::string seed; + m_wallet->get_seed(seed); + print_seed(seed); + } + else + { + message_writer(epee::log_space::console_color_green, false) << "\nYou had been using " << + "a deprecated version of the wallet. Your wallet file format is being upgraded now.\n"; + m_wallet->rewrite(m_wallet_file, password); + } + } } catch (const std::exception& e) { @@ -1056,15 +1181,14 @@ bool simple_wallet::transfer(const std::vector &args_) try { // figure out what tx will be necessary - auto ptx_vector = m_wallet->create_transactions(dsts, fake_outs_count, 0 /* unlock_time */, DEFAULT_FEE, extra); + auto ptx_vector = m_wallet->create_transactions(dsts, fake_outs_count, 0 /* unlock_time */, 0 /* unused fee arg*/, extra); // if more than one tx necessary, prompt user to confirm if (ptx_vector.size() > 1) { std::string prompt_str = "Your transaction needs to be split into "; prompt_str += std::to_string(ptx_vector.size()); - prompt_str += " transactions. This will result in a fee of "; - prompt_str += print_money(ptx_vector.size() * DEFAULT_FEE); + prompt_str += " transactions. This will result in a transaction fee being applied to each transaction"; prompt_str += ". Is this okay? (Y/Yes/N/No)"; std::string accepted = command_line::input_line(prompt_str); if (accepted != "Y" && accepted != "y" && accepted != "Yes" && accepted != "yes") diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index af6d4172a..a8fe78414 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // @@ -81,6 +81,17 @@ namespace cryptonote bool viewkey(const std::vector &args = std::vector()); bool seed(const std::vector &args = std::vector()); + + /*! + * \brief Sets seed language. + * + * interactive + * - prompts for password so wallet can be rewritten + * - calls get_mnemonic_language() which prompts for language + * + * \return success status + */ + bool seed_set_language(const std::vector &args = std::vector()); bool help(const std::vector &args = std::vector()); bool start_mining(const std::vector &args); bool stop_mining(const std::vector &args); @@ -96,11 +107,17 @@ namespace cryptonote ); bool print_address(const std::vector &args = std::vector()); bool save(const std::vector &args); + bool set_variable(const std::vector &args); bool set_log(const std::vector &args); uint64_t get_daemon_blockchain_height(std::string& err); bool try_connect_to_daemon(); bool ask_wallet_create_if_needed(); + /*! + * \brief Prints the seed with a nice message + * \param seed seed to print + */ + void print_seed(std::string seed); /*! * \brief Gets the word seed language from the user. diff --git a/src/version.cmake b/src/version.cmake index 2f3aa0b25..ef4eb1fc9 100644 --- a/src/version.cmake +++ b/src/version.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2014, The Monero Project +# Copyright (c) 2014-2015, The Monero Project # # All rights reserved. # @@ -68,7 +68,7 @@ else() message(STATUS "The most recent tag was at ${TAGGEDCOMMIT}") # Check if we're building that tagged commit or a different one - if(${COMMIT} MATCHES ${TAGGEDCOMMIT}) + if(COMMIT STREQUAL TAGGEDCOMMIT) message(STATUS "You are building a tagged release") set(VERSIONTAG "release") else() @@ -80,4 +80,4 @@ else() endif() configure_file("src/version.h.in" "${TO}") -endif() \ No newline at end of file +endif() diff --git a/src/version.h.in b/src/version.h.in index 9862431de..6dd62faf9 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -1,3 +1,3 @@ #define MONERO_VERSION_TAG "@VERSIONTAG@" -#define MONERO_VERSION "0.8.8.4" +#define MONERO_VERSION "0.8.8.7" #define MONERO_VERSION_FULL MONERO_VERSION "-" MONERO_VERSION_TAG diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt new file mode 100644 index 000000000..6107e2136 --- /dev/null +++ b/src/wallet/CMakeLists.txt @@ -0,0 +1,57 @@ +# Copyright (c) 2014-2015, The Monero Project +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other +# materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be +# used to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set(wallet_sources + wallet2.cpp + wallet_rpc_server.cpp + wallet_json_rpc_handlers.cpp) + +set(wallet_headers) + +set(wallet_private_headers + wallet2.h + wallet_errors.h + wallet_rpc_server.h + wallet_rpc_server_commands_defs.h + wallet_rpc_server_error_codes.h) + +bitmonero_private_headers(wallet + ${wallet_private_headers}) +bitmonero_add_library(wallet + ${wallet_sources} + ${wallet_headers} + ${wallet_private_headers}) +target_link_libraries(wallet + LINK_PUBLIC + cryptonote_core + mnemonics + LINK_PRIVATE + ${Boost_SERIALIZATION_LIBRARY} + ${Boost_SYSTEM_LIBRARY} + ${Boost_THREAD_LIBRARY} + ${EXTRA_LIBRARIES}) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 5af9a71bd..da8898132 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014, The Monero Project +// Copyright (c) 2014-2015, The Monero Project // // All rights reserved. // @@ -48,6 +48,9 @@ using namespace epee; #include "cryptonote_protocol/blobdatatype.h" #include "mnemonics/electrum-words.h" #include "common/dns_utils.h" +#include "rapidjson/document.h" +#include "rapidjson/writer.h" +#include "rapidjson/stringbuffer.h" extern "C" { @@ -86,24 +89,55 @@ void wallet2::init(const std::string& daemon_address, uint64_t upper_transaction m_daemon_address = daemon_address; } //---------------------------------------------------------------------------------------------------- -bool wallet2::get_seed(std::string& electrum_words) +bool wallet2::is_deterministic() { - crypto::ElectrumWords::bytes_to_words(get_account().get_keys().m_spend_secret_key, electrum_words, seed_language); - crypto::secret_key second; keccak((uint8_t *)&get_account().get_keys().m_spend_secret_key, sizeof(crypto::secret_key), (uint8_t *)&second, sizeof(crypto::secret_key)); - sc_reduce32((uint8_t *)&second); - - return memcmp(second.data,get_account().get_keys().m_view_secret_key.data, sizeof(crypto::secret_key)) == 0; + bool keys_deterministic = memcmp(second.data,get_account().get_keys().m_view_secret_key.data, sizeof(crypto::secret_key)) == 0; + return keys_deterministic; +} +//---------------------------------------------------------------------------------------------------- +bool wallet2::get_seed(std::string& electrum_words) +{ + bool keys_deterministic = is_deterministic(); + if (!keys_deterministic) + { + std::cout << "This is not a deterministic wallet" << std::endl; + return false; + } + if (seed_language.empty()) + { + std::cout << "seed_language not set" << std::endl; + return false; + } + + crypto::ElectrumWords::bytes_to_words(get_account().get_keys().m_spend_secret_key, electrum_words, seed_language); + + return true; +} +/*! + * \brief Gets the seed language + */ +const std::string wallet2::get_seed_language() +{ + return seed_language; } /*! * \brief Sets the seed language + * \param language Seed language to set to */ void wallet2::set_seed_language(const std::string &language) { seed_language = language; } +/*! + * \brief Tells if the wallet file is deprecated. + */ +bool wallet2::is_deprecated() const +{ + return is_old_file_format; +} //---------------------------------------------------------------------------------------------------- void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_t height) { @@ -432,7 +466,13 @@ bool wallet2::clear() m_local_bc_height = 1; return true; } -//---------------------------------------------------------------------------------------------------- + +/*! + * \brief Stores wallet information to wallet file. + * \param keys_file_name Name of wallet file + * \param password Password of wallet file + * \return Whether it was successful. + */ bool wallet2::store_keys(const std::string& keys_file_name, const std::string& password) { std::string account_data; @@ -440,6 +480,25 @@ bool wallet2::store_keys(const std::string& keys_file_name, const std::string& p CHECK_AND_ASSERT_MES(r, false, "failed to serialize wallet keys"); wallet2::keys_file_data keys_file_data = boost::value_initialized(); + // Create a JSON object with "key_data" and "seed_language" as keys. + rapidjson::Document json; + json.SetObject(); + rapidjson::Value value(rapidjson::kStringType); + value.SetString(account_data.c_str(), account_data.length()); + json.AddMember("key_data", value, json.GetAllocator()); + if (!seed_language.empty()) + { + value.SetString(seed_language.c_str(), seed_language.length()); + json.AddMember("seed_language", value, json.GetAllocator()); + } + + // Serialize the JSON object + rapidjson::StringBuffer buffer; + rapidjson::Writer writer(buffer); + json.Accept(writer); + account_data = buffer.GetString(); + + // Encrypt the entire JSON object. crypto::chacha8_key key; crypto::generate_chacha8_key(password, key); std::string cipher; @@ -465,30 +524,111 @@ namespace return r && expected_pub == pub; } } -//---------------------------------------------------------------------------------------------------- + +/*! + * \brief Load wallet information from wallet file. + * \param keys_file_name Name of wallet file + * \param password Password of wallet file + */ void wallet2::load_keys(const std::string& keys_file_name, const std::string& password) { wallet2::keys_file_data keys_file_data; std::string buf; bool r = epee::file_io_utils::load_file_to_string(keys_file_name, buf); THROW_WALLET_EXCEPTION_IF(!r, error::file_read_error, keys_file_name); + + // Decrypt the contents r = ::serialization::parse_binary(buf, keys_file_data); THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "internal error: failed to deserialize \"" + keys_file_name + '\"'); - crypto::chacha8_key key; crypto::generate_chacha8_key(password, key); std::string account_data; account_data.resize(keys_file_data.account_data.size()); crypto::chacha8(keys_file_data.account_data.data(), keys_file_data.account_data.size(), key, keys_file_data.iv, &account_data[0]); + // The contents should be JSON if the wallet follows the new format. + rapidjson::Document json; + if (json.Parse(account_data.c_str(), keys_file_data.account_data.size()).HasParseError()) + { + is_old_file_format = true; + } + else + { + account_data = std::string(json["key_data"].GetString(), json["key_data"].GetString() + + json["key_data"].GetStringLength()); + if (json.HasMember("seed_language")) + { + set_seed_language(std::string(json["seed_language"].GetString(), json["seed_language"].GetString() + + json["seed_language"].GetStringLength())); + } + } + const cryptonote::account_keys& keys = m_account.get_keys(); r = epee::serialization::load_t_from_binary(m_account, account_data); r = r && verify_keys(keys.m_view_secret_key, keys.m_account_address.m_view_public_key); r = r && verify_keys(keys.m_spend_secret_key, keys.m_account_address.m_spend_public_key); THROW_WALLET_EXCEPTION_IF(!r, error::invalid_password); } -//---------------------------------------------------------------------------------------------------- -crypto::secret_key wallet2::generate(const std::string& wallet_, const std::string& password, const crypto::secret_key& recovery_param, bool recover, bool two_random) + +/*! + * \brief verify password for default wallet keys file. + * \param password Password to verify + * + * for verification only + * should not mutate state, unlike load_keys() + * can be used prior to rewriting wallet keys file, to ensure user has entered the correct password + * + */ +bool wallet2::verify_password(const std::string& password) +{ + const std::string keys_file_name = m_keys_file; + wallet2::keys_file_data keys_file_data; + std::string buf; + bool r = epee::file_io_utils::load_file_to_string(keys_file_name, buf); + THROW_WALLET_EXCEPTION_IF(!r, error::file_read_error, keys_file_name); + + // Decrypt the contents + r = ::serialization::parse_binary(buf, keys_file_data); + THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "internal error: failed to deserialize \"" + keys_file_name + '\"'); + crypto::chacha8_key key; + crypto::generate_chacha8_key(password, key); + std::string account_data; + account_data.resize(keys_file_data.account_data.size()); + crypto::chacha8(keys_file_data.account_data.data(), keys_file_data.account_data.size(), key, keys_file_data.iv, &account_data[0]); + + // The contents should be JSON if the wallet follows the new format. + rapidjson::Document json; + if (json.Parse(account_data.c_str(), keys_file_data.account_data.size()).HasParseError()) + { + // old format before JSON wallet key file format + } + else + { + account_data = std::string(json["key_data"].GetString(), json["key_data"].GetString() + + json["key_data"].GetStringLength()); + } + + cryptonote::account_base account_data_check; + + r = epee::serialization::load_t_from_binary(account_data_check, account_data); + const cryptonote::account_keys& keys = account_data_check.get_keys(); + + r = r && verify_keys(keys.m_view_secret_key, keys.m_account_address.m_view_public_key); + r = r && verify_keys(keys.m_spend_secret_key, keys.m_account_address.m_spend_public_key); + return r; +} + +/*! + * \brief Generates a wallet or restores one. + * \param wallet_ Name of wallet file + * \param password Password of wallet file + * \param recovery_param If it is a restore, the recovery key + * \param recover Whether it is a restore + * \param two_random Whether it is a non-deterministic wallet + * \return The secret key of the generated wallet + */ +crypto::secret_key wallet2::generate(const std::string& wallet_, const std::string& password, + const crypto::secret_key& recovery_param, bool recover, bool two_random) { clear(); prepare_file_names(wallet_); @@ -514,6 +654,20 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const std::stri store(); return retval; } + +/*! + * \brief Rewrites to the wallet file for wallet upgrade (doesn't generate key, assumes it's already there) + * \param wallet_name Name of wallet file (should exist) + * \param password Password for wallet file + */ +void wallet2::rewrite(const std::string& wallet_name, const std::string& password) +{ + prepare_file_names(wallet_name); + boost::system::error_code ignored_ec; + THROW_WALLET_EXCEPTION_IF(!boost::filesystem::exists(m_keys_file, ignored_ec), error::file_not_found, m_keys_file); + bool r = store_keys(m_keys_file, password); + THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_keys_file); +} //---------------------------------------------------------------------------------------------------- void wallet2::wallet_exists(const std::string& file_path, bool& keys_file_exists, bool& wallet_file_exists) { @@ -525,6 +679,11 @@ void wallet2::wallet_exists(const std::string& file_path, bool& keys_file_exists wallet_file_exists = boost::filesystem::exists(wallet_file, ignore); } //---------------------------------------------------------------------------------------------------- +bool wallet2::wallet_valid_path_format(const std::string& file_path) +{ + return !file_path.empty(); +} +//---------------------------------------------------------------------------------------------------- bool wallet2::parse_payment_id(const std::string& payment_id_str, crypto::hash& payment_id) { cryptonote::blobdata payment_id_data; @@ -578,14 +737,16 @@ void wallet2::load(const std::string& wallet_, const std::string& password) { LOG_PRINT_L0("file not found: " << m_wallet_file << ", starting with empty blockchain"); m_account_public_address = m_account.get_keys().m_account_address; - return; } - bool r = tools::unserialize_obj_from_file(*this, m_wallet_file); - THROW_WALLET_EXCEPTION_IF(!r, error::file_read_error, m_wallet_file); - THROW_WALLET_EXCEPTION_IF( - m_account_public_address.m_spend_public_key != m_account.get_keys().m_account_address.m_spend_public_key || - m_account_public_address.m_view_public_key != m_account.get_keys().m_account_address.m_view_public_key, - error::wallet_files_doesnt_correspond, m_keys_file, m_wallet_file); + else + { + bool r = tools::unserialize_obj_from_file(*this, m_wallet_file); + THROW_WALLET_EXCEPTION_IF(!r, error::file_read_error, m_wallet_file); + THROW_WALLET_EXCEPTION_IF( + m_account_public_address.m_spend_public_key != m_account.get_keys().m_account_address.m_spend_public_key || + m_account_public_address.m_view_public_key != m_account.get_keys().m_account_address.m_view_public_key, + error::wallet_files_doesnt_correspond, m_keys_file, m_wallet_file); + } cryptonote::block genesis; generate_genesis(genesis); @@ -764,7 +925,7 @@ void wallet2::add_unconfirmed_tx(const cryptonote::transaction& tx, uint64_t cha void wallet2::transfer(const std::vector& dsts, size_t fake_outputs_count, uint64_t unlock_time, uint64_t fee, const std::vector& extra, cryptonote::transaction& tx, pending_tx& ptx) { - transfer(dsts, fake_outputs_count, unlock_time, fee, extra, detail::digit_split_strategy, tx_dust_policy(fee), tx, ptx); + transfer(dsts, fake_outputs_count, unlock_time, fee, extra, detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), tx, ptx); } //---------------------------------------------------------------------------------------------------- void wallet2::transfer(const std::vector& dsts, size_t fake_outputs_count, @@ -930,7 +1091,7 @@ void wallet2::commit_tx(std::vector& ptx_vector) // // this function will make multiple calls to wallet2::transfer if multiple // transactions will be required -std::vector wallet2::create_transactions(std::vector dsts, const size_t fake_outs_count, const uint64_t unlock_time, const uint64_t fee, const std::vector extra) +std::vector wallet2::create_transactions(std::vector dsts, const size_t fake_outs_count, const uint64_t unlock_time, const uint64_t fee_UNUSED, const std::vector extra) { // failsafe split attempt counter @@ -954,7 +1115,22 @@ std::vector wallet2::create_transactions(std::vector