summaryrefslogtreecommitdiffstats
path: root/external_libs/yaml-cpp
diff options
context:
space:
mode:
authorDan Klein <danklei@cisco.com>2015-08-26 18:16:09 +0300
committerDan Klein <danklei@cisco.com>2015-08-26 18:16:09 +0300
commitf8ac9d14a989c8cf1535e16165551dfa370b0b74 (patch)
tree43e396eb5d096ad74ec02afeccf8995a4d241a0f /external_libs/yaml-cpp
parentcdcc62972d42f009f55e6aeb2ca5c60c3acd75eb (diff)
parent53f0e28d7f30c7175cbb15884c309613593859d8 (diff)
Merge branch 'master' into dan_stateless
Diffstat (limited to 'external_libs/yaml-cpp')
-rw-r--r--external_libs/yaml-cpp/CMakeLists.txt282
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/aliasmanager.h34
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/anchor.h16
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/binary.h66
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/contrib/anchordict.h42
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/contrib/graphbuilder.h133
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/conversion.h75
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/dll.h28
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/emitfromevents.h45
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/emitter.h186
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/emittermanip.h149
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/eventhandler.h36
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/exceptions.h164
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/iterator.h40
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/ltnode.h18
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/mark.h26
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/node.h135
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/nodeimpl.h85
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/nodereadimpl.h86
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/nodeutil.h62
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/noncopyable.h25
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/null.h25
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/ostream.h40
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/parser.h51
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/stlemitter.h51
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/stlnode.h38
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/traits.h57
-rw-r--r--external_libs/yaml-cpp/include/yaml-cpp/yaml.h23
-rw-r--r--external_libs/yaml-cpp/install.txt24
-rw-r--r--external_libs/yaml-cpp/license.txt19
-rw-r--r--external_libs/yaml-cpp/src/aliasmanager.cpp29
-rw-r--r--external_libs/yaml-cpp/src/binary.cpp102
-rw-r--r--external_libs/yaml-cpp/src/collectionstack.h35
-rw-r--r--external_libs/yaml-cpp/src/contrib/graphbuilder.cpp16
-rw-r--r--external_libs/yaml-cpp/src/contrib/graphbuilderadapter.cpp96
-rw-r--r--external_libs/yaml-cpp/src/contrib/graphbuilderadapter.h73
-rw-r--r--external_libs/yaml-cpp/src/conversion.cpp89
-rw-r--r--external_libs/yaml-cpp/src/directives.cpp24
-rw-r--r--external_libs/yaml-cpp/src/directives.h29
-rw-r--r--external_libs/yaml-cpp/src/emitfromevents.cpp105
-rw-r--r--external_libs/yaml-cpp/src/emitter.cpp882
-rw-r--r--external_libs/yaml-cpp/src/emitterstate.cpp284
-rw-r--r--external_libs/yaml-cpp/src/emitterstate.h217
-rw-r--r--external_libs/yaml-cpp/src/emitterutils.cpp378
-rw-r--r--external_libs/yaml-cpp/src/emitterutils.h32
-rw-r--r--external_libs/yaml-cpp/src/exp.cpp113
-rw-r--r--external_libs/yaml-cpp/src/exp.h196
-rw-r--r--external_libs/yaml-cpp/src/indentation.h38
-rw-r--r--external_libs/yaml-cpp/src/iterator.cpp103
-rw-r--r--external_libs/yaml-cpp/src/iterpriv.h33
-rw-r--r--external_libs/yaml-cpp/src/node.cpp269
-rw-r--r--external_libs/yaml-cpp/src/nodebuilder.cpp145
-rw-r--r--external_libs/yaml-cpp/src/nodebuilder.h61
-rw-r--r--external_libs/yaml-cpp/src/nodeownership.cpp31
-rw-r--r--external_libs/yaml-cpp/src/nodeownership.h39
-rw-r--r--external_libs/yaml-cpp/src/null.cpp12
-rw-r--r--external_libs/yaml-cpp/src/ostream.cpp63
-rw-r--r--external_libs/yaml-cpp/src/parser.cpp152
-rw-r--r--external_libs/yaml-cpp/src/ptr_stack.h46
-rw-r--r--external_libs/yaml-cpp/src/ptr_vector.h47
-rw-r--r--external_libs/yaml-cpp/src/regex.cpp60
-rw-r--r--external_libs/yaml-cpp/src/regex.h67
-rw-r--r--external_libs/yaml-cpp/src/regeximpl.h186
-rw-r--r--external_libs/yaml-cpp/src/scanner.cpp387
-rw-r--r--external_libs/yaml-cpp/src/scanner.h132
-rw-r--r--external_libs/yaml-cpp/src/scanscalar.cpp214
-rw-r--r--external_libs/yaml-cpp/src/scanscalar.h45
-rw-r--r--external_libs/yaml-cpp/src/scantag.cpp84
-rw-r--r--external_libs/yaml-cpp/src/scantag.h20
-rw-r--r--external_libs/yaml-cpp/src/scantoken.cpp439
-rw-r--r--external_libs/yaml-cpp/src/setting.h105
-rw-r--r--external_libs/yaml-cpp/src/simplekey.cpp139
-rw-r--r--external_libs/yaml-cpp/src/singledocparser.cpp381
-rw-r--r--external_libs/yaml-cpp/src/singledocparser.h65
-rw-r--r--external_libs/yaml-cpp/src/stream.cpp448
-rw-r--r--external_libs/yaml-cpp/src/stream.h79
-rw-r--r--external_libs/yaml-cpp/src/streamcharsource.h48
-rw-r--r--external_libs/yaml-cpp/src/stringsource.h47
-rw-r--r--external_libs/yaml-cpp/src/tag.cpp52
-rw-r--r--external_libs/yaml-cpp/src/tag.h28
-rw-r--r--external_libs/yaml-cpp/src/token.h85
-rw-r--r--external_libs/yaml-cpp/test/CMakeLists.txt15
-rw-r--r--external_libs/yaml-cpp/test/emittertests.cpp1148
-rw-r--r--external_libs/yaml-cpp/test/emittertests.h13
-rw-r--r--external_libs/yaml-cpp/test/main.cpp7
-rw-r--r--external_libs/yaml-cpp/test/nodetests.h13
-rw-r--r--external_libs/yaml-cpp/test/old-api/parsertests.cpp1237
-rw-r--r--external_libs/yaml-cpp/test/old-api/spectests.cpp1456
-rw-r--r--external_libs/yaml-cpp/test/parsertests.h13
-rw-r--r--external_libs/yaml-cpp/test/specexamples.h850
-rw-r--r--external_libs/yaml-cpp/test/spectests.cpp149
-rw-r--r--external_libs/yaml-cpp/test/spectests.h360
-rw-r--r--external_libs/yaml-cpp/test/tests.cpp30
-rw-r--r--external_libs/yaml-cpp/test/tests.h53
-rw-r--r--external_libs/yaml-cpp/util/CMakeLists.txt2
-rw-r--r--external_libs/yaml-cpp/util/api.cpp129
-rw-r--r--external_libs/yaml-cpp/util/parse.cpp65
-rw-r--r--external_libs/yaml-cpp/yaml-cpp.pc.cmake11
98 files changed, 14462 insertions, 0 deletions
diff --git a/external_libs/yaml-cpp/CMakeLists.txt b/external_libs/yaml-cpp/CMakeLists.txt
new file mode 100644
index 00000000..823ce201
--- /dev/null
+++ b/external_libs/yaml-cpp/CMakeLists.txt
@@ -0,0 +1,282 @@
+###
+### CMake settings
+###
+## Due to Mac OSX we need to keep compatibility with CMake 2.6
+# see http://www.cmake.org/Wiki/CMake_Policies
+cmake_minimum_required(VERSION 2.6)
+# see http://www.cmake.org/cmake/help/cmake-2-8-docs.html#policy:CMP0012
+if(POLICY CMP0012)
+ cmake_policy(SET CMP0012 OLD)
+endif()
+# see http://www.cmake.org/cmake/help/cmake-2-8-docs.html#policy:CMP0015
+if(POLICY CMP0015)
+ cmake_policy(SET CMP0015 OLD)
+endif()
+
+include(CheckCXXCompilerFlag)
+
+
+###
+### Project settings
+###
+project(YAML_CPP)
+
+set(YAML_CPP_VERSION_MAJOR "0")
+set(YAML_CPP_VERSION_MINOR "3")
+set(YAML_CPP_VERSION_PATCH "0")
+set(YAML_CPP_VERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}.${YAML_CPP_VERSION_PATCH}")
+
+enable_testing()
+
+
+###
+### Project options
+###
+## Project stuff
+option(YAML_CPP_BUILD_TOOLS "Enable testing and parse tools" ON)
+option(YAML_CPP_BUILD_CONTRIB "Enable contrib stuff in library" ON)
+
+## Build options
+# --> General
+# see http://www.cmake.org/cmake/help/cmake2.6docs.html#variable:BUILD_SHARED_LIBS
+# http://www.cmake.org/cmake/help/cmake2.6docs.html#command:add_library
+option(BUILD_SHARED_LIBS "Build Shared Libraries" OFF)
+
+# --> Apple
+option(APPLE_UNIVERSAL_BIN "Apple: Build universal binary" OFF)
+
+# --> Microsoft Visual C++
+# see http://msdn.microsoft.com/en-us/library/aa278396(v=VS.60).aspx
+# http://msdn.microsoft.com/en-us/library/2kzt1wy3(v=VS.71).aspx
+option(MSVC_SHARED_RT "MSVC: Build with shared runtime libs (/MD)" ON)
+option(MSVC_STHREADED_RT "MSVC: Build with single-threaded static runtime libs (/ML until VS .NET 2003)" OFF)
+
+###
+### Sources, headers, directories and libs
+###
+set(header_directory "include/yaml-cpp/")
+
+file(GLOB sources "src/[a-zA-Z]*.cpp")
+file(GLOB public_headers "include/yaml-cpp/[a-zA-Z]*.h")
+file(GLOB private_headers "src/[a-zA-Z]*.h")
+
+if(YAML_CPP_BUILD_CONTRIB)
+ file(GLOB contrib_sources "src/contrib/[a-zA-Z]*.cpp")
+ file(GLOB contrib_public_headers "include/yaml-cpp/contrib/[a-zA-Z]*.h")
+ file(GLOB contrib_private_headers "src/contrib/[a-zA-Z]*.h")
+else()
+ add_definitions(-DYAML_CPP_NO_CONTRIB)
+endif()
+
+if(VERBOSE)
+ message(STATUS "sources: ${sources}")
+ message(STATUS "public_headers: ${public_headers}")
+ message(STATUS "private_headers: ${private_headers}")
+ message(STATUS "contrib_sources: ${contrib_sources}")
+ message(STATUS "contrib_public_headers: ${contrib_public_headers}")
+ message(STATUS "contrib_private_headers: ${contrib_private_headers}")
+endif()
+
+include_directories(${YAML_CPP_SOURCE_DIR}/include)
+include_directories(${YAML_CPP_SOURCE_DIR}/src)
+
+
+###
+### General compilation settings
+###
+if(BUILD_SHARED_LIBS)
+ set(LABEL_SUFFIX "shared")
+else()
+ set(LABEL_SUFFIX "static")
+endif()
+
+if(APPLE)
+ if(APPLE_UNIVERSAL_BIN)
+ set(CMAKE_OSX_ARCHITECTURES ppc;i386)
+ endif()
+endif()
+
+if(IPHONE)
+ set(CMAKE_OSX_SYSROOT "iphoneos4.2")
+ set(CMAKE_OSX_ARCHITECTURES "armv6;armv7")
+endif()
+
+if(WIN32)
+ if(BUILD_SHARED_LIBS)
+ add_definitions(-D${PROJECT_NAME}_DLL) # use or build Windows DLL
+ endif()
+ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+ set(CMAKE_INSTALL_PREFIX "C:/")
+ endif()
+endif()
+
+# GCC specialities
+if(CMAKE_COMPILER_IS_GNUCXX)
+ ### General stuff
+ if(WIN32)
+ set(CMAKE_SHARED_LIBRARY_PREFIX "") # DLLs do not have a "lib" prefix
+ set(CMAKE_IMPORT_LIBRARY_PREFIX "") # same for DLL import libs
+ set(CMAKE_LINK_DEF_FILE_FLAG "") # CMake workaround (2.8.3)
+ endif()
+
+ ### Project stuff
+ if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE Release)
+ endif()
+ #
+ set(CMAKE_CXX_FLAGS_RELEASE "-O2")
+ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
+ set(CMAKE_CXX_FLAGS_DEBUG "-g")
+ set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os")
+ #
+ set(GCC_EXTRA_OPTIONS "")
+ #
+ set(FLAG_TESTED "-Wextra")
+ check_cxx_compiler_flag(${FLAG_TESTED} FLAG_WEXTRA)
+ if(FLAG_WEXTRA)
+ set(GCC_EXTRA_OPTIONS "${GCC_EXTRA_OPTIONS} ${FLAG_TESTED}")
+ endif()
+ #
+ set(CMAKE_CXX_FLAGS "-Wall ${GCC_EXTRA_OPTIONS} -pedantic -Wno-long-long ${CMAKE_CXX_FLAGS}")
+ #
+ add_custom_target(debuggable $(MAKE) clean
+ COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug ${CMAKE_SOURCE_DIR}
+ COMMENT "Adjusting settings for debug compilation"
+ VERBATIM)
+ add_custom_target(releasable $(MAKE) clean
+ COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Release ${CMAKE_SOURCE_DIR}
+ COMMENT "Adjusting settings for release compilation"
+ VERBATIM)
+endif()
+
+# Microsoft VisualC++ specialities
+if(MSVC)
+ ### General stuff
+ # a) Change MSVC runtime library settings (/MD[d], /MT[d], /ML[d] (single-threaded until VS 2003))
+ # plus set lib suffix for later use and project label accordingly
+ # see http://msdn.microsoft.com/en-us/library/aa278396(v=VS.60).aspx
+ # http://msdn.microsoft.com/en-us/library/2kzt1wy3(v=VS.71).aspx
+ set(LIB_RT_SUFFIX "md") # CMake defaults to /MD for MSVC
+ set(LIB_RT_OPTION "/MD")
+ #
+ if(NOT MSVC_SHARED_RT) # User wants to have static runtime libraries (/MT, /ML)
+ if(MSVC_STHREADED_RT) # User wants to have old single-threaded static runtime libraries
+ set(LIB_RT_SUFFIX "ml")
+ set(LIB_RT_OPTION "/ML")
+ if(NOT ${MSVC_VERSION} LESS 1400)
+ message(FATAL_ERROR "Single-threaded static runtime libraries (/ML) only available until VS .NET 2003 (7.1).")
+ endif()
+ else()
+ set(LIB_RT_SUFFIX "mt")
+ set(LIB_RT_OPTION "/MT")
+ endif()
+
+ # correct linker options
+ foreach(flag_var CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ foreach(config_name "" DEBUG RELEASE MINSIZEREL RELWITHDEBINFO)
+ set(var_name "${flag_var}")
+ if(NOT "${config_name}" STREQUAL "")
+ set(var_name "${var_name}_${config_name}")
+ endif()
+ string(REPLACE "/MD" "${LIB_RT_OPTION}" ${var_name} "${${var_name}}")
+ endforeach()
+ endforeach()
+ endif()
+ #
+ set(LABEL_SUFFIX "${LABEL_SUFFIX} ${LIB_RT_SUFFIX}")
+
+ # b) Change prefix for static libraries
+ set(CMAKE_STATIC_LIBRARY_PREFIX "lib") # to distinguish static libraries from DLL import libs
+
+ # c) Correct suffixes for static libraries
+ if(NOT BUILD_SHARED_LIBS)
+ ### General stuff
+ set(LIB_TARGET_SUFFIX "${LIB_SUFFIX}${LIB_RT_SUFFIX}")
+ endif()
+
+ ### Project stuff
+ # /W3 = set warning level; see http://msdn.microsoft.com/en-us/library/thxezb7y.aspx
+ # /wd4127 = disable warning C4127 "conditional expression is constant"; see http://msdn.microsoft.com/en-us/library/6t66728h.aspx
+ # /wd4355 = disable warning C4355 "'this' : used in base member initializer list"; http://msdn.microsoft.com/en-us/library/3c594ae3.aspx
+ set(CMAKE_CXX_FLAGS "/W3 /wd4127 /wd4355 /D_SCL_SECURE_NO_WARNINGS ${CMAKE_CXX_FLAGS}")
+endif()
+
+
+###
+### General install settings
+###
+if(WIN32)
+ set(_library_dir bin) # .dll are in PATH, like executables
+else()
+ set(_library_dir lib)
+endif()
+
+set(INCLUDE_INSTALL_ROOT_DIR include)
+
+set(INCLUDE_INSTALL_DIR ${INCLUDE_INSTALL_ROOT_DIR}/yaml-cpp)
+set(LIB_INSTALL_DIR "${_library_dir}${LIB_SUFFIX}")
+
+set(_INSTALL_DESTINATIONS
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION ${LIB_INSTALL_DIR}
+ ARCHIVE DESTINATION "lib${LIB_SUFFIX}"
+)
+
+
+###
+### Library
+###
+add_library(yaml-cpp
+ ${sources}
+ ${public_headers}
+ ${private_headers}
+ ${contrib_sources}
+ ${contrib_public_headers}
+ ${contrib_private_headers}
+)
+
+set_target_properties(yaml-cpp PROPERTIES
+ VERSION "${YAML_CPP_VERSION}"
+ SOVERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}"
+ PROJECT_LABEL "yaml-cpp ${LABEL_SUFFIX}"
+)
+
+if(IPHONE)
+ set_target_properties(yaml-cpp PROPERTIES
+ XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "3.0"
+ )
+endif()
+
+if(MSVC)
+ if(NOT BUILD_SHARED_LIBS)
+ # correct library names
+ set_target_properties(yaml-cpp PROPERTIES
+ DEBUG_POSTFIX "${LIB_TARGET_SUFFIX}d"
+ RELEASE_POSTFIX "${LIB_TARGET_SUFFIX}"
+ MINSIZEREL_POSTFIX "${LIB_TARGET_SUFFIX}"
+ RELWITHDEBINFO_POSTFIX "${LIB_TARGET_SUFFIX}"
+ )
+ endif()
+endif()
+
+install(TARGETS yaml-cpp ${_INSTALL_DESTINATIONS})
+install(
+ DIRECTORY ${header_directory}
+ DESTINATION ${INCLUDE_INSTALL_DIR}
+ FILES_MATCHING PATTERN "*.h"
+)
+
+if(UNIX)
+ set(PC_FILE ${CMAKE_BINARY_DIR}/yaml-cpp.pc)
+ configure_file("yaml-cpp.pc.cmake" ${PC_FILE} @ONLY)
+ install(FILES ${PC_FILE} DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+endif()
+
+
+###
+### Extras
+###
+if(YAML_CPP_BUILD_TOOLS)
+ add_subdirectory(test)
+ add_subdirectory(util)
+endif()
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/aliasmanager.h b/external_libs/yaml-cpp/include/yaml-cpp/aliasmanager.h
new file mode 100644
index 00000000..e90c93dd
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/aliasmanager.h
@@ -0,0 +1,34 @@
+#ifndef ALIASMANAGER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define ALIASMANAGER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/anchor.h"
+#include <map>
+
+namespace YAML
+{
+ class Node;
+
+ class AliasManager
+ {
+ public:
+ AliasManager();
+
+ void RegisterReference(const Node& node);
+ anchor_t LookupAnchor(const Node& node) const;
+
+ private:
+ anchor_t _CreateNewAnchor();
+
+ private:
+ typedef std::map<const Node*, anchor_t> AnchorByIdentity;
+ AnchorByIdentity m_anchorByIdentity;
+
+ anchor_t m_curAnchor;
+ };
+}
+
+#endif // ALIASMANAGER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/anchor.h b/external_libs/yaml-cpp/include/yaml-cpp/anchor.h
new file mode 100644
index 00000000..433f2fa5
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/anchor.h
@@ -0,0 +1,16 @@
+#ifndef ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <cstddef>
+
+namespace YAML
+{
+ typedef std::size_t anchor_t;
+ const anchor_t NullAnchor = 0;
+}
+
+#endif // ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/binary.h b/external_libs/yaml-cpp/include/yaml-cpp/binary.h
new file mode 100644
index 00000000..8504ebeb
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/binary.h
@@ -0,0 +1,66 @@
+#ifndef BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <string>
+#include <vector>
+
+namespace YAML
+{
+ class Node;
+
+ std::string EncodeBase64(const unsigned char *data, std::size_t size);
+ std::vector<unsigned char> DecodeBase64(const std::string& input);
+
+ class Binary {
+ public:
+ Binary(): m_unownedData(0), m_unownedSize(0) {}
+ Binary(const unsigned char *data, std::size_t size): m_unownedData(data), m_unownedSize(size) {}
+
+ bool owned() const { return !m_unownedData; }
+ std::size_t size() const { return owned() ? m_data.size() : m_unownedSize; }
+ const unsigned char *data() const { return owned() ? &m_data[0] : m_unownedData; }
+
+ void swap(std::vector<unsigned char>& rhs) {
+ if(m_unownedData) {
+ m_data.swap(rhs);
+ rhs.clear();
+ rhs.resize(m_unownedSize);
+ std::copy(m_unownedData, m_unownedData + m_unownedSize, &rhs[0]);
+ m_unownedData = 0;
+ m_unownedSize = 0;
+ } else {
+ m_data.swap(rhs);
+ }
+ }
+
+ bool operator == (const Binary& rhs) const {
+ const std::size_t s = size();
+ if(s != rhs.size())
+ return false;
+ const unsigned char *d1 = data();
+ const unsigned char *d2 = rhs.data();
+ for(std::size_t i=0;i<s;i++) {
+ if(*d1++ != *d2++)
+ return false;
+ }
+ return true;
+ }
+
+ bool operator != (const Binary& rhs) const {
+ return !(*this == rhs);
+ }
+
+ private:
+ std::vector<unsigned char> m_data;
+ const unsigned char *m_unownedData;
+ std::size_t m_unownedSize;
+ };
+
+ void operator >> (const Node& node, Binary& binary);
+}
+
+#endif // BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/contrib/anchordict.h b/external_libs/yaml-cpp/include/yaml-cpp/contrib/anchordict.h
new file mode 100644
index 00000000..e483dc4b
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/contrib/anchordict.h
@@ -0,0 +1,42 @@
+#ifndef ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <vector>
+
+#include "../anchor.h"
+
+namespace YAML
+{
+ /// AnchorDict
+ /// . An object that stores and retrieves values correlating to anchor_t
+ /// values.
+ /// . Efficient implementation that can make assumptions about how anchor_t
+ /// values are assigned by the Parser class.
+ template <class T>
+ class AnchorDict
+ {
+ public:
+ void Register(anchor_t anchor, T value)
+ {
+ if (anchor > m_data.size())
+ {
+ m_data.resize(anchor);
+ }
+ m_data[anchor - 1] = value;
+ }
+
+ T Get(anchor_t anchor) const
+ {
+ return m_data[anchor - 1];
+ }
+
+ private:
+ std::vector<T> m_data;
+ };
+}
+
+#endif // ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/contrib/graphbuilder.h b/external_libs/yaml-cpp/include/yaml-cpp/contrib/graphbuilder.h
new file mode 100644
index 00000000..6739a12b
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/contrib/graphbuilder.h
@@ -0,0 +1,133 @@
+#ifndef GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/mark.h"
+#include <string>
+
+namespace YAML
+{
+ class Parser;
+
+ // GraphBuilderInterface
+ // . Abstraction of node creation
+ // . pParentNode is always NULL or the return value of one of the NewXXX()
+ // functions.
+ class GraphBuilderInterface
+ {
+ public:
+ // Create and return a new node with a null value.
+ virtual void *NewNull(const Mark& mark, void *pParentNode) = 0;
+
+ // Create and return a new node with the given tag and value.
+ virtual void *NewScalar(const Mark& mark, const std::string& tag, void *pParentNode, const std::string& value) = 0;
+
+ // Create and return a new sequence node
+ virtual void *NewSequence(const Mark& mark, const std::string& tag, void *pParentNode) = 0;
+ // Add pNode to pSequence. pNode was created with one of the NewXxx()
+ // functions and pSequence with NewSequence().
+ virtual void AppendToSequence(void *pSequence, void *pNode) = 0;
+ // Note that no moew entries will be added to pSequence
+ virtual void SequenceComplete(void *pSequence) {(void)pSequence;}
+
+ // Create and return a new map node
+ virtual void *NewMap(const Mark& mark, const std::string& tag, void *pParentNode) = 0;
+ // Add the pKeyNode => pValueNode mapping to pMap. pKeyNode and pValueNode
+ // were created with one of the NewXxx() methods and pMap with NewMap().
+ virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) = 0;
+ // Note that no more assignments will be made in pMap
+ virtual void MapComplete(void *pMap) {(void)pMap;}
+
+ // Return the node that should be used in place of an alias referencing
+ // pNode (pNode by default)
+ virtual void *AnchorReference(const Mark& mark, void *pNode) {(void)mark; return pNode;}
+ };
+
+ // Typesafe wrapper for GraphBuilderInterface. Assumes that Impl defines
+ // Node, Sequence, and Map types. Sequence and Map must derive from Node
+ // (unless Node is defined as void). Impl must also implement function with
+ // all of the same names as the virtual functions in GraphBuilderInterface
+ // -- including the ones with default implementations -- but with the
+ // prototypes changed to accept an explicit Node*, Sequence*, or Map* where
+ // appropriate.
+ template <class Impl>
+ class GraphBuilder : public GraphBuilderInterface
+ {
+ public:
+ typedef typename Impl::Node Node;
+ typedef typename Impl::Sequence Sequence;
+ typedef typename Impl::Map Map;
+
+ GraphBuilder(Impl& impl) : m_impl(impl)
+ {
+ Map* pMap = NULL;
+ Sequence* pSeq = NULL;
+ Node* pNode = NULL;
+
+ // Type consistency checks
+ pNode = pMap;
+ pNode = pSeq;
+ }
+
+ GraphBuilderInterface& AsBuilderInterface() {return *this;}
+
+ virtual void *NewNull(const Mark& mark, void* pParentNode) {
+ return CheckType<Node>(m_impl.NewNull(mark, AsNode(pParentNode)));
+ }
+
+ virtual void *NewScalar(const Mark& mark, const std::string& tag, void *pParentNode, const std::string& value) {
+ return CheckType<Node>(m_impl.NewScalar(mark, tag, AsNode(pParentNode), value));
+ }
+
+ virtual void *NewSequence(const Mark& mark, const std::string& tag, void *pParentNode) {
+ return CheckType<Sequence>(m_impl.NewSequence(mark, tag, AsNode(pParentNode)));
+ }
+ virtual void AppendToSequence(void *pSequence, void *pNode) {
+ m_impl.AppendToSequence(AsSequence(pSequence), AsNode(pNode));
+ }
+ virtual void SequenceComplete(void *pSequence) {
+ m_impl.SequenceComplete(AsSequence(pSequence));
+ }
+
+ virtual void *NewMap(const Mark& mark, const std::string& tag, void *pParentNode) {
+ return CheckType<Map>(m_impl.NewMap(mark, tag, AsNode(pParentNode)));
+ }
+ virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) {
+ m_impl.AssignInMap(AsMap(pMap), AsNode(pKeyNode), AsNode(pValueNode));
+ }
+ virtual void MapComplete(void *pMap) {
+ m_impl.MapComplete(AsMap(pMap));
+ }
+
+ virtual void *AnchorReference(const Mark& mark, void *pNode) {
+ return CheckType<Node>(m_impl.AnchorReference(mark, AsNode(pNode)));
+ }
+
+ private:
+ Impl& m_impl;
+
+ // Static check for pointer to T
+ template <class T, class U>
+ static T* CheckType(U* p) {return p;}
+
+ static Node *AsNode(void *pNode) {return static_cast<Node*>(pNode);}
+ static Sequence *AsSequence(void *pSeq) {return static_cast<Sequence*>(pSeq);}
+ static Map *AsMap(void *pMap) {return static_cast<Map*>(pMap);}
+ };
+
+ void *BuildGraphOfNextDocument(Parser& parser, GraphBuilderInterface& graphBuilder);
+
+ template <class Impl>
+ typename Impl::Node *BuildGraphOfNextDocument(Parser& parser, Impl& impl)
+ {
+ GraphBuilder<Impl> graphBuilder(impl);
+ return static_cast<typename Impl::Node *>(BuildGraphOfNextDocument(
+ parser, graphBuilder
+ ));
+ }
+}
+
+#endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/conversion.h b/external_libs/yaml-cpp/include/yaml-cpp/conversion.h
new file mode 100644
index 00000000..1b557b56
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/conversion.h
@@ -0,0 +1,75 @@
+#ifndef CONVERSION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define CONVERSION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include "yaml-cpp/null.h"
+#include "yaml-cpp/traits.h"
+#include <limits>
+#include <string>
+#include <sstream>
+
+namespace YAML
+{
+ // traits for conversion
+
+ template<typename T>
+ struct is_scalar_convertible { enum { value = is_numeric<T>::value }; };
+
+ template<> struct is_scalar_convertible<std::string> { enum { value = true }; };
+ template<> struct is_scalar_convertible<bool> { enum { value = true }; };
+ template<> struct is_scalar_convertible<_Null> { enum { value = true }; };
+
+ // actual conversion
+
+ inline bool Convert(const std::string& input, std::string& output) {
+ output = input;
+ return true;
+ }
+
+ YAML_CPP_API bool Convert(const std::string& input, bool& output);
+ YAML_CPP_API bool Convert(const std::string& input, _Null& output);
+
+ inline bool IsInfinity(const std::string& input) {
+ return input == ".inf" || input == ".Inf" || input == ".INF" || input == "+.inf" || input == "+.Inf" || input == "+.INF";
+ }
+
+ inline bool IsNegativeInfinity(const std::string& input) {
+ return input == "-.inf" || input == "-.Inf" || input == "-.INF";
+ }
+
+ inline bool IsNaN(const std::string& input) {
+ return input == ".nan" || input == ".NaN" || input == ".NAN";
+ }
+
+
+ template <typename T>
+ inline bool Convert(const std::string& input, T& output, typename enable_if<is_numeric<T> >::type * = 0) {
+ std::stringstream stream(input);
+ stream.unsetf(std::ios::dec);
+ if((stream >> output) && (stream >> std::ws).eof())
+ return true;
+
+ if(std::numeric_limits<T>::has_infinity) {
+ if(IsInfinity(input)) {
+ output = std::numeric_limits<T>::infinity();
+ return true;
+ } else if(IsNegativeInfinity(input)) {
+ output = -std::numeric_limits<T>::infinity();
+ return true;
+ }
+ }
+
+ if(std::numeric_limits<T>::has_quiet_NaN && IsNaN(input)) {
+ output = std::numeric_limits<T>::quiet_NaN();
+ return true;
+ }
+
+ return false;
+ }
+}
+
+#endif // CONVERSION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/dll.h b/external_libs/yaml-cpp/include/yaml-cpp/dll.h
new file mode 100644
index 00000000..ea138401
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/dll.h
@@ -0,0 +1,28 @@
+#ifndef DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+// The following ifdef block is the standard way of creating macros which make exporting
+// from a DLL simpler. All files within this DLL are compiled with the yaml_cpp_EXPORTS
+// symbol defined on the command line. this symbol should not be defined on any project
+// that uses this DLL. This way any other project whose source files include this file see
+// YAML_CPP_API functions as being imported from a DLL, whereas this DLL sees symbols
+// defined with this macro as being exported.
+#undef YAML_CPP_API
+
+#ifdef YAML_CPP_DLL // Using or Building YAML-CPP DLL (definition defined manually)
+ #ifdef yaml_cpp_EXPORTS // Building YAML-CPP DLL (definition created by CMake or defined manually)
+ // #pragma message( "Defining YAML_CPP_API for DLL export" )
+ #define YAML_CPP_API __declspec(dllexport)
+ #else // yaml_cpp_EXPORTS
+ // #pragma message( "Defining YAML_CPP_API for DLL import" )
+ #define YAML_CPP_API __declspec(dllimport)
+ #endif // yaml_cpp_EXPORTS
+#else //YAML_CPP_DLL
+#define YAML_CPP_API
+#endif // YAML_CPP_DLL
+
+#endif // DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/emitfromevents.h b/external_libs/yaml-cpp/include/yaml-cpp/emitfromevents.h
new file mode 100644
index 00000000..e11ae640
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/emitfromevents.h
@@ -0,0 +1,45 @@
+#ifndef EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/eventhandler.h"
+#include <stack>
+
+namespace YAML
+{
+ class Emitter;
+
+ class EmitFromEvents: public EventHandler
+ {
+ public:
+ EmitFromEvents(Emitter& emitter);
+
+ virtual void OnDocumentStart(const Mark& mark);
+ virtual void OnDocumentEnd();
+
+ virtual void OnNull(const Mark& mark, anchor_t anchor);
+ virtual void OnAlias(const Mark& mark, anchor_t anchor);
+ virtual void OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value);
+
+ virtual void OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor);
+ virtual void OnSequenceEnd();
+
+ virtual void OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor);
+ virtual void OnMapEnd();
+
+ private:
+ void BeginNode();
+ void EmitProps(const std::string& tag, anchor_t anchor);
+
+ private:
+ Emitter& m_emitter;
+
+ struct State { enum value { WaitingForSequenceEntry, WaitingForKey, WaitingForValue }; };
+ std::stack<State::value> m_stateStack;
+ };
+}
+
+#endif // EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/emitter.h b/external_libs/yaml-cpp/include/yaml-cpp/emitter.h
new file mode 100644
index 00000000..1d7edf2f
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/emitter.h
@@ -0,0 +1,186 @@
+#ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include "yaml-cpp/dll.h"
+#include "yaml-cpp/binary.h"
+#include "yaml-cpp/emittermanip.h"
+#include "yaml-cpp/ostream.h"
+#include "yaml-cpp/noncopyable.h"
+#include "yaml-cpp/null.h"
+#include <memory>
+#include <string>
+#include <sstream>
+
+namespace YAML
+{
+ class EmitterState;
+
+ class YAML_CPP_API Emitter: private noncopyable
+ {
+ public:
+ Emitter();
+ ~Emitter();
+
+ // output
+ const char *c_str() const;
+ unsigned size() const;
+
+ // state checking
+ bool good() const;
+ const std::string GetLastError() const;
+
+ // global setters
+ bool SetOutputCharset(EMITTER_MANIP value);
+ bool SetStringFormat(EMITTER_MANIP value);
+ bool SetBoolFormat(EMITTER_MANIP value);
+ bool SetIntBase(EMITTER_MANIP value);
+ bool SetSeqFormat(EMITTER_MANIP value);
+ bool SetMapFormat(EMITTER_MANIP value);
+ bool SetIndent(unsigned n);
+ bool SetPreCommentIndent(unsigned n);
+ bool SetPostCommentIndent(unsigned n);
+ bool SetFloatPrecision(unsigned n);
+ bool SetDoublePrecision(unsigned n);
+
+ // local setters
+ Emitter& SetLocalValue(EMITTER_MANIP value);
+ Emitter& SetLocalIndent(const _Indent& indent);
+ Emitter& SetLocalPrecision(const _Precision& precision);
+
+ // overloads of write
+ Emitter& Write(const std::string& str);
+ Emitter& Write(bool b);
+ Emitter& Write(char ch);
+ Emitter& Write(const _Alias& alias);
+ Emitter& Write(const _Anchor& anchor);
+ Emitter& Write(const _Tag& tag);
+ Emitter& Write(const _Comment& comment);
+ Emitter& Write(const _Null& null);
+ Emitter& Write(const Binary& binary);
+
+ template <typename T>
+ Emitter& WriteIntegralType(T value);
+
+ template <typename T>
+ Emitter& WriteStreamable(T value);
+
+ private:
+ void PreWriteIntegralType(std::stringstream& str);
+ void PreWriteStreamable(std::stringstream& str);
+ void PostWriteIntegralType(const std::stringstream& str);
+ void PostWriteStreamable(const std::stringstream& str);
+
+ template<typename T> void SetStreamablePrecision(std::stringstream&) {}
+ unsigned GetFloatPrecision() const;
+ unsigned GetDoublePrecision() const;
+
+ private:
+ void PreAtomicWrite();
+ bool GotoNextPreAtomicState();
+ void PostAtomicWrite();
+ void EmitSeparationIfNecessary();
+
+ void EmitBeginDoc();
+ void EmitEndDoc();
+ void EmitBeginSeq();
+ void EmitEndSeq();
+ void EmitBeginMap();
+ void EmitEndMap();
+ void EmitKey();
+ void EmitValue();
+ void EmitNewline();
+ void EmitKindTag();
+ void EmitTag(bool verbatim, const _Tag& tag);
+
+ const char *ComputeFullBoolName(bool b) const;
+ bool CanEmitNewline() const;
+
+ private:
+ ostream m_stream;
+ std::auto_ptr <EmitterState> m_pState;
+ };
+
+ template <typename T>
+ inline Emitter& Emitter::WriteIntegralType(T value)
+ {
+ if(!good())
+ return *this;
+
+ std::stringstream str;
+ PreWriteIntegralType(str);
+ str << value;
+ PostWriteIntegralType(str);
+ return *this;
+ }
+
+ template <typename T>
+ inline Emitter& Emitter::WriteStreamable(T value)
+ {
+ if(!good())
+ return *this;
+
+ std::stringstream str;
+ PreWriteStreamable(str);
+ SetStreamablePrecision<T>(str);
+ str << value;
+ PostWriteStreamable(str);
+ return *this;
+ }
+
+ template<>
+ inline void Emitter::SetStreamablePrecision<float>(std::stringstream& str)
+ {
+ str.precision(GetFloatPrecision());
+ }
+
+ template<>
+ inline void Emitter::SetStreamablePrecision<double>(std::stringstream& str)
+ {
+ str.precision(GetDoublePrecision());
+ }
+
+ // overloads of insertion
+ inline Emitter& operator << (Emitter& emitter, const std::string& v) { return emitter.Write(v); }
+ inline Emitter& operator << (Emitter& emitter, bool v) { return emitter.Write(v); }
+ inline Emitter& operator << (Emitter& emitter, char v) { return emitter.Write(v); }
+ inline Emitter& operator << (Emitter& emitter, unsigned char v) { return emitter.Write(static_cast<char>(v)); }
+ inline Emitter& operator << (Emitter& emitter, const _Alias& v) { return emitter.Write(v); }
+ inline Emitter& operator << (Emitter& emitter, const _Anchor& v) { return emitter.Write(v); }
+ inline Emitter& operator << (Emitter& emitter, const _Tag& v) { return emitter.Write(v); }
+ inline Emitter& operator << (Emitter& emitter, const _Comment& v) { return emitter.Write(v); }
+ inline Emitter& operator << (Emitter& emitter, const _Null& v) { return emitter.Write(v); }
+ inline Emitter& operator << (Emitter& emitter, const Binary& b) { return emitter.Write(b); }
+
+ inline Emitter& operator << (Emitter& emitter, const char *v) { return emitter.Write(std::string(v)); }
+
+ inline Emitter& operator << (Emitter& emitter, int v) { return emitter.WriteIntegralType(v); }
+ inline Emitter& operator << (Emitter& emitter, unsigned int v) { return emitter.WriteIntegralType(v); }
+ inline Emitter& operator << (Emitter& emitter, short v) { return emitter.WriteIntegralType(v); }
+ inline Emitter& operator << (Emitter& emitter, unsigned short v) { return emitter.WriteIntegralType(v); }
+ inline Emitter& operator << (Emitter& emitter, long v) { return emitter.WriteIntegralType(v); }
+ inline Emitter& operator << (Emitter& emitter, unsigned long v) { return emitter.WriteIntegralType(v); }
+ inline Emitter& operator << (Emitter& emitter, long long v) { return emitter.WriteIntegralType(v); }
+ inline Emitter& operator << (Emitter& emitter, unsigned long long v) { return emitter.WriteIntegralType(v); }
+
+ inline Emitter& operator << (Emitter& emitter, float v) { return emitter.WriteStreamable(v); }
+ inline Emitter& operator << (Emitter& emitter, double v) { return emitter.WriteStreamable(v); }
+
+ inline Emitter& operator << (Emitter& emitter, EMITTER_MANIP value) {
+ return emitter.SetLocalValue(value);
+ }
+
+ inline Emitter& operator << (Emitter& emitter, _Indent indent) {
+ return emitter.SetLocalIndent(indent);
+ }
+
+ inline Emitter& operator << (Emitter& emitter, _Precision precision) {
+ return emitter.SetLocalPrecision(precision);
+ }
+}
+
+#endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/emittermanip.h b/external_libs/yaml-cpp/include/yaml-cpp/emittermanip.h
new file mode 100644
index 00000000..a8ec64a4
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/emittermanip.h
@@ -0,0 +1,149 @@
+#ifndef EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include <string>
+
+namespace YAML
+{
+ enum EMITTER_MANIP {
+ // general manipulators
+ Auto,
+ TagByKind,
+ Newline,
+
+ // output character set
+ EmitNonAscii,
+ EscapeNonAscii,
+
+ // string manipulators
+ // Auto, // duplicate
+ SingleQuoted,
+ DoubleQuoted,
+ Literal,
+
+ // bool manipulators
+ YesNoBool, // yes, no
+ TrueFalseBool, // true, false
+ OnOffBool, // on, off
+ UpperCase, // TRUE, N
+ LowerCase, // f, yes
+ CamelCase, // No, Off
+ LongBool, // yes, On
+ ShortBool, // y, t
+
+ // int manipulators
+ Dec,
+ Hex,
+ Oct,
+
+ // document manipulators
+ BeginDoc,
+ EndDoc,
+
+ // sequence manipulators
+ BeginSeq,
+ EndSeq,
+ Flow,
+ Block,
+
+ // map manipulators
+ BeginMap,
+ EndMap,
+ Key,
+ Value,
+ // Flow, // duplicate
+ // Block, // duplicate
+ // Auto, // duplicate
+ LongKey
+ };
+
+ struct _Indent {
+ _Indent(int value_): value(value_) {}
+ int value;
+ };
+
+ inline _Indent Indent(int value) {
+ return _Indent(value);
+ }
+
+ struct _Alias {
+ _Alias(const std::string& content_): content(content_) {}
+ std::string content;
+ };
+
+ inline _Alias Alias(const std::string content) {
+ return _Alias(content);
+ }
+
+ struct _Anchor {
+ _Anchor(const std::string& content_): content(content_) {}
+ std::string content;
+ };
+
+ inline _Anchor Anchor(const std::string content) {
+ return _Anchor(content);
+ }
+
+ struct _Tag {
+ struct Type { enum value { Verbatim, PrimaryHandle, NamedHandle }; };
+
+ explicit _Tag(const std::string& prefix_, const std::string& content_, Type::value type_)
+ : prefix(prefix_), content(content_), type(type_)
+ {
+ }
+ std::string prefix;
+ std::string content;
+ Type::value type;
+ };
+
+ inline _Tag VerbatimTag(const std::string content) {
+ return _Tag("", content, _Tag::Type::Verbatim);
+ }
+
+ inline _Tag LocalTag(const std::string content) {
+ return _Tag("", content, _Tag::Type::PrimaryHandle);
+ }
+
+ inline _Tag LocalTag(const std::string& prefix, const std::string content) {
+ return _Tag(prefix, content, _Tag::Type::NamedHandle);
+ }
+
+ inline _Tag SecondaryTag(const std::string content) {
+ return _Tag("", content, _Tag::Type::NamedHandle);
+ }
+
+ struct _Comment {
+ _Comment(const std::string& content_): content(content_) {}
+ std::string content;
+ };
+
+ inline _Comment Comment(const std::string content) {
+ return _Comment(content);
+ }
+
+ struct _Precision {
+ _Precision(int floatPrecision_, int doublePrecision_): floatPrecision(floatPrecision_), doublePrecision(doublePrecision_) {}
+
+ int floatPrecision;
+ int doublePrecision;
+ };
+
+ inline _Precision FloatPrecision(int n) {
+ return _Precision(n, -1);
+ }
+
+ inline _Precision DoublePrecision(int n) {
+ return _Precision(-1, n);
+ }
+
+ inline _Precision Precision(int n) {
+ return _Precision(n, n);
+ }
+}
+
+#endif // EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/eventhandler.h b/external_libs/yaml-cpp/include/yaml-cpp/eventhandler.h
new file mode 100644
index 00000000..3173a1fb
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/eventhandler.h
@@ -0,0 +1,36 @@
+#ifndef EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/anchor.h"
+#include <string>
+
+namespace YAML
+{
+ struct Mark;
+
+ class EventHandler
+ {
+ public:
+ virtual ~EventHandler() {}
+
+ virtual void OnDocumentStart(const Mark& mark) = 0;
+ virtual void OnDocumentEnd() = 0;
+
+ virtual void OnNull(const Mark& mark, anchor_t anchor) = 0;
+ virtual void OnAlias(const Mark& mark, anchor_t anchor) = 0;
+ virtual void OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value) = 0;
+
+ virtual void OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor) = 0;
+ virtual void OnSequenceEnd() = 0;
+
+ virtual void OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor) = 0;
+ virtual void OnMapEnd() = 0;
+ };
+}
+
+#endif // EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/exceptions.h b/external_libs/yaml-cpp/include/yaml-cpp/exceptions.h
new file mode 100644
index 00000000..394d5868
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/exceptions.h
@@ -0,0 +1,164 @@
+#ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include "yaml-cpp/mark.h"
+#include "yaml-cpp/traits.h"
+#include <stdexcept>
+#include <string>
+#include <sstream>
+
+namespace YAML
+{
+ // error messages
+ namespace ErrorMsg
+ {
+ const char * const YAML_DIRECTIVE_ARGS = "YAML directives must have exactly one argument";
+ const char * const YAML_VERSION = "bad YAML version: ";
+ const char * const YAML_MAJOR_VERSION = "YAML major version too large";
+ const char * const REPEATED_YAML_DIRECTIVE= "repeated YAML directive";
+ const char * const TAG_DIRECTIVE_ARGS = "TAG directives must have exactly two arguments";
+ const char * const REPEATED_TAG_DIRECTIVE = "repeated TAG directive";
+ const char * const CHAR_IN_TAG_HANDLE = "illegal character found while scanning tag handle";
+ const char * const TAG_WITH_NO_SUFFIX = "tag handle with no suffix";
+ const char * const END_OF_VERBATIM_TAG = "end of verbatim tag not found";
+ const char * const END_OF_MAP = "end of map not found";
+ const char * const END_OF_MAP_FLOW = "end of map flow not found";
+ const char * const END_OF_SEQ = "end of sequence not found";
+ const char * const END_OF_SEQ_FLOW = "end of sequence flow not found";
+ const char * const MULTIPLE_TAGS = "cannot assign multiple tags to the same node";
+ const char * const MULTIPLE_ANCHORS = "cannot assign multiple anchors to the same node";
+ const char * const MULTIPLE_ALIASES = "cannot assign multiple aliases to the same node";
+ const char * const ALIAS_CONTENT = "aliases can't have any content, *including* tags";
+ const char * const INVALID_HEX = "bad character found while scanning hex number";
+ const char * const INVALID_UNICODE = "invalid unicode: ";
+ const char * const INVALID_ESCAPE = "unknown escape character: ";
+ const char * const UNKNOWN_TOKEN = "unknown token";
+ const char * const DOC_IN_SCALAR = "illegal document indicator in scalar";
+ const char * const EOF_IN_SCALAR = "illegal EOF in scalar";
+ const char * const CHAR_IN_SCALAR = "illegal character in scalar";
+ const char * const TAB_IN_INDENTATION = "illegal tab when looking for indentation";
+ const char * const FLOW_END = "illegal flow end";
+ const char * const BLOCK_ENTRY = "illegal block entry";
+ const char * const MAP_KEY = "illegal map key";
+ const char * const MAP_VALUE = "illegal map value";
+ const char * const ALIAS_NOT_FOUND = "alias not found after *";
+ const char * const ANCHOR_NOT_FOUND = "anchor not found after &";
+ const char * const CHAR_IN_ALIAS = "illegal character found while scanning alias";
+ const char * const CHAR_IN_ANCHOR = "illegal character found while scanning anchor";
+ const char * const ZERO_INDENT_IN_BLOCK = "cannot set zero indentation for a block scalar";
+ const char * const CHAR_IN_BLOCK = "unexpected character in block scalar";
+ const char * const AMBIGUOUS_ANCHOR = "cannot assign the same alias to multiple nodes";
+ const char * const UNKNOWN_ANCHOR = "the referenced anchor is not defined";
+
+ const char * const INVALID_SCALAR = "invalid scalar";
+ const char * const KEY_NOT_FOUND = "key not found";
+ const char * const BAD_DEREFERENCE = "bad dereference";
+
+ const char * const UNMATCHED_GROUP_TAG = "unmatched group tag";
+ const char * const UNEXPECTED_END_SEQ = "unexpected end sequence token";
+ const char * const UNEXPECTED_END_MAP = "unexpected end map token";
+ const char * const SINGLE_QUOTED_CHAR = "invalid character in single-quoted string";
+ const char * const INVALID_ANCHOR = "invalid anchor";
+ const char * const INVALID_ALIAS = "invalid alias";
+ const char * const INVALID_TAG = "invalid tag";
+ const char * const EXPECTED_KEY_TOKEN = "expected key token";
+ const char * const EXPECTED_VALUE_TOKEN = "expected value token";
+ const char * const UNEXPECTED_KEY_TOKEN = "unexpected key token";
+ const char * const UNEXPECTED_VALUE_TOKEN = "unexpected value token";
+
+ template <typename T>
+ inline const std::string KEY_NOT_FOUND_WITH_KEY(const T&, typename disable_if<is_numeric<T> >::type * = 0) {
+ return KEY_NOT_FOUND;
+ }
+
+ inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) {
+ std::stringstream stream;
+ stream << KEY_NOT_FOUND << ": " << key;
+ return stream.str();
+ }
+
+ template <typename T>
+ inline const std::string KEY_NOT_FOUND_WITH_KEY(const T& key, typename enable_if<is_numeric<T> >::type * = 0) {
+ std::stringstream stream;
+ stream << KEY_NOT_FOUND << ": " << key;
+ return stream.str();
+ }
+ }
+
+ class Exception: public std::runtime_error {
+ public:
+ Exception(const Mark& mark_, const std::string& msg_)
+ : std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {}
+ virtual ~Exception() throw() {}
+
+ Mark mark;
+ std::string msg;
+
+ private:
+ static const std::string build_what(const Mark& mark, const std::string& msg) {
+ std::stringstream output;
+ output << "yaml-cpp: error at line " << mark.line+1 << ", column " << mark.column+1 << ": " << msg;
+ return output.str();
+ }
+ };
+
+ class ParserException: public Exception {
+ public:
+ ParserException(const Mark& mark_, const std::string& msg_)
+ : Exception(mark_, msg_) {}
+ };
+
+ class RepresentationException: public Exception {
+ public:
+ RepresentationException(const Mark& mark_, const std::string& msg_)
+ : Exception(mark_, msg_) {}
+ };
+
+ // representation exceptions
+ class InvalidScalar: public RepresentationException {
+ public:
+ InvalidScalar(const Mark& mark_)
+ : RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {}
+ };
+
+ class KeyNotFound: public RepresentationException {
+ public:
+ template <typename T>
+ KeyNotFound(const Mark& mark_, const T& key_)
+ : RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) {}
+ };
+
+ template <typename T>
+ class TypedKeyNotFound: public KeyNotFound {
+ public:
+ TypedKeyNotFound(const Mark& mark_, const T& key_)
+ : KeyNotFound(mark_, key_), key(key_) {}
+ virtual ~TypedKeyNotFound() throw() {}
+
+ T key;
+ };
+
+ template <typename T>
+ inline TypedKeyNotFound <T> MakeTypedKeyNotFound(const Mark& mark, const T& key) {
+ return TypedKeyNotFound <T> (mark, key);
+ }
+
+ class BadDereference: public RepresentationException {
+ public:
+ BadDereference()
+ : RepresentationException(Mark::null(), ErrorMsg::BAD_DEREFERENCE) {}
+ };
+
+ class EmitterException: public Exception {
+ public:
+ EmitterException(const std::string& msg_)
+ : Exception(Mark::null(), msg_) {}
+ };
+}
+
+#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/iterator.h b/external_libs/yaml-cpp/include/yaml-cpp/iterator.h
new file mode 100644
index 00000000..400ee340
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/iterator.h
@@ -0,0 +1,40 @@
+#ifndef ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/dll.h"
+#include <memory>
+
+namespace YAML
+{
+ class Node;
+ struct IterPriv;
+
+ class YAML_CPP_API Iterator
+ {
+ public:
+ Iterator();
+ Iterator(std::auto_ptr<IterPriv> pData);
+ Iterator(const Iterator& rhs);
+ ~Iterator();
+
+ Iterator& operator = (const Iterator& rhs);
+ Iterator& operator ++ ();
+ Iterator operator ++ (int);
+ const Node& operator * () const;
+ const Node *operator -> () const;
+ const Node& first() const;
+ const Node& second() const;
+
+ friend YAML_CPP_API bool operator == (const Iterator& it, const Iterator& jt);
+ friend YAML_CPP_API bool operator != (const Iterator& it, const Iterator& jt);
+
+ private:
+ std::auto_ptr<IterPriv> m_pData;
+ };
+}
+
+#endif // ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/ltnode.h b/external_libs/yaml-cpp/include/yaml-cpp/ltnode.h
new file mode 100644
index 00000000..30b4f950
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/ltnode.h
@@ -0,0 +1,18 @@
+#ifndef LTNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define LTNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+namespace YAML
+{
+ class Node;
+
+ struct ltnode {
+ bool operator()(const Node *pNode1, const Node *pNode2) const;
+ };
+}
+
+#endif // LTNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/mark.h b/external_libs/yaml-cpp/include/yaml-cpp/mark.h
new file mode 100644
index 00000000..7c80fbcb
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/mark.h
@@ -0,0 +1,26 @@
+#ifndef MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include "yaml-cpp/dll.h"
+
+namespace YAML
+{
+ struct YAML_CPP_API Mark {
+ Mark(): pos(0), line(0), column(0) {}
+
+ static const Mark null() { return Mark(-1, -1, -1); }
+
+ int pos;
+ int line, column;
+
+ private:
+ Mark(int pos_, int line_, int column_): pos(pos_), line(line_), column(column_) {}
+ };
+}
+
+#endif // MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/node.h b/external_libs/yaml-cpp/include/yaml-cpp/node.h
new file mode 100644
index 00000000..e78190e0
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/node.h
@@ -0,0 +1,135 @@
+#ifndef NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include "yaml-cpp/dll.h"
+#include "yaml-cpp/exceptions.h"
+#include "yaml-cpp/mark.h"
+#include "yaml-cpp/noncopyable.h"
+#include "yaml-cpp/conversion.h"
+#include "yaml-cpp/iterator.h"
+#include "yaml-cpp/ltnode.h"
+#include <iostream>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace YAML
+{
+ class AliasManager;
+ class Content;
+ class NodeOwnership;
+ class Scanner;
+ class Emitter;
+ class EventHandler;
+
+ struct NodeType { enum value { Null, Scalar, Sequence, Map }; };
+
+ class YAML_CPP_API Node: private noncopyable
+ {
+ public:
+ friend class NodeOwnership;
+ friend class NodeBuilder;
+
+ Node();
+ ~Node();
+
+ void Clear();
+ std::auto_ptr<Node> Clone() const;
+ void EmitEvents(EventHandler& eventHandler) const;
+ void EmitEvents(AliasManager& am, EventHandler& eventHandler) const;
+
+ NodeType::value Type() const { return m_type; }
+ bool IsAliased() const;
+
+ // file location of start of this node
+ const Mark GetMark() const { return m_mark; }
+
+ // accessors
+ Iterator begin() const;
+ Iterator end() const;
+ std::size_t size() const;
+
+ // extraction of scalars
+ bool GetScalar(std::string& s) const;
+
+ // we can specialize this for other values
+ template <typename T>
+ bool Read(T& value) const;
+
+ template <typename T>
+ const T to() const;
+
+ template <typename T>
+ friend YAML_CPP_API typename enable_if<is_scalar_convertible<T> >::type operator >> (const Node& node, T& value);
+
+ // retrieval for maps and sequences
+ template <typename T>
+ const Node *FindValue(const T& key) const;
+
+ template <typename T>
+ const Node& operator [] (const T& key) const;
+
+ // specific to maps
+ const Node *FindValue(const char *key) const;
+ const Node *FindValue(char *key) const;
+ const Node& operator [] (const char *key) const;
+ const Node& operator [] (char *key) const;
+
+ // for tags
+ const std::string& Tag() const { return m_tag; }
+
+ // emitting
+ friend YAML_CPP_API Emitter& operator << (Emitter& out, const Node& node);
+
+ // ordering
+ int Compare(const Node& rhs) const;
+ friend bool operator < (const Node& n1, const Node& n2);
+
+ private:
+ explicit Node(NodeOwnership& owner);
+ Node& CreateNode();
+
+ void Init(NodeType::value type, const Mark& mark, const std::string& tag);
+
+ void MarkAsAliased();
+ void SetScalarData(const std::string& data);
+ void Append(Node& node);
+ void Insert(Node& key, Node& value);
+
+ // helper for sequences
+ template <typename, bool> friend struct _FindFromNodeAtIndex;
+ const Node *FindAtIndex(std::size_t i) const;
+
+ // helper for maps
+ template <typename T>
+ const Node& GetValue(const T& key) const;
+
+ template <typename T>
+ const Node *FindValueForKey(const T& key) const;
+
+ private:
+ std::auto_ptr<NodeOwnership> m_pOwnership;
+
+ Mark m_mark;
+ std::string m_tag;
+
+ typedef std::vector<Node *> node_seq;
+ typedef std::map<Node *, Node *, ltnode> node_map;
+
+ NodeType::value m_type;
+ std::string m_scalarData;
+ node_seq m_seqData;
+ node_map m_mapData;
+ };
+}
+
+#include "yaml-cpp/nodeimpl.h"
+#include "yaml-cpp/nodereadimpl.h"
+
+#endif // NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/nodeimpl.h b/external_libs/yaml-cpp/include/yaml-cpp/nodeimpl.h
new file mode 100644
index 00000000..5ca7ddba
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/nodeimpl.h
@@ -0,0 +1,85 @@
+#ifndef NODEIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODEIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include "yaml-cpp/nodeutil.h"
+#include <cassert>
+
+namespace YAML
+{
+ // implementation of templated things
+ template <typename T>
+ inline const T Node::to() const {
+ T value;
+ *this >> value;
+ return value;
+ }
+
+ template <typename T>
+ inline typename enable_if<is_scalar_convertible<T> >::type operator >> (const Node& node, T& value) {
+ if(!ConvertScalar(node, value))
+ throw InvalidScalar(node.m_mark);
+ }
+
+ template <typename T>
+ inline const Node *Node::FindValue(const T& key) const {
+ switch(m_type) {
+ case NodeType::Null:
+ case NodeType::Scalar:
+ throw BadDereference();
+ case NodeType::Sequence:
+ return FindFromNodeAtIndex(*this, key);
+ case NodeType::Map:
+ return FindValueForKey(key);
+ }
+ assert(false);
+ throw BadDereference();
+ }
+
+ template <typename T>
+ inline const Node *Node::FindValueForKey(const T& key) const {
+ for(Iterator it=begin();it!=end();++it) {
+ T t;
+ if(it.first().Read(t)) {
+ if(key == t)
+ return &it.second();
+ }
+ }
+
+ return 0;
+ }
+
+ template <typename T>
+ inline const Node& Node::GetValue(const T& key) const {
+ if(const Node *pValue = FindValue(key))
+ return *pValue;
+ throw MakeTypedKeyNotFound(m_mark, key);
+ }
+
+ template <typename T>
+ inline const Node& Node::operator [] (const T& key) const {
+ return GetValue(key);
+ }
+
+ inline const Node *Node::FindValue(const char *key) const {
+ return FindValue(std::string(key));
+ }
+
+ inline const Node *Node::FindValue(char *key) const {
+ return FindValue(std::string(key));
+ }
+
+ inline const Node& Node::operator [] (const char *key) const {
+ return GetValue(std::string(key));
+ }
+
+ inline const Node& Node::operator [] (char *key) const {
+ return GetValue(std::string(key));
+ }
+}
+
+#endif // NODEIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/nodereadimpl.h b/external_libs/yaml-cpp/include/yaml-cpp/nodereadimpl.h
new file mode 100644
index 00000000..6838dc5a
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/nodereadimpl.h
@@ -0,0 +1,86 @@
+#ifndef NODEREADIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODEREADIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+namespace YAML
+{
+ // implementation for Node::Read
+ // (the goal is to call ConvertScalar if we can, and fall back to operator >> if not)
+ // thanks to litb from stackoverflow.com
+ // http://stackoverflow.com/questions/1386183/how-to-call-a-templated-function-if-it-exists-and-something-else-otherwise/1386390#1386390
+
+ // Note: this doesn't work on gcc 3.2, but does on gcc 3.4 and above. I'm not sure about 3.3.
+
+#if __GNUC__ && (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ <= 3))
+ // trick doesn't work? Just fall back to ConvertScalar.
+ // This means that we can't use any user-defined types as keys in a map
+ template <typename T>
+ inline bool Node::Read(T& value) const {
+ return ConvertScalar(*this, value);
+ }
+#else
+ // usual case: the trick!
+ template<bool>
+ struct read_impl;
+
+ // ConvertScalar available
+ template<>
+ struct read_impl<true> {
+ template<typename T>
+ static bool read(const Node& node, T& value) {
+ return ConvertScalar(node, value);
+ }
+ };
+
+ // ConvertScalar not available
+ template<>
+ struct read_impl<false> {
+ template<typename T>
+ static bool read(const Node& node, T& value) {
+ try {
+ node >> value;
+ } catch(const Exception&) {
+ return false;
+ }
+ return true;
+ }
+ };
+
+ namespace fallback {
+ // sizeof > 1
+ struct flag { char c[2]; };
+ flag Convert(...);
+
+ int operator,(flag, flag);
+
+ template<typename T>
+ char operator,(flag, T const&);
+
+ char operator,(int, flag);
+ int operator,(char, flag);
+ }
+
+ template <typename T>
+ inline bool Node::Read(T& value) const {
+ using namespace fallback;
+
+ return read_impl<sizeof (fallback::flag(), Convert(std::string(), value), fallback::flag()) != 1>::read(*this, value);
+ }
+#endif // done with trick
+
+ // the main conversion function
+ template <typename T>
+ inline bool ConvertScalar(const Node& node, T& value) {
+ std::string scalar;
+ if(!node.GetScalar(scalar))
+ return false;
+
+ return Convert(scalar, value);
+ }
+}
+
+#endif // NODEREADIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/nodeutil.h b/external_libs/yaml-cpp/include/yaml-cpp/nodeutil.h
new file mode 100644
index 00000000..d0c01d27
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/nodeutil.h
@@ -0,0 +1,62 @@
+#ifndef NODEUTIL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODEUTIL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+namespace YAML
+{
+ template <typename T, typename U>
+ struct is_same_type {
+ enum { value = false };
+ };
+
+ template <typename T>
+ struct is_same_type<T, T> {
+ enum { value = true };
+ };
+
+ template <typename T, bool check>
+ struct is_index_type_with_check {
+ enum { value = false };
+ };
+
+ template <> struct is_index_type_with_check<std::size_t, false> { enum { value = true }; };
+
+#define MAKE_INDEX_TYPE(Type) \
+ template <> struct is_index_type_with_check<Type, is_same_type<Type, std::size_t>::value> { enum { value = true }; }
+
+ MAKE_INDEX_TYPE(int);
+ MAKE_INDEX_TYPE(unsigned);
+ MAKE_INDEX_TYPE(short);
+ MAKE_INDEX_TYPE(unsigned short);
+ MAKE_INDEX_TYPE(long);
+ MAKE_INDEX_TYPE(unsigned long);
+
+#undef MAKE_INDEX_TYPE
+
+ template <typename T>
+ struct is_index_type: public is_index_type_with_check<T, false> {};
+
+ // messing around with template stuff to get the right overload for operator [] for a sequence
+ template <typename T, bool b>
+ struct _FindFromNodeAtIndex {
+ const Node *pRet;
+ _FindFromNodeAtIndex(const Node&, const T&): pRet(0) {}
+ };
+
+ template <typename T>
+ struct _FindFromNodeAtIndex<T, true> {
+ const Node *pRet;
+ _FindFromNodeAtIndex(const Node& node, const T& key): pRet(node.FindAtIndex(static_cast<std::size_t>(key))) {}
+ };
+
+ template <typename T>
+ inline const Node *FindFromNodeAtIndex(const Node& node, const T& key) {
+ return _FindFromNodeAtIndex<T, is_index_type<T>::value>(node, key).pRet;
+ }
+}
+
+#endif // NODEUTIL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/noncopyable.h b/external_libs/yaml-cpp/include/yaml-cpp/noncopyable.h
new file mode 100644
index 00000000..8e61e433
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/noncopyable.h
@@ -0,0 +1,25 @@
+#ifndef NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/dll.h"
+
+namespace YAML
+{
+ // this is basically boost::noncopyable
+ class YAML_CPP_API noncopyable
+ {
+ protected:
+ noncopyable() {}
+ ~noncopyable() {}
+
+ private:
+ noncopyable(const noncopyable&);
+ const noncopyable& operator = (const noncopyable&);
+ };
+}
+
+#endif // NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/null.h b/external_libs/yaml-cpp/include/yaml-cpp/null.h
new file mode 100644
index 00000000..711f18c3
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/null.h
@@ -0,0 +1,25 @@
+#ifndef NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include "yaml-cpp/dll.h"
+
+namespace YAML
+{
+ class Node;
+
+ struct YAML_CPP_API _Null {};
+ inline bool operator == (const _Null&, const _Null&) { return true; }
+ inline bool operator != (const _Null&, const _Null&) { return false; }
+
+ YAML_CPP_API bool IsNull(const Node& node); // old API only
+
+ extern YAML_CPP_API _Null Null;
+}
+
+#endif // NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/ostream.h b/external_libs/yaml-cpp/include/yaml-cpp/ostream.h
new file mode 100644
index 00000000..65839b1b
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/ostream.h
@@ -0,0 +1,40 @@
+#ifndef OSTREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define OSTREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include <string>
+
+namespace YAML
+{
+ class ostream
+ {
+ public:
+ ostream();
+ ~ostream();
+
+ void reserve(unsigned size);
+ void put(char ch);
+ const char *str() const { return m_buffer; }
+
+ unsigned row() const { return m_row; }
+ unsigned col() const { return m_col; }
+ unsigned pos() const { return m_pos; }
+
+ private:
+ char *m_buffer;
+ unsigned m_pos;
+ unsigned m_size;
+
+ unsigned m_row, m_col;
+ };
+
+ ostream& operator << (ostream& out, const char *str);
+ ostream& operator << (ostream& out, const std::string& str);
+ ostream& operator << (ostream& out, char ch);
+}
+
+#endif // OSTREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/parser.h b/external_libs/yaml-cpp/include/yaml-cpp/parser.h
new file mode 100644
index 00000000..f71cdff4
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/parser.h
@@ -0,0 +1,51 @@
+#ifndef PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include "yaml-cpp/dll.h"
+#include "yaml-cpp/noncopyable.h"
+#include <ios>
+#include <memory>
+
+namespace YAML
+{
+ struct Directives;
+ struct Mark;
+ struct Token;
+ class EventHandler;
+ class Node;
+ class Scanner;
+
+ class YAML_CPP_API Parser: private noncopyable
+ {
+ public:
+ Parser();
+ Parser(std::istream& in);
+ ~Parser();
+
+ operator bool() const;
+
+ void Load(std::istream& in);
+ bool HandleNextDocument(EventHandler& eventHandler);
+
+ bool GetNextDocument(Node& document); // old API only
+
+ void PrintTokens(std::ostream& out);
+
+ private:
+ void ParseDirectives();
+ void HandleDirective(const Token& token);
+ void HandleYamlDirective(const Token& token);
+ void HandleTagDirective(const Token& token);
+
+ private:
+ std::auto_ptr<Scanner> m_pScanner;
+ std::auto_ptr<Directives> m_pDirectives;
+ };
+}
+
+#endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/stlemitter.h b/external_libs/yaml-cpp/include/yaml-cpp/stlemitter.h
new file mode 100644
index 00000000..f8ff20ea
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/stlemitter.h
@@ -0,0 +1,51 @@
+#ifndef STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include <vector>
+#include <list>
+#include <set>
+#include <map>
+
+namespace YAML
+{
+ template<typename Seq>
+ inline Emitter& EmitSeq(Emitter& emitter, const Seq& seq) {
+ emitter << BeginSeq;
+ for(typename Seq::const_iterator it=seq.begin();it!=seq.end();++it)
+ emitter << *it;
+ emitter << EndSeq;
+ return emitter;
+ }
+
+ template<typename T>
+ inline Emitter& operator << (Emitter& emitter, const std::vector<T>& v) {
+ return EmitSeq(emitter, v);
+ }
+
+ template<typename T>
+ inline Emitter& operator << (Emitter& emitter, const std::list<T>& v) {
+ return EmitSeq(emitter, v);
+ }
+
+ template<typename T>
+ inline Emitter& operator << (Emitter& emitter, const std::set<T>& v) {
+ return EmitSeq(emitter, v);
+ }
+
+ template <typename K, typename V>
+ inline Emitter& operator << (Emitter& emitter, const std::map<K, V>& m) {
+ typedef typename std::map <K, V> map;
+ emitter << BeginMap;
+ for(typename map::const_iterator it=m.begin();it!=m.end();++it)
+ emitter << Key << it->first << Value << it->second;
+ emitter << EndMap;
+ return emitter;
+ }
+}
+
+#endif // STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/stlnode.h b/external_libs/yaml-cpp/include/yaml-cpp/stlnode.h
new file mode 100644
index 00000000..40d4ae79
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/stlnode.h
@@ -0,0 +1,38 @@
+#ifndef STLNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define STLNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include <vector>
+#include <map>
+
+namespace YAML
+{
+ template <typename T>
+ void operator >> (const Node& node, std::vector<T>& v)
+ {
+ v.clear();
+ v.resize(node.size());
+ for(unsigned i=0;i<node.size();++i)
+ node[i] >> v[i];
+ }
+
+
+ template <typename K, typename V>
+ void operator >> (const Node& node, std::map<K, V>& m)
+ {
+ m.clear();
+ for(Iterator it=node.begin();it!=node.end();++it) {
+ K k;
+ V v;
+ it.first() >> k;
+ it.second() >> v;
+ m[k] = v;
+ }
+ }
+}
+
+#endif // STLNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/traits.h b/external_libs/yaml-cpp/include/yaml-cpp/traits.h
new file mode 100644
index 00000000..09eead44
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/traits.h
@@ -0,0 +1,57 @@
+#ifndef TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+namespace YAML
+{
+ template <typename>
+ struct is_numeric { enum { value = false }; };
+
+ template <> struct is_numeric <char> { enum { value = true }; };
+ template <> struct is_numeric <unsigned char> { enum { value = true }; };
+ template <> struct is_numeric <int> { enum { value = true }; };
+ template <> struct is_numeric <unsigned int> { enum { value = true }; };
+ template <> struct is_numeric <long int> { enum { value = true }; };
+ template <> struct is_numeric <unsigned long int> { enum { value = true }; };
+ template <> struct is_numeric <short int> { enum { value = true }; };
+ template <> struct is_numeric <unsigned short int> { enum { value = true }; };
+#if defined(_MSC_VER) && (_MSC_VER < 1310)
+ template <> struct is_numeric <__int64> { enum { value = true }; };
+ template <> struct is_numeric <unsigned __int64> { enum { value = true }; };
+#else
+ template <> struct is_numeric <long long> { enum { value = true }; };
+ template <> struct is_numeric <unsigned long long> { enum { value = true }; };
+#endif
+ template <> struct is_numeric <float> { enum { value = true }; };
+ template <> struct is_numeric <double> { enum { value = true }; };
+ template <> struct is_numeric <long double> { enum { value = true }; };
+
+ template <bool, class T = void>
+ struct enable_if_c {
+ typedef T type;
+ };
+
+ template <class T>
+ struct enable_if_c<false, T> {};
+
+ template <class Cond, class T = void>
+ struct enable_if : public enable_if_c<Cond::value, T> {};
+
+ template <bool, class T = void>
+ struct disable_if_c {
+ typedef T type;
+ };
+
+ template <class T>
+ struct disable_if_c<true, T> {};
+
+ template <class Cond, class T = void>
+ struct disable_if : public disable_if_c<Cond::value, T> {};
+}
+
+#endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
diff --git a/external_libs/yaml-cpp/include/yaml-cpp/yaml.h b/external_libs/yaml-cpp/include/yaml-cpp/yaml.h
new file mode 100644
index 00000000..29595553
--- /dev/null
+++ b/external_libs/yaml-cpp/include/yaml-cpp/yaml.h
@@ -0,0 +1,23 @@
+#ifndef YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#if defined(_MSC_VER)
+#pragma warning(disable:4786)
+#pragma warning(disable:4146)
+#pragma warning(disable:4244)
+#endif
+
+#include "yaml-cpp/parser.h"
+#include "yaml-cpp/emitter.h"
+#include "yaml-cpp/stlemitter.h"
+#include "yaml-cpp/exceptions.h"
+
+#include "yaml-cpp/node.h"
+#include "yaml-cpp/stlnode.h"
+#include "yaml-cpp/iterator.h"
+
+#endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/install.txt b/external_libs/yaml-cpp/install.txt
new file mode 100644
index 00000000..93923624
--- /dev/null
+++ b/external_libs/yaml-cpp/install.txt
@@ -0,0 +1,24 @@
+*** With CMake ***
+
+yaml-cpp uses CMake to support cross-platform building. In a UNIX-like system, the basic steps to build are:
+
+1. Download and install CMake (if you don't have root privileges, just install to a local directory, like ~/bin)
+
+2. From the source directory, run:
+
+mkdir build
+cd build
+cmake ..
+
+and then the usual
+
+make
+make install
+
+3. To clean up, just remove the 'build' directory.
+
+*** Without CMake ***
+
+If you don't want to use CMake, just add all .cpp files to a makefile. yaml-cpp does not need any special build settings, so no 'configure' file is necessary.
+
+(Note: this is pretty tedious. It's sooo much easier to use CMake.)
diff --git a/external_libs/yaml-cpp/license.txt b/external_libs/yaml-cpp/license.txt
new file mode 100644
index 00000000..5bd9e1a1
--- /dev/null
+++ b/external_libs/yaml-cpp/license.txt
@@ -0,0 +1,19 @@
+Copyright (c) 2008 Jesse Beder.
+
+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.
diff --git a/external_libs/yaml-cpp/src/aliasmanager.cpp b/external_libs/yaml-cpp/src/aliasmanager.cpp
new file mode 100644
index 00000000..ed4d3b5a
--- /dev/null
+++ b/external_libs/yaml-cpp/src/aliasmanager.cpp
@@ -0,0 +1,29 @@
+#include "yaml-cpp/aliasmanager.h"
+#include "yaml-cpp/node.h"
+#include <cassert>
+#include <sstream>
+
+namespace YAML
+{
+ AliasManager::AliasManager(): m_curAnchor(0)
+ {
+ }
+
+ void AliasManager::RegisterReference(const Node& node)
+ {
+ m_anchorByIdentity.insert(std::make_pair(&node, _CreateNewAnchor()));
+ }
+
+ anchor_t AliasManager::LookupAnchor(const Node& node) const
+ {
+ AnchorByIdentity::const_iterator it = m_anchorByIdentity.find(&node);
+ if(it == m_anchorByIdentity.end())
+ return 0;
+ return it->second;
+ }
+
+ anchor_t AliasManager::_CreateNewAnchor()
+ {
+ return ++m_curAnchor;
+ }
+}
diff --git a/external_libs/yaml-cpp/src/binary.cpp b/external_libs/yaml-cpp/src/binary.cpp
new file mode 100644
index 00000000..589eb089
--- /dev/null
+++ b/external_libs/yaml-cpp/src/binary.cpp
@@ -0,0 +1,102 @@
+#include "yaml-cpp/binary.h"
+#include "yaml-cpp/node.h"
+
+namespace YAML
+{
+ static const char encoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+ std::string EncodeBase64(const unsigned char *data, std::size_t size)
+ {
+ const char PAD = '=';
+
+ std::string ret;
+ ret.resize(4 * size / 3 + 3);
+ char *out = &ret[0];
+
+ std::size_t chunks = size / 3;
+ std::size_t remainder = size % 3;
+
+ for(std::size_t i=0;i<chunks;i++, data += 3) {
+ *out++ = encoding[data[0] >> 2];
+ *out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)];
+ *out++ = encoding[((data[1] & 0xf) << 2) | (data[2] >> 6)];
+ *out++ = encoding[data[2] & 0x3f];
+ }
+
+ switch(remainder) {
+ case 0:
+ break;
+ case 1:
+ *out++ = encoding[data[0] >> 2];
+ *out++ = encoding[((data[0] & 0x3) << 4)];
+ *out++ = PAD;
+ *out++ = PAD;
+ break;
+ case 2:
+ *out++ = encoding[data[0] >> 2];
+ *out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)];
+ *out++ = encoding[((data[1] & 0xf) << 2)];
+ *out++ = PAD;
+ break;
+ }
+
+ ret.resize(out - &ret[0]);
+ return ret;
+ }
+
+ static const unsigned char decoding[] = {
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255,
+ 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255,
+ 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ };
+
+ std::vector<unsigned char> DecodeBase64(const std::string& input)
+ {
+ typedef std::vector<unsigned char> ret_type;
+ if(input.empty())
+ return ret_type();
+
+ ret_type ret(3 * input.size() / 4 + 1);
+ unsigned char *out = &ret[0];
+
+ unsigned value = 0;
+ for(std::size_t i=0;i<input.size();i++) {
+ unsigned char d = decoding[static_cast<unsigned>(input[i])];
+ if(d == 255)
+ return ret_type();
+
+ value = (value << 6) | d;
+ if(i % 4 == 3) {
+ *out++ = value >> 16;
+ if(i > 0 && input[i - 1] != '=')
+ *out++ = value >> 8;
+ if(input[i] != '=')
+ *out++ = value;
+ }
+ }
+
+ ret.resize(out - &ret[0]);
+ return ret;
+ }
+
+ void operator >> (const Node& node, Binary& binary)
+ {
+ std::string scalar;
+ node.GetScalar(scalar);
+ std::vector<unsigned char> data = DecodeBase64(scalar);
+ binary.swap(data);
+ }
+}
diff --git a/external_libs/yaml-cpp/src/collectionstack.h b/external_libs/yaml-cpp/src/collectionstack.h
new file mode 100644
index 00000000..4a986bc9
--- /dev/null
+++ b/external_libs/yaml-cpp/src/collectionstack.h
@@ -0,0 +1,35 @@
+#ifndef COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include <stack>
+#include <cassert>
+
+namespace YAML
+{
+ struct CollectionType {
+ enum value { None, BlockMap, BlockSeq, FlowMap, FlowSeq, CompactMap };
+ };
+
+ class CollectionStack
+ {
+ public:
+ CollectionType::value GetCurCollectionType() const {
+ if(collectionStack.empty())
+ return CollectionType::None;
+ return collectionStack.top();
+ }
+
+ void PushCollectionType(CollectionType::value type) { collectionStack.push(type); }
+ void PopCollectionType(CollectionType::value type) { assert(type == GetCurCollectionType()); collectionStack.pop(); }
+
+ private:
+ std::stack<CollectionType::value> collectionStack;
+ };
+}
+
+#endif // COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/src/contrib/graphbuilder.cpp b/external_libs/yaml-cpp/src/contrib/graphbuilder.cpp
new file mode 100644
index 00000000..ab5159cc
--- /dev/null
+++ b/external_libs/yaml-cpp/src/contrib/graphbuilder.cpp
@@ -0,0 +1,16 @@
+#include "yaml-cpp/parser.h"
+#include "yaml-cpp/contrib/graphbuilder.h"
+#include "graphbuilderadapter.h"
+
+namespace YAML
+{
+ void *BuildGraphOfNextDocument(Parser& parser, GraphBuilderInterface& graphBuilder)
+ {
+ GraphBuilderAdapter eventHandler(graphBuilder);
+ if (parser.HandleNextDocument(eventHandler)) {
+ return eventHandler.RootNode();
+ } else {
+ return NULL;
+ }
+ }
+}
diff --git a/external_libs/yaml-cpp/src/contrib/graphbuilderadapter.cpp b/external_libs/yaml-cpp/src/contrib/graphbuilderadapter.cpp
new file mode 100644
index 00000000..557e97c8
--- /dev/null
+++ b/external_libs/yaml-cpp/src/contrib/graphbuilderadapter.cpp
@@ -0,0 +1,96 @@
+#include "graphbuilderadapter.h"
+
+namespace YAML
+{
+ int GraphBuilderAdapter::ContainerFrame::sequenceMarker;
+
+ void GraphBuilderAdapter::OnNull(const Mark& mark, anchor_t anchor)
+ {
+ void *pParent = GetCurrentParent();
+ void *pNode = m_builder.NewNull(mark, pParent);
+ RegisterAnchor(anchor, pNode);
+
+ DispositionNode(pNode);
+ }
+
+ void GraphBuilderAdapter::OnAlias(const Mark& mark, anchor_t anchor)
+ {
+ void *pReffedNode = m_anchors.Get(anchor);
+ DispositionNode(m_builder.AnchorReference(mark, pReffedNode));
+ }
+
+ void GraphBuilderAdapter::OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value)
+ {
+ void *pParent = GetCurrentParent();
+ void *pNode = m_builder.NewScalar(mark, tag, pParent, value);
+ RegisterAnchor(anchor, pNode);
+
+ DispositionNode(pNode);
+ }
+
+ void GraphBuilderAdapter::OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor)
+ {
+ void *pNode = m_builder.NewSequence(mark, tag, GetCurrentParent());
+ m_containers.push(ContainerFrame(pNode));
+ RegisterAnchor(anchor, pNode);
+ }
+
+ void GraphBuilderAdapter::OnSequenceEnd()
+ {
+ void *pSequence = m_containers.top().pContainer;
+ m_containers.pop();
+
+ DispositionNode(pSequence);
+ }
+
+ void GraphBuilderAdapter::OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor)
+ {
+ void *pNode = m_builder.NewMap(mark, tag, GetCurrentParent());
+ m_containers.push(ContainerFrame(pNode, m_pKeyNode));
+ m_pKeyNode = NULL;
+ RegisterAnchor(anchor, pNode);
+ }
+
+ void GraphBuilderAdapter::OnMapEnd()
+ {
+ void *pMap = m_containers.top().pContainer;
+ m_pKeyNode = m_containers.top().pPrevKeyNode;
+ m_containers.pop();
+ DispositionNode(pMap);
+ }
+
+ void *GraphBuilderAdapter::GetCurrentParent() const
+ {
+ if (m_containers.empty()) {
+ return NULL;
+ }
+ return m_containers.top().pContainer;
+ }
+
+ void GraphBuilderAdapter::RegisterAnchor(anchor_t anchor, void *pNode)
+ {
+ if (anchor) {
+ m_anchors.Register(anchor, pNode);
+ }
+ }
+
+ void GraphBuilderAdapter::DispositionNode(void *pNode)
+ {
+ if (m_containers.empty()) {
+ m_pRootNode = pNode;
+ return;
+ }
+
+ void *pContainer = m_containers.top().pContainer;
+ if (m_containers.top().isMap()) {
+ if (m_pKeyNode) {
+ m_builder.AssignInMap(pContainer, m_pKeyNode, pNode);
+ m_pKeyNode = NULL;
+ } else {
+ m_pKeyNode = pNode;
+ }
+ } else {
+ m_builder.AppendToSequence(pContainer, pNode);
+ }
+ }
+}
diff --git a/external_libs/yaml-cpp/src/contrib/graphbuilderadapter.h b/external_libs/yaml-cpp/src/contrib/graphbuilderadapter.h
new file mode 100644
index 00000000..3ef8ab6c
--- /dev/null
+++ b/external_libs/yaml-cpp/src/contrib/graphbuilderadapter.h
@@ -0,0 +1,73 @@
+#ifndef GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <cstdlib>
+#include <map>
+#include <stack>
+#include "yaml-cpp/eventhandler.h"
+#include "yaml-cpp/contrib/anchordict.h"
+#include "yaml-cpp/contrib/graphbuilder.h"
+
+namespace YAML
+{
+ class GraphBuilderAdapter : public EventHandler
+ {
+ public:
+ GraphBuilderAdapter(GraphBuilderInterface& builder)
+ : m_builder(builder), m_pRootNode(NULL), m_pKeyNode(NULL)
+ {
+ }
+
+ virtual void OnDocumentStart(const Mark& mark) {(void)mark;}
+ virtual void OnDocumentEnd() {}
+
+ virtual void OnNull(const Mark& mark, anchor_t anchor);
+ virtual void OnAlias(const Mark& mark, anchor_t anchor);
+ virtual void OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value);
+
+ virtual void OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor);
+ virtual void OnSequenceEnd();
+
+ virtual void OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor);
+ virtual void OnMapEnd();
+
+ void *RootNode() const {return m_pRootNode;}
+
+ private:
+ struct ContainerFrame
+ {
+ ContainerFrame(void *pSequence)
+ : pContainer(pSequence), pPrevKeyNode(&sequenceMarker)
+ {}
+ ContainerFrame(void *pMap, void* pPrevKeyNode)
+ : pContainer(pMap), pPrevKeyNode(pPrevKeyNode)
+ {}
+
+ void *pContainer;
+ void *pPrevKeyNode;
+
+ bool isMap() const {return pPrevKeyNode != &sequenceMarker;}
+
+ private:
+ static int sequenceMarker;
+ };
+ typedef std::stack<ContainerFrame> ContainerStack;
+ typedef AnchorDict<void*> AnchorMap;
+
+ GraphBuilderInterface& m_builder;
+ ContainerStack m_containers;
+ AnchorMap m_anchors;
+ void *m_pRootNode;
+ void *m_pKeyNode;
+
+ void *GetCurrentParent() const;
+ void RegisterAnchor(anchor_t anchor, void *pNode);
+ void DispositionNode(void *pNode);
+ };
+}
+
+#endif // GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/src/conversion.cpp b/external_libs/yaml-cpp/src/conversion.cpp
new file mode 100644
index 00000000..f81e1a0b
--- /dev/null
+++ b/external_libs/yaml-cpp/src/conversion.cpp
@@ -0,0 +1,89 @@
+#include "yaml-cpp/conversion.h"
+#include <algorithm>
+
+////////////////////////////////////////////////////////////////
+// Specializations for converting a string to specific types
+
+namespace
+{
+ // we're not gonna mess with the mess that is all the isupper/etc. functions
+ bool IsLower(char ch) { return 'a' <= ch && ch <= 'z'; }
+ bool IsUpper(char ch) { return 'A' <= ch && ch <= 'Z'; }
+ char ToLower(char ch) { return IsUpper(ch) ? ch + 'a' - 'A' : ch; }
+
+ std::string tolower(const std::string& str)
+ {
+ std::string s(str);
+ std::transform(s.begin(), s.end(), s.begin(), ToLower);
+ return s;
+ }
+
+ template <typename T>
+ bool IsEntirely(const std::string& str, T func)
+ {
+ for(std::size_t i=0;i<str.size();i++)
+ if(!func(str[i]))
+ return false;
+
+ return true;
+ }
+
+ // IsFlexibleCase
+ // . Returns true if 'str' is:
+ // . UPPERCASE
+ // . lowercase
+ // . Capitalized
+ bool IsFlexibleCase(const std::string& str)
+ {
+ if(str.empty())
+ return true;
+
+ if(IsEntirely(str, IsLower))
+ return true;
+
+ bool firstcaps = IsUpper(str[0]);
+ std::string rest = str.substr(1);
+ return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper));
+ }
+}
+
+namespace YAML
+{
+ bool Convert(const std::string& input, bool& b)
+ {
+ // we can't use iostream bool extraction operators as they don't
+ // recognize all possible values in the table below (taken from
+ // http://yaml.org/type/bool.html)
+ static const struct {
+ std::string truename, falsename;
+ } names[] = {
+ { "y", "n" },
+ { "yes", "no" },
+ { "true", "false" },
+ { "on", "off" },
+ };
+
+ if(!IsFlexibleCase(input))
+ return false;
+
+ for(unsigned i=0;i<sizeof(names)/sizeof(names[0]);i++) {
+ if(names[i].truename == tolower(input)) {
+ b = true;
+ return true;
+ }
+
+ if(names[i].falsename == tolower(input)) {
+ b = false;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ bool Convert(const std::string& input, _Null& /*output*/)
+ {
+ return input.empty() || input == "~" || input == "null" || input == "Null" || input == "NULL";
+ }
+}
+
diff --git a/external_libs/yaml-cpp/src/directives.cpp b/external_libs/yaml-cpp/src/directives.cpp
new file mode 100644
index 00000000..faf1483b
--- /dev/null
+++ b/external_libs/yaml-cpp/src/directives.cpp
@@ -0,0 +1,24 @@
+#include "directives.h"
+
+namespace YAML
+{
+ Directives::Directives()
+ {
+ // version
+ version.isDefault = true;
+ version.major = 1;
+ version.minor = 2;
+ }
+
+ const std::string Directives::TranslateTagHandle(const std::string& handle) const
+ {
+ std::map <std::string, std::string>::const_iterator it = tags.find(handle);
+ if(it == tags.end()) {
+ if(handle == "!!")
+ return "tag:yaml.org,2002:";
+ return handle;
+ }
+
+ return it->second;
+ }
+}
diff --git a/external_libs/yaml-cpp/src/directives.h b/external_libs/yaml-cpp/src/directives.h
new file mode 100644
index 00000000..a3308f72
--- /dev/null
+++ b/external_libs/yaml-cpp/src/directives.h
@@ -0,0 +1,29 @@
+#ifndef DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include <string>
+#include <map>
+
+namespace YAML
+{
+ struct Version {
+ bool isDefault;
+ int major, minor;
+ };
+
+ struct Directives {
+ Directives();
+
+ const std::string TranslateTagHandle(const std::string& handle) const;
+
+ Version version;
+ std::map<std::string, std::string> tags;
+ };
+}
+
+#endif // DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/src/emitfromevents.cpp b/external_libs/yaml-cpp/src/emitfromevents.cpp
new file mode 100644
index 00000000..49fc10b2
--- /dev/null
+++ b/external_libs/yaml-cpp/src/emitfromevents.cpp
@@ -0,0 +1,105 @@
+#include "yaml-cpp/emitfromevents.h"
+#include "yaml-cpp/emitter.h"
+#include "yaml-cpp/null.h"
+#include <cassert>
+#include <sstream>
+
+namespace {
+ std::string ToString(YAML::anchor_t anchor) {
+ std::stringstream stream;
+ stream << anchor;
+ return stream.str();
+ }
+}
+
+namespace YAML
+{
+ EmitFromEvents::EmitFromEvents(Emitter& emitter): m_emitter(emitter)
+ {
+ }
+
+ void EmitFromEvents::OnDocumentStart(const Mark&)
+ {
+ }
+
+ void EmitFromEvents::OnDocumentEnd()
+ {
+ }
+
+ void EmitFromEvents::OnNull(const Mark&, anchor_t anchor)
+ {
+ BeginNode();
+ EmitProps("", anchor);
+ m_emitter << Null;
+ }
+
+ void EmitFromEvents::OnAlias(const Mark&, anchor_t anchor)
+ {
+ BeginNode();
+ m_emitter << Alias(ToString(anchor));
+ }
+
+ void EmitFromEvents::OnScalar(const Mark&, const std::string& tag, anchor_t anchor, const std::string& value)
+ {
+ BeginNode();
+ EmitProps(tag, anchor);
+ m_emitter << value;
+ }
+
+ void EmitFromEvents::OnSequenceStart(const Mark&, const std::string& tag, anchor_t anchor)
+ {
+ BeginNode();
+ EmitProps(tag, anchor);
+ m_emitter << BeginSeq;
+ m_stateStack.push(State::WaitingForSequenceEntry);
+ }
+
+ void EmitFromEvents::OnSequenceEnd()
+ {
+ m_emitter << EndSeq;
+ assert(m_stateStack.top() == State::WaitingForSequenceEntry);
+ m_stateStack.pop();
+ }
+
+ void EmitFromEvents::OnMapStart(const Mark&, const std::string& tag, anchor_t anchor)
+ {
+ BeginNode();
+ EmitProps(tag, anchor);
+ m_emitter << BeginMap;
+ m_stateStack.push(State::WaitingForKey);
+ }
+
+ void EmitFromEvents::OnMapEnd()
+ {
+ m_emitter << EndMap;
+ assert(m_stateStack.top() == State::WaitingForKey);
+ m_stateStack.pop();
+ }
+
+ void EmitFromEvents::BeginNode()
+ {
+ if(m_stateStack.empty())
+ return;
+
+ switch(m_stateStack.top()) {
+ case State::WaitingForKey:
+ m_emitter << Key;
+ m_stateStack.top() = State::WaitingForValue;
+ break;
+ case State::WaitingForValue:
+ m_emitter << Value;
+ m_stateStack.top() = State::WaitingForKey;
+ break;
+ default:
+ break;
+ }
+ }
+
+ void EmitFromEvents::EmitProps(const std::string& tag, anchor_t anchor)
+ {
+ if(!tag.empty() && tag != "?")
+ m_emitter << VerbatimTag(tag);
+ if(anchor)
+ m_emitter << Anchor(ToString(anchor));
+ }
+}
diff --git a/external_libs/yaml-cpp/src/emitter.cpp b/external_libs/yaml-cpp/src/emitter.cpp
new file mode 100644
index 00000000..91f48da7
--- /dev/null
+++ b/external_libs/yaml-cpp/src/emitter.cpp
@@ -0,0 +1,882 @@
+#include "yaml-cpp/emitter.h"
+#include "emitterstate.h"
+#include "emitterutils.h"
+#include "indentation.h"
+#include "yaml-cpp/exceptions.h"
+#include <sstream>
+
+namespace YAML
+{
+ Emitter::Emitter(): m_pState(new EmitterState)
+ {
+ }
+
+ Emitter::~Emitter()
+ {
+ }
+
+ const char *Emitter::c_str() const
+ {
+ return m_stream.str();
+ }
+
+ unsigned Emitter::size() const
+ {
+ return m_stream.pos();
+ }
+
+ // state checking
+ bool Emitter::good() const
+ {
+ return m_pState->good();
+ }
+
+ const std::string Emitter::GetLastError() const
+ {
+ return m_pState->GetLastError();
+ }
+
+ // global setters
+ bool Emitter::SetOutputCharset(EMITTER_MANIP value)
+ {
+ return m_pState->SetOutputCharset(value, GLOBAL);
+ }
+
+ bool Emitter::SetStringFormat(EMITTER_MANIP value)
+ {
+ return m_pState->SetStringFormat(value, GLOBAL);
+ }
+
+ bool Emitter::SetBoolFormat(EMITTER_MANIP value)
+ {
+ bool ok = false;
+ if(m_pState->SetBoolFormat(value, GLOBAL))
+ ok = true;
+ if(m_pState->SetBoolCaseFormat(value, GLOBAL))
+ ok = true;
+ if(m_pState->SetBoolLengthFormat(value, GLOBAL))
+ ok = true;
+ return ok;
+ }
+
+ bool Emitter::SetIntBase(EMITTER_MANIP value)
+ {
+ return m_pState->SetIntFormat(value, GLOBAL);
+ }
+
+ bool Emitter::SetSeqFormat(EMITTER_MANIP value)
+ {
+ return m_pState->SetFlowType(GT_SEQ, value, GLOBAL);
+ }
+
+ bool Emitter::SetMapFormat(EMITTER_MANIP value)
+ {
+ bool ok = false;
+ if(m_pState->SetFlowType(GT_MAP, value, GLOBAL))
+ ok = true;
+ if(m_pState->SetMapKeyFormat(value, GLOBAL))
+ ok = true;
+ return ok;
+ }
+
+ bool Emitter::SetIndent(unsigned n)
+ {
+ return m_pState->SetIndent(n, GLOBAL);
+ }
+
+ bool Emitter::SetPreCommentIndent(unsigned n)
+ {
+ return m_pState->SetPreCommentIndent(n, GLOBAL);
+ }
+
+ bool Emitter::SetPostCommentIndent(unsigned n)
+ {
+ return m_pState->SetPostCommentIndent(n, GLOBAL);
+ }
+
+ bool Emitter::SetFloatPrecision(unsigned n)
+ {
+ return m_pState->SetFloatPrecision(n, GLOBAL);
+ }
+
+ bool Emitter::SetDoublePrecision(unsigned n)
+ {
+ return m_pState->SetDoublePrecision(n, GLOBAL);
+ }
+
+ // SetLocalValue
+ // . Either start/end a group, or set a modifier locally
+ Emitter& Emitter::SetLocalValue(EMITTER_MANIP value)
+ {
+ if(!good())
+ return *this;
+
+ switch(value) {
+ case BeginDoc:
+ EmitBeginDoc();
+ break;
+ case EndDoc:
+ EmitEndDoc();
+ break;
+ case BeginSeq:
+ EmitBeginSeq();
+ break;
+ case EndSeq:
+ EmitEndSeq();
+ break;
+ case BeginMap:
+ EmitBeginMap();
+ break;
+ case EndMap:
+ EmitEndMap();
+ break;
+ case Key:
+ EmitKey();
+ break;
+ case Value:
+ EmitValue();
+ break;
+ case TagByKind:
+ EmitKindTag();
+ break;
+ case Newline:
+ EmitNewline();
+ break;
+ default:
+ m_pState->SetLocalValue(value);
+ break;
+ }
+ return *this;
+ }
+
+ Emitter& Emitter::SetLocalIndent(const _Indent& indent)
+ {
+ m_pState->SetIndent(indent.value, LOCAL);
+ return *this;
+ }
+
+ Emitter& Emitter::SetLocalPrecision(const _Precision& precision)
+ {
+ if(precision.floatPrecision >= 0)
+ m_pState->SetFloatPrecision(precision.floatPrecision, LOCAL);
+ if(precision.doublePrecision >= 0)
+ m_pState->SetDoublePrecision(precision.doublePrecision, LOCAL);
+ return *this;
+ }
+
+ // GotoNextPreAtomicState
+ // . Runs the state machine, emitting if necessary, and returns 'true' if done (i.e., ready to emit an atom)
+ bool Emitter::GotoNextPreAtomicState()
+ {
+ if(!good())
+ return true;
+
+ unsigned curIndent = m_pState->GetCurIndent();
+
+ EMITTER_STATE curState = m_pState->GetCurState();
+ switch(curState) {
+ // document-level
+ case ES_WAITING_FOR_DOC:
+ m_pState->SwitchState(ES_WRITING_DOC);
+ return true;
+ case ES_WRITING_DOC:
+ return true;
+ case ES_DONE_WITH_DOC:
+ EmitBeginDoc();
+ return false;
+
+ // block sequence
+ case ES_WAITING_FOR_BLOCK_SEQ_ENTRY:
+ m_stream << IndentTo(curIndent) << "-";
+ m_pState->RequireSoftSeparation();
+ m_pState->SwitchState(ES_WRITING_BLOCK_SEQ_ENTRY);
+ return true;
+ case ES_WRITING_BLOCK_SEQ_ENTRY:
+ return true;
+ case ES_DONE_WITH_BLOCK_SEQ_ENTRY:
+ m_stream << '\n';
+ m_pState->SwitchState(ES_WAITING_FOR_BLOCK_SEQ_ENTRY);
+ return false;
+
+ // flow sequence
+ case ES_WAITING_FOR_FLOW_SEQ_ENTRY:
+ m_pState->SwitchState(ES_WRITING_FLOW_SEQ_ENTRY);
+ return true;
+ case ES_WRITING_FLOW_SEQ_ENTRY:
+ return true;
+ case ES_DONE_WITH_FLOW_SEQ_ENTRY:
+ EmitSeparationIfNecessary();
+ m_stream << ',';
+ m_pState->RequireSoftSeparation();
+ m_pState->SwitchState(ES_WAITING_FOR_FLOW_SEQ_ENTRY);
+ return false;
+
+ // block map
+ case ES_WAITING_FOR_BLOCK_MAP_ENTRY:
+ m_pState->SetError(ErrorMsg::EXPECTED_KEY_TOKEN);
+ return true;
+ case ES_WAITING_FOR_BLOCK_MAP_KEY:
+ if(m_pState->CurrentlyInLongKey()) {
+ m_stream << IndentTo(curIndent) << '?';
+ m_pState->RequireSoftSeparation();
+ }
+ m_pState->SwitchState(ES_WRITING_BLOCK_MAP_KEY);
+ return true;
+ case ES_WRITING_BLOCK_MAP_KEY:
+ return true;
+ case ES_DONE_WITH_BLOCK_MAP_KEY:
+ m_pState->SetError(ErrorMsg::EXPECTED_VALUE_TOKEN);
+ return true;
+ case ES_WAITING_FOR_BLOCK_MAP_VALUE:
+ m_pState->SwitchState(ES_WRITING_BLOCK_MAP_VALUE);
+ return true;
+ case ES_WRITING_BLOCK_MAP_VALUE:
+ return true;
+ case ES_DONE_WITH_BLOCK_MAP_VALUE:
+ m_pState->SetError(ErrorMsg::EXPECTED_KEY_TOKEN);
+ return true;
+
+ // flow map
+ case ES_WAITING_FOR_FLOW_MAP_ENTRY:
+ m_pState->SetError(ErrorMsg::EXPECTED_KEY_TOKEN);
+ return true;
+ case ES_WAITING_FOR_FLOW_MAP_KEY:
+ EmitSeparationIfNecessary();
+ m_pState->SwitchState(ES_WRITING_FLOW_MAP_KEY);
+ if(m_pState->CurrentlyInLongKey()) {
+ m_stream << '?';
+ m_pState->RequireSoftSeparation();
+ }
+ return true;
+ case ES_WRITING_FLOW_MAP_KEY:
+ return true;
+ case ES_DONE_WITH_FLOW_MAP_KEY:
+ m_pState->SetError(ErrorMsg::EXPECTED_VALUE_TOKEN);
+ return true;
+ case ES_WAITING_FOR_FLOW_MAP_VALUE:
+ EmitSeparationIfNecessary();
+ m_stream << ':';
+ m_pState->RequireSoftSeparation();
+ m_pState->SwitchState(ES_WRITING_FLOW_MAP_VALUE);
+ return true;
+ case ES_WRITING_FLOW_MAP_VALUE:
+ return true;
+ case ES_DONE_WITH_FLOW_MAP_VALUE:
+ m_pState->SetError(ErrorMsg::EXPECTED_KEY_TOKEN);
+ return true;
+ default:
+ assert(false);
+ }
+
+ assert(false);
+ return true;
+ }
+
+ // PreAtomicWrite
+ // . Depending on the emitter state, write to the stream to get it
+ // in position to do an atomic write (e.g., scalar, sequence, or map)
+ void Emitter::PreAtomicWrite()
+ {
+ if(!good())
+ return;
+
+ while(!GotoNextPreAtomicState())
+ ;
+ }
+
+ // PostAtomicWrite
+ // . Clean up
+ void Emitter::PostAtomicWrite()
+ {
+ if(!good())
+ return;
+
+ EMITTER_STATE curState = m_pState->GetCurState();
+ switch(curState) {
+ // document-level
+ case ES_WRITING_DOC:
+ m_pState->SwitchState(ES_DONE_WITH_DOC);
+ break;
+
+ // block seq
+ case ES_WRITING_BLOCK_SEQ_ENTRY:
+ m_pState->SwitchState(ES_DONE_WITH_BLOCK_SEQ_ENTRY);
+ break;
+
+ // flow seq
+ case ES_WRITING_FLOW_SEQ_ENTRY:
+ m_pState->SwitchState(ES_DONE_WITH_FLOW_SEQ_ENTRY);
+ break;
+
+ // block map
+ case ES_WRITING_BLOCK_MAP_KEY:
+ if(!m_pState->CurrentlyInLongKey()) {
+ m_stream << ':';
+ m_pState->RequireSoftSeparation();
+ }
+ m_pState->SwitchState(ES_DONE_WITH_BLOCK_MAP_KEY);
+ break;
+ case ES_WRITING_BLOCK_MAP_VALUE:
+ m_pState->SwitchState(ES_DONE_WITH_BLOCK_MAP_VALUE);
+ break;
+
+ // flow map
+ case ES_WRITING_FLOW_MAP_KEY:
+ m_pState->SwitchState(ES_DONE_WITH_FLOW_MAP_KEY);
+ break;
+ case ES_WRITING_FLOW_MAP_VALUE:
+ m_pState->SwitchState(ES_DONE_WITH_FLOW_MAP_VALUE);
+ break;
+ default:
+ assert(false);
+ };
+
+ m_pState->ClearModifiedSettings();
+ }
+
+ // EmitSeparationIfNecessary
+ void Emitter::EmitSeparationIfNecessary()
+ {
+ if(!good())
+ return;
+
+ if(m_pState->RequiresSoftSeparation())
+ m_stream << ' ';
+ else if(m_pState->RequiresHardSeparation())
+ m_stream << '\n';
+ m_pState->UnsetSeparation();
+ }
+
+ // EmitBeginDoc
+ void Emitter::EmitBeginDoc()
+ {
+ if(!good())
+ return;
+
+ EMITTER_STATE curState = m_pState->GetCurState();
+ if(curState != ES_WAITING_FOR_DOC && curState != ES_WRITING_DOC && curState != ES_DONE_WITH_DOC) {
+ m_pState->SetError("Unexpected begin document");
+ return;
+ }
+
+ if(curState == ES_WRITING_DOC || curState == ES_DONE_WITH_DOC)
+ m_stream << '\n';
+ m_stream << "---\n";
+
+ m_pState->UnsetSeparation();
+ m_pState->SwitchState(ES_WAITING_FOR_DOC);
+ }
+
+ // EmitEndDoc
+ void Emitter::EmitEndDoc()
+ {
+ if(!good())
+ return;
+
+
+ EMITTER_STATE curState = m_pState->GetCurState();
+ if(curState != ES_WAITING_FOR_DOC && curState != ES_WRITING_DOC && curState != ES_DONE_WITH_DOC) {
+ m_pState->SetError("Unexpected end document");
+ return;
+ }
+
+ if(curState == ES_WRITING_DOC || curState == ES_DONE_WITH_DOC)
+ m_stream << '\n';
+ m_stream << "...\n";
+
+ m_pState->UnsetSeparation();
+ m_pState->SwitchState(ES_WAITING_FOR_DOC);
+ }
+
+ // EmitBeginSeq
+ void Emitter::EmitBeginSeq()
+ {
+ if(!good())
+ return;
+
+ // must have a long key if we're emitting a sequence
+ m_pState->StartLongKey();
+
+ PreAtomicWrite();
+
+ EMITTER_STATE curState = m_pState->GetCurState();
+ EMITTER_MANIP flowType = m_pState->GetFlowType(GT_SEQ);
+ if(flowType == Block) {
+ if(curState == ES_WRITING_BLOCK_SEQ_ENTRY ||
+ curState == ES_WRITING_BLOCK_MAP_KEY || curState == ES_WRITING_BLOCK_MAP_VALUE ||
+ curState == ES_WRITING_DOC
+ ) {
+ if(m_pState->RequiresHardSeparation() || curState != ES_WRITING_DOC) {
+ m_stream << "\n";
+ m_pState->UnsetSeparation();
+ }
+ }
+ m_pState->PushState(ES_WAITING_FOR_BLOCK_SEQ_ENTRY);
+ } else if(flowType == Flow) {
+ EmitSeparationIfNecessary();
+ m_stream << "[";
+ m_pState->PushState(ES_WAITING_FOR_FLOW_SEQ_ENTRY);
+ } else
+ assert(false);
+
+ m_pState->BeginGroup(GT_SEQ);
+ }
+
+ // EmitEndSeq
+ void Emitter::EmitEndSeq()
+ {
+ if(!good())
+ return;
+
+ if(m_pState->GetCurGroupType() != GT_SEQ)
+ return m_pState->SetError(ErrorMsg::UNEXPECTED_END_SEQ);
+
+ EMITTER_STATE curState = m_pState->GetCurState();
+ FLOW_TYPE flowType = m_pState->GetCurGroupFlowType();
+ if(flowType == FT_BLOCK) {
+ // Note: block sequences are *not* allowed to be empty, but we convert it
+ // to a flow sequence if it is
+ assert(curState == ES_DONE_WITH_BLOCK_SEQ_ENTRY || curState == ES_WAITING_FOR_BLOCK_SEQ_ENTRY);
+ if(curState == ES_WAITING_FOR_BLOCK_SEQ_ENTRY) {
+ // Note: only one of these will actually output anything for a given situation
+ EmitSeparationIfNecessary();
+ unsigned curIndent = m_pState->GetCurIndent();
+ m_stream << IndentTo(curIndent);
+
+ m_stream << "[]";
+ }
+ } else if(flowType == FT_FLOW) {
+ // Note: flow sequences are allowed to be empty
+ assert(curState == ES_DONE_WITH_FLOW_SEQ_ENTRY || curState == ES_WAITING_FOR_FLOW_SEQ_ENTRY);
+ m_stream << "]";
+ } else
+ assert(false);
+
+ m_pState->PopState();
+ m_pState->EndGroup(GT_SEQ);
+
+ PostAtomicWrite();
+ }
+
+ // EmitBeginMap
+ void Emitter::EmitBeginMap()
+ {
+ if(!good())
+ return;
+
+ // must have a long key if we're emitting a map
+ m_pState->StartLongKey();
+
+ PreAtomicWrite();
+
+ EMITTER_STATE curState = m_pState->GetCurState();
+ EMITTER_MANIP flowType = m_pState->GetFlowType(GT_MAP);
+ if(flowType == Block) {
+ if(curState == ES_WRITING_BLOCK_SEQ_ENTRY ||
+ curState == ES_WRITING_BLOCK_MAP_KEY || curState == ES_WRITING_BLOCK_MAP_VALUE ||
+ curState == ES_WRITING_DOC
+ ) {
+ if(m_pState->RequiresHardSeparation() || (curState != ES_WRITING_DOC && curState != ES_WRITING_BLOCK_SEQ_ENTRY)) {
+ m_stream << "\n";
+ m_pState->UnsetSeparation();
+ }
+ }
+ m_pState->PushState(ES_WAITING_FOR_BLOCK_MAP_ENTRY);
+ } else if(flowType == Flow) {
+ EmitSeparationIfNecessary();
+ m_stream << "{";
+ m_pState->PushState(ES_WAITING_FOR_FLOW_MAP_ENTRY);
+ } else
+ assert(false);
+
+ m_pState->BeginGroup(GT_MAP);
+ }
+
+ // EmitEndMap
+ void Emitter::EmitEndMap()
+ {
+ if(!good())
+ return;
+
+ if(m_pState->GetCurGroupType() != GT_MAP)
+ return m_pState->SetError(ErrorMsg::UNEXPECTED_END_MAP);
+
+ EMITTER_STATE curState = m_pState->GetCurState();
+ FLOW_TYPE flowType = m_pState->GetCurGroupFlowType();
+ if(flowType == FT_BLOCK) {
+ // Note: block sequences are *not* allowed to be empty, but we convert it
+ // to a flow sequence if it is
+ assert(curState == ES_DONE_WITH_BLOCK_MAP_VALUE || curState == ES_WAITING_FOR_BLOCK_MAP_ENTRY);
+ if(curState == ES_WAITING_FOR_BLOCK_MAP_ENTRY) {
+ // Note: only one of these will actually output anything for a given situation
+ EmitSeparationIfNecessary();
+ unsigned curIndent = m_pState->GetCurIndent();
+ m_stream << IndentTo(curIndent);
+ m_stream << "{}";
+ }
+ } else if(flowType == FT_FLOW) {
+ // Note: flow maps are allowed to be empty
+ assert(curState == ES_DONE_WITH_FLOW_MAP_VALUE || curState == ES_WAITING_FOR_FLOW_MAP_ENTRY);
+ EmitSeparationIfNecessary();
+ m_stream << "}";
+ } else
+ assert(false);
+
+ m_pState->PopState();
+ m_pState->EndGroup(GT_MAP);
+
+ PostAtomicWrite();
+ }
+
+ // EmitKey
+ void Emitter::EmitKey()
+ {
+ if(!good())
+ return;
+
+ EMITTER_STATE curState = m_pState->GetCurState();
+ FLOW_TYPE flowType = m_pState->GetCurGroupFlowType();
+ if(curState != ES_WAITING_FOR_BLOCK_MAP_ENTRY && curState != ES_DONE_WITH_BLOCK_MAP_VALUE
+ && curState != ES_WAITING_FOR_FLOW_MAP_ENTRY && curState != ES_DONE_WITH_FLOW_MAP_VALUE)
+ return m_pState->SetError(ErrorMsg::UNEXPECTED_KEY_TOKEN);
+
+ if(flowType == FT_BLOCK) {
+ if(curState == ES_DONE_WITH_BLOCK_MAP_VALUE)
+ m_stream << '\n';
+ unsigned curIndent = m_pState->GetCurIndent();
+ m_stream << IndentTo(curIndent);
+ m_pState->UnsetSeparation();
+ m_pState->SwitchState(ES_WAITING_FOR_BLOCK_MAP_KEY);
+ } else if(flowType == FT_FLOW) {
+ EmitSeparationIfNecessary();
+ if(curState == ES_DONE_WITH_FLOW_MAP_VALUE) {
+ m_stream << ',';
+ m_pState->RequireSoftSeparation();
+ }
+ m_pState->SwitchState(ES_WAITING_FOR_FLOW_MAP_KEY);
+ } else
+ assert(false);
+
+ if(m_pState->GetMapKeyFormat() == LongKey)
+ m_pState->StartLongKey();
+ else if(m_pState->GetMapKeyFormat() == Auto)
+ m_pState->StartSimpleKey();
+ else
+ assert(false);
+ }
+
+ // EmitValue
+ void Emitter::EmitValue()
+ {
+ if(!good())
+ return;
+
+ EMITTER_STATE curState = m_pState->GetCurState();
+ FLOW_TYPE flowType = m_pState->GetCurGroupFlowType();
+ if(curState != ES_DONE_WITH_BLOCK_MAP_KEY && curState != ES_DONE_WITH_FLOW_MAP_KEY)
+ return m_pState->SetError(ErrorMsg::UNEXPECTED_VALUE_TOKEN);
+
+ if(flowType == FT_BLOCK) {
+ if(m_pState->CurrentlyInLongKey()) {
+ m_stream << '\n';
+ m_stream << IndentTo(m_pState->GetCurIndent());
+ m_stream << ':';
+ m_pState->RequireSoftSeparation();
+ }
+ m_pState->SwitchState(ES_WAITING_FOR_BLOCK_MAP_VALUE);
+ } else if(flowType == FT_FLOW) {
+ m_pState->SwitchState(ES_WAITING_FOR_FLOW_MAP_VALUE);
+ } else
+ assert(false);
+ }
+
+ // EmitNewline
+ void Emitter::EmitNewline()
+ {
+ if(!good())
+ return;
+
+ if(CanEmitNewline()) {
+ m_stream << '\n';
+ m_pState->UnsetSeparation();
+ }
+ }
+
+ bool Emitter::CanEmitNewline() const
+ {
+ FLOW_TYPE flowType = m_pState->GetCurGroupFlowType();
+ if(flowType == FT_BLOCK && m_pState->CurrentlyInLongKey())
+ return true;
+
+ EMITTER_STATE curState = m_pState->GetCurState();
+ return curState != ES_DONE_WITH_BLOCK_MAP_KEY && curState != ES_WAITING_FOR_BLOCK_MAP_VALUE && curState != ES_WRITING_BLOCK_MAP_VALUE;
+ }
+
+ // *******************************************************************************************
+ // overloads of Write
+
+ Emitter& Emitter::Write(const std::string& str)
+ {
+ if(!good())
+ return *this;
+
+ // literal scalars must use long keys
+ if(m_pState->GetStringFormat() == Literal && m_pState->GetCurGroupFlowType() != FT_FLOW)
+ m_pState->StartLongKey();
+
+ PreAtomicWrite();
+ EmitSeparationIfNecessary();
+
+ bool escapeNonAscii = m_pState->GetOutputCharset() == EscapeNonAscii;
+ EMITTER_MANIP strFmt = m_pState->GetStringFormat();
+ FLOW_TYPE flowType = m_pState->GetCurGroupFlowType();
+ unsigned curIndent = m_pState->GetCurIndent();
+
+ switch(strFmt) {
+ case Auto:
+ Utils::WriteString(m_stream, str, flowType == FT_FLOW, escapeNonAscii);
+ break;
+ case SingleQuoted:
+ if(!Utils::WriteSingleQuotedString(m_stream, str)) {
+ m_pState->SetError(ErrorMsg::SINGLE_QUOTED_CHAR);
+ return *this;
+ }
+ break;
+ case DoubleQuoted:
+ Utils::WriteDoubleQuotedString(m_stream, str, escapeNonAscii);
+ break;
+ case Literal:
+ if(flowType == FT_FLOW)
+ Utils::WriteString(m_stream, str, flowType == FT_FLOW, escapeNonAscii);
+ else
+ Utils::WriteLiteralString(m_stream, str, curIndent + m_pState->GetIndent());
+ break;
+ default:
+ assert(false);
+ }
+
+ PostAtomicWrite();
+ return *this;
+ }
+
+ void Emitter::PreWriteIntegralType(std::stringstream& str)
+ {
+ PreAtomicWrite();
+ EmitSeparationIfNecessary();
+
+ EMITTER_MANIP intFmt = m_pState->GetIntFormat();
+ switch(intFmt) {
+ case Dec:
+ str << std::dec;
+ break;
+ case Hex:
+ str << "0x";
+ str << std::hex;
+ break;
+ case Oct:
+ str << "0";
+ str << std::oct;
+ break;
+ default:
+ assert(false);
+ }
+ }
+
+ void Emitter::PreWriteStreamable(std::stringstream&)
+ {
+ PreAtomicWrite();
+ EmitSeparationIfNecessary();
+ }
+
+ unsigned Emitter::GetFloatPrecision() const
+ {
+ return m_pState->GetFloatPrecision();
+ }
+
+ unsigned Emitter::GetDoublePrecision() const
+ {
+ return m_pState->GetDoublePrecision();
+ }
+
+ void Emitter::PostWriteIntegralType(const std::stringstream& str)
+ {
+ m_stream << str.str();
+ PostAtomicWrite();
+ }
+
+ void Emitter::PostWriteStreamable(const std::stringstream& str)
+ {
+ m_stream << str.str();
+ PostAtomicWrite();
+ }
+
+ const char *Emitter::ComputeFullBoolName(bool b) const
+ {
+ const EMITTER_MANIP mainFmt = (m_pState->GetBoolLengthFormat() == ShortBool ? YesNoBool : m_pState->GetBoolFormat());
+ const EMITTER_MANIP caseFmt = m_pState->GetBoolCaseFormat();
+ switch(mainFmt) {
+ case YesNoBool:
+ switch(caseFmt) {
+ case UpperCase: return b ? "YES" : "NO";
+ case CamelCase: return b ? "Yes" : "No";
+ case LowerCase: return b ? "yes" : "no";
+ default: break;
+ }
+ break;
+ case OnOffBool:
+ switch(caseFmt) {
+ case UpperCase: return b ? "ON" : "OFF";
+ case CamelCase: return b ? "On" : "Off";
+ case LowerCase: return b ? "on" : "off";
+ default: break;
+ }
+ break;
+ case TrueFalseBool:
+ switch(caseFmt) {
+ case UpperCase: return b ? "TRUE" : "FALSE";
+ case CamelCase: return b ? "True" : "False";
+ case LowerCase: return b ? "true" : "false";
+ default: break;
+ }
+ break;
+ default:
+ break;
+ }
+ return b ? "y" : "n"; // should never get here, but it can't hurt to give these answers
+ }
+
+ Emitter& Emitter::Write(bool b)
+ {
+ if(!good())
+ return *this;
+
+ PreAtomicWrite();
+ EmitSeparationIfNecessary();
+
+ const char *name = ComputeFullBoolName(b);
+ if(m_pState->GetBoolLengthFormat() == ShortBool)
+ m_stream << name[0];
+ else
+ m_stream << name;
+
+ PostAtomicWrite();
+ return *this;
+ }
+
+ Emitter& Emitter::Write(char ch)
+ {
+ if(!good())
+ return *this;
+
+ PreAtomicWrite();
+ EmitSeparationIfNecessary();
+
+ Utils::WriteChar(m_stream, ch);
+
+ PostAtomicWrite();
+ return *this;
+ }
+
+ Emitter& Emitter::Write(const _Alias& alias)
+ {
+ if(!good())
+ return *this;
+
+ PreAtomicWrite();
+ EmitSeparationIfNecessary();
+ if(!Utils::WriteAlias(m_stream, alias.content)) {
+ m_pState->SetError(ErrorMsg::INVALID_ALIAS);
+ return *this;
+ }
+ PostAtomicWrite();
+ return *this;
+ }
+
+ Emitter& Emitter::Write(const _Anchor& anchor)
+ {
+ if(!good())
+ return *this;
+
+ PreAtomicWrite();
+ EmitSeparationIfNecessary();
+ if(!Utils::WriteAnchor(m_stream, anchor.content)) {
+ m_pState->SetError(ErrorMsg::INVALID_ANCHOR);
+ return *this;
+ }
+ m_pState->RequireHardSeparation();
+ // Note: no PostAtomicWrite() because we need another value for this node
+ return *this;
+ }
+
+ Emitter& Emitter::Write(const _Tag& tag)
+ {
+ if(!good())
+ return *this;
+
+ PreAtomicWrite();
+ EmitSeparationIfNecessary();
+
+ bool success = false;
+ if(tag.type == _Tag::Type::Verbatim)
+ success = Utils::WriteTag(m_stream, tag.content, true);
+ else if(tag.type == _Tag::Type::PrimaryHandle)
+ success = Utils::WriteTag(m_stream, tag.content, false);
+ else
+ success = Utils::WriteTagWithPrefix(m_stream, tag.prefix, tag.content);
+
+ if(!success) {
+ m_pState->SetError(ErrorMsg::INVALID_TAG);
+ return *this;
+ }
+
+ m_pState->RequireHardSeparation();
+ // Note: no PostAtomicWrite() because we need another value for this node
+ return *this;
+ }
+
+ void Emitter::EmitKindTag()
+ {
+ Write(LocalTag(""));
+ }
+
+ Emitter& Emitter::Write(const _Comment& comment)
+ {
+ if(!good())
+ return *this;
+
+ if(m_stream.col() > 0)
+ m_stream << Indentation(m_pState->GetPreCommentIndent());
+ Utils::WriteComment(m_stream, comment.content, m_pState->GetPostCommentIndent());
+ m_pState->RequireHardSeparation();
+ m_pState->ForceHardSeparation();
+
+ return *this;
+ }
+
+ Emitter& Emitter::Write(const _Null& /*null*/)
+ {
+ if(!good())
+ return *this;
+
+ PreAtomicWrite();
+ EmitSeparationIfNecessary();
+ m_stream << "~";
+ PostAtomicWrite();
+ return *this;
+ }
+
+ Emitter& Emitter::Write(const Binary& binary)
+ {
+ Write(SecondaryTag("binary"));
+
+ if(!good())
+ return *this;
+
+ PreAtomicWrite();
+ EmitSeparationIfNecessary();
+ Utils::WriteBinary(m_stream, binary);
+ PostAtomicWrite();
+ return *this;
+ }
+}
+
diff --git a/external_libs/yaml-cpp/src/emitterstate.cpp b/external_libs/yaml-cpp/src/emitterstate.cpp
new file mode 100644
index 00000000..562e82c9
--- /dev/null
+++ b/external_libs/yaml-cpp/src/emitterstate.cpp
@@ -0,0 +1,284 @@
+#include "emitterstate.h"
+#include "yaml-cpp/exceptions.h"
+#include <limits>
+
+namespace YAML
+{
+ EmitterState::EmitterState(): m_isGood(true), m_curIndent(0), m_requiresSoftSeparation(false), m_requiresHardSeparation(false)
+ {
+ // start up
+ m_stateStack.push(ES_WAITING_FOR_DOC);
+
+ // set default global manipulators
+ m_charset.set(EmitNonAscii);
+ m_strFmt.set(Auto);
+ m_boolFmt.set(TrueFalseBool);
+ m_boolLengthFmt.set(LongBool);
+ m_boolCaseFmt.set(LowerCase);
+ m_intFmt.set(Dec);
+ m_indent.set(2);
+ m_preCommentIndent.set(2);
+ m_postCommentIndent.set(1);
+ m_seqFmt.set(Block);
+ m_mapFmt.set(Block);
+ m_mapKeyFmt.set(Auto);
+ m_floatPrecision.set(6);
+ m_doublePrecision.set(15);
+ }
+
+ EmitterState::~EmitterState()
+ {
+ }
+
+ // SetLocalValue
+ // . We blindly tries to set all possible formatters to this value
+ // . Only the ones that make sense will be accepted
+ void EmitterState::SetLocalValue(EMITTER_MANIP value)
+ {
+ SetOutputCharset(value, LOCAL);
+ SetStringFormat(value, LOCAL);
+ SetBoolFormat(value, LOCAL);
+ SetBoolCaseFormat(value, LOCAL);
+ SetBoolLengthFormat(value, LOCAL);
+ SetIntFormat(value, LOCAL);
+ SetFlowType(GT_SEQ, value, LOCAL);
+ SetFlowType(GT_MAP, value, LOCAL);
+ SetMapKeyFormat(value, LOCAL);
+ }
+
+ void EmitterState::BeginGroup(GROUP_TYPE type)
+ {
+ unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
+ m_curIndent += lastIndent;
+
+ std::auto_ptr<Group> pGroup(new Group(type));
+
+ // transfer settings (which last until this group is done)
+ pGroup->modifiedSettings = m_modifiedSettings;
+
+ // set up group
+ pGroup->flow = GetFlowType(type);
+ pGroup->indent = GetIndent();
+ pGroup->usingLongKey = (GetMapKeyFormat() == LongKey ? true : false);
+
+ m_groups.push(pGroup);
+ }
+
+ void EmitterState::EndGroup(GROUP_TYPE type)
+ {
+ if(m_groups.empty())
+ return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
+
+ // get rid of the current group
+ {
+ std::auto_ptr<Group> pFinishedGroup = m_groups.pop();
+ if(pFinishedGroup->type != type)
+ return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
+ }
+
+ // reset old settings
+ unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
+ assert(m_curIndent >= lastIndent);
+ m_curIndent -= lastIndent;
+
+ // some global settings that we changed may have been overridden
+ // by a local setting we just popped, so we need to restore them
+ m_globalModifiedSettings.restore();
+ }
+
+ GROUP_TYPE EmitterState::GetCurGroupType() const
+ {
+ if(m_groups.empty())
+ return GT_NONE;
+
+ return m_groups.top().type;
+ }
+
+ FLOW_TYPE EmitterState::GetCurGroupFlowType() const
+ {
+ if(m_groups.empty())
+ return FT_NONE;
+
+ return (m_groups.top().flow == Flow ? FT_FLOW : FT_BLOCK);
+ }
+
+ bool EmitterState::CurrentlyInLongKey()
+ {
+ if(m_groups.empty())
+ return false;
+ return m_groups.top().usingLongKey;
+ }
+
+ void EmitterState::StartLongKey()
+ {
+ if(!m_groups.empty())
+ m_groups.top().usingLongKey = true;
+ }
+
+ void EmitterState::StartSimpleKey()
+ {
+ if(!m_groups.empty())
+ m_groups.top().usingLongKey = false;
+ }
+
+ void EmitterState::ClearModifiedSettings()
+ {
+ m_modifiedSettings.clear();
+ }
+
+ bool EmitterState::SetOutputCharset(EMITTER_MANIP value, FMT_SCOPE scope)
+ {
+ switch(value) {
+ case EmitNonAscii:
+ case EscapeNonAscii:
+ _Set(m_charset, value, scope);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool EmitterState::SetStringFormat(EMITTER_MANIP value, FMT_SCOPE scope)
+ {
+ switch(value) {
+ case Auto:
+ case SingleQuoted:
+ case DoubleQuoted:
+ case Literal:
+ _Set(m_strFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FMT_SCOPE scope)
+ {
+ switch(value) {
+ case OnOffBool:
+ case TrueFalseBool:
+ case YesNoBool:
+ _Set(m_boolFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value, FMT_SCOPE scope)
+ {
+ switch(value) {
+ case LongBool:
+ case ShortBool:
+ _Set(m_boolLengthFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value, FMT_SCOPE scope)
+ {
+ switch(value) {
+ case UpperCase:
+ case LowerCase:
+ case CamelCase:
+ _Set(m_boolCaseFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool EmitterState::SetIntFormat(EMITTER_MANIP value, FMT_SCOPE scope)
+ {
+ switch(value) {
+ case Dec:
+ case Hex:
+ case Oct:
+ _Set(m_intFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool EmitterState::SetIndent(unsigned value, FMT_SCOPE scope)
+ {
+ if(value == 0)
+ return false;
+
+ _Set(m_indent, value, scope);
+ return true;
+ }
+
+ bool EmitterState::SetPreCommentIndent(unsigned value, FMT_SCOPE scope)
+ {
+ if(value == 0)
+ return false;
+
+ _Set(m_preCommentIndent, value, scope);
+ return true;
+ }
+
+ bool EmitterState::SetPostCommentIndent(unsigned value, FMT_SCOPE scope)
+ {
+ if(value == 0)
+ return false;
+
+ _Set(m_postCommentIndent, value, scope);
+ return true;
+ }
+
+ bool EmitterState::SetFlowType(GROUP_TYPE groupType, EMITTER_MANIP value, FMT_SCOPE scope)
+ {
+ switch(value) {
+ case Block:
+ case Flow:
+ _Set(groupType == GT_SEQ ? m_seqFmt : m_mapFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ EMITTER_MANIP EmitterState::GetFlowType(GROUP_TYPE groupType) const
+ {
+ // force flow style if we're currently in a flow
+ FLOW_TYPE flowType = GetCurGroupFlowType();
+ if(flowType == FT_FLOW)
+ return Flow;
+
+ // otherwise, go with what's asked of use
+ return (groupType == GT_SEQ ? m_seqFmt.get() : m_mapFmt.get());
+ }
+
+ bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FMT_SCOPE scope)
+ {
+ switch(value) {
+ case Auto:
+ case LongKey:
+ _Set(m_mapKeyFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool EmitterState::SetFloatPrecision(int value, FMT_SCOPE scope)
+ {
+ if(value < 0 || value > std::numeric_limits<float>::digits10)
+ return false;
+ _Set(m_floatPrecision, value, scope);
+ return true;
+ }
+
+ bool EmitterState::SetDoublePrecision(int value, FMT_SCOPE scope)
+ {
+ if(value < 0 || value > std::numeric_limits<double>::digits10)
+ return false;
+ _Set(m_doublePrecision, value, scope);
+ return true;
+ }
+}
+
diff --git a/external_libs/yaml-cpp/src/emitterstate.h b/external_libs/yaml-cpp/src/emitterstate.h
new file mode 100644
index 00000000..5698e325
--- /dev/null
+++ b/external_libs/yaml-cpp/src/emitterstate.h
@@ -0,0 +1,217 @@
+#ifndef EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include "ptr_stack.h"
+#include "setting.h"
+#include "yaml-cpp/emittermanip.h"
+#include <cassert>
+#include <vector>
+#include <stack>
+#include <memory>
+
+namespace YAML
+{
+ enum FMT_SCOPE {
+ LOCAL,
+ GLOBAL
+ };
+
+ enum GROUP_TYPE {
+ GT_NONE,
+ GT_SEQ,
+ GT_MAP
+ };
+
+ enum FLOW_TYPE {
+ FT_NONE,
+ FT_FLOW,
+ FT_BLOCK
+ };
+
+ enum NODE_STATE {
+ NS_START,
+ NS_READY_FOR_ATOM,
+ NS_END
+ };
+
+ enum EMITTER_STATE {
+ ES_WAITING_FOR_DOC,
+ ES_WRITING_DOC,
+ ES_DONE_WITH_DOC,
+
+ // block seq
+ ES_WAITING_FOR_BLOCK_SEQ_ENTRY,
+ ES_WRITING_BLOCK_SEQ_ENTRY,
+ ES_DONE_WITH_BLOCK_SEQ_ENTRY,
+
+ // flow seq
+ ES_WAITING_FOR_FLOW_SEQ_ENTRY,
+ ES_WRITING_FLOW_SEQ_ENTRY,
+ ES_DONE_WITH_FLOW_SEQ_ENTRY,
+
+ // block map
+ ES_WAITING_FOR_BLOCK_MAP_ENTRY,
+ ES_WAITING_FOR_BLOCK_MAP_KEY,
+ ES_WRITING_BLOCK_MAP_KEY,
+ ES_DONE_WITH_BLOCK_MAP_KEY,
+ ES_WAITING_FOR_BLOCK_MAP_VALUE,
+ ES_WRITING_BLOCK_MAP_VALUE,
+ ES_DONE_WITH_BLOCK_MAP_VALUE,
+
+ // flow map
+ ES_WAITING_FOR_FLOW_MAP_ENTRY,
+ ES_WAITING_FOR_FLOW_MAP_KEY,
+ ES_WRITING_FLOW_MAP_KEY,
+ ES_DONE_WITH_FLOW_MAP_KEY,
+ ES_WAITING_FOR_FLOW_MAP_VALUE,
+ ES_WRITING_FLOW_MAP_VALUE,
+ ES_DONE_WITH_FLOW_MAP_VALUE
+ };
+
+ class EmitterState
+ {
+ public:
+ EmitterState();
+ ~EmitterState();
+
+ // basic state checking
+ bool good() const { return m_isGood; }
+ const std::string GetLastError() const { return m_lastError; }
+ void SetError(const std::string& error) { m_isGood = false; m_lastError = error; }
+
+ // main state of the machine
+ EMITTER_STATE GetCurState() const { return m_stateStack.top(); }
+ void SwitchState(EMITTER_STATE state) { PopState(); PushState(state); }
+ void PushState(EMITTER_STATE state) { m_stateStack.push(state); }
+ void PopState() { m_stateStack.pop(); }
+
+ void SetLocalValue(EMITTER_MANIP value);
+
+ // group handling
+ void BeginGroup(GROUP_TYPE type);
+ void EndGroup(GROUP_TYPE type);
+
+ GROUP_TYPE GetCurGroupType() const;
+ FLOW_TYPE GetCurGroupFlowType() const;
+ int GetCurIndent() const { return m_curIndent; }
+
+ bool CurrentlyInLongKey();
+ void StartLongKey();
+ void StartSimpleKey();
+
+ bool RequiresSoftSeparation() const { return m_requiresSoftSeparation; }
+ bool RequiresHardSeparation() const { return m_requiresHardSeparation; }
+ void RequireSoftSeparation() { m_requiresSoftSeparation = true; }
+ void RequireHardSeparation() { m_requiresSoftSeparation = true; m_requiresHardSeparation = true; }
+ void ForceHardSeparation() { m_requiresSoftSeparation = false; }
+ void UnsetSeparation() { m_requiresSoftSeparation = false; m_requiresHardSeparation = false; }
+
+ void ClearModifiedSettings();
+
+ // formatters
+ bool SetOutputCharset(EMITTER_MANIP value, FMT_SCOPE scope);
+ EMITTER_MANIP GetOutputCharset() const { return m_charset.get(); }
+
+ bool SetStringFormat(EMITTER_MANIP value, FMT_SCOPE scope);
+ EMITTER_MANIP GetStringFormat() const { return m_strFmt.get(); }
+
+ bool SetBoolFormat(EMITTER_MANIP value, FMT_SCOPE scope);
+ EMITTER_MANIP GetBoolFormat() const { return m_boolFmt.get(); }
+
+ bool SetBoolLengthFormat(EMITTER_MANIP value, FMT_SCOPE scope);
+ EMITTER_MANIP GetBoolLengthFormat() const { return m_boolLengthFmt.get(); }
+
+ bool SetBoolCaseFormat(EMITTER_MANIP value, FMT_SCOPE scope);
+ EMITTER_MANIP GetBoolCaseFormat() const { return m_boolCaseFmt.get(); }
+
+ bool SetIntFormat(EMITTER_MANIP value, FMT_SCOPE scope);
+ EMITTER_MANIP GetIntFormat() const { return m_intFmt.get(); }
+
+ bool SetIndent(unsigned value, FMT_SCOPE scope);
+ int GetIndent() const { return m_indent.get(); }
+
+ bool SetPreCommentIndent(unsigned value, FMT_SCOPE scope);
+ int GetPreCommentIndent() const { return m_preCommentIndent.get(); }
+ bool SetPostCommentIndent(unsigned value, FMT_SCOPE scope);
+ int GetPostCommentIndent() const { return m_postCommentIndent.get(); }
+
+ bool SetFlowType(GROUP_TYPE groupType, EMITTER_MANIP value, FMT_SCOPE scope);
+ EMITTER_MANIP GetFlowType(GROUP_TYPE groupType) const;
+
+ bool SetMapKeyFormat(EMITTER_MANIP value, FMT_SCOPE scope);
+ EMITTER_MANIP GetMapKeyFormat() const { return m_mapKeyFmt.get(); }
+
+ bool SetFloatPrecision(int value, FMT_SCOPE scope);
+ unsigned GetFloatPrecision() const { return m_floatPrecision.get(); }
+ bool SetDoublePrecision(int value, FMT_SCOPE scope);
+ unsigned GetDoublePrecision() const { return m_doublePrecision.get(); }
+
+ private:
+ template <typename T>
+ void _Set(Setting<T>& fmt, T value, FMT_SCOPE scope);
+
+ private:
+ // basic state ok?
+ bool m_isGood;
+ std::string m_lastError;
+
+ // other state
+ std::stack<EMITTER_STATE> m_stateStack;
+
+ Setting<EMITTER_MANIP> m_charset;
+ Setting<EMITTER_MANIP> m_strFmt;
+ Setting<EMITTER_MANIP> m_boolFmt;
+ Setting<EMITTER_MANIP> m_boolLengthFmt;
+ Setting<EMITTER_MANIP> m_boolCaseFmt;
+ Setting<EMITTER_MANIP> m_intFmt;
+ Setting<unsigned> m_indent;
+ Setting<unsigned> m_preCommentIndent, m_postCommentIndent;
+ Setting<EMITTER_MANIP> m_seqFmt;
+ Setting<EMITTER_MANIP> m_mapFmt;
+ Setting<EMITTER_MANIP> m_mapKeyFmt;
+ Setting<int> m_floatPrecision;
+ Setting<int> m_doublePrecision;
+
+ SettingChanges m_modifiedSettings;
+ SettingChanges m_globalModifiedSettings;
+
+ struct Group {
+ Group(GROUP_TYPE type_): type(type_), usingLongKey(false), indent(0) {}
+
+ GROUP_TYPE type;
+ EMITTER_MANIP flow;
+ bool usingLongKey;
+ int indent;
+
+ SettingChanges modifiedSettings;
+ };
+
+ ptr_stack<Group> m_groups;
+ unsigned m_curIndent;
+ bool m_requiresSoftSeparation;
+ bool m_requiresHardSeparation;
+ };
+
+ template <typename T>
+ void EmitterState::_Set(Setting<T>& fmt, T value, FMT_SCOPE scope) {
+ switch(scope) {
+ case LOCAL:
+ m_modifiedSettings.push(fmt.set(value));
+ break;
+ case GLOBAL:
+ fmt.set(value);
+ m_globalModifiedSettings.push(fmt.set(value)); // this pushes an identity set, so when we restore,
+ // it restores to the value here, and not the previous one
+ break;
+ default:
+ assert(false);
+ }
+ }
+}
+
+#endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/src/emitterutils.cpp b/external_libs/yaml-cpp/src/emitterutils.cpp
new file mode 100644
index 00000000..3d184d6c
--- /dev/null
+++ b/external_libs/yaml-cpp/src/emitterutils.cpp
@@ -0,0 +1,378 @@
+#include "emitterutils.h"
+#include "exp.h"
+#include "indentation.h"
+#include "yaml-cpp/binary.h"
+#include "yaml-cpp/exceptions.h"
+#include "stringsource.h"
+#include <sstream>
+#include <iomanip>
+
+namespace YAML
+{
+ namespace Utils
+ {
+ namespace {
+ enum {REPLACEMENT_CHARACTER = 0xFFFD};
+
+ bool IsAnchorChar(int ch) { // test for ns-anchor-char
+ switch (ch) {
+ case ',': case '[': case ']': case '{': case '}': // c-flow-indicator
+ case ' ': case '\t': // s-white
+ case 0xFEFF: // c-byte-order-mark
+ case 0xA: case 0xD: // b-char
+ return false;
+ case 0x85:
+ return true;
+ }
+
+ if (ch < 0x20)
+ return false;
+
+ if (ch < 0x7E)
+ return true;
+
+ if (ch < 0xA0)
+ return false;
+ if (ch >= 0xD800 && ch <= 0xDFFF)
+ return false;
+ if ((ch & 0xFFFE) == 0xFFFE)
+ return false;
+ if ((ch >= 0xFDD0) && (ch <= 0xFDEF))
+ return false;
+ if (ch > 0x10FFFF)
+ return false;
+
+ return true;
+ }
+
+ int Utf8BytesIndicated(char ch) {
+ int byteVal = static_cast<unsigned char>(ch);
+ switch (byteVal >> 4) {
+ case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
+ return 1;
+ case 12: case 13:
+ return 2;
+ case 14:
+ return 3;
+ case 15:
+ return 4;
+ default:
+ return -1;
+ }
+ }
+
+ bool IsTrailingByte(char ch) {
+ return (ch & 0xC0) == 0x80;
+ }
+
+ bool GetNextCodePointAndAdvance(int& codePoint, std::string::const_iterator& first, std::string::const_iterator last) {
+ if (first == last)
+ return false;
+
+ int nBytes = Utf8BytesIndicated(*first);
+ if (nBytes < 1) {
+ // Bad lead byte
+ ++first;
+ codePoint = REPLACEMENT_CHARACTER;
+ return true;
+ }
+
+ if (nBytes == 1) {
+ codePoint = *first++;
+ return true;
+ }
+
+ // Gather bits from trailing bytes
+ codePoint = static_cast<unsigned char>(*first) & ~(0xFF << (7 - nBytes));
+ ++first;
+ --nBytes;
+ for (; nBytes > 0; ++first, --nBytes) {
+ if ((first == last) || !IsTrailingByte(*first)) {
+ codePoint = REPLACEMENT_CHARACTER;
+ break;
+ }
+ codePoint <<= 6;
+ codePoint |= *first & 0x3F;
+ }
+
+ // Check for illegal code points
+ if (codePoint > 0x10FFFF)
+ codePoint = REPLACEMENT_CHARACTER;
+ else if (codePoint >= 0xD800 && codePoint <= 0xDFFF)
+ codePoint = REPLACEMENT_CHARACTER;
+ else if ((codePoint & 0xFFFE) == 0xFFFE)
+ codePoint = REPLACEMENT_CHARACTER;
+ else if (codePoint >= 0xFDD0 && codePoint <= 0xFDEF)
+ codePoint = REPLACEMENT_CHARACTER;
+ return true;
+ }
+
+ void WriteCodePoint(ostream& out, int codePoint) {
+ if (codePoint < 0 || codePoint > 0x10FFFF) {
+ codePoint = REPLACEMENT_CHARACTER;
+ }
+ if (codePoint < 0x7F) {
+ out << static_cast<char>(codePoint);
+ } else if (codePoint < 0x7FF) {
+ out << static_cast<char>(0xC0 | (codePoint >> 6))
+ << static_cast<char>(0x80 | (codePoint & 0x3F));
+ } else if (codePoint < 0xFFFF) {
+ out << static_cast<char>(0xE0 | (codePoint >> 12))
+ << static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F))
+ << static_cast<char>(0x80 | (codePoint & 0x3F));
+ } else {
+ out << static_cast<char>(0xF0 | (codePoint >> 18))
+ << static_cast<char>(0x80 | ((codePoint >> 12) & 0x3F))
+ << static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F))
+ << static_cast<char>(0x80 | (codePoint & 0x3F));
+ }
+ }
+
+ bool IsValidPlainScalar(const std::string& str, bool inFlow, bool allowOnlyAscii) {
+ if(str.empty())
+ return false;
+
+ // first check the start
+ const RegEx& start = (inFlow ? Exp::PlainScalarInFlow() : Exp::PlainScalar());
+ if(!start.Matches(str))
+ return false;
+
+ // and check the end for plain whitespace (which can't be faithfully kept in a plain scalar)
+ if(!str.empty() && *str.rbegin() == ' ')
+ return false;
+
+ // then check until something is disallowed
+ const RegEx& disallowed = (inFlow ? Exp::EndScalarInFlow() : Exp::EndScalar())
+ || (Exp::BlankOrBreak() + Exp::Comment())
+ || Exp::NotPrintable()
+ || Exp::Utf8_ByteOrderMark()
+ || Exp::Break()
+ || Exp::Tab();
+ StringCharSource buffer(str.c_str(), str.size());
+ while(buffer) {
+ if(disallowed.Matches(buffer))
+ return false;
+ if(allowOnlyAscii && (0x7F < static_cast<unsigned char>(buffer[0])))
+ return false;
+ ++buffer;
+ }
+
+ return true;
+ }
+
+ void WriteDoubleQuoteEscapeSequence(ostream& out, int codePoint) {
+ static const char hexDigits[] = "0123456789abcdef";
+
+ char escSeq[] = "\\U00000000";
+ int digits = 8;
+ if (codePoint < 0xFF) {
+ escSeq[1] = 'x';
+ digits = 2;
+ } else if (codePoint < 0xFFFF) {
+ escSeq[1] = 'u';
+ digits = 4;
+ }
+
+ // Write digits into the escape sequence
+ int i = 2;
+ for (; digits > 0; --digits, ++i) {
+ escSeq[i] = hexDigits[(codePoint >> (4 * (digits - 1))) & 0xF];
+ }
+
+ escSeq[i] = 0; // terminate with NUL character
+ out << escSeq;
+ }
+
+ bool WriteAliasName(ostream& out, const std::string& str) {
+ int codePoint;
+ for(std::string::const_iterator i = str.begin();
+ GetNextCodePointAndAdvance(codePoint, i, str.end());
+ )
+ {
+ if (!IsAnchorChar(codePoint))
+ return false;
+
+ WriteCodePoint(out, codePoint);
+ }
+ return true;
+ }
+ }
+
+ bool WriteString(ostream& out, const std::string& str, bool inFlow, bool escapeNonAscii)
+ {
+ if(IsValidPlainScalar(str, inFlow, escapeNonAscii)) {
+ out << str;
+ return true;
+ } else
+ return WriteDoubleQuotedString(out, str, escapeNonAscii);
+ }
+
+ bool WriteSingleQuotedString(ostream& out, const std::string& str)
+ {
+ out << "'";
+ int codePoint;
+ for(std::string::const_iterator i = str.begin();
+ GetNextCodePointAndAdvance(codePoint, i, str.end());
+ )
+ {
+ if (codePoint == '\n')
+ return false; // We can't handle a new line and the attendant indentation yet
+
+ if (codePoint == '\'')
+ out << "''";
+ else
+ WriteCodePoint(out, codePoint);
+ }
+ out << "'";
+ return true;
+ }
+
+ bool WriteDoubleQuotedString(ostream& out, const std::string& str, bool escapeNonAscii)
+ {
+ out << "\"";
+ int codePoint;
+ for(std::string::const_iterator i = str.begin();
+ GetNextCodePointAndAdvance(codePoint, i, str.end());
+ )
+ {
+ if (codePoint == '\"')
+ out << "\\\"";
+ else if (codePoint == '\\')
+ out << "\\\\";
+ else if (codePoint < 0x20 || (codePoint >= 0x80 && codePoint <= 0xA0)) // Control characters and non-breaking space
+ WriteDoubleQuoteEscapeSequence(out, codePoint);
+ else if (codePoint == 0xFEFF) // Byte order marks (ZWNS) should be escaped (YAML 1.2, sec. 5.2)
+ WriteDoubleQuoteEscapeSequence(out, codePoint);
+ else if (escapeNonAscii && codePoint > 0x7E)
+ WriteDoubleQuoteEscapeSequence(out, codePoint);
+ else
+ WriteCodePoint(out, codePoint);
+ }
+ out << "\"";
+ return true;
+ }
+
+ bool WriteLiteralString(ostream& out, const std::string& str, int indent)
+ {
+ out << "|\n";
+ out << IndentTo(indent);
+ int codePoint;
+ for(std::string::const_iterator i = str.begin();
+ GetNextCodePointAndAdvance(codePoint, i, str.end());
+ )
+ {
+ if (codePoint == '\n')
+ out << "\n" << IndentTo(indent);
+ else
+ WriteCodePoint(out, codePoint);
+ }
+ return true;
+ }
+
+ bool WriteChar(ostream& out, char ch)
+ {
+ if(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z'))
+ out << ch;
+ else if((0x20 <= ch && ch <= 0x7e) || ch == ' ')
+ out << "\"" << ch << "\"";
+ else if(ch == '\t')
+ out << "\"\\t\"";
+ else if(ch == '\n')
+ out << "\"\\n\"";
+ else if(ch == '\b')
+ out << "\"\\b\"";
+ else {
+ out << "\"";
+ WriteDoubleQuoteEscapeSequence(out, ch);
+ out << "\"";
+ }
+ return true;
+ }
+
+ bool WriteComment(ostream& out, const std::string& str, int postCommentIndent)
+ {
+ const unsigned curIndent = out.col();
+ out << "#" << Indentation(postCommentIndent);
+ int codePoint;
+ for(std::string::const_iterator i = str.begin();
+ GetNextCodePointAndAdvance(codePoint, i, str.end());
+ )
+ {
+ if(codePoint == '\n')
+ out << "\n" << IndentTo(curIndent) << "#" << Indentation(postCommentIndent);
+ else
+ WriteCodePoint(out, codePoint);
+ }
+ return true;
+ }
+
+ bool WriteAlias(ostream& out, const std::string& str)
+ {
+ out << "*";
+ return WriteAliasName(out, str);
+ }
+
+ bool WriteAnchor(ostream& out, const std::string& str)
+ {
+ out << "&";
+ return WriteAliasName(out, str);
+ }
+
+ bool WriteTag(ostream& out, const std::string& str, bool verbatim)
+ {
+ out << (verbatim ? "!<" : "!");
+ StringCharSource buffer(str.c_str(), str.size());
+ const RegEx& reValid = verbatim ? Exp::URI() : Exp::Tag();
+ while(buffer) {
+ int n = reValid.Match(buffer);
+ if(n <= 0)
+ return false;
+
+ while(--n >= 0) {
+ out << buffer[0];
+ ++buffer;
+ }
+ }
+ if (verbatim)
+ out << ">";
+ return true;
+ }
+
+ bool WriteTagWithPrefix(ostream& out, const std::string& prefix, const std::string& tag)
+ {
+ out << "!";
+ StringCharSource prefixBuffer(prefix.c_str(), prefix.size());
+ while(prefixBuffer) {
+ int n = Exp::URI().Match(prefixBuffer);
+ if(n <= 0)
+ return false;
+
+ while(--n >= 0) {
+ out << prefixBuffer[0];
+ ++prefixBuffer;
+ }
+ }
+
+ out << "!";
+ StringCharSource tagBuffer(tag.c_str(), tag.size());
+ while(tagBuffer) {
+ int n = Exp::Tag().Match(tagBuffer);
+ if(n <= 0)
+ return false;
+
+ while(--n >= 0) {
+ out << tagBuffer[0];
+ ++tagBuffer;
+ }
+ }
+ return true;
+ }
+
+ bool WriteBinary(ostream& out, const Binary& binary)
+ {
+ WriteDoubleQuotedString(out, EncodeBase64(binary.data(), binary.size()), false);
+ return true;
+ }
+ }
+}
+
diff --git a/external_libs/yaml-cpp/src/emitterutils.h b/external_libs/yaml-cpp/src/emitterutils.h
new file mode 100644
index 00000000..0e270d69
--- /dev/null
+++ b/external_libs/yaml-cpp/src/emitterutils.h
@@ -0,0 +1,32 @@
+#ifndef EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include "yaml-cpp/ostream.h"
+#include <string>
+
+namespace YAML
+{
+ class Binary;
+
+ namespace Utils
+ {
+ bool WriteString(ostream& out, const std::string& str, bool inFlow, bool escapeNonAscii);
+ bool WriteSingleQuotedString(ostream& out, const std::string& str);
+ bool WriteDoubleQuotedString(ostream& out, const std::string& str, bool escapeNonAscii);
+ bool WriteLiteralString(ostream& out, const std::string& str, int indent);
+ bool WriteChar(ostream& out, char ch);
+ bool WriteComment(ostream& out, const std::string& str, int postCommentIndent);
+ bool WriteAlias(ostream& out, const std::string& str);
+ bool WriteAnchor(ostream& out, const std::string& str);
+ bool WriteTag(ostream& out, const std::string& str, bool verbatim);
+ bool WriteTagWithPrefix(ostream& out, const std::string& prefix, const std::string& tag);
+ bool WriteBinary(ostream& out, const Binary& binary);
+ }
+}
+
+#endif // EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/src/exp.cpp b/external_libs/yaml-cpp/src/exp.cpp
new file mode 100644
index 00000000..7bc54546
--- /dev/null
+++ b/external_libs/yaml-cpp/src/exp.cpp
@@ -0,0 +1,113 @@
+#include "exp.h"
+#include "yaml-cpp/exceptions.h"
+#include <sstream>
+
+namespace YAML
+{
+ namespace Exp
+ {
+ unsigned ParseHex(const std::string& str, const Mark& mark)
+ {
+ unsigned value = 0;
+ for(std::size_t i=0;i<str.size();i++) {
+ char ch = str[i];
+ int digit = 0;
+ if('a' <= ch && ch <= 'f')
+ digit = ch - 'a' + 10;
+ else if('A' <= ch && ch <= 'F')
+ digit = ch - 'A' + 10;
+ else if('0' <= ch && ch <= '9')
+ digit = ch - '0';
+ else
+ throw ParserException(mark, ErrorMsg::INVALID_HEX);
+
+ value = (value << 4) + digit;
+ }
+
+ return value;
+ }
+
+ std::string Str(unsigned ch)
+ {
+ return std::string(1, static_cast<char>(ch));
+ }
+
+ // Escape
+ // . Translates the next 'codeLength' characters into a hex number and returns the result.
+ // . Throws if it's not actually hex.
+ std::string Escape(Stream& in, int codeLength)
+ {
+ // grab string
+ std::string str;
+ for(int i=0;i<codeLength;i++)
+ str += in.get();
+
+ // get the value
+ unsigned value = ParseHex(str, in.mark());
+
+ // legal unicode?
+ if((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) {
+ std::stringstream msg;
+ msg << ErrorMsg::INVALID_UNICODE << value;
+ throw ParserException(in.mark(), msg.str());
+ }
+
+ // now break it up into chars
+ if(value <= 0x7F)
+ return Str(value);
+ else if(value <= 0x7FF)
+ return Str(0xC0 + (value >> 6)) + Str(0x80 + (value & 0x3F));
+ else if(value <= 0xFFFF)
+ return Str(0xE0 + (value >> 12)) + Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F));
+ else
+ return Str(0xF0 + (value >> 18)) + Str(0x80 + ((value >> 12) & 0x3F)) +
+ Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F));
+ }
+
+ // Escape
+ // . Escapes the sequence starting 'in' (it must begin with a '\' or single quote)
+ // and returns the result.
+ // . Throws if it's an unknown escape character.
+ std::string Escape(Stream& in)
+ {
+ // eat slash
+ char escape = in.get();
+
+ // switch on escape character
+ char ch = in.get();
+
+ // first do single quote, since it's easier
+ if(escape == '\'' && ch == '\'')
+ return "\'";
+
+ // now do the slash (we're not gonna check if it's a slash - you better pass one!)
+ switch(ch) {
+ case '0': return std::string(1, '\x00');
+ case 'a': return "\x07";
+ case 'b': return "\x08";
+ case 't':
+ case '\t': return "\x09";
+ case 'n': return "\x0A";
+ case 'v': return "\x0B";
+ case 'f': return "\x0C";
+ case 'r': return "\x0D";
+ case 'e': return "\x1B";
+ case ' ': return "\x20";
+ case '\"': return "\"";
+ case '\'': return "\'";
+ case '\\': return "\\";
+ case '/': return "/";
+ case 'N': return "\x85";
+ case '_': return "\xA0";
+ case 'L': return "\xE2\x80\xA8"; // LS (#x2028)
+ case 'P': return "\xE2\x80\xA9"; // PS (#x2029)
+ case 'x': return Escape(in, 2);
+ case 'u': return Escape(in, 4);
+ case 'U': return Escape(in, 8);
+ }
+
+ std::stringstream msg;
+ throw ParserException(in.mark(), std::string(ErrorMsg::INVALID_ESCAPE) + ch);
+ }
+ }
+}
diff --git a/external_libs/yaml-cpp/src/exp.h b/external_libs/yaml-cpp/src/exp.h
new file mode 100644
index 00000000..3e12aba4
--- /dev/null
+++ b/external_libs/yaml-cpp/src/exp.h
@@ -0,0 +1,196 @@
+#ifndef EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include "regex.h"
+#include <string>
+#include <ios>
+#include "stream.h"
+
+namespace YAML
+{
+ ////////////////////////////////////////////////////////////////////////////////
+ // Here we store a bunch of expressions for matching different parts of the file.
+
+ namespace Exp
+ {
+ // misc
+ inline const RegEx& Space() {
+ static const RegEx e = RegEx(' ');
+ return e;
+ }
+ inline const RegEx& Tab() {
+ static const RegEx e = RegEx('\t');
+ return e;
+ }
+ inline const RegEx& Blank() {
+ static const RegEx e = Space() || Tab();
+ return e;
+ }
+ inline const RegEx& Break() {
+ static const RegEx e = RegEx('\n') || RegEx("\r\n");
+ return e;
+ }
+ inline const RegEx& BlankOrBreak() {
+ static const RegEx e = Blank() || Break();
+ return e;
+ }
+ inline const RegEx& Digit() {
+ static const RegEx e = RegEx('0', '9');
+ return e;
+ }
+ inline const RegEx& Alpha() {
+ static const RegEx e = RegEx('a', 'z') || RegEx('A', 'Z');
+ return e;
+ }
+ inline const RegEx& AlphaNumeric() {
+ static const RegEx e = Alpha() || Digit();
+ return e;
+ }
+ inline const RegEx& Word() {
+ static const RegEx e = AlphaNumeric() || RegEx('-');
+ return e;
+ }
+ inline const RegEx& Hex() {
+ static const RegEx e = Digit() || RegEx('A', 'F') || RegEx('a', 'f');
+ return e;
+ }
+ // Valid Unicode code points that are not part of c-printable (YAML 1.2, sec. 5.1)
+ inline const RegEx& NotPrintable() {
+ static const RegEx e = RegEx(0) ||
+ RegEx("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) ||
+ RegEx(0x0E, 0x1F) ||
+ (RegEx('\xC2') + (RegEx('\x80', '\x84') || RegEx('\x86', '\x9F')));
+ return e;
+ }
+ inline const RegEx& Utf8_ByteOrderMark() {
+ static const RegEx e = RegEx("\xEF\xBB\xBF");
+ return e;
+ }
+
+ // actual tags
+
+ inline const RegEx& DocStart() {
+ static const RegEx e = RegEx("---") + (BlankOrBreak() || RegEx());
+ return e;
+ }
+ inline const RegEx& DocEnd() {
+ static const RegEx e = RegEx("...") + (BlankOrBreak() || RegEx());
+ return e;
+ }
+ inline const RegEx& DocIndicator() {
+ static const RegEx e = DocStart() || DocEnd();
+ return e;
+ }
+ inline const RegEx& BlockEntry() {
+ static const RegEx e = RegEx('-') + (BlankOrBreak() || RegEx());
+ return e;
+ }
+ inline const RegEx& Key() {
+ static const RegEx e = RegEx('?');
+ return e;
+ }
+ inline const RegEx& KeyInFlow() {
+ static const RegEx e = RegEx('?') + BlankOrBreak();
+ return e;
+ }
+ inline const RegEx& Value() {
+ static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx());
+ return e;
+ }
+ inline const RegEx& ValueInFlow() {
+ static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx(",}", REGEX_OR));
+ return e;
+ }
+ inline const RegEx& ValueInJSONFlow() {
+ static const RegEx e = RegEx(':');
+ return e;
+ }
+ inline const RegEx Comment() {
+ static const RegEx e = RegEx('#');
+ return e;
+ }
+ inline const RegEx& Anchor() {
+ static const RegEx e = !(RegEx("[]{},", REGEX_OR) || BlankOrBreak());
+ return e;
+ }
+ inline const RegEx& AnchorEnd() {
+ static const RegEx e = RegEx("?:,]}%@`", REGEX_OR) || BlankOrBreak();
+ return e;
+ }
+ inline const RegEx& URI() {
+ static const RegEx e = Word() || RegEx("#;/?:@&=+$,_.!~*'()[]", REGEX_OR) || (RegEx('%') + Hex() + Hex());
+ return e;
+ }
+ inline const RegEx& Tag() {
+ static const RegEx e = Word() || RegEx("#;/?:@&=+$_.~*'", REGEX_OR) || (RegEx('%') + Hex() + Hex());
+ return e;
+ }
+
+ // Plain scalar rules:
+ // . Cannot start with a blank.
+ // . Can never start with any of , [ ] { } # & * ! | > \' \" % @ `
+ // . In the block context - ? : must be not be followed with a space.
+ // . In the flow context ? is illegal and : and - must not be followed with a space.
+ inline const RegEx& PlainScalar() {
+ static const RegEx e = !(BlankOrBreak() || RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-?:", REGEX_OR) + (BlankOrBreak() || RegEx())));
+ return e;
+ }
+ inline const RegEx& PlainScalarInFlow() {
+ static const RegEx e = !(BlankOrBreak() || RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-:", REGEX_OR) + Blank()));
+ return e;
+ }
+ inline const RegEx& EndScalar() {
+ static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx());
+ return e;
+ }
+ inline const RegEx& EndScalarInFlow() {
+ static const RegEx e = (RegEx(':') + (BlankOrBreak() || RegEx() || RegEx(",]}", REGEX_OR))) || RegEx(",?[]{}", REGEX_OR);
+ return e;
+ }
+
+ inline const RegEx& EscSingleQuote() {
+ static const RegEx e = RegEx("\'\'");
+ return e;
+ }
+ inline const RegEx& EscBreak() {
+ static const RegEx e = RegEx('\\') + Break();
+ return e;
+ }
+
+ inline const RegEx& ChompIndicator() {
+ static const RegEx e = RegEx("+-", REGEX_OR);
+ return e;
+ }
+ inline const RegEx& Chomp() {
+ static const RegEx e = (ChompIndicator() + Digit()) || (Digit() + ChompIndicator()) || ChompIndicator() || Digit();
+ return e;
+ }
+
+ // and some functions
+ std::string Escape(Stream& in);
+ }
+
+ namespace Keys
+ {
+ const char Directive = '%';
+ const char FlowSeqStart = '[';
+ const char FlowSeqEnd = ']';
+ const char FlowMapStart = '{';
+ const char FlowMapEnd = '}';
+ const char FlowEntry = ',';
+ const char Alias = '*';
+ const char Anchor = '&';
+ const char Tag = '!';
+ const char LiteralScalar = '|';
+ const char FoldedScalar = '>';
+ const char VerbatimTagStart = '<';
+ const char VerbatimTagEnd = '>';
+ }
+}
+
+#endif // EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/src/indentation.h b/external_libs/yaml-cpp/src/indentation.h
new file mode 100644
index 00000000..25f684f8
--- /dev/null
+++ b/external_libs/yaml-cpp/src/indentation.h
@@ -0,0 +1,38 @@
+#ifndef INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include "yaml-cpp/ostream.h"
+#include <iostream>
+
+namespace YAML
+{
+ struct Indentation {
+ Indentation(unsigned n_): n(n_) {}
+ unsigned n;
+ };
+
+ inline ostream& operator << (ostream& out, const Indentation& indent) {
+ for(unsigned i=0;i<indent.n;i++)
+ out << ' ';
+ return out;
+ }
+
+ struct IndentTo {
+ IndentTo(unsigned n_): n(n_) {}
+ unsigned n;
+ };
+
+ inline ostream& operator << (ostream& out, const IndentTo& indent) {
+ while(out.col() < indent.n)
+ out << ' ';
+ return out;
+ }
+}
+
+
+#endif // INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/src/iterator.cpp b/external_libs/yaml-cpp/src/iterator.cpp
new file mode 100644
index 00000000..f4159e32
--- /dev/null
+++ b/external_libs/yaml-cpp/src/iterator.cpp
@@ -0,0 +1,103 @@
+#include "yaml-cpp/node.h"
+#include "yaml-cpp/exceptions.h"
+#include "iterpriv.h"
+
+namespace YAML
+{
+ Iterator::Iterator(): m_pData(new IterPriv)
+ {
+ }
+
+ Iterator::Iterator(std::auto_ptr<IterPriv> pData): m_pData(pData)
+ {
+ }
+
+ Iterator::Iterator(const Iterator& rhs): m_pData(new IterPriv(*rhs.m_pData))
+ {
+ }
+
+ Iterator& Iterator::operator = (const Iterator& rhs)
+ {
+ if(this == &rhs)
+ return *this;
+
+ m_pData.reset(new IterPriv(*rhs.m_pData));
+ return *this;
+ }
+
+ Iterator::~Iterator()
+ {
+ }
+
+ Iterator& Iterator::operator ++ ()
+ {
+ if(m_pData->type == IterPriv::IT_SEQ)
+ ++m_pData->seqIter;
+ else if(m_pData->type == IterPriv::IT_MAP)
+ ++m_pData->mapIter;
+
+ return *this;
+ }
+
+ Iterator Iterator::operator ++ (int)
+ {
+ Iterator temp = *this;
+
+ if(m_pData->type == IterPriv::IT_SEQ)
+ ++m_pData->seqIter;
+ else if(m_pData->type == IterPriv::IT_MAP)
+ ++m_pData->mapIter;
+
+ return temp;
+ }
+
+ const Node& Iterator::operator * () const
+ {
+ if(m_pData->type == IterPriv::IT_SEQ)
+ return **m_pData->seqIter;
+
+ throw BadDereference();
+ }
+
+ const Node *Iterator::operator -> () const
+ {
+ if(m_pData->type == IterPriv::IT_SEQ)
+ return *m_pData->seqIter;
+
+ throw BadDereference();
+ }
+
+ const Node& Iterator::first() const
+ {
+ if(m_pData->type == IterPriv::IT_MAP)
+ return *m_pData->mapIter->first;
+
+ throw BadDereference();
+ }
+
+ const Node& Iterator::second() const
+ {
+ if(m_pData->type == IterPriv::IT_MAP)
+ return *m_pData->mapIter->second;
+
+ throw BadDereference();
+ }
+
+ bool operator == (const Iterator& it, const Iterator& jt)
+ {
+ if(it.m_pData->type != jt.m_pData->type)
+ return false;
+
+ if(it.m_pData->type == IterPriv::IT_SEQ)
+ return it.m_pData->seqIter == jt.m_pData->seqIter;
+ else if(it.m_pData->type == IterPriv::IT_MAP)
+ return it.m_pData->mapIter == jt.m_pData->mapIter;
+
+ return true;
+ }
+
+ bool operator != (const Iterator& it, const Iterator& jt)
+ {
+ return !(it == jt);
+ }
+}
diff --git a/external_libs/yaml-cpp/src/iterpriv.h b/external_libs/yaml-cpp/src/iterpriv.h
new file mode 100644
index 00000000..c511e8ac
--- /dev/null
+++ b/external_libs/yaml-cpp/src/iterpriv.h
@@ -0,0 +1,33 @@
+#ifndef ITERPRIV_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define ITERPRIV_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include "yaml-cpp/ltnode.h"
+#include <vector>
+#include <map>
+
+namespace YAML
+{
+ class Node;
+
+ // IterPriv
+ // . The implementation for iterators - essentially a union of sequence and map iterators.
+ struct IterPriv
+ {
+ IterPriv(): type(IT_NONE) {}
+ IterPriv(std::vector <Node *>::const_iterator it): type(IT_SEQ), seqIter(it) {}
+ IterPriv(std::map <Node *, Node *, ltnode>::const_iterator it): type(IT_MAP), mapIter(it) {}
+
+ enum ITER_TYPE { IT_NONE, IT_SEQ, IT_MAP };
+ ITER_TYPE type;
+
+ std::vector <Node *>::const_iterator seqIter;
+ std::map <Node *, Node *, ltnode>::const_iterator mapIter;
+ };
+}
+
+#endif // ITERPRIV_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/src/node.cpp b/external_libs/yaml-cpp/src/node.cpp
new file mode 100644
index 00000000..360b4ad9
--- /dev/null
+++ b/external_libs/yaml-cpp/src/node.cpp
@@ -0,0 +1,269 @@
+#include "yaml-cpp/node.h"
+#include "yaml-cpp/aliasmanager.h"
+#include "yaml-cpp/emitfromevents.h"
+#include "yaml-cpp/emitter.h"
+#include "yaml-cpp/eventhandler.h"
+#include "iterpriv.h"
+#include "nodebuilder.h"
+#include "nodeownership.h"
+#include "scanner.h"
+#include "tag.h"
+#include "token.h"
+#include <cassert>
+#include <stdexcept>
+
+namespace YAML
+{
+ bool ltnode::operator()(const Node *pNode1, const Node *pNode2) const {
+ return *pNode1 < *pNode2;
+ }
+
+ Node::Node(): m_pOwnership(new NodeOwnership), m_type(NodeType::Null)
+ {
+ }
+
+ Node::Node(NodeOwnership& owner): m_pOwnership(new NodeOwnership(&owner)), m_type(NodeType::Null)
+ {
+ }
+
+ Node::~Node()
+ {
+ Clear();
+ }
+
+ void Node::Clear()
+ {
+ m_pOwnership.reset(new NodeOwnership);
+ m_type = NodeType::Null;
+ m_tag.clear();
+ m_scalarData.clear();
+ m_seqData.clear();
+ m_mapData.clear();
+ }
+
+ bool Node::IsAliased() const
+ {
+ return m_pOwnership->IsAliased(*this);
+ }
+
+ Node& Node::CreateNode()
+ {
+ return m_pOwnership->Create();
+ }
+
+ std::auto_ptr<Node> Node::Clone() const
+ {
+ std::auto_ptr<Node> pNode(new Node);
+ NodeBuilder nodeBuilder(*pNode);
+ EmitEvents(nodeBuilder);
+ return pNode;
+ }
+
+ void Node::EmitEvents(EventHandler& eventHandler) const
+ {
+ eventHandler.OnDocumentStart(m_mark);
+ AliasManager am;
+ EmitEvents(am, eventHandler);
+ eventHandler.OnDocumentEnd();
+ }
+
+ void Node::EmitEvents(AliasManager& am, EventHandler& eventHandler) const
+ {
+ anchor_t anchor = NullAnchor;
+ if(IsAliased()) {
+ anchor = am.LookupAnchor(*this);
+ if(anchor) {
+ eventHandler.OnAlias(m_mark, anchor);
+ return;
+ }
+
+ am.RegisterReference(*this);
+ anchor = am.LookupAnchor(*this);
+ }
+
+ switch(m_type) {
+ case NodeType::Null:
+ eventHandler.OnNull(m_mark, anchor);
+ break;
+ case NodeType::Scalar:
+ eventHandler.OnScalar(m_mark, m_tag, anchor, m_scalarData);
+ break;
+ case NodeType::Sequence:
+ eventHandler.OnSequenceStart(m_mark, m_tag, anchor);
+ for(std::size_t i=0;i<m_seqData.size();i++)
+ m_seqData[i]->EmitEvents(am, eventHandler);
+ eventHandler.OnSequenceEnd();
+ break;
+ case NodeType::Map:
+ eventHandler.OnMapStart(m_mark, m_tag, anchor);
+ for(node_map::const_iterator it=m_mapData.begin();it!=m_mapData.end();++it) {
+ it->first->EmitEvents(am, eventHandler);
+ it->second->EmitEvents(am, eventHandler);
+ }
+ eventHandler.OnMapEnd();
+ break;
+ }
+ }
+
+ void Node::Init(NodeType::value type, const Mark& mark, const std::string& tag)
+ {
+ Clear();
+ m_mark = mark;
+ m_type = type;
+ m_tag = tag;
+ }
+
+ void Node::MarkAsAliased()
+ {
+ m_pOwnership->MarkAsAliased(*this);
+ }
+
+ void Node::SetScalarData(const std::string& data)
+ {
+ assert(m_type == NodeType::Scalar); // TODO: throw?
+ m_scalarData = data;
+ }
+
+ void Node::Append(Node& node)
+ {
+ assert(m_type == NodeType::Sequence); // TODO: throw?
+ m_seqData.push_back(&node);
+ }
+
+ void Node::Insert(Node& key, Node& value)
+ {
+ assert(m_type == NodeType::Map); // TODO: throw?
+ m_mapData[&key] = &value;
+ }
+
+ // begin
+ // Returns an iterator to the beginning of this (sequence or map).
+ Iterator Node::begin() const
+ {
+ switch(m_type) {
+ case NodeType::Null:
+ case NodeType::Scalar:
+ return Iterator();
+ case NodeType::Sequence:
+ return Iterator(std::auto_ptr<IterPriv>(new IterPriv(m_seqData.begin())));
+ case NodeType::Map:
+ return Iterator(std::auto_ptr<IterPriv>(new IterPriv(m_mapData.begin())));
+ }
+
+ assert(false);
+ return Iterator();
+ }
+
+ // end
+ // . Returns an iterator to the end of this (sequence or map).
+ Iterator Node::end() const
+ {
+ switch(m_type) {
+ case NodeType::Null:
+ case NodeType::Scalar:
+ return Iterator();
+ case NodeType::Sequence:
+ return Iterator(std::auto_ptr<IterPriv>(new IterPriv(m_seqData.end())));
+ case NodeType::Map:
+ return Iterator(std::auto_ptr<IterPriv>(new IterPriv(m_mapData.end())));
+ }
+
+ assert(false);
+ return Iterator();
+ }
+
+ // size
+ // . Returns the size of a sequence or map node
+ // . Otherwise, returns zero.
+ std::size_t Node::size() const
+ {
+ switch(m_type) {
+ case NodeType::Null:
+ case NodeType::Scalar:
+ return 0;
+ case NodeType::Sequence:
+ return m_seqData.size();
+ case NodeType::Map:
+ return m_mapData.size();
+ }
+
+ assert(false);
+ return 0;
+ }
+
+ const Node *Node::FindAtIndex(std::size_t i) const
+ {
+ if(m_type == NodeType::Sequence)
+ return m_seqData[i];
+ return 0;
+ }
+
+ bool Node::GetScalar(std::string& s) const
+ {
+ switch(m_type) {
+ case NodeType::Null:
+ s = "~";
+ return true;
+ case NodeType::Scalar:
+ s = m_scalarData;
+ return true;
+ case NodeType::Sequence:
+ case NodeType::Map:
+ return false;
+ }
+
+ assert(false);
+ return false;
+ }
+
+ Emitter& operator << (Emitter& out, const Node& node)
+ {
+ EmitFromEvents emitFromEvents(out);
+ node.EmitEvents(emitFromEvents);
+ return out;
+ }
+
+ int Node::Compare(const Node& rhs) const
+ {
+ if(m_type != rhs.m_type)
+ return rhs.m_type - m_type;
+
+ switch(m_type) {
+ case NodeType::Null:
+ return 0;
+ case NodeType::Scalar:
+ return m_scalarData.compare(rhs.m_scalarData);
+ case NodeType::Sequence:
+ if(m_seqData.size() < rhs.m_seqData.size())
+ return 1;
+ else if(m_seqData.size() > rhs.m_seqData.size())
+ return -1;
+ for(std::size_t i=0;i<m_seqData.size();i++)
+ if(int cmp = m_seqData[i]->Compare(*rhs.m_seqData[i]))
+ return cmp;
+ return 0;
+ case NodeType::Map:
+ if(m_mapData.size() < rhs.m_mapData.size())
+ return 1;
+ else if(m_mapData.size() > rhs.m_mapData.size())
+ return -1;
+ node_map::const_iterator it = m_mapData.begin();
+ node_map::const_iterator jt = rhs.m_mapData.begin();
+ for(;it!=m_mapData.end() && jt!=rhs.m_mapData.end();it++, jt++) {
+ if(int cmp = it->first->Compare(*jt->first))
+ return cmp;
+ if(int cmp = it->second->Compare(*jt->second))
+ return cmp;
+ }
+ return 0;
+ }
+
+ assert(false);
+ return 0;
+ }
+
+ bool operator < (const Node& n1, const Node& n2)
+ {
+ return n1.Compare(n2) < 0;
+ }
+}
diff --git a/external_libs/yaml-cpp/src/nodebuilder.cpp b/external_libs/yaml-cpp/src/nodebuilder.cpp
new file mode 100644
index 00000000..13a70326
--- /dev/null
+++ b/external_libs/yaml-cpp/src/nodebuilder.cpp
@@ -0,0 +1,145 @@
+#include "nodebuilder.h"
+#include "yaml-cpp/mark.h"
+#include "yaml-cpp/node.h"
+#include <cassert>
+
+namespace YAML
+{
+ NodeBuilder::NodeBuilder(Node& root): m_root(root), m_initializedRoot(false), m_finished(false)
+ {
+ m_root.Clear();
+ m_anchors.push_back(0); // since the anchors start at 1
+ }
+
+ NodeBuilder::~NodeBuilder()
+ {
+ }
+
+ void NodeBuilder::OnDocumentStart(const Mark&)
+ {
+ }
+
+ void NodeBuilder::OnDocumentEnd()
+ {
+ assert(m_finished);
+ }
+
+ void NodeBuilder::OnNull(const Mark& mark, anchor_t anchor)
+ {
+ Node& node = Push(anchor);
+ node.Init(NodeType::Null, mark, "");
+ Pop();
+ }
+
+ void NodeBuilder::OnAlias(const Mark& /*mark*/, anchor_t anchor)
+ {
+ Node& node = *m_anchors[anchor];
+ Insert(node);
+ node.MarkAsAliased();
+ }
+
+ void NodeBuilder::OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value)
+ {
+ Node& node = Push(anchor);
+ node.Init(NodeType::Scalar, mark, tag);
+ node.SetScalarData(value);
+ Pop();
+ }
+
+ void NodeBuilder::OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor)
+ {
+ Node& node = Push(anchor);
+ node.Init(NodeType::Sequence, mark, tag);
+ }
+
+ void NodeBuilder::OnSequenceEnd()
+ {
+ Pop();
+ }
+
+ void NodeBuilder::OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor)
+ {
+ Node& node = Push(anchor);
+ node.Init(NodeType::Map, mark, tag);
+ m_didPushKey.push(false);
+ }
+
+ void NodeBuilder::OnMapEnd()
+ {
+ m_didPushKey.pop();
+ Pop();
+ }
+
+ Node& NodeBuilder::Push(anchor_t anchor)
+ {
+ Node& node = Push();
+ RegisterAnchor(anchor, node);
+ return node;
+ }
+
+ Node& NodeBuilder::Push()
+ {
+ if(!m_initializedRoot) {
+ m_initializedRoot = true;
+ return m_root;
+ }
+
+ Node& node = m_root.CreateNode();
+ m_stack.push(&node);
+ return node;
+ }
+
+ Node& NodeBuilder::Top()
+ {
+ return m_stack.empty() ? m_root : *m_stack.top();
+ }
+
+ void NodeBuilder::Pop()
+ {
+ assert(!m_finished);
+ if(m_stack.empty()) {
+ m_finished = true;
+ return;
+ }
+
+ Node& node = *m_stack.top();
+ m_stack.pop();
+ Insert(node);
+ }
+
+ void NodeBuilder::Insert(Node& node)
+ {
+ Node& curTop = Top();
+ switch(curTop.Type()) {
+ case NodeType::Null:
+ case NodeType::Scalar:
+ assert(false);
+ break;
+ case NodeType::Sequence:
+ curTop.Append(node);
+ break;
+ case NodeType::Map:
+ assert(!m_didPushKey.empty());
+ if(m_didPushKey.top()) {
+ assert(!m_pendingKeys.empty());
+
+ Node& key = *m_pendingKeys.top();
+ m_pendingKeys.pop();
+ curTop.Insert(key, node);
+ m_didPushKey.top() = false;
+ } else {
+ m_pendingKeys.push(&node);
+ m_didPushKey.top() = true;
+ }
+ break;
+ }
+ }
+
+ void NodeBuilder::RegisterAnchor(anchor_t anchor, Node& node)
+ {
+ if(anchor) {
+ assert(anchor == m_anchors.size());
+ m_anchors.push_back(&node);
+ }
+ }
+}
diff --git a/external_libs/yaml-cpp/src/nodebuilder.h b/external_libs/yaml-cpp/src/nodebuilder.h
new file mode 100644
index 00000000..9c1d16a0
--- /dev/null
+++ b/external_libs/yaml-cpp/src/nodebuilder.h
@@ -0,0 +1,61 @@
+#ifndef NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/eventhandler.h"
+#include <map>
+#include <memory>
+#include <stack>
+#include <vector>
+
+namespace YAML
+{
+ class Node;
+
+ class NodeBuilder: public EventHandler
+ {
+ public:
+ explicit NodeBuilder(Node& root);
+ virtual ~NodeBuilder();
+
+ virtual void OnDocumentStart(const Mark& mark);
+ virtual void OnDocumentEnd();
+
+ virtual void OnNull(const Mark& mark, anchor_t anchor);
+ virtual void OnAlias(const Mark& mark, anchor_t anchor);
+ virtual void OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value);
+
+ virtual void OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor);
+ virtual void OnSequenceEnd();
+
+ virtual void OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor);
+ virtual void OnMapEnd();
+
+ private:
+ Node& Push(anchor_t anchor);
+ Node& Push();
+ Node& Top();
+ void Pop();
+
+ void Insert(Node& node);
+ void RegisterAnchor(anchor_t anchor, Node& node);
+
+ private:
+ Node& m_root;
+ bool m_initializedRoot;
+ bool m_finished;
+
+ std::stack<Node *> m_stack;
+ std::stack<Node *> m_pendingKeys;
+ std::stack<bool> m_didPushKey;
+
+ typedef std::vector<Node *> Anchors;
+ Anchors m_anchors;
+ };
+}
+
+#endif // NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
diff --git a/external_libs/yaml-cpp/src/nodeownership.cpp b/external_libs/yaml-cpp/src/nodeownership.cpp
new file mode 100644
index 00000000..118edbc8
--- /dev/null
+++ b/external_libs/yaml-cpp/src/nodeownership.cpp
@@ -0,0 +1,31 @@
+#include "nodeownership.h"
+#include "yaml-cpp/node.h"
+
+namespace YAML
+{
+ NodeOwnership::NodeOwnership(NodeOwnership *pOwner): m_pOwner(pOwner)
+ {
+ if(!m_pOwner)
+ m_pOwner = this;
+ }
+
+ NodeOwnership::~NodeOwnership()
+ {
+ }
+
+ Node& NodeOwnership::_Create()
+ {
+ m_nodes.push_back(std::auto_ptr<Node>(new Node));
+ return m_nodes.back();
+ }
+
+ void NodeOwnership::_MarkAsAliased(const Node& node)
+ {
+ m_aliasedNodes.insert(&node);
+ }
+
+ bool NodeOwnership::_IsAliased(const Node& node) const
+ {
+ return m_aliasedNodes.count(&node) > 0;
+ }
+}
diff --git a/external_libs/yaml-cpp/src/nodeownership.h b/external_libs/yaml-cpp/src/nodeownership.h
new file mode 100644
index 00000000..69870814
--- /dev/null
+++ b/external_libs/yaml-cpp/src/nodeownership.h
@@ -0,0 +1,39 @@
+#ifndef NODE_OWNERSHIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODE_OWNERSHIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include "yaml-cpp/noncopyable.h"
+#include "ptr_vector.h"
+#include <set>
+
+namespace YAML
+{
+ class Node;
+
+ class NodeOwnership: private noncopyable
+ {
+ public:
+ explicit NodeOwnership(NodeOwnership *pOwner = 0);
+ ~NodeOwnership();
+
+ Node& Create() { return m_pOwner->_Create(); }
+ void MarkAsAliased(const Node& node) { m_pOwner->_MarkAsAliased(node); }
+ bool IsAliased(const Node& node) const { return m_pOwner->_IsAliased(node); }
+
+ private:
+ Node& _Create();
+ void _MarkAsAliased(const Node& node);
+ bool _IsAliased(const Node& node) const;
+
+ private:
+ ptr_vector<Node> m_nodes;
+ std::set<const Node *> m_aliasedNodes;
+ NodeOwnership *m_pOwner;
+ };
+}
+
+#endif // NODE_OWNERSHIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/src/null.cpp b/external_libs/yaml-cpp/src/null.cpp
new file mode 100644
index 00000000..08fa9aae
--- /dev/null
+++ b/external_libs/yaml-cpp/src/null.cpp
@@ -0,0 +1,12 @@
+#include "yaml-cpp/null.h"
+#include "yaml-cpp/node.h"
+
+namespace YAML
+{
+ _Null Null;
+
+ bool IsNull(const Node& node)
+ {
+ return node.Read(Null);
+ }
+}
diff --git a/external_libs/yaml-cpp/src/ostream.cpp b/external_libs/yaml-cpp/src/ostream.cpp
new file mode 100644
index 00000000..a7f1e14b
--- /dev/null
+++ b/external_libs/yaml-cpp/src/ostream.cpp
@@ -0,0 +1,63 @@
+#include "yaml-cpp/ostream.h"
+#include <cstring>
+
+namespace YAML
+{
+ ostream::ostream(): m_buffer(0), m_pos(0), m_size(0), m_row(0), m_col(0)
+ {
+ reserve(1024);
+ }
+
+ ostream::~ostream()
+ {
+ delete [] m_buffer;
+ }
+
+ void ostream::reserve(unsigned size)
+ {
+ if(size <= m_size)
+ return;
+
+ char *newBuffer = new char[size];
+ std::memset(newBuffer, 0, size * sizeof(char));
+ std::memcpy(newBuffer, m_buffer, m_size * sizeof(char));
+ delete [] m_buffer;
+ m_buffer = newBuffer;
+ m_size = size;
+ }
+
+ void ostream::put(char ch)
+ {
+ if(m_pos >= m_size - 1) // an extra space for the NULL terminator
+ reserve(m_size * 2);
+
+ m_buffer[m_pos] = ch;
+ m_pos++;
+
+ if(ch == '\n') {
+ m_row++;
+ m_col = 0;
+ } else
+ m_col++;
+ }
+
+ ostream& operator << (ostream& out, const char *str)
+ {
+ std::size_t length = std::strlen(str);
+ for(std::size_t i=0;i<length;i++)
+ out.put(str[i]);
+ return out;
+ }
+
+ ostream& operator << (ostream& out, const std::string& str)
+ {
+ out << str.c_str();
+ return out;
+ }
+
+ ostream& operator << (ostream& out, char ch)
+ {
+ out.put(ch);
+ return out;
+ }
+}
diff --git a/external_libs/yaml-cpp/src/parser.cpp b/external_libs/yaml-cpp/src/parser.cpp
new file mode 100644
index 00000000..b836823f
--- /dev/null
+++ b/external_libs/yaml-cpp/src/parser.cpp
@@ -0,0 +1,152 @@
+#include "yaml-cpp/parser.h"
+#include "yaml-cpp/eventhandler.h"
+#include "yaml-cpp/exceptions.h"
+#include "yaml-cpp/node.h"
+#include "directives.h"
+#include "nodebuilder.h"
+#include "scanner.h"
+#include "singledocparser.h"
+#include "tag.h"
+#include "token.h"
+#include <sstream>
+#include <cstdio>
+
+namespace YAML
+{
+ Parser::Parser()
+ {
+ }
+
+ Parser::Parser(std::istream& in)
+ {
+ Load(in);
+ }
+
+ Parser::~Parser()
+ {
+ }
+
+ Parser::operator bool() const
+ {
+ return m_pScanner.get() && !m_pScanner->empty();
+ }
+
+ void Parser::Load(std::istream& in)
+ {
+ m_pScanner.reset(new Scanner(in));
+ m_pDirectives.reset(new Directives);
+ }
+
+ // HandleNextDocument
+ // . Handles the next document
+ // . Throws a ParserException on error.
+ // . Returns false if there are no more documents
+ bool Parser::HandleNextDocument(EventHandler& eventHandler)
+ {
+ if(!m_pScanner.get())
+ return false;
+
+ ParseDirectives();
+ if(m_pScanner->empty())
+ return false;
+
+ SingleDocParser sdp(*m_pScanner, *m_pDirectives);
+ sdp.HandleDocument(eventHandler);
+ return true;
+ }
+
+ // GetNextDocument
+ // . Reads the next document in the queue (of tokens).
+ // . Throws a ParserException on error.
+ bool Parser::GetNextDocument(Node& document)
+ {
+ NodeBuilder builder(document);
+ return HandleNextDocument(builder);
+ }
+
+ // ParseDirectives
+ // . Reads any directives that are next in the queue.
+ void Parser::ParseDirectives()
+ {
+ bool readDirective = false;
+
+ while(1) {
+ if(m_pScanner->empty())
+ break;
+
+ Token& token = m_pScanner->peek();
+ if(token.type != Token::DIRECTIVE)
+ break;
+
+ // we keep the directives from the last document if none are specified;
+ // but if any directives are specific, then we reset them
+ if(!readDirective)
+ m_pDirectives.reset(new Directives);
+
+ readDirective = true;
+ HandleDirective(token);
+ m_pScanner->pop();
+ }
+ }
+
+ void Parser::HandleDirective(const Token& token)
+ {
+ if(token.value == "YAML")
+ HandleYamlDirective(token);
+ else if(token.value == "TAG")
+ HandleTagDirective(token);
+ }
+
+ // HandleYamlDirective
+ // . Should be of the form 'major.minor' (like a version number)
+ void Parser::HandleYamlDirective(const Token& token)
+ {
+ if(token.params.size() != 1)
+ throw ParserException(token.mark, ErrorMsg::YAML_DIRECTIVE_ARGS);
+
+ if(!m_pDirectives->version.isDefault)
+ throw ParserException(token.mark, ErrorMsg::REPEATED_YAML_DIRECTIVE);
+
+ std::stringstream str(token.params[0]);
+ str >> m_pDirectives->version.major;
+ str.get();
+ str >> m_pDirectives->version.minor;
+ if(!str || str.peek() != EOF)
+ throw ParserException(token.mark, std::string(ErrorMsg::YAML_VERSION) + token.params[0]);
+
+ if(m_pDirectives->version.major > 1)
+ throw ParserException(token.mark, ErrorMsg::YAML_MAJOR_VERSION);
+
+ m_pDirectives->version.isDefault = false;
+ // TODO: warning on major == 1, minor > 2?
+ }
+
+ // HandleTagDirective
+ // . Should be of the form 'handle prefix', where 'handle' is converted to 'prefix' in the file.
+ void Parser::HandleTagDirective(const Token& token)
+ {
+ if(token.params.size() != 2)
+ throw ParserException(token.mark, ErrorMsg::TAG_DIRECTIVE_ARGS);
+
+ const std::string& handle = token.params[0];
+ const std::string& prefix = token.params[1];
+ if(m_pDirectives->tags.find(handle) != m_pDirectives->tags.end())
+ throw ParserException(token.mark, ErrorMsg::REPEATED_TAG_DIRECTIVE);
+
+ m_pDirectives->tags[handle] = prefix;
+ }
+
+ void Parser::PrintTokens(std::ostream& out)
+ {
+ if(!m_pScanner.get())
+ return;
+
+ while(1) {
+ if(m_pScanner->empty())
+ break;
+
+ out << m_pScanner->peek() << "\n";
+ m_pScanner->pop();
+ }
+ }
+}
diff --git a/external_libs/yaml-cpp/src/ptr_stack.h b/external_libs/yaml-cpp/src/ptr_stack.h
new file mode 100644
index 00000000..bf454fb3
--- /dev/null
+++ b/external_libs/yaml-cpp/src/ptr_stack.h
@@ -0,0 +1,46 @@
+#ifndef PTR_STACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define PTR_STACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/noncopyable.h"
+#include <cstddef>
+#include <cstdlib>
+#include <memory>
+#include <vector>
+
+template <typename T>
+class ptr_stack: private YAML::noncopyable
+{
+public:
+ ptr_stack() {}
+ ~ptr_stack() { clear(); }
+
+ void clear() {
+ for(unsigned i=0;i<m_data.size();i++)
+ delete m_data[i];
+ m_data.clear();
+ }
+
+ std::size_t size() const { return m_data.size(); }
+ bool empty() const { return m_data.empty(); }
+
+ void push(std::auto_ptr<T> t) {
+ m_data.push_back(NULL);
+ m_data.back() = t.release();
+ }
+ std::auto_ptr<T> pop() {
+ std::auto_ptr<T> t(m_data.back());
+ m_data.pop_back();
+ return t;
+ }
+ T& top() { return *m_data.back(); }
+ const T& top() const { return *m_data.back(); }
+
+private:
+ std::vector<T*> m_data;
+};
+
+#endif // PTR_STACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/src/ptr_vector.h b/external_libs/yaml-cpp/src/ptr_vector.h
new file mode 100644
index 00000000..7b936cb5
--- /dev/null
+++ b/external_libs/yaml-cpp/src/ptr_vector.h
@@ -0,0 +1,47 @@
+#ifndef PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/noncopyable.h"
+#include <cstddef>
+#include <cstdlib>
+#include <memory>
+#include <vector>
+
+namespace YAML {
+
+ template <typename T>
+ class ptr_vector: private YAML::noncopyable
+ {
+ public:
+ ptr_vector() {}
+ ~ptr_vector() { clear(); }
+
+ void clear() {
+ for(unsigned i=0;i<m_data.size();i++)
+ delete m_data[i];
+ m_data.clear();
+ }
+
+ std::size_t size() const { return m_data.size(); }
+ bool empty() const { return m_data.empty(); }
+
+ void push_back(std::auto_ptr<T> t) {
+ m_data.push_back(NULL);
+ m_data.back() = t.release();
+ }
+ T& operator[](std::size_t i) { return *m_data[i]; }
+ const T& operator[](std::size_t i) const { return *m_data[i]; }
+
+ T& back() { return *m_data.back(); }
+ const T& back() const { return *m_data.back(); }
+
+ private:
+ std::vector<T*> m_data;
+ };
+}
+
+#endif // PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/src/regex.cpp b/external_libs/yaml-cpp/src/regex.cpp
new file mode 100644
index 00000000..b35b1f43
--- /dev/null
+++ b/external_libs/yaml-cpp/src/regex.cpp
@@ -0,0 +1,60 @@
+#include "regex.h"
+
+namespace YAML
+{
+ // constructors
+ RegEx::RegEx(): m_op(REGEX_EMPTY)
+ {
+ }
+
+ RegEx::RegEx(REGEX_OP op): m_op(op)
+ {
+ }
+
+ RegEx::RegEx(char ch): m_op(REGEX_MATCH), m_a(ch)
+ {
+ }
+
+ RegEx::RegEx(char a, char z): m_op(REGEX_RANGE), m_a(a), m_z(z)
+ {
+ }
+
+ RegEx::RegEx(const std::string& str, REGEX_OP op): m_op(op)
+ {
+ for(std::size_t i=0;i<str.size();i++)
+ m_params.push_back(RegEx(str[i]));
+ }
+
+ // combination constructors
+ RegEx operator ! (const RegEx& ex)
+ {
+ RegEx ret(REGEX_NOT);
+ ret.m_params.push_back(ex);
+ return ret;
+ }
+
+ RegEx operator || (const RegEx& ex1, const RegEx& ex2)
+ {
+ RegEx ret(REGEX_OR);
+ ret.m_params.push_back(ex1);
+ ret.m_params.push_back(ex2);
+ return ret;
+ }
+
+ RegEx operator && (const RegEx& ex1, const RegEx& ex2)
+ {
+ RegEx ret(REGEX_AND);
+ ret.m_params.push_back(ex1);
+ ret.m_params.push_back(ex2);
+ return ret;
+ }
+
+ RegEx operator + (const RegEx& ex1, const RegEx& ex2)
+ {
+ RegEx ret(REGEX_SEQ);
+ ret.m_params.push_back(ex1);
+ ret.m_params.push_back(ex2);
+ return ret;
+ }
+}
+
diff --git a/external_libs/yaml-cpp/src/regex.h b/external_libs/yaml-cpp/src/regex.h
new file mode 100644
index 00000000..8722e626
--- /dev/null
+++ b/external_libs/yaml-cpp/src/regex.h
@@ -0,0 +1,67 @@
+#ifndef REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include <vector>
+#include <string>
+
+namespace YAML
+{
+ class Stream;
+
+ enum REGEX_OP { REGEX_EMPTY, REGEX_MATCH, REGEX_RANGE, REGEX_OR, REGEX_AND, REGEX_NOT, REGEX_SEQ };
+
+ // simplified regular expressions
+ // . Only straightforward matches (no repeated characters)
+ // . Only matches from start of string
+ class RegEx
+ {
+ public:
+ RegEx();
+ RegEx(char ch);
+ RegEx(char a, char z);
+ RegEx(const std::string& str, REGEX_OP op = REGEX_SEQ);
+ ~RegEx() {}
+
+ friend RegEx operator ! (const RegEx& ex);
+ friend RegEx operator || (const RegEx& ex1, const RegEx& ex2);
+ friend RegEx operator && (const RegEx& ex1, const RegEx& ex2);
+ friend RegEx operator + (const RegEx& ex1, const RegEx& ex2);
+
+ bool Matches(char ch) const;
+ bool Matches(const std::string& str) const;
+ bool Matches(const Stream& in) const;
+ template <typename Source> bool Matches(const Source& source) const;
+
+ int Match(const std::string& str) const;
+ int Match(const Stream& in) const;
+ template <typename Source> int Match(const Source& source) const;
+
+ private:
+ RegEx(REGEX_OP op);
+
+ template <typename Source> bool IsValidSource(const Source& source) const;
+ template <typename Source> int MatchUnchecked(const Source& source) const;
+
+ template <typename Source> int MatchOpEmpty(const Source& source) const;
+ template <typename Source> int MatchOpMatch(const Source& source) const;
+ template <typename Source> int MatchOpRange(const Source& source) const;
+ template <typename Source> int MatchOpOr(const Source& source) const;
+ template <typename Source> int MatchOpAnd(const Source& source) const;
+ template <typename Source> int MatchOpNot(const Source& source) const;
+ template <typename Source> int MatchOpSeq(const Source& source) const;
+
+ private:
+ REGEX_OP m_op;
+ char m_a, m_z;
+ std::vector <RegEx> m_params;
+ };
+}
+
+#include "regeximpl.h"
+
+#endif // REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/src/regeximpl.h b/external_libs/yaml-cpp/src/regeximpl.h
new file mode 100644
index 00000000..d5c20d74
--- /dev/null
+++ b/external_libs/yaml-cpp/src/regeximpl.h
@@ -0,0 +1,186 @@
+#ifndef REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include "stream.h"
+#include "stringsource.h"
+#include "streamcharsource.h"
+
+namespace YAML
+{
+ // query matches
+ inline bool RegEx::Matches(char ch) const {
+ std::string str;
+ str += ch;
+ return Matches(str);
+ }
+
+ inline bool RegEx::Matches(const std::string& str) const {
+ return Match(str) >= 0;
+ }
+
+ inline bool RegEx::Matches(const Stream& in) const {
+ return Match(in) >= 0;
+ }
+
+ template <typename Source>
+ inline bool RegEx::Matches(const Source& source) const {
+ return Match(source) >= 0;
+ }
+
+ // Match
+ // . Matches the given string against this regular expression.
+ // . Returns the number of characters matched.
+ // . Returns -1 if no characters were matched (the reason for
+ // not returning zero is that we may have an empty regex
+ // which is ALWAYS successful at matching zero characters).
+ // . REMEMBER that we only match from the start of the buffer!
+ inline int RegEx::Match(const std::string& str) const
+ {
+ StringCharSource source(str.c_str(), str.size());
+ return Match(source);
+ }
+
+ inline int RegEx::Match(const Stream& in) const
+ {
+ StreamCharSource source(in);
+ return Match(source);
+ }
+
+ template <typename Source>
+ inline bool RegEx::IsValidSource(const Source& source) const
+ {
+ return source;
+ }
+
+ template<>
+ inline bool RegEx::IsValidSource<StringCharSource>(const StringCharSource&source) const
+ {
+ switch(m_op) {
+ case REGEX_MATCH:
+ case REGEX_RANGE:
+ return source;
+ default:
+ return true;
+ }
+ }
+
+ template <typename Source>
+ inline int RegEx::Match(const Source& source) const
+ {
+ return IsValidSource(source) ? MatchUnchecked(source) : -1;
+ }
+
+ template <typename Source>
+ inline int RegEx::MatchUnchecked(const Source& source) const
+ {
+ switch(m_op) {
+ case REGEX_EMPTY:
+ return MatchOpEmpty(source);
+ case REGEX_MATCH:
+ return MatchOpMatch(source);
+ case REGEX_RANGE:
+ return MatchOpRange(source);
+ case REGEX_OR:
+ return MatchOpOr(source);
+ case REGEX_AND:
+ return MatchOpAnd(source);
+ case REGEX_NOT:
+ return MatchOpNot(source);
+ case REGEX_SEQ:
+ return MatchOpSeq(source);
+ }
+
+ return -1;
+ }
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Operators
+ // Note: the convention MatchOp*<Source> is that we can assume IsSourceValid(source).
+ // So we do all our checks *before* we call these functions
+
+ // EmptyOperator
+ template <typename Source>
+ inline int RegEx::MatchOpEmpty(const Source& source) const {
+ return source[0] == Stream::eof() ? 0 : -1;
+ }
+
+ template <>
+ inline int RegEx::MatchOpEmpty<StringCharSource>(const StringCharSource& source) const {
+ return !source ? 0 : -1; // the empty regex only is successful on the empty string
+ }
+
+ // MatchOperator
+ template <typename Source>
+ inline int RegEx::MatchOpMatch(const Source& source) const {
+ if(source[0] != m_a)
+ return -1;
+ return 1;
+ }
+
+ // RangeOperator
+ template <typename Source>
+ inline int RegEx::MatchOpRange(const Source& source) const {
+ if(m_a > source[0] || m_z < source[0])
+ return -1;
+ return 1;
+ }
+
+ // OrOperator
+ template <typename Source>
+ inline int RegEx::MatchOpOr(const Source& source) const {
+ for(std::size_t i=0;i<m_params.size();i++) {
+ int n = m_params[i].MatchUnchecked(source);
+ if(n >= 0)
+ return n;
+ }
+ return -1;
+ }
+
+ // AndOperator
+ // Note: 'AND' is a little funny, since we may be required to match things
+ // of different lengths. If we find a match, we return the length of
+ // the FIRST entry on the list.
+ template <typename Source>
+ inline int RegEx::MatchOpAnd(const Source& source) const {
+ int first = -1;
+ for(std::size_t i=0;i<m_params.size();i++) {
+ int n = m_params[i].MatchUnchecked(source);
+ if(n == -1)
+ return -1;
+ if(i == 0)
+ first = n;
+ }
+ return first;
+ }
+
+ // NotOperator
+ template <typename Source>
+ inline int RegEx::MatchOpNot(const Source& source) const {
+ if(m_params.empty())
+ return -1;
+ if(m_params[0].MatchUnchecked(source) >= 0)
+ return -1;
+ return 1;
+ }
+
+ // SeqOperator
+ template <typename Source>
+ inline int RegEx::MatchOpSeq(const Source& source) const {
+ int offset = 0;
+ for(std::size_t i=0;i<m_params.size();i++) {
+ int n = m_params[i].Match(source + offset); // note Match, not MatchUnchecked because we need to check validity after the offset
+ if(n == -1)
+ return -1;
+ offset += n;
+ }
+
+ return offset;
+ }
+}
+
+#endif // REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/src/scanner.cpp b/external_libs/yaml-cpp/src/scanner.cpp
new file mode 100644
index 00000000..199ef25a
--- /dev/null
+++ b/external_libs/yaml-cpp/src/scanner.cpp
@@ -0,0 +1,387 @@
+#include "scanner.h"
+#include "token.h"
+#include "yaml-cpp/exceptions.h"
+#include "exp.h"
+#include <cassert>
+#include <memory>
+
+namespace YAML
+{
+ Scanner::Scanner(std::istream& in)
+ : INPUT(in), m_startedStream(false), m_endedStream(false), m_simpleKeyAllowed(false), m_canBeJSONFlow(false)
+ {
+ }
+
+ Scanner::~Scanner()
+ {
+ }
+
+ // empty
+ // . Returns true if there are no more tokens to be read
+ bool Scanner::empty()
+ {
+ EnsureTokensInQueue();
+ return m_tokens.empty();
+ }
+
+ // pop
+ // . Simply removes the next token on the queue.
+ void Scanner::pop()
+ {
+ EnsureTokensInQueue();
+ if(!m_tokens.empty())
+ m_tokens.pop();
+ }
+
+ // peek
+ // . Returns (but does not remove) the next token on the queue.
+ Token& Scanner::peek()
+ {
+ EnsureTokensInQueue();
+ assert(!m_tokens.empty()); // should we be asserting here? I mean, we really just be checking
+ // if it's empty before peeking.
+
+#if 0
+ static Token *pLast = 0;
+ if(pLast != &m_tokens.front())
+ std::cerr << "peek: " << m_tokens.front() << "\n";
+ pLast = &m_tokens.front();
+#endif
+
+ return m_tokens.front();
+ }
+
+ // EnsureTokensInQueue
+ // . Scan until there's a valid token at the front of the queue,
+ // or we're sure the queue is empty.
+ void Scanner::EnsureTokensInQueue()
+ {
+ while(1) {
+ if(!m_tokens.empty()) {
+ Token& token = m_tokens.front();
+
+ // if this guy's valid, then we're done
+ if(token.status == Token::VALID)
+ return;
+
+ // here's where we clean up the impossible tokens
+ if(token.status == Token::INVALID) {
+ m_tokens.pop();
+ continue;
+ }
+
+ // note: what's left are the unverified tokens
+ }
+
+ // no token? maybe we've actually finished
+ if(m_endedStream)
+ return;
+
+ // no? then scan...
+ ScanNextToken();
+ }
+ }
+
+ // ScanNextToken
+ // . The main scanning function; here we branch out and
+ // scan whatever the next token should be.
+ void Scanner::ScanNextToken()
+ {
+ if(m_endedStream)
+ return;
+
+ if(!m_startedStream)
+ return StartStream();
+
+ // get rid of whitespace, etc. (in between tokens it should be irrelevent)
+ ScanToNextToken();
+
+ // maybe need to end some blocks
+ PopIndentToHere();
+
+ // *****
+ // And now branch based on the next few characters!
+ // *****
+
+ // end of stream
+ if(!INPUT)
+ return EndStream();
+
+ if(INPUT.column() == 0 && INPUT.peek() == Keys::Directive)
+ return ScanDirective();
+
+ // document token
+ if(INPUT.column() == 0 && Exp::DocStart().Matches(INPUT))
+ return ScanDocStart();
+
+ if(INPUT.column() == 0 && Exp::DocEnd().Matches(INPUT))
+ return ScanDocEnd();
+
+ // flow start/end/entry
+ if(INPUT.peek() == Keys::FlowSeqStart || INPUT.peek() == Keys::FlowMapStart)
+ return ScanFlowStart();
+
+ if(INPUT.peek() == Keys::FlowSeqEnd || INPUT.peek() == Keys::FlowMapEnd)
+ return ScanFlowEnd();
+
+ if(INPUT.peek() == Keys::FlowEntry)
+ return ScanFlowEntry();
+
+ // block/map stuff
+ if(Exp::BlockEntry().Matches(INPUT))
+ return ScanBlockEntry();
+
+ if((InBlockContext() ? Exp::Key() : Exp::KeyInFlow()).Matches(INPUT))
+ return ScanKey();
+
+ if(GetValueRegex().Matches(INPUT))
+ return ScanValue();
+
+ // alias/anchor
+ if(INPUT.peek() == Keys::Alias || INPUT.peek() == Keys::Anchor)
+ return ScanAnchorOrAlias();
+
+ // tag
+ if(INPUT.peek() == Keys::Tag)
+ return ScanTag();
+
+ // special scalars
+ if(InBlockContext() && (INPUT.peek() == Keys::LiteralScalar || INPUT.peek() == Keys::FoldedScalar))
+ return ScanBlockScalar();
+
+ if(INPUT.peek() == '\'' || INPUT.peek() == '\"')
+ return ScanQuotedScalar();
+
+ // plain scalars
+ if((InBlockContext() ? Exp::PlainScalar() : Exp::PlainScalarInFlow()).Matches(INPUT))
+ return ScanPlainScalar();
+
+ // don't know what it is!
+ throw ParserException(INPUT.mark(), ErrorMsg::UNKNOWN_TOKEN);
+ }
+
+ // ScanToNextToken
+ // . Eats input until we reach the next token-like thing.
+ void Scanner::ScanToNextToken()
+ {
+ while(1) {
+ // first eat whitespace
+ while(INPUT && IsWhitespaceToBeEaten(INPUT.peek())) {
+ if(InBlockContext() && Exp::Tab().Matches(INPUT))
+ m_simpleKeyAllowed = false;
+ INPUT.eat(1);
+ }
+
+ // then eat a comment
+ if(Exp::Comment().Matches(INPUT)) {
+ // eat until line break
+ while(INPUT && !Exp::Break().Matches(INPUT))
+ INPUT.eat(1);
+ }
+
+ // if it's NOT a line break, then we're done!
+ if(!Exp::Break().Matches(INPUT))
+ break;
+
+ // otherwise, let's eat the line break and keep going
+ int n = Exp::Break().Match(INPUT);
+ INPUT.eat(n);
+
+ // oh yeah, and let's get rid of that simple key
+ InvalidateSimpleKey();
+
+ // new line - we may be able to accept a simple key now
+ if(InBlockContext())
+ m_simpleKeyAllowed = true;
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ // Misc. helpers
+
+ // IsWhitespaceToBeEaten
+ // . We can eat whitespace if it's a space or tab
+ // . Note: originally tabs in block context couldn't be eaten
+ // "where a simple key could be allowed
+ // (i.e., not at the beginning of a line, or following '-', '?', or ':')"
+ // I think this is wrong, since tabs can be non-content whitespace; it's just
+ // that they can't contribute to indentation, so once you've seen a tab in a
+ // line, you can't start a simple key
+ bool Scanner::IsWhitespaceToBeEaten(char ch)
+ {
+ if(ch == ' ')
+ return true;
+
+ if(ch == '\t')
+ return true;
+
+ return false;
+ }
+
+ // GetValueRegex
+ // . Get the appropriate regex to check if it's a value token
+ const RegEx& Scanner::GetValueRegex() const
+ {
+ if(InBlockContext())
+ return Exp::Value();
+
+ return m_canBeJSONFlow ? Exp::ValueInJSONFlow() : Exp::ValueInFlow();
+ }
+
+ // StartStream
+ // . Set the initial conditions for starting a stream.
+ void Scanner::StartStream()
+ {
+ m_startedStream = true;
+ m_simpleKeyAllowed = true;
+ std::auto_ptr<IndentMarker> pIndent(new IndentMarker(-1, IndentMarker::NONE));
+ m_indentRefs.push_back(pIndent);
+ m_indents.push(&m_indentRefs.back());
+ }
+
+ // EndStream
+ // . Close out the stream, finish up, etc.
+ void Scanner::EndStream()
+ {
+ // force newline
+ if(INPUT.column() > 0)
+ INPUT.ResetColumn();
+
+ PopAllIndents();
+ PopAllSimpleKeys();
+
+ m_simpleKeyAllowed = false;
+ m_endedStream = true;
+ }
+
+ Token *Scanner::PushToken(Token::TYPE type)
+ {
+ m_tokens.push(Token(type, INPUT.mark()));
+ return &m_tokens.back();
+ }
+
+ Token::TYPE Scanner::GetStartTokenFor(IndentMarker::INDENT_TYPE type) const
+ {
+ switch(type) {
+ case IndentMarker::SEQ: return Token::BLOCK_SEQ_START;
+ case IndentMarker::MAP: return Token::BLOCK_MAP_START;
+ case IndentMarker::NONE: assert(false); break;
+ }
+ assert(false);
+ throw std::runtime_error("yaml-cpp: internal error, invalid indent type");
+ }
+
+ // PushIndentTo
+ // . Pushes an indentation onto the stack, and enqueues the
+ // proper token (sequence start or mapping start).
+ // . Returns the indent marker it generates (if any).
+ Scanner::IndentMarker *Scanner::PushIndentTo(int column, IndentMarker::INDENT_TYPE type)
+ {
+ // are we in flow?
+ if(InFlowContext())
+ return 0;
+
+ std::auto_ptr<IndentMarker> pIndent(new IndentMarker(column, type));
+ IndentMarker& indent = *pIndent;
+ const IndentMarker& lastIndent = *m_indents.top();
+
+ // is this actually an indentation?
+ if(indent.column < lastIndent.column)
+ return 0;
+ if(indent.column == lastIndent.column && !(indent.type == IndentMarker::SEQ && lastIndent.type == IndentMarker::MAP))
+ return 0;
+
+ // push a start token
+ indent.pStartToken = PushToken(GetStartTokenFor(type));
+
+ // and then the indent
+ m_indents.push(&indent);
+ m_indentRefs.push_back(pIndent);
+ return &m_indentRefs.back();
+ }
+
+ // PopIndentToHere
+ // . Pops indentations off the stack until we reach the current indentation level,
+ // and enqueues the proper token each time.
+ // . Then pops all invalid indentations off.
+ void Scanner::PopIndentToHere()
+ {
+ // are we in flow?
+ if(InFlowContext())
+ return;
+
+ // now pop away
+ while(!m_indents.empty()) {
+ const IndentMarker& indent = *m_indents.top();
+ if(indent.column < INPUT.column())
+ break;
+ if(indent.column == INPUT.column() && !(indent.type == IndentMarker::SEQ && !Exp::BlockEntry().Matches(INPUT)))
+ break;
+
+ PopIndent();
+ }
+
+ while(!m_indents.empty() && m_indents.top()->status == IndentMarker::INVALID)
+ PopIndent();
+ }
+
+ // PopAllIndents
+ // . Pops all indentations (except for the base empty one) off the stack,
+ // and enqueues the proper token each time.
+ void Scanner::PopAllIndents()
+ {
+ // are we in flow?
+ if(InFlowContext())
+ return;
+
+ // now pop away
+ while(!m_indents.empty()) {
+ const IndentMarker& indent = *m_indents.top();
+ if(indent.type == IndentMarker::NONE)
+ break;
+
+ PopIndent();
+ }
+ }
+
+ // PopIndent
+ // . Pops a single indent, pushing the proper token
+ void Scanner::PopIndent()
+ {
+ const IndentMarker& indent = *m_indents.top();
+ m_indents.pop();
+
+ if(indent.status != IndentMarker::VALID) {
+ InvalidateSimpleKey();
+ return;
+ }
+
+ if(indent.type == IndentMarker::SEQ)
+ m_tokens.push(Token(Token::BLOCK_SEQ_END, INPUT.mark()));
+ else if(indent.type == IndentMarker::MAP)
+ m_tokens.push(Token(Token::BLOCK_MAP_END, INPUT.mark()));
+ }
+
+ // GetTopIndent
+ int Scanner::GetTopIndent() const
+ {
+ if(m_indents.empty())
+ return 0;
+ return m_indents.top()->column;
+ }
+
+ // ThrowParserException
+ // . Throws a ParserException with the current token location
+ // (if available).
+ // . Does not parse any more tokens.
+ void Scanner::ThrowParserException(const std::string& msg) const
+ {
+ Mark mark = Mark::null();
+ if(!m_tokens.empty()) {
+ const Token& token = m_tokens.front();
+ mark = token.mark;
+ }
+ throw ParserException(mark, msg);
+ }
+}
+
diff --git a/external_libs/yaml-cpp/src/scanner.h b/external_libs/yaml-cpp/src/scanner.h
new file mode 100644
index 00000000..bc8dcbe5
--- /dev/null
+++ b/external_libs/yaml-cpp/src/scanner.h
@@ -0,0 +1,132 @@
+#ifndef SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include <ios>
+#include <string>
+#include <queue>
+#include <stack>
+#include <set>
+#include <map>
+#include "ptr_vector.h"
+#include "stream.h"
+#include "token.h"
+
+namespace YAML
+{
+ class Node;
+ class RegEx;
+
+ class Scanner
+ {
+ public:
+ Scanner(std::istream& in);
+ ~Scanner();
+
+ // token queue management (hopefully this looks kinda stl-ish)
+ bool empty();
+ void pop();
+ Token& peek();
+
+ private:
+ struct IndentMarker {
+ enum INDENT_TYPE { MAP, SEQ, NONE };
+ enum STATUS { VALID, INVALID, UNKNOWN };
+ IndentMarker(int column_, INDENT_TYPE type_): column(column_), type(type_), status(VALID), pStartToken(0) {}
+
+ int column;
+ INDENT_TYPE type;
+ STATUS status;
+ Token *pStartToken;
+ };
+
+ enum FLOW_MARKER { FLOW_MAP, FLOW_SEQ };
+
+ private:
+ // scanning
+ void EnsureTokensInQueue();
+ void ScanNextToken();
+ void ScanToNextToken();
+ void StartStream();
+ void EndStream();
+ Token *PushToken(Token::TYPE type);
+
+ bool InFlowContext() const { return !m_flows.empty(); }
+ bool InBlockContext() const { return m_flows.empty(); }
+ int GetFlowLevel() const { return m_flows.size(); }
+
+ Token::TYPE GetStartTokenFor(IndentMarker::INDENT_TYPE type) const;
+ IndentMarker *PushIndentTo(int column, IndentMarker::INDENT_TYPE type);
+ void PopIndentToHere();
+ void PopAllIndents();
+ void PopIndent();
+ int GetTopIndent() const;
+
+ // checking input
+ bool CanInsertPotentialSimpleKey() const;
+ bool ExistsActiveSimpleKey() const;
+ void InsertPotentialSimpleKey();
+ void InvalidateSimpleKey();
+ bool VerifySimpleKey();
+ void PopAllSimpleKeys();
+
+ void ThrowParserException(const std::string& msg) const;
+
+ bool IsWhitespaceToBeEaten(char ch);
+ const RegEx& GetValueRegex() const;
+
+ struct SimpleKey {
+ SimpleKey(const Mark& mark_, int flowLevel_);
+
+ void Validate();
+ void Invalidate();
+
+ Mark mark;
+ int flowLevel;
+ IndentMarker *pIndent;
+ Token *pMapStart, *pKey;
+ };
+
+ // and the tokens
+ void ScanDirective();
+ void ScanDocStart();
+ void ScanDocEnd();
+ void ScanBlockSeqStart();
+ void ScanBlockMapSTart();
+ void ScanBlockEnd();
+ void ScanBlockEntry();
+ void ScanFlowStart();
+ void ScanFlowEnd();
+ void ScanFlowEntry();
+ void ScanKey();
+ void ScanValue();
+ void ScanAnchorOrAlias();
+ void ScanTag();
+ void ScanPlainScalar();
+ void ScanQuotedScalar();
+ void ScanBlockScalar();
+
+ private:
+ // the stream
+ Stream INPUT;
+
+ // the output (tokens)
+ std::queue<Token> m_tokens;
+
+ // state info
+ bool m_startedStream, m_endedStream;
+ bool m_simpleKeyAllowed;
+ bool m_canBeJSONFlow;
+ std::stack<SimpleKey> m_simpleKeys;
+ std::stack<IndentMarker *> m_indents;
+ ptr_vector<IndentMarker> m_indentRefs; // for "garbage collection"
+ std::stack<FLOW_MARKER> m_flows;
+ };
+}
+
+#endif // SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
diff --git a/external_libs/yaml-cpp/src/scanscalar.cpp b/external_libs/yaml-cpp/src/scanscalar.cpp
new file mode 100644
index 00000000..064c0867
--- /dev/null
+++ b/external_libs/yaml-cpp/src/scanscalar.cpp
@@ -0,0 +1,214 @@
+#include "scanscalar.h"
+#include "scanner.h"
+#include "exp.h"
+#include "yaml-cpp/exceptions.h"
+#include "token.h"
+
+namespace YAML
+{
+ // ScanScalar
+ // . This is where the scalar magic happens.
+ //
+ // . We do the scanning in three phases:
+ // 1. Scan until newline
+ // 2. Eat newline
+ // 3. Scan leading blanks.
+ //
+ // . Depending on the parameters given, we store or stop
+ // and different places in the above flow.
+ std::string ScanScalar(Stream& INPUT, ScanScalarParams& params)
+ {
+ bool foundNonEmptyLine = false;
+ bool pastOpeningBreak = (params.fold == FOLD_FLOW);
+ bool emptyLine = false, moreIndented = false;
+ int foldedNewlineCount = 0;
+ bool foldedNewlineStartedMoreIndented = false;
+ std::size_t lastEscapedChar = std::string::npos;
+ std::string scalar;
+ params.leadingSpaces = false;
+
+ while(INPUT) {
+ // ********************************
+ // Phase #1: scan until line ending
+
+ std::size_t lastNonWhitespaceChar = scalar.size();
+ bool escapedNewline = false;
+ while(!params.end.Matches(INPUT) && !Exp::Break().Matches(INPUT)) {
+ if(!INPUT)
+ break;
+
+ // document indicator?
+ if(INPUT.column() == 0 && Exp::DocIndicator().Matches(INPUT)) {
+ if(params.onDocIndicator == BREAK)
+ break;
+ else if(params.onDocIndicator == THROW)
+ throw ParserException(INPUT.mark(), ErrorMsg::DOC_IN_SCALAR);
+ }
+
+ foundNonEmptyLine = true;
+ pastOpeningBreak = true;
+
+ // escaped newline? (only if we're escaping on slash)
+ if(params.escape == '\\' && Exp::EscBreak().Matches(INPUT)) {
+ // eat escape character and get out (but preserve trailing whitespace!)
+ INPUT.get();
+ lastNonWhitespaceChar = scalar.size();
+ lastEscapedChar = scalar.size();
+ escapedNewline = true;
+ break;
+ }
+
+ // escape this?
+ if(INPUT.peek() == params.escape) {
+ scalar += Exp::Escape(INPUT);
+ lastNonWhitespaceChar = scalar.size();
+ lastEscapedChar = scalar.size();
+ continue;
+ }
+
+ // otherwise, just add the damn character
+ char ch = INPUT.get();
+ scalar += ch;
+ if(ch != ' ' && ch != '\t')
+ lastNonWhitespaceChar = scalar.size();
+ }
+
+ // eof? if we're looking to eat something, then we throw
+ if(!INPUT) {
+ if(params.eatEnd)
+ throw ParserException(INPUT.mark(), ErrorMsg::EOF_IN_SCALAR);
+ break;
+ }
+
+ // doc indicator?
+ if(params.onDocIndicator == BREAK && INPUT.column() == 0 && Exp::DocIndicator().Matches(INPUT))
+ break;
+
+ // are we done via character match?
+ int n = params.end.Match(INPUT);
+ if(n >= 0) {
+ if(params.eatEnd)
+ INPUT.eat(n);
+ break;
+ }
+
+ // do we remove trailing whitespace?
+ if(params.fold == FOLD_FLOW)
+ scalar.erase(lastNonWhitespaceChar);
+
+ // ********************************
+ // Phase #2: eat line ending
+ n = Exp::Break().Match(INPUT);
+ INPUT.eat(n);
+
+ // ********************************
+ // Phase #3: scan initial spaces
+
+ // first the required indentation
+ while(INPUT.peek() == ' ' && (INPUT.column() < params.indent || (params.detectIndent && !foundNonEmptyLine)))
+ INPUT.eat(1);
+
+ // update indent if we're auto-detecting
+ if(params.detectIndent && !foundNonEmptyLine)
+ params.indent = std::max(params.indent, INPUT.column());
+
+ // and then the rest of the whitespace
+ while(Exp::Blank().Matches(INPUT)) {
+ // we check for tabs that masquerade as indentation
+ if(INPUT.peek() == '\t'&& INPUT.column() < params.indent && params.onTabInIndentation == THROW)
+ throw ParserException(INPUT.mark(), ErrorMsg::TAB_IN_INDENTATION);
+
+ if(!params.eatLeadingWhitespace)
+ break;
+
+ INPUT.eat(1);
+ }
+
+ // was this an empty line?
+ bool nextEmptyLine = Exp::Break().Matches(INPUT);
+ bool nextMoreIndented = Exp::Blank().Matches(INPUT);
+ if(params.fold == FOLD_BLOCK && foldedNewlineCount == 0 && nextEmptyLine)
+ foldedNewlineStartedMoreIndented = moreIndented;
+
+ // for block scalars, we always start with a newline, so we should ignore it (not fold or keep)
+ if(pastOpeningBreak) {
+ switch(params.fold) {
+ case DONT_FOLD:
+ scalar += "\n";
+ break;
+ case FOLD_BLOCK:
+ if(!emptyLine && !nextEmptyLine && !moreIndented && !nextMoreIndented && INPUT.column() >= params.indent)
+ scalar += " ";
+ else if(nextEmptyLine)
+ foldedNewlineCount++;
+ else
+ scalar += "\n";
+
+ if(!nextEmptyLine && foldedNewlineCount > 0) {
+ scalar += std::string(foldedNewlineCount - 1, '\n');
+ if(foldedNewlineStartedMoreIndented || nextMoreIndented | !foundNonEmptyLine)
+ scalar += "\n";
+ foldedNewlineCount = 0;
+ }
+ break;
+ case FOLD_FLOW:
+ if(nextEmptyLine)
+ scalar += "\n";
+ else if(!emptyLine && !nextEmptyLine && !escapedNewline)
+ scalar += " ";
+ break;
+ }
+ }
+
+ emptyLine = nextEmptyLine;
+ moreIndented = nextMoreIndented;
+ pastOpeningBreak = true;
+
+ // are we done via indentation?
+ if(!emptyLine && INPUT.column() < params.indent) {
+ params.leadingSpaces = true;
+ break;
+ }
+ }
+
+ // post-processing
+ if(params.trimTrailingSpaces) {
+ std::size_t pos = scalar.find_last_not_of(' ');
+ if(lastEscapedChar != std::string::npos) {
+ if(pos < lastEscapedChar || pos == std::string::npos)
+ pos = lastEscapedChar;
+ }
+ if(pos < scalar.size())
+ scalar.erase(pos + 1);
+ }
+
+ switch(params.chomp) {
+ case CLIP: {
+ std::size_t pos = scalar.find_last_not_of('\n');
+ if(lastEscapedChar != std::string::npos) {
+ if(pos < lastEscapedChar || pos == std::string::npos)
+ pos = lastEscapedChar;
+ }
+ if(pos == std::string::npos)
+ scalar.erase();
+ else if(pos + 1 < scalar.size())
+ scalar.erase(pos + 2);
+ } break;
+ case STRIP: {
+ std::size_t pos = scalar.find_last_not_of('\n');
+ if(lastEscapedChar != std::string::npos) {
+ if(pos < lastEscapedChar || pos == std::string::npos)
+ pos = lastEscapedChar;
+ }
+ if(pos == std::string::npos)
+ scalar.erase();
+ else if(pos < scalar.size())
+ scalar.erase(pos + 1);
+ } break;
+ default:
+ break;
+ }
+
+ return scalar;
+ }
+}
diff --git a/external_libs/yaml-cpp/src/scanscalar.h b/external_libs/yaml-cpp/src/scanscalar.h
new file mode 100644
index 00000000..c198cb18
--- /dev/null
+++ b/external_libs/yaml-cpp/src/scanscalar.h
@@ -0,0 +1,45 @@
+#ifndef SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include <string>
+#include "regex.h"
+#include "stream.h"
+
+namespace YAML
+{
+ enum CHOMP { STRIP = -1, CLIP, KEEP };
+ enum ACTION { NONE, BREAK, THROW };
+ enum FOLD { DONT_FOLD, FOLD_BLOCK, FOLD_FLOW };
+
+ struct ScanScalarParams {
+ ScanScalarParams(): eatEnd(false), indent(0), detectIndent(false), eatLeadingWhitespace(0), escape(0), fold(DONT_FOLD),
+ trimTrailingSpaces(0), chomp(CLIP), onDocIndicator(NONE), onTabInIndentation(NONE), leadingSpaces(false) {}
+
+ // input:
+ RegEx end; // what condition ends this scalar?
+ bool eatEnd; // should we eat that condition when we see it?
+ int indent; // what level of indentation should be eaten and ignored?
+ bool detectIndent; // should we try to autodetect the indent?
+ bool eatLeadingWhitespace; // should we continue eating this delicious indentation after 'indent' spaces?
+ char escape; // what character do we escape on (i.e., slash or single quote) (0 for none)
+ FOLD fold; // how do we fold line ends?
+ bool trimTrailingSpaces; // do we remove all trailing spaces (at the very end)
+ CHOMP chomp; // do we strip, clip, or keep trailing newlines (at the very end)
+ // Note: strip means kill all, clip means keep at most one, keep means keep all
+ ACTION onDocIndicator; // what do we do if we see a document indicator?
+ ACTION onTabInIndentation; // what do we do if we see a tab where we should be seeing indentation spaces
+
+ // output:
+ bool leadingSpaces;
+ };
+
+ std::string ScanScalar(Stream& INPUT, ScanScalarParams& info);
+}
+
+#endif // SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
diff --git a/external_libs/yaml-cpp/src/scantag.cpp b/external_libs/yaml-cpp/src/scantag.cpp
new file mode 100644
index 00000000..b71cbcc4
--- /dev/null
+++ b/external_libs/yaml-cpp/src/scantag.cpp
@@ -0,0 +1,84 @@
+#include "scanner.h"
+#include "regex.h"
+#include "exp.h"
+#include "yaml-cpp/exceptions.h"
+
+namespace YAML
+{
+ const std::string ScanVerbatimTag(Stream& INPUT)
+ {
+ std::string tag;
+
+ // eat the start character
+ INPUT.get();
+
+ while(INPUT) {
+ if(INPUT.peek() == Keys::VerbatimTagEnd) {
+ // eat the end character
+ INPUT.get();
+ return tag;
+ }
+
+ int n = Exp::URI().Match(INPUT);
+ if(n <= 0)
+ break;
+
+ tag += INPUT.get(n);
+ }
+
+ throw ParserException(INPUT.mark(), ErrorMsg::END_OF_VERBATIM_TAG);
+ }
+
+ const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle)
+ {
+ std::string tag;
+ canBeHandle = true;
+ Mark firstNonWordChar;
+
+ while(INPUT) {
+ if(INPUT.peek() == Keys::Tag) {
+ if(!canBeHandle)
+ throw ParserException(firstNonWordChar, ErrorMsg::CHAR_IN_TAG_HANDLE);
+ break;
+ }
+
+ int n = 0;
+ if(canBeHandle) {
+ n = Exp::Word().Match(INPUT);
+ if(n <= 0) {
+ canBeHandle = false;
+ firstNonWordChar = INPUT.mark();
+ }
+ }
+
+ if(!canBeHandle)
+ n = Exp::Tag().Match(INPUT);
+
+ if(n <= 0)
+ break;
+
+ tag += INPUT.get(n);
+ }
+
+ return tag;
+ }
+
+ const std::string ScanTagSuffix(Stream& INPUT)
+ {
+ std::string tag;
+
+ while(INPUT) {
+ int n = Exp::Tag().Match(INPUT);
+ if(n <= 0)
+ break;
+
+ tag += INPUT.get(n);
+ }
+
+ if(tag.empty())
+ throw ParserException(INPUT.mark(), ErrorMsg::TAG_WITH_NO_SUFFIX);
+
+ return tag;
+ }
+}
+
diff --git a/external_libs/yaml-cpp/src/scantag.h b/external_libs/yaml-cpp/src/scantag.h
new file mode 100644
index 00000000..38437c03
--- /dev/null
+++ b/external_libs/yaml-cpp/src/scantag.h
@@ -0,0 +1,20 @@
+#ifndef SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include <string>
+#include "stream.h"
+
+namespace YAML
+{
+ const std::string ScanVerbatimTag(Stream& INPUT);
+ const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle);
+ const std::string ScanTagSuffix(Stream& INPUT);
+}
+
+#endif // SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
diff --git a/external_libs/yaml-cpp/src/scantoken.cpp b/external_libs/yaml-cpp/src/scantoken.cpp
new file mode 100644
index 00000000..06d9cd62
--- /dev/null
+++ b/external_libs/yaml-cpp/src/scantoken.cpp
@@ -0,0 +1,439 @@
+#include "scanner.h"
+#include "token.h"
+#include "yaml-cpp/exceptions.h"
+#include "exp.h"
+#include "scanscalar.h"
+#include "scantag.h"
+#include "tag.h"
+#include <sstream>
+
+namespace YAML
+{
+ ///////////////////////////////////////////////////////////////////////
+ // Specialization for scanning specific tokens
+
+ // Directive
+ // . Note: no semantic checking is done here (that's for the parser to do)
+ void Scanner::ScanDirective()
+ {
+ std::string name;
+ std::vector <std::string> params;
+
+ // pop indents and simple keys
+ PopAllIndents();
+ PopAllSimpleKeys();
+
+ m_simpleKeyAllowed = false;
+ m_canBeJSONFlow = false;
+
+ // store pos and eat indicator
+ Token token(Token::DIRECTIVE, INPUT.mark());
+ INPUT.eat(1);
+
+ // read name
+ while(INPUT && !Exp::BlankOrBreak().Matches(INPUT))
+ token.value += INPUT.get();
+
+ // read parameters
+ while(1) {
+ // first get rid of whitespace
+ while(Exp::Blank().Matches(INPUT))
+ INPUT.eat(1);
+
+ // break on newline or comment
+ if(!INPUT || Exp::Break().Matches(INPUT) || Exp::Comment().Matches(INPUT))
+ break;
+
+ // now read parameter
+ std::string param;
+ while(INPUT && !Exp::BlankOrBreak().Matches(INPUT))
+ param += INPUT.get();
+
+ token.params.push_back(param);
+ }
+
+ m_tokens.push(token);
+ }
+
+ // DocStart
+ void Scanner::ScanDocStart()
+ {
+ PopAllIndents();
+ PopAllSimpleKeys();
+ m_simpleKeyAllowed = false;
+ m_canBeJSONFlow = false;
+
+ // eat
+ Mark mark = INPUT.mark();
+ INPUT.eat(3);
+ m_tokens.push(Token(Token::DOC_START, mark));
+ }
+
+ // DocEnd
+ void Scanner::ScanDocEnd()
+ {
+ PopAllIndents();
+ PopAllSimpleKeys();
+ m_simpleKeyAllowed = false;
+ m_canBeJSONFlow = false;
+
+ // eat
+ Mark mark = INPUT.mark();
+ INPUT.eat(3);
+ m_tokens.push(Token(Token::DOC_END, mark));
+ }
+
+ // FlowStart
+ void Scanner::ScanFlowStart()
+ {
+ // flows can be simple keys
+ InsertPotentialSimpleKey();
+ m_simpleKeyAllowed = true;
+ m_canBeJSONFlow = false;
+
+ // eat
+ Mark mark = INPUT.mark();
+ char ch = INPUT.get();
+ FLOW_MARKER flowType = (ch == Keys::FlowSeqStart ? FLOW_SEQ : FLOW_MAP);
+ m_flows.push(flowType);
+ Token::TYPE type = (flowType == FLOW_SEQ ? Token::FLOW_SEQ_START : Token::FLOW_MAP_START);
+ m_tokens.push(Token(type, mark));
+ }
+
+ // FlowEnd
+ void Scanner::ScanFlowEnd()
+ {
+ if(InBlockContext())
+ throw ParserException(INPUT.mark(), ErrorMsg::FLOW_END);
+
+ // we might have a solo entry in the flow context
+ if(InFlowContext()) {
+ if(m_flows.top() == FLOW_MAP && VerifySimpleKey())
+ m_tokens.push(Token(Token::VALUE, INPUT.mark()));
+ else if(m_flows.top() == FLOW_SEQ)
+ InvalidateSimpleKey();
+ }
+
+ m_simpleKeyAllowed = false;
+ m_canBeJSONFlow = true;
+
+ // eat
+ Mark mark = INPUT.mark();
+ char ch = INPUT.get();
+
+ // check that it matches the start
+ FLOW_MARKER flowType = (ch == Keys::FlowSeqEnd ? FLOW_SEQ : FLOW_MAP);
+ if(m_flows.top() != flowType)
+ throw ParserException(mark, ErrorMsg::FLOW_END);
+ m_flows.pop();
+
+ Token::TYPE type = (flowType ? Token::FLOW_SEQ_END : Token::FLOW_MAP_END);
+ m_tokens.push(Token(type, mark));
+ }
+
+ // FlowEntry
+ void Scanner::ScanFlowEntry()
+ {
+ // we might have a solo entry in the flow context
+ if(InFlowContext()) {
+ if(m_flows.top() == FLOW_MAP && VerifySimpleKey())
+ m_tokens.push(Token(Token::VALUE, INPUT.mark()));
+ else if(m_flows.top() == FLOW_SEQ)
+ InvalidateSimpleKey();
+ }
+
+ m_simpleKeyAllowed = true;
+ m_canBeJSONFlow = false;
+
+ // eat
+ Mark mark = INPUT.mark();
+ INPUT.eat(1);
+ m_tokens.push(Token(Token::FLOW_ENTRY, mark));
+ }
+
+ // BlockEntry
+ void Scanner::ScanBlockEntry()
+ {
+ // we better be in the block context!
+ if(InFlowContext())
+ throw ParserException(INPUT.mark(), ErrorMsg::BLOCK_ENTRY);
+
+ // can we put it here?
+ if(!m_simpleKeyAllowed)
+ throw ParserException(INPUT.mark(), ErrorMsg::BLOCK_ENTRY);
+
+ PushIndentTo(INPUT.column(), IndentMarker::SEQ);
+ m_simpleKeyAllowed = true;
+ m_canBeJSONFlow = false;
+
+ // eat
+ Mark mark = INPUT.mark();
+ INPUT.eat(1);
+ m_tokens.push(Token(Token::BLOCK_ENTRY, mark));
+ }
+
+ // Key
+ void Scanner::ScanKey()
+ {
+ // handle keys diffently in the block context (and manage indents)
+ if(InBlockContext()) {
+ if(!m_simpleKeyAllowed)
+ throw ParserException(INPUT.mark(), ErrorMsg::MAP_KEY);
+
+ PushIndentTo(INPUT.column(), IndentMarker::MAP);
+ }
+
+ // can only put a simple key here if we're in block context
+ m_simpleKeyAllowed = InBlockContext();
+
+ // eat
+ Mark mark = INPUT.mark();
+ INPUT.eat(1);
+ m_tokens.push(Token(Token::KEY, mark));
+ }
+
+ // Value
+ void Scanner::ScanValue()
+ {
+ // and check that simple key
+ bool isSimpleKey = VerifySimpleKey();
+ m_canBeJSONFlow = false;
+
+ if(isSimpleKey) {
+ // can't follow a simple key with another simple key (dunno why, though - it seems fine)
+ m_simpleKeyAllowed = false;
+ } else {
+ // handle values diffently in the block context (and manage indents)
+ if(InBlockContext()) {
+ if(!m_simpleKeyAllowed)
+ throw ParserException(INPUT.mark(), ErrorMsg::MAP_VALUE);
+
+ PushIndentTo(INPUT.column(), IndentMarker::MAP);
+ }
+
+ // can only put a simple key here if we're in block context
+ m_simpleKeyAllowed = InBlockContext();
+ }
+
+ // eat
+ Mark mark = INPUT.mark();
+ INPUT.eat(1);
+ m_tokens.push(Token(Token::VALUE, mark));
+ }
+
+ // AnchorOrAlias
+ void Scanner::ScanAnchorOrAlias()
+ {
+ bool alias;
+ std::string name;
+
+ // insert a potential simple key
+ InsertPotentialSimpleKey();
+ m_simpleKeyAllowed = false;
+ m_canBeJSONFlow = false;
+
+ // eat the indicator
+ Mark mark = INPUT.mark();
+ char indicator = INPUT.get();
+ alias = (indicator == Keys::Alias);
+
+ // now eat the content
+ while(INPUT && Exp::Anchor().Matches(INPUT))
+ name += INPUT.get();
+
+ // we need to have read SOMETHING!
+ if(name.empty())
+ throw ParserException(INPUT.mark(), alias ? ErrorMsg::ALIAS_NOT_FOUND : ErrorMsg::ANCHOR_NOT_FOUND);
+
+ // and needs to end correctly
+ if(INPUT && !Exp::AnchorEnd().Matches(INPUT))
+ throw ParserException(INPUT.mark(), alias ? ErrorMsg::CHAR_IN_ALIAS : ErrorMsg::CHAR_IN_ANCHOR);
+
+ // and we're done
+ Token token(alias ? Token::ALIAS : Token::ANCHOR, mark);
+ token.value = name;
+ m_tokens.push(token);
+ }
+
+ // Tag
+ void Scanner::ScanTag()
+ {
+ // insert a potential simple key
+ InsertPotentialSimpleKey();
+ m_simpleKeyAllowed = false;
+ m_canBeJSONFlow = false;
+
+ Token token(Token::TAG, INPUT.mark());
+
+ // eat the indicator
+ INPUT.get();
+
+ if(INPUT && INPUT.peek() == Keys::VerbatimTagStart){
+ std::string tag = ScanVerbatimTag(INPUT);
+
+ token.value = tag;
+ token.data = Tag::VERBATIM;
+ } else {
+ bool canBeHandle;
+ token.value = ScanTagHandle(INPUT, canBeHandle);
+ if(!canBeHandle && token.value.empty())
+ token.data = Tag::NON_SPECIFIC;
+ else if(token.value.empty())
+ token.data = Tag::SECONDARY_HANDLE;
+ else
+ token.data = Tag::PRIMARY_HANDLE;
+
+ // is there a suffix?
+ if(canBeHandle && INPUT.peek() == Keys::Tag) {
+ // eat the indicator
+ INPUT.get();
+ token.params.push_back(ScanTagSuffix(INPUT));
+ token.data = Tag::NAMED_HANDLE;
+ }
+ }
+
+ m_tokens.push(token);
+ }
+
+ // PlainScalar
+ void Scanner::ScanPlainScalar()
+ {
+ std::string scalar;
+
+ // set up the scanning parameters
+ ScanScalarParams params;
+ params.end = (InFlowContext() ? Exp::EndScalarInFlow() : Exp::EndScalar()) || (Exp::BlankOrBreak() + Exp::Comment());
+ params.eatEnd = false;
+ params.indent = (InFlowContext() ? 0 : GetTopIndent() + 1);
+ params.fold = FOLD_FLOW;
+ params.eatLeadingWhitespace = true;
+ params.trimTrailingSpaces = true;
+ params.chomp = STRIP;
+ params.onDocIndicator = BREAK;
+ params.onTabInIndentation = THROW;
+
+ // insert a potential simple key
+ InsertPotentialSimpleKey();
+
+ Mark mark = INPUT.mark();
+ scalar = ScanScalar(INPUT, params);
+
+ // can have a simple key only if we ended the scalar by starting a new line
+ m_simpleKeyAllowed = params.leadingSpaces;
+ m_canBeJSONFlow = false;
+
+ // finally, check and see if we ended on an illegal character
+ //if(Exp::IllegalCharInScalar.Matches(INPUT))
+ // throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_SCALAR);
+
+ Token token(Token::PLAIN_SCALAR, mark);
+ token.value = scalar;
+ m_tokens.push(token);
+ }
+
+ // QuotedScalar
+ void Scanner::ScanQuotedScalar()
+ {
+ std::string scalar;
+
+ // peek at single or double quote (don't eat because we need to preserve (for the time being) the input position)
+ char quote = INPUT.peek();
+ bool single = (quote == '\'');
+
+ // setup the scanning parameters
+ ScanScalarParams params;
+ params.end = (single ? RegEx(quote) && !Exp::EscSingleQuote() : RegEx(quote));
+ params.eatEnd = true;
+ params.escape = (single ? '\'' : '\\');
+ params.indent = 0;
+ params.fold = FOLD_FLOW;
+ params.eatLeadingWhitespace = true;
+ params.trimTrailingSpaces = false;
+ params.chomp = CLIP;
+ params.onDocIndicator = THROW;
+
+ // insert a potential simple key
+ InsertPotentialSimpleKey();
+
+ Mark mark = INPUT.mark();
+
+ // now eat that opening quote
+ INPUT.get();
+
+ // and scan
+ scalar = ScanScalar(INPUT, params);
+ m_simpleKeyAllowed = false;
+ m_canBeJSONFlow = true;
+
+ Token token(Token::NON_PLAIN_SCALAR, mark);
+ token.value = scalar;
+ m_tokens.push(token);
+ }
+
+ // BlockScalarToken
+ // . These need a little extra processing beforehand.
+ // . We need to scan the line where the indicator is (this doesn't count as part of the scalar),
+ // and then we need to figure out what level of indentation we'll be using.
+ void Scanner::ScanBlockScalar()
+ {
+ std::string scalar;
+
+ ScanScalarParams params;
+ params.indent = 1;
+ params.detectIndent = true;
+
+ // eat block indicator ('|' or '>')
+ Mark mark = INPUT.mark();
+ char indicator = INPUT.get();
+ params.fold = (indicator == Keys::FoldedScalar ? FOLD_BLOCK : DONT_FOLD);
+
+ // eat chomping/indentation indicators
+ params.chomp = CLIP;
+ int n = Exp::Chomp().Match(INPUT);
+ for(int i=0;i<n;i++) {
+ char ch = INPUT.get();
+ if(ch == '+')
+ params.chomp = KEEP;
+ else if(ch == '-')
+ params.chomp = STRIP;
+ else if(Exp::Digit().Matches(ch)) {
+ if(ch == '0')
+ throw ParserException(INPUT.mark(), ErrorMsg::ZERO_INDENT_IN_BLOCK);
+
+ params.indent = ch - '0';
+ params.detectIndent = false;
+ }
+ }
+
+ // now eat whitespace
+ while(Exp::Blank().Matches(INPUT))
+ INPUT.eat(1);
+
+ // and comments to the end of the line
+ if(Exp::Comment().Matches(INPUT))
+ while(INPUT && !Exp::Break().Matches(INPUT))
+ INPUT.eat(1);
+
+ // if it's not a line break, then we ran into a bad character inline
+ if(INPUT && !Exp::Break().Matches(INPUT))
+ throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_BLOCK);
+
+ // set the initial indentation
+ if(GetTopIndent() >= 0)
+ params.indent += GetTopIndent();
+
+ params.eatLeadingWhitespace = false;
+ params.trimTrailingSpaces = false;
+ params.onTabInIndentation = THROW;
+
+ scalar = ScanScalar(INPUT, params);
+
+ // simple keys always ok after block scalars (since we're gonna start a new line anyways)
+ m_simpleKeyAllowed = true;
+ m_canBeJSONFlow = false;
+
+ Token token(Token::NON_PLAIN_SCALAR, mark);
+ token.value = scalar;
+ m_tokens.push(token);
+ }
+}
diff --git a/external_libs/yaml-cpp/src/setting.h b/external_libs/yaml-cpp/src/setting.h
new file mode 100644
index 00000000..806ccdae
--- /dev/null
+++ b/external_libs/yaml-cpp/src/setting.h
@@ -0,0 +1,105 @@
+#ifndef SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include <memory>
+#include <vector>
+#include "yaml-cpp/noncopyable.h"
+
+namespace YAML
+{
+ class SettingChangeBase;
+
+ template <typename T>
+ class Setting
+ {
+ public:
+ Setting(): m_value() {}
+
+ const T get() const { return m_value; }
+ std::auto_ptr <SettingChangeBase> set(const T& value);
+ void restore(const Setting<T>& oldSetting) {
+ m_value = oldSetting.get();
+ }
+
+ private:
+ T m_value;
+ };
+
+ class SettingChangeBase
+ {
+ public:
+ virtual ~SettingChangeBase() {}
+ virtual void pop() = 0;
+ };
+
+ template <typename T>
+ class SettingChange: public SettingChangeBase
+ {
+ public:
+ SettingChange(Setting<T> *pSetting): m_pCurSetting(pSetting) {
+ // copy old setting to save its state
+ m_oldSetting = *pSetting;
+ }
+
+ virtual void pop() {
+ m_pCurSetting->restore(m_oldSetting);
+ }
+
+ private:
+ Setting<T> *m_pCurSetting;
+ Setting<T> m_oldSetting;
+ };
+
+ template <typename T>
+ inline std::auto_ptr <SettingChangeBase> Setting<T>::set(const T& value) {
+ std::auto_ptr <SettingChangeBase> pChange(new SettingChange<T> (this));
+ m_value = value;
+ return pChange;
+ }
+
+ class SettingChanges: private noncopyable
+ {
+ public:
+ SettingChanges() {}
+ ~SettingChanges() { clear(); }
+
+ void clear() {
+ restore();
+
+ for(setting_changes::const_iterator it=m_settingChanges.begin();it!=m_settingChanges.end();++it)
+ delete *it;
+ m_settingChanges.clear();
+ }
+
+ void restore() {
+ for(setting_changes::const_iterator it=m_settingChanges.begin();it!=m_settingChanges.end();++it)
+ (*it)->pop();
+ }
+
+ void push(std::auto_ptr <SettingChangeBase> pSettingChange) {
+ m_settingChanges.push_back(pSettingChange.release());
+ }
+
+ // like std::auto_ptr - assignment is transfer of ownership
+ SettingChanges& operator = (SettingChanges& rhs) {
+ if(this == &rhs)
+ return *this;
+
+ clear();
+ m_settingChanges = rhs.m_settingChanges;
+ rhs.m_settingChanges.clear();
+ return *this;
+ }
+
+ private:
+ typedef std::vector <SettingChangeBase *> setting_changes;
+ setting_changes m_settingChanges;
+ };
+}
+
+#endif // SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/src/simplekey.cpp b/external_libs/yaml-cpp/src/simplekey.cpp
new file mode 100644
index 00000000..857a9e0b
--- /dev/null
+++ b/external_libs/yaml-cpp/src/simplekey.cpp
@@ -0,0 +1,139 @@
+#include "scanner.h"
+#include "token.h"
+#include "yaml-cpp/exceptions.h"
+#include "exp.h"
+
+namespace YAML
+{
+ Scanner::SimpleKey::SimpleKey(const Mark& mark_, int flowLevel_)
+ : mark(mark_), flowLevel(flowLevel_), pIndent(0), pMapStart(0), pKey(0)
+ {
+ }
+
+ void Scanner::SimpleKey::Validate()
+ {
+ // Note: pIndent will *not* be garbage here;
+ // we "garbage collect" them so we can
+ // always refer to them
+ if(pIndent)
+ pIndent->status = IndentMarker::VALID;
+ if(pMapStart)
+ pMapStart->status = Token::VALID;
+ if(pKey)
+ pKey->status = Token::VALID;
+ }
+
+ void Scanner::SimpleKey::Invalidate()
+ {
+ if(pIndent)
+ pIndent->status = IndentMarker::INVALID;
+ if(pMapStart)
+ pMapStart->status = Token::INVALID;
+ if(pKey)
+ pKey->status = Token::INVALID;
+ }
+
+ // CanInsertPotentialSimpleKey
+ bool Scanner::CanInsertPotentialSimpleKey() const
+ {
+ if(!m_simpleKeyAllowed)
+ return false;
+
+ return !ExistsActiveSimpleKey();
+ }
+
+ // ExistsActiveSimpleKey
+ // . Returns true if there's a potential simple key at our flow level
+ // (there's allowed at most one per flow level, i.e., at the start of the flow start token)
+ bool Scanner::ExistsActiveSimpleKey() const
+ {
+ if(m_simpleKeys.empty())
+ return false;
+
+ const SimpleKey& key = m_simpleKeys.top();
+ return key.flowLevel == GetFlowLevel();
+ }
+
+ // InsertPotentialSimpleKey
+ // . If we can, add a potential simple key to the queue,
+ // and save it on a stack.
+ void Scanner::InsertPotentialSimpleKey()
+ {
+ if(!CanInsertPotentialSimpleKey())
+ return;
+
+ SimpleKey key(INPUT.mark(), GetFlowLevel());
+
+ // first add a map start, if necessary
+ if(InBlockContext()) {
+ key.pIndent = PushIndentTo(INPUT.column(), IndentMarker::MAP);
+ if(key.pIndent) {
+ key.pIndent->status = IndentMarker::UNKNOWN;
+ key.pMapStart = key.pIndent->pStartToken;
+ key.pMapStart->status = Token::UNVERIFIED;
+ }
+ }
+
+ // then add the (now unverified) key
+ m_tokens.push(Token(Token::KEY, INPUT.mark()));
+ key.pKey = &m_tokens.back();
+ key.pKey->status = Token::UNVERIFIED;
+
+ m_simpleKeys.push(key);
+ }
+
+ // InvalidateSimpleKey
+ // . Automatically invalidate the simple key in our flow level
+ void Scanner::InvalidateSimpleKey()
+ {
+ if(m_simpleKeys.empty())
+ return;
+
+ // grab top key
+ SimpleKey& key = m_simpleKeys.top();
+ if(key.flowLevel != GetFlowLevel())
+ return;
+
+ key.Invalidate();
+ m_simpleKeys.pop();
+ }
+
+ // VerifySimpleKey
+ // . Determines whether the latest simple key to be added is valid,
+ // and if so, makes it valid.
+ bool Scanner::VerifySimpleKey()
+ {
+ if(m_simpleKeys.empty())
+ return false;
+
+ // grab top key
+ SimpleKey key = m_simpleKeys.top();
+
+ // only validate if we're in the correct flow level
+ if(key.flowLevel != GetFlowLevel())
+ return false;
+
+ m_simpleKeys.pop();
+
+ bool isValid = true;
+
+ // needs to be less than 1024 characters and inline
+ if(INPUT.line() != key.mark.line || INPUT.pos() - key.mark.pos > 1024)
+ isValid = false;
+
+ // invalidate key
+ if(isValid)
+ key.Validate();
+ else
+ key.Invalidate();
+
+ return isValid;
+ }
+
+ void Scanner::PopAllSimpleKeys()
+ {
+ while(!m_simpleKeys.empty())
+ m_simpleKeys.pop();
+ }
+}
+
diff --git a/external_libs/yaml-cpp/src/singledocparser.cpp b/external_libs/yaml-cpp/src/singledocparser.cpp
new file mode 100644
index 00000000..47759c32
--- /dev/null
+++ b/external_libs/yaml-cpp/src/singledocparser.cpp
@@ -0,0 +1,381 @@
+#include "singledocparser.h"
+#include "collectionstack.h"
+#include "directives.h"
+#include "yaml-cpp/eventhandler.h"
+#include "yaml-cpp/exceptions.h"
+#include "scanner.h"
+#include "tag.h"
+#include "token.h"
+#include <sstream>
+#include <cstdio>
+#include <algorithm>
+
+namespace YAML
+{
+ SingleDocParser::SingleDocParser(Scanner& scanner, const Directives& directives): m_scanner(scanner), m_directives(directives), m_pCollectionStack(new CollectionStack), m_curAnchor(0)
+ {
+ }
+
+ SingleDocParser::~SingleDocParser()
+ {
+ }
+
+ // HandleDocument
+ // . Handles the next document
+ // . Throws a ParserException on error.
+ void SingleDocParser::HandleDocument(EventHandler& eventHandler)
+ {
+ assert(!m_scanner.empty()); // guaranteed that there are tokens
+ assert(!m_curAnchor);
+
+ eventHandler.OnDocumentStart(m_scanner.peek().mark);
+
+ // eat doc start
+ if(m_scanner.peek().type == Token::DOC_START)
+ m_scanner.pop();
+
+ // recurse!
+ HandleNode(eventHandler);
+
+ eventHandler.OnDocumentEnd();
+
+ // and finally eat any doc ends we see
+ while(!m_scanner.empty() && m_scanner.peek().type == Token::DOC_END)
+ m_scanner.pop();
+ }
+
+ void SingleDocParser::HandleNode(EventHandler& eventHandler)
+ {
+ // an empty node *is* a possibility
+ if(m_scanner.empty()) {
+ eventHandler.OnNull(Mark::null(), NullAnchor);
+ return;
+ }
+
+ // save location
+ Mark mark = m_scanner.peek().mark;
+
+ // special case: a value node by itself must be a map, with no header
+ if(m_scanner.peek().type == Token::VALUE) {
+ eventHandler.OnMapStart(mark, "", NullAnchor);
+ HandleMap(eventHandler);
+ eventHandler.OnMapEnd();
+ return;
+ }
+
+ // special case: an alias node
+ if(m_scanner.peek().type == Token::ALIAS) {
+ eventHandler.OnAlias(mark, LookupAnchor(mark, m_scanner.peek().value));
+ m_scanner.pop();
+ return;
+ }
+
+ std::string tag;
+ anchor_t anchor;
+ ParseProperties(tag, anchor);
+
+ const Token& token = m_scanner.peek();
+
+ // add non-specific tags
+ if(tag.empty())
+ tag = (token.type == Token::NON_PLAIN_SCALAR ? "!" : "?");
+
+ // now split based on what kind of node we should be
+ switch(token.type) {
+ case Token::PLAIN_SCALAR:
+ case Token::NON_PLAIN_SCALAR:
+ eventHandler.OnScalar(mark, tag, anchor, token.value);
+ m_scanner.pop();
+ return;
+ case Token::FLOW_SEQ_START:
+ case Token::BLOCK_SEQ_START:
+ eventHandler.OnSequenceStart(mark, tag, anchor);
+ HandleSequence(eventHandler);
+ eventHandler.OnSequenceEnd();
+ return;
+ case Token::FLOW_MAP_START:
+ case Token::BLOCK_MAP_START:
+ eventHandler.OnMapStart(mark, tag, anchor);
+ HandleMap(eventHandler);
+ eventHandler.OnMapEnd();
+ return;
+ case Token::KEY:
+ // compact maps can only go in a flow sequence
+ if(m_pCollectionStack->GetCurCollectionType() == CollectionType::FlowSeq) {
+ eventHandler.OnMapStart(mark, tag, anchor);
+ HandleMap(eventHandler);
+ eventHandler.OnMapEnd();
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if(tag == "?")
+ eventHandler.OnNull(mark, anchor);
+ else
+ eventHandler.OnScalar(mark, tag, anchor, "");
+ }
+
+ void SingleDocParser::HandleSequence(EventHandler& eventHandler)
+ {
+ // split based on start token
+ switch(m_scanner.peek().type) {
+ case Token::BLOCK_SEQ_START: HandleBlockSequence(eventHandler); break;
+ case Token::FLOW_SEQ_START: HandleFlowSequence(eventHandler); break;
+ default: break;
+ }
+ }
+
+ void SingleDocParser::HandleBlockSequence(EventHandler& eventHandler)
+ {
+ // eat start token
+ m_scanner.pop();
+ m_pCollectionStack->PushCollectionType(CollectionType::BlockSeq);
+
+ while(1) {
+ if(m_scanner.empty())
+ throw ParserException(Mark::null(), ErrorMsg::END_OF_SEQ);
+
+ Token token = m_scanner.peek();
+ if(token.type != Token::BLOCK_ENTRY && token.type != Token::BLOCK_SEQ_END)
+ throw ParserException(token.mark, ErrorMsg::END_OF_SEQ);
+
+ m_scanner.pop();
+ if(token.type == Token::BLOCK_SEQ_END)
+ break;
+
+ // check for null
+ if(!m_scanner.empty()) {
+ const Token& token = m_scanner.peek();
+ if(token.type == Token::BLOCK_ENTRY || token.type == Token::BLOCK_SEQ_END) {
+ eventHandler.OnNull(token.mark, NullAnchor);
+ continue;
+ }
+ }
+
+ HandleNode(eventHandler);
+ }
+
+ m_pCollectionStack->PopCollectionType(CollectionType::BlockSeq);
+ }
+
+ void SingleDocParser::HandleFlowSequence(EventHandler& eventHandler)
+ {
+ // eat start token
+ m_scanner.pop();
+ m_pCollectionStack->PushCollectionType(CollectionType::FlowSeq);
+
+ while(1) {
+ if(m_scanner.empty())
+ throw ParserException(Mark::null(), ErrorMsg::END_OF_SEQ_FLOW);
+
+ // first check for end
+ if(m_scanner.peek().type == Token::FLOW_SEQ_END) {
+ m_scanner.pop();
+ break;
+ }
+
+ // then read the node
+ HandleNode(eventHandler);
+
+ // now eat the separator (or could be a sequence end, which we ignore - but if it's neither, then it's a bad node)
+ Token& token = m_scanner.peek();
+ if(token.type == Token::FLOW_ENTRY)
+ m_scanner.pop();
+ else if(token.type != Token::FLOW_SEQ_END)
+ throw ParserException(token.mark, ErrorMsg::END_OF_SEQ_FLOW);
+ }
+
+ m_pCollectionStack->PopCollectionType(CollectionType::FlowSeq);
+ }
+
+ void SingleDocParser::HandleMap(EventHandler& eventHandler)
+ {
+ // split based on start token
+ switch(m_scanner.peek().type) {
+ case Token::BLOCK_MAP_START: HandleBlockMap(eventHandler); break;
+ case Token::FLOW_MAP_START: HandleFlowMap(eventHandler); break;
+ case Token::KEY: HandleCompactMap(eventHandler); break;
+ case Token::VALUE: HandleCompactMapWithNoKey(eventHandler); break;
+ default: break;
+ }
+ }
+
+ void SingleDocParser::HandleBlockMap(EventHandler& eventHandler)
+ {
+ // eat start token
+ m_scanner.pop();
+ m_pCollectionStack->PushCollectionType(CollectionType::BlockMap);
+
+ while(1) {
+ if(m_scanner.empty())
+ throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP);
+
+ Token token = m_scanner.peek();
+ if(token.type != Token::KEY && token.type != Token::VALUE && token.type != Token::BLOCK_MAP_END)
+ throw ParserException(token.mark, ErrorMsg::END_OF_MAP);
+
+ if(token.type == Token::BLOCK_MAP_END) {
+ m_scanner.pop();
+ break;
+ }
+
+ // grab key (if non-null)
+ if(token.type == Token::KEY) {
+ m_scanner.pop();
+ HandleNode(eventHandler);
+ } else {
+ eventHandler.OnNull(token.mark, NullAnchor);
+ }
+
+ // now grab value (optional)
+ if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
+ m_scanner.pop();
+ HandleNode(eventHandler);
+ } else {
+ eventHandler.OnNull(token.mark, NullAnchor);
+ }
+ }
+
+ m_pCollectionStack->PopCollectionType(CollectionType::BlockMap);
+ }
+
+ void SingleDocParser::HandleFlowMap(EventHandler& eventHandler)
+ {
+ // eat start token
+ m_scanner.pop();
+ m_pCollectionStack->PushCollectionType(CollectionType::FlowMap);
+
+ while(1) {
+ if(m_scanner.empty())
+ throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP_FLOW);
+
+ Token& token = m_scanner.peek();
+ // first check for end
+ if(token.type == Token::FLOW_MAP_END) {
+ m_scanner.pop();
+ break;
+ }
+
+ // grab key (if non-null)
+ if(token.type == Token::KEY) {
+ m_scanner.pop();
+ HandleNode(eventHandler);
+ } else {
+ eventHandler.OnNull(token.mark, NullAnchor);
+ }
+
+ // now grab value (optional)
+ if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
+ m_scanner.pop();
+ HandleNode(eventHandler);
+ } else {
+ eventHandler.OnNull(token.mark, NullAnchor);
+ }
+
+ // now eat the separator (or could be a map end, which we ignore - but if it's neither, then it's a bad node)
+ Token& nextToken = m_scanner.peek();
+ if(nextToken.type == Token::FLOW_ENTRY)
+ m_scanner.pop();
+ else if(nextToken.type != Token::FLOW_MAP_END)
+ throw ParserException(nextToken.mark, ErrorMsg::END_OF_MAP_FLOW);
+ }
+
+ m_pCollectionStack->PopCollectionType(CollectionType::FlowMap);
+ }
+
+ // . Single "key: value" pair in a flow sequence
+ void SingleDocParser::HandleCompactMap(EventHandler& eventHandler)
+ {
+ m_pCollectionStack->PushCollectionType(CollectionType::CompactMap);
+
+ // grab key
+ Mark mark = m_scanner.peek().mark;
+ m_scanner.pop();
+ HandleNode(eventHandler);
+
+ // now grab value (optional)
+ if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
+ m_scanner.pop();
+ HandleNode(eventHandler);
+ } else {
+ eventHandler.OnNull(mark, NullAnchor);
+ }
+
+ m_pCollectionStack->PopCollectionType(CollectionType::CompactMap);
+ }
+
+ // . Single ": value" pair in a flow sequence
+ void SingleDocParser::HandleCompactMapWithNoKey(EventHandler& eventHandler)
+ {
+ m_pCollectionStack->PushCollectionType(CollectionType::CompactMap);
+
+ // null key
+ eventHandler.OnNull(m_scanner.peek().mark, NullAnchor);
+
+ // grab value
+ m_scanner.pop();
+ HandleNode(eventHandler);
+
+ m_pCollectionStack->PopCollectionType(CollectionType::CompactMap);
+ }
+
+ // ParseProperties
+ // . Grabs any tag or anchor tokens and deals with them.
+ void SingleDocParser::ParseProperties(std::string& tag, anchor_t& anchor)
+ {
+ tag.clear();
+ anchor = NullAnchor;
+
+ while(1) {
+ if(m_scanner.empty())
+ return;
+
+ switch(m_scanner.peek().type) {
+ case Token::TAG: ParseTag(tag); break;
+ case Token::ANCHOR: ParseAnchor(anchor); break;
+ default: return;
+ }
+ }
+ }
+
+ void SingleDocParser::ParseTag(std::string& tag)
+ {
+ Token& token = m_scanner.peek();
+ if(!tag.empty())
+ throw ParserException(token.mark, ErrorMsg::MULTIPLE_TAGS);
+
+ Tag tagInfo(token);
+ tag = tagInfo.Translate(m_directives);
+ m_scanner.pop();
+ }
+
+ void SingleDocParser::ParseAnchor(anchor_t& anchor)
+ {
+ Token& token = m_scanner.peek();
+ if(anchor)
+ throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS);
+
+ anchor = RegisterAnchor(token.value);
+ m_scanner.pop();
+ }
+
+ anchor_t SingleDocParser::RegisterAnchor(const std::string& name)
+ {
+ if(name.empty())
+ return NullAnchor;
+
+ return m_anchors[name] = ++m_curAnchor;
+ }
+
+ anchor_t SingleDocParser::LookupAnchor(const Mark& mark, const std::string& name) const
+ {
+ Anchors::const_iterator it = m_anchors.find(name);
+ if(it == m_anchors.end())
+ throw ParserException(mark, ErrorMsg::UNKNOWN_ANCHOR);
+
+ return it->second;
+ }
+}
diff --git a/external_libs/yaml-cpp/src/singledocparser.h b/external_libs/yaml-cpp/src/singledocparser.h
new file mode 100644
index 00000000..3798dccf
--- /dev/null
+++ b/external_libs/yaml-cpp/src/singledocparser.h
@@ -0,0 +1,65 @@
+#ifndef SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include "yaml-cpp/anchor.h"
+#include "yaml-cpp/noncopyable.h"
+#include <string>
+#include <map>
+#include <memory>
+
+namespace YAML
+{
+ struct Directives;
+ struct Mark;
+ struct Token;
+ class CollectionStack;
+ class EventHandler;
+ class Node;
+ class Scanner;
+
+ class SingleDocParser: private noncopyable
+ {
+ public:
+ SingleDocParser(Scanner& scanner, const Directives& directives);
+ ~SingleDocParser();
+
+ void HandleDocument(EventHandler& eventHandler);
+
+ private:
+ void HandleNode(EventHandler& eventHandler);
+
+ void HandleSequence(EventHandler& eventHandler);
+ void HandleBlockSequence(EventHandler& eventHandler);
+ void HandleFlowSequence(EventHandler& eventHandler);
+
+ void HandleMap(EventHandler& eventHandler);
+ void HandleBlockMap(EventHandler& eventHandler);
+ void HandleFlowMap(EventHandler& eventHandler);
+ void HandleCompactMap(EventHandler& eventHandler);
+ void HandleCompactMapWithNoKey(EventHandler& eventHandler);
+
+ void ParseProperties(std::string& tag, anchor_t& anchor);
+ void ParseTag(std::string& tag);
+ void ParseAnchor(anchor_t& anchor);
+
+ anchor_t RegisterAnchor(const std::string& name);
+ anchor_t LookupAnchor(const Mark& mark, const std::string& name) const;
+
+ private:
+ Scanner& m_scanner;
+ const Directives& m_directives;
+ std::auto_ptr<CollectionStack> m_pCollectionStack;
+
+ typedef std::map<std::string, anchor_t> Anchors;
+ Anchors m_anchors;
+
+ anchor_t m_curAnchor;
+ };
+}
+
+#endif // SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/src/stream.cpp b/external_libs/yaml-cpp/src/stream.cpp
new file mode 100644
index 00000000..447b67c1
--- /dev/null
+++ b/external_libs/yaml-cpp/src/stream.cpp
@@ -0,0 +1,448 @@
+#include "stream.h"
+#include <iostream>
+#include "exp.h"
+
+#ifndef YAML_PREFETCH_SIZE
+#define YAML_PREFETCH_SIZE 2048
+#endif
+
+#define S_ARRAY_SIZE( A ) (sizeof(A)/sizeof(*(A)))
+#define S_ARRAY_END( A ) ((A) + S_ARRAY_SIZE(A))
+
+#define CP_REPLACEMENT_CHARACTER (0xFFFD)
+
+namespace YAML
+{
+ enum UtfIntroState {
+ uis_start,
+ uis_utfbe_b1,
+ uis_utf32be_b2,
+ uis_utf32be_bom3,
+ uis_utf32be,
+ uis_utf16be,
+ uis_utf16be_bom1,
+ uis_utfle_bom1,
+ uis_utf16le_bom2,
+ uis_utf32le_bom3,
+ uis_utf16le,
+ uis_utf32le,
+ uis_utf8_imp,
+ uis_utf16le_imp,
+ uis_utf32le_imp3,
+ uis_utf8_bom1,
+ uis_utf8_bom2,
+ uis_utf8,
+ uis_error
+ };
+
+ enum UtfIntroCharType {
+ uict00,
+ uictBB,
+ uictBF,
+ uictEF,
+ uictFE,
+ uictFF,
+ uictAscii,
+ uictOther,
+ uictMax
+ };
+
+ static bool s_introFinalState[] = {
+ false, //uis_start
+ false, //uis_utfbe_b1
+ false, //uis_utf32be_b2
+ false, //uis_utf32be_bom3
+ true, //uis_utf32be
+ true, //uis_utf16be
+ false, //uis_utf16be_bom1
+ false, //uis_utfle_bom1
+ false, //uis_utf16le_bom2
+ false, //uis_utf32le_bom3
+ true, //uis_utf16le
+ true, //uis_utf32le
+ false, //uis_utf8_imp
+ false, //uis_utf16le_imp
+ false, //uis_utf32le_imp3
+ false, //uis_utf8_bom1
+ false, //uis_utf8_bom2
+ true, //uis_utf8
+ true, //uis_error
+ };
+
+ static UtfIntroState s_introTransitions[][uictMax] = {
+ // uict00, uictBB, uictBF, uictEF, uictFE, uictFF, uictAscii, uictOther
+ {uis_utfbe_b1, uis_utf8, uis_utf8, uis_utf8_bom1, uis_utf16be_bom1, uis_utfle_bom1, uis_utf8_imp, uis_utf8},
+ {uis_utf32be_b2, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf16be, uis_utf8},
+ {uis_utf32be, uis_utf8, uis_utf8, uis_utf8, uis_utf32be_bom3, uis_utf8, uis_utf8, uis_utf8},
+ {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf32be, uis_utf8, uis_utf8},
+ {uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be},
+ {uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be},
+ {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf16be, uis_utf8, uis_utf8},
+ {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf16le_bom2, uis_utf8, uis_utf8, uis_utf8},
+ {uis_utf32le_bom3, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le},
+ {uis_utf32le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le},
+ {uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le},
+ {uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le},
+ {uis_utf16le_imp, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8},
+ {uis_utf32le_imp3, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le},
+ {uis_utf32le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le},
+ {uis_utf8, uis_utf8_bom2, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8},
+ {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8},
+ {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8},
+ };
+
+ static char s_introUngetCount[][uictMax] = {
+ // uict00, uictBB, uictBF, uictEF, uictFE, uictFF, uictAscii, uictOther
+ {0, 1, 1, 0, 0, 0, 0, 1},
+ {0, 2, 2, 2, 2, 2, 2, 2},
+ {3, 3, 3, 3, 0, 3, 3, 3},
+ {4, 4, 4, 4, 4, 0, 4, 4},
+ {1, 1, 1, 1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1, 1, 1, 1},
+ {2, 2, 2, 2, 2, 0, 2, 2},
+ {2, 2, 2, 2, 0, 2, 2, 2},
+ {0, 1, 1, 1, 1, 1, 1, 1},
+ {0, 2, 2, 2, 2, 2, 2, 2},
+ {1, 1, 1, 1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1, 1, 1, 1},
+ {0, 2, 2, 2, 2, 2, 2, 2},
+ {0, 3, 3, 3, 3, 3, 3, 3},
+ {4, 4, 4, 4, 4, 4, 4, 4},
+ {2, 0, 2, 2, 2, 2, 2, 2},
+ {3, 3, 0, 3, 3, 3, 3, 3},
+ {1, 1, 1, 1, 1, 1, 1, 1},
+ };
+
+ inline UtfIntroCharType IntroCharTypeOf(std::istream::int_type ch)
+ {
+ if (std::istream::traits_type::eof() == ch) {
+ return uictOther;
+ }
+
+ switch (ch) {
+ case 0: return uict00;
+ case 0xBB: return uictBB;
+ case 0xBF: return uictBF;
+ case 0xEF: return uictEF;
+ case 0xFE: return uictFE;
+ case 0xFF: return uictFF;
+ }
+
+ if ((ch > 0) && (ch < 0xFF)) {
+ return uictAscii;
+ }
+
+ return uictOther;
+ }
+
+ inline char Utf8Adjust(unsigned long ch, unsigned char lead_bits, unsigned char rshift)
+ {
+ const unsigned char header = ((1 << lead_bits) - 1) << (8 - lead_bits);
+ const unsigned char mask = (0xFF >> (lead_bits + 1));
+ return static_cast<char>(static_cast<unsigned char>(
+ header | ((ch >> rshift) & mask)
+ ));
+ }
+
+ inline void QueueUnicodeCodepoint(std::deque<char>& q, unsigned long ch)
+ {
+ // We are not allowed to queue the Stream::eof() codepoint, so
+ // replace it with CP_REPLACEMENT_CHARACTER
+ if (static_cast<unsigned long>(Stream::eof()) == ch)
+ {
+ ch = CP_REPLACEMENT_CHARACTER;
+ }
+
+ if (ch < 0x80)
+ {
+ q.push_back(Utf8Adjust(ch, 0, 0));
+ }
+ else if (ch < 0x800)
+ {
+ q.push_back(Utf8Adjust(ch, 2, 6));
+ q.push_back(Utf8Adjust(ch, 1, 0));
+ }
+ else if (ch < 0x10000)
+ {
+ q.push_back(Utf8Adjust(ch, 3, 12));
+ q.push_back(Utf8Adjust(ch, 1, 6));
+ q.push_back(Utf8Adjust(ch, 1, 0));
+ }
+ else
+ {
+ q.push_back(Utf8Adjust(ch, 4, 18));
+ q.push_back(Utf8Adjust(ch, 1, 12));
+ q.push_back(Utf8Adjust(ch, 1, 6));
+ q.push_back(Utf8Adjust(ch, 1, 0));
+ }
+ }
+
+ Stream::Stream(std::istream& input)
+ : m_input(input),
+ m_pPrefetched(new unsigned char[YAML_PREFETCH_SIZE]),
+ m_nPrefetchedAvailable(0), m_nPrefetchedUsed(0)
+ {
+ typedef std::istream::traits_type char_traits;
+
+ if(!input)
+ return;
+
+ // Determine (or guess) the character-set by reading the BOM, if any. See
+ // the YAML specification for the determination algorithm.
+ char_traits::int_type intro[4];
+ int nIntroUsed = 0;
+ UtfIntroState state = uis_start;
+ for(; !s_introFinalState[state]; ) {
+ std::istream::int_type ch = input.get();
+ intro[nIntroUsed++] = ch;
+ UtfIntroCharType charType = IntroCharTypeOf(ch);
+ UtfIntroState newState = s_introTransitions[state][charType];
+ int nUngets = s_introUngetCount[state][charType];
+ if(nUngets > 0) {
+ input.clear();
+ for(; nUngets > 0; --nUngets) {
+ if(char_traits::eof() != intro[--nIntroUsed])
+ input.putback(char_traits::to_char_type(intro[nIntroUsed]));
+ }
+ }
+ state = newState;
+ }
+
+ switch (state) {
+ case uis_utf8: m_charSet = utf8; break;
+ case uis_utf16le: m_charSet = utf16le; break;
+ case uis_utf16be: m_charSet = utf16be; break;
+ case uis_utf32le: m_charSet = utf32le; break;
+ case uis_utf32be: m_charSet = utf32be; break;
+ default: m_charSet = utf8; break;
+ }
+
+ ReadAheadTo(0);
+ }
+
+ Stream::~Stream()
+ {
+ delete[] m_pPrefetched;
+ }
+
+ char Stream::peek() const
+ {
+ if (m_readahead.empty())
+ {
+ return Stream::eof();
+ }
+
+ return m_readahead[0];
+ }
+
+ Stream::operator bool() const
+ {
+ return m_input.good() || (!m_readahead.empty() && m_readahead[0] != Stream::eof());
+ }
+
+ // get
+ // . Extracts a character from the stream and updates our position
+ char Stream::get()
+ {
+ char ch = peek();
+ AdvanceCurrent();
+ m_mark.column++;
+
+ if(ch == '\n') {
+ m_mark.column = 0;
+ m_mark.line++;
+ }
+
+ return ch;
+ }
+
+ // get
+ // . Extracts 'n' characters from the stream and updates our position
+ std::string Stream::get(int n)
+ {
+ std::string ret;
+ ret.reserve(n);
+ for(int i=0;i<n;i++)
+ ret += get();
+ return ret;
+ }
+
+ // eat
+ // . Eats 'n' characters and updates our position.
+ void Stream::eat(int n)
+ {
+ for(int i=0;i<n;i++)
+ get();
+ }
+
+ void Stream::AdvanceCurrent()
+ {
+ if (!m_readahead.empty())
+ {
+ m_readahead.pop_front();
+ m_mark.pos++;
+ }
+
+ ReadAheadTo(0);
+ }
+
+ bool Stream::_ReadAheadTo(size_t i) const
+ {
+ while (m_input.good() && (m_readahead.size() <= i))
+ {
+ switch (m_charSet)
+ {
+ case utf8: StreamInUtf8(); break;
+ case utf16le: StreamInUtf16(); break;
+ case utf16be: StreamInUtf16(); break;
+ case utf32le: StreamInUtf32(); break;
+ case utf32be: StreamInUtf32(); break;
+ }
+ }
+
+ // signal end of stream
+ if(!m_input.good())
+ m_readahead.push_back(Stream::eof());
+
+ return m_readahead.size() > i;
+ }
+
+ void Stream::StreamInUtf8() const
+ {
+ unsigned char b = GetNextByte();
+ if (m_input.good())
+ {
+ m_readahead.push_back(b);
+ }
+ }
+
+ void Stream::StreamInUtf16() const
+ {
+ unsigned long ch = 0;
+ unsigned char bytes[2];
+ int nBigEnd = (m_charSet == utf16be) ? 0 : 1;
+
+ bytes[0] = GetNextByte();
+ bytes[1] = GetNextByte();
+ if (!m_input.good())
+ {
+ return;
+ }
+ ch = (static_cast<unsigned long>(bytes[nBigEnd]) << 8) |
+ static_cast<unsigned long>(bytes[1 ^ nBigEnd]);
+
+ if (ch >= 0xDC00 && ch < 0xE000)
+ {
+ // Trailing (low) surrogate...ugh, wrong order
+ QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER);
+ return;
+ }
+ else if (ch >= 0xD800 && ch < 0xDC00)
+ {
+ // ch is a leading (high) surrogate
+
+ // Four byte UTF-8 code point
+
+ // Read the trailing (low) surrogate
+ for (;;)
+ {
+ bytes[0] = GetNextByte();
+ bytes[1] = GetNextByte();
+ if (!m_input.good())
+ {
+ QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER);
+ return;
+ }
+ unsigned long chLow = (static_cast<unsigned long>(bytes[nBigEnd]) << 8) |
+ static_cast<unsigned long>(bytes[1 ^ nBigEnd]);
+ if (chLow < 0xDC00 || ch >= 0xE000)
+ {
+ // Trouble...not a low surrogate. Dump a REPLACEMENT CHARACTER into the stream.
+ QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER);
+
+ // Deal with the next UTF-16 unit
+ if (chLow < 0xD800 || ch >= 0xE000)
+ {
+ // Easiest case: queue the codepoint and return
+ QueueUnicodeCodepoint(m_readahead, ch);
+ return;
+ }
+ else
+ {
+ // Start the loop over with the new high surrogate
+ ch = chLow;
+ continue;
+ }
+ }
+
+ // Select the payload bits from the high surrogate
+ ch &= 0x3FF;
+ ch <<= 10;
+
+ // Include bits from low surrogate
+ ch |= (chLow & 0x3FF);
+
+ // Add the surrogacy offset
+ ch += 0x10000;
+ }
+ }
+
+ QueueUnicodeCodepoint(m_readahead, ch);
+ }
+
+ inline char* ReadBuffer(unsigned char* pBuffer)
+ {
+ return reinterpret_cast<char*>(pBuffer);
+ }
+
+ unsigned char Stream::GetNextByte() const
+ {
+ if (m_nPrefetchedUsed >= m_nPrefetchedAvailable)
+ {
+ std::streambuf *pBuf = m_input.rdbuf();
+ m_nPrefetchedAvailable = (size_t)pBuf->sgetn(ReadBuffer(m_pPrefetched),
+ YAML_PREFETCH_SIZE);
+ m_nPrefetchedUsed = 0;
+ if (!m_nPrefetchedAvailable)
+ {
+ m_input.setstate(std::ios_base::eofbit);
+ }
+
+ if (0 == m_nPrefetchedAvailable)
+ {
+ return 0;
+ }
+ }
+
+ return m_pPrefetched[m_nPrefetchedUsed++];
+ }
+
+ void Stream::StreamInUtf32() const
+ {
+ static int indexes[2][4] = {
+ {3, 2, 1, 0},
+ {0, 1, 2, 3}
+ };
+
+ unsigned long ch = 0;
+ unsigned char bytes[4];
+ int* pIndexes = (m_charSet == utf32be) ? indexes[1] : indexes[0];
+
+ bytes[0] = GetNextByte();
+ bytes[1] = GetNextByte();
+ bytes[2] = GetNextByte();
+ bytes[3] = GetNextByte();
+ if (!m_input.good())
+ {
+ return;
+ }
+
+ for (int i = 0; i < 4; ++i)
+ {
+ ch <<= 8;
+ ch |= bytes[pIndexes[i]];
+ }
+
+ QueueUnicodeCodepoint(m_readahead, ch);
+ }
+}
diff --git a/external_libs/yaml-cpp/src/stream.h b/external_libs/yaml-cpp/src/stream.h
new file mode 100644
index 00000000..87f48dc8
--- /dev/null
+++ b/external_libs/yaml-cpp/src/stream.h
@@ -0,0 +1,79 @@
+#ifndef STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include "yaml-cpp/noncopyable.h"
+#include "yaml-cpp/mark.h"
+#include <cstddef>
+#include <deque>
+#include <ios>
+#include <iostream>
+#include <set>
+#include <string>
+
+namespace YAML
+{
+ class Stream: private noncopyable
+ {
+ public:
+ friend class StreamCharSource;
+
+ Stream(std::istream& input);
+ ~Stream();
+
+ operator bool() const;
+ bool operator !() const { return !static_cast <bool>(*this); }
+
+ char peek() const;
+ char get();
+ std::string get(int n);
+ void eat(int n = 1);
+
+ static char eof() { return 0x04; }
+
+ const Mark mark() const { return m_mark; }
+ int pos() const { return m_mark.pos; }
+ int line() const { return m_mark.line; }
+ int column() const { return m_mark.column; }
+ void ResetColumn() { m_mark.column = 0; }
+
+ private:
+ enum CharacterSet {utf8, utf16le, utf16be, utf32le, utf32be};
+
+ std::istream& m_input;
+ Mark m_mark;
+
+ CharacterSet m_charSet;
+ mutable std::deque<char> m_readahead;
+ unsigned char* const m_pPrefetched;
+ mutable size_t m_nPrefetchedAvailable;
+ mutable size_t m_nPrefetchedUsed;
+
+ void AdvanceCurrent();
+ char CharAt(size_t i) const;
+ bool ReadAheadTo(size_t i) const;
+ bool _ReadAheadTo(size_t i) const;
+ void StreamInUtf8() const;
+ void StreamInUtf16() const;
+ void StreamInUtf32() const;
+ unsigned char GetNextByte() const;
+ };
+
+ // CharAt
+ // . Unchecked access
+ inline char Stream::CharAt(size_t i) const {
+ return m_readahead[i];
+ }
+
+ inline bool Stream::ReadAheadTo(size_t i) const {
+ if(m_readahead.size() > i)
+ return true;
+ return _ReadAheadTo(i);
+ }
+}
+
+#endif // STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/src/streamcharsource.h b/external_libs/yaml-cpp/src/streamcharsource.h
new file mode 100644
index 00000000..21fae4e1
--- /dev/null
+++ b/external_libs/yaml-cpp/src/streamcharsource.h
@@ -0,0 +1,48 @@
+#ifndef STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include "yaml-cpp/noncopyable.h"
+#include <cstddef>
+
+namespace YAML
+{
+ class StreamCharSource
+ {
+ public:
+ StreamCharSource(const Stream& stream): m_offset(0), m_stream(stream) {}
+ StreamCharSource(const StreamCharSource& source): m_offset(source.m_offset), m_stream(source.m_stream) {}
+ ~StreamCharSource() {}
+
+ operator bool() const;
+ char operator [] (std::size_t i) const { return m_stream.CharAt(m_offset + i); }
+ bool operator !() const { return !static_cast<bool>(*this); }
+
+ const StreamCharSource operator + (int i) const;
+
+ private:
+ std::size_t m_offset;
+ const Stream& m_stream;
+
+ StreamCharSource& operator = (const StreamCharSource&); // non-assignable
+ };
+
+ inline StreamCharSource::operator bool() const {
+ return m_stream.ReadAheadTo(m_offset);
+ }
+
+ inline const StreamCharSource StreamCharSource::operator + (int i) const {
+ StreamCharSource source(*this);
+ if(static_cast<int> (source.m_offset) + i >= 0)
+ source.m_offset += i;
+ else
+ source.m_offset = 0;
+ return source;
+ }
+}
+
+#endif // STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/src/stringsource.h b/external_libs/yaml-cpp/src/stringsource.h
new file mode 100644
index 00000000..21be3c9a
--- /dev/null
+++ b/external_libs/yaml-cpp/src/stringsource.h
@@ -0,0 +1,47 @@
+#ifndef STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include <cstddef>
+
+namespace YAML
+{
+ class StringCharSource
+ {
+ public:
+ StringCharSource(const char *str, std::size_t size): m_str(str), m_size(size), m_offset(0) {}
+
+ operator bool() const { return m_offset < m_size; }
+ char operator [] (std::size_t i) const { return m_str[m_offset + i]; }
+ bool operator !() const { return !static_cast<bool>(*this); }
+
+ const StringCharSource operator + (int i) const {
+ StringCharSource source(*this);
+ if(static_cast<int> (source.m_offset) + i >= 0)
+ source.m_offset += i;
+ else
+ source.m_offset = 0;
+ return source;
+ }
+
+ StringCharSource& operator ++ () {
+ ++m_offset;
+ return *this;
+ }
+
+ StringCharSource& operator += (std::size_t offset) {
+ m_offset += offset;
+ return *this;
+ }
+ private:
+ const char *m_str;
+ std::size_t m_size;
+ std::size_t m_offset;
+ };
+}
+
+#endif // STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/src/tag.cpp b/external_libs/yaml-cpp/src/tag.cpp
new file mode 100644
index 00000000..82a47047
--- /dev/null
+++ b/external_libs/yaml-cpp/src/tag.cpp
@@ -0,0 +1,52 @@
+#include "tag.h"
+#include "directives.h"
+#include "token.h"
+#include <cassert>
+#include <stdexcept>
+
+namespace YAML
+{
+ Tag::Tag(const Token& token): type(static_cast<TYPE>(token.data))
+ {
+ switch(type) {
+ case VERBATIM:
+ value = token.value;
+ break;
+ case PRIMARY_HANDLE:
+ value = token.value;
+ break;
+ case SECONDARY_HANDLE:
+ value = token.value;
+ break;
+ case NAMED_HANDLE:
+ handle = token.value;
+ value = token.params[0];
+ break;
+ case NON_SPECIFIC:
+ break;
+ default:
+ assert(false);
+ }
+ }
+
+ const std::string Tag::Translate(const Directives& directives)
+ {
+ switch(type) {
+ case VERBATIM:
+ return value;
+ case PRIMARY_HANDLE:
+ return directives.TranslateTagHandle("!") + value;
+ case SECONDARY_HANDLE:
+ return directives.TranslateTagHandle("!!") + value;
+ case NAMED_HANDLE:
+ return directives.TranslateTagHandle("!" + handle + "!") + value;
+ case NON_SPECIFIC:
+ // TODO:
+ return "!";
+ default:
+ assert(false);
+ }
+ throw std::runtime_error("yaml-cpp: internal error, bad tag type");
+ }
+}
+
diff --git a/external_libs/yaml-cpp/src/tag.h b/external_libs/yaml-cpp/src/tag.h
new file mode 100644
index 00000000..5f77548d
--- /dev/null
+++ b/external_libs/yaml-cpp/src/tag.h
@@ -0,0 +1,28 @@
+#ifndef TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <string>
+
+namespace YAML
+{
+ struct Token;
+ struct Directives;
+
+ struct Tag {
+ enum TYPE {
+ VERBATIM, PRIMARY_HANDLE, SECONDARY_HANDLE, NAMED_HANDLE, NON_SPECIFIC
+ };
+
+ Tag(const Token& token);
+ const std::string Translate(const Directives& directives);
+
+ TYPE type;
+ std::string handle, value;
+ };
+}
+
+#endif // TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/src/token.h b/external_libs/yaml-cpp/src/token.h
new file mode 100644
index 00000000..9807e258
--- /dev/null
+++ b/external_libs/yaml-cpp/src/token.h
@@ -0,0 +1,85 @@
+#ifndef TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+
+#include "yaml-cpp/mark.h"
+#include <iostream>
+#include <string>
+#include <vector>
+
+namespace YAML
+{
+ const std::string TokenNames[] = {
+ "DIRECTIVE",
+ "DOC_START",
+ "DOC_END",
+ "BLOCK_SEQ_START",
+ "BLOCK_MAP_START",
+ "BLOCK_SEQ_END",
+ "BLOCK_MAP_END",
+ "BLOCK_ENTRY",
+ "FLOW_SEQ_START",
+ "FLOW_MAP_START",
+ "FLOW_SEQ_END",
+ "FLOW_MAP_END",
+ "FLOW_MAP_COMPACT",
+ "FLOW_ENTRY",
+ "KEY",
+ "VALUE",
+ "ANCHOR",
+ "ALIAS",
+ "TAG",
+ "SCALAR"
+ };
+
+ struct Token {
+ // enums
+ enum STATUS { VALID, INVALID, UNVERIFIED };
+ enum TYPE {
+ DIRECTIVE,
+ DOC_START,
+ DOC_END,
+ BLOCK_SEQ_START,
+ BLOCK_MAP_START,
+ BLOCK_SEQ_END,
+ BLOCK_MAP_END,
+ BLOCK_ENTRY,
+ FLOW_SEQ_START,
+ FLOW_MAP_START,
+ FLOW_SEQ_END,
+ FLOW_MAP_END,
+ FLOW_MAP_COMPACT,
+ FLOW_ENTRY,
+ KEY,
+ VALUE,
+ ANCHOR,
+ ALIAS,
+ TAG,
+ PLAIN_SCALAR,
+ NON_PLAIN_SCALAR
+ };
+
+ // data
+ Token(TYPE type_, const Mark& mark_): status(VALID), type(type_), mark(mark_), data(0) {}
+
+ friend std::ostream& operator << (std::ostream& out, const Token& token) {
+ out << TokenNames[token.type] << std::string(": ") << token.value;
+ for(std::size_t i=0;i<token.params.size();i++)
+ out << std::string(" ") << token.params[i];
+ return out;
+ }
+
+ STATUS status;
+ TYPE type;
+ Mark mark;
+ std::string value;
+ std::vector <std::string> params;
+ int data;
+ };
+}
+
+#endif // TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/test/CMakeLists.txt b/external_libs/yaml-cpp/test/CMakeLists.txt
new file mode 100644
index 00000000..241c19ef
--- /dev/null
+++ b/external_libs/yaml-cpp/test/CMakeLists.txt
@@ -0,0 +1,15 @@
+file(GLOB test_headers [a-z]*.h)
+file(GLOB test_sources [a-z]*.cpp)
+file(GLOB test_old_api_sources old-api/[a-z]*.cpp)
+
+list(APPEND test_sources ${test_old_api_sources})
+
+include_directories(${YAML_CPP_SOURCE_DIR}/test)
+
+add_executable(run-tests
+ ${test_sources}
+ ${test_headers}
+)
+target_link_libraries(run-tests yaml-cpp)
+
+add_test(yaml-reader-test run-tests)
diff --git a/external_libs/yaml-cpp/test/emittertests.cpp b/external_libs/yaml-cpp/test/emittertests.cpp
new file mode 100644
index 00000000..a7fdab67
--- /dev/null
+++ b/external_libs/yaml-cpp/test/emittertests.cpp
@@ -0,0 +1,1148 @@
+#include "tests.h"
+#include "yaml-cpp/yaml.h"
+#include <iostream>
+
+namespace Test
+{
+ namespace Emitter {
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // correct emitting
+
+ void SimpleScalar(YAML::Emitter& out, std::string& desiredOutput) {
+ out << "Hello, World!";
+ desiredOutput = "Hello, World!";
+ }
+
+ void SimpleSeq(YAML::Emitter& out, std::string& desiredOutput) {
+ out << YAML::BeginSeq;
+ out << "eggs";
+ out << "bread";
+ out << "milk";
+ out << YAML::EndSeq;
+
+ desiredOutput = "- eggs\n- bread\n- milk";
+ }
+
+ void SimpleFlowSeq(YAML::Emitter& out, std::string& desiredOutput) {
+ out << YAML::Flow;
+ out << YAML::BeginSeq;
+ out << "Larry";
+ out << "Curly";
+ out << "Moe";
+ out << YAML::EndSeq;
+
+ desiredOutput = "[Larry, Curly, Moe]";
+ }
+
+ void EmptyFlowSeq(YAML::Emitter& out, std::string& desiredOutput) {
+ out << YAML::Flow;
+ out << YAML::BeginSeq;
+ out << YAML::EndSeq;
+
+ desiredOutput = "[]";
+ }
+
+ void NestedBlockSeq(YAML::Emitter& out, std::string& desiredOutput) {
+ out << YAML::BeginSeq;
+ out << "item 1";
+ out << YAML::BeginSeq << "subitem 1" << "subitem 2" << YAML::EndSeq;
+ out << YAML::EndSeq;
+
+ desiredOutput = "- item 1\n-\n - subitem 1\n - subitem 2";
+ }
+
+ void NestedFlowSeq(YAML::Emitter& out, std::string& desiredOutput) {
+ out << YAML::BeginSeq;
+ out << "one";
+ out << YAML::Flow << YAML::BeginSeq << "two" << "three" << YAML::EndSeq;
+ out << YAML::EndSeq;
+
+ desiredOutput = "- one\n- [two, three]";
+ }
+
+ void SimpleMap(YAML::Emitter& out, std::string& desiredOutput) {
+ out << YAML::BeginMap;
+ out << YAML::Key << "name";
+ out << YAML::Value << "Ryan Braun";
+ out << YAML::Key << "position";
+ out << YAML::Value << "3B";
+ out << YAML::EndMap;
+
+ desiredOutput = "name: Ryan Braun\nposition: 3B";
+ }
+
+ void SimpleFlowMap(YAML::Emitter& out, std::string& desiredOutput) {
+ out << YAML::Flow;
+ out << YAML::BeginMap;
+ out << YAML::Key << "shape";
+ out << YAML::Value << "square";
+ out << YAML::Key << "color";
+ out << YAML::Value << "blue";
+ out << YAML::EndMap;
+
+ desiredOutput = "{shape: square, color: blue}";
+ }
+
+ void MapAndList(YAML::Emitter& out, std::string& desiredOutput) {
+ out << YAML::BeginMap;
+ out << YAML::Key << "name";
+ out << YAML::Value << "Barack Obama";
+ out << YAML::Key << "children";
+ out << YAML::Value << YAML::BeginSeq << "Sasha" << "Malia" << YAML::EndSeq;
+ out << YAML::EndMap;
+
+ desiredOutput = "name: Barack Obama\nchildren:\n - Sasha\n - Malia";
+ }
+
+ void ListAndMap(YAML::Emitter& out, std::string& desiredOutput) {
+ out << YAML::BeginSeq;
+ out << "item 1";
+ out << YAML::BeginMap;
+ out << YAML::Key << "pens" << YAML::Value << 8;
+ out << YAML::Key << "pencils" << YAML::Value << 14;
+ out << YAML::EndMap;
+ out << "item 2";
+ out << YAML::EndSeq;
+
+ desiredOutput = "- item 1\n- pens: 8\n pencils: 14\n- item 2";
+ }
+
+ void NestedBlockMap(YAML::Emitter& out, std::string& desiredOutput) {
+ out << YAML::BeginMap;
+ out << YAML::Key << "name";
+ out << YAML::Value << "Fred";
+ out << YAML::Key << "grades";
+ out << YAML::Value;
+ out << YAML::BeginMap;
+ out << YAML::Key << "algebra" << YAML::Value << "A";
+ out << YAML::Key << "physics" << YAML::Value << "C+";
+ out << YAML::Key << "literature" << YAML::Value << "B";
+ out << YAML::EndMap;
+ out << YAML::EndMap;
+
+ desiredOutput = "name: Fred\ngrades:\n algebra: A\n physics: C+\n literature: B";
+ }
+
+ void NestedFlowMap(YAML::Emitter& out, std::string& desiredOutput) {
+ out << YAML::Flow;
+ out << YAML::BeginMap;
+ out << YAML::Key << "name";
+ out << YAML::Value << "Fred";
+ out << YAML::Key << "grades";
+ out << YAML::Value;
+ out << YAML::BeginMap;
+ out << YAML::Key << "algebra" << YAML::Value << "A";
+ out << YAML::Key << "physics" << YAML::Value << "C+";
+ out << YAML::Key << "literature" << YAML::Value << "B";
+ out << YAML::EndMap;
+ out << YAML::EndMap;
+
+ desiredOutput = "{name: Fred, grades: {algebra: A, physics: C+, literature: B}}";
+ }
+
+ void MapListMix(YAML::Emitter& out, std::string& desiredOutput) {
+ out << YAML::BeginMap;
+ out << YAML::Key << "name";
+ out << YAML::Value << "Bob";
+ out << YAML::Key << "position";
+ out << YAML::Value;
+ out << YAML::Flow << YAML::BeginSeq << 2 << 4 << YAML::EndSeq;
+ out << YAML::Key << "invincible" << YAML::Value << YAML::OnOffBool << false;
+ out << YAML::EndMap;
+
+ desiredOutput = "name: Bob\nposition: [2, 4]\ninvincible: off";
+ }
+
+ void SimpleLongKey(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::LongKey;
+ out << YAML::BeginMap;
+ out << YAML::Key << "height";
+ out << YAML::Value << "5'9\"";
+ out << YAML::Key << "weight";
+ out << YAML::Value << 145;
+ out << YAML::EndMap;
+
+ desiredOutput = "? height\n: 5'9\"\n? weight\n: 145";
+ }
+
+ void SingleLongKey(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginMap;
+ out << YAML::Key << "age";
+ out << YAML::Value << "24";
+ out << YAML::LongKey << YAML::Key << "height";
+ out << YAML::Value << "5'9\"";
+ out << YAML::Key << "weight";
+ out << YAML::Value << 145;
+ out << YAML::EndMap;
+
+ desiredOutput = "age: 24\n? height\n: 5'9\"\nweight: 145";
+ }
+
+ void ComplexLongKey(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::LongKey;
+ out << YAML::BeginMap;
+ out << YAML::Key << YAML::BeginSeq << 1 << 3 << YAML::EndSeq;
+ out << YAML::Value << "monster";
+ out << YAML::Key << YAML::Flow << YAML::BeginSeq << 2 << 0 << YAML::EndSeq;
+ out << YAML::Value << "demon";
+ out << YAML::EndMap;
+
+ desiredOutput = "?\n - 1\n - 3\n: monster\n? [2, 0]\n: demon";
+ }
+
+ void AutoLongKey(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginMap;
+ out << YAML::Key << YAML::BeginSeq << 1 << 3 << YAML::EndSeq;
+ out << YAML::Value << "monster";
+ out << YAML::Key << YAML::Flow << YAML::BeginSeq << 2 << 0 << YAML::EndSeq;
+ out << YAML::Value << "demon";
+ out << YAML::Key << "the origin";
+ out << YAML::Value << "angel";
+ out << YAML::EndMap;
+
+ desiredOutput = "?\n - 1\n - 3\n: monster\n? [2, 0]\n: demon\nthe origin: angel";
+ }
+
+ void ScalarFormat(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginSeq;
+ out << "simple scalar";
+ out << YAML::SingleQuoted << "explicit single-quoted scalar";
+ out << YAML::DoubleQuoted << "explicit double-quoted scalar";
+ out << "auto-detected\ndouble-quoted scalar";
+ out << "a non-\"auto-detected\" double-quoted scalar";
+ out << YAML::Literal << "literal scalar\nthat may span\nmany, many\nlines and have \"whatever\" crazy\tsymbols that we like";
+ out << YAML::EndSeq;
+
+ desiredOutput = "- simple scalar\n- 'explicit single-quoted scalar'\n- \"explicit double-quoted scalar\"\n- \"auto-detected\\x0adouble-quoted scalar\"\n- a non-\"auto-detected\" double-quoted scalar\n- |\n literal scalar\n that may span\n many, many\n lines and have \"whatever\" crazy\tsymbols that we like";
+ }
+
+ void AutoLongKeyScalar(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginMap;
+ out << YAML::Key << YAML::Literal << "multi-line\nscalar";
+ out << YAML::Value << "and its value";
+ out << YAML::EndMap;
+
+ desiredOutput = "? |\n multi-line\n scalar\n: and its value";
+ }
+
+ void LongKeyFlowMap(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::Flow;
+ out << YAML::BeginMap;
+ out << YAML::Key << "simple key";
+ out << YAML::Value << "and value";
+ out << YAML::LongKey << YAML::Key << "long key";
+ out << YAML::Value << "and its value";
+ out << YAML::EndMap;
+
+ desiredOutput = "{simple key: and value, ? long key: and its value}";
+ }
+
+ void BlockMapAsKey(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginMap;
+ out << YAML::Key;
+ out << YAML::BeginMap;
+ out << YAML::Key << "key" << YAML::Value << "value";
+ out << YAML::Key << "next key" << YAML::Value << "next value";
+ out << YAML::EndMap;
+ out << YAML::Value;
+ out << "total value";
+ out << YAML::EndMap;
+
+ desiredOutput = "?\n key: value\n next key: next value\n: total value";
+ }
+
+ void AliasAndAnchor(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginSeq;
+ out << YAML::Anchor("fred");
+ out << YAML::BeginMap;
+ out << YAML::Key << "name" << YAML::Value << "Fred";
+ out << YAML::Key << "age" << YAML::Value << 42;
+ out << YAML::EndMap;
+ out << YAML::Alias("fred");
+ out << YAML::EndSeq;
+
+ desiredOutput = "- &fred\n name: Fred\n age: 42\n- *fred";
+ }
+
+ void AliasAndAnchorWithNull(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginSeq;
+ out << YAML::Anchor("fred") << YAML::Null;
+ out << YAML::Alias("fred");
+ out << YAML::EndSeq;
+
+ desiredOutput = "- &fred ~\n- *fred";
+ }
+
+ void AliasAndAnchorInFlow(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::Flow << YAML::BeginSeq;
+ out << YAML::Anchor("fred");
+ out << YAML::BeginMap;
+ out << YAML::Key << "name" << YAML::Value << "Fred";
+ out << YAML::Key << "age" << YAML::Value << 42;
+ out << YAML::EndMap;
+ out << YAML::Alias("fred");
+ out << YAML::EndSeq;
+
+ desiredOutput = "[&fred {name: Fred, age: 42}, *fred]";
+ }
+
+ void SimpleVerbatimTag(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::VerbatimTag("!foo") << "bar";
+
+ desiredOutput = "!<!foo> bar";
+ }
+
+ void VerbatimTagInBlockSeq(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginSeq;
+ out << YAML::VerbatimTag("!foo") << "bar";
+ out << "baz";
+ out << YAML::EndSeq;
+
+ desiredOutput = "- !<!foo> bar\n- baz";
+ }
+
+ void VerbatimTagInFlowSeq(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::Flow << YAML::BeginSeq;
+ out << YAML::VerbatimTag("!foo") << "bar";
+ out << "baz";
+ out << YAML::EndSeq;
+
+ desiredOutput = "[!<!foo> bar, baz]";
+ }
+
+ void VerbatimTagInFlowSeqWithNull(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::Flow << YAML::BeginSeq;
+ out << YAML::VerbatimTag("!foo") << YAML::Null;
+ out << "baz";
+ out << YAML::EndSeq;
+
+ desiredOutput = "[!<!foo> ~, baz]";
+ }
+
+ void VerbatimTagInBlockMap(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginMap;
+ out << YAML::Key << YAML::VerbatimTag("!foo") << "bar";
+ out << YAML::Value << YAML::VerbatimTag("!waz") << "baz";
+ out << YAML::EndMap;
+
+ desiredOutput = "!<!foo> bar: !<!waz> baz";
+ }
+
+ void VerbatimTagInFlowMap(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::Flow << YAML::BeginMap;
+ out << YAML::Key << YAML::VerbatimTag("!foo") << "bar";
+ out << YAML::Value << "baz";
+ out << YAML::EndMap;
+
+ desiredOutput = "{!<!foo> bar: baz}";
+ }
+
+ void VerbatimTagInFlowMapWithNull(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::Flow << YAML::BeginMap;
+ out << YAML::Key << YAML::VerbatimTag("!foo") << YAML::Null;
+ out << YAML::Value << "baz";
+ out << YAML::EndMap;
+
+ desiredOutput = "{!<!foo> ~: baz}";
+ }
+
+ void VerbatimTagWithEmptySeq(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::VerbatimTag("!foo") << YAML::BeginSeq << YAML::EndSeq;
+
+ desiredOutput = "!<!foo>\n[]";
+ }
+
+ void VerbatimTagWithEmptyMap(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::VerbatimTag("!bar") << YAML::BeginMap << YAML::EndMap;
+
+ desiredOutput = "!<!bar>\n{}";
+ }
+
+ void VerbatimTagWithEmptySeqAndMap(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginSeq;
+ out << YAML::VerbatimTag("!foo") << YAML::BeginSeq << YAML::EndSeq;
+ out << YAML::VerbatimTag("!bar") << YAML::BeginMap << YAML::EndMap;
+ out << YAML::EndSeq;
+
+ desiredOutput = "- !<!foo>\n []\n- !<!bar>\n {}";
+ }
+
+ void ByKindTagWithScalar(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginSeq;
+ out << YAML::DoubleQuoted << "12";
+ out << "12";
+ out << YAML::TagByKind << "12";
+ out << YAML::EndSeq;
+
+ desiredOutput = "- \"12\"\n- 12\n- ! 12";
+ }
+
+ void LocalTagWithScalar(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::LocalTag("foo") << "bar";
+
+ desiredOutput = "!foo bar";
+ }
+
+ void BadLocalTag(YAML::Emitter& out, std::string& desiredError)
+ {
+ out << YAML::LocalTag("e!far") << "bar";
+
+ desiredError = "invalid tag";
+ }
+
+ void ComplexDoc(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginMap;
+ out << YAML::Key << "receipt";
+ out << YAML::Value << "Oz-Ware Purchase Invoice";
+ out << YAML::Key << "date";
+ out << YAML::Value << "2007-08-06";
+ out << YAML::Key << "customer";
+ out << YAML::Value;
+ out << YAML::BeginMap;
+ out << YAML::Key << "given";
+ out << YAML::Value << "Dorothy";
+ out << YAML::Key << "family";
+ out << YAML::Value << "Gale";
+ out << YAML::EndMap;
+ out << YAML::Key << "items";
+ out << YAML::Value;
+ out << YAML::BeginSeq;
+ out << YAML::BeginMap;
+ out << YAML::Key << "part_no";
+ out << YAML::Value << "A4786";
+ out << YAML::Key << "descrip";
+ out << YAML::Value << "Water Bucket (Filled)";
+ out << YAML::Key << "price";
+ out << YAML::Value << 1.47;
+ out << YAML::Key << "quantity";
+ out << YAML::Value << 4;
+ out << YAML::EndMap;
+ out << YAML::BeginMap;
+ out << YAML::Key << "part_no";
+ out << YAML::Value << "E1628";
+ out << YAML::Key << "descrip";
+ out << YAML::Value << "High Heeled \"Ruby\" Slippers";
+ out << YAML::Key << "price";
+ out << YAML::Value << 100.27;
+ out << YAML::Key << "quantity";
+ out << YAML::Value << 1;
+ out << YAML::EndMap;
+ out << YAML::EndSeq;
+ out << YAML::Key << "bill-to";
+ out << YAML::Value << YAML::Anchor("id001");
+ out << YAML::BeginMap;
+ out << YAML::Key << "street";
+ out << YAML::Value << YAML::Literal << "123 Tornado Alley\nSuite 16";
+ out << YAML::Key << "city";
+ out << YAML::Value << "East Westville";
+ out << YAML::Key << "state";
+ out << YAML::Value << "KS";
+ out << YAML::EndMap;
+ out << YAML::Key << "ship-to";
+ out << YAML::Value << YAML::Alias("id001");
+ out << YAML::EndMap;
+
+ desiredOutput = "receipt: Oz-Ware Purchase Invoice\ndate: 2007-08-06\ncustomer:\n given: Dorothy\n family: Gale\nitems:\n - part_no: A4786\n descrip: Water Bucket (Filled)\n price: 1.47\n quantity: 4\n - part_no: E1628\n descrip: High Heeled \"Ruby\" Slippers\n price: 100.27\n quantity: 1\nbill-to: &id001\n street: |\n 123 Tornado Alley\n Suite 16\n city: East Westville\n state: KS\nship-to: *id001";
+ }
+
+ void STLContainers(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginSeq;
+ std::vector <int> primes;
+ primes.push_back(2);
+ primes.push_back(3);
+ primes.push_back(5);
+ primes.push_back(7);
+ primes.push_back(11);
+ primes.push_back(13);
+ out << YAML::Flow << primes;
+ std::map <std::string, int> ages;
+ ages["Daniel"] = 26;
+ ages["Jesse"] = 24;
+ out << ages;
+ out << YAML::EndSeq;
+
+ desiredOutput = "- [2, 3, 5, 7, 11, 13]\n- Daniel: 26\n Jesse: 24";
+ }
+
+ void SimpleComment(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginMap;
+ out << YAML::Key << "method";
+ out << YAML::Value << "least squares" << YAML::Comment("should we change this method?");
+ out << YAML::EndMap;
+
+ desiredOutput = "method: least squares # should we change this method?";
+ }
+
+ void MultiLineComment(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginSeq;
+ out << "item 1" << YAML::Comment("really really long\ncomment that couldn't possibly\nfit on one line");
+ out << "item 2";
+ out << YAML::EndSeq;
+
+ desiredOutput = "- item 1 # really really long\n # comment that couldn't possibly\n # fit on one line\n- item 2";
+ }
+
+ void ComplexComments(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginMap;
+ out << YAML::LongKey << YAML::Key << "long key" << YAML::Comment("long key");
+ out << YAML::Value << "value";
+ out << YAML::EndMap;
+
+ desiredOutput = "? long key # long key\n: value";
+ }
+
+ void InitialComment(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::Comment("A comment describing the purpose of the file.");
+ out << YAML::BeginMap << YAML::Key << "key" << YAML::Value << "value" << YAML::EndMap;
+
+ desiredOutput = "# A comment describing the purpose of the file.\nkey: value";
+ }
+
+ void InitialCommentWithDocIndicator(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginDoc << YAML::Comment("A comment describing the purpose of the file.");
+ out << YAML::BeginMap << YAML::Key << "key" << YAML::Value << "value" << YAML::EndMap;
+
+ desiredOutput = "---\n# A comment describing the purpose of the file.\nkey: value";
+ }
+
+ void CommentInFlowSeq(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::Flow << YAML::BeginSeq << "foo" << YAML::Comment("foo!") << "bar" << YAML::EndSeq;
+
+ desiredOutput = "[foo # foo!\n, bar]";
+ }
+
+ void CommentInFlowMap(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::Flow << YAML::BeginMap;
+ out << YAML::Key << "foo" << YAML::Value << "foo value";
+ out << YAML::Key << "bar" << YAML::Value << "bar value" << YAML::Comment("bar!");
+ out << YAML::Key << "baz" << YAML::Value << "baz value" << YAML::Comment("baz!");
+ out << YAML::EndMap;
+
+ desiredOutput = "{foo: foo value, bar: bar value # bar!\n, baz: baz value # baz!\n}";
+ }
+
+ void Indentation(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::Indent(4);
+ out << YAML::BeginSeq;
+ out << YAML::BeginMap;
+ out << YAML::Key << "key 1" << YAML::Value << "value 1";
+ out << YAML::Key << "key 2" << YAML::Value << YAML::BeginSeq << "a" << "b" << "c" << YAML::EndSeq;
+ out << YAML::EndMap;
+ out << YAML::EndSeq;
+
+ desiredOutput = "- key 1: value 1\n key 2:\n - a\n - b\n - c";
+ }
+
+ void SimpleGlobalSettings(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out.SetIndent(4);
+ out.SetMapFormat(YAML::LongKey);
+
+ out << YAML::BeginSeq;
+ out << YAML::BeginMap;
+ out << YAML::Key << "key 1" << YAML::Value << "value 1";
+ out << YAML::Key << "key 2" << YAML::Value << YAML::Flow << YAML::BeginSeq << "a" << "b" << "c" << YAML::EndSeq;
+ out << YAML::EndMap;
+ out << YAML::EndSeq;
+
+ desiredOutput = "- ? key 1\n : value 1\n ? key 2\n : [a, b, c]";
+ }
+
+ void ComplexGlobalSettings(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginSeq;
+ out << YAML::Block;
+ out << YAML::BeginMap;
+ out << YAML::Key << "key 1" << YAML::Value << "value 1";
+ out << YAML::Key << "key 2" << YAML::Value;
+ out.SetSeqFormat(YAML::Flow);
+ out << YAML::BeginSeq << "a" << "b" << "c" << YAML::EndSeq;
+ out << YAML::EndMap;
+ out << YAML::BeginMap;
+ out << YAML::Key << YAML::BeginSeq << 1 << 2 << YAML::EndSeq;
+ out << YAML::Value << YAML::BeginMap << YAML::Key << "a" << YAML::Value << "b" << YAML::EndMap;
+ out << YAML::EndMap;
+ out << YAML::EndSeq;
+
+ desiredOutput = "- key 1: value 1\n key 2: [a, b, c]\n- ? [1, 2]\n :\n a: b";
+ }
+
+ void Null(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginSeq;
+ out << YAML::Null;
+ out << YAML::BeginMap;
+ out << YAML::Key << "null value" << YAML::Value << YAML::Null;
+ out << YAML::Key << YAML::Null << YAML::Value << "null key";
+ out << YAML::EndMap;
+ out << YAML::EndSeq;
+
+ desiredOutput = "- ~\n- null value: ~\n ~: null key";
+ }
+
+ void EscapedUnicode(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::EscapeNonAscii << "\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2";
+
+ desiredOutput = "\"$ \\xa2 \\u20ac \\U00024b62\"";
+ }
+
+ void Unicode(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << "\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2";
+ desiredOutput = "\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2";
+ }
+
+ void DoubleQuotedUnicode(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::DoubleQuoted << "\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2";
+ desiredOutput = "\"\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2\"";
+ }
+
+ struct Foo {
+ Foo(): x(0) {}
+ Foo(int x_, const std::string& bar_): x(x_), bar(bar_) {}
+
+ int x;
+ std::string bar;
+ };
+
+ YAML::Emitter& operator << (YAML::Emitter& out, const Foo& foo) {
+ out << YAML::BeginMap;
+ out << YAML::Key << "x" << YAML::Value << foo.x;
+ out << YAML::Key << "bar" << YAML::Value << foo.bar;
+ out << YAML::EndMap;
+ return out;
+ }
+
+ void UserType(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginSeq;
+ out << Foo(5, "hello");
+ out << Foo(3, "goodbye");
+ out << YAML::EndSeq;
+
+ desiredOutput = "- x: 5\n bar: hello\n- x: 3\n bar: goodbye";
+ }
+
+ void UserTypeInContainer(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ std::vector<Foo> fv;
+ fv.push_back(Foo(5, "hello"));
+ fv.push_back(Foo(3, "goodbye"));
+ out << fv;
+
+ desiredOutput = "- x: 5\n bar: hello\n- x: 3\n bar: goodbye";
+ }
+
+ template <typename T>
+ YAML::Emitter& operator << (YAML::Emitter& out, const T *v) {
+ if(v)
+ out << *v;
+ else
+ out << YAML::Null;
+ return out;
+ }
+
+ void PointerToInt(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ int foo = 5;
+ int *bar = &foo;
+ int *baz = 0;
+ out << YAML::BeginSeq;
+ out << bar << baz;
+ out << YAML::EndSeq;
+
+ desiredOutput = "- 5\n- ~";
+ }
+
+ void PointerToUserType(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ Foo foo(5, "hello");
+ Foo *bar = &foo;
+ Foo *baz = 0;
+ out << YAML::BeginSeq;
+ out << bar << baz;
+ out << YAML::EndSeq;
+
+ desiredOutput = "- x: 5\n bar: hello\n- ~";
+ }
+
+ void NewlineAtEnd(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << "Hello" << YAML::Newline << YAML::Newline;
+ desiredOutput = "Hello\n\n";
+ }
+
+ void NewlineInBlockSequence(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginSeq;
+ out << "a" << YAML::Newline << "b" << "c" << YAML::Newline << "d";
+ out << YAML::EndSeq;
+ desiredOutput = "- a\n\n- b\n- c\n\n- d";
+ }
+
+ void NewlineInFlowSequence(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::Flow << YAML::BeginSeq;
+ out << "a" << YAML::Newline << "b" << "c" << YAML::Newline << "d";
+ out << YAML::EndSeq;
+ desiredOutput = "[a\n, b, c\n, d]";
+ }
+
+ void NewlineInBlockMap(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginMap;
+ out << YAML::Key << "a" << YAML::Value << "foo" << YAML::Newline;
+ out << YAML::Key << "b" << YAML::Newline << YAML::Value << "bar";
+ out << YAML::LongKey << YAML::Key << "c" << YAML::Newline << YAML::Value << "car";
+ out << YAML::EndMap;
+ desiredOutput = "a: foo\n\nb: bar\n? c\n\n: car";
+ }
+
+ void NewlineInFlowMap(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::Flow << YAML::BeginMap;
+ out << YAML::Key << "a" << YAML::Value << "foo" << YAML::Newline;
+ out << YAML::Key << "b" << YAML::Value << "bar";
+ out << YAML::EndMap;
+ desiredOutput = "{a: foo\n, b: bar}";
+ }
+
+ void LotsOfNewlines(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginSeq;
+ out << "a" << YAML::Newline;
+ out << YAML::BeginSeq;
+ out << "b" << "c" << YAML::Newline;
+ out << YAML::EndSeq;
+ out << YAML::Newline;
+ out << YAML::BeginMap;
+ out << YAML::Newline << YAML::Key << "d" << YAML::Value << YAML::Newline << "e";
+ out << YAML::LongKey << YAML::Key << "f" << YAML::Newline << YAML::Value << "foo";
+ out << YAML::EndMap;
+ out << YAML::EndSeq;
+ desiredOutput = "- a\n\n-\n - b\n - c\n\n\n-\n d: e\n ? f\n\n : foo";
+ }
+
+ void Binary(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::Binary(reinterpret_cast<const unsigned char*>("Hello, World!"), 13);
+ desiredOutput = "!!binary \"SGVsbG8sIFdvcmxkIQ==\"";
+ }
+
+ void LongBinary(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::Binary(reinterpret_cast<const unsigned char*>("Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.\n"), 270);
+ desiredOutput = "!!binary \"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4K\"";
+ }
+
+ void EmptyBinary(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::Binary(reinterpret_cast<const unsigned char *>(""), 0);
+ desiredOutput = "!!binary \"\"";
+ }
+
+ void ColonAtEndOfScalar(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << "a:";
+ desiredOutput = "\"a:\"";
+ }
+
+ void ColonAsScalar(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginMap;
+ out << YAML::Key << "apple" << YAML::Value << ":";
+ out << YAML::Key << "banana" << YAML::Value << ":";
+ out << YAML::EndMap;
+ desiredOutput = "apple: \":\"\nbanana: \":\"";
+ }
+
+ void ColonAtEndOfScalarInFlow(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::Flow << YAML::BeginMap << YAML::Key << "C:" << YAML::Value << "C:" << YAML::EndMap;
+ desiredOutput = "{\"C:\": \"C:\"}";
+ }
+
+ void BoolFormatting(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginSeq;
+ out << YAML::TrueFalseBool << YAML::UpperCase << true;
+ out << YAML::TrueFalseBool << YAML::CamelCase << true;
+ out << YAML::TrueFalseBool << YAML::LowerCase << true;
+ out << YAML::TrueFalseBool << YAML::UpperCase << false;
+ out << YAML::TrueFalseBool << YAML::CamelCase << false;
+ out << YAML::TrueFalseBool << YAML::LowerCase << false;
+ out << YAML::YesNoBool << YAML::UpperCase << true;
+ out << YAML::YesNoBool << YAML::CamelCase << true;
+ out << YAML::YesNoBool << YAML::LowerCase << true;
+ out << YAML::YesNoBool << YAML::UpperCase << false;
+ out << YAML::YesNoBool << YAML::CamelCase << false;
+ out << YAML::YesNoBool << YAML::LowerCase << false;
+ out << YAML::OnOffBool << YAML::UpperCase << true;
+ out << YAML::OnOffBool << YAML::CamelCase << true;
+ out << YAML::OnOffBool << YAML::LowerCase << true;
+ out << YAML::OnOffBool << YAML::UpperCase << false;
+ out << YAML::OnOffBool << YAML::CamelCase << false;
+ out << YAML::OnOffBool << YAML::LowerCase << false;
+ out << YAML::ShortBool << YAML::UpperCase << true;
+ out << YAML::ShortBool << YAML::CamelCase << true;
+ out << YAML::ShortBool << YAML::LowerCase << true;
+ out << YAML::ShortBool << YAML::UpperCase << false;
+ out << YAML::ShortBool << YAML::CamelCase << false;
+ out << YAML::ShortBool << YAML::LowerCase << false;
+ out << YAML::EndSeq;
+ desiredOutput =
+ "- TRUE\n- True\n- true\n- FALSE\n- False\n- false\n"
+ "- YES\n- Yes\n- yes\n- NO\n- No\n- no\n"
+ "- ON\n- On\n- on\n- OFF\n- Off\n- off\n"
+ "- Y\n- Y\n- y\n- N\n- N\n- n";
+ }
+
+ void DocStartAndEnd(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginDoc;
+ out << YAML::BeginSeq << 1 << 2 << 3 << YAML::EndSeq;
+ out << YAML::BeginDoc;
+ out << "Hi there!";
+ out << YAML::EndDoc;
+ out << YAML::EndDoc;
+ out << YAML::EndDoc;
+ out << YAML::BeginDoc;
+ out << YAML::VerbatimTag("foo") << "bar";
+ desiredOutput = "---\n- 1\n- 2\n- 3\n---\nHi there!\n...\n...\n...\n---\n!<foo> bar";
+ }
+
+ void ImplicitDocStart(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << "Hi";
+ out << "Bye";
+ out << "Oops";
+ desiredOutput = "Hi\n---\nBye\n---\nOops";
+ }
+
+ void EmptyString(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginMap;
+ out << YAML::Key << "key" << YAML::Value << "";
+ out << YAML::EndMap;
+ desiredOutput = "key: \"\"";
+ }
+
+ void SingleChar(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginSeq;
+ out << 'a';
+ out << ':';
+ out << (char)0x10;
+ out << '\n';
+ out << ' ';
+ out << '\t';
+ out << YAML::EndSeq;
+ desiredOutput = "- a\n- \":\"\n- \"\\x10\"\n- \"\\n\"\n- \" \"\n- \"\\t\"";
+ }
+
+ void DefaultPrecision(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginSeq;
+ out << 1.234f;
+ out << 3.14159265358979;
+ out << YAML::EndSeq;
+ desiredOutput = "- 1.234\n- 3.14159265358979";
+ }
+
+ void SetPrecision(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginSeq;
+ out << YAML::FloatPrecision(3) << 1.234f;
+ out << YAML::DoublePrecision(6) << 3.14159265358979;
+ out << YAML::EndSeq;
+ desiredOutput = "- 1.23\n- 3.14159";
+ }
+
+ void DashInBlockContext(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::BeginMap;
+ out << YAML::Key << "key" << YAML::Value << "-";
+ out << YAML::EndMap;
+ desiredOutput = "key: \"-\"";
+ }
+
+ void HexAndOct(YAML::Emitter& out, std::string& desiredOutput)
+ {
+ out << YAML::Flow << YAML::BeginSeq;
+ out << 31;
+ out << YAML::Hex << 31;
+ out << YAML::Oct << 31;
+ out << YAML::EndSeq;
+ desiredOutput = "[31, 0x1f, 037]";
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // incorrect emitting
+
+ void ExtraEndSeq(YAML::Emitter& out, std::string& desiredError)
+ {
+ desiredError = YAML::ErrorMsg::UNEXPECTED_END_SEQ;
+
+ out << YAML::BeginSeq;
+ out << "Hello";
+ out << "World";
+ out << YAML::EndSeq;
+ out << YAML::EndSeq;
+ }
+
+ void ExtraEndMap(YAML::Emitter& out, std::string& desiredError)
+ {
+ desiredError = YAML::ErrorMsg::UNEXPECTED_END_MAP;
+
+ out << YAML::BeginMap;
+ out << YAML::Key << "Hello" << YAML::Value << "World";
+ out << YAML::EndMap;
+ out << YAML::EndMap;
+ }
+
+ void BadSingleQuoted(YAML::Emitter& out, std::string& desiredError)
+ {
+ desiredError = YAML::ErrorMsg::SINGLE_QUOTED_CHAR;
+
+ out << YAML::SingleQuoted << "Hello\nWorld";
+ }
+
+ void InvalidAnchor(YAML::Emitter& out, std::string& desiredError)
+ {
+ desiredError = YAML::ErrorMsg::INVALID_ANCHOR;
+
+ out << YAML::BeginSeq;
+ out << YAML::Anchor("new\nline") << "Test";
+ out << YAML::EndSeq;
+ }
+
+ void InvalidAlias(YAML::Emitter& out, std::string& desiredError)
+ {
+ desiredError = YAML::ErrorMsg::INVALID_ALIAS;
+
+ out << YAML::BeginSeq;
+ out << YAML::Alias("new\nline");
+ out << YAML::EndSeq;
+ }
+
+ void MissingKey(YAML::Emitter& out, std::string& desiredError)
+ {
+ desiredError = YAML::ErrorMsg::EXPECTED_KEY_TOKEN;
+
+ out << YAML::BeginMap;
+ out << YAML::Key << "key" << YAML::Value << "value";
+ out << "missing key" << YAML::Value << "value";
+ out << YAML::EndMap;
+ }
+
+ void MissingValue(YAML::Emitter& out, std::string& desiredError)
+ {
+ desiredError = YAML::ErrorMsg::EXPECTED_VALUE_TOKEN;
+
+ out << YAML::BeginMap;
+ out << YAML::Key << "key" << "value";
+ out << YAML::EndMap;
+ }
+
+ void UnexpectedKey(YAML::Emitter& out, std::string& desiredError)
+ {
+ desiredError = YAML::ErrorMsg::UNEXPECTED_KEY_TOKEN;
+
+ out << YAML::BeginSeq;
+ out << YAML::Key << "hi";
+ out << YAML::EndSeq;
+ }
+
+ void UnexpectedValue(YAML::Emitter& out, std::string& desiredError)
+ {
+ desiredError = YAML::ErrorMsg::UNEXPECTED_VALUE_TOKEN;
+
+ out << YAML::BeginSeq;
+ out << YAML::Value << "hi";
+ out << YAML::EndSeq;
+ }
+ }
+
+ namespace {
+ void RunEmitterTest(void (*test)(YAML::Emitter&, std::string&), const std::string& name, int& passed, int& total) {
+ YAML::Emitter out;
+ std::string desiredOutput;
+ test(out, desiredOutput);
+ std::string output = out.c_str();
+ std::string lastError = out.GetLastError();
+
+ if(output == desiredOutput) {
+ try {
+ std::stringstream stream(output);
+ YAML::Parser parser;
+ YAML::Node node;
+ parser.GetNextDocument(node);
+ passed++;
+ } catch(const YAML::Exception& e) {
+ std::cout << "Emitter test failed: " << name << "\n";
+ std::cout << "Parsing output error: " << e.what() << "\n";
+ }
+ } else {
+ std::cout << "Emitter test failed: " << name << "\n";
+ std::cout << "Output:\n";
+ std::cout << output << "<<<\n";
+ std::cout << "Desired output:\n";
+ std::cout << desiredOutput << "<<<\n";
+ if(!out.good())
+ std::cout << "Emitter error: " << lastError << "\n";
+ }
+ total++;
+ }
+
+ void RunEmitterErrorTest(void (*test)(YAML::Emitter&, std::string&), const std::string& name, int& passed, int& total) {
+ YAML::Emitter out;
+ std::string desiredError;
+ test(out, desiredError);
+ std::string lastError = out.GetLastError();
+ if(!out.good() && lastError == desiredError) {
+ passed++;
+ } else {
+ std::cout << "Emitter test failed: " << name << "\n";
+ if(out.good())
+ std::cout << "No error detected\n";
+ else
+ std::cout << "Detected error: " << lastError << "\n";
+ std::cout << "Expected error: " << desiredError << "\n";
+ }
+ total++;
+ }
+ }
+
+ bool RunEmitterTests()
+ {
+ int passed = 0;
+ int total = 0;
+ RunEmitterTest(&Emitter::SimpleScalar, "simple scalar", passed, total);
+ RunEmitterTest(&Emitter::SimpleSeq, "simple seq", passed, total);
+ RunEmitterTest(&Emitter::SimpleFlowSeq, "simple flow seq", passed, total);
+ RunEmitterTest(&Emitter::EmptyFlowSeq, "empty flow seq", passed, total);
+ RunEmitterTest(&Emitter::NestedBlockSeq, "nested block seq", passed, total);
+ RunEmitterTest(&Emitter::NestedFlowSeq, "nested flow seq", passed, total);
+ RunEmitterTest(&Emitter::SimpleMap, "simple map", passed, total);
+ RunEmitterTest(&Emitter::SimpleFlowMap, "simple flow map", passed, total);
+ RunEmitterTest(&Emitter::MapAndList, "map and list", passed, total);
+ RunEmitterTest(&Emitter::ListAndMap, "list and map", passed, total);
+ RunEmitterTest(&Emitter::NestedBlockMap, "nested block map", passed, total);
+ RunEmitterTest(&Emitter::NestedFlowMap, "nested flow map", passed, total);
+ RunEmitterTest(&Emitter::MapListMix, "map list mix", passed, total);
+ RunEmitterTest(&Emitter::SimpleLongKey, "simple long key", passed, total);
+ RunEmitterTest(&Emitter::SingleLongKey, "single long key", passed, total);
+ RunEmitterTest(&Emitter::ComplexLongKey, "complex long key", passed, total);
+ RunEmitterTest(&Emitter::AutoLongKey, "auto long key", passed, total);
+ RunEmitterTest(&Emitter::ScalarFormat, "scalar format", passed, total);
+ RunEmitterTest(&Emitter::AutoLongKeyScalar, "auto long key scalar", passed, total);
+ RunEmitterTest(&Emitter::LongKeyFlowMap, "long key flow map", passed, total);
+ RunEmitterTest(&Emitter::BlockMapAsKey, "block map as key", passed, total);
+ RunEmitterTest(&Emitter::AliasAndAnchor, "alias and anchor", passed, total);
+ RunEmitterTest(&Emitter::AliasAndAnchorWithNull, "alias and anchor with null", passed, total);
+ RunEmitterTest(&Emitter::AliasAndAnchorInFlow, "alias and anchor in flow", passed, total);
+ RunEmitterTest(&Emitter::SimpleVerbatimTag, "simple verbatim tag", passed, total);
+ RunEmitterTest(&Emitter::VerbatimTagInBlockSeq, "verbatim tag in block seq", passed, total);
+ RunEmitterTest(&Emitter::VerbatimTagInFlowSeq, "verbatim tag in flow seq", passed, total);
+ RunEmitterTest(&Emitter::VerbatimTagInFlowSeqWithNull, "verbatim tag in flow seq with null", passed, total);
+ RunEmitterTest(&Emitter::VerbatimTagInBlockMap, "verbatim tag in block map", passed, total);
+ RunEmitterTest(&Emitter::VerbatimTagInFlowMap, "verbatim tag in flow map", passed, total);
+ RunEmitterTest(&Emitter::VerbatimTagInFlowMapWithNull, "verbatim tag in flow map with null", passed, total);
+ RunEmitterTest(&Emitter::VerbatimTagWithEmptySeq, "verbatim tag with empty seq", passed, total);
+ RunEmitterTest(&Emitter::VerbatimTagWithEmptyMap, "verbatim tag with empty map", passed, total);
+ RunEmitterTest(&Emitter::VerbatimTagWithEmptySeqAndMap, "verbatim tag with empty seq and map", passed, total);
+ RunEmitterTest(&Emitter::ByKindTagWithScalar, "by-kind tag with scalar", passed, total);
+ RunEmitterTest(&Emitter::LocalTagWithScalar, "local tag with scalar", passed, total);
+ RunEmitterTest(&Emitter::ComplexDoc, "complex doc", passed, total);
+ RunEmitterTest(&Emitter::STLContainers, "STL containers", passed, total);
+ RunEmitterTest(&Emitter::SimpleComment, "simple comment", passed, total);
+ RunEmitterTest(&Emitter::MultiLineComment, "multi-line comment", passed, total);
+ RunEmitterTest(&Emitter::ComplexComments, "complex comments", passed, total);
+ RunEmitterTest(&Emitter::InitialComment, "initial comment", passed, total);
+ RunEmitterTest(&Emitter::InitialCommentWithDocIndicator, "initial comment with doc indicator", passed, total);
+ RunEmitterTest(&Emitter::CommentInFlowSeq, "comment in flow seq", passed, total);
+ RunEmitterTest(&Emitter::CommentInFlowMap, "comment in flow map", passed, total);
+ RunEmitterTest(&Emitter::Indentation, "indentation", passed, total);
+ RunEmitterTest(&Emitter::SimpleGlobalSettings, "simple global settings", passed, total);
+ RunEmitterTest(&Emitter::ComplexGlobalSettings, "complex global settings", passed, total);
+ RunEmitterTest(&Emitter::Null, "null", passed, total);
+ RunEmitterTest(&Emitter::EscapedUnicode, "escaped unicode", passed, total);
+ RunEmitterTest(&Emitter::Unicode, "unicode", passed, total);
+ RunEmitterTest(&Emitter::DoubleQuotedUnicode, "double quoted unicode", passed, total);
+ RunEmitterTest(&Emitter::UserType, "user type", passed, total);
+ RunEmitterTest(&Emitter::UserTypeInContainer, "user type in container", passed, total);
+ RunEmitterTest(&Emitter::PointerToInt, "pointer to int", passed, total);
+ RunEmitterTest(&Emitter::PointerToUserType, "pointer to user type", passed, total);
+ RunEmitterTest(&Emitter::NewlineAtEnd, "newline at end", passed, total);
+ RunEmitterTest(&Emitter::NewlineInBlockSequence, "newline in block sequence", passed, total);
+ RunEmitterTest(&Emitter::NewlineInFlowSequence, "newline in flow sequence", passed, total);
+ RunEmitterTest(&Emitter::NewlineInBlockMap, "newline in block map", passed, total);
+ RunEmitterTest(&Emitter::NewlineInFlowMap, "newline in flow map", passed, total);
+ RunEmitterTest(&Emitter::LotsOfNewlines, "lots of newlines", passed, total);
+ RunEmitterTest(&Emitter::Binary, "binary", passed, total);
+ RunEmitterTest(&Emitter::LongBinary, "long binary", passed, total);
+ RunEmitterTest(&Emitter::EmptyBinary, "empty binary", passed, total);
+ RunEmitterTest(&Emitter::ColonAtEndOfScalar, "colon at end of scalar", passed, total);
+ RunEmitterTest(&Emitter::ColonAsScalar, "colon as scalar", passed, total);
+ RunEmitterTest(&Emitter::ColonAtEndOfScalarInFlow, "colon at end of scalar in flow", passed, total);
+ RunEmitterTest(&Emitter::BoolFormatting, "bool formatting", passed, total);
+ RunEmitterTest(&Emitter::DocStartAndEnd, "doc start and end", passed, total);
+ RunEmitterTest(&Emitter::ImplicitDocStart, "implicit doc start", passed, total);
+ RunEmitterTest(&Emitter::EmptyString, "empty string", passed, total);
+ RunEmitterTest(&Emitter::SingleChar, "single char", passed, total);
+ RunEmitterTest(&Emitter::DefaultPrecision, "default precision", passed, total);
+ RunEmitterTest(&Emitter::SetPrecision, "set precision", passed, total);
+ RunEmitterTest(&Emitter::DashInBlockContext, "dash in block context", passed, total);
+ RunEmitterTest(&Emitter::HexAndOct, "hex and oct", passed, total);
+
+ RunEmitterErrorTest(&Emitter::ExtraEndSeq, "extra EndSeq", passed, total);
+ RunEmitterErrorTest(&Emitter::ExtraEndMap, "extra EndMap", passed, total);
+ RunEmitterErrorTest(&Emitter::BadSingleQuoted, "bad single quoted string", passed, total);
+ RunEmitterErrorTest(&Emitter::InvalidAnchor, "invalid anchor", passed, total);
+ RunEmitterErrorTest(&Emitter::InvalidAlias, "invalid alias", passed, total);
+ RunEmitterErrorTest(&Emitter::MissingKey, "missing key", passed, total);
+ RunEmitterErrorTest(&Emitter::MissingValue, "missing value", passed, total);
+ RunEmitterErrorTest(&Emitter::UnexpectedKey, "unexpected key", passed, total);
+ RunEmitterErrorTest(&Emitter::UnexpectedValue, "unexpected value", passed, total);
+ RunEmitterErrorTest(&Emitter::BadLocalTag, "bad local tag", passed, total);
+
+ std::cout << "Emitter tests: " << passed << "/" << total << " passed\n";
+ return passed == total;
+ }
+}
+
diff --git a/external_libs/yaml-cpp/test/emittertests.h b/external_libs/yaml-cpp/test/emittertests.h
new file mode 100644
index 00000000..e7c6ac50
--- /dev/null
+++ b/external_libs/yaml-cpp/test/emittertests.h
@@ -0,0 +1,13 @@
+#ifndef EMITTERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define EMITTERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+namespace Test {
+ bool RunEmitterTests();
+}
+
+#endif // EMITTERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
diff --git a/external_libs/yaml-cpp/test/main.cpp b/external_libs/yaml-cpp/test/main.cpp
new file mode 100644
index 00000000..64c69f10
--- /dev/null
+++ b/external_libs/yaml-cpp/test/main.cpp
@@ -0,0 +1,7 @@
+#include "tests.h"
+
+int main()
+{
+ Test::RunAll();
+ return 0;
+}
diff --git a/external_libs/yaml-cpp/test/nodetests.h b/external_libs/yaml-cpp/test/nodetests.h
new file mode 100644
index 00000000..733e782e
--- /dev/null
+++ b/external_libs/yaml-cpp/test/nodetests.h
@@ -0,0 +1,13 @@
+#ifndef NODETESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODETESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+namespace Test {
+ bool RunNodeTests();
+}
+
+#endif // NODETESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A6666
+
diff --git a/external_libs/yaml-cpp/test/old-api/parsertests.cpp b/external_libs/yaml-cpp/test/old-api/parsertests.cpp
new file mode 100644
index 00000000..de7f1238
--- /dev/null
+++ b/external_libs/yaml-cpp/test/old-api/parsertests.cpp
@@ -0,0 +1,1237 @@
+#include "tests.h"
+#include "yaml-cpp/yaml.h"
+#include <sstream>
+#include <algorithm>
+#include <iostream>
+
+namespace Test
+{
+ namespace Parser {
+ void SimpleScalar(std::string& inputScalar, std::string& desiredOutput)
+ {
+ inputScalar = "Hello, World!";
+ desiredOutput = "Hello, World!";
+ }
+
+ void MultiLineScalar(std::string& inputScalar, std::string& desiredOutput)
+ {
+ inputScalar =
+ "normal scalar, but\n"
+ "over several lines";
+ desiredOutput = "normal scalar, but over several lines";
+ }
+
+ void LiteralScalar(std::string& inputScalar, std::string& desiredOutput)
+ {
+ inputScalar =
+ "|\n"
+ " literal scalar - so we can draw ASCII:\n"
+ " \n"
+ " - -\n"
+ " | - |\n"
+ " -----\n";
+ desiredOutput =
+ "literal scalar - so we can draw ASCII:\n"
+ "\n"
+ " - -\n"
+ " | - |\n"
+ " -----\n";
+ }
+
+ void FoldedScalar(std::string& inputScalar, std::string& desiredOutput)
+ {
+ inputScalar =
+ ">\n"
+ " and a folded scalar... so we\n"
+ " can just keep writing various\n"
+ " things. And if we want to keep indentation:\n"
+ " \n"
+ " we just indent a little\n"
+ " see, this stays indented";
+ desiredOutput =
+ "and a folded scalar... so we"
+ " can just keep writing various"
+ " things. And if we want to keep indentation:\n"
+ "\n"
+ " we just indent a little\n"
+ " see, this stays indented";
+ }
+
+ void ChompedFoldedScalar(std::string& inputScalar, std::string& desiredOutput)
+ {
+ inputScalar =
+ ">-\n"
+ " Here's a folded scalar\n"
+ " that gets chomped.";
+ desiredOutput =
+ "Here's a folded scalar"
+ " that gets chomped.";
+ }
+
+ void ChompedLiteralScalar(std::string& inputScalar, std::string& desiredOutput)
+ {
+ inputScalar =
+ "|-\n"
+ " Here's a literal scalar\n"
+ " that gets chomped.";
+ desiredOutput =
+ "Here's a literal scalar\n"
+ "that gets chomped.";
+ }
+
+ void FoldedScalarWithIndent(std::string& inputScalar, std::string& desiredOutput)
+ {
+ inputScalar =
+ ">2\n"
+ " Here's a folded scalar\n"
+ " that starts with some indentation.";
+ desiredOutput =
+ " Here's a folded scalar\n"
+ "that starts with some indentation.";
+ }
+
+ void ColonScalar(std::string& inputScalar, std::string& desiredOutput)
+ {
+ inputScalar = "::vector";
+ desiredOutput = "::vector";
+ }
+
+ void QuotedScalar(std::string& inputScalar, std::string& desiredOutput)
+ {
+ inputScalar = "\": - ()\"";
+ desiredOutput = ": - ()";
+ }
+
+ void CommaScalar(std::string& inputScalar, std::string& desiredOutput)
+ {
+ inputScalar = "Up, up, and away!";
+ desiredOutput = "Up, up, and away!";
+ }
+
+ void DashScalar(std::string& inputScalar, std::string& desiredOutput)
+ {
+ inputScalar = "-123";
+ desiredOutput = "-123";
+ }
+
+ void URLScalar(std::string& inputScalar, std::string& desiredOutput)
+ {
+ inputScalar = "http://example.com/foo#bar";
+ desiredOutput = "http://example.com/foo#bar";
+ }
+
+ bool SimpleSeq()
+ {
+ std::string input =
+ "- eggs\n"
+ "- bread\n"
+ "- milk";
+
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ std::string output;
+ if(doc[0].to<std::string>() != "eggs")
+ return false;
+ if(doc[1].to<std::string>() != "bread")
+ return false;
+ if(doc[2].to<std::string>() != "milk")
+ return false;
+
+ return true;
+ }
+
+ bool SimpleMap()
+ {
+ std::string input =
+ "name: Prince Fielder\n"
+ "position: 1B\n"
+ "bats: L";
+
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ std::string output;
+ doc["name"] >> output;
+ if(output != "Prince Fielder")
+ return false;
+ doc["position"] >> output;
+ if(output != "1B")
+ return false;
+ doc["bats"] >> output;
+ if(output != "L")
+ return false;
+
+ return true;
+ }
+
+ bool FlowSeq()
+ {
+ std::string input = "[ 2 , 3, 5 , 7, 11]";
+
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ int output;
+ doc[0] >> output;
+ if(output != 2)
+ return false;
+ doc[1] >> output;
+ if(output != 3)
+ return false;
+ doc[2] >> output;
+ if(output != 5)
+ return false;
+ doc[3] >> output;
+ if(output != 7)
+ return false;
+ doc[4] >> output;
+ if(output != 11)
+ return false;
+
+ return true;
+ }
+
+ bool FlowMap()
+ {
+ std::string input = "{hr: 65, avg: 0.278}";
+
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ std::string output;
+ doc["hr"] >> output;
+ if(output != "65")
+ return false;
+ doc["avg"] >> output;
+ if(output != "0.278")
+ return false;
+
+ return true;
+ }
+
+ bool FlowMapWithOmittedKey()
+ {
+ std::string input = "{: omitted key}";
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ std::string output;
+ doc[YAML::Null] >> output;
+ if(output != "omitted key")
+ return false;
+
+ return true;
+ }
+
+ bool FlowMapWithOmittedValue()
+ {
+ std::string input = "{a: b, c:, d:}";
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ std::string output;
+ doc["a"] >> output;
+ if(output != "b")
+ return false;
+ if(!IsNull(doc["c"]))
+ return false;
+ if(!IsNull(doc["d"]))
+ return false;
+
+ return true;
+ }
+
+ bool FlowMapWithSoloEntry()
+ {
+ std::string input = "{a: b, c, d: e}";
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ std::string output;
+ doc["a"] >> output;
+ if(output != "b")
+ return false;
+ if(!IsNull(doc["c"]))
+ return false;
+ doc["d"] >> output;
+ if(output != "e")
+ return false;
+
+ return true;
+ }
+
+ bool FlowMapEndingWithSoloEntry()
+ {
+ std::string input = "{a: b, c}";
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ std::string output;
+ doc["a"] >> output;
+ if(output != "b")
+ return false;
+ if(!IsNull(doc["c"]))
+ return false;
+
+ return true;
+ }
+
+ bool QuotedSimpleKeys()
+ {
+ std::string KeyValue[3] = { "\"double\": double\n", "'single': single\n", "plain: plain\n" };
+
+ int perm[3] = { 0, 1, 2 };
+ do {
+ std::string input = KeyValue[perm[0]] + KeyValue[perm[1]] + KeyValue[perm[2]];
+
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ std::string output;
+ doc["double"] >> output;
+ if(output != "double")
+ return false;
+ doc["single"] >> output;
+ if(output != "single")
+ return false;
+ doc["plain"] >> output;
+ if(output != "plain")
+ return false;
+ } while(std::next_permutation(perm, perm + 3));
+
+ return true;
+ }
+
+ bool CompressedMapAndSeq()
+ {
+ std::string input = "key:\n- one\n- two";
+
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ const YAML::Node& seq = doc["key"];
+ if(seq.size() != 2)
+ return false;
+
+ std::string output;
+ seq[0] >> output;
+ if(output != "one")
+ return false;
+ seq[1] >> output;
+ if(output != "two")
+ return false;
+
+ return true;
+ }
+
+ bool NullBlockSeqEntry()
+ {
+ std::string input = "- hello\n-\n- world";
+
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ std::string output;
+ doc[0] >> output;
+ if(output != "hello")
+ return false;
+ if(!IsNull(doc[1]))
+ return false;
+ doc[2] >> output;
+ if(output != "world")
+ return false;
+
+ return true;
+ }
+
+ bool NullBlockMapKey()
+ {
+ std::string input = ": empty key";
+
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ std::string output;
+ doc[YAML::Null] >> output;
+ if(output != "empty key")
+ return false;
+
+ return true;
+ }
+
+ bool NullBlockMapValue()
+ {
+ std::string input = "empty value:";
+
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ if(!IsNull(doc["empty value"]))
+ return false;
+
+ return true;
+ }
+
+ bool SimpleAlias()
+ {
+ std::string input = "- &alias test\n- *alias";
+
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ std::string output;
+ doc[0] >> output;
+ if(output != "test")
+ return false;
+
+ doc[1] >> output;
+ if(output != "test")
+ return false;
+
+ if(doc.size() != 2)
+ return false;
+
+ return true;
+ }
+
+ bool AliasWithNull()
+ {
+ std::string input = "- &alias\n- *alias";
+
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ if(!IsNull(doc[0]))
+ return false;
+
+ if(!IsNull(doc[1]))
+ return false;
+
+ if(doc.size() != 2)
+ return false;
+
+ return true;
+ }
+
+ bool AnchorInSimpleKey()
+ {
+ std::string input = "- &a b: c\n- *a";
+
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ if(doc.size() != 2)
+ return false;
+
+ std::string output;
+ doc[0]["b"] >> output;
+ if(output != "c")
+ return false;
+
+ doc[1] >> output;
+ if(output != "b")
+ return false;
+
+ return true;
+ }
+
+ bool AliasAsSimpleKey()
+ {
+ std::string input = "- &a b\n- *a : c";
+
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ if(doc.size() != 2)
+ return false;
+
+ std::string output;
+ doc[0] >> output;
+ if(output != "b")
+ return false;
+
+ doc[1]["b"] >> output;
+ if(output != "c")
+ return false;
+
+ return true;
+ }
+
+ bool ExplicitDoc()
+ {
+ std::string input = "---\n- one\n- two";
+
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ if(doc.size() != 2)
+ return false;
+
+ std::string output;
+ doc[0] >> output;
+ if(output != "one")
+ return false;
+ doc[1] >> output;
+ if(output != "two")
+ return false;
+
+ return true;
+ }
+
+ bool MultipleDocs()
+ {
+ std::string input = "---\nname: doc1\n---\nname: doc2";
+
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ std::string output;
+ doc["name"] >> output;
+ if(output != "doc1")
+ return false;
+
+ if(!parser)
+ return false;
+
+ parser.GetNextDocument(doc);
+ doc["name"] >> output;
+ if(output != "doc2")
+ return false;
+
+ return true;
+ }
+
+ bool ExplicitEndDoc()
+ {
+ std::string input = "- one\n- two\n...\n...";
+
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ if(doc.size() != 2)
+ return false;
+
+ std::string output;
+ doc[0] >> output;
+ if(output != "one")
+ return false;
+ doc[1] >> output;
+ if(output != "two")
+ return false;
+
+ return true;
+ }
+
+ bool MultipleDocsWithSomeExplicitIndicators()
+ {
+ std::string input =
+ "- one\n- two\n...\n"
+ "---\nkey: value\n...\n...\n"
+ "- three\n- four\n"
+ "---\nkey: value";
+
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ std::string output;
+
+ parser.GetNextDocument(doc);
+ if(doc.size() != 2)
+ return false;
+ doc[0] >> output;
+ if(output != "one")
+ return false;
+ doc[1] >> output;
+ if(output != "two")
+ return false;
+
+ parser.GetNextDocument(doc);
+ doc["key"] >> output;
+ if(output != "value")
+ return false;
+
+ parser.GetNextDocument(doc);
+ if(doc.size() != 2)
+ return false;
+ doc[0] >> output;
+ if(output != "three")
+ return false;
+ doc[1] >> output;
+ if(output != "four")
+ return false;
+
+ parser.GetNextDocument(doc);
+ doc["key"] >> output;
+ if(output != "value")
+ return false;
+
+ return true;
+ }
+
+ bool BlockKeyWithNullValue()
+ {
+ std::string input =
+ "key:\n"
+ "just a key: value";
+
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+
+ parser.GetNextDocument(doc);
+ if(doc.size() != 2)
+ return false;
+ if(!IsNull(doc["key"]))
+ return false;
+ if(doc["just a key"].to<std::string>() != "value")
+ return false;
+
+ return true;
+ }
+
+ bool Bases()
+ {
+ std::string input =
+ "- 15\n"
+ "- 0x10\n"
+ "- 030\n"
+ "- 0xffffffff\n";
+
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+
+ parser.GetNextDocument(doc);
+ if(doc.size() != 4)
+ return false;
+ if(doc[0].to<int>() != 15)
+ return false;
+ if(doc[1].to<int>() != 0x10)
+ return false;
+ if(doc[2].to<int>() != 030)
+ return false;
+ if(doc[3].to<unsigned>() != 0xffffffff)
+ return false;
+ return true;
+ }
+
+ bool KeyNotFound()
+ {
+ std::string input = "key: value";
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ try {
+ doc["bad key"];
+ } catch(const YAML::Exception& e) {
+ if(e.msg != std::string(YAML::ErrorMsg::KEY_NOT_FOUND) + ": bad key")
+ throw;
+ }
+
+ try {
+ doc[5];
+ } catch(const YAML::Exception& e) {
+ if(e.msg != std::string(YAML::ErrorMsg::KEY_NOT_FOUND) + ": 5")
+ throw;
+ }
+
+ try {
+ doc[2.5];
+ } catch(const YAML::Exception& e) {
+ if(e.msg != std::string(YAML::ErrorMsg::KEY_NOT_FOUND) + ": 2.5")
+ throw;
+ }
+
+ return true;
+ }
+
+ bool DuplicateKey()
+ {
+ std::string input = "{a: 1, b: 2, c: 3, a: 4}";
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ if(doc["a"].to<int>() != 4)
+ return false;
+ if(doc["b"].to<int>() != 2)
+ return false;
+ if(doc["c"].to<int>() != 3)
+ return false;
+ return true;
+ }
+
+ void PrepareNodeForTagExam(YAML::Node& doc, const std::string& input)
+ {
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ parser.GetNextDocument(doc);
+ }
+
+ struct TagMismatch: public std::exception {
+ TagMismatch(const std::string& actualTag, const std::string& expectedTag) {
+ std::stringstream output;
+ output << "Tag has value \"" << actualTag << "\" but \"" << expectedTag << "\" was expected";
+ what_ = output.str();
+ }
+ virtual ~TagMismatch() throw() {}
+ virtual const char *what() const throw() { return what_.c_str(); }
+
+ private:
+ std::string what_;
+ };
+
+ bool ExpectedTagValue(YAML::Node& node, const char* tag)
+ {
+ if(node.Tag() == tag)
+ return true;
+
+ throw TagMismatch(node.Tag(), tag);
+ }
+
+ bool DefaultPlainScalarTag()
+ {
+ YAML::Node node;
+ PrepareNodeForTagExam(node, "--- 12");
+
+ return ExpectedTagValue(node, "?");
+ }
+
+ bool DefaultSingleQuotedScalarTag()
+ {
+ YAML::Node node;
+ PrepareNodeForTagExam(node, "--- '12'");
+
+ return ExpectedTagValue(node, "!");
+ }
+
+ bool ExplicitNonSpecificPlainScalarTag()
+ {
+ YAML::Node node;
+ PrepareNodeForTagExam(node, "--- ! 12");
+
+ return ExpectedTagValue(node, "!");
+ }
+
+ bool BasicLocalTag()
+ {
+ YAML::Node node;
+ PrepareNodeForTagExam(node, "--- !foo 12");
+
+ return ExpectedTagValue(node, "!foo");
+ }
+
+ bool VerbatimLocalTag()
+ {
+ YAML::Node node;
+ PrepareNodeForTagExam(node, "--- !<!foo> 12");
+
+ return ExpectedTagValue(node, "!foo");
+ }
+
+ bool StandardShortcutTag()
+ {
+ YAML::Node node;
+ PrepareNodeForTagExam(node, "--- !!int 12");
+
+ return ExpectedTagValue(node, "tag:yaml.org,2002:int");
+ }
+
+ bool VerbatimURITag()
+ {
+ YAML::Node node;
+ PrepareNodeForTagExam(node, "--- !<tag:yaml.org,2002:int> 12");
+
+ return ExpectedTagValue(node, "tag:yaml.org,2002:int");
+ }
+
+ bool DefaultSequenceTag()
+ {
+ YAML::Node node;
+ PrepareNodeForTagExam(node, "--- [12]");
+
+ return ExpectedTagValue(node, "?");
+ }
+
+ bool ExplicitNonSpecificSequenceTag()
+ {
+ YAML::Node node;
+ PrepareNodeForTagExam(node, "--- ! [12]");
+
+ return ExpectedTagValue(node, "!");
+ }
+
+ bool Infinity()
+ {
+ std::string input =
+ "- .inf\n"
+ "- .Inf\n"
+ "- .INF\n"
+ "- +.inf\n"
+ "- +.Inf\n"
+ "- +.INF\n"
+ "- -.inf\n"
+ "- -.Inf\n"
+ "- -.INF\n";
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ for(unsigned i=0;i<doc.size();i++)
+ if(doc[i].to<double>() != (i < 6 ? +1 : -1) * std::numeric_limits<double>::infinity())
+ return false;
+ for(unsigned i=0;i<doc.size();i++)
+ if(doc[i].to<long double>() != (i < 6 ? +1 : -1) * std::numeric_limits<long double>::infinity())
+ return false;
+ for(unsigned i=0;i<doc.size();i++)
+ if(doc[i].to<float>() != (i < 6 ? +1 : -1) * std::numeric_limits<float>::infinity())
+ return false;
+ return true;
+ }
+
+ bool NaN()
+ {
+ std::string input =
+ "- .nan\n"
+ "- .NaN\n"
+ "- .NAN\n";
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ for(unsigned i=0;i<doc.size();i++) {
+ double d;
+ doc[i] >> d;
+ if(d == d)
+ return false;
+ }
+ for(unsigned i=0;i<doc.size();i++) {
+ long double d;
+ doc[i] >> d;
+ if(d == d)
+ return false;
+ }
+ for(unsigned i=0;i<doc.size();i++) {
+ float d;
+ doc[i] >> d;
+ if(d == d)
+ return false;
+ }
+ return true;
+ }
+
+ bool NonConstKey()
+ {
+ std::string input = "{a: 1}";
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ std::vector<char> key(2);
+ key[0] = 'a';
+ key[1] = '\0';
+ if(doc[&key[0]].to<int>() != 1)
+ return false;
+ return true;
+ }
+
+ bool SingleChar()
+ {
+ std::string input = "5";
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ return doc.to<int>() == 5;
+ }
+
+ bool QuotedNewline()
+ {
+ std::string input = "foo: \"\\n\"";
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ return doc["foo"].to<std::string>() == "\n";
+ }
+
+ bool DoubleAsInt()
+ {
+ std::string input = "1.5";
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ try {
+ doc.to<int>();
+ } catch(const YAML::InvalidScalar& e) {
+ return true;
+ }
+
+ return false;
+ }
+
+ bool Binary()
+ {
+ std::string input = "[!!binary \"SGVsbG8sIFdvcmxkIQ==\", !!binary \"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4K\"]";
+ std::stringstream stream(input);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ if(doc[0].to<YAML::Binary>() != YAML::Binary(reinterpret_cast<const unsigned char*>("Hello, World!"), 13))
+ return false;
+ if(doc[1].to<YAML::Binary>() != YAML::Binary(reinterpret_cast<const unsigned char*>("Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.\n"), 270))
+ return false;
+ return true;
+ }
+ }
+
+ namespace {
+ void RunScalarParserTest(void (*test)(std::string&, std::string&), const std::string& name, int& passed, int& total) {
+ std::string error;
+ std::string inputScalar, desiredOutput;
+ std::string output;
+ bool ok = true;
+ try {
+ test(inputScalar, desiredOutput);
+ std::stringstream stream(inputScalar);
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+ doc >> output;
+ } catch(const YAML::Exception& e) {
+ ok = false;
+ error = e.what();
+ }
+ if(ok && output == desiredOutput) {
+ passed++;
+ } else {
+ std::cout << "Parser test failed: " << name << "\n";
+ if(error != "")
+ std::cout << "Caught exception: " << error << "\n";
+ else {
+ std::cout << "Output:\n" << output << "<<<\n";
+ std::cout << "Desired output:\n" << desiredOutput << "<<<\n";
+ }
+ }
+ total++;
+ }
+
+ void RunParserTest(bool (*test)(), const std::string& name, int& passed, int& total) {
+ std::string error;
+ bool ok = true;
+ try {
+ ok = test();
+ } catch(const YAML::Exception& e) {
+ ok = false;
+ error = e.what();
+ } catch(const Parser::TagMismatch& e) {
+ ok = false;
+ error = e.what();
+ }
+ if(ok) {
+ passed++;
+ } else {
+ std::cout << "Parser test failed: " << name << "\n";
+ if(error != "")
+ std::cout << " Caught exception: " << error << "\n";
+ }
+ total++;
+ }
+
+ typedef void (*EncodingFn)(std::ostream&, int);
+
+ inline char Byte(int ch)
+ {
+ return static_cast<char>(static_cast<unsigned char>(static_cast<unsigned int>(ch)));
+ }
+
+ void EncodeToUtf8(std::ostream& stream, int ch)
+ {
+ if (ch <= 0x7F)
+ {
+ stream << Byte(ch);
+ }
+ else if (ch <= 0x7FF)
+ {
+ stream << Byte(0xC0 | (ch >> 6));
+ stream << Byte(0x80 | (ch & 0x3F));
+ }
+ else if (ch <= 0xFFFF)
+ {
+ stream << Byte(0xE0 | (ch >> 12));
+ stream << Byte(0x80 | ((ch >> 6) & 0x3F));
+ stream << Byte(0x80 | (ch & 0x3F));
+ }
+ else if (ch <= 0x1FFFFF)
+ {
+ stream << Byte(0xF0 | (ch >> 18));
+ stream << Byte(0x80 | ((ch >> 12) & 0x3F));
+ stream << Byte(0x80 | ((ch >> 6) & 0x3F));
+ stream << Byte(0x80 | (ch & 0x3F));
+ }
+ }
+
+ bool SplitUtf16HighChar(std::ostream& stream, EncodingFn encoding, int ch)
+ {
+ int biasedValue = ch - 0x10000;
+ if (biasedValue < 0)
+ {
+ return false;
+ }
+ int high = 0xD800 | (biasedValue >> 10);
+ int low = 0xDC00 | (biasedValue & 0x3FF);
+ encoding(stream, high);
+ encoding(stream, low);
+ return true;
+ }
+
+ void EncodeToUtf16LE(std::ostream& stream, int ch)
+ {
+ if (!SplitUtf16HighChar(stream, &EncodeToUtf16LE, ch))
+ {
+ stream << Byte(ch & 0xFF) << Byte(ch >> 8);
+ }
+ }
+
+ void EncodeToUtf16BE(std::ostream& stream, int ch)
+ {
+ if (!SplitUtf16HighChar(stream, &EncodeToUtf16BE, ch))
+ {
+ stream << Byte(ch >> 8) << Byte(ch & 0xFF);
+ }
+ }
+
+ void EncodeToUtf32LE(std::ostream& stream, int ch)
+ {
+ stream << Byte(ch & 0xFF) << Byte((ch >> 8) & 0xFF)
+ << Byte((ch >> 16) & 0xFF) << Byte((ch >> 24) & 0xFF);
+ }
+
+ void EncodeToUtf32BE(std::ostream& stream, int ch)
+ {
+ stream << Byte((ch >> 24) & 0xFF) << Byte((ch >> 16) & 0xFF)
+ << Byte((ch >> 8) & 0xFF) << Byte(ch & 0xFF);
+ }
+
+ class EncodingTester
+ {
+ public:
+ EncodingTester(EncodingFn encoding, bool declareEncoding)
+ {
+ if (declareEncoding)
+ {
+ encoding(m_yaml, 0xFEFF);
+ }
+
+ AddEntry(encoding, 0x0021, 0x007E); // Basic Latin
+ AddEntry(encoding, 0x00A1, 0x00FF); // Latin-1 Supplement
+ AddEntry(encoding, 0x0660, 0x06FF); // Arabic (largest contiguous block)
+
+ // CJK unified ideographs (multiple lines)
+ AddEntry(encoding, 0x4E00, 0x4EFF);
+ AddEntry(encoding, 0x4F00, 0x4FFF);
+ AddEntry(encoding, 0x5000, 0x51FF); // 512 character line
+ AddEntry(encoding, 0x5200, 0x54FF); // 768 character line
+ AddEntry(encoding, 0x5500, 0x58FF); // 1024 character line
+
+ AddEntry(encoding, 0x103A0, 0x103C3); // Old Persian
+
+ m_yaml.seekg(0, std::ios::beg);
+ }
+
+ std::istream& stream() {return m_yaml;}
+ const std::vector<std::string>& entries() {return m_entries;}
+
+ private:
+ std::stringstream m_yaml;
+ std::vector<std::string> m_entries;
+
+ void AddEntry(EncodingFn encoding, int startCh, int endCh)
+ {
+ encoding(m_yaml, '-');
+ encoding(m_yaml, ' ');
+ encoding(m_yaml, '|');
+ encoding(m_yaml, '\n');
+ encoding(m_yaml, ' ');
+ encoding(m_yaml, ' ');
+
+ std::stringstream entry;
+ for (int ch = startCh; ch <= endCh; ++ch)
+ {
+ encoding(m_yaml, ch);
+ EncodeToUtf8(entry, ch);
+ }
+ encoding(m_yaml, '\n');
+
+ m_entries.push_back(entry.str());
+ }
+ };
+
+ void RunEncodingTest(EncodingFn encoding, bool declareEncoding, const std::string& name, int& passed, int& total)
+ {
+ EncodingTester tester(encoding, declareEncoding);
+ std::string error;
+ bool ok = true;
+ try {
+ YAML::Parser parser(tester.stream());
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+
+ YAML::Iterator itNode = doc.begin();
+ std::vector<std::string>::const_iterator itEntry = tester.entries().begin();
+ for (; (itNode != doc.end()) && (itEntry != tester.entries().end()); ++itNode, ++itEntry)
+ {
+ std::string stScalarValue;
+ if (!itNode->GetScalar(stScalarValue) && (stScalarValue == *itEntry))
+ {
+ break;
+ }
+ }
+
+ if ((itNode != doc.end()) || (itEntry != tester.entries().end()))
+ {
+ ok = false;
+ }
+ } catch(const YAML::Exception& e) {
+ ok = false;
+ error = e.msg;
+ }
+ if(ok) {
+ passed++;
+ } else {
+ std::cout << "Parser test failed: " << name << "\n";
+ if(error != "")
+ std::cout << " Caught exception: " << error << "\n";
+ }
+ total++;
+ }
+ }
+
+ bool RunParserTests()
+ {
+ int passed = 0;
+ int total = 0;
+ RunScalarParserTest(&Parser::SimpleScalar, "simple scalar", passed, total);
+ RunScalarParserTest(&Parser::MultiLineScalar, "multi-line scalar", passed, total);
+ RunScalarParserTest(&Parser::LiteralScalar, "literal scalar", passed, total);
+ RunScalarParserTest(&Parser::FoldedScalar, "folded scalar", passed, total);
+ RunScalarParserTest(&Parser::ChompedFoldedScalar, "chomped folded scalar", passed, total);
+ RunScalarParserTest(&Parser::ChompedLiteralScalar, "chomped literal scalar", passed, total);
+ RunScalarParserTest(&Parser::FoldedScalarWithIndent, "folded scalar with indent", passed, total);
+ RunScalarParserTest(&Parser::ColonScalar, "colon scalar", passed, total);
+ RunScalarParserTest(&Parser::QuotedScalar, "quoted scalar", passed, total);
+ RunScalarParserTest(&Parser::CommaScalar, "comma scalar", passed, total);
+ RunScalarParserTest(&Parser::DashScalar, "dash scalar", passed, total);
+ RunScalarParserTest(&Parser::URLScalar, "url scalar", passed, total);
+
+ RunParserTest(&Parser::SimpleSeq, "simple seq", passed, total);
+ RunParserTest(&Parser::SimpleMap, "simple map", passed, total);
+ RunParserTest(&Parser::FlowSeq, "flow seq", passed, total);
+ RunParserTest(&Parser::FlowMap, "flow map", passed, total);
+ RunParserTest(&Parser::FlowMapWithOmittedKey, "flow map with omitted key", passed, total);
+ RunParserTest(&Parser::FlowMapWithOmittedValue, "flow map with omitted value", passed, total);
+ RunParserTest(&Parser::FlowMapWithSoloEntry, "flow map with solo entry", passed, total);
+ RunParserTest(&Parser::FlowMapEndingWithSoloEntry, "flow map ending with solo entry", passed, total);
+ RunParserTest(&Parser::QuotedSimpleKeys, "quoted simple keys", passed, total);
+ RunParserTest(&Parser::CompressedMapAndSeq, "compressed map and seq", passed, total);
+ RunParserTest(&Parser::NullBlockSeqEntry, "null block seq entry", passed, total);
+ RunParserTest(&Parser::NullBlockMapKey, "null block map key", passed, total);
+ RunParserTest(&Parser::NullBlockMapValue, "null block map value", passed, total);
+ RunParserTest(&Parser::SimpleAlias, "simple alias", passed, total);
+ RunParserTest(&Parser::AliasWithNull, "alias with null", passed, total);
+ RunParserTest(&Parser::AnchorInSimpleKey, "anchor in simple key", passed, total);
+ RunParserTest(&Parser::AliasAsSimpleKey, "alias as simple key", passed, total);
+ RunParserTest(&Parser::ExplicitDoc, "explicit doc", passed, total);
+ RunParserTest(&Parser::MultipleDocs, "multiple docs", passed, total);
+ RunParserTest(&Parser::ExplicitEndDoc, "explicit end doc", passed, total);
+ RunParserTest(&Parser::MultipleDocsWithSomeExplicitIndicators, "multiple docs with some explicit indicators", passed, total);
+ RunParserTest(&Parser::BlockKeyWithNullValue, "block key with null value", passed, total);
+ RunParserTest(&Parser::Bases, "bases", passed, total);
+ RunParserTest(&Parser::KeyNotFound, "key not found", passed, total);
+ RunParserTest(&Parser::DuplicateKey, "duplicate key", passed, total);
+ RunParserTest(&Parser::DefaultPlainScalarTag, "default plain scalar tag", passed, total);
+ RunParserTest(&Parser::DefaultSingleQuotedScalarTag, "default single-quoted scalar tag", passed, total);
+ RunParserTest(&Parser::ExplicitNonSpecificPlainScalarTag, "explicit, non-specific plain scalar tag", passed, total);
+ RunParserTest(&Parser::BasicLocalTag, "basic local tag", passed, total);
+ RunParserTest(&Parser::VerbatimLocalTag, "verbatim local tag", passed, total);
+ RunParserTest(&Parser::StandardShortcutTag, "standard shortcut tag", passed, total);
+ RunParserTest(&Parser::VerbatimURITag, "verbatim URI tag", passed, total);
+ RunParserTest(&Parser::DefaultPlainScalarTag, "default plain scalar tag", passed, total);
+ RunParserTest(&Parser::DefaultSequenceTag, "default sequence tag", passed, total);
+ RunParserTest(&Parser::ExplicitNonSpecificSequenceTag, "explicit, non-specific sequence tag", passed, total);
+ RunParserTest(&Parser::Infinity, "infinity", passed, total);
+ RunParserTest(&Parser::NaN, "NaN", passed, total);
+ RunParserTest(&Parser::NonConstKey, "non const key", passed, total);
+ RunParserTest(&Parser::SingleChar, "single char", passed, total);
+ RunParserTest(&Parser::QuotedNewline, "quoted newline", passed, total);
+ RunParserTest(&Parser::DoubleAsInt, "double as int", passed, total);
+ RunParserTest(&Parser::Binary, "binary", passed, total);
+
+ RunEncodingTest(&EncodeToUtf8, false, "UTF-8, no BOM", passed, total);
+ RunEncodingTest(&EncodeToUtf8, true, "UTF-8 with BOM", passed, total);
+ RunEncodingTest(&EncodeToUtf16LE, false, "UTF-16LE, no BOM", passed, total);
+ RunEncodingTest(&EncodeToUtf16LE, true, "UTF-16LE with BOM", passed, total);
+ RunEncodingTest(&EncodeToUtf16BE, false, "UTF-16BE, no BOM", passed, total);
+ RunEncodingTest(&EncodeToUtf16BE, true, "UTF-16BE with BOM", passed, total);
+ RunEncodingTest(&EncodeToUtf32LE, false, "UTF-32LE, no BOM", passed, total);
+ RunEncodingTest(&EncodeToUtf32LE, true, "UTF-32LE with BOM", passed, total);
+ RunEncodingTest(&EncodeToUtf32BE, false, "UTF-32BE, no BOM", passed, total);
+ RunEncodingTest(&EncodeToUtf32BE, true, "UTF-32BE with BOM", passed, total);
+
+ std::cout << "Parser tests: " << passed << "/" << total << " passed\n";
+ return passed == total;
+ }
+}
+
diff --git a/external_libs/yaml-cpp/test/old-api/spectests.cpp b/external_libs/yaml-cpp/test/old-api/spectests.cpp
new file mode 100644
index 00000000..fb5505be
--- /dev/null
+++ b/external_libs/yaml-cpp/test/old-api/spectests.cpp
@@ -0,0 +1,1456 @@
+#include "spectests.h"
+#include "specexamples.h"
+#include "yaml-cpp/yaml.h"
+#include <fstream>
+#include <sstream>
+#include <vector>
+#include <iostream>
+
+#define YAML_ASSERT(cond) do { if(!(cond)) return " Assert failed: " #cond; } while(false)
+#define PARSE(doc, input) \
+ std::stringstream stream(input);\
+ YAML::Parser parser(stream);\
+ YAML::Node doc;\
+ parser.GetNextDocument(doc)
+#define PARSE_NEXT(doc) parser.GetNextDocument(doc)
+
+namespace Test {
+ namespace Spec {
+ // 2.1
+ TEST SeqScalars() {
+ PARSE(doc, ex2_1);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc[0].to<std::string>() == "Mark McGwire");
+ YAML_ASSERT(doc[1].to<std::string>() == "Sammy Sosa");
+ YAML_ASSERT(doc[2].to<std::string>() == "Ken Griffey");
+ return true;
+ }
+
+ // 2.2
+ TEST MappingScalarsToScalars() {
+ PARSE(doc, ex2_2);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc["hr"].to<std::string>() == "65");
+ YAML_ASSERT(doc["avg"].to<std::string>() == "0.278");
+ YAML_ASSERT(doc["rbi"].to<std::string>() == "147");
+ return true;
+ }
+
+ // 2.3
+ TEST MappingScalarsToSequences() {
+ PARSE(doc, ex2_3);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc["american"].size() == 3);
+ YAML_ASSERT(doc["american"][0].to<std::string>() == "Boston Red Sox");
+ YAML_ASSERT(doc["american"][1].to<std::string>() == "Detroit Tigers");
+ YAML_ASSERT(doc["american"][2].to<std::string>() == "New York Yankees");
+ YAML_ASSERT(doc["national"].size() == 3);
+ YAML_ASSERT(doc["national"][0].to<std::string>() == "New York Mets");
+ YAML_ASSERT(doc["national"][1].to<std::string>() == "Chicago Cubs");
+ YAML_ASSERT(doc["national"][2].to<std::string>() == "Atlanta Braves");
+ return true;
+ }
+
+ // 2.4
+ TEST SequenceOfMappings()
+ {
+ PARSE(doc, ex2_4);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc[0].size() == 3);
+ YAML_ASSERT(doc[0]["name"].to<std::string>() == "Mark McGwire");
+ YAML_ASSERT(doc[0]["hr"].to<std::string>() == "65");
+ YAML_ASSERT(doc[0]["avg"].to<std::string>() == "0.278");
+ YAML_ASSERT(doc[1].size() == 3);
+ YAML_ASSERT(doc[1]["name"].to<std::string>() == "Sammy Sosa");
+ YAML_ASSERT(doc[1]["hr"].to<std::string>() == "63");
+ YAML_ASSERT(doc[1]["avg"].to<std::string>() == "0.288");
+ return true;
+ }
+
+ // 2.5
+ TEST SequenceOfSequences()
+ {
+ PARSE(doc, ex2_5);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc[0].size() == 3);
+ YAML_ASSERT(doc[0][0].to<std::string>() == "name");
+ YAML_ASSERT(doc[0][1].to<std::string>() == "hr");
+ YAML_ASSERT(doc[0][2].to<std::string>() == "avg");
+ YAML_ASSERT(doc[1].size() == 3);
+ YAML_ASSERT(doc[1][0].to<std::string>() == "Mark McGwire");
+ YAML_ASSERT(doc[1][1].to<std::string>() == "65");
+ YAML_ASSERT(doc[1][2].to<std::string>() == "0.278");
+ YAML_ASSERT(doc[2].size() == 3);
+ YAML_ASSERT(doc[2][0].to<std::string>() == "Sammy Sosa");
+ YAML_ASSERT(doc[2][1].to<std::string>() == "63");
+ YAML_ASSERT(doc[2][2].to<std::string>() == "0.288");
+ return true;
+ }
+
+ // 2.6
+ TEST MappingOfMappings()
+ {
+ PARSE(doc, ex2_6);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc["Mark McGwire"].size() == 2);
+ YAML_ASSERT(doc["Mark McGwire"]["hr"].to<std::string>() == "65");
+ YAML_ASSERT(doc["Mark McGwire"]["avg"].to<std::string>() == "0.278");
+ YAML_ASSERT(doc["Sammy Sosa"].size() == 2);
+ YAML_ASSERT(doc["Sammy Sosa"]["hr"].to<std::string>() == "63");
+ YAML_ASSERT(doc["Sammy Sosa"]["avg"].to<std::string>() == "0.288");
+ return true;
+ }
+
+ // 2.7
+ TEST TwoDocumentsInAStream()
+ {
+ PARSE(doc, ex2_7);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc[0].to<std::string>() == "Mark McGwire");
+ YAML_ASSERT(doc[1].to<std::string>() == "Sammy Sosa");
+ YAML_ASSERT(doc[2].to<std::string>() == "Ken Griffey");
+
+ PARSE_NEXT(doc);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc[0].to<std::string>() == "Chicago Cubs");
+ YAML_ASSERT(doc[1].to<std::string>() == "St Louis Cardinals");
+ return true;
+ }
+
+ // 2.8
+ TEST PlayByPlayFeed()
+ {
+ PARSE(doc, ex2_8);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc["time"].to<std::string>() == "20:03:20");
+ YAML_ASSERT(doc["player"].to<std::string>() == "Sammy Sosa");
+ YAML_ASSERT(doc["action"].to<std::string>() == "strike (miss)");
+
+ PARSE_NEXT(doc);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc["time"].to<std::string>() == "20:03:47");
+ YAML_ASSERT(doc["player"].to<std::string>() == "Sammy Sosa");
+ YAML_ASSERT(doc["action"].to<std::string>() == "grand slam");
+ return true;
+ }
+
+ // 2.9
+ TEST SingleDocumentWithTwoComments()
+ {
+ PARSE(doc, ex2_9);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc["hr"].size() == 2);
+ YAML_ASSERT(doc["hr"][0].to<std::string>() == "Mark McGwire");
+ YAML_ASSERT(doc["hr"][1].to<std::string>() == "Sammy Sosa");
+ YAML_ASSERT(doc["rbi"].size() == 2);
+ YAML_ASSERT(doc["rbi"][0].to<std::string>() == "Sammy Sosa");
+ YAML_ASSERT(doc["rbi"][1].to<std::string>() == "Ken Griffey");
+ return true;
+ }
+
+ // 2.10
+ TEST SimpleAnchor()
+ {
+ PARSE(doc, ex2_10);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc["hr"].size() == 2);
+ YAML_ASSERT(doc["hr"][0].to<std::string>() == "Mark McGwire");
+ YAML_ASSERT(doc["hr"][1].to<std::string>() == "Sammy Sosa");
+ YAML_ASSERT(doc["rbi"].size() == 2);
+ YAML_ASSERT(doc["rbi"][0].to<std::string>() == "Sammy Sosa");
+ YAML_ASSERT(doc["rbi"][1].to<std::string>() == "Ken Griffey");
+ return true;
+ }
+
+ struct Pair {
+ Pair() {}
+ Pair(const std::string& f, const std::string& s): first(f), second(s) {}
+ std::string first, second;
+ };
+
+ bool operator == (const Pair& p, const Pair& q) {
+ return p.first == q.first && p.second == q.second;
+ }
+
+ void operator >> (const YAML::Node& node, Pair& p) {
+ node[0] >> p.first;
+ node[1] >> p.second;
+ }
+
+ // 2.11
+ TEST MappingBetweenSequences()
+ {
+ PARSE(doc, ex2_11);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc[Pair("Detroit Tigers", "Chicago cubs")].size() == 1);
+ YAML_ASSERT(doc[Pair("Detroit Tigers", "Chicago cubs")][0].to<std::string>() == "2001-07-23");
+ YAML_ASSERT(doc[Pair("New York Yankees", "Atlanta Braves")].size() == 3);
+ YAML_ASSERT(doc[Pair("New York Yankees", "Atlanta Braves")][0].to<std::string>() == "2001-07-02");
+ YAML_ASSERT(doc[Pair("New York Yankees", "Atlanta Braves")][1].to<std::string>() == "2001-08-12");
+ YAML_ASSERT(doc[Pair("New York Yankees", "Atlanta Braves")][2].to<std::string>() == "2001-08-14");
+ return true;
+ }
+
+ // 2.12
+ TEST CompactNestedMapping()
+ {
+ PARSE(doc, ex2_12);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc[0].size() == 2);
+ YAML_ASSERT(doc[0]["item"].to<std::string>() == "Super Hoop");
+ YAML_ASSERT(doc[0]["quantity"].to<int>() == 1);
+ YAML_ASSERT(doc[1].size() == 2);
+ YAML_ASSERT(doc[1]["item"].to<std::string>() == "Basketball");
+ YAML_ASSERT(doc[1]["quantity"].to<int>() == 4);
+ YAML_ASSERT(doc[2].size() == 2);
+ YAML_ASSERT(doc[2]["item"].to<std::string>() == "Big Shoes");
+ YAML_ASSERT(doc[2]["quantity"].to<int>() == 1);
+ return true;
+ }
+
+ // 2.13
+ TEST InLiteralsNewlinesArePreserved()
+ {
+ PARSE(doc, ex2_13);
+ YAML_ASSERT(doc.to<std::string>() ==
+ "\\//||\\/||\n"
+ "// || ||__");
+ return true;
+ }
+
+ // 2.14
+ TEST InFoldedScalarsNewlinesBecomeSpaces()
+ {
+ PARSE(doc, ex2_14);
+ YAML_ASSERT(doc.to<std::string>() == "Mark McGwire's year was crippled by a knee injury.");
+ return true;
+ }
+
+ // 2.15
+ TEST FoldedNewlinesArePreservedForMoreIndentedAndBlankLines()
+ {
+ PARSE(doc, ex2_15);
+ YAML_ASSERT(doc.to<std::string>() ==
+ "Sammy Sosa completed another fine season with great stats.\n\n"
+ " 63 Home Runs\n"
+ " 0.288 Batting Average\n\n"
+ "What a year!");
+ return true;
+ }
+
+ // 2.16
+ TEST IndentationDeterminesScope()
+ {
+ PARSE(doc, ex2_16);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc["name"].to<std::string>() == "Mark McGwire");
+ YAML_ASSERT(doc["accomplishment"].to<std::string>() == "Mark set a major league home run record in 1998.\n");
+ YAML_ASSERT(doc["stats"].to<std::string>() == "65 Home Runs\n0.278 Batting Average\n");
+ return true;
+ }
+
+ // 2.17
+ TEST QuotedScalars()
+ {
+ PARSE(doc, ex2_17);
+ YAML_ASSERT(doc.size() == 6);
+ YAML_ASSERT(doc["unicode"].to<std::string>() == "Sosa did fine.\xe2\x98\xba");
+ YAML_ASSERT(doc["control"].to<std::string>() == "\b1998\t1999\t2000\n");
+ YAML_ASSERT(doc["hex esc"].to<std::string>() == "\x0d\x0a is \r\n");
+ YAML_ASSERT(doc["single"].to<std::string>() == "\"Howdy!\" he cried.");
+ YAML_ASSERT(doc["quoted"].to<std::string>() == " # Not a 'comment'.");
+ YAML_ASSERT(doc["tie-fighter"].to<std::string>() == "|\\-*-/|");
+ return true;
+ }
+
+ // 2.18
+ TEST MultiLineFlowScalars()
+ {
+ PARSE(doc, ex2_18);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc["plain"].to<std::string>() == "This unquoted scalar spans many lines.");
+ YAML_ASSERT(doc["quoted"].to<std::string>() == "So does this quoted scalar.\n");
+ return true;
+ }
+
+ // TODO: 2.19 - 2.22 schema tags
+
+ // 2.23
+ TEST VariousExplicitTags()
+ {
+ PARSE(doc, ex2_23);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc["not-date"].Tag() == "tag:yaml.org,2002:str");
+ YAML_ASSERT(doc["not-date"].to<std::string>() == "2002-04-28");
+ YAML_ASSERT(doc["picture"].Tag() == "tag:yaml.org,2002:binary");
+ YAML_ASSERT(doc["picture"].to<std::string>() ==
+ "R0lGODlhDAAMAIQAAP//9/X\n"
+ "17unp5WZmZgAAAOfn515eXv\n"
+ "Pz7Y6OjuDg4J+fn5OTk6enp\n"
+ "56enmleECcgggoBADs=\n"
+ );
+ YAML_ASSERT(doc["application specific tag"].Tag() == "!something");
+ YAML_ASSERT(doc["application specific tag"].to<std::string>() ==
+ "The semantics of the tag\n"
+ "above may be different for\n"
+ "different documents."
+ );
+ return true;
+ }
+
+ // 2.24
+ TEST GlobalTags()
+ {
+ PARSE(doc, ex2_24);
+ YAML_ASSERT(doc.Tag() == "tag:clarkevans.com,2002:shape");
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc[0].Tag() == "tag:clarkevans.com,2002:circle");
+ YAML_ASSERT(doc[0].size() == 2);
+ YAML_ASSERT(doc[0]["center"].size() == 2);
+ YAML_ASSERT(doc[0]["center"]["x"].to<int>() == 73);
+ YAML_ASSERT(doc[0]["center"]["y"].to<int>() == 129);
+ YAML_ASSERT(doc[0]["radius"].to<int>() == 7);
+ YAML_ASSERT(doc[1].Tag() == "tag:clarkevans.com,2002:line");
+ YAML_ASSERT(doc[1].size() == 2);
+ YAML_ASSERT(doc[1]["start"].size() == 2);
+ YAML_ASSERT(doc[1]["start"]["x"].to<int>() == 73);
+ YAML_ASSERT(doc[1]["start"]["y"].to<int>() == 129);
+ YAML_ASSERT(doc[1]["finish"].size() == 2);
+ YAML_ASSERT(doc[1]["finish"]["x"].to<int>() == 89);
+ YAML_ASSERT(doc[1]["finish"]["y"].to<int>() == 102);
+ YAML_ASSERT(doc[2].Tag() == "tag:clarkevans.com,2002:label");
+ YAML_ASSERT(doc[2].size() == 3);
+ YAML_ASSERT(doc[2]["start"].size() == 2);
+ YAML_ASSERT(doc[2]["start"]["x"].to<int>() == 73);
+ YAML_ASSERT(doc[2]["start"]["y"].to<int>() == 129);
+ YAML_ASSERT(doc[2]["color"].to<std::string>() == "0xFFEEBB");
+ YAML_ASSERT(doc[2]["text"].to<std::string>() == "Pretty vector drawing.");
+ return true;
+ }
+
+ // 2.25
+ TEST UnorderedSets()
+ {
+ PARSE(doc, ex2_25);
+ YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:set");
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(IsNull(doc["Mark McGwire"]));
+ YAML_ASSERT(IsNull(doc["Sammy Sosa"]));
+ YAML_ASSERT(IsNull(doc["Ken Griffey"]));
+ return true;
+ }
+
+ // 2.26
+ TEST OrderedMappings()
+ {
+ PARSE(doc, ex2_26);
+ YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:omap");
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc[0].size() == 1);
+ YAML_ASSERT(doc[0]["Mark McGwire"].to<int>() == 65);
+ YAML_ASSERT(doc[1].size() == 1);
+ YAML_ASSERT(doc[1]["Sammy Sosa"].to<int>() == 63);
+ YAML_ASSERT(doc[2].size() == 1);
+ YAML_ASSERT(doc[2]["Ken Griffey"].to<int>() == 58);
+ return true;
+ }
+
+ // 2.27
+ TEST Invoice()
+ {
+ PARSE(doc, ex2_27);
+ YAML_ASSERT(doc.Tag() == "tag:clarkevans.com,2002:invoice");
+ YAML_ASSERT(doc.size() == 8);
+ YAML_ASSERT(doc["invoice"].to<int>() == 34843);
+ YAML_ASSERT(doc["date"].to<std::string>() == "2001-01-23");
+ YAML_ASSERT(doc["bill-to"].size() == 3);
+ YAML_ASSERT(doc["bill-to"]["given"].to<std::string>() == "Chris");
+ YAML_ASSERT(doc["bill-to"]["family"].to<std::string>() == "Dumars");
+ YAML_ASSERT(doc["bill-to"]["address"].size() == 4);
+ YAML_ASSERT(doc["bill-to"]["address"]["lines"].to<std::string>() == "458 Walkman Dr.\nSuite #292\n");
+ YAML_ASSERT(doc["bill-to"]["address"]["city"].to<std::string>() == "Royal Oak");
+ YAML_ASSERT(doc["bill-to"]["address"]["state"].to<std::string>() == "MI");
+ YAML_ASSERT(doc["bill-to"]["address"]["postal"].to<std::string>() == "48046");
+ YAML_ASSERT(doc["ship-to"].size() == 3);
+ YAML_ASSERT(doc["ship-to"]["given"].to<std::string>() == "Chris");
+ YAML_ASSERT(doc["ship-to"]["family"].to<std::string>() == "Dumars");
+ YAML_ASSERT(doc["ship-to"]["address"].size() == 4);
+ YAML_ASSERT(doc["ship-to"]["address"]["lines"].to<std::string>() == "458 Walkman Dr.\nSuite #292\n");
+ YAML_ASSERT(doc["ship-to"]["address"]["city"].to<std::string>() == "Royal Oak");
+ YAML_ASSERT(doc["ship-to"]["address"]["state"].to<std::string>() == "MI");
+ YAML_ASSERT(doc["ship-to"]["address"]["postal"].to<std::string>() == "48046");
+ YAML_ASSERT(doc["product"].size() == 2);
+ YAML_ASSERT(doc["product"][0].size() == 4);
+ YAML_ASSERT(doc["product"][0]["sku"].to<std::string>() == "BL394D");
+ YAML_ASSERT(doc["product"][0]["quantity"].to<int>() == 4);
+ YAML_ASSERT(doc["product"][0]["description"].to<std::string>() == "Basketball");
+ YAML_ASSERT(doc["product"][0]["price"].to<std::string>() == "450.00");
+ YAML_ASSERT(doc["product"][1].size() == 4);
+ YAML_ASSERT(doc["product"][1]["sku"].to<std::string>() == "BL4438H");
+ YAML_ASSERT(doc["product"][1]["quantity"].to<int>() == 1);
+ YAML_ASSERT(doc["product"][1]["description"].to<std::string>() == "Super Hoop");
+ YAML_ASSERT(doc["product"][1]["price"].to<std::string>() == "2392.00");
+ YAML_ASSERT(doc["tax"].to<std::string>() == "251.42");
+ YAML_ASSERT(doc["total"].to<std::string>() == "4443.52");
+ YAML_ASSERT(doc["comments"].to<std::string>() == "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.");
+ return true;
+ }
+
+ // 2.28
+ TEST LogFile()
+ {
+ PARSE(doc, ex2_28);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc["Time"].to<std::string>() == "2001-11-23 15:01:42 -5");
+ YAML_ASSERT(doc["User"].to<std::string>() == "ed");
+ YAML_ASSERT(doc["Warning"].to<std::string>() == "This is an error message for the log file");
+
+ PARSE_NEXT(doc);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc["Time"].to<std::string>() == "2001-11-23 15:02:31 -5");
+ YAML_ASSERT(doc["User"].to<std::string>() == "ed");
+ YAML_ASSERT(doc["Warning"].to<std::string>() == "A slightly different error message.");
+
+ PARSE_NEXT(doc);
+ YAML_ASSERT(doc.size() == 4);
+ YAML_ASSERT(doc["Date"].to<std::string>() == "2001-11-23 15:03:17 -5");
+ YAML_ASSERT(doc["User"].to<std::string>() == "ed");
+ YAML_ASSERT(doc["Fatal"].to<std::string>() == "Unknown variable \"bar\"");
+ YAML_ASSERT(doc["Stack"].size() == 2);
+ YAML_ASSERT(doc["Stack"][0].size() == 3);
+ YAML_ASSERT(doc["Stack"][0]["file"].to<std::string>() == "TopClass.py");
+ YAML_ASSERT(doc["Stack"][0]["line"].to<std::string>() == "23");
+ YAML_ASSERT(doc["Stack"][0]["code"].to<std::string>() == "x = MoreObject(\"345\\n\")\n");
+ YAML_ASSERT(doc["Stack"][1].size() == 3);
+ YAML_ASSERT(doc["Stack"][1]["file"].to<std::string>() == "MoreClass.py");
+ YAML_ASSERT(doc["Stack"][1]["line"].to<std::string>() == "58");
+ YAML_ASSERT(doc["Stack"][1]["code"].to<std::string>() == "foo = bar");
+ return true;
+ }
+
+ // TODO: 5.1 - 5.2 BOM
+
+ // 5.3
+ TEST BlockStructureIndicators()
+ {
+ PARSE(doc, ex5_3);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc["sequence"].size() == 2);
+ YAML_ASSERT(doc["sequence"][0].to<std::string>() == "one");
+ YAML_ASSERT(doc["sequence"][1].to<std::string>() == "two");
+ YAML_ASSERT(doc["mapping"].size() == 2);
+ YAML_ASSERT(doc["mapping"]["sky"].to<std::string>() == "blue");
+ YAML_ASSERT(doc["mapping"]["sea"].to<std::string>() == "green");
+ return true;
+ }
+
+ // 5.4
+ TEST FlowStructureIndicators()
+ {
+ PARSE(doc, ex5_4);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc["sequence"].size() == 2);
+ YAML_ASSERT(doc["sequence"][0].to<std::string>() == "one");
+ YAML_ASSERT(doc["sequence"][1].to<std::string>() == "two");
+ YAML_ASSERT(doc["mapping"].size() == 2);
+ YAML_ASSERT(doc["mapping"]["sky"].to<std::string>() == "blue");
+ YAML_ASSERT(doc["mapping"]["sea"].to<std::string>() == "green");
+ return true;
+ }
+
+ // 5.5
+ TEST CommentIndicator()
+ {
+ PARSE(doc, ex5_5);
+ YAML_ASSERT(doc.size() == 0);
+ return true;
+ }
+
+ // 5.6
+ TEST NodePropertyIndicators()
+ {
+ PARSE(doc, ex5_6);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc["anchored"].to<std::string>() == "value"); // TODO: assert tag
+ YAML_ASSERT(doc["alias"].to<std::string>() == "value");
+ return true;
+ }
+
+ // 5.7
+ TEST BlockScalarIndicators()
+ {
+ PARSE(doc, ex5_7);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc["literal"].to<std::string>() == "some\ntext\n");
+ YAML_ASSERT(doc["folded"].to<std::string>() == "some text\n");
+ return true;
+ }
+
+ // 5.8
+ TEST QuotedScalarIndicators()
+ {
+ PARSE(doc, ex5_8);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc["single"].to<std::string>() == "text");
+ YAML_ASSERT(doc["double"].to<std::string>() == "text");
+ return true;
+ }
+
+ // TODO: 5.9 directive
+ // TODO: 5.10 reserved indicator
+
+ // 5.11
+ TEST LineBreakCharacters()
+ {
+ PARSE(doc, ex5_11);
+ YAML_ASSERT(doc.to<std::string>() == "Line break (no glyph)\nLine break (glyphed)\n");
+ return true;
+ }
+
+ // 5.12
+ TEST TabsAndSpaces()
+ {
+ PARSE(doc, ex5_12);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc["quoted"].to<std::string>() == "Quoted\t");
+ YAML_ASSERT(doc["block"].to<std::string>() ==
+ "void main() {\n"
+ "\tprintf(\"Hello, world!\\n\");\n"
+ "}");
+ return true;
+ }
+
+ // 5.13
+ TEST EscapedCharacters()
+ {
+ PARSE(doc, ex5_13);
+ YAML_ASSERT(doc.to<std::string>() == "Fun with \x5C \x22 \x07 \x08 \x1B \x0C \x0A \x0D \x09 \x0B " + std::string("\x00", 1) + " \x20 \xA0 \x85 \xe2\x80\xa8 \xe2\x80\xa9 A A A");
+ return true;
+ }
+
+ // 5.14
+ TEST InvalidEscapedCharacters()
+ {
+ std::stringstream stream(ex5_14);
+ try {
+ YAML::Parser parser(stream);
+ YAML::Node doc;
+ parser.GetNextDocument(doc);
+ } catch(const YAML::ParserException& e) {
+ YAML_ASSERT(e.msg == std::string(YAML::ErrorMsg::INVALID_ESCAPE) + "c");
+ return true;
+ }
+
+ return false;
+ }
+
+ // 6.1
+ TEST IndentationSpaces()
+ {
+ PARSE(doc, ex6_1);
+ YAML_ASSERT(doc.size() == 1);
+ YAML_ASSERT(doc["Not indented"].size() == 2);
+ YAML_ASSERT(doc["Not indented"]["By one space"].to<std::string>() == "By four\n spaces\n");
+ YAML_ASSERT(doc["Not indented"]["Flow style"].size() == 3);
+ YAML_ASSERT(doc["Not indented"]["Flow style"][0].to<std::string>() == "By two");
+ YAML_ASSERT(doc["Not indented"]["Flow style"][1].to<std::string>() == "Also by two");
+ YAML_ASSERT(doc["Not indented"]["Flow style"][2].to<std::string>() == "Still by two");
+ return true;
+ }
+
+ // 6.2
+ TEST IndentationIndicators()
+ {
+ PARSE(doc, ex6_2);
+ YAML_ASSERT(doc.size() == 1);
+ YAML_ASSERT(doc["a"].size() == 2);
+ YAML_ASSERT(doc["a"][0].to<std::string>() == "b");
+ YAML_ASSERT(doc["a"][1].size() == 2);
+ YAML_ASSERT(doc["a"][1][0].to<std::string>() == "c");
+ YAML_ASSERT(doc["a"][1][1].to<std::string>() == "d");
+ return true;
+ }
+
+ // 6.3
+ TEST SeparationSpaces()
+ {
+ PARSE(doc, ex6_3);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc[0].size() == 1);
+ YAML_ASSERT(doc[0]["foo"].to<std::string>() == "bar");
+ YAML_ASSERT(doc[1].size() == 2);
+ YAML_ASSERT(doc[1][0].to<std::string>() == "baz");
+ YAML_ASSERT(doc[1][1].to<std::string>() == "baz");
+ return true;
+ }
+
+ // 6.4
+ TEST LinePrefixes()
+ {
+ PARSE(doc, ex6_4);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc["plain"].to<std::string>() == "text lines");
+ YAML_ASSERT(doc["quoted"].to<std::string>() == "text lines");
+ YAML_ASSERT(doc["block"].to<std::string>() == "text\n \tlines\n");
+ return true;
+ }
+
+ // 6.5
+ TEST EmptyLines()
+ {
+ PARSE(doc, ex6_5);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc["Folding"].to<std::string>() == "Empty line\nas a line feed");
+ YAML_ASSERT(doc["Chomping"].to<std::string>() == "Clipped empty lines\n");
+ return true;
+ }
+
+ // 6.6
+ TEST LineFolding()
+ {
+ PARSE(doc, ex6_6);
+ YAML_ASSERT(doc.to<std::string>() == "trimmed\n\n\nas space");
+ return true;
+ }
+
+ // 6.7
+ TEST BlockFolding()
+ {
+ PARSE(doc, ex6_7);
+ YAML_ASSERT(doc.to<std::string>() == "foo \n\n\t bar\n\nbaz\n");
+ return true;
+ }
+
+ // 6.8
+ TEST FlowFolding()
+ {
+ PARSE(doc, ex6_8);
+ YAML_ASSERT(doc.to<std::string>() == " foo\nbar\nbaz ");
+ return true;
+ }
+
+ // 6.9
+ TEST SeparatedComment()
+ {
+ PARSE(doc, ex6_9);
+ YAML_ASSERT(doc.size() == 1);
+ YAML_ASSERT(doc["key"].to<std::string>() == "value");
+ return true;
+ }
+
+ // 6.10
+ TEST CommentLines()
+ {
+ PARSE(doc, ex6_10);
+ YAML_ASSERT(doc.size() == 0);
+ return true;
+ }
+
+ // 6.11
+ TEST MultiLineComments()
+ {
+ PARSE(doc, ex6_11);
+ YAML_ASSERT(doc.size() == 1);
+ YAML_ASSERT(doc["key"].to<std::string>() == "value");
+ return true;
+ }
+
+ struct StringMap {
+ typedef std::map<std::string, std::string> Map;
+ Map _;
+ };
+
+ bool operator == (const StringMap& m, const StringMap& n) {
+ return m._ == n._;
+ }
+
+ void operator >> (const YAML::Node& node, StringMap& m) {
+ m._.clear();
+ for(YAML::Iterator it=node.begin();it!=node.end();++it) {
+ std::string key = it.first().to<std::string>();
+ std::string value = it.second().to<std::string>();
+ m._[key] = value;
+ }
+ }
+
+
+ // 6.12
+ TEST SeparationSpacesII()
+ {
+ PARSE(doc, ex6_12);
+ std::map<std::string, std::string> key;
+ key["first"] = "Sammy";
+ key["last"] = "Sosa";
+ YAML_ASSERT(doc.size() == 1);
+ YAML_ASSERT(doc[key].size() == 2);
+ YAML_ASSERT(doc[key]["hr"].to<int>() == 65);
+ YAML_ASSERT(doc[key]["avg"].to<std::string>() == "0.278");
+ return true;
+ }
+
+ // 6.13
+ TEST ReservedDirectives()
+ {
+ PARSE(doc, ex6_13);
+ return true;
+ }
+
+ // 6.14
+ TEST YAMLDirective()
+ {
+ PARSE(doc, ex6_14);
+ return true;
+ }
+
+ // 6.15
+ TEST InvalidRepeatedYAMLDirective()
+ {
+ try {
+ PARSE(doc, ex6_15);
+ } catch(const YAML::ParserException& e) {
+ if(e.msg == YAML::ErrorMsg::REPEATED_YAML_DIRECTIVE)
+ return true;
+
+ throw;
+ }
+
+ return " No exception was thrown";
+ }
+
+ // 6.16
+ TEST TagDirective()
+ {
+ PARSE(doc, ex6_16);
+ YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:str");
+ YAML_ASSERT(doc.to<std::string>() == "foo");
+ return true;
+ }
+
+ // 6.17
+ TEST InvalidRepeatedTagDirective()
+ {
+ try {
+ PARSE(doc, ex6_17);
+ } catch(const YAML::ParserException& e) {
+ if(e.msg == YAML::ErrorMsg::REPEATED_TAG_DIRECTIVE)
+ return true;
+
+ throw;
+ }
+
+ return " No exception was thrown";
+ }
+
+ // 6.18
+ TEST PrimaryTagHandle()
+ {
+ PARSE(doc, ex6_18);
+ YAML_ASSERT(doc.Tag() == "!foo");
+ YAML_ASSERT(doc.to<std::string>() == "bar");
+
+ PARSE_NEXT(doc);
+ YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo");
+ YAML_ASSERT(doc.to<std::string>() == "bar");
+ return true;
+ }
+
+ // 6.19
+ TEST SecondaryTagHandle()
+ {
+ PARSE(doc, ex6_19);
+ YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/int");
+ YAML_ASSERT(doc.to<std::string>() == "1 - 3");
+ return true;
+ }
+
+ // 6.20
+ TEST TagHandles()
+ {
+ PARSE(doc, ex6_20);
+ YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo");
+ YAML_ASSERT(doc.to<std::string>() == "bar");
+ return true;
+ }
+
+ // 6.21
+ TEST LocalTagPrefix()
+ {
+ PARSE(doc, ex6_21);
+ YAML_ASSERT(doc.Tag() == "!my-light");
+ YAML_ASSERT(doc.to<std::string>() == "fluorescent");
+
+ PARSE_NEXT(doc);
+ YAML_ASSERT(doc.Tag() == "!my-light");
+ YAML_ASSERT(doc.to<std::string>() == "green");
+ return true;
+ }
+
+ // 6.22
+ TEST GlobalTagPrefix()
+ {
+ PARSE(doc, ex6_22);
+ YAML_ASSERT(doc.size() == 1);
+ YAML_ASSERT(doc[0].Tag() == "tag:example.com,2000:app/foo");
+ YAML_ASSERT(doc[0].to<std::string>() == "bar");
+ return true;
+ }
+
+ // 6.23
+ TEST NodeProperties()
+ {
+ PARSE(doc, ex6_23);
+ YAML_ASSERT(doc.size() == 2);
+ for(YAML::Iterator it=doc.begin();it!=doc.end();++it) {
+ if(it.first().to<std::string>() == "foo") {
+ YAML_ASSERT(it.first().Tag() == "tag:yaml.org,2002:str");
+ YAML_ASSERT(it.second().Tag() == "tag:yaml.org,2002:str");
+ YAML_ASSERT(it.second().to<std::string>() == "bar");
+ } else if(it.first().to<std::string>() == "baz") {
+ YAML_ASSERT(it.second().to<std::string>() == "foo");
+ } else
+ return " unknown key";
+ }
+
+ return true;
+ }
+
+ // 6.24
+ TEST VerbatimTags()
+ {
+ PARSE(doc, ex6_24);
+ YAML_ASSERT(doc.size() == 1);
+ for(YAML::Iterator it=doc.begin();it!=doc.end();++it) {
+ YAML_ASSERT(it.first().Tag() == "tag:yaml.org,2002:str");
+ YAML_ASSERT(it.first().to<std::string>() == "foo");
+ YAML_ASSERT(it.second().Tag() == "!bar");
+ YAML_ASSERT(it.second().to<std::string>() == "baz");
+ }
+ return true;
+ }
+
+ // 6.25
+ TEST InvalidVerbatimTags()
+ {
+ PARSE(doc, ex6_25);
+ return " not implemented yet"; // TODO: check tags (but we probably will say these are valid, I think)
+ }
+
+ // 6.26
+ TEST TagShorthands()
+ {
+ PARSE(doc, ex6_26);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc[0].Tag() == "!local");
+ YAML_ASSERT(doc[0].to<std::string>() == "foo");
+ YAML_ASSERT(doc[1].Tag() == "tag:yaml.org,2002:str");
+ YAML_ASSERT(doc[1].to<std::string>() == "bar");
+ YAML_ASSERT(doc[2].Tag() == "tag:example.com,2000:app/tag%21");
+ YAML_ASSERT(doc[2].to<std::string>() == "baz");
+ return true;
+ }
+
+ // 6.27
+ TEST InvalidTagShorthands()
+ {
+ bool threw = false;
+ try {
+ PARSE(doc, ex6_27a);
+ } catch(const YAML::ParserException& e) {
+ threw = true;
+ if(e.msg != YAML::ErrorMsg::TAG_WITH_NO_SUFFIX)
+ throw;
+ }
+
+ if(!threw)
+ return " No exception was thrown for a tag with no suffix";
+
+ PARSE(doc, ex6_27b); // TODO: should we reject this one (since !h! is not declared)?
+ return " not implemented yet";
+ }
+
+ // 6.28
+ TEST NonSpecificTags()
+ {
+ PARSE(doc, ex6_28);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc[0].to<std::string>() == "12"); // TODO: check tags. How?
+ YAML_ASSERT(doc[1].to<int>() == 12);
+ YAML_ASSERT(doc[2].to<std::string>() == "12");
+ return true;
+ }
+
+ // 6.29
+ TEST NodeAnchors()
+ {
+ PARSE(doc, ex6_29);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc["First occurrence"].to<std::string>() == "Value");
+ YAML_ASSERT(doc["Second occurrence"].to<std::string>() == "Value");
+ return true;
+ }
+
+ // 7.1
+ TEST AliasNodes()
+ {
+ PARSE(doc, ex7_1);
+ YAML_ASSERT(doc.size() == 4);
+ YAML_ASSERT(doc["First occurrence"].to<std::string>() == "Foo");
+ YAML_ASSERT(doc["Second occurrence"].to<std::string>() == "Foo");
+ YAML_ASSERT(doc["Override anchor"].to<std::string>() == "Bar");
+ YAML_ASSERT(doc["Reuse anchor"].to<std::string>() == "Bar");
+ return true;
+ }
+
+ // 7.2
+ TEST EmptyNodes()
+ {
+ PARSE(doc, ex7_2);
+ YAML_ASSERT(doc.size() == 2);
+ for(YAML::Iterator it=doc.begin();it!=doc.end();++it) {
+ if(it.first().to<std::string>() == "foo") {
+ YAML_ASSERT(it.second().Tag() == "tag:yaml.org,2002:str");
+ YAML_ASSERT(it.second().to<std::string>() == "");
+ } else if(it.first().to<std::string>() == "") {
+ YAML_ASSERT(it.first().Tag() == "tag:yaml.org,2002:str");
+ YAML_ASSERT(it.second().to<std::string>() == "bar");
+ } else
+ return " unexpected key";
+ }
+ return true;
+ }
+
+ // 7.3
+ TEST CompletelyEmptyNodes()
+ {
+ PARSE(doc, ex7_3);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(IsNull(doc["foo"]));
+ YAML_ASSERT(doc[YAML::Null].to<std::string>() == "bar");
+ return true;
+ }
+
+ // 7.4
+ TEST DoubleQuotedImplicitKeys()
+ {
+ PARSE(doc, ex7_4);
+ YAML_ASSERT(doc.size() == 1);
+ YAML_ASSERT(doc["implicit block key"].size() == 1);
+ YAML_ASSERT(doc["implicit block key"][0].size() == 1);
+ YAML_ASSERT(doc["implicit block key"][0]["implicit flow key"].to<std::string>() == "value");
+ return true;
+ }
+
+ // 7.5
+ TEST DoubleQuotedLineBreaks()
+ {
+ PARSE(doc, ex7_5);
+ YAML_ASSERT(doc.to<std::string>() == "folded to a space,\nto a line feed, or \t \tnon-content");
+ return true;
+ }
+
+ // 7.6
+ TEST DoubleQuotedLines()
+ {
+ PARSE(doc, ex7_6);
+ YAML_ASSERT(doc.to<std::string>() == " 1st non-empty\n2nd non-empty 3rd non-empty ");
+ return true;
+ }
+
+ // 7.7
+ TEST SingleQuotedCharacters()
+ {
+ PARSE(doc, ex7_7);
+ YAML_ASSERT(doc.to<std::string>() == "here's to \"quotes\"");
+ return true;
+ }
+
+ // 7.8
+ TEST SingleQuotedImplicitKeys()
+ {
+ PARSE(doc, ex7_8);
+ YAML_ASSERT(doc.size() == 1);
+ YAML_ASSERT(doc["implicit block key"].size() == 1);
+ YAML_ASSERT(doc["implicit block key"][0].size() == 1);
+ YAML_ASSERT(doc["implicit block key"][0]["implicit flow key"].to<std::string>() == "value");
+ return true;
+ }
+
+ // 7.9
+ TEST SingleQuotedLines()
+ {
+ PARSE(doc, ex7_9);
+ YAML_ASSERT(doc.to<std::string>() == " 1st non-empty\n2nd non-empty 3rd non-empty ");
+ return true;
+ }
+
+ // 7.10
+ TEST PlainCharacters()
+ {
+ PARSE(doc, ex7_10);
+ YAML_ASSERT(doc.size() == 6);
+ YAML_ASSERT(doc[0].to<std::string>() == "::vector");
+ YAML_ASSERT(doc[1].to<std::string>() == ": - ()");
+ YAML_ASSERT(doc[2].to<std::string>() == "Up, up, and away!");
+ YAML_ASSERT(doc[3].to<int>() == -123);
+ YAML_ASSERT(doc[4].to<std::string>() == "http://example.com/foo#bar");
+ YAML_ASSERT(doc[5].size() == 5);
+ YAML_ASSERT(doc[5][0].to<std::string>() == "::vector");
+ YAML_ASSERT(doc[5][1].to<std::string>() == ": - ()");
+ YAML_ASSERT(doc[5][2].to<std::string>() == "Up, up, and away!");
+ YAML_ASSERT(doc[5][3].to<int>() == -123);
+ YAML_ASSERT(doc[5][4].to<std::string>() == "http://example.com/foo#bar");
+ return true;
+ }
+
+ // 7.11
+ TEST PlainImplicitKeys()
+ {
+ PARSE(doc, ex7_11);
+ YAML_ASSERT(doc.size() == 1);
+ YAML_ASSERT(doc["implicit block key"].size() == 1);
+ YAML_ASSERT(doc["implicit block key"][0].size() == 1);
+ YAML_ASSERT(doc["implicit block key"][0]["implicit flow key"].to<std::string>() == "value");
+ return true;
+ }
+
+ // 7.12
+ TEST PlainLines()
+ {
+ PARSE(doc, ex7_12);
+ YAML_ASSERT(doc.to<std::string>() == "1st non-empty\n2nd non-empty 3rd non-empty");
+ return true;
+ }
+
+ // 7.13
+ TEST FlowSequence()
+ {
+ PARSE(doc, ex7_13);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc[0].size() == 2);
+ YAML_ASSERT(doc[0][0].to<std::string>() == "one");
+ YAML_ASSERT(doc[0][1].to<std::string>() == "two");
+ YAML_ASSERT(doc[1].size() == 2);
+ YAML_ASSERT(doc[1][0].to<std::string>() == "three");
+ YAML_ASSERT(doc[1][1].to<std::string>() == "four");
+ return true;
+ }
+
+ // 7.14
+ TEST FlowSequenceEntries()
+ {
+ PARSE(doc, ex7_14);
+ YAML_ASSERT(doc.size() == 5);
+ YAML_ASSERT(doc[0].to<std::string>() == "double quoted");
+ YAML_ASSERT(doc[1].to<std::string>() == "single quoted");
+ YAML_ASSERT(doc[2].to<std::string>() == "plain text");
+ YAML_ASSERT(doc[3].size() == 1);
+ YAML_ASSERT(doc[3][0].to<std::string>() == "nested");
+ YAML_ASSERT(doc[4].size() == 1);
+ YAML_ASSERT(doc[4]["single"].to<std::string>() == "pair");
+ return true;
+ }
+
+ // 7.15
+ TEST FlowMappings()
+ {
+ PARSE(doc, ex7_15);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc[0].size() == 2);
+ YAML_ASSERT(doc[0]["one"].to<std::string>() == "two");
+ YAML_ASSERT(doc[0]["three"].to<std::string>() == "four");
+ YAML_ASSERT(doc[1].size() == 2);
+ YAML_ASSERT(doc[1]["five"].to<std::string>() == "six");
+ YAML_ASSERT(doc[1]["seven"].to<std::string>() == "eight");
+ return true;
+ }
+
+ // 7.16
+ TEST FlowMappingEntries()
+ {
+ PARSE(doc, ex7_16);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc["explicit"].to<std::string>() == "entry");
+ YAML_ASSERT(doc["implicit"].to<std::string>() == "entry");
+ YAML_ASSERT(IsNull(doc[YAML::Null]));
+ return true;
+ }
+
+ // 7.17
+ TEST FlowMappingSeparateValues()
+ {
+ PARSE(doc, ex7_17);
+ YAML_ASSERT(doc.size() == 4);
+ YAML_ASSERT(doc["unquoted"].to<std::string>() == "separate");
+ YAML_ASSERT(IsNull(doc["http://foo.com"]));
+ YAML_ASSERT(IsNull(doc["omitted value"]));
+ YAML_ASSERT(doc[YAML::Null].to<std::string>() == "omitted key");
+ return true;
+ }
+
+ // 7.18
+ TEST FlowMappingAdjacentValues()
+ {
+ PARSE(doc, ex7_18);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc["adjacent"].to<std::string>() == "value");
+ YAML_ASSERT(doc["readable"].to<std::string>() == "value");
+ YAML_ASSERT(IsNull(doc["empty"]));
+ return true;
+ }
+
+ // 7.19
+ TEST SinglePairFlowMappings()
+ {
+ PARSE(doc, ex7_19);
+ YAML_ASSERT(doc.size() == 1);
+ YAML_ASSERT(doc[0].size() == 1);
+ YAML_ASSERT(doc[0]["foo"].to<std::string>() == "bar");
+ return true;
+ }
+
+ // 7.20
+ TEST SinglePairExplicitEntry()
+ {
+ PARSE(doc, ex7_20);
+ YAML_ASSERT(doc.size() == 1);
+ YAML_ASSERT(doc[0].size() == 1);
+ YAML_ASSERT(doc[0]["foo bar"].to<std::string>() == "baz");
+ return true;
+ }
+
+ // 7.21
+ TEST SinglePairImplicitEntries()
+ {
+ PARSE(doc, ex7_21);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc[0].size() == 1);
+ YAML_ASSERT(doc[0][0].size() == 1);
+ YAML_ASSERT(doc[0][0]["YAML"].to<std::string>() == "separate");
+ YAML_ASSERT(doc[1].size() == 1);
+ YAML_ASSERT(doc[1][0].size() == 1);
+ YAML_ASSERT(doc[1][0][YAML::Null].to<std::string>() == "empty key entry");
+ YAML_ASSERT(doc[2].size() == 1);
+ YAML_ASSERT(doc[2][0].size() == 1);
+ StringMap key;
+ key._["JSON"] = "like";
+ YAML_ASSERT(doc[2][0][key].to<std::string>() == "adjacent");
+ return true;
+ }
+
+ // 7.22
+ TEST InvalidImplicitKeys()
+ {
+ try {
+ PARSE(doc, ex7_22);
+ } catch(const YAML::Exception& e) {
+ if(e.msg == YAML::ErrorMsg::END_OF_SEQ_FLOW)
+ return true;
+
+ throw;
+ }
+ return " no exception thrown";
+ }
+
+ // 7.23
+ TEST FlowContent()
+ {
+ PARSE(doc, ex7_23);
+ YAML_ASSERT(doc.size() == 5);
+ YAML_ASSERT(doc[0].size() == 2);
+ YAML_ASSERT(doc[0][0].to<std::string>() == "a");
+ YAML_ASSERT(doc[0][1].to<std::string>() == "b");
+ YAML_ASSERT(doc[1].size() == 1);
+ YAML_ASSERT(doc[1]["a"].to<std::string>() == "b");
+ YAML_ASSERT(doc[2].to<std::string>() == "a");
+ YAML_ASSERT(doc[3].to<char>() == 'b');
+ YAML_ASSERT(doc[4].to<std::string>() == "c");
+ return true;
+ }
+
+ // 7.24
+ TEST FlowNodes()
+ {
+ PARSE(doc, ex7_24);
+ YAML_ASSERT(doc.size() == 5);
+ YAML_ASSERT(doc[0].Tag() == "tag:yaml.org,2002:str");
+ YAML_ASSERT(doc[0].to<std::string>() == "a");
+ YAML_ASSERT(doc[1].to<char>() == 'b');
+ YAML_ASSERT(doc[2].to<std::string>() == "c");
+ YAML_ASSERT(doc[3].to<std::string>() == "c");
+ YAML_ASSERT(doc[4].Tag() == "tag:yaml.org,2002:str");
+ YAML_ASSERT(doc[4].to<std::string>() == "");
+ return true;
+ }
+
+ // 8.1
+ TEST BlockScalarHeader()
+ {
+ PARSE(doc, ex8_1);
+ YAML_ASSERT(doc.size() == 4);
+ YAML_ASSERT(doc[0].to<std::string>() == "literal\n");
+ YAML_ASSERT(doc[1].to<std::string>() == " folded\n");
+ YAML_ASSERT(doc[2].to<std::string>() == "keep\n\n");
+ YAML_ASSERT(doc[3].to<std::string>() == " strip");
+ return true;
+ }
+
+ // 8.2
+ TEST BlockIndentationHeader()
+ {
+ PARSE(doc, ex8_2);
+ YAML_ASSERT(doc.size() == 4);
+ YAML_ASSERT(doc[0].to<std::string>() == "detected\n");
+ YAML_ASSERT(doc[1].to<std::string>() == "\n\n# detected\n");
+ YAML_ASSERT(doc[2].to<std::string>() == " explicit\n");
+ YAML_ASSERT(doc[3].to<std::string>() == "\t\ndetected\n");
+ return true;
+ }
+
+ // 8.3
+ TEST InvalidBlockScalarIndentationIndicators()
+ {
+ {
+ bool threw = false;
+ try {
+ PARSE(doc, ex8_3a);
+ } catch(const YAML::Exception& e) {
+ if(e.msg != YAML::ErrorMsg::END_OF_SEQ)
+ throw;
+
+ threw = true;
+ }
+
+ if(!threw)
+ return " no exception thrown for less indented auto-detecting indentation for a literal block scalar";
+ }
+
+ {
+ bool threw = false;
+ try {
+ PARSE(doc, ex8_3b);
+ } catch(const YAML::Exception& e) {
+ if(e.msg != YAML::ErrorMsg::END_OF_SEQ)
+ throw;
+
+ threw = true;
+ }
+
+ if(!threw)
+ return " no exception thrown for less indented auto-detecting indentation for a folded block scalar";
+ }
+
+ {
+ bool threw = false;
+ try {
+ PARSE(doc, ex8_3c);
+ } catch(const YAML::Exception& e) {
+ if(e.msg != YAML::ErrorMsg::END_OF_SEQ)
+ throw;
+
+ threw = true;
+ }
+
+ if(!threw)
+ return " no exception thrown for less indented explicit indentation for a literal block scalar";
+ }
+
+ return true;
+ }
+
+ // 8.4
+ TEST ChompingFinalLineBreak()
+ {
+ PARSE(doc, ex8_4);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc["strip"].to<std::string>() == "text");
+ YAML_ASSERT(doc["clip"].to<std::string>() == "text\n");
+ YAML_ASSERT(doc["keep"].to<std::string>() == "text\n");
+ return true;
+ }
+
+ // 8.5
+ TEST ChompingTrailingLines()
+ {
+ PARSE(doc, ex8_5);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc["strip"].to<std::string>() == "# text");
+ YAML_ASSERT(doc["clip"].to<std::string>() == "# text\n");
+ YAML_ASSERT(doc["keep"].to<std::string>() == "# text\n"); // Note: I believe this is a bug in the YAML spec - it should be "# text\n\n"
+ return true;
+ }
+
+ // 8.6
+ TEST EmptyScalarChomping()
+ {
+ PARSE(doc, ex8_6);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc["strip"].to<std::string>() == "");
+ YAML_ASSERT(doc["clip"].to<std::string>() == "");
+ YAML_ASSERT(doc["keep"].to<std::string>() == "\n");
+ return true;
+ }
+
+ // 8.7
+ TEST LiteralScalar()
+ {
+ PARSE(doc, ex8_7);
+ YAML_ASSERT(doc.to<std::string>() == "literal\n\ttext\n");
+ return true;
+ }
+
+ // 8.8
+ TEST LiteralContent()
+ {
+ PARSE(doc, ex8_8);
+ YAML_ASSERT(doc.to<std::string>() == "\n\nliteral\n \n\ntext\n");
+ return true;
+ }
+
+ // 8.9
+ TEST FoldedScalar()
+ {
+ PARSE(doc, ex8_9);
+ YAML_ASSERT(doc.to<std::string>() == "folded text\n");
+ return true;
+ }
+
+ // 8.10
+ TEST FoldedLines()
+ {
+ PARSE(doc, ex8_10);
+ YAML_ASSERT(doc.to<std::string>() == "\nfolded line\nnext line\n * bullet\n\n * list\n * lines\n\nlast line\n");
+ return true;
+ }
+
+ // 8.11
+ TEST MoreIndentedLines()
+ {
+ return true; // same as 8.10
+ }
+
+ // 8.12
+ TEST EmptySeparationLines()
+ {
+ return true; // same as 8.10
+ }
+
+ // 8.13
+ TEST FinalEmptyLines()
+ {
+ return true; // same as 8.10
+ }
+
+ // 8.14
+ TEST BlockSequence()
+ {
+ PARSE(doc, ex8_14);
+ YAML_ASSERT(doc.size() == 1);
+ YAML_ASSERT(doc["block sequence"].size() == 2);
+ YAML_ASSERT(doc["block sequence"][0].to<std::string>() == "one");
+ YAML_ASSERT(doc["block sequence"][1].size() == 1);
+ YAML_ASSERT(doc["block sequence"][1]["two"].to<std::string>() == "three");
+ return true;
+ }
+
+ // 8.15
+ TEST BlockSequenceEntryTypes()
+ {
+ PARSE(doc, ex8_15);
+ YAML_ASSERT(doc.size() == 4);
+ YAML_ASSERT(YAML::IsNull(doc[0]));
+ YAML_ASSERT(doc[1].to<std::string>() == "block node\n");
+ YAML_ASSERT(doc[2].size() == 2);
+ YAML_ASSERT(doc[2][0].to<std::string>() == "one");
+ YAML_ASSERT(doc[2][1].to<std::string>() == "two");
+ YAML_ASSERT(doc[3].size() == 1);
+ YAML_ASSERT(doc[3]["one"].to<std::string>() == "two");
+ return true;
+ }
+
+ // 8.16
+ TEST BlockMappings()
+ {
+ PARSE(doc, ex8_16);
+ YAML_ASSERT(doc.size() == 1);
+ YAML_ASSERT(doc["block mapping"].size() == 1);
+ YAML_ASSERT(doc["block mapping"]["key"].to<std::string>() == "value");
+ return true;
+ }
+
+ // 8.17
+ TEST ExplicitBlockMappingEntries()
+ {
+ PARSE(doc, ex8_17);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(IsNull(doc["explicit key"]));
+ YAML_ASSERT(doc["block key\n"].size() == 2);
+ YAML_ASSERT(doc["block key\n"][0].to<std::string>() == "one");
+ YAML_ASSERT(doc["block key\n"][1].to<std::string>() == "two");
+ return true;
+ }
+
+ // 8.18
+ TEST ImplicitBlockMappingEntries()
+ {
+ PARSE(doc, ex8_18);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc["plain key"].to<std::string>() == "in-line value");
+ YAML_ASSERT(IsNull(doc[YAML::Null]));
+ YAML_ASSERT(doc["quoted key"].size() == 1);
+ YAML_ASSERT(doc["quoted key"][0].to<std::string>() == "entry");
+ return true;
+ }
+
+ // 8.19
+ TEST CompactBlockMappings()
+ {
+ PARSE(doc, ex8_19);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc[0].size() == 1);
+ YAML_ASSERT(doc[0]["sun"].to<std::string>() == "yellow");
+ YAML_ASSERT(doc[1].size() == 1);
+ std::map<std::string, std::string> key;
+ key["earth"] = "blue";
+ YAML_ASSERT(doc[1][key].size() == 1);
+ YAML_ASSERT(doc[1][key]["moon"].to<std::string>() == "white");
+ return true;
+ }
+
+ // 8.20
+ TEST BlockNodeTypes()
+ {
+ PARSE(doc, ex8_20);
+ YAML_ASSERT(doc.size() == 3);
+ YAML_ASSERT(doc[0].to<std::string>() == "flow in block");
+ YAML_ASSERT(doc[1].to<std::string>() == "Block scalar\n");
+ YAML_ASSERT(doc[2].size() == 1);
+ YAML_ASSERT(doc[2]["foo"].to<std::string>() == "bar");
+ return true;
+ }
+
+ // 8.21
+ TEST BlockScalarNodes()
+ {
+ PARSE(doc, ex8_21);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc["literal"].to<std::string>() == "value"); // Note: I believe this is a bug in the YAML spec - it should be "value\n"
+ YAML_ASSERT(doc["folded"].to<std::string>() == "value");
+ YAML_ASSERT(doc["folded"].Tag() == "!foo");
+ return true;
+ }
+
+ // 8.22
+ TEST BlockCollectionNodes()
+ {
+ PARSE(doc, ex8_22);
+ YAML_ASSERT(doc.size() == 2);
+ YAML_ASSERT(doc["sequence"].size() == 2);
+ YAML_ASSERT(doc["sequence"][0].to<std::string>() == "entry");
+ YAML_ASSERT(doc["sequence"][1].size() == 1);
+ YAML_ASSERT(doc["sequence"][1][0].to<std::string>() == "nested");
+ YAML_ASSERT(doc["mapping"].size() == 1);
+ YAML_ASSERT(doc["mapping"]["foo"].to<std::string>() == "bar");
+ return true;
+ }
+ }
+}
diff --git a/external_libs/yaml-cpp/test/parsertests.h b/external_libs/yaml-cpp/test/parsertests.h
new file mode 100644
index 00000000..f3de1b8c
--- /dev/null
+++ b/external_libs/yaml-cpp/test/parsertests.h
@@ -0,0 +1,13 @@
+#ifndef PARSERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define PARSERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+namespace Test {
+ bool RunParserTests();
+}
+
+#endif // PARSERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
diff --git a/external_libs/yaml-cpp/test/specexamples.h b/external_libs/yaml-cpp/test/specexamples.h
new file mode 100644
index 00000000..4688bdcf
--- /dev/null
+++ b/external_libs/yaml-cpp/test/specexamples.h
@@ -0,0 +1,850 @@
+namespace Test {
+ namespace Spec {
+ const char *ex2_1 =
+ "- Mark McGwire\n"
+ "- Sammy Sosa\n"
+ "- Ken Griffey";
+
+ const char *ex2_2 =
+ "hr: 65 # Home runs\n"
+ "avg: 0.278 # Batting average\n"
+ "rbi: 147 # Runs Batted In";
+
+ const char *ex2_3 =
+ "american:\n"
+ "- Boston Red Sox\n"
+ "- Detroit Tigers\n"
+ "- New York Yankees\n"
+ "national:\n"
+ "- New York Mets\n"
+ "- Chicago Cubs\n"
+ "- Atlanta Braves";
+
+ const char *ex2_4 =
+ "-\n"
+ " name: Mark McGwire\n"
+ " hr: 65\n"
+ " avg: 0.278\n"
+ "-\n"
+ " name: Sammy Sosa\n"
+ " hr: 63\n"
+ " avg: 0.288";
+
+ const char *ex2_5 =
+ "- [name , hr, avg ]\n"
+ "- [Mark McGwire, 65, 0.278]\n"
+ "- [Sammy Sosa , 63, 0.288]";
+
+ const char *ex2_6 =
+ "Mark McGwire: {hr: 65, avg: 0.278}\n"
+ "Sammy Sosa: {\n"
+ " hr: 63,\n"
+ " avg: 0.288\n"
+ " }";
+
+ const char *ex2_7 =
+ "# Ranking of 1998 home runs\n"
+ "---\n"
+ "- Mark McGwire\n"
+ "- Sammy Sosa\n"
+ "- Ken Griffey\n"
+ "\n"
+ "# Team ranking\n"
+ "---\n"
+ "- Chicago Cubs\n"
+ "- St Louis Cardinals";
+
+ const char *ex2_8 =
+ "---\n"
+ "time: 20:03:20\n"
+ "player: Sammy Sosa\n"
+ "action: strike (miss)\n"
+ "...\n"
+ "---\n"
+ "time: 20:03:47\n"
+ "player: Sammy Sosa\n"
+ "action: grand slam\n"
+ "...";
+
+ const char *ex2_9 =
+ "---\n"
+ "hr: # 1998 hr ranking\n"
+ " - Mark McGwire\n"
+ " - Sammy Sosa\n"
+ "rbi:\n"
+ " # 1998 rbi ranking\n"
+ " - Sammy Sosa\n"
+ " - Ken Griffey";
+
+ const char *ex2_10 =
+ "---\n"
+ "hr:\n"
+ " - Mark McGwire\n"
+ " # Following node labeled SS\n"
+ " - &SS Sammy Sosa\n"
+ "rbi:\n"
+ " - *SS # Subsequent occurrence\n"
+ " - Ken Griffey";
+
+ const char *ex2_11 =
+ "? - Detroit Tigers\n"
+ " - Chicago cubs\n"
+ ":\n"
+ " - 2001-07-23\n"
+ "\n"
+ "? [ New York Yankees,\n"
+ " Atlanta Braves ]\n"
+ ": [ 2001-07-02, 2001-08-12,\n"
+ " 2001-08-14 ]";
+
+ const char *ex2_12 =
+ "---\n"
+ "# Products purchased\n"
+ "- item : Super Hoop\n"
+ " quantity: 1\n"
+ "- item : Basketball\n"
+ " quantity: 4\n"
+ "- item : Big Shoes\n"
+ " quantity: 1";
+
+ const char *ex2_13 =
+ "# ASCII Art\n"
+ "--- |\n"
+ " \\//||\\/||\n"
+ " // || ||__";
+
+ const char *ex2_14 =
+ "--- >\n"
+ " Mark McGwire's\n"
+ " year was crippled\n"
+ " by a knee injury.";
+
+ const char *ex2_15 =
+ ">\n"
+ " Sammy Sosa completed another\n"
+ " fine season with great stats.\n"
+ " \n"
+ " 63 Home Runs\n"
+ " 0.288 Batting Average\n"
+ " \n"
+ " What a year!";
+
+ const char *ex2_16 =
+ "name: Mark McGwire\n"
+ "accomplishment: >\n"
+ " Mark set a major league\n"
+ " home run record in 1998.\n"
+ "stats: |\n"
+ " 65 Home Runs\n"
+ " 0.278 Batting Average\n";
+
+ const char *ex2_17 =
+ "unicode: \"Sosa did fine.\\u263A\"\n"
+ "control: \"\\b1998\\t1999\\t2000\\n\"\n"
+ "hex esc: \"\\x0d\\x0a is \\r\\n\"\n"
+ "\n"
+ "single: '\"Howdy!\" he cried.'\n"
+ "quoted: ' # Not a ''comment''.'\n"
+ "tie-fighter: '|\\-*-/|'";
+
+ const char *ex2_18 =
+ "plain:\n"
+ " This unquoted scalar\n"
+ " spans many lines.\n"
+ "\n"
+ "quoted: \"So does this\n"
+ " quoted scalar.\\n\"";
+
+ // TODO: 2.19 - 2.22 schema tags
+
+ const char *ex2_23 =
+ "---\n"
+ "not-date: !!str 2002-04-28\n"
+ "\n"
+ "picture: !!binary |\n"
+ " R0lGODlhDAAMAIQAAP//9/X\n"
+ " 17unp5WZmZgAAAOfn515eXv\n"
+ " Pz7Y6OjuDg4J+fn5OTk6enp\n"
+ " 56enmleECcgggoBADs=\n"
+ "\n"
+ "application specific tag: !something |\n"
+ " The semantics of the tag\n"
+ " above may be different for\n"
+ " different documents.";
+
+ const char *ex2_24 =
+ "%TAG ! tag:clarkevans.com,2002:\n"
+ "--- !shape\n"
+ " # Use the ! handle for presenting\n"
+ " # tag:clarkevans.com,2002:circle\n"
+ "- !circle\n"
+ " center: &ORIGIN {x: 73, y: 129}\n"
+ " radius: 7\n"
+ "- !line\n"
+ " start: *ORIGIN\n"
+ " finish: { x: 89, y: 102 }\n"
+ "- !label\n"
+ " start: *ORIGIN\n"
+ " color: 0xFFEEBB\n"
+ " text: Pretty vector drawing.";
+
+ const char *ex2_25 =
+ "# Sets are represented as a\n"
+ "# Mapping where each key is\n"
+ "# associated with a null value\n"
+ "--- !!set\n"
+ "? Mark McGwire\n"
+ "? Sammy Sosa\n"
+ "? Ken Griffey";
+
+ const char *ex2_26 =
+ "# Ordered maps are represented as\n"
+ "# A sequence of mappings, with\n"
+ "# each mapping having one key\n"
+ "--- !!omap\n"
+ "- Mark McGwire: 65\n"
+ "- Sammy Sosa: 63\n"
+ "- Ken Griffey: 58";
+
+ const char *ex2_27 =
+ "--- !<tag:clarkevans.com,2002:invoice>\n"
+ "invoice: 34843\n"
+ "date : 2001-01-23\n"
+ "bill-to: &id001\n"
+ " given : Chris\n"
+ " family : Dumars\n"
+ " address:\n"
+ " lines: |\n"
+ " 458 Walkman Dr.\n"
+ " Suite #292\n"
+ " city : Royal Oak\n"
+ " state : MI\n"
+ " postal : 48046\n"
+ "ship-to: *id001\n"
+ "product:\n"
+ " - sku : BL394D\n"
+ " quantity : 4\n"
+ " description : Basketball\n"
+ " price : 450.00\n"
+ " - sku : BL4438H\n"
+ " quantity : 1\n"
+ " description : Super Hoop\n"
+ " price : 2392.00\n"
+ "tax : 251.42\n"
+ "total: 4443.52\n"
+ "comments:\n"
+ " Late afternoon is best.\n"
+ " Backup contact is Nancy\n"
+ " Billsmer @ 338-4338.";
+
+ const char *ex2_28 =
+ "---\n"
+ "Time: 2001-11-23 15:01:42 -5\n"
+ "User: ed\n"
+ "Warning:\n"
+ " This is an error message\n"
+ " for the log file\n"
+ "---\n"
+ "Time: 2001-11-23 15:02:31 -5\n"
+ "User: ed\n"
+ "Warning:\n"
+ " A slightly different error\n"
+ " message.\n"
+ "---\n"
+ "Date: 2001-11-23 15:03:17 -5\n"
+ "User: ed\n"
+ "Fatal:\n"
+ " Unknown variable \"bar\"\n"
+ "Stack:\n"
+ " - file: TopClass.py\n"
+ " line: 23\n"
+ " code: |\n"
+ " x = MoreObject(\"345\\n\")\n"
+ " - file: MoreClass.py\n"
+ " line: 58\n"
+ " code: |-\n"
+ " foo = bar";
+
+ // TODO: 5.1 - 5.2 BOM
+
+ const char *ex5_3 =
+ "sequence:\n"
+ "- one\n"
+ "- two\n"
+ "mapping:\n"
+ " ? sky\n"
+ " : blue\n"
+ " sea : green";
+
+ const char *ex5_4 =
+ "sequence: [ one, two, ]\n"
+ "mapping: { sky: blue, sea: green }";
+
+ const char *ex5_5 =
+ "# Comment only.";
+
+ const char *ex5_6 =
+ "anchored: !local &anchor value\n"
+ "alias: *anchor";
+
+ const char *ex5_7 =
+ "literal: |\n"
+ " some\n"
+ " text\n"
+ "folded: >\n"
+ " some\n"
+ " text\n";
+
+ const char *ex5_8 =
+ "single: 'text'\n"
+ "double: \"text\"";
+
+ // TODO: 5.9 directive
+ // TODO: 5.10 reserved indicator
+
+ const char *ex5_11 =
+ "|\n"
+ " Line break (no glyph)\n"
+ " Line break (glyphed)\n";
+
+ const char *ex5_12 =
+ "# Tabs and spaces\n"
+ "quoted: \"Quoted\t\"\n"
+ "block: |\n"
+ " void main() {\n"
+ " \tprintf(\"Hello, world!\\n\");\n"
+ " }";
+
+ const char *ex5_13 =
+ "\"Fun with \\\\\n"
+ "\\\" \\a \\b \\e \\f \\\n"
+ "\\n \\r \\t \\v \\0 \\\n"
+ "\\ \\_ \\N \\L \\P \\\n"
+ "\\x41 \\u0041 \\U00000041\"";
+
+ const char *ex5_14 =
+ "Bad escapes:\n"
+ " \"\\c\n"
+ " \\xq-\"";
+
+ const char *ex6_1 =
+ " # Leading comment line spaces are\n"
+ " # neither content nor indentation.\n"
+ " \n"
+ "Not indented:\n"
+ " By one space: |\n"
+ " By four\n"
+ " spaces\n"
+ " Flow style: [ # Leading spaces\n"
+ " By two, # in flow style\n"
+ " Also by two, # are neither\n"
+ " \tStill by two # content nor\n"
+ " ] # indentation.";
+
+ const char *ex6_2 =
+ "? a\n"
+ ": -\tb\n"
+ " - -\tc\n"
+ " - d";
+
+ const char *ex6_3 =
+ "- foo:\t bar\n"
+ "- - baz\n"
+ " -\tbaz";
+
+ const char *ex6_4 =
+ "plain: text\n"
+ " lines\n"
+ "quoted: \"text\n"
+ " \tlines\"\n"
+ "block: |\n"
+ " text\n"
+ " \tlines\n";
+
+ const char *ex6_5 =
+ "Folding:\n"
+ " \"Empty line\n"
+ " \t\n"
+ " as a line feed\"\n"
+ "Chomping: |\n"
+ " Clipped empty lines\n"
+ " ";
+
+ const char *ex6_6 =
+ ">-\n"
+ " trimmed\n"
+ " \n"
+ " \n"
+ "\n"
+ " as\n"
+ " space";
+
+ const char *ex6_7 =
+ ">\n"
+ " foo \n"
+ " \n"
+ " \t bar\n"
+ "\n"
+ " baz\n";
+
+ const char *ex6_8 =
+ "\"\n"
+ " foo \n"
+ " \n"
+ " \t bar\n"
+ "\n"
+ " baz\n"
+ "\"";
+
+ const char *ex6_9 =
+ "key: # Comment\n"
+ " value";
+
+ const char *ex6_10 =
+ " # Comment\n"
+ " \n"
+ "\n";
+
+ const char *ex6_11 =
+ "key: # Comment\n"
+ " # lines\n"
+ " value\n"
+ "\n";
+
+ const char *ex6_12 =
+ "{ first: Sammy, last: Sosa }:\n"
+ "# Statistics:\n"
+ " hr: # Home runs\n"
+ " 65\n"
+ " avg: # Average\n"
+ " 0.278";
+
+ const char *ex6_13 =
+ "%FOO bar baz # Should be ignored\n"
+ " # with a warning.\n"
+ "--- \"foo\"";
+
+ const char *ex6_14 =
+ "%YAML 1.3 # Attempt parsing\n"
+ " # with a warning\n"
+ "---\n"
+ "\"foo\"";
+
+ const char *ex6_15 =
+ "%YAML 1.2\n"
+ "%YAML 1.1\n"
+ "foo";
+
+ const char *ex6_16 =
+ "%TAG !yaml! tag:yaml.org,2002:\n"
+ "---\n"
+ "!yaml!str \"foo\"";
+
+ const char *ex6_17 =
+ "%TAG ! !foo\n"
+ "%TAG ! !foo\n"
+ "bar";
+
+ const char *ex6_18 =
+ "# Private\n"
+ "!foo \"bar\"\n"
+ "...\n"
+ "# Global\n"
+ "%TAG ! tag:example.com,2000:app/\n"
+ "---\n"
+ "!foo \"bar\"";
+
+ const char *ex6_19 =
+ "%TAG !! tag:example.com,2000:app/\n"
+ "---\n"
+ "!!int 1 - 3 # Interval, not integer";
+
+ const char *ex6_20 =
+ "%TAG !e! tag:example.com,2000:app/\n"
+ "---\n"
+ "!e!foo \"bar\"";
+
+ const char *ex6_21 =
+ "%TAG !m! !my-\n"
+ "--- # Bulb here\n"
+ "!m!light fluorescent\n"
+ "...\n"
+ "%TAG !m! !my-\n"
+ "--- # Color here\n"
+ "!m!light green";
+
+ const char *ex6_22 =
+ "%TAG !e! tag:example.com,2000:app/\n"
+ "---\n"
+ "- !e!foo \"bar\"";
+
+ const char *ex6_23 =
+ "!!str &a1 \"foo\":\n"
+ " !!str bar\n"
+ "&a2 baz : *a1";
+
+ const char *ex6_24 =
+ "!<tag:yaml.org,2002:str> foo :\n"
+ " !<!bar> baz";
+
+ const char *ex6_25 =
+ "- !<!> foo\n"
+ "- !<$:?> bar\n";
+
+ const char *ex6_26 =
+ "%TAG !e! tag:example.com,2000:app/\n"
+ "---\n"
+ "- !local foo\n"
+ "- !!str bar\n"
+ "- !e!tag%21 baz\n";
+
+ const char *ex6_27a =
+ "%TAG !e! tag:example,2000:app/\n"
+ "---\n"
+ "- !e! foo";
+
+ const char *ex6_27b =
+ "%TAG !e! tag:example,2000:app/\n"
+ "---\n"
+ "- !h!bar baz";
+
+ const char *ex6_28 =
+ "# Assuming conventional resolution:\n"
+ "- \"12\"\n"
+ "- 12\n"
+ "- ! 12";
+
+ const char *ex6_29 =
+ "First occurrence: &anchor Value\n"
+ "Second occurrence: *anchor";
+
+ const char *ex7_1 =
+ "First occurrence: &anchor Foo\n"
+ "Second occurrence: *anchor\n"
+ "Override anchor: &anchor Bar\n"
+ "Reuse anchor: *anchor";
+
+ const char *ex7_2 =
+ "{\n"
+ " foo : !!str,\n"
+ " !!str : bar,\n"
+ "}";
+
+ const char *ex7_3 =
+ "{\n"
+ " ? foo :,\n"
+ " : bar,\n"
+ "}\n";
+
+ const char *ex7_4 =
+ "\"implicit block key\" : [\n"
+ " \"implicit flow key\" : value,\n"
+ " ]";
+
+ const char *ex7_5 =
+ "\"folded \n"
+ "to a space,\t\n"
+ " \n"
+ "to a line feed, or \t\\\n"
+ " \\ \tnon-content\"";
+
+ const char *ex7_6 =
+ "\" 1st non-empty\n"
+ "\n"
+ " 2nd non-empty \n"
+ "\t3rd non-empty \"";
+
+ const char *ex7_7 =
+ " 'here''s to \"quotes\"'";
+
+ const char *ex7_8 =
+ "'implicit block key' : [\n"
+ " 'implicit flow key' : value,\n"
+ " ]";
+
+ const char *ex7_9 =
+ "' 1st non-empty\n"
+ "\n"
+ " 2nd non-empty \n"
+ "\t3rd non-empty '";
+
+ const char *ex7_10 =
+ "# Outside flow collection:\n"
+ "- ::vector\n"
+ "- \": - ()\"\n"
+ "- Up, up, and away!\n"
+ "- -123\n"
+ "- http://example.com/foo#bar\n"
+ "# Inside flow collection:\n"
+ "- [ ::vector,\n"
+ " \": - ()\",\n"
+ " \"Up, up, and away!\",\n"
+ " -123,\n"
+ " http://example.com/foo#bar ]";
+
+ const char *ex7_11 =
+ "implicit block key : [\n"
+ " implicit flow key : value,\n"
+ " ]";
+
+ const char *ex7_12 =
+ "1st non-empty\n"
+ "\n"
+ " 2nd non-empty \n"
+ "\t3rd non-empty";
+
+ const char *ex7_13 =
+ "- [ one, two, ]\n"
+ "- [three ,four]";
+
+ const char *ex7_14 =
+ "[\n"
+ "\"double\n"
+ " quoted\", 'single\n"
+ " quoted',\n"
+ "plain\n"
+ " text, [ nested ],\n"
+ "single: pair,\n"
+ "]";
+
+ const char *ex7_15 =
+ "- { one : two , three: four , }\n"
+ "- {five: six,seven : eight}";
+
+ const char *ex7_16 =
+ "{\n"
+ "? explicit: entry,\n"
+ "implicit: entry,\n"
+ "?\n"
+ "}";
+
+ const char *ex7_17 =
+ "{\n"
+ "unquoted : \"separate\",\n"
+ "http://foo.com,\n"
+ "omitted value:,\n"
+ ": omitted key,\n"
+ "}";
+
+ const char *ex7_18 =
+ "{\n"
+ "\"adjacent\":value,\n"
+ "\"readable\":value,\n"
+ "\"empty\":\n"
+ "}";
+
+ const char *ex7_19 =
+ "[\n"
+ "foo: bar\n"
+ "]";
+
+ const char *ex7_20 =
+ "[\n"
+ "? foo\n"
+ " bar : baz\n"
+ "]";
+
+ const char *ex7_21 =
+ "- [ YAML : separate ]\n"
+ "- [ : empty key entry ]\n"
+ "- [ {JSON: like}:adjacent ]";
+
+ const char *ex7_22 =
+ "[ foo\n"
+ " bar: invalid,"; // Note: we don't check (on purpose) the >1K chars for an implicit key
+
+ const char *ex7_23 =
+ "- [ a, b ]\n"
+ "- { a: b }\n"
+ "- \"a\"\n"
+ "- 'b'\n"
+ "- c";
+
+ const char *ex7_24 =
+ "- !!str \"a\"\n"
+ "- 'b'\n"
+ "- &anchor \"c\"\n"
+ "- *anchor\n"
+ "- !!str";
+
+ const char *ex8_1 =
+ "- | # Empty header\n"
+ " literal\n"
+ "- >1 # Indentation indicator\n"
+ " folded\n"
+ "- |+ # Chomping indicator\n"
+ " keep\n"
+ "\n"
+ "- >1- # Both indicators\n"
+ " strip\n";
+
+ const char *ex8_2 =
+ "- |\n"
+ " detected\n"
+ "- >\n"
+ " \n"
+ " \n"
+ " # detected\n"
+ "- |1\n"
+ " explicit\n"
+ "- >\n"
+ " \t\n"
+ " detected\n";
+
+ const char *ex8_3a =
+ "- |\n"
+ " \n"
+ " text";
+
+ const char *ex8_3b =
+ "- >\n"
+ " text\n"
+ " text";
+
+ const char *ex8_3c =
+ "- |2\n"
+ " text";
+
+ const char *ex8_4 =
+ "strip: |-\n"
+ " text\n"
+ "clip: |\n"
+ " text\n"
+ "keep: |+\n"
+ " text\n";
+
+ const char *ex8_5 =
+ " # Strip\n"
+ " # Comments:\n"
+ "strip: |-\n"
+ " # text\n"
+ " \n"
+ " # Clip\n"
+ " # comments:\n"
+ "\n"
+ "clip: |\n"
+ " # text\n"
+ " \n"
+ " # Keep\n"
+ " # comments:\n"
+ "\n"
+ "keep: |+\n"
+ " # text\n"
+ "\n"
+ " # Trail\n"
+ " # Comments\n";
+
+ const char *ex8_6 =
+ "strip: >-\n"
+ "\n"
+ "clip: >\n"
+ "\n"
+ "keep: |+\n"
+ "\n";
+
+ const char *ex8_7 =
+ "|\n"
+ " literal\n"
+ " \ttext\n"
+ "\n";
+
+ const char *ex8_8 =
+ "|\n"
+ " \n"
+ " \n"
+ " literal\n"
+ " \n"
+ " \n"
+ " text\n"
+ "\n"
+ " # Comment\n";
+
+ const char *ex8_9 =
+ ">\n"
+ " folded\n"
+ " text\n"
+ "\n";
+
+ const char *ex8_10 =
+ ">\n"
+ "\n"
+ " folded\n"
+ " line\n"
+ "\n"
+ " next\n"
+ " line\n"
+ " * bullet\n"
+ "\n"
+ " * list\n"
+ " * lines\n"
+ "\n"
+ " last\n"
+ " line\n"
+ "\n"
+ "# Comment\n";
+
+ const char *ex8_11 = ex8_10;
+ const char *ex8_12 = ex8_10;
+ const char *ex8_13 = ex8_10;
+
+ const char *ex8_14 =
+ "block sequence:\n"
+ " - one\n"
+ " - two : three\n";
+
+ const char *ex8_15 =
+ "- # Empty\n"
+ "- |\n"
+ " block node\n"
+ "- - one # Compact\n"
+ " - two # sequence\n"
+ "- one: two # Compact mapping\n";
+
+ const char *ex8_16 =
+ "block mapping:\n"
+ " key: value\n";
+
+ const char *ex8_17 =
+ "? explicit key # Empty value\n"
+ "? |\n"
+ " block key\n"
+ ": - one # Explicit compact\n"
+ " - two # block value\n";
+
+ const char *ex8_18 =
+ "plain key: in-line value\n"
+ ": # Both empty\n"
+ "\"quoted key\":\n"
+ "- entry\n";
+
+ const char *ex8_19 =
+ "- sun: yellow\n"
+ "- ? earth: blue\n"
+ " : moon: white\n";
+
+ const char *ex8_20 =
+ "-\n"
+ " \"flow in block\"\n"
+ "- >\n"
+ " Block scalar\n"
+ "- !!map # Block collection\n"
+ " foo : bar\n";
+
+ const char *ex8_21 =
+ "literal: |2\n"
+ " value\n"
+ "folded:\n"
+ " !foo\n"
+ " >1\n"
+ " value\n";
+
+ const char *ex8_22 =
+ "sequence: !!seq\n"
+ "- entry\n"
+ "- !!seq\n"
+ " - nested\n"
+ "mapping: !!map\n"
+ " foo: bar\n";
+ }
+}
+
diff --git a/external_libs/yaml-cpp/test/spectests.cpp b/external_libs/yaml-cpp/test/spectests.cpp
new file mode 100644
index 00000000..bffc5062
--- /dev/null
+++ b/external_libs/yaml-cpp/test/spectests.cpp
@@ -0,0 +1,149 @@
+#include "spectests.h"
+#include "yaml-cpp/yaml.h"
+#include <iostream>
+
+namespace Test
+{
+ namespace {
+ void RunSpecTest(TEST (*test)(), const std::string& index, const std::string& name, int& passed, int& total) {
+ TEST ret;
+ try {
+ ret = test();
+ } catch(const YAML::Exception& e) {
+ ret.ok = false;
+ ret.error = std::string(" Exception caught: ") + e.what();
+ }
+
+ if(!ret.ok) {
+ std::cout << "Spec test " << index << " failed: " << name << "\n";
+ std::cout << ret.error << "\n";
+ }
+
+ if(ret.ok)
+ passed++;
+ total++;
+ }
+ }
+
+ bool RunSpecTests()
+ {
+ int passed = 0;
+ int total = 0;
+ RunSpecTest(&Spec::SeqScalars, "2.1", "Sequence of Scalars", passed, total);
+ RunSpecTest(&Spec::MappingScalarsToScalars, "2.2", "Mapping Scalars to Scalars", passed, total);
+ RunSpecTest(&Spec::MappingScalarsToSequences, "2.3", "Mapping Scalars to Sequences", passed, total);
+ RunSpecTest(&Spec::SequenceOfMappings, "2.4", "Sequence of Mappings", passed, total);
+ RunSpecTest(&Spec::SequenceOfSequences, "2.5", "Sequence of Sequences", passed, total);
+ RunSpecTest(&Spec::MappingOfMappings, "2.6", "Mapping of Mappings", passed, total);
+ RunSpecTest(&Spec::TwoDocumentsInAStream, "2.7", "Two Documents in a Stream", passed, total);
+ RunSpecTest(&Spec::PlayByPlayFeed, "2.8", "Play by Play Feed from a Game", passed, total);
+ RunSpecTest(&Spec::SingleDocumentWithTwoComments, "2.9", "Single Document with Two Comments", passed, total);
+ RunSpecTest(&Spec::SimpleAnchor, "2.10", "Node for \"Sammy Sosa\" appears twice in this document", passed, total);
+ RunSpecTest(&Spec::MappingBetweenSequences, "2.11", "Mapping between Sequences", passed, total);
+ RunSpecTest(&Spec::CompactNestedMapping, "2.12", "Compact Nested Mapping", passed, total);
+ RunSpecTest(&Spec::InLiteralsNewlinesArePreserved, "2.13", "In literals, newlines are preserved", passed, total);
+ RunSpecTest(&Spec::InFoldedScalarsNewlinesBecomeSpaces, "2.14", "In folded scalars, newlines become spaces", passed, total);
+ RunSpecTest(&Spec::FoldedNewlinesArePreservedForMoreIndentedAndBlankLines, "2.15", "Folded newlines are preserved for \"more indented\" and blank lines", passed, total);
+ RunSpecTest(&Spec::IndentationDeterminesScope, "2.16", "Indentation determines scope", passed, total);
+ RunSpecTest(&Spec::QuotedScalars, "2.17", "Quoted scalars", passed, total);
+ RunSpecTest(&Spec::MultiLineFlowScalars, "2.18", "Multi-line flow scalars", passed, total);
+
+ RunSpecTest(&Spec::VariousExplicitTags, "2.23", "Various Explicit Tags", passed, total);
+ RunSpecTest(&Spec::GlobalTags, "2.24", "Global Tags", passed, total);
+ RunSpecTest(&Spec::UnorderedSets, "2.25", "Unordered Sets", passed, total);
+ RunSpecTest(&Spec::OrderedMappings, "2.26", "Ordered Mappings", passed, total);
+ RunSpecTest(&Spec::Invoice, "2.27", "Invoice", passed, total);
+ RunSpecTest(&Spec::LogFile, "2.28", "Log File", passed, total);
+
+ RunSpecTest(&Spec::BlockStructureIndicators, "5.3", "Block Structure Indicators", passed, total);
+ RunSpecTest(&Spec::FlowStructureIndicators, "5.4", "Flow Structure Indicators", passed, total);
+ RunSpecTest(&Spec::NodePropertyIndicators, "5.6", "Node Property Indicators", passed, total);
+ RunSpecTest(&Spec::BlockScalarIndicators, "5.7", "Block Scalar Indicators", passed, total);
+ RunSpecTest(&Spec::QuotedScalarIndicators, "5.8", "Quoted Scalar Indicators", passed, total);
+ RunSpecTest(&Spec::LineBreakCharacters, "5.11", "Line Break Characters", passed, total);
+ RunSpecTest(&Spec::TabsAndSpaces, "5.12", "Tabs and Spaces", passed, total);
+ RunSpecTest(&Spec::EscapedCharacters, "5.13", "Escaped Characters", passed, total);
+ RunSpecTest(&Spec::InvalidEscapedCharacters, "5.14", "Invalid Escaped Characters", passed, total);
+
+ RunSpecTest(&Spec::IndentationSpaces, "6.1", "Indentation Spaces", passed, total);
+ RunSpecTest(&Spec::IndentationIndicators, "6.2", "Indentation Indicators", passed, total);
+ RunSpecTest(&Spec::SeparationSpaces, "6.3", "Separation Spaces", passed, total);
+ RunSpecTest(&Spec::LinePrefixes, "6.4", "Line Prefixes", passed, total);
+ RunSpecTest(&Spec::EmptyLines, "6.5", "Empty Lines", passed, total);
+ RunSpecTest(&Spec::LineFolding, "6.6", "Line Folding", passed, total);
+ RunSpecTest(&Spec::BlockFolding, "6.7", "Block Folding", passed, total);
+ RunSpecTest(&Spec::FlowFolding, "6.8", "Flow Folding", passed, total);
+ RunSpecTest(&Spec::SeparatedComment, "6.9", "Separated Comment", passed, total);
+ RunSpecTest(&Spec::CommentLines, "6.10", "Comment Lines", passed, total);
+ RunSpecTest(&Spec::MultiLineComments, "6.11", "Multi-Line Comments", passed, total);
+ RunSpecTest(&Spec::SeparationSpacesII, "6.12", "Separation Spaces", passed, total);
+ RunSpecTest(&Spec::ReservedDirectives, "6.13", "Reserved Directives", passed, total);
+ RunSpecTest(&Spec::YAMLDirective, "6.14", "YAML Directive", passed, total);
+ RunSpecTest(&Spec::InvalidRepeatedYAMLDirective, "6.15", "Invalid Repeated YAML Directive", passed, total);
+ RunSpecTest(&Spec::TagDirective, "6.16", "Tag Directive", passed, total);
+ RunSpecTest(&Spec::InvalidRepeatedTagDirective, "6.17", "Invalid Repeated Tag Directive", passed, total);
+ RunSpecTest(&Spec::PrimaryTagHandle, "6.18", "Primary Tag Handle", passed, total);
+ RunSpecTest(&Spec::SecondaryTagHandle, "6.19", "SecondaryTagHandle", passed, total);
+ RunSpecTest(&Spec::TagHandles, "6.20", "TagHandles", passed, total);
+ RunSpecTest(&Spec::LocalTagPrefix, "6.21", "LocalTagPrefix", passed, total);
+ RunSpecTest(&Spec::GlobalTagPrefix, "6.22", "GlobalTagPrefix", passed, total);
+ RunSpecTest(&Spec::NodeProperties, "6.23", "NodeProperties", passed, total);
+ RunSpecTest(&Spec::VerbatimTags, "6.24", "Verbatim Tags", passed, total);
+ RunSpecTest(&Spec::InvalidVerbatimTags, "6.25", "Invalid Verbatim Tags", passed, total);
+ RunSpecTest(&Spec::TagShorthands, "6.26", "Tag Shorthands", passed, total);
+ RunSpecTest(&Spec::InvalidTagShorthands, "6.27", "Invalid Tag Shorthands", passed, total);
+ RunSpecTest(&Spec::NonSpecificTags, "6.28", "Non Specific Tags", passed, total);
+ RunSpecTest(&Spec::NodeAnchors, "6.29", "Node Anchors", passed, total);
+
+ RunSpecTest(&Spec::AliasNodes, "7.1", "Alias Nodes", passed, total);
+ RunSpecTest(&Spec::EmptyNodes, "7.2", "Empty Nodes", passed, total);
+ RunSpecTest(&Spec::CompletelyEmptyNodes, "7.3", "Completely Empty Nodes", passed, total);
+ RunSpecTest(&Spec::DoubleQuotedImplicitKeys, "7.4", "Double Quoted Implicit Keys", passed, total);
+ RunSpecTest(&Spec::DoubleQuotedLineBreaks, "7.5", "Double Quoted Line Breaks", passed, total);
+ RunSpecTest(&Spec::DoubleQuotedLines, "7.6", "Double Quoted Lines", passed, total);
+ RunSpecTest(&Spec::SingleQuotedCharacters, "7.7", "Single Quoted Characters", passed, total);
+ RunSpecTest(&Spec::SingleQuotedImplicitKeys, "7.8", "Single Quoted Implicit Keys", passed, total);
+ RunSpecTest(&Spec::SingleQuotedLines, "7.9", "Single Quoted Lines", passed, total);
+ RunSpecTest(&Spec::PlainCharacters, "7.10", "Plain Characters", passed, total);
+ RunSpecTest(&Spec::PlainImplicitKeys, "7.11", "Plain Implicit Keys", passed, total);
+ RunSpecTest(&Spec::PlainLines, "7.12", "Plain Lines", passed, total);
+ RunSpecTest(&Spec::FlowSequence, "7.13", "Flow Sequence", passed, total);
+ RunSpecTest(&Spec::FlowSequenceEntries, "7.14", "Flow Sequence Entries", passed, total);
+ RunSpecTest(&Spec::FlowMappings, "7.15", "Flow Mappings", passed, total);
+ RunSpecTest(&Spec::FlowMappingEntries, "7.16", "Flow Mapping Entries", passed, total);
+ RunSpecTest(&Spec::FlowMappingSeparateValues, "7.17", "Flow Mapping Separate Values", passed, total);
+ RunSpecTest(&Spec::FlowMappingAdjacentValues, "7.18", "Flow Mapping Adjacent Values", passed, total);
+ RunSpecTest(&Spec::SinglePairFlowMappings, "7.19", "Single Pair Flow Mappings", passed, total);
+ RunSpecTest(&Spec::SinglePairExplicitEntry, "7.20", "Single Pair Explicit Entry", passed, total);
+ RunSpecTest(&Spec::SinglePairImplicitEntries, "7.21", "Single Pair Implicit Entries", passed, total);
+ RunSpecTest(&Spec::InvalidImplicitKeys, "7.22", "Invalid Implicit Keys", passed, total);
+ RunSpecTest(&Spec::FlowContent, "7.23", "Flow Content", passed, total);
+ RunSpecTest(&Spec::FlowNodes, "7.24", "FlowNodes", passed, total);
+
+ RunSpecTest(&Spec::BlockScalarHeader, "8.1", "Block Scalar Header", passed, total);
+ RunSpecTest(&Spec::BlockIndentationHeader, "8.2", "Block Indentation Header", passed, total);
+ RunSpecTest(&Spec::InvalidBlockScalarIndentationIndicators, "8.3", "Invalid Block Scalar Indentation Indicators", passed, total);
+ RunSpecTest(&Spec::ChompingFinalLineBreak, "8.4", "Chomping Final Line Break", passed, total);
+ RunSpecTest(&Spec::ChompingTrailingLines, "8.5", "Chomping Trailing Lines", passed, total);
+ RunSpecTest(&Spec::EmptyScalarChomping, "8.6", "Empty Scalar Chomping", passed, total);
+ RunSpecTest(&Spec::LiteralScalar, "8.7", "Literal Scalar", passed, total);
+ RunSpecTest(&Spec::LiteralContent, "8.8", "Literal Content", passed, total);
+ RunSpecTest(&Spec::FoldedScalar, "8.9", "Folded Scalar", passed, total);
+ RunSpecTest(&Spec::FoldedLines, "8.10", "Folded Lines", passed, total);
+ RunSpecTest(&Spec::MoreIndentedLines, "8.11", "More Indented Lines", passed, total);
+ RunSpecTest(&Spec::EmptySeparationLines, "8.12", "Empty Separation Lines", passed, total);
+ RunSpecTest(&Spec::FinalEmptyLines, "8.13", "Final Empty Lines", passed, total);
+ RunSpecTest(&Spec::BlockSequence, "8.14", "Block Sequence", passed, total);
+ RunSpecTest(&Spec::BlockSequenceEntryTypes, "8.15", "Block Sequence Entry Types", passed, total);
+ RunSpecTest(&Spec::BlockMappings, "8.16", "Block Mappings", passed, total);
+ RunSpecTest(&Spec::ExplicitBlockMappingEntries, "8.17", "Explicit Block Mapping Entries", passed, total);
+ RunSpecTest(&Spec::ImplicitBlockMappingEntries, "8.18", "Implicit Block Mapping Entries", passed, total);
+ RunSpecTest(&Spec::CompactBlockMappings, "8.19", "Compact Block Mappings", passed, total);
+ RunSpecTest(&Spec::BlockNodeTypes, "8.20", "Block Node Types", passed, total);
+ RunSpecTest(&Spec::BlockScalarNodes, "8.21", "Block Scalar Nodes", passed, total);
+ RunSpecTest(&Spec::BlockCollectionNodes, "8.22", "Block Collection Nodes", passed, total);
+
+ std::cout << "Spec tests: " << passed << "/" << total << " passed\n";
+ return passed == total;
+ }
+}
diff --git a/external_libs/yaml-cpp/test/spectests.h b/external_libs/yaml-cpp/test/spectests.h
new file mode 100644
index 00000000..5246df58
--- /dev/null
+++ b/external_libs/yaml-cpp/test/spectests.h
@@ -0,0 +1,360 @@
+#ifndef SPECTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define SPECTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <string>
+
+namespace Test {
+ struct TEST {
+ TEST(): ok(false) {}
+ TEST(bool ok_): ok(ok_) {}
+ TEST(const char *error_): ok(false), error(error_) {}
+
+ bool ok;
+ std::string error;
+ };
+
+ namespace Spec {
+ // 2.1
+ TEST SeqScalars();
+
+ // 2.2
+ TEST MappingScalarsToScalars();
+
+ // 2.3
+ TEST MappingScalarsToSequences();
+
+ // 2.4
+ TEST SequenceOfMappings();
+
+ // 2.5
+ TEST SequenceOfSequences();
+
+ // 2.6
+ TEST MappingOfMappings();
+
+ // 2.7
+ TEST TwoDocumentsInAStream();
+
+ // 2.8
+ TEST PlayByPlayFeed();
+
+ // 2.9
+ TEST SingleDocumentWithTwoComments();
+
+ // 2.10
+ TEST SimpleAnchor();
+
+ // 2.11
+ TEST MappingBetweenSequences();
+
+ // 2.12
+ TEST CompactNestedMapping();
+
+ // 2.13
+ TEST InLiteralsNewlinesArePreserved();
+
+ // 2.14
+ TEST InFoldedScalarsNewlinesBecomeSpaces();
+
+ // 2.15
+ TEST FoldedNewlinesArePreservedForMoreIndentedAndBlankLines();
+
+ // 2.16
+ TEST IndentationDeterminesScope();
+
+ // 2.17
+ TEST QuotedScalars();
+
+ // 2.18
+ TEST MultiLineFlowScalars();
+
+ // TODO: 2.19 - 2.22 schema tags
+
+ // 2.23
+ TEST VariousExplicitTags();
+
+ // 2.24
+ TEST GlobalTags();
+
+ // 2.25
+ TEST UnorderedSets();
+
+ // 2.26
+ TEST OrderedMappings();
+
+ // 2.27
+ TEST Invoice();
+
+ // 2.28
+ TEST LogFile();
+
+ // TODO: 5.1 - 5.2 BOM
+
+ // 5.3
+ TEST BlockStructureIndicators();
+
+ // 5.4
+ TEST FlowStructureIndicators();
+
+ // 5.5
+ TEST CommentIndicator();
+
+ // 5.6
+ TEST NodePropertyIndicators();
+
+ // 5.7
+ TEST BlockScalarIndicators();
+
+ // 5.8
+ TEST QuotedScalarIndicators();
+
+ // TODO: 5.9 directive
+ // TODO: 5.10 reserved indicator
+
+ // 5.11
+ TEST LineBreakCharacters();
+
+ // 5.12
+ TEST TabsAndSpaces();
+
+ // 5.13
+ TEST EscapedCharacters();
+
+ // 5.14
+ TEST InvalidEscapedCharacters();
+
+ // 6.1
+ TEST IndentationSpaces();
+
+ // 6.2
+ TEST IndentationIndicators();
+
+ // 6.3
+ TEST SeparationSpaces();
+
+ // 6.4
+ TEST LinePrefixes();
+
+ // 6.5
+ TEST EmptyLines();
+
+ // 6.6
+ TEST LineFolding();
+
+ // 6.7
+ TEST BlockFolding();
+
+ // 6.8
+ TEST FlowFolding();
+
+ // 6.9
+ TEST SeparatedComment();
+
+ // 6.10
+ TEST CommentLines();
+
+ // 6.11
+ TEST MultiLineComments();
+
+ // 6.12
+ TEST SeparationSpacesII();
+
+ // 6.13
+ TEST ReservedDirectives();
+
+ // 6.14
+ TEST YAMLDirective();
+
+ // 6.15
+ TEST InvalidRepeatedYAMLDirective();
+
+ // 6.16
+ TEST TagDirective();
+
+ // 6.17
+ TEST InvalidRepeatedTagDirective();
+
+ // 6.18
+ TEST PrimaryTagHandle();
+
+ // 6.19
+ TEST SecondaryTagHandle();
+
+ // 6.20
+ TEST TagHandles();
+
+ // 6.21
+ TEST LocalTagPrefix();
+
+ // 6.22
+ TEST GlobalTagPrefix();
+
+ // 6.23
+ TEST NodeProperties();
+
+ // 6.24
+ TEST VerbatimTags();
+
+ // 6.25
+ TEST InvalidVerbatimTags();
+
+ // 6.26
+ TEST TagShorthands();
+
+ // 6.27
+ TEST InvalidTagShorthands();
+
+ // 6.28
+ TEST NonSpecificTags();
+
+ // 6.29
+ TEST NodeAnchors();
+
+ // 7.1
+ TEST AliasNodes();
+
+ // 7.2
+ TEST EmptyNodes();
+
+ // 7.3
+ TEST CompletelyEmptyNodes();
+
+ // 7.4
+ TEST DoubleQuotedImplicitKeys();
+
+ // 7.5
+ TEST DoubleQuotedLineBreaks();
+
+ // 7.6
+ TEST DoubleQuotedLines();
+
+ // 7.7
+ TEST SingleQuotedCharacters();
+
+ // 7.8
+ TEST SingleQuotedImplicitKeys();
+
+ // 7.9
+ TEST SingleQuotedLines();
+
+ // 7.10
+ TEST PlainCharacters();
+
+ // 7.11
+ TEST PlainImplicitKeys();
+
+ // 7.12
+ TEST PlainLines();
+
+ // 7.13
+ TEST FlowSequence();
+
+ // 7.14
+ TEST FlowSequenceEntries();
+
+ // 7.15
+ TEST FlowMappings();
+
+ // 7.16
+ TEST FlowMappingEntries();
+
+ // 7.17
+ TEST FlowMappingSeparateValues();
+
+ // 7.18
+ TEST FlowMappingAdjacentValues();
+
+ // 7.19
+ TEST SinglePairFlowMappings();
+
+ // 7.20
+ TEST SinglePairExplicitEntry();
+
+ // 7.21
+ TEST SinglePairImplicitEntries();
+
+ // 7.22
+ TEST InvalidImplicitKeys();
+
+ // 7.23
+ TEST FlowContent();
+
+ // 7.24
+ TEST FlowNodes();
+
+ // 8.1
+ TEST BlockScalarHeader();
+
+ // 8.2
+ TEST BlockIndentationHeader();
+
+ // 8.3
+ TEST InvalidBlockScalarIndentationIndicators();
+
+ // 8.4
+ TEST ChompingFinalLineBreak();
+
+ // 8.5
+ TEST ChompingTrailingLines();
+
+ // 8.6
+ TEST EmptyScalarChomping();
+
+ // 8.7
+ TEST LiteralScalar();
+
+ // 8.8
+ TEST LiteralContent();
+
+ // 8.9
+ TEST FoldedScalar();
+
+ // 8.10
+ TEST FoldedLines();
+
+ // 8.11
+ TEST MoreIndentedLines();
+
+ // 8.12
+ TEST EmptySeparationLines();
+
+ // 8.13
+ TEST FinalEmptyLines();
+
+ // 8.14
+ TEST BlockSequence();
+
+ // 8.15
+ TEST BlockSequenceEntryTypes();
+
+ // 8.16
+ TEST BlockMappings();
+
+ // 8.17
+ TEST ExplicitBlockMappingEntries();
+
+ // 8.18
+ TEST ImplicitBlockMappingEntries();
+
+ // 8.19
+ TEST CompactBlockMappings();
+
+ // 8.20
+ TEST BlockNodeTypes();
+
+ // 8.21
+ TEST BlockScalarNodes();
+
+ // 8.22
+ TEST BlockCollectionNodes();
+ }
+
+ bool RunSpecTests();
+}
+
+#endif // SPECTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
diff --git a/external_libs/yaml-cpp/test/tests.cpp b/external_libs/yaml-cpp/test/tests.cpp
new file mode 100644
index 00000000..2dff6eeb
--- /dev/null
+++ b/external_libs/yaml-cpp/test/tests.cpp
@@ -0,0 +1,30 @@
+#include "tests.h"
+#include "emittertests.h"
+#include "nodetests.h"
+#include "parsertests.h"
+#include "spectests.h"
+#include "yaml-cpp/yaml.h"
+#include <fstream>
+#include <sstream>
+#include <vector>
+#include <iostream>
+
+namespace Test
+{
+ void RunAll()
+ {
+ bool passed = true;
+ if(!RunParserTests())
+ passed = false;
+
+ if(!RunEmitterTests())
+ passed = false;
+
+ if(!RunSpecTests())
+ passed = false;
+
+ if(passed)
+ std::cout << "All tests passed!\n";
+ }
+}
+
diff --git a/external_libs/yaml-cpp/test/tests.h b/external_libs/yaml-cpp/test/tests.h
new file mode 100644
index 00000000..757dbc53
--- /dev/null
+++ b/external_libs/yaml-cpp/test/tests.h
@@ -0,0 +1,53 @@
+#ifndef TESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define TESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <string>
+
+namespace Test {
+ void RunAll();
+
+ namespace Parser {
+ // scalar tests
+ void SimpleScalar(std::string& inputScalar, std::string& desiredOutput);
+ void MultiLineScalar(std::string& inputScalar, std::string& desiredOutput);
+ void LiteralScalar(std::string& inputScalar, std::string& desiredOutput);
+ void FoldedScalar(std::string& inputScalar, std::string& desiredOutput);
+ void ChompedFoldedScalar(std::string& inputScalar, std::string& desiredOutput);
+ void ChompedLiteralScalar(std::string& inputScalar, std::string& desiredOutput);
+ void FoldedScalarWithIndent(std::string& inputScalar, std::string& desiredOutput);
+ void ColonScalar(std::string& inputScalar, std::string& desiredOutput);
+ void QuotedScalar(std::string& inputScalar, std::string& desiredOutput);
+ void CommaScalar(std::string& inputScalar, std::string& desiredOutput);
+ void DashScalar(std::string& inputScalar, std::string& desiredOutput);
+ void URLScalar(std::string& inputScalar, std::string& desiredOutput);
+
+ // misc tests
+ bool SimpleSeq();
+ bool SimpleMap();
+ bool FlowSeq();
+ bool FlowMap();
+ bool FlowMapWithOmittedKey();
+ bool FlowMapWithOmittedValue();
+ bool FlowMapWithSoloEntry();
+ bool FlowMapEndingWithSoloEntry();
+ bool QuotedSimpleKeys();
+ bool CompressedMapAndSeq();
+ bool NullBlockSeqEntry();
+ bool NullBlockMapKey();
+ bool NullBlockMapValue();
+ bool SimpleAlias();
+ bool AliasWithNull();
+ bool AnchorInSimpleKey();
+ bool AliasAsSimpleKey();
+ bool ExplicitDoc();
+ bool MultipleDocs();
+ bool ExplicitEndDoc();
+ bool MultipleDocsWithSomeExplicitIndicators();
+ }
+}
+
+#endif // TESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/external_libs/yaml-cpp/util/CMakeLists.txt b/external_libs/yaml-cpp/util/CMakeLists.txt
new file mode 100644
index 00000000..22339f02
--- /dev/null
+++ b/external_libs/yaml-cpp/util/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_executable(parse parse.cpp)
+target_link_libraries(parse yaml-cpp)
diff --git a/external_libs/yaml-cpp/util/api.cpp b/external_libs/yaml-cpp/util/api.cpp
new file mode 100644
index 00000000..e5180a8a
--- /dev/null
+++ b/external_libs/yaml-cpp/util/api.cpp
@@ -0,0 +1,129 @@
+// a sketch of what the new API might look like
+
+#include "yaml-cpp/yaml.h"
+#include <iostream>
+
+int main()
+{
+ {
+ // test.yaml
+ // - foo
+ // - primes: [2, 3, 5, 7, 11]
+ // odds: [1, 3, 5, 7, 9, 11]
+ // - [x, y]
+
+ // move-like semantics
+ YAML::Value root = YAML::Parse("test.yaml");
+
+ std::cout << root[0].as<std::string>(); // "foo"
+ std::cout << str(root[0]); // "foo", shorthand?
+ std::cout << root[1]["primes"][3].as<int>(); // "7"
+ std::cout << root[1]["odds"][6].as<int>(); // throws?
+
+ root[2].push_back(5);
+ root[3] = "Hello, World";
+ root[0].reset();
+ root[0]["key"] = "value";
+
+ std::cout << root;
+ // # not sure about formatting
+ // - {key: value}
+ // - primes: [2, 3, 5, 7, 11]
+ // odds: [1, 3, 5, 7, 9, 11]
+ // - [x, y, 5]
+ // - Hello, World
+ }
+
+ {
+ // for all copy-like commands, think of python's "name/value" semantics
+ YAML::Value root = "Hello"; // Hello
+ root = YAML::Sequence(); // []
+ root[0] = 0; // [0]
+ root[2] = "two"; // [0, ~, two] # forces root[1] to be initialized to null
+
+ YAML::Value other = root; // both point to the same thing
+ other[0] = 5; // now root[0] is 0 also
+ other.push_back(root); // &1 [5, ~, two, *1]
+ other[3][0] = 0; // &1 [0, ~, two, *1] # since it's a true alias
+ other.push_back(Copy(root)); // &1 [0, ~, two, *1, &2 [0, ~, two, *2]]
+ other[4][0] = 5; // &1 [0, ~, two, *1, &2 [5, ~, two, *2]] # they're really different
+ }
+
+ {
+ YAML::Value node; // ~
+ node[0] = 1; // [1] # auto-construct a sequence
+ node["key"] = 5; // {0: 1, key: 5} # auto-turn it into a map
+ node.push_back(10); // error, can't turn a map into a sequence
+ node.erase("key"); // {0: 1} # still a map, even if we remove the key that caused the problem
+ node = "Hello"; // Hello # assignment overwrites everything, so it's now just a plain scalar
+ }
+
+ {
+ YAML::Value map; // ~
+ map[3] = 1; // {3: 1} # auto-constructs a map, *not* a sequence
+
+ YAML::Value seq; // ~
+ seq = YAML::Sequence(); // []
+ seq[3] = 1; // [~, ~, ~, 1]
+ }
+
+ {
+ YAML::Value node; // ~
+ node[0] = node; // &1 [*1] # fun stuff
+ }
+
+ {
+ YAML::Value node;
+ YAML::Value subnode = node["key"]; // 'subnode' is not instantiated ('node' is still null)
+ subnode = "value"; // {key: value} # now it is
+ YAML::Value subnode2 = node["key2"];
+ node["key3"] = subnode2; // subnode2 is still not instantiated, but node["key3"] is "pseudo" aliased to it
+ subnode2 = "monkey"; // {key: value, key2: &1 monkey, key3: *1} # bam! it instantiates both
+ }
+
+ {
+ YAML::Value seq = YAML::Sequence();
+ seq[0] = "zero"; // [zero]
+ seq[1] = seq[0]; // [&1 zero, *1]
+ seq[0] = seq[1]; // [&1 zero, *1] # no-op (they both alias the same thing, so setting them equal is nothing)
+ Is(seq[0], seq[1]); // true
+ seq[1] = "one"; // [&1 one, *1]
+ UnAlias(seq[1]); // [one, one]
+ Is(seq[0], seq[1]); // false
+ }
+
+ {
+ YAML::Value root;
+ root.push_back("zero");
+ root.push_back("one");
+ root.push_back("two");
+ YAML::Value two = root[2];
+ root = "scalar"; // 'two' is still "two", even though 'root' is "scalar" (the sequence effectively no longer exists)
+
+ // Note: in all likelihood, the memory for nodes "zero" and "one" is still allocated. How can it go away? Weak pointers?
+ }
+
+ {
+ YAML::Value root; // ~
+ root[0] = root; // &1 [*1]
+ root[0] = 5; // [5]
+ }
+
+ {
+ YAML::Value root;
+ YAML::Value key;
+ key["key"] = "value";
+ root[key] = key; // &1 {key: value}: *1
+ }
+
+ {
+ YAML::Value root;
+ root[0] = "hi";
+ root[1][0] = "bye";
+ root[1][1] = root; // &1 [hi, [bye, *1]] # root
+ YAML::Value sub = root[1]; // &1 [bye, [hi, *1]] # sub
+ root = "gone"; // [bye, gone] # sub
+ }
+
+ return 0;
+}
diff --git a/external_libs/yaml-cpp/util/parse.cpp b/external_libs/yaml-cpp/util/parse.cpp
new file mode 100644
index 00000000..d02a76a7
--- /dev/null
+++ b/external_libs/yaml-cpp/util/parse.cpp
@@ -0,0 +1,65 @@
+#include "yaml-cpp/yaml.h"
+#include "yaml-cpp/eventhandler.h"
+#include <fstream>
+#include <iostream>
+#include <vector>
+
+struct Params {
+ bool hasFile;
+ std::string fileName;
+};
+
+Params ParseArgs(int argc, char **argv) {
+ Params p;
+
+ std::vector<std::string> args(argv + 1, argv + argc);
+
+ return p;
+}
+
+class NullEventHandler: public YAML::EventHandler
+{
+public:
+ virtual void OnDocumentStart(const YAML::Mark&) {}
+ virtual void OnDocumentEnd() {}
+
+ virtual void OnNull(const YAML::Mark&, YAML::anchor_t) {}
+ virtual void OnAlias(const YAML::Mark&, YAML::anchor_t) {}
+ virtual void OnScalar(const YAML::Mark&, const std::string&, YAML::anchor_t, const std::string&) {}
+
+ virtual void OnSequenceStart(const YAML::Mark&, const std::string&, YAML::anchor_t) {}
+ virtual void OnSequenceEnd() {}
+
+ virtual void OnMapStart(const YAML::Mark&, const std::string&, YAML::anchor_t) {}
+ virtual void OnMapEnd() {}
+};
+
+void parse(std::istream& input)
+{
+ try {
+ YAML::Parser parser(input);
+ YAML::Node doc;
+ while(parser.GetNextDocument(doc)) {
+ YAML::Emitter emitter;
+ emitter << doc;
+ std::cout << emitter.c_str() << "\n";
+ }
+ } catch(const YAML::Exception& e) {
+ std::cerr << e.what() << "\n";
+ }
+}
+
+int main(int argc, char **argv)
+{
+ Params p = ParseArgs(argc, argv);
+
+ if(argc > 1) {
+ std::ifstream fin;
+ fin.open(argv[1]);
+ parse(fin);
+ } else {
+ parse(std::cin);
+ }
+
+ return 0;
+}
diff --git a/external_libs/yaml-cpp/yaml-cpp.pc.cmake b/external_libs/yaml-cpp/yaml-cpp.pc.cmake
new file mode 100644
index 00000000..04d343f6
--- /dev/null
+++ b/external_libs/yaml-cpp/yaml-cpp.pc.cmake
@@ -0,0 +1,11 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=@CMAKE_INSTALL_PREFIX@
+libdir=${prefix}/@LIB_INSTALL_DIR@
+includedir=${prefix}/@INCLUDE_INSTALL_ROOT_DIR@
+
+Name: Yaml-cpp
+Description: A YAML parser and emitter for C++
+Version: @YAML_CPP_VERSION@
+Requires:
+Libs: -L${libdir} -lyaml-cpp
+Cflags: -I${includedir}