Import yaml-cpp_0.5.1.orig.tar.gz
authorLifeng Sun <lifongsun@gmail.com>
Fri, 30 Aug 2013 10:29:05 +0000 (11:29 +0100)
committerLifeng Sun <lifongsun@gmail.com>
Fri, 30 Aug 2013 10:29:05 +0000 (11:29 +0100)
[dgit import orig yaml-cpp_0.5.1.orig.tar.gz]

117 files changed:
CMakeLists.txt [new file with mode: 0644]
include/yaml-cpp/anchor.h [new file with mode: 0644]
include/yaml-cpp/binary.h [new file with mode: 0644]
include/yaml-cpp/contrib/anchordict.h [new file with mode: 0644]
include/yaml-cpp/contrib/graphbuilder.h [new file with mode: 0644]
include/yaml-cpp/dll.h [new file with mode: 0644]
include/yaml-cpp/emitfromevents.h [new file with mode: 0644]
include/yaml-cpp/emitter.h [new file with mode: 0644]
include/yaml-cpp/emitterdef.h [new file with mode: 0644]
include/yaml-cpp/emittermanip.h [new file with mode: 0644]
include/yaml-cpp/eventhandler.h [new file with mode: 0644]
include/yaml-cpp/exceptions.h [new file with mode: 0644]
include/yaml-cpp/mark.h [new file with mode: 0644]
include/yaml-cpp/node/convert.h [new file with mode: 0644]
include/yaml-cpp/node/detail/bool_type.h [new file with mode: 0644]
include/yaml-cpp/node/detail/impl.h [new file with mode: 0644]
include/yaml-cpp/node/detail/iterator.h [new file with mode: 0644]
include/yaml-cpp/node/detail/iterator_fwd.h [new file with mode: 0644]
include/yaml-cpp/node/detail/memory.h [new file with mode: 0644]
include/yaml-cpp/node/detail/node.h [new file with mode: 0644]
include/yaml-cpp/node/detail/node_data.h [new file with mode: 0644]
include/yaml-cpp/node/detail/node_iterator.h [new file with mode: 0644]
include/yaml-cpp/node/detail/node_ref.h [new file with mode: 0644]
include/yaml-cpp/node/emit.h [new file with mode: 0644]
include/yaml-cpp/node/impl.h [new file with mode: 0644]
include/yaml-cpp/node/iterator.h [new file with mode: 0644]
include/yaml-cpp/node/node.h [new file with mode: 0644]
include/yaml-cpp/node/parse.h [new file with mode: 0644]
include/yaml-cpp/node/ptr.h [new file with mode: 0644]
include/yaml-cpp/node/type.h [new file with mode: 0644]
include/yaml-cpp/noncopyable.h [new file with mode: 0644]
include/yaml-cpp/null.h [new file with mode: 0644]
include/yaml-cpp/ostream_wrapper.h [new file with mode: 0644]
include/yaml-cpp/parser.h [new file with mode: 0644]
include/yaml-cpp/stlemitter.h [new file with mode: 0644]
include/yaml-cpp/traits.h [new file with mode: 0644]
include/yaml-cpp/yaml.h [new file with mode: 0644]
install.txt [new file with mode: 0644]
license.txt [new file with mode: 0644]
src/binary.cpp [new file with mode: 0644]
src/collectionstack.h [new file with mode: 0644]
src/contrib/graphbuilder.cpp [new file with mode: 0644]
src/contrib/graphbuilderadapter.cpp [new file with mode: 0644]
src/contrib/graphbuilderadapter.h [new file with mode: 0644]
src/convert.cpp [new file with mode: 0644]
src/directives.cpp [new file with mode: 0644]
src/directives.h [new file with mode: 0644]
src/emit.cpp [new file with mode: 0644]
src/emitfromevents.cpp [new file with mode: 0644]
src/emitter.cpp [new file with mode: 0644]
src/emitterstate.cpp [new file with mode: 0644]
src/emitterstate.h [new file with mode: 0644]
src/emitterutils.cpp [new file with mode: 0644]
src/emitterutils.h [new file with mode: 0644]
src/exp.cpp [new file with mode: 0644]
src/exp.h [new file with mode: 0644]
src/indentation.h [new file with mode: 0644]
src/memory.cpp [new file with mode: 0644]
src/node.cpp [new file with mode: 0644]
src/node_data.cpp [new file with mode: 0644]
src/nodebuilder.cpp [new file with mode: 0644]
src/nodebuilder.h [new file with mode: 0644]
src/nodeevents.cpp [new file with mode: 0644]
src/nodeevents.h [new file with mode: 0644]
src/null.cpp [new file with mode: 0644]
src/ostream_wrapper.cpp [new file with mode: 0644]
src/parse.cpp [new file with mode: 0644]
src/parser.cpp [new file with mode: 0644]
src/ptr_stack.h [new file with mode: 0644]
src/ptr_vector.h [new file with mode: 0644]
src/regex.cpp [new file with mode: 0644]
src/regex.h [new file with mode: 0644]
src/regeximpl.h [new file with mode: 0644]
src/scanner.cpp [new file with mode: 0644]
src/scanner.h [new file with mode: 0644]
src/scanscalar.cpp [new file with mode: 0644]
src/scanscalar.h [new file with mode: 0644]
src/scantag.cpp [new file with mode: 0644]
src/scantag.h [new file with mode: 0644]
src/scantoken.cpp [new file with mode: 0644]
src/setting.h [new file with mode: 0644]
src/simplekey.cpp [new file with mode: 0644]
src/singledocparser.cpp [new file with mode: 0644]
src/singledocparser.h [new file with mode: 0644]
src/stream.cpp [new file with mode: 0644]
src/stream.h [new file with mode: 0644]
src/streamcharsource.h [new file with mode: 0644]
src/stringsource.h [new file with mode: 0644]
src/tag.cpp [new file with mode: 0644]
src/tag.h [new file with mode: 0644]
src/token.h [new file with mode: 0644]
test/CMakeLists.txt [new file with mode: 0644]
test/core/parsertests.cpp [new file with mode: 0644]
test/core/spectests.cpp [new file with mode: 0644]
test/create-emitter-tests.py [new file with mode: 0644]
test/emittertests.cpp [new file with mode: 0644]
test/emittertests.h [new file with mode: 0644]
test/genemittertests.h [new file with mode: 0644]
test/handlermacros.h [new file with mode: 0644]
test/main.cpp [new file with mode: 0644]
test/new-api/nodetests.cpp [new file with mode: 0644]
test/new-api/parsertests.cpp [new file with mode: 0644]
test/new-api/spectests.cpp [new file with mode: 0644]
test/nodetests.h [new file with mode: 0644]
test/parsertests.h [new file with mode: 0644]
test/specexamples.h [new file with mode: 0644]
test/spectests.cpp [new file with mode: 0644]
test/spectests.h [new file with mode: 0644]
test/tests.cpp [new file with mode: 0644]
test/tests.h [new file with mode: 0644]
test/teststruct.h [new file with mode: 0644]
util/CMakeLists.txt [new file with mode: 0644]
util/api.cpp [new file with mode: 0644]
util/parse.cpp [new file with mode: 0644]
util/read.cpp [new file with mode: 0644]
util/sandbox.cpp [new file with mode: 0644]
yaml-cpp.pc.cmake [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..4cefdbf
--- /dev/null
@@ -0,0 +1,285 @@
+###
+### 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 "5")
+set(YAML_CPP_VERSION_PATCH "1")
+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_RECURSE 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}/src)
+include_directories(${YAML_CPP_SOURCE_DIR}/include)
+
+find_package(Boost REQUIRED)
+include_directories(${Boost_INCLUDE_DIRS})
+
+
+###
+### 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/include/yaml-cpp/anchor.h b/include/yaml-cpp/anchor.h
new file mode 100644 (file)
index 0000000..433f2fa
--- /dev/null
@@ -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/include/yaml-cpp/binary.h b/include/yaml-cpp/binary.h
new file mode 100644 (file)
index 0000000..edc0b2c
--- /dev/null
@@ -0,0 +1,62 @@
+#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
+{
+    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;
+    };
+}
+
+#endif // BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/include/yaml-cpp/contrib/anchordict.h b/include/yaml-cpp/contrib/anchordict.h
new file mode 100644 (file)
index 0000000..e483dc4
--- /dev/null
@@ -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/include/yaml-cpp/contrib/graphbuilder.h b/include/yaml-cpp/contrib/graphbuilder.h
new file mode 100644 (file)
index 0000000..6739a12
--- /dev/null
@@ -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/include/yaml-cpp/dll.h b/include/yaml-cpp/dll.h
new file mode 100644 (file)
index 0000000..ea13840
--- /dev/null
@@ -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/include/yaml-cpp/emitfromevents.h b/include/yaml-cpp/emitfromevents.h
new file mode 100644 (file)
index 0000000..e11ae64
--- /dev/null
@@ -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/include/yaml-cpp/emitter.h b/include/yaml-cpp/emitter.h
new file mode 100644 (file)
index 0000000..927fe6c
--- /dev/null
@@ -0,0 +1,209 @@
+#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/emitterdef.h"
+#include "yaml-cpp/emittermanip.h"
+#include "yaml-cpp/noncopyable.h"
+#include "yaml-cpp/null.h"
+#include "yaml-cpp/ostream_wrapper.h"
+#include <memory>
+#include <string>
+#include <sstream>
+
+namespace YAML
+{
+       class EmitterState;
+       
+       class YAML_CPP_API Emitter: private noncopyable
+       {
+       public:
+               Emitter();
+        explicit Emitter(std::ostream& stream);
+               ~Emitter();
+               
+               // output
+               const char *c_str() const;
+        std::size_t 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& n);
+               Emitter& Write(const Binary& binary);
+               
+               template <typename T>
+               Emitter& WriteIntegralType(T value);
+               
+               template <typename T>
+               Emitter& WriteStreamable(T value);
+
+       private:
+        template<typename T> void SetStreamablePrecision(std::stringstream&) {}
+        unsigned GetFloatPrecision() const;
+        unsigned GetDoublePrecision() const;
+        
+        void PrepareIntegralStream(std::stringstream& stream) const;
+        void StartedScalar();
+       
+       private:
+               void EmitBeginDoc();
+               void EmitEndDoc();
+               void EmitBeginSeq();
+               void EmitEndSeq();
+               void EmitBeginMap();
+               void EmitEndMap();
+               void EmitNewline();
+               void EmitKindTag();
+               void EmitTag(bool verbatim, const _Tag& tag);
+               
+        void PrepareNode(EmitterNodeType::value child);
+        void PrepareTopNode(EmitterNodeType::value child);
+        void FlowSeqPrepareNode(EmitterNodeType::value child);
+        void BlockSeqPrepareNode(EmitterNodeType::value child);
+
+        void FlowMapPrepareNode(EmitterNodeType::value child);
+
+        void FlowMapPrepareLongKey(EmitterNodeType::value child);
+        void FlowMapPrepareLongKeyValue(EmitterNodeType::value child);
+        void FlowMapPrepareSimpleKey(EmitterNodeType::value child);
+        void FlowMapPrepareSimpleKeyValue(EmitterNodeType::value child);
+
+        void BlockMapPrepareNode(EmitterNodeType::value child);
+
+        void BlockMapPrepareLongKey(EmitterNodeType::value child);
+        void BlockMapPrepareLongKeyValue(EmitterNodeType::value child);
+        void BlockMapPrepareSimpleKey(EmitterNodeType::value child);
+        void BlockMapPrepareSimpleKeyValue(EmitterNodeType::value child);
+        
+        void SpaceOrIndentTo(bool requireSpace, unsigned indent);
+        
+               const char *ComputeFullBoolName(bool b) const;
+               bool CanEmitNewline() const;
+               
+       private:
+               std::auto_ptr<EmitterState> m_pState;
+               ostream_wrapper m_stream;
+       };
+       
+       template <typename T>
+       inline Emitter& Emitter::WriteIntegralType(T value)
+       {
+               if(!good())
+                       return *this;
+               
+        PrepareNode(EmitterNodeType::Scalar);
+
+        std::stringstream stream;
+        PrepareIntegralStream(stream);
+        stream << value;
+        m_stream << stream.str();
+        
+        StartedScalar();
+
+               return *this;
+       }
+
+       template <typename T>
+       inline Emitter& Emitter::WriteStreamable(T value)
+       {
+               if(!good())
+                       return *this;
+               
+        PrepareNode(EmitterNodeType::Scalar);
+
+               std::stringstream stream;
+        SetStreamablePrecision<T>(stream);
+               stream << value;
+        m_stream << stream.str();
+        
+        StartedScalar();
+
+               return *this;
+       }
+       
+    template<>
+    inline void Emitter::SetStreamablePrecision<float>(std::stringstream& stream)
+    {
+               stream.precision(GetFloatPrecision());
+    }
+
+    template<>
+    inline void Emitter::SetStreamablePrecision<double>(std::stringstream& stream)
+    {
+               stream.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/include/yaml-cpp/emitterdef.h b/include/yaml-cpp/emitterdef.h
new file mode 100644 (file)
index 0000000..c5ca00b
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define EMITTERDEF_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
+{
+    struct EmitterNodeType { enum value { None, Property, Scalar, FlowSeq, BlockSeq, FlowMap, BlockMap }; };
+}
+
+#endif // EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/include/yaml-cpp/emittermanip.h b/include/yaml-cpp/emittermanip.h
new file mode 100644 (file)
index 0000000..a8ec64a
--- /dev/null
@@ -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/include/yaml-cpp/eventhandler.h b/include/yaml-cpp/eventhandler.h
new file mode 100644 (file)
index 0000000..3173a1f
--- /dev/null
@@ -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/include/yaml-cpp/exceptions.h b/include/yaml-cpp/exceptions.h
new file mode 100644 (file)
index 0000000..ffbf7bd
--- /dev/null
@@ -0,0 +1,208 @@
+#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_NODE           = "invalid node; this may result from using a map iterator as a sequence iterator, or vice-versa";
+               const char * const INVALID_SCALAR         = "invalid scalar";
+               const char * const KEY_NOT_FOUND          = "key not found";
+        const char * const BAD_CONVERSION         = "bad conversion";
+               const char * const BAD_DEREFERENCE        = "bad dereference";
+        const char * const BAD_SUBSCRIPT          = "operator[] call on a scalar";
+        const char * const BAD_PUSHBACK           = "appending to a non-sequence";
+        const char * const BAD_INSERT             = "inserting in a non-convertible-to-map";
+               
+               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 BAD_FILE               = "bad file";
+
+               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 InvalidNode: public RepresentationException {
+       public:
+               InvalidNode()
+        : RepresentationException(Mark::null_mark(), ErrorMsg::INVALID_NODE) {}
+       };
+
+    class BadConversion: public RepresentationException {
+       public:
+               BadConversion()
+        : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_CONVERSION) {}
+       };
+
+    template<typename T>
+       class TypedBadConversion: public BadConversion {
+       public:
+               TypedBadConversion()
+        : BadConversion() {}
+       };
+
+       class BadDereference: public RepresentationException {
+       public:
+               BadDereference()
+               : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_DEREFERENCE) {}
+       };
+
+       class BadSubscript: public RepresentationException {
+       public:
+               BadSubscript()
+               : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_SUBSCRIPT) {}
+       };
+
+       class BadPushback: public RepresentationException {
+       public:
+               BadPushback()
+               : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_PUSHBACK) {}
+       };
+       
+       class BadInsert: public RepresentationException {
+       public:
+               BadInsert()
+               : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_INSERT) {}
+       };
+
+       class EmitterException: public Exception {
+       public:
+               EmitterException(const std::string& msg_)
+               : Exception(Mark::null_mark(), msg_) {}
+       };
+    
+    class BadFile: public Exception {
+    public:
+        BadFile(): Exception(Mark::null_mark(), ErrorMsg::BAD_FILE) {}
+    };
+}
+
+#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/include/yaml-cpp/mark.h b/include/yaml-cpp/mark.h
new file mode 100644 (file)
index 0000000..e07b317
--- /dev/null
@@ -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_mark() { 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/include/yaml-cpp/node/convert.h b/include/yaml-cpp/node/convert.h
new file mode 100644 (file)
index 0000000..d73f284
--- /dev/null
@@ -0,0 +1,280 @@
+#ifndef NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODE_CONVERT_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/binary.h"
+#include "yaml-cpp/node/node.h"
+#include "yaml-cpp/node/iterator.h"
+#include "yaml-cpp/null.h"
+#include <limits>
+#include <list>
+#include <map>
+#include <sstream>
+#include <vector>
+
+namespace YAML
+{
+    namespace conversion {
+        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";
+        }
+    }
+    
+       // std::string
+       template<>
+       struct convert<std::string> {
+               static Node encode(const std::string& rhs) {
+                       return Node(rhs);
+               }
+               
+               static bool decode(const Node& node, std::string& rhs) {
+                       if(!node.IsScalar())
+                               return false;
+                       rhs = node.Scalar();
+                       return true;
+               }
+       };
+       
+       // C-strings can only be encoded
+       template<>
+       struct convert<const char *> {
+               static Node encode(const char *&rhs) {
+                       return Node(rhs);
+               }
+       };
+
+       template<std::size_t N>
+       struct convert<const char[N]> {
+               static Node encode(const char (&rhs)[N]) {
+                       return Node(rhs);
+               }
+       };
+
+    template<>
+       struct convert<_Null> {
+               static Node encode(const _Null& /* rhs */) {
+                       return Node();
+               }
+               
+               static bool decode(const Node& node, _Null& /* rhs */) {
+                       return node.IsNull();
+               }
+       };
+       
+#define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op)\
+       template<>\
+       struct convert<type> {\
+               static Node encode(const type& rhs) {\
+                       std::stringstream stream;\
+            stream.precision(std::numeric_limits<type>::digits10 + 1);\
+                       stream << rhs;\
+                       return Node(stream.str());\
+               }\
+               \
+               static bool decode(const Node& node, type& rhs) {\
+                       if(node.Type() != NodeType::Scalar)\
+                               return false;\
+            const std::string& input = node.Scalar();\
+                       std::stringstream stream(input);\
+            stream.unsetf(std::ios::dec);\
+                       if((stream >> rhs) && (stream >> std::ws).eof())\
+                return true;\
+            if(std::numeric_limits<type>::has_infinity) {\
+                if(conversion::IsInfinity(input)) {\
+                    rhs = std::numeric_limits<type>::infinity();\
+                    return true;\
+                } else if(conversion::IsNegativeInfinity(input)) {\
+                    rhs = negative_op std::numeric_limits<type>::infinity();\
+                    return true;\
+                }\
+            }\
+            \
+            if(std::numeric_limits<type>::has_quiet_NaN && conversion::IsNaN(input)) {\
+                rhs = std::numeric_limits<type>::quiet_NaN();\
+                return true;\
+            }\
+            \
+            return false;\
+               }\
+       }
+       
+#define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type)\
+    YAML_DEFINE_CONVERT_STREAMABLE(type, -)
+
+#define YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(type)\
+    YAML_DEFINE_CONVERT_STREAMABLE(type, +)
+
+    YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(int);
+       YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(short);
+       YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long);
+       YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long long);
+       YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned);
+       YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned short);
+       YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long);
+       YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long long);
+       
+       YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(char);
+       YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned char);
+       
+       YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(float);
+       YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(double);
+       YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long double);
+       
+#undef YAML_DEFINE_CONVERT_STREAMABLE_SIGNED
+#undef YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED
+#undef YAML_DEFINE_CONVERT_STREAMABLE
+       
+       // bool
+       template<>
+       struct convert<bool> {
+               static Node encode(bool rhs) {
+                       return rhs ? Node("true") : Node("false");
+               }
+               
+               static bool decode(const Node& node, bool& rhs);
+       };
+
+       // std::map
+       template<typename K, typename V>
+       struct convert<std::map<K, V> > {
+               static Node encode(const std::map<K, V>& rhs) {
+                       Node node(NodeType::Map);
+                       for(typename std::map<K, V>::const_iterator it=rhs.begin();it!=rhs.end();++it)
+                node.force_insert(it->first, it->second);
+                       return node;
+               }
+               
+               static bool decode(const Node& node, std::map<K, V>& rhs) {
+                       if(!node.IsMap())
+                               return false;
+
+                       rhs.clear();
+                       for(const_iterator it=node.begin();it!=node.end();++it)
+#if defined(__GNUC__) && __GNUC__ < 4
+//workaround for GCC 3:
+                               rhs[it->first.template as<K>()] = it->second.template as<V>();
+#else
+                               rhs[it->first.as<K>()] = it->second.as<V>();
+#endif
+                       return true;
+               }
+       };
+       
+       // std::vector
+       template<typename T>
+       struct convert<std::vector<T> > {
+               static Node encode(const std::vector<T>& rhs) {
+                       Node node(NodeType::Sequence);
+                       for(typename std::vector<T>::const_iterator it=rhs.begin();it!=rhs.end();++it)
+                               node.push_back(*it);
+                       return node;
+               }
+               
+               static bool decode(const Node& node, std::vector<T>& rhs) {
+                       if(!node.IsSequence())
+                               return false;
+                       
+                       rhs.clear();
+                       for(const_iterator it=node.begin();it!=node.end();++it)
+#if defined(__GNUC__) && __GNUC__ < 4
+//workaround for GCC 3:
+                               rhs.push_back(it->template as<T>());
+#else
+                               rhs.push_back(it->as<T>());
+#endif
+                       return true;
+               }
+       };
+       
+       // std::list
+       template<typename T>
+       struct convert<std::list<T> > {
+               static Node encode(const std::list<T>& rhs) {
+                       Node node(NodeType::Sequence);
+                       for(typename std::list<T>::const_iterator it=rhs.begin();it!=rhs.end();++it)
+                               node.push_back(*it);
+                       return node;
+               }
+               
+               static bool decode(const Node& node, std::list<T>& rhs) {
+                       if(!node.IsSequence())
+                               return false;
+                       
+                       rhs.clear();
+                       for(const_iterator it=node.begin();it!=node.end();++it)
+#if defined(__GNUC__) && __GNUC__ < 4
+//workaround for GCC 3:
+                               rhs.push_back(it->template as<T>());
+#else
+                               rhs.push_back(it->as<T>());
+#endif
+                       return true;
+               }
+       };
+    
+       // std::pair
+       template<typename T, typename U>
+       struct convert<std::pair<T, U> > {
+               static Node encode(const std::pair<T, U>& rhs) {
+                       Node node(NodeType::Sequence);
+            node.push_back(rhs.first);
+            node.push_back(rhs.second);
+                       return node;
+               }
+               
+               static bool decode(const Node& node, std::pair<T, U>& rhs) {
+                       if(!node.IsSequence())
+                               return false;
+            if (node.size() != 2)
+                return false;
+
+#if defined(__GNUC__) && __GNUC__ < 4
+//workaround for GCC 3:
+                               rhs.first = node[0].template as<T>();
+#else
+                               rhs.first = node[0].as<T>();
+#endif
+#if defined(__GNUC__) && __GNUC__ < 4
+//workaround for GCC 3:
+                               rhs.second = node[1].template as<U>();
+#else
+                               rhs.second = node[1].as<U>();
+#endif
+                       return true;
+               }
+       };
+
+    // binary
+    template<>
+       struct convert<Binary> {
+               static Node encode(const Binary& rhs) {
+            return Node(EncodeBase64(rhs.data(), rhs.size()));
+               }
+               
+               static bool decode(const Node& node, Binary& rhs) {
+                       if(!node.IsScalar())
+                               return false;
+            
+            std::vector<unsigned char> data = DecodeBase64(node.Scalar());
+            if(data.empty() && !node.Scalar().empty())
+                return false;
+            
+            rhs.swap(data);
+            return true;
+               }
+       };
+}
+
+#endif // NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/include/yaml-cpp/node/detail/bool_type.h b/include/yaml-cpp/node/detail/bool_type.h
new file mode 100644 (file)
index 0000000..80ed9a4
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODE_DETAIL_BOOL_TYPE_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
+{
+       namespace detail
+       {
+               struct unspecified_bool {
+                       struct NOT_ALLOWED;
+                       static void true_value(NOT_ALLOWED*) {}
+               };
+               typedef void (*unspecified_bool_type)(unspecified_bool::NOT_ALLOWED*);
+       }
+}
+
+#define YAML_CPP_OPERATOR_BOOL()\
+operator YAML::detail::unspecified_bool_type() const\
+{\
+       return this->operator!() ? 0 : &YAML::detail::unspecified_bool::true_value;\
+}
+
+#endif // NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/include/yaml-cpp/node/detail/impl.h b/include/yaml-cpp/node/detail/impl.h
new file mode 100644 (file)
index 0000000..ce5fd57
--- /dev/null
@@ -0,0 +1,168 @@
+#ifndef NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODE_DETAIL_IMPL_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/node/detail/node.h"
+#include "yaml-cpp/node/detail/node_data.h"
+#include <boost/type_traits.hpp>
+
+namespace YAML
+{
+       namespace detail
+       {
+               template<typename Key, typename Enable = void>
+               struct get_idx {
+                       static node *get(const std::vector<node *>& /* sequence */, const Key& /* key */, shared_memory_holder /* pMemory */) {
+                               return 0;
+                       }
+               };
+
+               template<typename Key>
+               struct get_idx<Key, typename boost::enable_if_c<boost::is_unsigned<Key>::value && !boost::is_same<Key, bool>::value>::type> {
+                       static node *get(const std::vector<node *>& sequence, const Key& key, shared_memory_holder /* pMemory */) {
+                               return key < sequence.size() ? sequence[key] : 0;
+                       }
+
+                       static node *get(std::vector<node *>& sequence, const Key& key, shared_memory_holder pMemory) {
+                               if(key > sequence.size())
+                                       return 0;
+                               if(key == sequence.size())
+                                       sequence.push_back(&pMemory->create_node());
+                               return sequence[key];
+                       }
+               };
+               
+               template<typename Key>
+               struct get_idx<Key, typename boost::enable_if<boost::is_signed<Key> >::type> {
+                       static node *get(const std::vector<node *>& sequence, const Key& key, shared_memory_holder pMemory) {
+                               return key >= 0 ? get_idx<std::size_t>::get(sequence, static_cast<std::size_t>(key), pMemory) : 0;
+                       }
+                       static node *get(std::vector<node *>& sequence, const Key& key, shared_memory_holder pMemory) {
+                               return key >= 0 ? get_idx<std::size_t>::get(sequence, static_cast<std::size_t>(key), pMemory) : 0;
+                       }
+               };
+
+               // indexing
+               template<typename Key>
+               inline node& node_data::get(const Key& key, shared_memory_holder pMemory) const
+               {
+                       switch(m_type) {
+                               case NodeType::Map:
+                                       break;
+                               case NodeType::Undefined:
+                               case NodeType::Null:
+                                       return pMemory->create_node();
+                               case NodeType::Sequence:
+                                       if(node *pNode = get_idx<Key>::get(m_sequence, key, pMemory))
+                                               return *pNode;
+                                       return pMemory->create_node();
+                               case NodeType::Scalar:
+                    throw BadSubscript();
+                       }
+
+                       for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
+                               if(equals(*it->first, key, pMemory))
+                                       return *it->second;
+                       }
+                       
+                       return pMemory->create_node();
+               }
+               
+               template<typename Key>
+               inline node& node_data::get(const Key& key, shared_memory_holder pMemory)
+               {
+                       switch(m_type) {
+                               case NodeType::Map:
+                                       break;
+                               case NodeType::Undefined:
+                               case NodeType::Null:
+                               case NodeType::Sequence:
+                                       if(node *pNode = get_idx<Key>::get(m_sequence, key, pMemory)) {
+                                               m_type = NodeType::Sequence;
+                                               return *pNode;
+                                       }
+                                       
+                                       convert_to_map(pMemory);
+                                       break;
+                               case NodeType::Scalar:
+                    throw BadSubscript();
+                       }
+                       
+                       for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
+                               if(equals(*it->first, key, pMemory))
+                                       return *it->second;
+                       }
+                       
+                       node& k = convert_to_node(key, pMemory);
+                       node& v = pMemory->create_node();
+                       insert_map_pair(k, v);
+                       return v;
+               }
+               
+               template<typename Key>
+               inline bool node_data::remove(const Key& key, shared_memory_holder pMemory)
+               {
+                       if(m_type != NodeType::Map)
+                               return false;
+                       
+                       for(node_map::iterator it=m_map.begin();it!=m_map.end();++it) {
+                               if(equals(*it->first, key, pMemory)) {
+                                       m_map.erase(it);
+                                       return true;
+                               }
+                       }
+                       
+                       return false;
+               }
+        
+        // map
+        template<typename Key, typename Value>
+        inline void node_data::force_insert(const Key& key, const Value& value, shared_memory_holder pMemory)
+        {
+                       switch(m_type) {
+                               case NodeType::Map:
+                                       break;
+                               case NodeType::Undefined:
+                               case NodeType::Null:
+                               case NodeType::Sequence:
+                                       convert_to_map(pMemory);
+                                       break;
+                               case NodeType::Scalar:
+                    throw BadInsert();
+                       }
+                       
+                       node& k = convert_to_node(key, pMemory);
+                       node& v = convert_to_node(value, pMemory);
+                       insert_map_pair(k, v);
+        }
+
+               template<typename T>
+               inline bool node_data::equals(node& node, const T& rhs, shared_memory_holder pMemory)
+               {
+                       T lhs;
+                       if(convert<T>::decode(Node(node, pMemory), lhs))
+                               return lhs == rhs;
+                       return false;
+               }
+               
+               inline bool node_data::equals(node& node, const char *rhs, shared_memory_holder pMemory)
+               {
+            return equals<std::string>(node, rhs, pMemory);
+               }
+
+        template<typename T>
+               inline node& node_data::convert_to_node(const T& rhs, shared_memory_holder pMemory)
+               {
+                       Node value = convert<T>::encode(rhs);
+                       value.EnsureNodeExists();
+                       pMemory->merge(*value.m_pMemory);
+                       return *value.m_pNode;
+               }
+       }
+}
+
+#endif // NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/include/yaml-cpp/node/detail/iterator.h b/include/yaml-cpp/node/detail/iterator.h
new file mode 100644 (file)
index 0000000..dc699f4
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define VALUE_DETAIL_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 "yaml-cpp/node/ptr.h"
+#include "yaml-cpp/node/detail/node_iterator.h"
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/utility.hpp>
+
+namespace YAML
+{
+       namespace detail
+       {
+               struct iterator_value;
+
+               template<typename V>
+               class iterator_base: public boost::iterator_adaptor<
+               iterator_base<V>,
+               node_iterator,
+               V,
+               std::forward_iterator_tag,
+               V>
+               {
+               private:
+                       template<typename> friend class iterator_base;
+                       struct enabler {};
+                       typedef typename iterator_base::base_type base_type;
+            
+        public:
+                       typedef typename iterator_base::value_type value_type;
+                       
+               public:
+                       iterator_base() {}
+                       explicit iterator_base(base_type rhs, shared_memory_holder pMemory): iterator_base::iterator_adaptor_(rhs), m_pMemory(pMemory) {}
+                       
+                       template<class W>
+                       iterator_base(const iterator_base<W>& rhs, typename boost::enable_if<boost::is_convertible<W*, V*>, enabler>::type = enabler()): iterator_base::iterator_adaptor_(rhs.base()), m_pMemory(rhs.m_pMemory) {}
+               
+               private:
+                       friend class boost::iterator_core_access;
+
+                       void increment() { this->base_reference() = boost::next(this->base()); }
+                       
+                       value_type dereference() const {
+                               const typename base_type::value_type& v = *this->base();
+                               if(v.pNode)
+                                       return value_type(Node(*v, m_pMemory));
+                               if(v.first && v.second)
+                                       return value_type(Node(*v.first, m_pMemory), Node(*v.second, m_pMemory));
+                               return value_type();
+                       }
+               
+               private:
+                       shared_memory_holder m_pMemory;
+               };
+       }
+}
+
+#endif // VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/include/yaml-cpp/node/detail/iterator_fwd.h b/include/yaml-cpp/node/detail/iterator_fwd.h
new file mode 100644 (file)
index 0000000..c4efb2c
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define VALUE_DETAIL_ITERATOR_FWD_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 <list>
+#include <utility>
+#include <vector>
+
+namespace YAML
+{
+       class node;
+       
+       namespace detail {
+               struct iterator_value;
+               template<typename V> class iterator_base;
+       }
+
+       typedef detail::iterator_base<detail::iterator_value> iterator;
+       typedef detail::iterator_base<const detail::iterator_value> const_iterator;
+}
+
+#endif // VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/include/yaml-cpp/node/detail/memory.h b/include/yaml-cpp/node/detail/memory.h
new file mode 100644 (file)
index 0000000..243a81a
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define VALUE_DETAIL_MEMORY_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/node/ptr.h"
+#include <set>
+#include <boost/shared_ptr.hpp>
+
+namespace YAML
+{
+       namespace detail
+       {
+               class memory {
+               public:
+                       node& create_node();
+                       void merge(const memory& rhs);
+                       
+               private:
+                       typedef std::set<shared_node> Nodes;
+                       Nodes m_nodes;
+               };
+
+               class memory_holder {
+               public:
+                       memory_holder(): m_pMemory(new memory) {}
+                       
+                       node& create_node() { return m_pMemory->create_node(); }
+                       void merge(memory_holder& rhs);
+                       
+               private:
+                       boost::shared_ptr<memory> m_pMemory;
+               };
+       }
+}
+
+#endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/include/yaml-cpp/node/detail/node.h b/include/yaml-cpp/node/detail/node.h
new file mode 100644 (file)
index 0000000..ce3a76d
--- /dev/null
@@ -0,0 +1,130 @@
+#ifndef NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODE_DETAIL_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/node/type.h"
+#include "yaml-cpp/node/ptr.h"
+#include "yaml-cpp/node/detail/node_ref.h"
+#include <set>
+#include <boost/utility.hpp>
+
+namespace YAML
+{
+       namespace detail
+       {
+               class node: private boost::noncopyable
+               {
+               public:
+                       node(): m_pRef(new node_ref) {}
+
+                       bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; }
+                       const node_ref *ref() const { return m_pRef.get(); }
+                       
+                       bool is_defined() const { return m_pRef->is_defined(); }
+                       NodeType::value type() const { return m_pRef->type(); }
+                       
+                       const std::string& scalar() const { return m_pRef->scalar(); }
+                       const std::string& tag() const { return m_pRef->tag(); }
+                       
+                       void mark_defined() {
+                               if(is_defined())
+                                       return;
+                               
+                               m_pRef->mark_defined();
+                               for(nodes::iterator it=m_dependencies.begin();it!=m_dependencies.end();++it)
+                                       (*it)->mark_defined();
+                               m_dependencies.clear();
+                       }
+                       
+                       void add_dependency(node& rhs) {
+                               if(is_defined())
+                                       rhs.mark_defined();
+                               else
+                                       m_dependencies.insert(&rhs);
+                       }
+                       
+                       void set_ref(const node& rhs) {
+                               if(rhs.is_defined())
+                                       mark_defined();
+                               m_pRef = rhs.m_pRef;
+                       }
+                       void set_data(const node& rhs) {
+                               if(rhs.is_defined())
+                                       mark_defined();
+                               m_pRef->set_data(*rhs.m_pRef);
+                       }
+                               
+                       void set_type(NodeType::value type) {
+                               if(type != NodeType::Undefined)
+                                       mark_defined();
+                               m_pRef->set_type(type);
+                       }
+                       void set_null() {
+                               mark_defined();
+                               m_pRef->set_null();
+                       }
+                       void set_scalar(const std::string& scalar) {
+                               mark_defined();
+                               m_pRef->set_scalar(scalar);
+                       }
+                       void set_tag(const std::string& tag) {
+                               mark_defined();
+                               m_pRef->set_tag(tag);
+                       }
+
+                       // size/iterator
+                       std::size_t size() const { return m_pRef->size(); }
+                       
+                       const_node_iterator begin() const { return static_cast<const node_ref&>(*m_pRef).begin(); }
+                       node_iterator begin() { return m_pRef->begin(); }
+                       
+                       const_node_iterator end() const { return static_cast<const node_ref&>(*m_pRef).end(); }
+                       node_iterator end() { return m_pRef->end(); }
+
+                       // sequence
+                       void push_back(node& node, shared_memory_holder pMemory) {
+                               m_pRef->push_back(node, pMemory);
+                               node.add_dependency(*this);
+                       }
+                       void insert(node& key, node& value, shared_memory_holder pMemory) {
+                               m_pRef->insert(key, value, pMemory);
+                               key.add_dependency(*this);
+                               value.add_dependency(*this);
+                       }
+
+                       // indexing
+                       template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) const { return static_cast<const node_ref&>(*m_pRef).get(key, pMemory); }
+                       template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) {
+                               node& value = m_pRef->get(key, pMemory);
+                               value.add_dependency(*this);
+                               return value;
+                       }
+                       template<typename Key> bool remove(const Key& key, shared_memory_holder pMemory) { return m_pRef->remove(key, pMemory); }
+                       
+                       node& get(node& key, shared_memory_holder pMemory) const { return static_cast<const node_ref&>(*m_pRef).get(key, pMemory); }
+                       node& get(node& key, shared_memory_holder pMemory) {
+                               node& value = m_pRef->get(key, pMemory);
+                               key.add_dependency(*this);
+                               value.add_dependency(*this);
+                               return value;
+                       }
+                       bool remove(node& key, shared_memory_holder pMemory) { return m_pRef->remove(key, pMemory); }
+
+            // map
+            template<typename Key, typename Value>
+            void force_insert(const Key& key, const Value& value, shared_memory_holder pMemory){ m_pRef->force_insert(key, value, pMemory); }
+
+               private:
+                       shared_node_ref m_pRef;
+                       typedef std::set<node *> nodes;
+                       nodes m_dependencies;
+               };
+       }
+}
+
+#endif // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/include/yaml-cpp/node/detail/node_data.h b/include/yaml-cpp/node/detail/node_data.h
new file mode 100644 (file)
index 0000000..413da5f
--- /dev/null
@@ -0,0 +1,110 @@
+#ifndef VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define VALUE_DETAIL_NODE_DATA_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/node/iterator.h"
+#include "yaml-cpp/node/ptr.h"
+#include "yaml-cpp/node/type.h"
+#include <boost/utility.hpp>
+#include <list>
+#include <utility>
+#include <vector>
+
+namespace YAML
+{
+       namespace detail
+       {
+               class node_data: private boost::noncopyable
+               {
+               public:
+                       node_data();
+                       
+                       void mark_defined();
+                       void set_type(NodeType::value type);
+                       void set_tag(const std::string& tag);
+                       void set_null();
+                       void set_scalar(const std::string& scalar);
+                       
+                       bool is_defined() const { return m_isDefined; }
+                       NodeType::value type() const { return m_isDefined ? m_type : NodeType::Undefined; }
+                       const std::string& scalar() const { return m_scalar; }
+                       const std::string& tag() const { return m_tag; }
+                       
+                       // size/iterator
+                       std::size_t size() const;
+                       
+                       const_node_iterator begin() const;
+                       node_iterator begin();
+                       
+                       const_node_iterator end() const;
+                       node_iterator end();
+
+                       // sequence
+                       void push_back(node& node, shared_memory_holder pMemory);
+                       void insert(node& key, node& value, shared_memory_holder pMemory);
+
+                       // indexing
+                       template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) const;
+                       template<typename Key> node& get(const Key& key, shared_memory_holder pMemory);
+                       template<typename Key> bool remove(const Key& key, shared_memory_holder pMemory);
+                       
+                       node& get(node& key, shared_memory_holder pMemory) const;
+                       node& get(node& key, shared_memory_holder pMemory);
+                       bool remove(node& key, shared_memory_holder pMemory);
+            
+            // map
+            template<typename Key, typename Value>
+            void force_insert(const Key& key, const Value& value, shared_memory_holder pMemory);
+                       
+               public:
+                       static std::string empty_scalar;
+                       
+               private:
+                       void compute_seq_size() const;
+                       void compute_map_size() const;
+
+                       void reset_sequence();
+                       void reset_map();
+                       
+                       void insert_map_pair(node& key, node& value);
+                       void convert_to_map(shared_memory_holder pMemory);
+                       void convert_sequence_to_map(shared_memory_holder pMemory);
+                       
+                       template<typename T>
+                       static bool equals(node& node, const T& rhs, shared_memory_holder pMemory);
+                       static bool equals(node& node, const char *rhs, shared_memory_holder pMemory);
+                       
+                       template<typename T>
+                       static node& convert_to_node(const T& rhs, shared_memory_holder pMemory);
+
+               private:
+                       bool m_isDefined;
+                       NodeType::value m_type;
+                       std::string m_tag;
+                       
+                       // scalar
+                       std::string m_scalar;
+                       
+                       // sequence
+                       typedef std::vector<node *> node_seq;
+                       node_seq m_sequence;
+                       
+                       mutable std::size_t m_seqSize;
+                       
+                       // map
+                       typedef std::map<node *, node *> node_map;
+                       node_map m_map;
+                       
+                       typedef std::pair<node *, node *> kv_pair;
+                       typedef std::list<kv_pair> kv_pairs;
+                       mutable kv_pairs m_undefinedPairs;
+               };
+       }
+}
+
+#endif // VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/include/yaml-cpp/node/detail/node_iterator.h b/include/yaml-cpp/node/detail/node_iterator.h
new file mode 100644 (file)
index 0000000..294921b
--- /dev/null
@@ -0,0 +1,139 @@
+#ifndef VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define VALUE_DETAIL_NODE_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 "yaml-cpp/node/ptr.h"
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <map>
+#include <utility>
+#include <vector>
+
+namespace YAML
+{
+       namespace detail
+       {
+               struct iterator_type { enum value { None, Sequence, Map }; };
+               
+               template<typename V>
+               struct node_iterator_value: public std::pair<V*, V*> {
+                       typedef std::pair<V*, V*> kv;
+                       
+                       node_iterator_value(): kv(), pNode(0) {}
+                       explicit node_iterator_value(V& rhs): kv(), pNode(&rhs) {}
+                       explicit node_iterator_value(V& key, V& value): kv(&key, &value), pNode(0) {}
+                       
+                       V& operator *() const { return *pNode; }
+                       V& operator ->() const { return *pNode; }
+                       
+                       V *pNode;
+               };
+               
+               typedef std::vector<node *> node_seq;
+               typedef std::map<node *, node *> node_map;
+               
+               template<typename V>
+               struct node_iterator_type {
+                       typedef node_seq::iterator seq;
+                       typedef node_map::iterator map;
+               };
+               
+               template<typename V>
+               struct node_iterator_type<const V> {
+                       typedef node_seq::const_iterator seq;
+                       typedef node_map::const_iterator map;
+               };
+               
+
+               template<typename V>
+               class node_iterator_base: public boost::iterator_facade<
+               node_iterator_base<V>,
+               node_iterator_value<V>,
+               std::forward_iterator_tag,
+               node_iterator_value<V> >
+               {
+               private:
+                       struct enabler {};
+                       
+               public:
+                       typedef typename node_iterator_type<V>::seq SeqIter;
+                       typedef typename node_iterator_type<V>::map MapIter;
+                       typedef node_iterator_value<V> value_type;
+                       
+                       node_iterator_base(): m_type(iterator_type::None) {}
+                       explicit node_iterator_base(SeqIter seqIt): m_type(iterator_type::Sequence), m_seqIt(seqIt) {}
+                       explicit node_iterator_base(MapIter mapIt, MapIter mapEnd): m_type(iterator_type::Map), m_mapIt(mapIt), m_mapEnd(mapEnd) {
+                               m_mapIt = increment_until_defined(m_mapIt);
+                       }
+                       
+                       template<typename W>
+                       node_iterator_base(const node_iterator_base<W>& rhs, typename boost::enable_if<boost::is_convertible<W*, V*>, enabler>::type = enabler())
+                       : m_type(rhs.m_type), m_seqIt(rhs.m_seqIt), m_mapIt(rhs.m_mapIt), m_mapEnd(rhs.m_mapEnd) {}
+                       
+               private:
+                       friend class boost::iterator_core_access;
+                       template<typename> friend class node_iterator_base;
+                       
+                       template<typename W>
+                       bool equal(const node_iterator_base<W>& rhs) const {
+                               if(m_type != rhs.m_type)
+                                       return false;
+                               
+                               switch(m_type) {
+                                       case iterator_type::None: return true;
+                                       case iterator_type::Sequence: return m_seqIt == rhs.m_seqIt;
+                                       case iterator_type::Map: return m_mapIt == rhs.m_mapIt;
+                               }
+                               return true;
+                       }
+                       
+                       void increment() {
+                               switch(m_type) {
+                                       case iterator_type::None: break;
+                                       case iterator_type::Sequence:
+                                               ++m_seqIt;
+                                               break;
+                                       case iterator_type::Map:
+                                               ++m_mapIt;
+                                               m_mapIt = increment_until_defined(m_mapIt);
+                                               break;
+                               }
+                       }
+
+                       value_type dereference() const {
+                               switch(m_type) {
+                                       case iterator_type::None: return value_type();
+                                       case iterator_type::Sequence: return value_type(**m_seqIt);
+                                       case iterator_type::Map: return value_type(*m_mapIt->first, *m_mapIt->second);
+                               }
+                               return value_type();
+                       }
+                       
+                       MapIter increment_until_defined(MapIter it) {
+                               while(it != m_mapEnd && !is_defined(it))
+                                       ++it;
+                               return it;
+                       }
+                       
+                       bool is_defined(MapIter it) const {
+                               return it->first->is_defined() && it->second->is_defined();
+                       }
+
+               private:
+                       typename iterator_type::value m_type;
+
+                       SeqIter m_seqIt;
+                       MapIter m_mapIt, m_mapEnd;
+               };
+
+               typedef node_iterator_base<node> node_iterator;
+               typedef node_iterator_base<const node> const_node_iterator;
+       }
+}
+
+#endif // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/include/yaml-cpp/node/detail/node_ref.h b/include/yaml-cpp/node/detail/node_ref.h
new file mode 100644 (file)
index 0000000..64cdb98
--- /dev/null
@@ -0,0 +1,69 @@
+#ifndef VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define VALUE_DETAIL_NODE_REF_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/node/type.h"
+#include "yaml-cpp/node/ptr.h"
+#include "yaml-cpp/node/detail/node_data.h"
+#include <boost/utility.hpp>
+
+namespace YAML
+{
+       namespace detail
+       {
+               class node_ref: private boost::noncopyable
+               {
+               public:
+                       node_ref(): m_pData(new node_data) {}
+                       
+                       bool is_defined() const { return m_pData->is_defined(); }
+                       NodeType::value type() const { return m_pData->type(); }
+                       const std::string& scalar() const { return m_pData->scalar(); }
+                       const std::string& tag() const { return m_pData->tag(); }
+                       
+                       void mark_defined() { m_pData->mark_defined(); }
+                       void set_data(const node_ref& rhs) { m_pData = rhs.m_pData; }
+                       
+                       void set_type(NodeType::value type) { m_pData->set_type(type); }
+                       void set_tag(const std::string& tag) { m_pData->set_tag(tag); }
+                       void set_null() { m_pData->set_null(); }
+                       void set_scalar(const std::string& scalar) { m_pData->set_scalar(scalar); }
+                       
+                       // size/iterator
+                       std::size_t size() const { return m_pData->size(); }
+                       
+                       const_node_iterator begin() const { return static_cast<const node_data&>(*m_pData).begin(); }
+                       node_iterator begin() {return m_pData->begin(); }
+                       
+                       const_node_iterator end() const { return static_cast<const node_data&>(*m_pData).end(); }
+                       node_iterator end() {return m_pData->end(); }
+
+                       // sequence
+                       void push_back(node& node, shared_memory_holder pMemory) { m_pData->push_back(node, pMemory); }
+                       void insert(node& key, node& value, shared_memory_holder pMemory) { m_pData->insert(key, value, pMemory); }
+                       
+                       // indexing
+                       template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) const { return static_cast<const node_data&>(*m_pData).get(key, pMemory); }
+                       template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) { return m_pData->get(key, pMemory); }
+                       template<typename Key> bool remove(const Key& key, shared_memory_holder pMemory) { return m_pData->remove(key, pMemory); }
+                       
+                       node& get(node& key, shared_memory_holder pMemory) const { return static_cast<const node_data&>(*m_pData).get(key, pMemory); }
+                       node& get(node& key, shared_memory_holder pMemory) { return m_pData->get(key, pMemory); }
+                       bool remove(node& key, shared_memory_holder pMemory) { return m_pData->remove(key, pMemory); }
+            
+            // map
+            template<typename Key, typename Value>
+            void force_insert(const Key& key, const Value& value, shared_memory_holder pMemory) { m_pData->force_insert(key, value, pMemory); }
+
+               private:
+                       shared_node_data m_pData;
+               };
+       }
+}
+
+#endif // VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/include/yaml-cpp/node/emit.h b/include/yaml-cpp/node/emit.h
new file mode 100644 (file)
index 0000000..7abf80b
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODE_EMIT_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 <iosfwd>
+
+namespace YAML
+{
+       class Emitter;
+       class Node;
+       
+       Emitter& operator << (Emitter& out, const Node& node);
+       std::ostream& operator << (std::ostream& out, const Node& node);
+       
+       std::string Dump(const Node& node);
+}
+
+#endif // NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
diff --git a/include/yaml-cpp/node/impl.h b/include/yaml-cpp/node/impl.h
new file mode 100644 (file)
index 0000000..41c2fcd
--- /dev/null
@@ -0,0 +1,451 @@
+#ifndef NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODE_IMPL_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/node/node.h"
+#include "yaml-cpp/node/iterator.h"
+#include "yaml-cpp/node/detail/memory.h"
+#include "yaml-cpp/node/detail/node.h"
+#include "yaml-cpp/exceptions.h"
+#include <string>
+
+namespace YAML
+{
+       inline Node::Node(): m_isValid(true), m_pNode(NULL)
+       {
+       }
+       
+       inline Node::Node(NodeType::value type): m_isValid(true), m_pMemory(new detail::memory_holder), m_pNode(&m_pMemory->create_node())
+       {
+               m_pNode->set_type(type);
+       }
+       
+       template<typename T>
+       inline Node::Node(const T& rhs): m_isValid(true), m_pMemory(new detail::memory_holder), m_pNode(&m_pMemory->create_node())
+       {
+               Assign(rhs);
+       }
+       
+    inline Node::Node(const detail::iterator_value& rhs): m_isValid(rhs.m_isValid), m_pMemory(rhs.m_pMemory), m_pNode(rhs.m_pNode)
+    {
+    }
+
+       inline Node::Node(const Node& rhs): m_isValid(rhs.m_isValid), m_pMemory(rhs.m_pMemory), m_pNode(rhs.m_pNode)
+       {
+       }
+       
+    inline Node::Node(Zombie): m_isValid(false), m_pNode(NULL)
+    {
+    }
+
+    inline Node::Node(detail::node& node, detail::shared_memory_holder pMemory): m_isValid(true), m_pMemory(pMemory), m_pNode(&node)
+       {
+       }
+
+       inline Node::~Node()
+       {
+       }
+
+       inline void Node::EnsureNodeExists() const
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+               if(!m_pNode) {
+                       m_pMemory.reset(new detail::memory_holder);
+                       m_pNode = &m_pMemory->create_node();
+                       m_pNode->set_null();
+               }
+       }
+       
+       inline bool Node::IsDefined() const
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+               return m_pNode ? m_pNode->is_defined() : true;
+       }
+
+       inline NodeType::value Node::Type() const
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+               return m_pNode ? m_pNode->type() : NodeType::Null;
+       }
+       
+       // access
+    
+    // template helpers
+    template<typename T, typename S>
+    struct as_if {
+        explicit as_if(const Node& node_): node(node_) {}
+        const Node& node;
+        
+        const T operator()(const S& fallback) const {
+            if(!node.m_pNode)
+                return fallback;
+            
+            T t;
+            if(convert<T>::decode(node, t))
+                return t;
+            return fallback;
+        }
+    };
+    
+    template<typename S>
+    struct as_if<std::string, S> {
+        explicit as_if(const Node& node_): node(node_) {}
+        const Node& node;
+        
+        const std::string operator()(const S& fallback) const {
+            if(node.Type() != NodeType::Scalar)
+                return fallback;
+            return node.Scalar();
+        }
+    };
+    
+    template<typename T>
+    struct as_if<T, void> {
+        explicit as_if(const Node& node_): node(node_) {}
+        const Node& node;
+        
+        const T operator()() const {
+            if(!node.m_pNode)
+                throw TypedBadConversion<T>();
+                       
+            T t;
+            if(convert<T>::decode(node, t))
+                return t;
+            throw TypedBadConversion<T>();
+        }
+    };
+    
+    template<>
+    struct as_if<std::string, void> {
+        explicit as_if(const Node& node_): node(node_) {}
+        const Node& node;
+        
+        const std::string operator()() const {
+            if(node.Type() != NodeType::Scalar)
+                throw TypedBadConversion<std::string>();
+            return node.Scalar();
+        }
+    };
+
+    // access functions
+       template<typename T>
+       inline const T Node::as() const
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+        return as_if<T, void>(*this)();
+       }
+
+    template<typename T, typename S>
+    inline const T Node::as(const S& fallback) const
+    {
+        if(!m_isValid)
+            throw InvalidNode();
+        return as_if<T, S>(*this)(fallback);
+    }
+    
+       inline const std::string& Node::Scalar() const
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+               return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar;
+       }
+
+       inline const std::string& Node::Tag() const
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+               return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar;
+       }
+
+       inline void Node::SetTag(const std::string& tag)
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+               EnsureNodeExists();
+               m_pNode->set_tag(tag);
+       }
+
+       // assignment
+       inline bool Node::is(const Node& rhs) const
+       {
+        if(!m_isValid || !rhs.m_isValid)
+            throw InvalidNode();
+        if(!m_pNode || !rhs.m_pNode)
+            return false;
+               return m_pNode->is(*rhs.m_pNode);
+       }
+
+       template<typename T>
+       inline Node& Node::operator=(const T& rhs)
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+               Assign(rhs);
+               return *this;
+       }
+       
+    inline void Node::reset(const YAML::Node& rhs)
+    {
+        if(!m_isValid || !rhs.m_isValid)
+            throw InvalidNode();
+        m_pMemory = rhs.m_pMemory;
+        m_pNode = rhs.m_pNode;
+    }
+
+       template<typename T>
+       inline void Node::Assign(const T& rhs)
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+               AssignData(convert<T>::encode(rhs));
+       }
+
+       template<>
+       inline void Node::Assign(const std::string& rhs)
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+               EnsureNodeExists();
+               m_pNode->set_scalar(rhs);
+       }
+
+       inline void Node::Assign(const char *rhs)
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+               EnsureNodeExists();
+               m_pNode->set_scalar(rhs);
+       }
+
+       inline void Node::Assign(char *rhs)
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+               EnsureNodeExists();
+               m_pNode->set_scalar(rhs);
+       }
+       
+       inline Node& Node::operator=(const Node& rhs)
+       {
+        if(!m_isValid || !rhs.m_isValid)
+            throw InvalidNode();
+               if(is(rhs))
+                       return *this;
+               AssignNode(rhs);
+               return *this;
+       }
+
+       inline void Node::AssignData(const Node& rhs)
+       {
+        if(!m_isValid || !rhs.m_isValid)
+            throw InvalidNode();
+               EnsureNodeExists();
+               rhs.EnsureNodeExists();
+               
+               m_pNode->set_data(*rhs.m_pNode);
+               m_pMemory->merge(*rhs.m_pMemory);
+       }
+
+       inline void Node::AssignNode(const Node& rhs)
+       {
+        if(!m_isValid || !rhs.m_isValid)
+            throw InvalidNode();
+               rhs.EnsureNodeExists();
+
+               if(!m_pNode) {
+                       m_pNode = rhs.m_pNode;
+                       m_pMemory = rhs.m_pMemory;
+                       return;
+               }
+
+               m_pNode->set_ref(*rhs.m_pNode);
+               m_pMemory->merge(*rhs.m_pMemory);
+               m_pNode = rhs.m_pNode;
+       }
+    
+       // size/iterator
+       inline std::size_t Node::size() const
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+               return m_pNode ? m_pNode->size() : 0;
+       }
+
+       inline const_iterator Node::begin() const
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+               return m_pNode ? const_iterator(m_pNode->begin(), m_pMemory) : const_iterator();
+       }
+       
+       inline iterator Node::begin()
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+               return m_pNode ? iterator(m_pNode->begin(), m_pMemory) : iterator();
+       }
+
+       inline const_iterator Node::end() const
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+               return m_pNode ? const_iterator(m_pNode->end(), m_pMemory) : const_iterator();
+       }
+
+       inline iterator Node::end()
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+               return m_pNode ? iterator(m_pNode->end(), m_pMemory) : iterator();
+       }
+       
+       // sequence
+       template<typename T>
+       inline void Node::push_back(const T& rhs)
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+               push_back(Node(rhs));
+       }
+       
+       inline void Node::push_back(const Node& rhs)
+       {
+        if(!m_isValid || !rhs.m_isValid)
+            throw InvalidNode();
+               EnsureNodeExists();
+               rhs.EnsureNodeExists();
+               
+               m_pNode->push_back(*rhs.m_pNode, m_pMemory);
+               m_pMemory->merge(*rhs.m_pMemory);
+       }
+
+    // helpers for indexing
+    namespace detail {
+        template<typename T>
+        struct to_value_t {
+            explicit to_value_t(const T& t_): t(t_) {}
+            const T& t;
+            typedef const T& return_type;
+            
+            const T& operator()() const { return t; }
+        };
+        
+        template<>
+        struct to_value_t<const char*> {
+            explicit to_value_t(const char *t_): t(t_) {}
+            const char *t;
+            typedef std::string return_type;
+            
+            const std::string operator()() const { return t; }
+        };
+        
+        template<>
+        struct to_value_t<char*> {
+            explicit to_value_t(char *t_): t(t_) {}
+            const char *t;
+            typedef std::string return_type;
+            
+            const std::string operator()() const { return t; }
+        };
+        
+        template<std::size_t N>
+        struct to_value_t<char [N]> {
+            explicit to_value_t(const char *t_): t(t_) {}
+            const char *t;
+            typedef std::string return_type;
+            
+            const std::string operator()() const { return t; }
+        };
+
+        // converts C-strings to std::strings so they can be copied
+        template<typename T>
+        inline typename to_value_t<T>::return_type to_value(const T& t) {
+            return to_value_t<T>(t)();
+        }
+    }
+
+       // indexing
+       template<typename Key>
+       inline const Node Node::operator[](const Key& key) const
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+               EnsureNodeExists();
+               detail::node& value = static_cast<const detail::node&>(*m_pNode).get(detail::to_value(key), m_pMemory);
+               return Node(value, m_pMemory);
+       }
+       
+       template<typename Key>
+       inline Node Node::operator[](const Key& key)
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+               EnsureNodeExists();
+               detail::node& value = m_pNode->get(detail::to_value(key), m_pMemory);
+               return Node(value, m_pMemory);
+       }
+       
+       template<typename Key>
+       inline bool Node::remove(const Key& key)
+       {
+        if(!m_isValid)
+            throw InvalidNode();
+               EnsureNodeExists();
+               return m_pNode->remove(detail::to_value(key), m_pMemory);
+       }
+       
+       inline const Node Node::operator[](const Node& key) const
+       {
+        if(!m_isValid || !key.m_isValid)
+            throw InvalidNode();
+               EnsureNodeExists();
+               key.EnsureNodeExists();
+               detail::node& value = static_cast<const detail::node&>(*m_pNode).get(*key.m_pNode, m_pMemory);
+               return Node(value, m_pMemory);
+       }
+       
+       inline Node Node::operator[](const Node& key)
+       {
+        if(!m_isValid || !key.m_isValid)
+            throw InvalidNode();
+               EnsureNodeExists();
+               key.EnsureNodeExists();
+               detail::node& value = m_pNode->get(*key.m_pNode, m_pMemory);
+               return Node(value, m_pMemory);
+       }
+       
+       inline bool Node::remove(const Node& key)
+       {
+        if(!m_isValid || !key.m_isValid)
+            throw InvalidNode();
+               EnsureNodeExists();
+               key.EnsureNodeExists();
+               return m_pNode->remove(*key.m_pNode, m_pMemory);
+       }
+    
+    // map
+    template<typename Key, typename Value>
+    inline void Node::force_insert(const Key& key, const Value& value)
+    {
+        if(!m_isValid)
+            throw InvalidNode();
+        EnsureNodeExists();
+               m_pNode->force_insert(detail::to_value(key), detail::to_value(value), m_pMemory);
+    }
+
+       // free functions
+       inline bool operator==(const Node& lhs, const Node& rhs)
+       {
+               return lhs.is(rhs);
+       }
+}
+
+#endif // NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/include/yaml-cpp/node/iterator.h b/include/yaml-cpp/node/iterator.h
new file mode 100644 (file)
index 0000000..98c8851
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define VALUE_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 "yaml-cpp/node/node.h"
+#include "yaml-cpp/node/detail/iterator_fwd.h"
+#include "yaml-cpp/node/detail/iterator.h"
+#include <list>
+#include <utility>
+#include <vector>
+
+namespace YAML
+{
+       namespace detail {
+               struct iterator_value: public Node, std::pair<Node, Node> {
+                       iterator_value() {}
+                       explicit iterator_value(const Node& rhs): Node(rhs), std::pair<Node, Node>(Node(Node::ZombieNode), Node(Node::ZombieNode)) {}
+                       explicit iterator_value(const Node& key, const Node& value): Node(Node::ZombieNode), std::pair<Node, Node>(key, value) {}
+               };
+       }
+}
+
+#endif // VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/include/yaml-cpp/node/node.h b/include/yaml-cpp/node/node.h
new file mode 100644 (file)
index 0000000..b949850
--- /dev/null
@@ -0,0 +1,116 @@
+#ifndef NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODE_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/node/ptr.h"
+#include "yaml-cpp/node/type.h"
+#include "yaml-cpp/node/detail/iterator_fwd.h"
+#include "yaml-cpp/node/detail/bool_type.h"
+#include <stdexcept>
+
+namespace YAML
+{
+       class Node
+       {
+       public:
+               friend class NodeBuilder;
+               friend class NodeEvents;
+        friend struct detail::iterator_value;
+               friend class detail::node_data;
+               template<typename> friend class detail::iterator_base;
+        template<typename T, typename S> friend struct as_if;
+        
+        typedef YAML::iterator iterator;
+        typedef YAML::const_iterator const_iterator;
+               
+               Node();
+               explicit Node(NodeType::value type);
+               template<typename T> explicit Node(const T& rhs);
+        explicit Node(const detail::iterator_value& rhs);
+               Node(const Node& rhs);
+               ~Node();
+               
+               NodeType::value Type() const;
+               bool IsDefined() const;
+               bool IsNull() const { return Type() == NodeType::Null; }
+               bool IsScalar() const { return Type() == NodeType::Scalar; }
+               bool IsSequence() const { return Type() == NodeType::Sequence; }
+               bool IsMap() const { return Type() == NodeType::Map; }
+               
+               // bool conversions
+               YAML_CPP_OPERATOR_BOOL();
+               bool operator!() const { return !IsDefined(); }
+               
+               // access
+               template<typename T> const T as() const;
+               template<typename T, typename S> const T as(const S& fallback) const;
+               const std::string& Scalar() const;
+               const std::string& Tag() const;
+               void SetTag(const std::string& tag);
+
+               // assignment
+               bool is(const Node& rhs) const;
+               template<typename T> Node& operator=(const T& rhs);
+               Node& operator=(const Node& rhs);
+        void reset(const Node& rhs = Node());
+        
+               // size/iterator
+               std::size_t size() const;
+
+               const_iterator begin() const;
+               iterator begin();
+               
+               const_iterator end() const;
+               iterator end();
+               
+               // sequence
+               template<typename T> void push_back(const T& rhs);
+               void push_back(const Node& rhs);
+               
+               // indexing
+               template<typename Key> const Node operator[](const Key& key) const;
+               template<typename Key> Node operator[](const Key& key);
+               template<typename Key> bool remove(const Key& key);
+
+               const Node operator[](const Node& key) const;
+               Node operator[](const Node& key);
+               bool remove(const Node& key);
+        
+        // map
+        template<typename Key, typename Value>
+        void force_insert(const Key& key, const Value& value);
+
+       private:
+        enum Zombie { ZombieNode };
+        explicit Node(Zombie);
+               explicit Node(detail::node& node, detail::shared_memory_holder pMemory);
+               
+               void EnsureNodeExists() const;
+               
+               template<typename T> void Assign(const T& rhs);
+               void Assign(const char *rhs);
+               void Assign(char *rhs);
+
+               void AssignData(const Node& rhs);
+               void AssignNode(const Node& rhs);
+               
+       private:
+        bool m_isValid;
+               mutable detail::shared_memory_holder m_pMemory;
+               mutable detail::node *m_pNode;
+       };
+
+       bool operator==(const Node& lhs, const Node& rhs);
+    
+    Node Clone(const Node& node);
+       
+       template<typename T>
+       struct convert;
+}
+
+#endif // NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/include/yaml-cpp/node/parse.h b/include/yaml-cpp/node/parse.h
new file mode 100644 (file)
index 0000000..82dbdc1
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define VALUE_PARSE_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 <iosfwd>
+#include <string>
+#include <vector>
+
+namespace YAML
+{
+       class Node;
+       
+       Node Load(const std::string& input);
+       Node Load(const char *input);
+       Node Load(std::istream& input);
+    Node LoadFile(const std::string& filename);
+
+       std::vector<Node> LoadAll(const std::string& input);
+       std::vector<Node> LoadAll(const char *input);
+       std::vector<Node> LoadAll(std::istream& input);
+    std::vector<Node> LoadAllFromFile(const std::string& filename);
+}
+
+#endif // VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
diff --git a/include/yaml-cpp/node/ptr.h b/include/yaml-cpp/node/ptr.h
new file mode 100644 (file)
index 0000000..316dbd2
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define VALUE_PTR_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 <boost/shared_ptr.hpp>
+
+namespace YAML
+{
+       namespace detail {
+               class node;
+               class node_ref;
+               class node_data;
+               class memory;
+               class memory_holder;
+
+               typedef boost::shared_ptr<node> shared_node;
+               typedef boost::shared_ptr<node_ref> shared_node_ref;
+               typedef boost::shared_ptr<node_data> shared_node_data;
+               typedef boost::shared_ptr<memory_holder> shared_memory_holder;
+               typedef boost::shared_ptr<memory> shared_memory;
+       }
+}
+
+#endif // VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/include/yaml-cpp/node/type.h b/include/yaml-cpp/node/type.h
new file mode 100644 (file)
index 0000000..5ac8041
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define VALUE_TYPE_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
+{
+       struct NodeType { enum value { Undefined, Null, Scalar, Sequence, Map }; };     
+}
+
+#endif // VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/include/yaml-cpp/noncopyable.h b/include/yaml-cpp/noncopyable.h
new file mode 100644 (file)
index 0000000..8e61e43
--- /dev/null
@@ -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/include/yaml-cpp/null.h b/include/yaml-cpp/null.h
new file mode 100644 (file)
index 0000000..711f18c
--- /dev/null
@@ -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/include/yaml-cpp/ostream_wrapper.h b/include/yaml-cpp/ostream_wrapper.h
new file mode 100644 (file)
index 0000000..a6d96c5
--- /dev/null
@@ -0,0 +1,69 @@
+#ifndef OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define OSTREAM_WRAPPER_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 ostream_wrapper
+       {
+       public:
+               ostream_wrapper();
+        explicit ostream_wrapper(std::ostream& stream);
+               ~ostream_wrapper();
+               
+        void write(const std::string& str);
+        void write(const char *str, std::size_t size);
+        
+        void set_comment() { m_comment = true; }
+
+               const char *str() const {
+            if(m_pStream) {
+                return 0;
+            } else {
+                m_buffer[m_pos] = '\0';
+                return &m_buffer[0];
+            }
+        }
+               
+               std::size_t row() const { return m_row; }
+               std::size_t col() const { return m_col; }
+               std::size_t pos() const { return m_pos; }
+        bool comment() const { return m_comment; }
+        
+    private:
+        void update_pos(char ch);
+               
+       private:
+        mutable std::vector<char> m_buffer;
+        std::ostream *m_pStream;
+
+               std::size_t m_pos;
+               std::size_t m_row, m_col;
+        bool m_comment;
+       };
+       
+    template<std::size_t N>
+       inline ostream_wrapper& operator << (ostream_wrapper& stream, const char (&str)[N]) {
+        stream.write(str, N-1);
+        return stream;
+    }
+    
+       inline ostream_wrapper& operator << (ostream_wrapper& stream, const std::string& str) {
+        stream.write(str);
+        return stream;
+    }
+    
+       inline ostream_wrapper& operator << (ostream_wrapper& stream, char ch) {
+        stream.write(&ch, 1);
+        return stream;
+    }
+}
+
+#endif // OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/include/yaml-cpp/parser.h b/include/yaml-cpp/parser.h
new file mode 100644 (file)
index 0000000..8ec926b
--- /dev/null
@@ -0,0 +1,47 @@
+#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 Token;
+       class EventHandler;
+       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);
+
+               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/include/yaml-cpp/stlemitter.h b/include/yaml-cpp/stlemitter.h
new file mode 100644 (file)
index 0000000..f8ff20e
--- /dev/null
@@ -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/include/yaml-cpp/traits.h b/include/yaml-cpp/traits.h
new file mode 100644 (file)
index 0000000..09eead4
--- /dev/null
@@ -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/include/yaml-cpp/yaml.h b/include/yaml-cpp/yaml.h
new file mode 100644 (file)
index 0000000..4e63408
--- /dev/null
@@ -0,0 +1,21 @@
+#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
+
+#include "yaml-cpp/parser.h"
+#include "yaml-cpp/emitter.h"
+#include "yaml-cpp/stlemitter.h"
+#include "yaml-cpp/exceptions.h"
+
+#include "yaml-cpp/node/node.h"
+#include "yaml-cpp/node/impl.h"
+#include "yaml-cpp/node/convert.h"
+#include "yaml-cpp/node/iterator.h"
+#include "yaml-cpp/node/detail/impl.h"
+#include "yaml-cpp/node/parse.h"
+#include "yaml-cpp/node/emit.h"
+
+#endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/install.txt b/install.txt
new file mode 100644 (file)
index 0000000..9392362
--- /dev/null
@@ -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/license.txt b/license.txt
new file mode 100644 (file)
index 0000000..5bd9e1a
--- /dev/null
@@ -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/src/binary.cpp b/src/binary.cpp
new file mode 100644 (file)
index 0000000..62a6032
--- /dev/null
@@ -0,0 +1,93 @@
+#include "yaml-cpp/binary.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;
+    }
+}
diff --git a/src/collectionstack.h b/src/collectionstack.h
new file mode 100644 (file)
index 0000000..4a986bc
--- /dev/null
@@ -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/src/contrib/graphbuilder.cpp b/src/contrib/graphbuilder.cpp
new file mode 100644 (file)
index 0000000..ab5159c
--- /dev/null
@@ -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/src/contrib/graphbuilderadapter.cpp b/src/contrib/graphbuilderadapter.cpp
new file mode 100644 (file)
index 0000000..557e97c
--- /dev/null
@@ -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/src/contrib/graphbuilderadapter.h b/src/contrib/graphbuilderadapter.h
new file mode 100644 (file)
index 0000000..3ef8ab6
--- /dev/null
@@ -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/src/convert.cpp b/src/convert.cpp
new file mode 100644 (file)
index 0000000..dc715f7
--- /dev/null
@@ -0,0 +1,83 @@
+#include "yaml-cpp/node/convert.h"
+#include "yaml-cpp/node/impl.h"
+#include <algorithm>
+
+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<bool>::decode(const Node& node, bool& rhs) {
+               if(!node.IsScalar())
+                       return false;
+               
+               // 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(node.Scalar()))
+                       return false;
+               
+               for(unsigned i=0;i<sizeof(names)/sizeof(names[0]);i++) {
+                       if(names[i].truename == tolower(node.Scalar())) {
+                               rhs = true;
+                               return true;
+                       }
+                       
+                       if(names[i].falsename == tolower(node.Scalar())) {
+                               rhs = false;
+                               return true;
+                       }
+               }
+               
+               return false;
+       }
+}
diff --git a/src/directives.cpp b/src/directives.cpp
new file mode 100644 (file)
index 0000000..faf1483
--- /dev/null
@@ -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/src/directives.h b/src/directives.h
new file mode 100644 (file)
index 0000000..a3308f7
--- /dev/null
@@ -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/src/emit.cpp b/src/emit.cpp
new file mode 100644 (file)
index 0000000..1f0a647
--- /dev/null
@@ -0,0 +1,29 @@
+#include "yaml-cpp/node/emit.h"
+#include "yaml-cpp/emitfromevents.h"
+#include "yaml-cpp/emitter.h"
+#include "nodeevents.h"
+
+namespace YAML
+{
+       Emitter& operator << (Emitter& out, const Node& node)
+       {
+               EmitFromEvents emitFromEvents(out);
+               NodeEvents events(node);
+               events.Emit(emitFromEvents);
+               return out;
+       }
+       
+       std::ostream& operator << (std::ostream& out, const Node& node)
+       {
+               Emitter emitter(out);
+               emitter << node;
+               return out;
+       }
+
+       std::string Dump(const Node& node)
+       {
+               Emitter emitter;
+               emitter << node;
+               return emitter.c_str();
+       }
+}
diff --git a/src/emitfromevents.cpp b/src/emitfromevents.cpp
new file mode 100644 (file)
index 0000000..49fc10b
--- /dev/null
@@ -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/src/emitter.cpp b/src/emitter.cpp
new file mode 100644 (file)
index 0000000..8a5a706
--- /dev/null
@@ -0,0 +1,951 @@
+#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(std::ostream& stream): m_pState(new EmitterState), m_stream(stream)
+       {
+       }
+
+       Emitter::~Emitter()
+       {
+       }
+       
+       const char *Emitter::c_str() const
+       {
+               return m_stream.str();
+       }
+       
+    std::size_t 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, FmtScope::Global);
+       }
+
+       bool Emitter::SetStringFormat(EMITTER_MANIP value)
+       {
+               return m_pState->SetStringFormat(value, FmtScope::Global);
+       }
+       
+       bool Emitter::SetBoolFormat(EMITTER_MANIP value)
+       {
+               bool ok = false;
+               if(m_pState->SetBoolFormat(value, FmtScope::Global))
+                       ok = true;
+               if(m_pState->SetBoolCaseFormat(value, FmtScope::Global))
+                       ok = true;
+               if(m_pState->SetBoolLengthFormat(value, FmtScope::Global))
+                       ok = true;
+               return ok;
+       }
+       
+       bool Emitter::SetIntBase(EMITTER_MANIP value)
+       {
+               return m_pState->SetIntFormat(value, FmtScope::Global);
+       }
+       
+       bool Emitter::SetSeqFormat(EMITTER_MANIP value)
+       {
+               return m_pState->SetFlowType(GroupType::Seq, value, FmtScope::Global);
+       }
+       
+       bool Emitter::SetMapFormat(EMITTER_MANIP value)
+       {
+               bool ok = false;
+               if(m_pState->SetFlowType(GroupType::Map, value, FmtScope::Global))
+                       ok = true;
+               if(m_pState->SetMapKeyFormat(value, FmtScope::Global))
+                       ok = true;
+               return ok;
+       }
+       
+       bool Emitter::SetIndent(unsigned n)
+       {
+               return m_pState->SetIndent(n, FmtScope::Global);
+       }
+       
+       bool Emitter::SetPreCommentIndent(unsigned n)
+       {
+               return m_pState->SetPreCommentIndent(n, FmtScope::Global);
+       }
+       
+       bool Emitter::SetPostCommentIndent(unsigned n)
+       {
+               return m_pState->SetPostCommentIndent(n, FmtScope::Global);
+       }
+    
+    bool Emitter::SetFloatPrecision(unsigned n)
+    {
+        return m_pState->SetFloatPrecision(n, FmtScope::Global);
+    }
+
+    bool Emitter::SetDoublePrecision(unsigned n)
+    {
+        return m_pState->SetDoublePrecision(n, FmtScope::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:
+                       case Value:
+                // deprecated (these can be deduced by the parity of nodes in a map)
+                               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, FmtScope::Local);
+               return *this;
+       }
+
+    Emitter& Emitter::SetLocalPrecision(const _Precision& precision)
+    {
+        if(precision.floatPrecision >= 0)
+            m_pState->SetFloatPrecision(precision.floatPrecision, FmtScope::Local);
+        if(precision.doublePrecision >= 0)
+            m_pState->SetDoublePrecision(precision.doublePrecision, FmtScope::Local);
+        return *this;
+    }
+
+       // EmitBeginDoc
+       void Emitter::EmitBeginDoc()
+       {
+               if(!good())
+                       return;
+        
+        if(m_pState->CurGroupType() != GroupType::None) {
+                       m_pState->SetError("Unexpected begin document");
+                       return;
+        }
+        
+        if(m_pState->HasAnchor() || m_pState->HasTag()) {
+                       m_pState->SetError("Unexpected begin document");
+                       return;
+        }
+        
+        if(m_stream.col() > 0)
+            m_stream << "\n";
+        m_stream << "---\n";
+        
+        m_pState->StartedDoc();
+       }
+       
+       // EmitEndDoc
+       void Emitter::EmitEndDoc()
+       {
+               if(!good())
+                       return;
+        
+        if(m_pState->CurGroupType() != GroupType::None) {
+                       m_pState->SetError("Unexpected begin document");
+                       return;
+        }
+        
+        if(m_pState->HasAnchor() || m_pState->HasTag()) {
+                       m_pState->SetError("Unexpected begin document");
+                       return;
+        }
+        
+        if(m_stream.col() > 0)
+            m_stream << "\n";
+        m_stream << "...\n";
+       }
+
+       // EmitBeginSeq
+       void Emitter::EmitBeginSeq()
+       {
+               if(!good())
+                       return;
+        
+        PrepareNode(m_pState->NextGroupType(GroupType::Seq));
+        
+        m_pState->StartedGroup(GroupType::Seq);
+       }
+       
+       // EmitEndSeq
+       void Emitter::EmitEndSeq()
+       {
+               if(!good())
+                       return;
+        
+        if(m_pState->CurGroupChildCount() == 0)
+            m_pState->ForceFlow();
+        
+        if(m_pState->CurGroupFlowType() == FlowType::Flow) {
+            if(m_stream.comment())
+                m_stream << "\n";
+            m_stream << IndentTo(m_pState->CurIndent());
+            if(m_pState->CurGroupChildCount() == 0)
+                m_stream << "[";
+            m_stream << "]";
+        }
+        
+        m_pState->EndedGroup(GroupType::Seq);
+       }
+       
+       // EmitBeginMap
+       void Emitter::EmitBeginMap()
+       {
+               if(!good())
+                       return;
+
+        PrepareNode(m_pState->NextGroupType(GroupType::Map));
+        
+        m_pState->StartedGroup(GroupType::Map);
+       }
+       
+       // EmitEndMap
+       void Emitter::EmitEndMap()
+       {
+               if(!good())
+                       return;
+
+        if(m_pState->CurGroupChildCount() == 0)
+            m_pState->ForceFlow();
+        
+        if(m_pState->CurGroupFlowType() == FlowType::Flow) {
+            if(m_stream.comment())
+                m_stream << "\n";
+            m_stream << IndentTo(m_pState->CurIndent());
+            if(m_pState->CurGroupChildCount() == 0)
+                m_stream << "{";
+            m_stream << "}";
+        }
+
+        m_pState->EndedGroup(GroupType::Map);
+    }
+
+       // EmitNewline
+       void Emitter::EmitNewline()
+       {
+               if(!good())
+                       return;
+        
+        PrepareNode(EmitterNodeType::None);
+        m_stream << "\n";
+        m_pState->SetNonContent();
+       }
+
+       bool Emitter::CanEmitNewline() const
+       {
+        return true;
+       }
+
+    // Put the stream in a state so we can simply write the next node
+    // E.g., if we're in a sequence, write the "- "
+    void Emitter::PrepareNode(EmitterNodeType::value child)
+    {
+        switch(m_pState->CurGroupNodeType()) {
+            case EmitterNodeType::None:
+                PrepareTopNode(child);
+                break;
+            case EmitterNodeType::FlowSeq:
+                FlowSeqPrepareNode(child);
+                break;
+            case EmitterNodeType::BlockSeq:
+                BlockSeqPrepareNode(child);
+                break;
+            case EmitterNodeType::FlowMap:
+                FlowMapPrepareNode(child);
+                break;
+            case EmitterNodeType::BlockMap:
+                BlockMapPrepareNode(child);
+                break;
+            case EmitterNodeType::Property:
+            case EmitterNodeType::Scalar:
+                assert(false);
+                break;
+        }
+    }
+    
+    void Emitter::PrepareTopNode(EmitterNodeType::value child)
+    {
+        if(child == EmitterNodeType::None)
+            return;
+        
+        if(m_pState->CurGroupChildCount() > 0 && m_stream.col() > 0) {
+            if(child != EmitterNodeType::None)
+                EmitBeginDoc();
+        }
+        
+        switch(child) {
+            case EmitterNodeType::None:
+                break;
+            case EmitterNodeType::Property:
+            case EmitterNodeType::Scalar:
+            case EmitterNodeType::FlowSeq:
+            case EmitterNodeType::FlowMap:
+                // TODO: if we were writing null, and
+                // we wanted it blank, we wouldn't want a space
+                SpaceOrIndentTo(m_pState->HasBegunContent(), 0);
+                break;
+            case EmitterNodeType::BlockSeq:
+            case EmitterNodeType::BlockMap:
+                if(m_pState->HasBegunNode())
+                    m_stream << "\n";
+                break;
+        }
+    }
+    
+    void Emitter::FlowSeqPrepareNode(EmitterNodeType::value child)
+    {
+        const unsigned lastIndent = m_pState->LastIndent();
+
+        if(!m_pState->HasBegunNode()) {
+            if(m_stream.comment())
+                m_stream << "\n";
+            m_stream << IndentTo(lastIndent);
+            if(m_pState->CurGroupChildCount() == 0)
+                m_stream << "[";
+            else
+                m_stream << ",";
+        }
+
+        switch(child) {
+            case EmitterNodeType::None:
+                break;
+            case EmitterNodeType::Property:
+            case EmitterNodeType::Scalar:
+            case EmitterNodeType::FlowSeq:
+            case EmitterNodeType::FlowMap:
+                SpaceOrIndentTo(m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0, lastIndent);
+                break;
+            case EmitterNodeType::BlockSeq:
+            case EmitterNodeType::BlockMap:
+                assert(false);
+                break;
+        }
+    }
+
+    void Emitter::BlockSeqPrepareNode(EmitterNodeType::value child)
+    {
+        const unsigned curIndent = m_pState->CurIndent();
+        const unsigned nextIndent = curIndent + m_pState->CurGroupIndent();
+        
+        if(child == EmitterNodeType::None)
+            return;
+        
+        if(!m_pState->HasBegunContent()) {
+            if(m_pState->CurGroupChildCount() > 0 || m_stream.comment()) {
+                m_stream << "\n";
+            }
+            m_stream << IndentTo(curIndent);
+            m_stream << "-";
+        }
+        
+        switch(child) {
+            case EmitterNodeType::None:
+                break;
+            case EmitterNodeType::Property:
+            case EmitterNodeType::Scalar:
+            case EmitterNodeType::FlowSeq:
+            case EmitterNodeType::FlowMap:
+                SpaceOrIndentTo(m_pState->HasBegunContent(), nextIndent);
+                break;
+            case EmitterNodeType::BlockSeq:
+                m_stream << "\n";
+                break;
+            case EmitterNodeType::BlockMap:
+                if(m_pState->HasBegunContent() || m_stream.comment())
+                    m_stream << "\n";
+                break;
+        }
+    }
+    
+    void Emitter::FlowMapPrepareNode(EmitterNodeType::value child)
+    {
+        if(m_pState->CurGroupChildCount() % 2 == 0) {
+            if(m_pState->GetMapKeyFormat() == LongKey)
+                m_pState->SetLongKey();
+            
+            if(m_pState->CurGroupLongKey())
+                FlowMapPrepareLongKey(child);
+            else
+                FlowMapPrepareSimpleKey(child);
+        } else {
+            if(m_pState->CurGroupLongKey())
+                FlowMapPrepareLongKeyValue(child);
+            else
+                FlowMapPrepareSimpleKeyValue(child);
+        }
+    }
+
+    void Emitter::FlowMapPrepareLongKey(EmitterNodeType::value child)
+    {
+        const unsigned lastIndent = m_pState->LastIndent();
+        
+        if(!m_pState->HasBegunNode()) {
+            if(m_stream.comment())
+                m_stream << "\n";
+            m_stream << IndentTo(lastIndent);
+            if(m_pState->CurGroupChildCount() == 0)
+                m_stream << "{ ?";
+            else
+                m_stream << ", ?";
+        }
+        
+        switch(child) {
+            case EmitterNodeType::None:
+                break;
+            case EmitterNodeType::Property:
+            case EmitterNodeType::Scalar:
+            case EmitterNodeType::FlowSeq:
+            case EmitterNodeType::FlowMap:
+                SpaceOrIndentTo(m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0, lastIndent);
+                break;
+            case EmitterNodeType::BlockSeq:
+            case EmitterNodeType::BlockMap:
+                assert(false);
+                break;
+        }
+    }
+    
+    void Emitter::FlowMapPrepareLongKeyValue(EmitterNodeType::value child)
+    {
+        const unsigned lastIndent = m_pState->LastIndent();
+        
+        if(!m_pState->HasBegunNode()) {
+            if(m_stream.comment())
+                m_stream << "\n";
+            m_stream << IndentTo(lastIndent);
+            m_stream << ":";
+        }
+        
+        switch(child) {
+            case EmitterNodeType::None:
+                break;
+            case EmitterNodeType::Property:
+            case EmitterNodeType::Scalar:
+            case EmitterNodeType::FlowSeq:
+            case EmitterNodeType::FlowMap:
+                SpaceOrIndentTo(m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0, lastIndent);
+                break;
+            case EmitterNodeType::BlockSeq:
+            case EmitterNodeType::BlockMap:
+                assert(false);
+                break;
+        }
+    }
+    
+    void Emitter::FlowMapPrepareSimpleKey(EmitterNodeType::value child)
+    {
+        const unsigned lastIndent = m_pState->LastIndent();
+        
+        if(!m_pState->HasBegunNode()) {
+            if(m_stream.comment())
+                m_stream << "\n";
+            m_stream << IndentTo(lastIndent);
+            if(m_pState->CurGroupChildCount() == 0)
+                m_stream << "{";
+            else
+                m_stream << ",";
+        }
+        
+        switch(child) {
+            case EmitterNodeType::None:
+                break;
+            case EmitterNodeType::Property:
+            case EmitterNodeType::Scalar:
+            case EmitterNodeType::FlowSeq:
+            case EmitterNodeType::FlowMap:
+                SpaceOrIndentTo(m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0, lastIndent);
+                break;
+            case EmitterNodeType::BlockSeq:
+            case EmitterNodeType::BlockMap:
+                assert(false);
+                break;
+        }
+    }
+    
+    void Emitter::FlowMapPrepareSimpleKeyValue(EmitterNodeType::value child)
+    {
+        const unsigned lastIndent = m_pState->LastIndent();
+        
+        if(!m_pState->HasBegunNode()) {
+            if(m_stream.comment())
+                m_stream << "\n";
+            m_stream << IndentTo(lastIndent);
+            m_stream << ":";
+        }
+        
+        switch(child) {
+            case EmitterNodeType::None:
+                break;
+            case EmitterNodeType::Property:
+            case EmitterNodeType::Scalar:
+            case EmitterNodeType::FlowSeq:
+            case EmitterNodeType::FlowMap:
+                SpaceOrIndentTo(m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0, lastIndent);
+                break;
+            case EmitterNodeType::BlockSeq:
+            case EmitterNodeType::BlockMap:
+                assert(false);
+                break;
+        }
+    }
+
+    void Emitter::BlockMapPrepareNode(EmitterNodeType::value child)
+    {
+        if(m_pState->CurGroupChildCount() % 2 == 0) {
+            if(m_pState->GetMapKeyFormat() == LongKey)
+                m_pState->SetLongKey();
+            if(child == EmitterNodeType::BlockSeq || child == EmitterNodeType::BlockMap)
+                m_pState->SetLongKey();
+            
+            if(m_pState->CurGroupLongKey())
+                BlockMapPrepareLongKey(child);
+            else
+                BlockMapPrepareSimpleKey(child);
+        } else {
+            if(m_pState->CurGroupLongKey())
+                BlockMapPrepareLongKeyValue(child);
+            else
+                BlockMapPrepareSimpleKeyValue(child);
+        }
+    }
+    
+    void Emitter::BlockMapPrepareLongKey(EmitterNodeType::value child)
+    {
+        const unsigned curIndent = m_pState->CurIndent();
+        const std::size_t childCount = m_pState->CurGroupChildCount();
+        
+        if(child == EmitterNodeType::None)
+            return;
+
+        if(!m_pState->HasBegunContent()) {
+            if(childCount > 0) {
+                m_stream << "\n";
+            }
+            if(m_stream.comment()) {
+                m_stream << "\n";
+            }
+            m_stream << IndentTo(curIndent);
+            m_stream << "?";
+        }
+        
+        switch(child) {
+            case EmitterNodeType::None:
+                break;
+            case EmitterNodeType::Property:
+            case EmitterNodeType::Scalar:
+            case EmitterNodeType::FlowSeq:
+            case EmitterNodeType::FlowMap:
+                SpaceOrIndentTo(true, curIndent + 1);
+                break;
+            case EmitterNodeType::BlockSeq:
+            case EmitterNodeType::BlockMap:
+                break;
+        }
+    }
+
+    void Emitter::BlockMapPrepareLongKeyValue(EmitterNodeType::value child)
+    {
+        const unsigned curIndent = m_pState->CurIndent();
+        
+        if(child == EmitterNodeType::None)
+            return;
+
+        if(!m_pState->HasBegunContent()) {
+            m_stream << "\n";
+            m_stream << IndentTo(curIndent);
+            m_stream << ":";
+        }
+        
+        switch(child) {
+            case EmitterNodeType::None:
+                break;
+            case EmitterNodeType::Property:
+            case EmitterNodeType::Scalar:
+            case EmitterNodeType::FlowSeq:
+            case EmitterNodeType::FlowMap:
+            case EmitterNodeType::BlockSeq:
+            case EmitterNodeType::BlockMap:
+                SpaceOrIndentTo(true, curIndent + 1);
+                break;
+        }
+    }
+
+    void Emitter::BlockMapPrepareSimpleKey(EmitterNodeType::value child)
+    {
+        const unsigned curIndent = m_pState->CurIndent();
+        const std::size_t childCount = m_pState->CurGroupChildCount();
+        
+        if(child == EmitterNodeType::None)
+            return;
+        
+        if(!m_pState->HasBegunNode()) {
+            if(childCount > 0) {
+                m_stream << "\n";
+            }
+        }
+        
+        switch(child) {
+            case EmitterNodeType::None:
+                break;
+            case EmitterNodeType::Property:
+            case EmitterNodeType::Scalar:
+            case EmitterNodeType::FlowSeq:
+            case EmitterNodeType::FlowMap:
+                SpaceOrIndentTo(m_pState->HasBegunContent(), curIndent);
+                break;
+            case EmitterNodeType::BlockSeq:
+            case EmitterNodeType::BlockMap:
+                break;
+        }
+    }
+    
+    void Emitter::BlockMapPrepareSimpleKeyValue(EmitterNodeType::value child)
+    {
+        const unsigned curIndent = m_pState->CurIndent();
+        const unsigned nextIndent = curIndent + m_pState->CurGroupIndent();
+        
+        if(!m_pState->HasBegunNode()) {
+            m_stream << ":";
+        }
+        
+        switch(child) {
+            case EmitterNodeType::None:
+                break;
+            case EmitterNodeType::Property:
+            case EmitterNodeType::Scalar:
+            case EmitterNodeType::FlowSeq:
+            case EmitterNodeType::FlowMap:
+                SpaceOrIndentTo(true, nextIndent);
+                break;
+            case EmitterNodeType::BlockSeq:
+            case EmitterNodeType::BlockMap:
+                m_stream << "\n";
+                break;
+        }
+    }
+    
+    // SpaceOrIndentTo
+    // . Prepares for some more content by proper spacing
+    void Emitter::SpaceOrIndentTo(bool requireSpace, unsigned indent)
+    {
+        if(m_stream.comment())
+            m_stream << "\n";
+        if(m_stream.col() > 0 && requireSpace)
+            m_stream << " ";
+        m_stream << IndentTo(indent);
+    }
+
+    void Emitter::PrepareIntegralStream(std::stringstream& stream) const
+    {
+               
+               switch(m_pState->GetIntFormat()) {
+                       case Dec:
+                               stream << std::dec;
+                               break;
+                       case Hex:
+                stream << "0x";
+                               stream << std::hex;
+                               break;
+                       case Oct:
+                stream << "0";
+                               stream << std::oct;
+                               break;
+                       default:
+                               assert(false);
+               }
+    }
+
+    void Emitter::StartedScalar()
+    {
+        m_pState->StartedScalar();
+    }
+
+       // *******************************************************************************************
+       // overloads of Write
+       
+       Emitter& Emitter::Write(const std::string& str)
+       {
+               if(!good())
+                       return *this;
+        
+               const bool escapeNonAscii = m_pState->GetOutputCharset() == EscapeNonAscii;
+        const StringFormat::value strFormat = Utils::ComputeStringFormat(str, m_pState->GetStringFormat(), m_pState->CurGroupFlowType(), escapeNonAscii);
+        
+        if(strFormat == StringFormat::Literal)
+            m_pState->SetMapKeyFormat(YAML::LongKey, FmtScope::Local);
+        
+        PrepareNode(EmitterNodeType::Scalar);
+        
+        switch(strFormat) {
+            case StringFormat::Plain:
+                m_stream << str;
+                break;
+            case StringFormat::SingleQuoted:
+                Utils::WriteSingleQuotedString(m_stream, str);
+                break;
+            case StringFormat::DoubleQuoted:
+                Utils::WriteDoubleQuotedString(m_stream, str, escapeNonAscii);
+                break;
+            case StringFormat::Literal:
+                Utils::WriteLiteralString(m_stream, str, m_pState->CurIndent() + m_pState->GetIndent());
+                break;
+        }
+
+        StartedScalar();
+        
+               return *this;
+       }
+
+    unsigned Emitter::GetFloatPrecision() const
+    {
+        return m_pState->GetFloatPrecision();
+    }
+    
+    unsigned Emitter::GetDoublePrecision() const
+    {
+        return m_pState->GetDoublePrecision();
+    }
+
+       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;
+
+        PrepareNode(EmitterNodeType::Scalar);
+
+               const char *name = ComputeFullBoolName(b);
+               if(m_pState->GetBoolLengthFormat() == ShortBool)
+                       m_stream << name[0];
+               else
+                       m_stream << name;
+
+        StartedScalar();
+
+               return *this;
+       }
+
+       Emitter& Emitter::Write(char ch)
+       {
+               if(!good())
+                       return *this;
+
+        PrepareNode(EmitterNodeType::Scalar);
+        Utils::WriteChar(m_stream, ch);
+        StartedScalar();
+
+               return *this;
+       }
+
+       Emitter& Emitter::Write(const _Alias& alias)
+       {
+               if(!good())
+                       return *this;
+        
+        if(m_pState->HasAnchor() || m_pState->HasTag()) {
+            m_pState->SetError(ErrorMsg::INVALID_ALIAS);
+            return *this;
+        }
+
+        PrepareNode(EmitterNodeType::Scalar);
+
+               if(!Utils::WriteAlias(m_stream, alias.content)) {
+                       m_pState->SetError(ErrorMsg::INVALID_ALIAS);
+                       return *this;
+               }
+        
+        StartedScalar();
+
+               return *this;
+       }
+       
+       Emitter& Emitter::Write(const _Anchor& anchor)
+       {
+               if(!good())
+                       return *this;
+        
+        if(m_pState->HasAnchor()) {
+            m_pState->SetError(ErrorMsg::INVALID_ANCHOR);
+            return *this;
+        }
+
+        PrepareNode(EmitterNodeType::Property);
+
+               if(!Utils::WriteAnchor(m_stream, anchor.content)) {
+                       m_pState->SetError(ErrorMsg::INVALID_ANCHOR);
+                       return *this;
+               }
+        
+        m_pState->SetAnchor();
+
+               return *this;
+       }
+       
+       Emitter& Emitter::Write(const _Tag& tag)
+       {
+               if(!good())
+                       return *this;
+        
+        if(m_pState->HasTag()) {
+            m_pState->SetError(ErrorMsg::INVALID_TAG);
+            return *this;
+        }
+        
+        PrepareNode(EmitterNodeType::Property);
+        
+               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->SetTag();
+
+               return *this;
+       }
+
+       void Emitter::EmitKindTag()
+       {
+               Write(LocalTag(""));
+       }
+
+       Emitter& Emitter::Write(const _Comment& comment)
+       {
+               if(!good())
+                       return *this;
+
+        PrepareNode(EmitterNodeType::None);
+        
+               if(m_stream.col() > 0)
+                       m_stream << Indentation(m_pState->GetPreCommentIndent());
+               Utils::WriteComment(m_stream, comment.content, m_pState->GetPostCommentIndent());
+
+        m_pState->SetNonContent();
+
+               return *this;
+       }
+
+       Emitter& Emitter::Write(const _Null& /*null*/)
+       {
+               if(!good())
+                       return *this;
+
+        PrepareNode(EmitterNodeType::Scalar);
+        
+        m_stream << "~";
+
+        StartedScalar();
+
+               return *this;
+       }
+
+       Emitter& Emitter::Write(const Binary& binary)
+       {
+               Write(SecondaryTag("binary"));
+
+               if(!good())
+                       return *this;
+
+        PrepareNode(EmitterNodeType::Scalar);
+               Utils::WriteBinary(m_stream, binary);
+        StartedScalar();
+
+               return *this;
+       }
+}
+
diff --git a/src/emitterstate.cpp b/src/emitterstate.cpp
new file mode 100644 (file)
index 0000000..10c3976
--- /dev/null
@@ -0,0 +1,384 @@
+#include "emitterstate.h"
+#include "yaml-cpp/exceptions.h"
+#include <limits>
+
+namespace YAML
+{
+       EmitterState::EmitterState(): m_isGood(true), m_curIndent(0), m_hasAnchor(false), m_hasTag(false), m_hasNonContent(false), m_docCount(0)
+       {
+               // 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(std::numeric_limits<float>::digits10 + 1);
+        m_doublePrecision.set(std::numeric_limits<double>::digits10 + 1);
+       }
+       
+       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, FmtScope::Local);
+               SetStringFormat(value, FmtScope::Local);
+               SetBoolFormat(value, FmtScope::Local);
+               SetBoolCaseFormat(value, FmtScope::Local);
+               SetBoolLengthFormat(value, FmtScope::Local);
+               SetIntFormat(value, FmtScope::Local);
+               SetFlowType(GroupType::Seq, value, FmtScope::Local);
+               SetFlowType(GroupType::Map, value, FmtScope::Local);
+               SetMapKeyFormat(value, FmtScope::Local);
+       }
+       
+    void EmitterState::SetAnchor()
+    {
+        m_hasAnchor = true;
+    }
+        
+    void EmitterState::SetTag()
+    {
+        m_hasTag = true;
+    }
+
+    void EmitterState::SetNonContent()
+    {
+        m_hasNonContent = true;
+    }
+
+    void EmitterState::SetLongKey()
+    {
+        assert(!m_groups.empty());        
+        if(m_groups.empty())
+            return;
+        
+        assert(m_groups.top().type == GroupType::Map);
+        m_groups.top().longKey = true;
+    }
+    
+    void EmitterState::ForceFlow()
+    {
+        assert(!m_groups.empty());
+        if(m_groups.empty())
+            return;
+        
+        m_groups.top().flowType = FlowType::Flow;
+    }
+
+    void EmitterState::StartedNode()
+    {
+        if(m_groups.empty()) {
+            m_docCount++;
+        } else {
+            m_groups.top().childCount++;
+            if(m_groups.top().childCount % 2 == 0)
+                m_groups.top().longKey = false;
+        }
+        
+        m_hasAnchor = false;
+        m_hasTag = false;
+        m_hasNonContent = false;
+    }
+
+    EmitterNodeType::value EmitterState::NextGroupType(GroupType::value type) const
+    {
+        if(type == GroupType::Seq) {
+            if(GetFlowType(type) == Block)
+                return EmitterNodeType::BlockSeq;
+            else
+                return EmitterNodeType::FlowSeq;
+        } else {
+            if(GetFlowType(type) == Block)
+                return EmitterNodeType::BlockMap;
+            else
+                return EmitterNodeType::FlowMap;
+        }
+        
+        // can't happen
+        assert(false);
+        return EmitterNodeType::None;
+    }
+    
+    void EmitterState::StartedDoc()
+    {
+        m_hasAnchor = false;
+        m_hasTag = false;
+        m_hasNonContent = false;
+    }
+    
+    void EmitterState::EndedDoc()
+    {
+        m_hasAnchor = false;
+        m_hasTag = false;
+        m_hasNonContent = false;
+    }
+
+    void EmitterState::StartedScalar()
+    {
+        StartedNode();
+        ClearModifiedSettings();
+    }
+
+       void EmitterState::StartedGroup(GroupType::value type)
+       {
+        StartedNode();
+
+               const int lastGroupIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
+               m_curIndent += lastGroupIndent;
+               
+               std::auto_ptr<Group> pGroup(new Group(type));
+               
+               // transfer settings (which last until this group is done)
+               pGroup->modifiedSettings = m_modifiedSettings;
+
+               // set up group
+        if(GetFlowType(type) == Block)
+            pGroup->flowType = FlowType::Block;
+        else
+            pGroup->flowType = FlowType::Flow;
+               pGroup->indent = GetIndent();
+
+               m_groups.push(pGroup);
+       }
+       
+       void EmitterState::EndedGroup(GroupType::value type)
+       {
+               if(m_groups.empty()) {
+            if(type == GroupType::Seq)
+                return SetError(ErrorMsg::UNEXPECTED_END_SEQ);
+            else
+                return SetError(ErrorMsg::UNEXPECTED_END_MAP);
+        }
+               
+               // 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();
+
+        ClearModifiedSettings();
+       }
+
+    EmitterNodeType::value EmitterState::CurGroupNodeType() const
+    {
+        if(m_groups.empty())
+            return EmitterNodeType::None;
+        
+        return m_groups.top().NodeType();
+    }
+
+    GroupType::value EmitterState::CurGroupType() const
+       {
+        return m_groups.empty() ? GroupType::None : m_groups.top().type;
+       }
+       
+    FlowType::value EmitterState::CurGroupFlowType() const
+       {
+        return m_groups.empty() ? FlowType::None : m_groups.top().flowType;
+       }
+
+    int EmitterState::CurGroupIndent() const
+    {
+        return m_groups.empty() ? 0 : m_groups.top().indent;
+    }
+
+    std::size_t EmitterState::CurGroupChildCount() const
+    {
+        return m_groups.empty() ? m_docCount : m_groups.top().childCount;
+    }
+
+    bool EmitterState::CurGroupLongKey() const
+    {
+        return m_groups.empty() ? false : m_groups.top().longKey;
+    }
+
+    int EmitterState::LastIndent() const
+    {
+        if(m_groups.size() <= 1)
+            return 0;
+        
+        return m_curIndent - m_groups.top(-1).indent;
+    }
+
+       void EmitterState::ClearModifiedSettings()
+       {
+               m_modifiedSettings.clear();
+       }
+
+       bool EmitterState::SetOutputCharset(EMITTER_MANIP value, FmtScope::value scope)
+       {
+               switch(value) {
+                       case EmitNonAscii:
+                       case EscapeNonAscii:
+                               _Set(m_charset, value, scope);
+                               return true;
+                       default:
+                               return false;
+               }
+       }
+       
+       bool EmitterState::SetStringFormat(EMITTER_MANIP value, FmtScope::value 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, FmtScope::value 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, FmtScope::value scope)
+       {
+               switch(value) {
+                       case LongBool:
+                       case ShortBool:
+                               _Set(m_boolLengthFmt, value, scope);
+                               return true;
+                       default:
+                               return false;
+               }
+       }
+
+       bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value, FmtScope::value 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, FmtScope::value scope)
+       {
+               switch(value) {
+                       case Dec:
+                       case Hex:
+                       case Oct:
+                               _Set(m_intFmt, value, scope);
+                               return true;
+                       default:
+                               return false;
+               }
+       }
+
+       bool EmitterState::SetIndent(unsigned value, FmtScope::value scope)
+       {
+               if(value <= 1)
+                       return false;
+               
+               _Set(m_indent, value, scope);
+               return true;
+       }
+
+       bool EmitterState::SetPreCommentIndent(unsigned value, FmtScope::value scope)
+       {
+               if(value == 0)
+                       return false;
+               
+               _Set(m_preCommentIndent, value, scope);
+               return true;
+       }
+       
+       bool EmitterState::SetPostCommentIndent(unsigned value, FmtScope::value scope)
+       {
+               if(value == 0)
+                       return false;
+               
+               _Set(m_postCommentIndent, value, scope);
+               return true;
+       }
+
+       bool EmitterState::SetFlowType(GroupType::value groupType, EMITTER_MANIP value, FmtScope::value scope)
+       {
+               switch(value) {
+                       case Block:
+                       case Flow:
+                               _Set(groupType == GroupType::Seq ? m_seqFmt : m_mapFmt, value, scope);
+                               return true;
+                       default:
+                               return false;
+               }
+       }
+
+       EMITTER_MANIP EmitterState::GetFlowType(GroupType::value groupType) const
+       {
+               // force flow style if we're currently in a flow
+               if(CurGroupFlowType() == FlowType::Flow)
+                       return Flow;
+               
+               // otherwise, go with what's asked of us
+               return (groupType == GroupType::Seq ? m_seqFmt.get() : m_mapFmt.get());
+       }
+       
+       bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope)
+       {
+               switch(value) {
+                       case Auto:
+                       case LongKey:
+                               _Set(m_mapKeyFmt, value, scope);
+                               return true;
+                       default:
+                               return false;
+               }
+       }
+
+    bool EmitterState::SetFloatPrecision(int value, FmtScope::value scope)
+    {
+        if(value < 0 || value > std::numeric_limits<float>::digits10 + 1)
+            return false;
+        _Set(m_floatPrecision, value, scope);
+        return true;
+    }
+    
+    bool EmitterState::SetDoublePrecision(int value, FmtScope::value scope)
+    {
+        if(value < 0 || value > std::numeric_limits<double>::digits10 + 1)
+            return false;
+        _Set(m_doublePrecision, value, scope);
+        return true;
+    }
+}
+
diff --git a/src/emitterstate.h b/src/emitterstate.h
new file mode 100644 (file)
index 0000000..f43f471
--- /dev/null
@@ -0,0 +1,190 @@
+#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/emitterdef.h"
+#include "yaml-cpp/emittermanip.h"
+#include <cassert>
+#include <vector>
+#include <stack>
+#include <memory>
+#include <stdexcept>
+
+namespace YAML
+{
+       struct FmtScope { enum value { Local, Global }; };
+       struct GroupType { enum value { None, Seq, Map }; };
+       struct FlowType { enum value { None, Flow, Block }; };
+
+       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; }
+               
+               // node handling
+        void SetAnchor();
+        void SetTag();
+        void SetNonContent();
+        void SetLongKey();
+        void ForceFlow();
+        void StartedDoc();
+        void EndedDoc();
+        void StartedScalar();
+               void StartedGroup(GroupType::value type);
+               void EndedGroup(GroupType::value type);
+
+        EmitterNodeType::value NextGroupType(GroupType::value type) const;
+        EmitterNodeType::value CurGroupNodeType() const;
+
+               GroupType::value CurGroupType() const;
+        FlowType::value CurGroupFlowType() const;
+        int CurGroupIndent() const;
+        std::size_t CurGroupChildCount() const;
+        bool CurGroupLongKey() const;
+
+        int LastIndent() const;
+               int CurIndent() const { return m_curIndent; }
+        bool HasAnchor() const { return m_hasAnchor; }
+        bool HasTag() const { return m_hasTag; }
+        bool HasBegunNode() const { return m_hasAnchor || m_hasTag || m_hasNonContent; }
+        bool HasBegunContent() const { return m_hasAnchor || m_hasTag; }
+
+               void ClearModifiedSettings();
+
+               // formatters
+               void SetLocalValue(EMITTER_MANIP value);
+
+               bool SetOutputCharset(EMITTER_MANIP value, FmtScope::value scope);
+               EMITTER_MANIP GetOutputCharset() const { return m_charset.get(); }
+
+               bool SetStringFormat(EMITTER_MANIP value, FmtScope::value scope);
+               EMITTER_MANIP GetStringFormat() const { return m_strFmt.get(); }
+               
+               bool SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope);
+               EMITTER_MANIP GetBoolFormat() const { return m_boolFmt.get(); }
+
+               bool SetBoolLengthFormat(EMITTER_MANIP value, FmtScope::value scope);
+               EMITTER_MANIP GetBoolLengthFormat() const { return m_boolLengthFmt.get(); }
+
+               bool SetBoolCaseFormat(EMITTER_MANIP value, FmtScope::value scope);
+               EMITTER_MANIP GetBoolCaseFormat() const { return m_boolCaseFmt.get(); }
+
+               bool SetIntFormat(EMITTER_MANIP value, FmtScope::value scope);
+               EMITTER_MANIP GetIntFormat() const { return m_intFmt.get(); }
+
+               bool SetIndent(unsigned value, FmtScope::value scope);
+               int GetIndent() const { return m_indent.get(); }
+               
+               bool SetPreCommentIndent(unsigned value, FmtScope::value scope);
+               int GetPreCommentIndent() const { return m_preCommentIndent.get(); }
+               bool SetPostCommentIndent(unsigned value, FmtScope::value scope);
+               int GetPostCommentIndent() const { return m_postCommentIndent.get(); }
+               
+               bool SetFlowType(GroupType::value groupType, EMITTER_MANIP value, FmtScope::value scope);
+               EMITTER_MANIP GetFlowType(GroupType::value groupType) const;
+               
+               bool SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope);
+               EMITTER_MANIP GetMapKeyFormat() const { return m_mapKeyFmt.get(); }
+        
+        bool SetFloatPrecision(int value, FmtScope::value scope);
+        unsigned GetFloatPrecision() const { return m_floatPrecision.get(); }
+        bool SetDoublePrecision(int value, FmtScope::value scope);
+        unsigned GetDoublePrecision() const { return m_doublePrecision.get(); }
+               
+       private:
+               template <typename T>
+               void _Set(Setting<T>& fmt, T value, FmtScope::value scope);
+        
+        void StartedNode();
+               
+       private:
+               // basic state ok?
+               bool m_isGood;
+               std::string m_lastError;
+               
+               // other state
+               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 {
+                       explicit Group(GroupType::value type_): type(type_), indent(0), childCount(0), longKey(false) {}
+                       
+            GroupType::value type;
+            FlowType::value flowType;
+                       int indent;
+            std::size_t childCount;
+            bool longKey;
+                       
+                       SettingChanges modifiedSettings;
+            
+            EmitterNodeType::value NodeType() const {
+                if(type == GroupType::Seq) {
+                    if(flowType == FlowType::Flow)
+                        return EmitterNodeType::FlowSeq;
+                    else
+                        return EmitterNodeType::BlockSeq;
+                } else {
+                    if(flowType == FlowType::Flow)
+                        return EmitterNodeType::FlowMap;
+                    else
+                        return EmitterNodeType::BlockMap;
+                }
+
+                // can't get here
+                assert(false);
+                return EmitterNodeType::None;
+            }
+               };
+
+               ptr_stack<Group> m_groups;
+               unsigned m_curIndent;
+        bool m_hasAnchor;
+        bool m_hasTag;
+        bool m_hasNonContent;
+        std::size_t m_docCount;
+       };
+
+       template <typename T>
+       void EmitterState::_Set(Setting<T>& fmt, T value, FmtScope::value scope) {
+               switch(scope) {
+                       case FmtScope::Local:
+                               m_modifiedSettings.push(fmt.set(value));
+                               break;
+                       case FmtScope::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/src/emitterutils.cpp b/src/emitterutils.cpp
new file mode 100644 (file)
index 0000000..09780d0
--- /dev/null
@@ -0,0 +1,424 @@
+#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_wrapper& 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, FlowType::value flowType, bool allowOnlyAscii) {
+                               if(str.empty())
+                                       return false;
+                               
+                               // first check the start
+                               const RegEx& start = (flowType == FlowType::Flow ? 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 = (flowType == FlowType::Flow ? 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 && (0x80 <= static_cast<unsigned char>(buffer[0]))) 
+                                               return false;
+                                       ++buffer;
+                               }
+                               
+                               return true;
+                       }
+
+                       bool IsValidSingleQuotedScalar(const std::string& str, bool escapeNonAscii)
+            {
+                // TODO: check for non-printable characters?
+                for(std::size_t i=0;i<str.size();i++) {
+                    if(escapeNonAscii && (0x80 <= static_cast<unsigned char>(str[i])))
+                       return false;
+                    if(str[i] == '\n')
+                        return false;
+                }
+                return true;
+                       }
+            
+            bool IsValidLiteralScalar(const std::string& str, FlowType::value flowType, bool escapeNonAscii)
+            {
+                if(flowType == FlowType::Flow)
+                    return false;
+
+                // TODO: check for non-printable characters?
+                for(std::size_t i=0;i<str.size();i++) {
+                    if(escapeNonAscii && (0x80 <= static_cast<unsigned char>(str[i])))
+                        return false;
+                }
+                return true;
+            }
+                       
+            void WriteDoubleQuoteEscapeSequence(ostream_wrapper& out, int codePoint) {
+                               static const char hexDigits[] = "0123456789abcdef";
+
+                out << "\\";
+                               int digits = 8;
+                               if(codePoint < 0xFF) {
+                    out << "x";
+                                       digits = 2;
+                               } else if(codePoint < 0xFFFF) {
+                    out << "u";
+                                       digits = 4;
+                               } else {
+                    out << "U";
+                    digits = 8;
+                }
+
+                               // Write digits into the escape sequence
+                               for (; digits > 0; --digits)
+                                       out << hexDigits[(codePoint >> (4 * (digits - 1))) & 0xF];
+                       }
+
+                       bool WriteAliasName(ostream_wrapper& 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;
+                       }
+               }
+               
+        StringFormat::value ComputeStringFormat(const std::string& str, EMITTER_MANIP strFormat, FlowType::value flowType, bool escapeNonAscii)
+        {
+            switch(strFormat) {
+                case Auto:
+                    if(IsValidPlainScalar(str, flowType, escapeNonAscii))
+                        return StringFormat::Plain;
+                    return StringFormat::DoubleQuoted;
+                case SingleQuoted:
+                    if(IsValidSingleQuotedScalar(str, escapeNonAscii))
+                        return StringFormat::SingleQuoted;
+                    return StringFormat::DoubleQuoted;
+                case DoubleQuoted:
+                    return StringFormat::DoubleQuoted;
+                case Literal:
+                    if(IsValidLiteralScalar(str, flowType, escapeNonAscii))
+                        return StringFormat::Literal;
+                    return StringFormat::DoubleQuoted;
+                default:
+                    break;
+            }
+
+            return StringFormat::DoubleQuoted;
+        }
+
+               bool WriteSingleQuotedString(ostream_wrapper& 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_wrapper& out, const std::string& str, bool escapeNonAscii)
+               {
+                       out << "\"";
+                       int codePoint;
+                       for(std::string::const_iterator i = str.begin();
+                               GetNextCodePointAndAdvance(codePoint, i, str.end());
+                               ) 
+                       {
+                switch(codePoint) {
+                    case '\"': out << "\\\""; break;
+                    case '\\': out << "\\\\"; break;
+                    case '\n': out << "\\n"; break;
+                    case '\t': out << "\\t"; break;
+                    case '\r': out << "\\r"; break;
+                    case '\b': out << "\\b"; break;
+                    default:
+                        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_wrapper& 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_wrapper& 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_wrapper& out, const std::string& str, int postCommentIndent)
+               {
+                       const unsigned curIndent = out.col();
+                       out << "#" << Indentation(postCommentIndent);
+            out.set_comment();
+                       int codePoint;
+                       for(std::string::const_iterator i = str.begin();
+                               GetNextCodePointAndAdvance(codePoint, i, str.end());
+                               )
+                       {
+                               if(codePoint == '\n') {
+                                       out << "\n" << IndentTo(curIndent) << "#" << Indentation(postCommentIndent);
+                    out.set_comment();
+                               } else {
+                                       WriteCodePoint(out, codePoint);
+                }
+                       }
+                       return true;
+               }
+
+               bool WriteAlias(ostream_wrapper& out, const std::string& str)
+               {
+                       out << "*";
+                       return WriteAliasName(out, str);
+               }
+               
+               bool WriteAnchor(ostream_wrapper& out, const std::string& str)
+               {
+                       out << "&";
+                       return WriteAliasName(out, str);
+               }
+
+               bool WriteTag(ostream_wrapper& 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_wrapper& 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_wrapper& out, const Binary& binary)
+               {
+            WriteDoubleQuotedString(out, EncodeBase64(binary.data(), binary.size()), false);
+            return true;
+               }
+       }
+}
+
diff --git a/src/emitterutils.h b/src/emitterutils.h
new file mode 100644 (file)
index 0000000..50b37f0
--- /dev/null
@@ -0,0 +1,36 @@
+#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 "emitterstate.h"
+#include "yaml-cpp/ostream_wrapper.h"
+#include <string>
+
+namespace YAML
+{
+    class Binary;
+    
+    struct StringFormat { enum value { Plain, SingleQuoted, DoubleQuoted, Literal }; };
+
+       namespace Utils
+       {
+        StringFormat::value ComputeStringFormat(const std::string& str, EMITTER_MANIP strFormat, FlowType::value flowType, bool escapeNonAscii);
+        
+               bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str);
+               bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str, bool escapeNonAscii);
+               bool WriteLiteralString(ostream_wrapper& out, const std::string& str, int indent);
+               bool WriteChar(ostream_wrapper& out, char ch);
+               bool WriteComment(ostream_wrapper& out, const std::string& str, int postCommentIndent);
+               bool WriteAlias(ostream_wrapper& out, const std::string& str);
+               bool WriteAnchor(ostream_wrapper& out, const std::string& str);
+               bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim);
+               bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix, const std::string& tag);
+               bool WriteBinary(ostream_wrapper& out, const Binary& binary);
+       }
+}
+
+#endif // EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/exp.cpp b/src/exp.cpp
new file mode 100644 (file)
index 0000000..7bc5454
--- /dev/null
@@ -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/src/exp.h b/src/exp.h
new file mode 100644 (file)
index 0000000..52bfd0a
--- /dev/null
+++ b/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('?') + BlankOrBreak();
+                       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/src/indentation.h b/src/indentation.h
new file mode 100644 (file)
index 0000000..426fcb5
--- /dev/null
@@ -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_wrapper.h"
+#include <iostream>
+
+namespace YAML
+{
+       struct Indentation {
+               Indentation(unsigned n_): n(n_) {}
+               unsigned n;
+       };
+       
+       inline ostream_wrapper& operator << (ostream_wrapper& 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_wrapper& operator << (ostream_wrapper& out, const IndentTo& indent) {
+               while(out.col() < indent.n)
+                       out << ' ';
+               return out;
+       }
+}
+
+
+#endif // INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/memory.cpp b/src/memory.cpp
new file mode 100644 (file)
index 0000000..98d0dfb
--- /dev/null
@@ -0,0 +1,29 @@
+#include "yaml-cpp/node/detail/memory.h"
+#include "yaml-cpp/node/detail/node.h"
+
+namespace YAML
+{
+       namespace detail
+       {
+               void memory_holder::merge(memory_holder& rhs)
+               {
+                       if(m_pMemory == rhs.m_pMemory)
+                               return;
+                       
+                       m_pMemory->merge(*rhs.m_pMemory);
+                       rhs.m_pMemory = m_pMemory;
+               }
+               
+               node& memory::create_node()
+               {
+                       shared_node pNode(new node);
+                       m_nodes.insert(pNode);
+                       return *pNode;
+               }
+               
+               void memory::merge(const memory& rhs)
+               {
+                       m_nodes.insert(rhs.m_nodes.begin(), rhs.m_nodes.end());
+               }
+       }
+}
diff --git a/src/node.cpp b/src/node.cpp
new file mode 100644 (file)
index 0000000..2d21aa9
--- /dev/null
@@ -0,0 +1,14 @@
+#include "yaml-cpp/node/node.h"
+#include "nodebuilder.h"
+#include "nodeevents.h"
+
+namespace YAML
+{
+    Node Clone(const Node& node)
+    {
+               NodeEvents events(node);
+        NodeBuilder builder;
+        events.Emit(builder);
+        return builder.Root();
+    }
+}
diff --git a/src/node_data.cpp b/src/node_data.cpp
new file mode 100644 (file)
index 0000000..6f82f7b
--- /dev/null
@@ -0,0 +1,295 @@
+#include "yaml-cpp/node/detail/node_data.h"
+#include "yaml-cpp/node/detail/memory.h"
+#include "yaml-cpp/node/detail/node.h"
+#include "yaml-cpp/exceptions.h"
+#include <sstream>
+
+namespace YAML
+{
+       namespace detail
+       {
+               std::string node_data::empty_scalar;
+
+               node_data::node_data(): m_isDefined(false), m_type(NodeType::Null), m_seqSize(0)
+               {
+               }
+
+               void node_data::mark_defined()
+               {
+                       if(m_type == NodeType::Undefined)
+                               m_type = NodeType::Null;
+                       m_isDefined = true;
+               }
+
+               void node_data::set_type(NodeType::value type)
+               {
+                       if(type == NodeType::Undefined) {
+                               m_type = type;
+                               m_isDefined = false;
+                               return;
+                       }
+                       
+
+                       m_isDefined = true;
+                       if(type == m_type)
+                               return;
+                       
+                       m_type = type;
+                       
+                       switch(m_type) {
+                               case NodeType::Null:
+                                       break;
+                               case NodeType::Scalar:
+                                       m_scalar.clear();
+                                       break;
+                               case NodeType::Sequence:
+                                       reset_sequence();
+                                       break;
+                               case NodeType::Map:
+                                       reset_map();
+                                       break;
+                               case NodeType::Undefined:
+                                       assert(false);
+                                       break;
+                       }
+               }
+
+               void node_data::set_tag(const std::string& tag)
+               {
+                       m_tag = tag;
+               }
+               
+               void node_data::set_null()
+               {
+                       m_isDefined = true;
+                       m_type = NodeType::Null;
+               }
+               
+               void node_data::set_scalar(const std::string& scalar)
+               {
+                       m_isDefined = true;
+                       m_type = NodeType::Scalar;
+                       m_scalar = scalar;
+               }
+
+               // size/iterator
+               std::size_t node_data::size() const
+               {
+                       if(!m_isDefined)
+                               return 0;
+
+                       switch(m_type) {
+                               case NodeType::Sequence: compute_seq_size(); return m_seqSize;
+                               case NodeType::Map: compute_map_size(); return m_map.size() - m_undefinedPairs.size();
+                               default:
+                                       return 0;
+                       }
+                       return 0;
+               }
+               
+               void node_data::compute_seq_size() const
+               {
+                       while(m_seqSize < m_sequence.size() && m_sequence[m_seqSize]->is_defined())
+                               m_seqSize++;
+               }
+
+               void node_data::compute_map_size() const
+               {
+                       kv_pairs::iterator it = m_undefinedPairs.begin();
+                       while(it != m_undefinedPairs.end()) {
+                               kv_pairs::iterator jt = boost::next(it);
+                               if(it->first->is_defined() && it->second->is_defined())
+                                       m_undefinedPairs.erase(it);
+                               it = jt;
+                       }
+               }
+               
+               const_node_iterator node_data::begin() const
+               {
+                       if(!m_isDefined)
+                               return const_node_iterator();
+                       
+                       switch(m_type) {
+                               case NodeType::Sequence: return const_node_iterator(m_sequence.begin());
+                               case NodeType::Map: return const_node_iterator(m_map.begin(), m_map.end());
+                               default: return const_node_iterator();
+                       }
+               }
+               
+               node_iterator node_data::begin()
+               {
+                       if(!m_isDefined)
+                               return node_iterator();
+
+                       switch(m_type) {
+                               case NodeType::Sequence: return node_iterator(m_sequence.begin());
+                               case NodeType::Map: return node_iterator(m_map.begin(), m_map.end());
+                               default: return node_iterator();
+                       }
+               }
+               
+               const_node_iterator node_data::end() const
+               {
+                       if(!m_isDefined)
+                               return const_node_iterator();
+
+                       switch(m_type) {
+                               case NodeType::Sequence: return const_node_iterator(m_sequence.end());
+                               case NodeType::Map: return const_node_iterator(m_map.end(), m_map.end());
+                               default: return const_node_iterator();
+                       }
+               }
+               
+               node_iterator node_data::end()
+               {
+                       if(!m_isDefined)
+                               return node_iterator();
+
+                       switch(m_type) {
+                               case NodeType::Sequence: return node_iterator(m_sequence.end());
+                               case NodeType::Map: return node_iterator(m_map.end(), m_map.end());
+                               default: return node_iterator();
+                       }
+               }
+
+               // sequence
+               void node_data::push_back(node& node, shared_memory_holder /* pMemory */)
+               {
+                       if(m_type == NodeType::Undefined || m_type == NodeType::Null) {
+                               m_type = NodeType::Sequence;
+                               reset_sequence();
+                       }
+                       
+                       if(m_type != NodeType::Sequence)
+                throw BadPushback();
+                       
+                       m_sequence.push_back(&node);
+               }
+
+               void node_data::insert(node& key, node& value, shared_memory_holder pMemory)
+               {
+                       switch(m_type) {
+                               case NodeType::Map:
+                                       break;
+                               case NodeType::Undefined:
+                               case NodeType::Null:
+                               case NodeType::Sequence:
+                                       convert_to_map(pMemory);
+                                       break;
+                               case NodeType::Scalar:
+                    throw BadSubscript();
+                       }
+
+                       insert_map_pair(key, value);
+               }
+
+               // indexing
+               node& node_data::get(node& key, shared_memory_holder pMemory) const
+               {
+                       if(m_type != NodeType::Map)
+                               return pMemory->create_node();
+                       
+                       for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
+                               if(it->first->is(key))
+                                       return *it->second;
+                       }
+                       
+                       return pMemory->create_node();
+               }
+               
+               node& node_data::get(node& key, shared_memory_holder pMemory)
+               {
+                       switch(m_type) {
+                               case NodeType::Map:
+                                       break;
+                               case NodeType::Undefined:
+                               case NodeType::Null:
+                               case NodeType::Sequence:
+                                       convert_to_map(pMemory);
+                                       break;
+                               case NodeType::Scalar:
+                    throw BadSubscript();
+                       }
+
+                       for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
+                               if(it->first->is(key))
+                                       return *it->second;
+                       }
+                       
+                       node& value = pMemory->create_node();
+                       insert_map_pair(key, value);
+                       return value;
+               }
+               
+               bool node_data::remove(node& key, shared_memory_holder /* pMemory */)
+               {
+                       if(m_type != NodeType::Map)
+                               return false;
+
+                       for(node_map::iterator it=m_map.begin();it!=m_map.end();++it) {
+                               if(it->first->is(key)) {
+                                       m_map.erase(it);
+                                       return true;
+                               }
+                       }
+                       
+                       return false;
+               }
+
+               void node_data::reset_sequence()
+               {
+                       m_sequence.clear();
+                       m_seqSize = 0;
+               }
+
+               void node_data::reset_map()
+               {
+                       m_map.clear();
+                       m_undefinedPairs.clear();
+               }
+
+               void node_data::insert_map_pair(node& key, node& value)
+               {
+                       m_map[&key] = &value;
+                       if(!key.is_defined() || !value.is_defined())
+                               m_undefinedPairs.push_back(kv_pair(&key, &value));
+               }
+
+               void node_data::convert_to_map(shared_memory_holder pMemory)
+               {
+                       switch(m_type) {
+                               case NodeType::Undefined:
+                               case NodeType::Null:
+                                       reset_map();
+                                       m_type = NodeType::Map;
+                                       break;
+                               case NodeType::Sequence:
+                                       convert_sequence_to_map(pMemory);
+                                       break;
+                               case NodeType::Map:
+                                       break;
+                               case NodeType::Scalar:
+                                       assert(false);
+                                       break;
+                       }
+               }
+
+               void node_data::convert_sequence_to_map(shared_memory_holder pMemory)
+               {
+                       assert(m_type == NodeType::Sequence);
+
+                       reset_map();
+                       for(std::size_t i=0;i<m_sequence.size();i++) {
+                               std::stringstream stream;
+                               stream << i;
+
+                               node& key = pMemory->create_node();
+                               key.set_scalar(stream.str());
+                               insert_map_pair(key, *m_sequence[i]);
+                       }
+                       
+                       reset_sequence();
+                       m_type = NodeType::Map;
+               }
+       }
+}
diff --git a/src/nodebuilder.cpp b/src/nodebuilder.cpp
new file mode 100644 (file)
index 0000000..6735f73
--- /dev/null
@@ -0,0 +1,138 @@
+#include "nodebuilder.h"
+#include "yaml-cpp/mark.h"
+#include "yaml-cpp/node/node.h"
+#include "yaml-cpp/node/impl.h"
+#include <cassert>
+
+namespace YAML
+{
+       NodeBuilder::NodeBuilder(): m_pMemory(new detail::memory_holder), m_pRoot(0), m_mapDepth(0)
+       {
+               m_anchors.push_back(0); // since the anchors start at 1
+       }
+       
+       NodeBuilder::~NodeBuilder()
+       {
+       }
+       
+       Node NodeBuilder::Root()
+       {
+               if(!m_pRoot)
+                       return Node();
+               
+               return Node(*m_pRoot, m_pMemory);
+       }
+
+       void NodeBuilder::OnDocumentStart(const Mark&)
+       {
+       }
+       
+       void NodeBuilder::OnDocumentEnd()
+       {
+       }
+       
+       void NodeBuilder::OnNull(const Mark& /* mark */, anchor_t anchor)
+       {
+               detail::node& node = Push(anchor);
+               node.set_null();
+               Pop();
+       }
+       
+       void NodeBuilder::OnAlias(const Mark& /* mark */, anchor_t anchor)
+       {
+               detail::node& node = *m_anchors[anchor];
+               Push(node);
+               Pop();
+       }
+       
+       void NodeBuilder::OnScalar(const Mark& /* mark */, const std::string& tag, anchor_t anchor, const std::string& value)
+       {
+               detail::node& node = Push(anchor);
+               node.set_scalar(value);
+               node.set_tag(tag);
+               Pop();
+       }
+       
+       void NodeBuilder::OnSequenceStart(const Mark& /* mark */, const std::string& tag, anchor_t anchor)
+       {
+               detail::node& node = Push(anchor);
+               node.set_tag(tag);
+               node.set_type(NodeType::Sequence);
+       }
+       
+       void NodeBuilder::OnSequenceEnd()
+       {
+               Pop();
+       }
+       
+       void NodeBuilder::OnMapStart(const Mark& /* mark */, const std::string& tag, anchor_t anchor)
+       {
+               detail::node& node = Push(anchor);
+               node.set_type(NodeType::Map);
+               node.set_tag(tag);
+               m_mapDepth++;
+       }
+       
+       void NodeBuilder::OnMapEnd()
+       {
+               assert(m_mapDepth > 0);
+               m_mapDepth--;
+               Pop();
+       }
+
+       detail::node& NodeBuilder::Push(anchor_t anchor)
+       {
+               detail::node& node = m_pMemory->create_node();
+               RegisterAnchor(anchor, node);
+               Push(node);
+               return node;
+       }
+       
+       void NodeBuilder::Push(detail::node& node)
+       {
+               const bool needsKey = (!m_stack.empty() && m_stack.back()->type() == NodeType::Map && m_keys.size() < m_mapDepth);
+               
+               m_stack.push_back(&node);
+               if(needsKey)
+                       m_keys.push_back(PushedKey(&node, false));
+       }
+       
+       void NodeBuilder::Pop()
+       {
+               assert(!m_stack.empty());
+               if(m_stack.size() == 1) {
+                       m_pRoot = m_stack[0];
+                       m_stack.pop_back();
+                       return;
+               }
+               
+               detail::node& node = *m_stack.back();
+               m_stack.pop_back();
+
+               detail::node& collection = *m_stack.back();
+               
+               if(collection.type() == NodeType::Sequence) {
+                       collection.push_back(node, m_pMemory);
+               } else if(collection.type() == NodeType::Map) {
+                       assert(!m_keys.empty());
+                       PushedKey& key = m_keys.back();
+                       if(key.second) {
+                               collection.insert(*key.first, node, m_pMemory);
+                               m_keys.pop_back();
+                       } else {
+                               key.second = true;
+                       }
+               } else {
+                       assert(false);
+                       m_stack.clear();
+               }
+       }
+
+       void NodeBuilder::RegisterAnchor(anchor_t anchor, detail::node& node)
+       {
+               if(anchor) {
+                       assert(anchor == m_anchors.size());
+                       m_anchors.push_back(&node);
+               }
+       }
+}
diff --git a/src/nodebuilder.h b/src/nodebuilder.h
new file mode 100644 (file)
index 0000000..cce91d3
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODE_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 "yaml-cpp/node/ptr.h"
+#include <vector>
+
+namespace YAML
+{
+       class Node;
+
+       class NodeBuilder: public EventHandler
+       {
+       public:
+               NodeBuilder();
+               virtual ~NodeBuilder();
+               
+               Node Root();
+               
+               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:
+               detail::node& Push(anchor_t anchor);
+               void Push(detail::node& node);
+               void Pop();
+               void RegisterAnchor(anchor_t anchor, detail::node& node);
+               
+       private:
+               detail::shared_memory_holder m_pMemory;
+               detail::node *m_pRoot;
+               
+               typedef std::vector<detail::node *> Nodes;
+               Nodes m_stack;
+               Nodes m_anchors;
+
+               typedef std::pair<detail::node *, bool> PushedKey;
+               std::vector<PushedKey> m_keys;
+               std::size_t m_mapDepth;
+       };
+}
+
+#endif // NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
diff --git a/src/nodeevents.cpp b/src/nodeevents.cpp
new file mode 100644 (file)
index 0000000..721f9c6
--- /dev/null
@@ -0,0 +1,99 @@
+#include "nodeevents.h"
+#include "yaml-cpp/node/node.h"
+#include "yaml-cpp/node/impl.h"
+#include "yaml-cpp/eventhandler.h"
+#include "yaml-cpp/mark.h"
+
+namespace YAML
+{
+       void NodeEvents::AliasManager::RegisterReference(const detail::node& node)
+       {
+               m_anchorByIdentity.insert(std::make_pair(node.ref(), _CreateNewAnchor()));
+       }
+       
+       anchor_t NodeEvents::AliasManager::LookupAnchor(const detail::node& node) const
+       {
+               AnchorByIdentity::const_iterator it = m_anchorByIdentity.find(node.ref());
+               if(it == m_anchorByIdentity.end())
+                       return 0;
+               return it->second;
+       }
+
+       NodeEvents::NodeEvents(const Node& node): m_pMemory(node.m_pMemory), m_root(*node.m_pNode)
+       {
+               Setup(m_root);
+       }
+
+       void NodeEvents::Setup(const detail::node& node)
+       {
+               int& refCount = m_refCount[node.ref()];
+               refCount++;
+               if(refCount > 1)
+                       return;
+               
+               if(node.type() == NodeType::Sequence) {
+                       for(detail::const_node_iterator it=node.begin();it!=node.end();++it)
+                               Setup(**it);
+               } else if(node.type() == NodeType::Map) {
+                       for(detail::const_node_iterator it=node.begin();it!=node.end();++it) {
+                               Setup(*it->first);
+                               Setup(*it->second);
+                       }
+               }
+       }
+
+       void NodeEvents::Emit(EventHandler& handler)
+       {
+               AliasManager am;
+               
+               handler.OnDocumentStart(Mark());
+               Emit(m_root, handler, am);
+               handler.OnDocumentEnd();
+       }
+
+       void NodeEvents::Emit(const detail::node& node, EventHandler& handler, AliasManager& am) const
+       {
+               anchor_t anchor = NullAnchor;
+               if(IsAliased(node)) {
+                       anchor = am.LookupAnchor(node);
+                       if(anchor) {
+                               handler.OnAlias(Mark(), anchor);
+                               return;
+                       }
+                       
+                       am.RegisterReference(node);
+                       anchor = am.LookupAnchor(node);
+               }
+               
+               switch(node.type()) {
+                       case NodeType::Undefined:
+                               break;
+                       case NodeType::Null:
+                               handler.OnNull(Mark(), anchor);
+                               break;
+                       case NodeType::Scalar:
+                               handler.OnScalar(Mark(), node.tag(), anchor, node.scalar());
+                               break;
+                       case NodeType::Sequence:
+                               handler.OnSequenceStart(Mark(), node.tag(), anchor);
+                               for(detail::const_node_iterator it=node.begin();it!=node.end();++it)
+                                       Emit(**it, handler, am);
+                               handler.OnSequenceEnd();
+                               break;
+                       case NodeType::Map:
+                               handler.OnMapStart(Mark(), node.tag(), anchor);
+                               for(detail::const_node_iterator it=node.begin();it!=node.end();++it) {
+                                       Emit(*it->first, handler, am);
+                                       Emit(*it->second, handler, am);
+                               }
+                               handler.OnMapEnd();
+                               break;
+               }
+       }
+
+       bool NodeEvents::IsAliased(const detail::node& node) const
+       {
+               RefCount::const_iterator it = m_refCount.find(node.ref());
+               return it != m_refCount.end() && it->second > 1;
+       }
+}
diff --git a/src/nodeevents.h b/src/nodeevents.h
new file mode 100644 (file)
index 0000000..d142115
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODE_NODEEVENTS_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/node/ptr.h"
+#include <map>
+#include <vector>
+
+namespace YAML
+{
+       class EventHandler;
+       class Node;
+       
+       class NodeEvents
+       {
+       public:
+               explicit NodeEvents(const Node& node);
+               
+               void Emit(EventHandler& handler);
+               
+       private:
+               class AliasManager {
+               public:
+                       AliasManager(): m_curAnchor(0) {}
+                       
+                       void RegisterReference(const detail::node& node);
+                       anchor_t LookupAnchor(const detail::node& node) const;
+                       
+               private:
+                       anchor_t _CreateNewAnchor() { return ++m_curAnchor; }
+                       
+               private:
+                       typedef std::map<const detail::node_ref*, anchor_t> AnchorByIdentity;
+                       AnchorByIdentity m_anchorByIdentity;
+                       
+                       anchor_t m_curAnchor;
+               };
+               
+               void Setup(const detail::node& node);
+               void Emit(const detail::node& node, EventHandler& handler, AliasManager& am) const;
+               bool IsAliased(const detail::node& node) const;
+               
+       private:
+               detail::shared_memory_holder m_pMemory;
+               detail::node& m_root;
+               
+               typedef std::map<const detail::node_ref *, int> RefCount;
+               RefCount m_refCount;
+       };
+}
+
+#endif // NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
diff --git a/src/null.cpp b/src/null.cpp
new file mode 100644 (file)
index 0000000..37f3197
--- /dev/null
@@ -0,0 +1,6 @@
+#include "yaml-cpp/null.h"
+
+namespace YAML
+{
+       _Null Null;
+}
diff --git a/src/ostream_wrapper.cpp b/src/ostream_wrapper.cpp
new file mode 100644 (file)
index 0000000..15d9f0f
--- /dev/null
@@ -0,0 +1,56 @@
+#include "yaml-cpp/ostream_wrapper.h"
+#include <cstring>
+#include <iostream>
+
+namespace YAML
+{
+       ostream_wrapper::ostream_wrapper(): m_pStream(0), m_pos(0), m_row(0), m_col(0), m_comment(false)
+       {
+       }
+       
+       ostream_wrapper::ostream_wrapper(std::ostream& stream): m_pStream(&stream), m_pos(0), m_row(0), m_col(0), m_comment(false)
+       {
+       }
+
+       ostream_wrapper::~ostream_wrapper()
+       {
+       }
+       
+    void ostream_wrapper::write(const std::string& str)
+    {
+        if(m_pStream) {
+            m_pStream->write(str.c_str(), str.size());
+        } else {
+            m_buffer.resize(std::max(m_buffer.size(), m_pos + str.size() + 1));
+            std::copy(str.begin(), str.end(), &m_buffer[m_pos]);
+        }
+        
+        for(std::size_t i=0;i<str.size();i++)
+            update_pos(str[i]);
+    }
+
+    void ostream_wrapper::write(const char *str, std::size_t size)
+    {
+        if(m_pStream) {
+            m_pStream->write(str, size);
+        } else {
+            m_buffer.resize(std::max(m_buffer.size(), m_pos + size + 1));
+            std::copy(str, str + size, &m_buffer[m_pos]);
+        }
+        
+        for(std::size_t i=0;i<size;i++)
+            update_pos(str[i]);
+    }
+       
+    void ostream_wrapper::update_pos(char ch)
+    {
+               m_pos++;
+        m_col++;
+               
+               if(ch == '\n') {
+                       m_row++;
+                       m_col = 0;
+            m_comment = false;
+               }
+    }
+}
diff --git a/src/parse.cpp b/src/parse.cpp
new file mode 100644 (file)
index 0000000..1537d55
--- /dev/null
@@ -0,0 +1,68 @@
+#include "yaml-cpp/node/parse.h"
+#include "yaml-cpp/node/node.h"
+#include "yaml-cpp/node/impl.h"
+#include "yaml-cpp/parser.h"
+#include "nodebuilder.h"
+
+#include <fstream>
+#include <sstream>
+
+namespace YAML
+{
+       Node Load(const std::string& input) {
+               std::stringstream stream(input);
+               return Load(stream);
+       }
+       
+       Node Load(const char *input) {
+               std::stringstream stream(input);
+               return Load(stream);
+       }
+       
+       Node Load(std::istream& input) {
+               Parser parser(input);
+               NodeBuilder builder;
+               if(!parser.HandleNextDocument(builder))
+                       return Node();
+               
+               return builder.Root();
+       }
+
+    Node LoadFile(const std::string& filename) {
+        std::ifstream fin(filename.c_str());
+        if(!fin)
+            throw BadFile();
+        return Load(fin);
+    }
+
+       std::vector<Node> LoadAll(const std::string& input) {
+               std::stringstream stream(input);
+               return LoadAll(stream);
+       }
+       
+       std::vector<Node> LoadAll(const char *input) {
+               std::stringstream stream(input);
+               return LoadAll(stream);
+       }
+       
+       std::vector<Node> LoadAll(std::istream& input) {
+               std::vector<Node> docs;
+               
+               Parser parser(input);
+               while(1) {
+                       NodeBuilder builder;
+                       if(!parser.HandleNextDocument(builder))
+                               break;
+                       docs.push_back(builder.Root());
+               }
+               
+               return docs;
+       }
+
+    std::vector<Node> LoadAllFromFile(const std::string& filename) {
+        std::ifstream fin(filename.c_str());
+        if(!fin)
+            throw BadFile();
+        return LoadAll(fin);
+    }
+}
diff --git a/src/parser.cpp b/src/parser.cpp
new file mode 100644 (file)
index 0000000..7861ec1
--- /dev/null
@@ -0,0 +1,141 @@
+#include "yaml-cpp/parser.h"
+#include "yaml-cpp/eventhandler.h"
+#include "yaml-cpp/exceptions.h"
+#include "directives.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;
+       }
+
+       // 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/src/ptr_stack.h b/src/ptr_stack.h
new file mode 100644 (file)
index 0000000..eec0fb8
--- /dev/null
@@ -0,0 +1,49 @@
+#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(); }
+
+       T& top(std::ptrdiff_t diff) { return **(m_data.end() - 1 + diff); }
+       const T& top(std::ptrdiff_t diff) const { return **(m_data.end() - 1 + diff); }
+
+private:
+       std::vector<T*> m_data;
+};
+
+#endif // PTR_STACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/ptr_vector.h b/src/ptr_vector.h
new file mode 100644 (file)
index 0000000..7b936cb
--- /dev/null
@@ -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/src/regex.cpp b/src/regex.cpp
new file mode 100644 (file)
index 0000000..b35b1f4
--- /dev/null
@@ -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/src/regex.h b/src/regex.h
new file mode 100644 (file)
index 0000000..8722e62
--- /dev/null
@@ -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/src/regeximpl.h b/src/regeximpl.h
new file mode 100644 (file)
index 0000000..d5c20d7
--- /dev/null
@@ -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/src/scanner.cpp b/src/scanner.cpp
new file mode 100644 (file)
index 0000000..66cce0a
--- /dev/null
@@ -0,0 +1,394 @@
+#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();
+       }
+
+    // mark
+    // . Returns the current mark in the stream
+    Mark Scanner::mark() const
+    {
+        return INPUT.mark();
+    }
+
+       // 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_mark();
+               if(!m_tokens.empty()) {
+                       const Token& token = m_tokens.front();
+                       mark = token.mark;
+               }
+               throw ParserException(mark, msg);
+       }
+}
+
diff --git a/src/scanner.h b/src/scanner.h
new file mode 100644 (file)
index 0000000..fe71124
--- /dev/null
@@ -0,0 +1,133 @@
+#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();
+        Mark mark() const;
+
+       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/src/scanscalar.cpp b/src/scanscalar.cpp
new file mode 100644 (file)
index 0000000..064c086
--- /dev/null
@@ -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/src/scanscalar.h b/src/scanscalar.h
new file mode 100644 (file)
index 0000000..c198cb1
--- /dev/null
@@ -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/src/scantag.cpp b/src/scantag.cpp
new file mode 100644 (file)
index 0000000..b71cbcc
--- /dev/null
@@ -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/src/scantag.h b/src/scantag.h
new file mode 100644 (file)
index 0000000..38437c0
--- /dev/null
@@ -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/src/scantoken.cpp b/src/scantoken.cpp
new file mode 100644 (file)
index 0000000..06d9cd6
--- /dev/null
@@ -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/src/setting.h b/src/setting.h
new file mode 100644 (file)
index 0000000..806ccda
--- /dev/null
@@ -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/src/simplekey.cpp b/src/simplekey.cpp
new file mode 100644 (file)
index 0000000..857a9e0
--- /dev/null
@@ -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/src/singledocparser.cpp b/src/singledocparser.cpp
new file mode 100644 (file)
index 0000000..e9f3222
--- /dev/null
@@ -0,0 +1,394 @@
+#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(m_scanner.mark(), 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();
+
+        if(token.type == Token::PLAIN_SCALAR && token.value == "null") {
+            eventHandler.OnNull(mark, anchor);
+            m_scanner.pop();
+            return;
+        }
+               
+               // 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(m_scanner.mark(), 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(m_scanner.mark(), 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);
+            
+            if(m_scanner.empty())
+                               throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW);
+                       
+                       // 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(m_scanner.mark(), 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(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW);
+                       
+                       Token& token = m_scanner.peek();
+            const Mark mark = token.mark;
+                       // 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(mark, NullAnchor);
+                       }
+                       
+                       // now grab value (optional)
+                       if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
+                               m_scanner.pop();
+                               HandleNode(eventHandler);
+                       } else {
+                               eventHandler.OnNull(mark, NullAnchor);
+                       }
+            
+            if(m_scanner.empty())
+                               throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW);
+                       
+                       // 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/src/singledocparser.h b/src/singledocparser.h
new file mode 100644 (file)
index 0000000..3798dcc
--- /dev/null
@@ -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/src/stream.cpp b/src/stream.cpp
new file mode 100644 (file)
index 0000000..efab7e2
--- /dev/null
@@ -0,0 +1,447 @@
+#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 = static_cast<std::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/src/stream.h b/src/stream.h
new file mode 100644 (file)
index 0000000..87f48dc
--- /dev/null
@@ -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/src/streamcharsource.h b/src/streamcharsource.h
new file mode 100644 (file)
index 0000000..21fae4e
--- /dev/null
@@ -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/src/stringsource.h b/src/stringsource.h
new file mode 100644 (file)
index 0000000..21be3c9
--- /dev/null
@@ -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/src/tag.cpp b/src/tag.cpp
new file mode 100644 (file)
index 0000000..82a4704
--- /dev/null
@@ -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/src/tag.h b/src/tag.h
new file mode 100644 (file)
index 0000000..5f77548
--- /dev/null
+++ b/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/src/token.h b/src/token.h
new file mode 100644 (file)
index 0000000..9807e25
--- /dev/null
@@ -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/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644 (file)
index 0000000..98777be
--- /dev/null
@@ -0,0 +1,15 @@
+file(GLOB test_headers [a-z]*.h)
+file(GLOB test_sources [a-z]*.cpp)
+file(GLOB test_new_api_sources new-api/[a-z]*.cpp)
+
+list(APPEND test_sources ${test_new_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/test/core/parsertests.cpp b/test/core/parsertests.cpp
new file mode 100644 (file)
index 0000000..5be7953
--- /dev/null
@@ -0,0 +1,77 @@
+#include "parsertests.h"
+#include "handlermacros.h"
+#include "yaml-cpp/yaml.h"
+#include <iostream>
+
+namespace Test
+{
+    namespace Parser {
+               TEST NoEndOfMapFlow()
+        {
+            try {
+                HANDLE("---{header: {id: 1");
+            } catch(const YAML::ParserException& e) {
+                YAML_ASSERT(e.msg == std::string(YAML::ErrorMsg::END_OF_MAP_FLOW));
+                return true;
+            }
+            return "  no exception caught";
+        }
+        
+        TEST PlainScalarStartingWithQuestionMark()
+        {
+            HANDLE("foo: ?bar");
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "foo");
+            EXPECT_SCALAR("?", 0, "?bar");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+
+        TEST NullStringScalar()
+        {
+            HANDLE("foo: null");
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "foo");
+            EXPECT_NULL(0);
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+    }
+    
+       namespace {
+               void RunParserTest(TEST (*test)(), 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 << "Parser test failed: " << name << "\n";
+                               std::cout << ret.error << "\n";
+                       }
+                       
+                       if(ret.ok)
+                               passed++;
+                       total++;
+               }
+       }
+       
+       bool RunParserTests()
+       {
+               int passed = 0;
+               int total = 0;
+               RunParserTest(&Parser::NoEndOfMapFlow, "No end of map flow", passed, total);
+               RunParserTest(&Parser::PlainScalarStartingWithQuestionMark, "Plain scalar starting with question mark", passed, total);
+               RunParserTest(&Parser::NullStringScalar, "Null string scalar", passed, total);
+               
+               std::cout << "Parser tests: " << passed << "/" << total << " passed\n";
+               return passed == total;
+       }
+}
diff --git a/test/core/spectests.cpp b/test/core/spectests.cpp
new file mode 100644 (file)
index 0000000..9d13465
--- /dev/null
@@ -0,0 +1,1939 @@
+#include "spectests.h"
+#include "handlermacros.h"
+#include "specexamples.h"
+#include "yaml-cpp/yaml.h"
+#include <cassert>
+
+namespace Test {
+       namespace Spec {
+               // 2.1
+               TEST SeqScalars()
+        {
+            HANDLE(ex2_1);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "Mark McGwire");
+            EXPECT_SCALAR("?", 0, "Sammy Sosa");
+            EXPECT_SCALAR("?", 0, "Ken Griffey");
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.2
+               TEST MappingScalarsToScalars()
+        {
+            HANDLE(ex2_2);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "hr");
+            EXPECT_SCALAR("?", 0, "65");
+            EXPECT_SCALAR("?", 0, "avg");
+            EXPECT_SCALAR("?", 0, "0.278");
+            EXPECT_SCALAR("?", 0, "rbi");
+            EXPECT_SCALAR("?", 0, "147");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.3
+               TEST MappingScalarsToSequences()
+        {
+            HANDLE(ex2_3);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "american");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "Boston Red Sox");
+            EXPECT_SCALAR("?", 0, "Detroit Tigers");
+            EXPECT_SCALAR("?", 0, "New York Yankees");
+            EXPECT_SEQ_END();
+            EXPECT_SCALAR("?", 0, "national");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "New York Mets");
+            EXPECT_SCALAR("?", 0, "Chicago Cubs");
+            EXPECT_SCALAR("?", 0, "Atlanta Braves");
+            EXPECT_SEQ_END();
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.4
+               TEST SequenceOfMappings()
+        {
+            HANDLE(ex2_4);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "name");
+            EXPECT_SCALAR("?", 0, "Mark McGwire");
+            EXPECT_SCALAR("?", 0, "hr");
+            EXPECT_SCALAR("?", 0, "65");
+            EXPECT_SCALAR("?", 0, "avg");
+            EXPECT_SCALAR("?", 0, "0.278");
+            EXPECT_MAP_END();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "name");
+            EXPECT_SCALAR("?", 0, "Sammy Sosa");
+            EXPECT_SCALAR("?", 0, "hr");
+            EXPECT_SCALAR("?", 0, "63");
+            EXPECT_SCALAR("?", 0, "avg");
+            EXPECT_SCALAR("?", 0, "0.288");
+            EXPECT_MAP_END();
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.5
+               TEST SequenceOfSequences()
+        {
+            HANDLE(ex2_5);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "name");
+            EXPECT_SCALAR("?", 0, "hr");
+            EXPECT_SCALAR("?", 0, "avg");
+            EXPECT_SEQ_END();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "Mark McGwire");
+            EXPECT_SCALAR("?", 0, "65");
+            EXPECT_SCALAR("?", 0, "0.278");
+            EXPECT_SEQ_END();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "Sammy Sosa");
+            EXPECT_SCALAR("?", 0, "63");
+            EXPECT_SCALAR("?", 0, "0.288");
+            EXPECT_SEQ_END();
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.6
+               TEST MappingOfMappings()
+        {
+            HANDLE(ex2_6);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "Mark McGwire");
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "hr");
+            EXPECT_SCALAR("?", 0, "65");
+            EXPECT_SCALAR("?", 0, "avg");
+            EXPECT_SCALAR("?", 0, "0.278");
+            EXPECT_MAP_END();
+            EXPECT_SCALAR("?", 0, "Sammy Sosa");
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "hr");
+            EXPECT_SCALAR("?", 0, "63");
+            EXPECT_SCALAR("?", 0, "avg");
+            EXPECT_SCALAR("?", 0, "0.288");
+            EXPECT_MAP_END();
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.7
+               TEST TwoDocumentsInAStream()
+        {
+            HANDLE(ex2_7);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "Mark McGwire");
+            EXPECT_SCALAR("?", 0, "Sammy Sosa");
+            EXPECT_SCALAR("?", 0, "Ken Griffey");
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "Chicago Cubs");
+            EXPECT_SCALAR("?", 0, "St Louis Cardinals");
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+        
+               // 2.8
+               TEST PlayByPlayFeed()
+        {
+            HANDLE(ex2_8);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "time");
+            EXPECT_SCALAR("?", 0, "20:03:20");
+            EXPECT_SCALAR("?", 0, "player");
+            EXPECT_SCALAR("?", 0, "Sammy Sosa");
+            EXPECT_SCALAR("?", 0, "action");
+            EXPECT_SCALAR("?", 0, "strike (miss)");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "time");
+            EXPECT_SCALAR("?", 0, "20:03:47");
+            EXPECT_SCALAR("?", 0, "player");
+            EXPECT_SCALAR("?", 0, "Sammy Sosa");
+            EXPECT_SCALAR("?", 0, "action");
+            EXPECT_SCALAR("?", 0, "grand slam");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.9
+               TEST SingleDocumentWithTwoComments()
+        {
+            HANDLE(ex2_9);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "hr");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "Mark McGwire");
+            EXPECT_SCALAR("?", 0, "Sammy Sosa");
+            EXPECT_SEQ_END();
+            EXPECT_SCALAR("?", 0, "rbi");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "Sammy Sosa");
+            EXPECT_SCALAR("?", 0, "Ken Griffey");
+            EXPECT_SEQ_END();
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.10
+               TEST SimpleAnchor()
+        {
+            HANDLE(ex2_10);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "hr");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "Mark McGwire");
+            EXPECT_SCALAR("?", 1, "Sammy Sosa");
+            EXPECT_SEQ_END();
+            EXPECT_SCALAR("?", 0, "rbi");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_ALIAS(1);
+            EXPECT_SCALAR("?", 0, "Ken Griffey");
+            EXPECT_SEQ_END();
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.11
+               TEST MappingBetweenSequences()
+        {
+            HANDLE(ex2_11);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "Detroit Tigers");
+            EXPECT_SCALAR("?", 0, "Chicago cubs");
+            EXPECT_SEQ_END();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "2001-07-23");
+            EXPECT_SEQ_END();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "New York Yankees");
+            EXPECT_SCALAR("?", 0, "Atlanta Braves");
+            EXPECT_SEQ_END();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "2001-07-02");
+            EXPECT_SCALAR("?", 0, "2001-08-12");
+            EXPECT_SCALAR("?", 0, "2001-08-14");
+            EXPECT_SEQ_END();
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.12
+               TEST CompactNestedMapping()
+        {
+            HANDLE(ex2_12);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "item");
+            EXPECT_SCALAR("?", 0, "Super Hoop");
+            EXPECT_SCALAR("?", 0, "quantity");
+            EXPECT_SCALAR("?", 0, "1");
+            EXPECT_MAP_END();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "item");
+            EXPECT_SCALAR("?", 0, "Basketball");
+            EXPECT_SCALAR("?", 0, "quantity");
+            EXPECT_SCALAR("?", 0, "4");
+            EXPECT_MAP_END();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "item");
+            EXPECT_SCALAR("?", 0, "Big Shoes");
+            EXPECT_SCALAR("?", 0, "quantity");
+            EXPECT_SCALAR("?", 0, "1");
+            EXPECT_MAP_END();
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.13
+               TEST InLiteralsNewlinesArePreserved()
+        {
+            HANDLE(ex2_13);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0,
+                          "\\//||\\/||\n"
+                          "// ||  ||__");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.14
+               TEST InFoldedScalarsNewlinesBecomeSpaces()
+        {
+            HANDLE(ex2_14);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0, "Mark McGwire's year was crippled by a knee injury.");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.15
+               TEST FoldedNewlinesArePreservedForMoreIndentedAndBlankLines()
+        {
+            HANDLE(ex2_15);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0,
+                          "Sammy Sosa completed another fine season with great stats.\n"
+                          "\n"
+                          "  63 Home Runs\n"
+                          "  0.288 Batting Average\n"
+                          "\n"
+                          "What a year!");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.16
+               TEST IndentationDeterminesScope()
+        {
+            HANDLE(ex2_16);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "name");
+            EXPECT_SCALAR("?", 0, "Mark McGwire");
+            EXPECT_SCALAR("?", 0, "accomplishment");
+            EXPECT_SCALAR("!", 0, "Mark set a major league home run record in 1998.\n");
+            EXPECT_SCALAR("?", 0, "stats");
+            EXPECT_SCALAR("!", 0,
+                          "65 Home Runs\n"
+                          "0.278 Batting Average\n");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.17
+               TEST QuotedScalars()
+        {
+            HANDLE(ex2_17);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "unicode");
+            EXPECT_SCALAR("!", 0, "Sosa did fine.\u263A");
+            EXPECT_SCALAR("?", 0, "control");
+            EXPECT_SCALAR("!", 0, "\b1998\t1999\t2000\n");
+            EXPECT_SCALAR("?", 0, "hex esc");
+            EXPECT_SCALAR("!", 0, "\x0d\x0a is \r\n");
+            EXPECT_SCALAR("?", 0, "single");
+            EXPECT_SCALAR("!", 0, "\"Howdy!\" he cried.");
+            EXPECT_SCALAR("?", 0, "quoted");
+            EXPECT_SCALAR("!", 0, " # Not a 'comment'.");
+            EXPECT_SCALAR("?", 0, "tie-fighter");
+            EXPECT_SCALAR("!", 0, "|\\-*-/|");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.18
+               TEST MultiLineFlowScalars()
+        {
+            HANDLE(ex2_18);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "plain");
+            EXPECT_SCALAR("?", 0, "This unquoted scalar spans many lines.");
+            EXPECT_SCALAR("?", 0, "quoted");
+            EXPECT_SCALAR("!", 0, "So does this quoted scalar.\n");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // TODO: 2.19 - 2.22 schema tags
+               
+               // 2.23
+               TEST VariousExplicitTags()
+        {
+            HANDLE(ex2_23);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "not-date");
+            EXPECT_SCALAR("tag:yaml.org,2002:str", 0, "2002-04-28");
+            EXPECT_SCALAR("?", 0, "picture");
+            EXPECT_SCALAR("tag:yaml.org,2002:binary", 0,
+                          "R0lGODlhDAAMAIQAAP//9/X\n"
+                          "17unp5WZmZgAAAOfn515eXv\n"
+                          "Pz7Y6OjuDg4J+fn5OTk6enp\n"
+                          "56enmleECcgggoBADs=\n");
+            EXPECT_SCALAR("?", 0, "application specific tag");
+            EXPECT_SCALAR("!something", 0,
+                          "The semantics of the tag\n"
+                          "above may be different for\n"
+                          "different documents.");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.24
+               TEST GlobalTags()
+        {
+            HANDLE(ex2_24);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("tag:clarkevans.com,2002:shape", 0);
+            EXPECT_MAP_START("tag:clarkevans.com,2002:circle", 0);
+            EXPECT_SCALAR("?", 0, "center");
+            EXPECT_MAP_START("?", 1);
+            EXPECT_SCALAR("?", 0, "x");
+            EXPECT_SCALAR("?", 0, "73");
+            EXPECT_SCALAR("?", 0, "y");
+            EXPECT_SCALAR("?", 0, "129");
+            EXPECT_MAP_END();
+            EXPECT_SCALAR("?", 0, "radius");
+            EXPECT_SCALAR("?", 0, "7");
+            EXPECT_MAP_END();
+            EXPECT_MAP_START("tag:clarkevans.com,2002:line", 0);
+            EXPECT_SCALAR("?", 0, "start");
+            EXPECT_ALIAS(1);
+            EXPECT_SCALAR("?", 0, "finish");
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "x");
+            EXPECT_SCALAR("?", 0, "89");
+            EXPECT_SCALAR("?", 0, "y");
+            EXPECT_SCALAR("?", 0, "102");
+            EXPECT_MAP_END();
+            EXPECT_MAP_END();
+            EXPECT_MAP_START("tag:clarkevans.com,2002:label", 0);
+            EXPECT_SCALAR("?", 0, "start");
+            EXPECT_ALIAS(1);
+            EXPECT_SCALAR("?", 0, "color");
+            EXPECT_SCALAR("?", 0, "0xFFEEBB");
+            EXPECT_SCALAR("?", 0, "text");
+            EXPECT_SCALAR("?", 0, "Pretty vector drawing.");
+            EXPECT_MAP_END();
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.25
+               TEST UnorderedSets()
+        {
+            HANDLE(ex2_25);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("tag:yaml.org,2002:set", 0);
+            EXPECT_SCALAR("?", 0, "Mark McGwire");
+            EXPECT_NULL(0);
+            EXPECT_SCALAR("?", 0, "Sammy Sosa");
+            EXPECT_NULL(0);
+            EXPECT_SCALAR("?", 0, "Ken Griffey");
+            EXPECT_NULL(0);
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.26
+               TEST OrderedMappings()
+        {
+            HANDLE(ex2_26);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("tag:yaml.org,2002:omap", 0);
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "Mark McGwire");
+            EXPECT_SCALAR("?", 0, "65");
+            EXPECT_MAP_END();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "Sammy Sosa");
+            EXPECT_SCALAR("?", 0, "63");
+            EXPECT_MAP_END();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "Ken Griffey");
+            EXPECT_SCALAR("?", 0, "58");
+            EXPECT_MAP_END();
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.27
+               TEST Invoice()
+        {
+            HANDLE(ex2_27);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("tag:clarkevans.com,2002:invoice", 0);
+            EXPECT_SCALAR("?", 0, "invoice");
+            EXPECT_SCALAR("?", 0, "34843");
+            EXPECT_SCALAR("?", 0, "date");
+            EXPECT_SCALAR("?", 0, "2001-01-23");
+            EXPECT_SCALAR("?", 0, "bill-to");
+            EXPECT_MAP_START("?", 1);
+            EXPECT_SCALAR("?", 0, "given");
+            EXPECT_SCALAR("?", 0, "Chris");
+            EXPECT_SCALAR("?", 0, "family");
+            EXPECT_SCALAR("?", 0, "Dumars");
+            EXPECT_SCALAR("?", 0, "address");
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "lines");
+            EXPECT_SCALAR("!", 0,
+                          "458 Walkman Dr.\n"
+                          "Suite #292\n");
+            EXPECT_SCALAR("?", 0, "city");
+            EXPECT_SCALAR("?", 0, "Royal Oak");
+            EXPECT_SCALAR("?", 0, "state");
+            EXPECT_SCALAR("?", 0, "MI");
+            EXPECT_SCALAR("?", 0, "postal");
+            EXPECT_SCALAR("?", 0, "48046");
+            EXPECT_MAP_END();
+            EXPECT_MAP_END();
+            EXPECT_SCALAR("?", 0, "ship-to");
+            EXPECT_ALIAS(1);
+            EXPECT_SCALAR("?", 0, "product");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "sku");
+            EXPECT_SCALAR("?", 0, "BL394D");
+            EXPECT_SCALAR("?", 0, "quantity");
+            EXPECT_SCALAR("?", 0, "4");
+            EXPECT_SCALAR("?", 0, "description");
+            EXPECT_SCALAR("?", 0, "Basketball");
+            EXPECT_SCALAR("?", 0, "price");
+            EXPECT_SCALAR("?", 0, "450.00");
+            EXPECT_MAP_END();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "sku");
+            EXPECT_SCALAR("?", 0, "BL4438H");
+            EXPECT_SCALAR("?", 0, "quantity");
+            EXPECT_SCALAR("?", 0, "1");
+            EXPECT_SCALAR("?", 0, "description");
+            EXPECT_SCALAR("?", 0, "Super Hoop");
+            EXPECT_SCALAR("?", 0, "price");
+            EXPECT_SCALAR("?", 0, "2392.00");
+            EXPECT_MAP_END();
+            EXPECT_SEQ_END();
+            EXPECT_SCALAR("?", 0, "tax");
+            EXPECT_SCALAR("?", 0, "251.42");
+            EXPECT_SCALAR("?", 0, "total");
+            EXPECT_SCALAR("?", 0, "4443.52");
+            EXPECT_SCALAR("?", 0, "comments");
+            EXPECT_SCALAR("?", 0, "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 2.28
+               TEST LogFile()
+        {
+            HANDLE(ex2_28);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "Time");
+            EXPECT_SCALAR("?", 0, "2001-11-23 15:01:42 -5");
+            EXPECT_SCALAR("?", 0, "User");
+            EXPECT_SCALAR("?", 0, "ed");
+            EXPECT_SCALAR("?", 0, "Warning");
+            EXPECT_SCALAR("?", 0, "This is an error message for the log file");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "Time");
+            EXPECT_SCALAR("?", 0, "2001-11-23 15:02:31 -5");
+            EXPECT_SCALAR("?", 0, "User");
+            EXPECT_SCALAR("?", 0, "ed");
+            EXPECT_SCALAR("?", 0, "Warning");
+            EXPECT_SCALAR("?", 0, "A slightly different error message.");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "Date");
+            EXPECT_SCALAR("?", 0, "2001-11-23 15:03:17 -5");
+            EXPECT_SCALAR("?", 0, "User");
+            EXPECT_SCALAR("?", 0, "ed");
+            EXPECT_SCALAR("?", 0, "Fatal");
+            EXPECT_SCALAR("?", 0, "Unknown variable \"bar\"");
+            EXPECT_SCALAR("?", 0, "Stack");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "file");
+            EXPECT_SCALAR("?", 0, "TopClass.py");
+            EXPECT_SCALAR("?", 0, "line");
+            EXPECT_SCALAR("?", 0, "23");
+            EXPECT_SCALAR("?", 0, "code");
+            EXPECT_SCALAR("!", 0, "x = MoreObject(\"345\\n\")\n");
+            EXPECT_MAP_END();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "file");
+            EXPECT_SCALAR("?", 0, "MoreClass.py");
+            EXPECT_SCALAR("?", 0, "line");
+            EXPECT_SCALAR("?", 0, "58");
+            EXPECT_SCALAR("?", 0, "code");
+            EXPECT_SCALAR("!", 0, "foo = bar");
+            EXPECT_MAP_END();
+            EXPECT_SEQ_END();
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // TODO: 5.1 - 5.2 BOM
+               
+               // 5.3
+               TEST BlockStructureIndicators()
+        {
+            HANDLE(ex5_3);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "sequence");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "one");
+            EXPECT_SCALAR("?", 0, "two");
+            EXPECT_SEQ_END();
+            EXPECT_SCALAR("?", 0, "mapping");
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "sky");
+            EXPECT_SCALAR("?", 0, "blue");
+            EXPECT_SCALAR("?", 0, "sea");
+            EXPECT_SCALAR("?", 0, "green");
+            EXPECT_MAP_END();
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 5.4
+               TEST FlowStructureIndicators()
+        {
+            HANDLE(ex5_4);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "sequence");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "one");
+            EXPECT_SCALAR("?", 0, "two");
+            EXPECT_SEQ_END();
+            EXPECT_SCALAR("?", 0, "mapping");
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "sky");
+            EXPECT_SCALAR("?", 0, "blue");
+            EXPECT_SCALAR("?", 0, "sea");
+            EXPECT_SCALAR("?", 0, "green");
+            EXPECT_MAP_END();
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 5.5
+               TEST CommentIndicator()
+        {
+            HANDLE(ex5_5);
+            DONE();
+        }
+               
+               // 5.6
+               TEST NodePropertyIndicators()
+        {
+            HANDLE(ex5_6);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "anchored");
+            EXPECT_SCALAR("!local", 1, "value");
+            EXPECT_SCALAR("?", 0, "alias");
+            EXPECT_ALIAS(1);
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 5.7
+               TEST BlockScalarIndicators()
+        {
+            HANDLE(ex5_7);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "literal");
+            EXPECT_SCALAR("!", 0, "some\ntext\n");
+            EXPECT_SCALAR("?", 0, "folded");
+            EXPECT_SCALAR("!", 0, "some text\n");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 5.8
+               TEST QuotedScalarIndicators()
+        {
+            HANDLE(ex5_8);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "single");
+            EXPECT_SCALAR("!", 0, "text");
+            EXPECT_SCALAR("?", 0, "double");
+            EXPECT_SCALAR("!", 0, "text");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // TODO: 5.9 directive
+               // TODO: 5.10 reserved indicator
+               
+               // 5.11
+               TEST LineBreakCharacters()
+        {
+            HANDLE(ex5_11);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0,
+                          "Line break (no glyph)\n"
+                          "Line break (glyphed)\n");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 5.12
+               TEST TabsAndSpaces()
+        {
+            HANDLE(ex5_12);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "quoted");
+            EXPECT_SCALAR("!", 0, "Quoted\t");
+            EXPECT_SCALAR("?", 0, "block");
+            EXPECT_SCALAR("!", 0,
+                          "void main() {\n"
+                          "\tprintf(\"Hello, world!\\n\");\n"
+                          "}");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 5.13
+               TEST EscapedCharacters()
+        {
+            HANDLE(ex5_13);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0, "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");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 5.14
+               TEST InvalidEscapedCharacters()
+        {
+            try {
+                HANDLE(ex5_14);
+            } catch(const YAML::ParserException& e) {
+                               YAML_ASSERT(e.msg == std::string(YAML::ErrorMsg::INVALID_ESCAPE) + "c");
+                               return true;
+                       }
+            return "  no exception caught";
+        }
+               
+               // 6.1
+               TEST IndentationSpaces()
+        {
+            HANDLE(ex6_1);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "Not indented");
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "By one space");
+            EXPECT_SCALAR("!", 0, "By four\n  spaces\n");
+            EXPECT_SCALAR("?", 0, "Flow style");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "By two");
+            EXPECT_SCALAR("?", 0, "Also by two");
+            EXPECT_SCALAR("?", 0, "Still by two");
+            EXPECT_SEQ_END();
+            EXPECT_MAP_END();
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.2
+               TEST IndentationIndicators()
+        {
+            HANDLE(ex6_2);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "a");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "b");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "c");
+            EXPECT_SCALAR("?", 0, "d");
+            EXPECT_SEQ_END();
+            EXPECT_SEQ_END();
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.3
+               TEST SeparationSpaces()
+        {
+            HANDLE(ex6_3);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "foo");
+            EXPECT_SCALAR("?", 0, "bar");
+            EXPECT_MAP_END();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "baz");
+            EXPECT_SCALAR("?", 0, "baz");
+            EXPECT_SEQ_END();
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.4
+               TEST LinePrefixes()
+        {
+            HANDLE(ex6_4);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "plain");
+            EXPECT_SCALAR("?", 0, "text lines");
+            EXPECT_SCALAR("?", 0, "quoted");
+            EXPECT_SCALAR("!", 0, "text lines");
+            EXPECT_SCALAR("?", 0, "block");
+            EXPECT_SCALAR("!", 0, "text\n \tlines\n");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.5
+               TEST EmptyLines()
+        {
+            HANDLE(ex6_5);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "Folding");
+            EXPECT_SCALAR("!", 0, "Empty line\nas a line feed");
+            EXPECT_SCALAR("?", 0, "Chomping");
+            EXPECT_SCALAR("!", 0, "Clipped empty lines\n");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.6
+               TEST LineFolding()
+        {
+            HANDLE(ex6_6);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0, "trimmed\n\n\nas space");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.7
+               TEST BlockFolding()
+        {
+            HANDLE(ex6_7);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0, "foo \n\n\t bar\n\nbaz\n");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.8
+               TEST FlowFolding()
+        {
+            HANDLE(ex6_8);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0, " foo\nbar\nbaz ");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.9
+               TEST SeparatedComment()
+        {
+            HANDLE(ex6_9);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "key");
+            EXPECT_SCALAR("?", 0, "value");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.10
+               TEST CommentLines()
+        {
+            HANDLE(ex6_10);
+            DONE();
+        }
+               
+               // 6.11
+               TEST MultiLineComments()
+        {
+            HANDLE(ex6_11);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "key");
+            EXPECT_SCALAR("?", 0, "value");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+        
+               // 6.12
+               TEST SeparationSpacesII()
+        {
+            HANDLE(ex6_12);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "first");
+            EXPECT_SCALAR("?", 0, "Sammy");
+            EXPECT_SCALAR("?", 0, "last");
+            EXPECT_SCALAR("?", 0, "Sosa");
+            EXPECT_MAP_END();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "hr");
+            EXPECT_SCALAR("?", 0, "65");
+            EXPECT_SCALAR("?", 0, "avg");
+            EXPECT_SCALAR("?", 0, "0.278");
+            EXPECT_MAP_END();
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.13
+               TEST ReservedDirectives()
+        {
+            HANDLE(ex6_13);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0, "foo");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.14
+               TEST YAMLDirective()
+        {
+            HANDLE(ex6_14);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0, "foo");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.15
+               TEST InvalidRepeatedYAMLDirective()
+        {
+            try {
+                HANDLE(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()
+        {
+            HANDLE(ex6_16);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("tag:yaml.org,2002:str", 0, "foo");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.17
+               TEST InvalidRepeatedTagDirective()
+        {
+            try {
+                HANDLE(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()
+        {
+            HANDLE(ex6_18);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!foo", 0, "bar");
+            EXPECT_DOC_END();
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("tag:example.com,2000:app/foo", 0, "bar");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.19
+               TEST SecondaryTagHandle()
+        {
+            HANDLE(ex6_19);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("tag:example.com,2000:app/int", 0, "1 - 3");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.20
+               TEST TagHandles()
+        {
+            HANDLE(ex6_20);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("tag:example.com,2000:app/foo", 0, "bar");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.21
+               TEST LocalTagPrefix()
+        {
+            HANDLE(ex6_21);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!my-light", 0, "fluorescent");
+            EXPECT_DOC_END();
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!my-light", 0, "green");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.22
+               TEST GlobalTagPrefix()
+        {
+            HANDLE(ex6_22);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("tag:example.com,2000:app/foo", 0, "bar");
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.23
+               TEST NodeProperties()
+        {
+            HANDLE(ex6_23);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("tag:yaml.org,2002:str", 1, "foo");
+            EXPECT_SCALAR("tag:yaml.org,2002:str", 0, "bar");
+            EXPECT_SCALAR("?", 2, "baz");
+            EXPECT_ALIAS(1);
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.24
+               TEST VerbatimTags()
+        {
+            HANDLE(ex6_24);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("tag:yaml.org,2002:str", 0, "foo");
+            EXPECT_SCALAR("!bar", 0, "baz");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.25
+               TEST InvalidVerbatimTags()
+        {
+            HANDLE(ex6_25);
+            return "  not implemented yet";
+        }
+               
+               // 6.26
+               TEST TagShorthands()
+        {
+            HANDLE(ex6_26);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("!local", 0, "foo");
+            EXPECT_SCALAR("tag:yaml.org,2002:str", 0, "bar");
+            EXPECT_SCALAR("tag:example.com,2000:app/tag%21", 0, "baz");
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.27
+               TEST InvalidTagShorthands()
+        {
+                       bool threw = false;
+                       try {
+                               HANDLE(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";
+            
+                       HANDLE(ex6_27b); // TODO: should we reject this one (since !h! is not declared)?
+                       return "  not implemented yet";
+        }
+               
+               // 6.28
+               TEST NonSpecificTags()
+        {
+            HANDLE(ex6_28);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("!", 0, "12");
+            EXPECT_SCALAR("?", 0, "12");
+            EXPECT_SCALAR("!", 0, "12");
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 6.29
+               TEST NodeAnchors()
+        {
+            HANDLE(ex6_29);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "First occurrence");
+            EXPECT_SCALAR("?", 1, "Value");
+            EXPECT_SCALAR("?", 0, "Second occurrence");
+            EXPECT_ALIAS(1);
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.1
+               TEST AliasNodes()
+        {
+            HANDLE(ex7_1);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "First occurrence");
+            EXPECT_SCALAR("?", 1, "Foo");
+            EXPECT_SCALAR("?", 0, "Second occurrence");
+            EXPECT_ALIAS(1);
+            EXPECT_SCALAR("?", 0, "Override anchor");
+            EXPECT_SCALAR("?", 2, "Bar");
+            EXPECT_SCALAR("?", 0, "Reuse anchor");
+            EXPECT_ALIAS(2);
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.2
+               TEST EmptyNodes()
+        {
+            HANDLE(ex7_2);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "foo");
+            EXPECT_SCALAR("tag:yaml.org,2002:str", 0, "");
+            EXPECT_SCALAR("tag:yaml.org,2002:str", 0, "");
+            EXPECT_SCALAR("?", 0, "bar");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.3
+               TEST CompletelyEmptyNodes()
+        {
+            HANDLE(ex7_3);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "foo");
+            EXPECT_NULL(0);
+            EXPECT_NULL(0);
+            EXPECT_SCALAR("?", 0, "bar");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.4
+               TEST DoubleQuotedImplicitKeys()
+        {
+            HANDLE(ex7_4);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("!", 0, "implicit block key");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("!", 0, "implicit flow key");
+            EXPECT_SCALAR("?", 0, "value");
+            EXPECT_MAP_END();
+            EXPECT_SEQ_END();
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.5
+               TEST DoubleQuotedLineBreaks()
+        {
+            HANDLE(ex7_5);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0, "folded to a space,\nto a line feed, or \t \tnon-content");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.6
+               TEST DoubleQuotedLines()
+        {
+            HANDLE(ex7_6);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0, " 1st non-empty\n2nd non-empty 3rd non-empty ");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.7
+               TEST SingleQuotedCharacters()
+        {
+            HANDLE(ex7_7);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0, "here's to \"quotes\"");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.8
+               TEST SingleQuotedImplicitKeys()
+        {
+            HANDLE(ex7_8);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("!", 0, "implicit block key");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("!", 0, "implicit flow key");
+            EXPECT_SCALAR("?", 0, "value");
+            EXPECT_MAP_END();
+            EXPECT_SEQ_END();
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.9
+               TEST SingleQuotedLines()
+        {
+            HANDLE(ex7_9);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0, " 1st non-empty\n2nd non-empty 3rd non-empty ");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.10
+               TEST PlainCharacters()
+        {
+            HANDLE(ex7_10);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "::vector");
+            EXPECT_SCALAR("!", 0, ": - ()");
+            EXPECT_SCALAR("?", 0, "Up, up, and away!");
+            EXPECT_SCALAR("?", 0, "-123");
+            EXPECT_SCALAR("?", 0, "http://example.com/foo#bar");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "::vector");
+            EXPECT_SCALAR("!", 0, ": - ()");
+            EXPECT_SCALAR("!", 0, "Up, up, and away!");
+            EXPECT_SCALAR("?", 0, "-123");
+            EXPECT_SCALAR("?", 0, "http://example.com/foo#bar");
+            EXPECT_SEQ_END();
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.11
+               TEST PlainImplicitKeys()
+        {
+            HANDLE(ex7_11);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "implicit block key");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "implicit flow key");
+            EXPECT_SCALAR("?", 0, "value");
+            EXPECT_MAP_END();
+            EXPECT_SEQ_END();
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.12
+               TEST PlainLines()
+        {
+            HANDLE(ex7_12);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("?", 0, "1st non-empty\n2nd non-empty 3rd non-empty");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.13
+               TEST FlowSequence()
+        {
+            HANDLE(ex7_13);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "one");
+            EXPECT_SCALAR("?", 0, "two");
+            EXPECT_SEQ_END();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "three");
+            EXPECT_SCALAR("?", 0, "four");
+            EXPECT_SEQ_END();
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.14
+               TEST FlowSequenceEntries()
+        {
+            HANDLE(ex7_14);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("!", 0, "double quoted");
+            EXPECT_SCALAR("!", 0, "single quoted");
+            EXPECT_SCALAR("?", 0, "plain text");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "nested");
+            EXPECT_SEQ_END();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "single");
+            EXPECT_SCALAR("?", 0, "pair");
+            EXPECT_MAP_END();
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.15
+               TEST FlowMappings()
+        {
+            HANDLE(ex7_15);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "one");
+            EXPECT_SCALAR("?", 0, "two");
+            EXPECT_SCALAR("?", 0, "three");
+            EXPECT_SCALAR("?", 0, "four");
+            EXPECT_MAP_END();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "five");
+            EXPECT_SCALAR("?", 0, "six");
+            EXPECT_SCALAR("?", 0, "seven");
+            EXPECT_SCALAR("?", 0, "eight");
+            EXPECT_MAP_END();
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.16
+               TEST FlowMappingEntries()
+        {
+            HANDLE(ex7_16);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "explicit");
+            EXPECT_SCALAR("?", 0, "entry");
+            EXPECT_SCALAR("?", 0, "implicit");
+            EXPECT_SCALAR("?", 0, "entry");
+            EXPECT_NULL(0);
+            EXPECT_NULL(0);
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.17
+               TEST FlowMappingSeparateValues()
+        {
+            HANDLE(ex7_17);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "unquoted");
+            EXPECT_SCALAR("!", 0, "separate");
+            EXPECT_SCALAR("?", 0, "http://foo.com");
+            EXPECT_NULL(0);
+            EXPECT_SCALAR("?", 0, "omitted value");
+            EXPECT_NULL(0);
+            EXPECT_NULL(0);
+            EXPECT_SCALAR("?", 0, "omitted key");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.18
+               TEST FlowMappingAdjacentValues()
+        {
+            HANDLE(ex7_18);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("!", 0, "adjacent");
+            EXPECT_SCALAR("?", 0, "value");
+            EXPECT_SCALAR("!", 0, "readable");
+            EXPECT_SCALAR("?", 0, "value");
+            EXPECT_SCALAR("!", 0, "empty");
+            EXPECT_NULL(0);
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.19
+               TEST SinglePairFlowMappings()
+        {
+            HANDLE(ex7_19);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "foo");
+            EXPECT_SCALAR("?", 0, "bar");
+            EXPECT_MAP_END();
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.20
+               TEST SinglePairExplicitEntry()
+        {
+            HANDLE(ex7_20);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "foo bar");
+            EXPECT_SCALAR("?", 0, "baz");
+            EXPECT_MAP_END();
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.21
+               TEST SinglePairImplicitEntries()
+        {
+            HANDLE(ex7_21);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "YAML");
+            EXPECT_SCALAR("?", 0, "separate");
+            EXPECT_MAP_END();
+            EXPECT_SEQ_END();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_MAP_START("?", 0);
+            EXPECT_NULL(0);
+            EXPECT_SCALAR("?", 0, "empty key entry");
+            EXPECT_MAP_END();
+            EXPECT_SEQ_END();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_MAP_START("?", 0);
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "JSON");
+            EXPECT_SCALAR("?", 0, "like");
+            EXPECT_MAP_END();
+            EXPECT_SCALAR("?", 0, "adjacent");
+            EXPECT_MAP_END();
+            EXPECT_SEQ_END();
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.22
+               TEST InvalidImplicitKeys()
+        {
+            try {
+                HANDLE(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()
+        {
+            HANDLE(ex7_23);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "a");
+            EXPECT_SCALAR("?", 0, "b");
+            EXPECT_SEQ_END();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "a");
+            EXPECT_SCALAR("?", 0, "b");
+            EXPECT_MAP_END();
+            EXPECT_SCALAR("!", 0, "a");
+            EXPECT_SCALAR("!", 0, "b");
+            EXPECT_SCALAR("?", 0, "c");
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 7.24
+               TEST FlowNodes()
+        {
+            HANDLE(ex7_24);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("tag:yaml.org,2002:str", 0, "a");
+            EXPECT_SCALAR("!", 0, "b");
+            EXPECT_SCALAR("!", 1, "c");
+            EXPECT_ALIAS(1);
+            EXPECT_SCALAR("tag:yaml.org,2002:str", 0, "");
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.1
+               TEST BlockScalarHeader()
+        {
+            HANDLE(ex8_1);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("!", 0, "literal\n");
+            EXPECT_SCALAR("!", 0, " folded\n");
+            EXPECT_SCALAR("!", 0, "keep\n\n");
+            EXPECT_SCALAR("!", 0, " strip");
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.2
+               TEST BlockIndentationHeader()
+        {
+            HANDLE(ex8_2);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("!", 0, "detected\n");
+            EXPECT_SCALAR("!", 0, "\n\n# detected\n");
+            EXPECT_SCALAR("!", 0, " explicit\n");
+            EXPECT_SCALAR("!", 0, "\t\ndetected\n");
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.3
+               TEST InvalidBlockScalarIndentationIndicators()
+        {
+                       {
+                               bool threw = false;
+                               try {
+                                       HANDLE(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 {
+                                       HANDLE(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 {
+                                       HANDLE(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()
+        {
+            HANDLE(ex8_4);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "strip");
+            EXPECT_SCALAR("!", 0, "text");
+            EXPECT_SCALAR("?", 0, "clip");
+            EXPECT_SCALAR("!", 0, "text\n");
+            EXPECT_SCALAR("?", 0, "keep");
+            EXPECT_SCALAR("!", 0, "text\n");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.5
+               TEST ChompingTrailingLines()
+        {
+            HANDLE(ex8_5);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "strip");
+            EXPECT_SCALAR("!", 0, "# text");
+            EXPECT_SCALAR("?", 0, "clip");
+            EXPECT_SCALAR("!", 0, "# text\n");
+            EXPECT_SCALAR("?", 0, "keep");
+            EXPECT_SCALAR("!", 0, "# text\n"); // Note: I believe this is a bug in the YAML spec - it should be "# text\n\n"
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.6
+               TEST EmptyScalarChomping()
+        {
+            HANDLE(ex8_6);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "strip");
+            EXPECT_SCALAR("!", 0, "");
+            EXPECT_SCALAR("?", 0, "clip");
+            EXPECT_SCALAR("!", 0, "");
+            EXPECT_SCALAR("?", 0, "keep");
+            EXPECT_SCALAR("!", 0, "\n");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.7
+               TEST LiteralScalar()
+        {
+            HANDLE(ex8_7);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0, "literal\n\ttext\n");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.8
+               TEST LiteralContent()
+        {
+            HANDLE(ex8_8);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0, "\n\nliteral\n \n\ntext\n");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.9
+               TEST FoldedScalar()
+        {
+            HANDLE(ex8_9);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0, "folded text\n");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.10
+               TEST FoldedLines()
+        {
+            HANDLE(ex8_10);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0, "\nfolded line\nnext line\n  * bullet\n\n  * list\n  * lines\n\nlast line\n");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.11
+               TEST MoreIndentedLines()
+        {
+            HANDLE(ex8_11);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0, "\nfolded line\nnext line\n  * bullet\n\n  * list\n  * lines\n\nlast line\n");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.12
+               TEST EmptySeparationLines()
+        {
+            HANDLE(ex8_12);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0, "\nfolded line\nnext line\n  * bullet\n\n  * list\n  * lines\n\nlast line\n");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.13
+               TEST FinalEmptyLines()
+        {
+            HANDLE(ex8_13);
+            EXPECT_DOC_START();
+            EXPECT_SCALAR("!", 0, "\nfolded line\nnext line\n  * bullet\n\n  * list\n  * lines\n\nlast line\n");
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.14
+               TEST BlockSequence()
+        {
+            HANDLE(ex8_14);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "block sequence");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "one");
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "two");
+            EXPECT_SCALAR("?", 0, "three");
+            EXPECT_MAP_END();
+            EXPECT_SEQ_END();
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.15
+               TEST BlockSequenceEntryTypes()
+        {
+            HANDLE(ex8_15);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_NULL(0);
+            EXPECT_SCALAR("!", 0, "block node\n");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "one");
+            EXPECT_SCALAR("?", 0, "two");
+            EXPECT_SEQ_END();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "one");
+            EXPECT_SCALAR("?", 0, "two");
+            EXPECT_MAP_END();
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.16
+               TEST BlockMappings()
+        {
+            HANDLE(ex8_16);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "block mapping");
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "key");
+            EXPECT_SCALAR("?", 0, "value");
+            EXPECT_MAP_END();
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.17
+               TEST ExplicitBlockMappingEntries()
+        {
+            HANDLE(ex8_17);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "explicit key");
+            EXPECT_NULL(0);
+            EXPECT_SCALAR("!", 0, "block key\n");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "one");
+            EXPECT_SCALAR("?", 0, "two");
+            EXPECT_SEQ_END();
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.18
+               TEST ImplicitBlockMappingEntries()
+        {
+            HANDLE(ex8_18);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "plain key");
+            EXPECT_SCALAR("?", 0, "in-line value");
+            EXPECT_NULL(0);
+            EXPECT_NULL(0);
+            EXPECT_SCALAR("!", 0, "quoted key");
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("?", 0, "entry");
+            EXPECT_SEQ_END();
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.19
+               TEST CompactBlockMappings()
+        {
+            HANDLE(ex8_19);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "sun");
+            EXPECT_SCALAR("?", 0, "yellow");
+            EXPECT_MAP_END();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "earth");
+            EXPECT_SCALAR("?", 0, "blue");
+            EXPECT_MAP_END();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "moon");
+            EXPECT_SCALAR("?", 0, "white");
+            EXPECT_MAP_END();
+            EXPECT_MAP_END();
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.20
+               TEST BlockNodeTypes()
+        {
+            HANDLE(ex8_20);
+            EXPECT_DOC_START();
+            EXPECT_SEQ_START("?", 0);
+            EXPECT_SCALAR("!", 0, "flow in block");
+            EXPECT_SCALAR("!", 0, "Block scalar\n");
+            EXPECT_MAP_START("tag:yaml.org,2002:map", 0);
+            EXPECT_SCALAR("?", 0, "foo");
+            EXPECT_SCALAR("?", 0, "bar");
+            EXPECT_MAP_END();
+            EXPECT_SEQ_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.21
+               TEST BlockScalarNodes()
+        {
+            HANDLE(ex8_21);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "literal");
+            EXPECT_SCALAR("!", 0, "value"); // Note: I believe this is a bug in the YAML spec - it should be "value\n"
+            EXPECT_SCALAR("?", 0, "folded");
+            EXPECT_SCALAR("!foo", 0, "value");
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+               
+               // 8.22
+               TEST BlockCollectionNodes()
+        {
+            HANDLE(ex8_22);
+            EXPECT_DOC_START();
+            EXPECT_MAP_START("?", 0);
+            EXPECT_SCALAR("?", 0, "sequence");
+            EXPECT_SEQ_START("tag:yaml.org,2002:seq", 0);
+            EXPECT_SCALAR("?", 0, "entry");
+            EXPECT_SEQ_START("tag:yaml.org,2002:seq", 0);
+            EXPECT_SCALAR("?", 0, "nested");
+            EXPECT_SEQ_END();
+            EXPECT_SEQ_END();
+            EXPECT_SCALAR("?", 0, "mapping");
+            EXPECT_MAP_START("tag:yaml.org,2002:map", 0);
+            EXPECT_SCALAR("?", 0, "foo");
+            EXPECT_SCALAR("?", 0, "bar");
+            EXPECT_MAP_END();
+            EXPECT_MAP_END();
+            EXPECT_DOC_END();
+            DONE();
+        }
+       }
+}
diff --git a/test/create-emitter-tests.py b/test/create-emitter-tests.py
new file mode 100644 (file)
index 0000000..bf17f0a
--- /dev/null
@@ -0,0 +1,184 @@
+import sys
+import yaml
+import hashlib
+
+NS = 'Emitter'
+DEFINE = 'YAML_GEN_TESTS'
+EVENT_COUNT = 5
+
+def encode_stream(line):
+    for c in line:
+        if c == '\n':
+            yield '\\n'
+        elif c == '"':
+            yield '\\"'
+        elif c == '\t':
+            yield '\\t'
+        elif ord(c) < 0x20:
+            yield '\\x' + hex(ord(c))
+        else:
+            yield c
+
+def encode(line):
+    return ''.join(encode_stream(line))
+
+def doc_start(implicit=False):
+    if implicit:
+        return {'emit': '', 'handle': 'DOC_START()'}
+    else:
+        return {'emit': 'YAML::BeginDoc', 'handle': 'DOC_START()'}
+
+def doc_end(implicit=False):
+    if implicit:
+        return {'emit': '', 'handle': 'DOC_END()'}
+    else:
+        return {'emit': 'YAML::EndDoc', 'handle': 'DOC_END()'}
+
+def scalar(value, tag='', anchor='', anchor_id=0):
+    emit = []
+    if tag:
+        emit += ['YAML::VerbatimTag("%s")' % encode(tag)]
+    if anchor:
+        emit += ['YAML::Anchor("%s")' % encode(anchor)]
+    if tag:
+        out_tag = encode(tag)
+    else:
+        if value == encode(value):
+            out_tag = '?'
+        else:
+            out_tag = '!'
+    emit += ['"%s"' % encode(value)]
+    return {'emit': emit, 'handle': 'SCALAR("%s", %s, "%s")' % (out_tag, anchor_id, encode(value))}
+
+def comment(value):
+    return {'emit': 'YAML::Comment("%s")' % value, 'handle': ''}
+
+def seq_start(tag='', anchor='', anchor_id=0):
+    emit = []
+    if tag:
+        emit += ['YAML::VerbatimTag("%s")' % encode(tag)]
+    if anchor:
+        emit += ['YAML::Anchor("%s")' % encode(anchor)]
+    if tag:
+        out_tag = encode(tag)
+    else:
+        out_tag = '?'
+    emit += ['YAML::BeginSeq']
+    return {'emit': emit, 'handle': 'SEQ_START("%s", %s)' % (out_tag, anchor_id)}
+
+def seq_end():
+    return {'emit': 'YAML::EndSeq', 'handle': 'SEQ_END()'}
+
+def map_start(tag='', anchor='', anchor_id=0):
+    emit = []
+    if tag:
+        emit += ['YAML::VerbatimTag("%s")' % encode(tag)]
+    if anchor:
+        emit += ['YAML::Anchor("%s")' % encode(anchor)]
+    if tag:
+        out_tag = encode(tag)
+    else:
+        out_tag = '?'
+    emit += ['YAML::BeginMap']
+    return {'emit': emit, 'handle': 'MAP_START("%s", %s)' % (out_tag, anchor_id)}
+
+def map_end():
+    return {'emit': 'YAML::EndMap', 'handle': 'MAP_END()'}
+
+def gen_templates():
+    yield [[doc_start(), doc_start(True)],
+           [scalar('foo'), scalar('foo\n'), scalar('foo', 'tag'), scalar('foo', '', 'anchor', 1)],
+           [doc_end(), doc_end(True)]]
+    yield [[doc_start(), doc_start(True)],
+           [seq_start()],
+           [[], [scalar('foo')], [scalar('foo', 'tag')], [scalar('foo', '', 'anchor', 1)], [scalar('foo', 'tag', 'anchor', 1)], [scalar('foo'), scalar('bar')], [scalar('foo', 'tag', 'anchor', 1), scalar('bar', 'tag', 'other', 2)]],
+           [seq_end()],
+           [doc_end(), doc_end(True)]]
+    yield [[doc_start(), doc_start(True)],
+           [map_start()],
+           [[], [scalar('foo'), scalar('bar')], [scalar('foo', 'tag', 'anchor', 1), scalar('bar', 'tag', 'other', 2)]],
+           [map_end()],
+           [doc_end(), doc_end(True)]]
+    yield [[doc_start(True)],
+           [map_start()],
+           [[scalar('foo')], [seq_start(), scalar('foo'), seq_end()], [map_start(), scalar('foo'), scalar('bar'), map_end()]],
+           [[scalar('foo')], [seq_start(), scalar('foo'), seq_end()], [map_start(), scalar('foo'), scalar('bar'), map_end()]],
+           [map_end()],
+           [doc_end(True)]]
+    yield [[doc_start(True)],
+           [seq_start()],
+           [[scalar('foo')], [seq_start(), scalar('foo'), seq_end()], [map_start(), scalar('foo'), scalar('bar'), map_end()]],
+           [[scalar('foo')], [seq_start(), scalar('foo'), seq_end()], [map_start(), scalar('foo'), scalar('bar'), map_end()]],
+           [seq_end()],
+           [doc_end(True)]]
+
+def expand(template):
+    if len(template) == 0:
+        pass
+    elif len(template) == 1:
+        for item in template[0]:
+            if isinstance(item, list):
+                yield item
+            else:
+                yield [item]
+    else:
+        for car in expand(template[:1]):
+            for cdr in expand(template[1:]):
+                yield car + cdr
+            
+
+def gen_events():
+    for template in gen_templates():
+        for events in expand(template):
+            base = list(events)
+            for i in range(0, len(base)+1):
+                cpy = list(base)
+                cpy.insert(i, comment('comment'))
+                yield cpy
+
+def gen_tests():
+    for events in gen_events():
+        name = 'test' + hashlib.sha1(''.join(yaml.dump(event) for event in events)).hexdigest()[:20]
+        yield {'name': name, 'events': events}
+        
+
+def create_emitter_tests(out):
+    out.write('#ifdef %s\n' % DEFINE)
+    out.write('namespace %s {\n' % NS)
+
+    tests = list(gen_tests())
+
+    for test in tests:
+        out.write('TEST %s(YAML::Emitter& out)\n' % test['name'])
+        out.write('{\n')
+        for event in test['events']:
+            emit = event['emit']
+            if isinstance(emit, list):
+                for e in emit:
+                    out.write('    out << %s;\n' % e)
+            elif emit:
+                out.write('    out << %s;\n' % emit)
+        out.write('\n')
+        out.write('    HANDLE(out.c_str());\n')
+        for event in test['events']:
+            handle = event['handle']
+            if handle:
+                out.write('    EXPECT_%s;\n' % handle)
+        out.write('    DONE();\n')
+        out.write('}\n')
+
+    out.write('}\n')
+    out.write('#endif // %s\n\n' % DEFINE)
+
+    out.write('void RunGenEmitterTests(int& passed, int& total)\n')
+    out.write('{\n')
+    out.write('#ifdef %s\n' % DEFINE)
+    for test in tests:
+        out.write('    RunGenEmitterTest(&Emitter::%s, "%s", passed, total);\n' % (test['name'], encode(test['name'])))
+    out.write('#else // %s\n' % DEFINE)
+    out.write('   (void)passed; (void)total;\n')
+    out.write('#endif // %s\n' % DEFINE)
+    out.write('}\n')
+
+if __name__ == '__main__':
+    create_emitter_tests(sys.stdout)
diff --git a/test/emittertests.cpp b/test/emittertests.cpp
new file mode 100644 (file)
index 0000000..cee64f5
--- /dev/null
@@ -0,0 +1,1164 @@
+#include "tests.h"
+#include "handlermacros.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 = "? - 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 = "? - 1\n  - 3\n: monster\n[2, 0]: 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\\ndouble-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 = "? 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!\nbar]";
+               }
+
+               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!\nbaz: 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    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,\nb, c,\nd]";
+               }
+
+               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\nb:\n  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,\nb: 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:\n    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]";
+        }
+        
+        void CompactMapWithNewline(YAML::Emitter& out, std::string& desiredOutput)
+        {
+            out << YAML::Comment("Characteristics");
+            out << YAML::BeginSeq;
+            out << YAML::BeginMap;
+            out << YAML::Key << "color" << YAML::Value << "blue";
+            out << YAML::Key << "height" << YAML::Value << 120;
+            out << YAML::EndMap;
+            out << YAML::Newline << YAML::Newline;
+            out << YAML::Comment("Skills");
+            out << YAML::BeginMap;
+            out << YAML::Key << "attack" << YAML::Value << 23;
+            out << YAML::Key << "intelligence" << YAML::Value << 56;
+            out << YAML::EndMap;
+            out << YAML::EndSeq;
+            
+            desiredOutput =
+            "# Characteristics\n"
+            "- color: blue\n"
+            "  height: 120\n"
+            "\n"
+            "# Skills\n"
+            "- attack: 23\n"
+            "  intelligence: 56";
+        }
+        
+               void ForceSingleQuotedToDouble(YAML::Emitter& out, std::string& desiredOutput)
+               {
+                       out << YAML::SingleQuoted << "Hello\nWorld";
+
+            desiredOutput = "\"Hello\\nWorld\"";
+               }
+        
+        ////////////////////////////////////////////////////////////////////////////////
+               // 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 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;
+               }
+       }
+       
+       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 {
+                    YAML::Node node = YAML::Load(output);
+                                       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++;
+               }
+        
+        void RunGenEmitterTest(TEST (*test)(YAML::Emitter&), const std::string& name, int& passed, int& total) {
+            YAML::Emitter out;
+            TEST ret;
+
+                       try {
+                               ret = test(out);
+                       } catch(const YAML::Exception& e) {
+                               ret.ok = false;
+                               ret.error = std::string("  Exception caught: ") + e.what();
+                       }
+            
+            if(!out.good()) {
+                ret.ok = false;
+                ret.error = out.GetLastError();
+            }
+                       
+                       if(!ret.ok) {
+                               std::cout << "Generated emitter test failed: " << name << "\n";
+                std::cout << "Output:\n";
+                std::cout << out.c_str() << "<<<\n";
+                               std::cout << ret.error << "\n";
+                       }
+                       
+                       if(ret.ok)
+                               passed++;
+                       total++;
+        }
+       }
+    
+#include "genemittertests.h"
+       
+       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);
+               RunEmitterTest(&Emitter::CompactMapWithNewline, "compact map with newline", passed, total);
+        RunEmitterTest(&Emitter::ForceSingleQuotedToDouble, "force single quoted to double", passed, total);
+               
+               RunEmitterErrorTest(&Emitter::ExtraEndSeq, "extra EndSeq", passed, total);
+               RunEmitterErrorTest(&Emitter::ExtraEndMap, "extra EndMap", passed, total);
+               RunEmitterErrorTest(&Emitter::InvalidAnchor, "invalid anchor", passed, total);
+               RunEmitterErrorTest(&Emitter::InvalidAlias, "invalid alias", passed, total);
+               RunEmitterErrorTest(&Emitter::BadLocalTag, "bad local tag", passed, total);
+        
+        RunGenEmitterTests(passed, total);
+
+               std::cout << "Emitter tests: " << passed << "/" << total << " passed\n";
+               return passed == total;
+       }
+}
+
diff --git a/test/emittertests.h b/test/emittertests.h
new file mode 100644 (file)
index 0000000..e7c6ac5
--- /dev/null
@@ -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/test/genemittertests.h b/test/genemittertests.h
new file mode 100644 (file)
index 0000000..d15690a
--- /dev/null
@@ -0,0 +1,10256 @@
+#ifdef YAML_GEN_TESTS
+namespace Emitter {
+TEST test02571eee35ac0cbd3777(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << "foo";
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test71b969ca18898d226320(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd69e4ea95ce6f221c6e7(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testffbfd295ad9bef4deb00(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << "foo";
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test6a459b2fe1f6e961e1a7(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << "foo";
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test869ab95640c9933ed4d6(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << "foo";
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test433c0771f40ac3ba853e(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << "foo";
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST teste181778974c4003bc5a4(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << "foo";
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf8cb7e3f1b11791f53b8(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << "foo\n";
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("!", 0, "foo\n");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test3c48ed06807100f0a111(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << "foo\n";
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("!", 0, "foo\n");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb13f7b031f425b0e383f(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << "foo\n";
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("!", 0, "foo\n");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb77284234d3fbe8b24a0(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << "foo\n";
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("!", 0, "foo\n");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test9c56fd285b563327a340(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << "foo\n";
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("!", 0, "foo\n");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test1c08639d56176e64c885(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << "foo\n";
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("!", 0, "foo\n");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test94c8742f8cab3cec1b4a(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << "foo\n";
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("!", 0, "foo\n");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test79d1806ceb3ecebfa60b(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << "foo\n";
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("!", 0, "foo\n");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test360afe50348ec36569d3(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST teste599b3fc1857f4265d3b(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test88adf7adb474ad063424(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0978ca6f6358ea06e024(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd915f57fca4b0f6d77b4(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test1fe1f22496f2a0ffd64e(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test76422a4077d3bdd03579(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test92b168a497cb0c7e3144(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testa93925b3ae311a7f11d4(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test2dd1aaf6a1c1924557d0(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test6ec0585d0f0945ad9dae(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test7e00bca835d55844bbfe(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test70912c7d920a0597bbb2(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test16eacbf77bccde360e54(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test556e0c86efb0716d2778(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test71b64326d72fe100e6ad(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0c7bb03fbd6b52ea3ad6(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb819efb5742c1176df98(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test1f7b7cd5a13070c723d3(YAML::Emitter& out)
+{
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test32126a88cb2b7311e779(YAML::Emitter& out)
+{
+    out << "foo";
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd7f952713bde5ce2f9e7(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << "foo";
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test5030b4f2d1efb798f320(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << "foo";
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb9015537b9a9e09b8ec8(YAML::Emitter& out)
+{
+    out << "foo";
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test03229f6d33fa9007a65d(YAML::Emitter& out)
+{
+    out << "foo";
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf998264dcfd0dba06c0a(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << "foo\n";
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("!", 0, "foo\n");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test7defadc52eddfbf766aa(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << "foo\n";
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("!", 0, "foo\n");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test55a7c58211689c7815b2(YAML::Emitter& out)
+{
+    out << "foo\n";
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("!", 0, "foo\n");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testc3873d954433175e0143(YAML::Emitter& out)
+{
+    out << "foo\n";
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("!", 0, "foo\n");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test81fb6bf1f976e0ad3fba(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << "foo\n";
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("!", 0, "foo\n");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test29e7ff04645f56a7ea2f(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << "foo\n";
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("!", 0, "foo\n");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testce0089a55f926d311ff4(YAML::Emitter& out)
+{
+    out << "foo\n";
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("!", 0, "foo\n");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd1d301bbc73ec11cd49b(YAML::Emitter& out)
+{
+    out << "foo\n";
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("!", 0, "foo\n");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test4640bfb42711b7209ef9(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test1133d19fc3a4ec9fb3e8(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test4a6d083241180899f7ed(YAML::Emitter& out)
+{
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testbadb5b228a4db78efac0(YAML::Emitter& out)
+{
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test5c6d607ed1ad046568e1(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testac34cde109884bb6876b(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test5c19597d5336d541f990(YAML::Emitter& out)
+{
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test39e174ed33d5508a61ce(YAML::Emitter& out)
+{
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test43e26cf94441cee4a0c4(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test06afa8e5b516630fc8da(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test4d109db0282a7797cdcb(YAML::Emitter& out)
+{
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0c1c00113c20dfa650a9(YAML::Emitter& out)
+{
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testccd7f2183f06483ee5e0(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test52e25e363a17f37c296f(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testdd81d16d3bdd8636af16(YAML::Emitter& out)
+{
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd76e8eb5043431c3434e(YAML::Emitter& out)
+{
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST teste03be55aff3dc08f07a1(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test8ba3e94c45f696c5027b(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test90e45bcf67b89e31fd12(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0b7c4e535bfebfa3c85d(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test3a1c08f490683d254cda(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test926cd343d3999525d9ce(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test1e5dd6b1e4dfb59f0346(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0f064b30c1187ff2dd4b(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test58fd20c1736964e12b53(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testbddd187d973b632dc188(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test5bc168e49ab7503fd2e1(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test712e139d81db4e14196d(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test48130bfdef5d192b888e(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test27552de54635da852895(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test6529691d17594d5abeb6(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test46b8a7b9d2461d80e0c0(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testbd1cb845de056e97a301(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testfe1f94c842b37340db76(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST teste3c7fbf8af4d82e891e3(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd6800d90d6d037d02ace(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testdf987230fa431b7a8f1b(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testcd22b774448a8b15345e(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test591a370a1ce302d23688(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test5e56c5800a9f2c4591ff(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test72f6d368cc2f52b488bd(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test6786da34791cbab71591(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test6d53136f35632180e2e8(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test01020a01f84721d7fb07(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testc3ab223703ef17e47ec7(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test033db6218db214ae5ef9(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test38fe09343ac97f51b38f(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test99eb29693d619703a052(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST teste9e58998a49132e15fb4(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testc1b4fba9280329b30583(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test2f8651438d44de183d22(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test4c506bf0bc7a972cb62d(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test6a42214b8698a0e87f5f(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST teste0b5020ccbc0cbc7f699(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test3fb453ac1de7a2d37a16(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test4d3236ecd88c5faa74e8(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test116230234c38c68eb060(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb7c63d73350b11bf4a56(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test26ae0a3b97fb1c7743bf(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testeabf01d5500c4f5c9de5(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf9195cd2fb4c57783870(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test8c7159f70888a6c5548e(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testba96c9cdf5e82c9ebd0f(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test6cbb2232cc1e43752958(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test2bc126cc8be9e3d0a5bb(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb053b9b6ee7c7eecc798(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testda8339179085c81ac7a9(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf38e7a065a9bda416bf0(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test5345180f2a8a65af5b72(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test7aee5968853276b78e65(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test1c20b15f6680fd1fa304(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test3ad355d8aa94a80ed9d0(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test717b89ec9b7b004e5c17(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testc540c8d6d92913953ef8(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test805391f6964c07b1fc51(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testafc978dbd9b5d8005968(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf137897e42e659d45548(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test41c10a5f012922d6d240(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test6d46af9b0e1bab6eefd2(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test6908c1e71bca5b5a09b6(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test158d6160ee94d7f929c0(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test07186666318de7b13975(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testdcb6011d1dbc47e024b4(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test998e6b11c32e19f91a43(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "bar";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test7b009b420c34f753e2dc(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "bar";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testba4c5b4eedf23c16ab44(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test022d120061a5c77c6640(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testeb346f4b70732835631f(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testade70114082f144726ee(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf2b68aae6173ab6ad66d(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST teste9a962c26a72ea4d3f8d(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testa9603ff993f8a8d47b5d(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test2b70cf1579b37e0fb086(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test3790d77103bac72dc302(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testadfa25cb2fd5a9346102(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test9764ad298ba1fe9ecfa8(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test22f20fac5e02211edadc(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test8b3b22c8ffd679b15623(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test438d1581dec9088389d7(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0b417297c8e11f038c7c(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testa3686f0b87652d4640c2(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd6f021791f2162c85174(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test3d34018a42371ab9fbcd(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test7a9287f053731d912e63(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testa9aa047a659d330a4a8b(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test74e66203a050c2ce6c17(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test7338d0bbe29dd57fab54(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testbd4f6be8cdb35c6f251d(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test8f0d1345830b83dfc1b7(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testa4e1c63bc2832a9ffb90(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test9d5abf8cc60b9bd0d314(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test332175e66c385ed1a97e(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test34238765b14f93c81e57(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test10797ce06190a3866a08(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST teste92cd495aff9e502a1ca(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf02ffda4a54ad1390ab6(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test252e5030af4f0ab7bf2b(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testfe3d96e64a5db1098e2d(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test94c9f1a9c03f970dde84(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd16f010f550e384c3e59(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test9b6529d7a517cd7dbc13(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test706fdc6bcd111cd4de81(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test7ce41e86a2afa55d59d7(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test14aebe584c51e7c2a682(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb9987fabfcd184f82c65(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testbe1a5e58793366c0c07a(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test1eac7fa4e151174d20c5(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test5a372a31cdbea0111962(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testcc1a35b80f0b02e1255e(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb04cc0e338c9b30cffa3(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb0a82e7bf3b5bdebdd9c(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0d883c1652c0b59e6643(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testa38bc626fc7e3454333b(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test8bea94aa1202a12d9ae9(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test24a263a0eb80caaaea4b(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb86b045d63884140fd1d(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test9d261e666ae24a9cfc70(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test331919d746512b1bd2dd(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test58b5cb1c0a14ca820fa0(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testfcc5a2d53d8b78bff00e(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test4e18e90b6551c4af46b7(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testfd0cdd7da5ea80def96c(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test31fa2c218bc9f47d31b5(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test486f1defd8f55e9519a9(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testbd67707be3be50792791(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test1a5d67d4591ad4c8d1e7(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd1b42a0d7e5156b00706(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test120e16514220d9f1b114(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf3200a3148254d3357d3(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test291bb8d225b135c1f926(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd89446599f31a400dcec(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test10810f50a49dfe065bfa(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb1f754216d575a8cc3af(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb9d82396ef66bed18aed(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test5469f77f98702583e6ea(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testea4d055788f9af327d2e(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test08ac3b6e6f8814cdc77a(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test9e8e5ac1687da916f607(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test6265b47bba1fd6839697(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testa78aad03d3d6c0cd9810(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test050fb21ac4e0ec123acc(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test41e74fd70f88555712db(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testc066eeba93b49bfd475e(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testba918d828779830ff775(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test9fc69104bdb595977460(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0dd65e43cc41ad032d71(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test324295b9fb6b58411e30(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test8aebc8d0e0485dfeb252(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd222de940e9a99d43cdd(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test9b7e3c531ced5ced7f08(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "bar";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testcfc4d3d407725683e731(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "bar";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test76848f10a77db08e038e(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testa4c728e62357ca05c45c(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test666ae3bb483cb7d83170(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test6ec557a6e48fd6900cb1(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test18a5d0db57d08d737b99(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd974ded8f39d6b77c0a1(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test6c6d47297f6ea03c588b(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testfb543650c644777c82ec(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test85cf601a990a9689b6c2(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testae2c05021a270e7e6ce6(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testceebe4a07ec516cb5a7a(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test1a2b24646720aa998cbb(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf415efe81b5c2c8112a2(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0f1b297a0cb08c094411(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test1b49cc3347751dcb09a9(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testffe72c176661d48910bd(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf3f2d1d0e79f326b3d2f(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testeb66a6725a958bb76923(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0a8fc83bac630f116c86(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test6c62ccca61f383967d91(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test6ba9e6495bef38087e7f(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test643e77d887ec7390c1c9(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testa9725ffe34acd33603c4(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test1a65df7ae90ac6ba1f22(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test7f982251b9a09ebb1059(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test4b2138b3eafc346d6bd3(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testa316e26e6b940d585005(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testda2e0d2a6fd2a83cb298(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test54aac276524c0baaecd1(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd1fb3fd39f4a2fda5c6a(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test4aaf20817b31a62e905f(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test446f00cbeee81a34d936(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb13663976ee52dac5370(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd245994f89c881efef06(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb6e7c5ee86f3c0559fe3(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testee28e38a088388ee5d9f(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test9b40d68cb65d34934b50(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test045fac0048d3cfc15d88(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "bar";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test85c3ad95991be29b3aff(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test2abfed1da9a2ab365c18(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testa999e4a9d0199bf463ec(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test8452a26a810950ad47b2(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test1e2b3a261f435a0f6316(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test1423ee4cd0795e6ef646(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf95070e81f8def8ceec9(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf533a12940040f665761(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test51bd09a609a537b79c8a(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testc10b994394aa86a1789b(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testc5de3511ef8fa1e5841e(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0e957613f266e5693f83(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf36b8fb2ec772e02a48c(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test249b4ee9b0e6936bdfcf(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testdae669b09d29d1d05e81(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testa3645755a60c69fe8af4(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test5500c0af0cbb6a8efc04(YAML::Emitter& out)
+{
+    out << YAML::BeginDoc;
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test6528fe35c2b993cbd28b(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test072a41bf81e5b4dcd7d2(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test3b47e24ba197ca8f686b(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test938c1c274b5ebf36c6b2(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testeea818614d4fbef183a8(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test18533eabe468baceac59(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST teste239cd01ef68ce26375d(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd3a9b36f8218cd633402(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testa899f4512569981104e8(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test230a8fd0d19c5e15963b(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test4fa431a3bea1c616f8d0(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testdd05d8f0df4f1ba79b8f(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0cb381d8a384434a2646(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testeadefbe24693d510ac03(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0b43e898410a9da3db1a(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test450ed0f6d19326bab043(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test38b7c3f09ffb6f4e73a5(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testab434195f62ee39997ae(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testdce4c351d6c426d24f14(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test2363249f46e86ae9bd64(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test6225a910ac0a5ce7304f(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "bar";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf7898be54854e4587c54(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test1ab55f98773e2e58c659(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf116d0bf1446d5e989db(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test90df709c20ab5305b5b0(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test37e041f7726819b98004(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test5c13c8d0762eb77abbbe(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test3c9ec0009e080492d6a0(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd016b2610a9701c799be(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test12e858bf6ec981811cc8(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+    out << YAML::EndDoc;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0e09fd8b6ac12a309a36(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndDoc;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testca30dc12961feab24a33(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test162ca62af5cdf9d02507(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST teste3a7658df7a81c1ce8e5(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test9dac5e4f0e78f96fcaad(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testaf2e952791b73c6bf78c(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test82b161574e0926b9c854(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test13c3f29be0e6b7bc92b1(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("anchor");
+    out << "foo";
+    out << YAML::VerbatimTag("tag");
+    out << YAML::Anchor("other");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("tag", 1, "foo");
+    EXPECT_SCALAR("tag", 2, "bar");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST teste87c7e9ce16fd2ac5f0e(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "foo";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testeed7f7f244221932d32f(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "foo";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test31a5563bfa532571339f(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "foo";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test502ab92aab5195ff4759(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testdbe2ce5bc02435009b2c(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test06b8d2cc9bbb233d55d5(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "foo";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test9adf48ae5d6dff37e89a(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "foo";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test398282871dcc1c7f8dbe(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test2e2b3c35732210898be1(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test155697ae715940b6d804(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb01c87881d846bb10ecd(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test84a9d3d2ae4eaacc9c98(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb836cd5dc876cf6eb204(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test4aa81dc715c5e5c53de1(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testfa8ba9d405de1af93537(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test3c07c460dae114d3f278(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf513330011b92283e713(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test88667a8fe856748b4dc6(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test7cbc7ae88a6b60d3cb54(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test8b126d00ee878273f3e9(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test414dcec883b2fb2668d9(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test41754fe2ab40560f1afe(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test39b7a9ee0ccb5580ef60(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test1f4cbfdb2f53d041fb74(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testc20612e8922a8eeba24d(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test693f48133cf726f1e05c(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test12b26bfed7a24736dd8b(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << "foo";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test41d6ec7f045897841e9c(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << "foo";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test2bc8d1d6e4ec042ede3e(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << "foo";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test647ff876c844ad7540ff(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << "foo";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test844c1bcb896dde8ea51b(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << "foo";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testbcf04a5174e8505d1891(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testdb6c8ca130035d7a271f(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testa0db96f3d93a255f2201(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << "foo";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test4fb3eaac714942122715(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << "foo";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test634678f31daa20127d6c(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test1dd395a1149e46dcc208(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testebc585cbde90d10a0af1(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd1ecec189e73f8932485(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf8fc72597f0a41b22daa(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd01959c5c228946c8759(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST teste8236a9672d9244ca486(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test22bd5d24dbd3f0670f97(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0f2c6cac0ce0e624eb08(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test2ed2eef7f03696ca3c94(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test6fe33177e10d14328a14(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0ea79e93c3439d90bdb8(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test2ab970621d7e037153c9(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test4229059ec3d639faf4b2(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test6df809b4712b73c8577f(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test37a0a34b2bef743d8241(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd6c37c1e50617419a37d(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test2fb71689fb176533159c(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testa91d7999dd9b43fb5827(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test8dfd4533e2891d3861ec(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0a9b0c29dfcf4f071eb9(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test3882a796318e573b115d(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test1ade39a1572a12eda7b8(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd308c7e19671725523cd(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << "foo";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test1ac58dc569ce7b4eebdf(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << "foo";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test5fe4c34b163d0efa12d5(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << "foo";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test78433ff7edf3224ce58b(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << "foo";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test089ed50cafddf39653d6(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "bar";
+    out << YAML::EndMap;
+    out << "foo";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test809723ec7bdea45cf562(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+    out << "foo";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test953cf821d2acc7898582(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0f1db947e4627596eace(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test52f3b0674f30d955eea7(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << "foo";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf95a488631e07f6ca914(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << "foo";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test9b7a916f4c1e2a1ae6ee(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test54ea34948e814ef79607(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testcef62af7508e0a1e3ee3(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testffcfb27f0c904fae7833(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test31ed1460205bbc5a4a68(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test7d04c8d923b046159db0(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test31b396851023614cf9fd(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test5befd800aa07d83e2df7(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test2df4f378f687fd80b98c(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test232f5aa6ea7e85e186c4(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test011421ad7da175099088(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf50217feca0ae03a0b03(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST teste4b49044063dd3c8a7ff(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testbe9295522ec1f0bc9de5(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test7a18055f1e3a49f93d40(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd8eebabad65b8ef02375(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test948f36e3182f3c1aa800(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testde02b69600e5931c39ab(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test5fdab21609e7017c3b86(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testfb52965f57b912ec23a4(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testa3f220ead85b78154f89(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0ef1b1c26e8a1fa34ccd(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test7661db62a921285da885(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test9382f466be3e19ca395f(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test33c4f45355dc7df2e2a8(YAML::Emitter& out)
+{
+    out << YAML::BeginMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testc55c40f32c34c890acce(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb06ba64c5895f218175d(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test14adb5374833871b2d0c(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test7ff7826c0f0563ce5a65(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test394e607327447b08e729(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testdf03e1437e901976c2c8(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test77467fcda467dd063050(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test5bcea73651331a2357d0(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test2956b3f097a16a4cd951(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test3170422d0cad24cd602a(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb37f0cd80f138e8f2622(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test3e00cce71da4636fa1f7(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testfd184c04759685f21abb(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test14ab4965eff0a569da16(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test271811f2df7210366780(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testfcfe8657dffc21f6cd45(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test609e44eab4ab95f31e33(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test7841fc715275a45a2770(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test662c03de87ca40bd943e(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0a9475ec3c946fe11991(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test94d28ebdbee90f430eb1(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd5035afc82e23b67ce03(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testcc9788c342da4454758f(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test140974453293fdb1155d(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testdc0b80a131730e98d735(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test1c5225b07d746c2bd331(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testa49a0be204cd2b57f17b(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testbe08cc0a08cf2cb5e7ec(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test4d2a2e12689655edd77c(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test4d4a25a54401f0282ceb(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test91f55feebb012ce89a93(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test1f3d0b19c6a346b087e0(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test4e26682c2daf8ded04a6(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test6f24e6df03922bba0d8a(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test60849eca7dc178908ff1(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test28b7db2ac68bb806e143(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test8db156db7065942bc260(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST teste240aced6e2292a9b091(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test468628a845426ce4a106(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testa3a2d467766b74acd6fd(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test5bf63d8ed606d688d869(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0d35c1487237ba7d8bdc(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb1fddc2897760d60e733(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testbaf845554a46f088bf71(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test6383f28d62ad9ce3c075(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test88a4c1cc11b99a61eccd(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test4716a2cf58a70705987b(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test75222084929bd0f9d38f(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test2fb23c79eec625216523(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb1699a6b7c5ded480677(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testd7de744a20ca1dc099db(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test900b2dcf20981b44ea65(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test20cc330b6d1171584aed(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test5ea8e3642fab864fb09d(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test42e21cbc65f534972ead(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test14e3b5dca1d7a5a0c957(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test9bd4800a58394b172738(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb715a2b66987a872ced8(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST teste9b56880009cc6899131(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test21f96f767e38471c9d4d(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testa8aebba05fc1858c0a6c(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST teste6e7442377049b17ee9e(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test428b593e283163fee752(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "bar";
+    out << YAML::EndMap;
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0b6c63323da4bf9798c2(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test0f4c45c39fe39dfc8a1d(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb8043a7ae1de42dd81db(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test4d9b278579ffb76fc56d(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test672fc8b6d281f82b9332(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb406d378fa0df952b051(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test68a227d03f20863f37e4(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testcee8582fd340377bda46(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test06fd48e8c86baf6fc05b(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test70b4ccbf71c0716bf8e4(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test449c2b349be8da36682b(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test9620fa69718e3b4fe391(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test3faaebe701bea6f8ee39(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test763ee61808091c7a354d(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test81b0d6b575228cde91e5(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testb607ae3c5d560092e37b(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testa53c54726737df14a5dd(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginSeq;
+    out << "foo";
+    out << YAML::EndSeq;
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SEQ_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test071d73b309a1365e0b07(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf8f45511528fa28cddcb(YAML::Emitter& out)
+{
+    out << YAML::Comment("comment");
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testabdd2bf3bdf550e3dd60(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test53424b35498a73fbede9(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testf0c6c1a1afced157d6a5(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST teste45dbac33918e0fee74f(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test903c7ab3d09d4323107f(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test5d39d351680dba4be04b(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << YAML::Comment("comment");
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testaa1e8d6d4385aab47bcd(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << YAML::Comment("comment");
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test9bd238b748ced1db588b(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::Comment("comment");
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST testec1cdffaae8842854947(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::Comment("comment");
+    out << YAML::EndSeq;
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test30727d97de63c1ad395a(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+TEST test7adafdc8be65a5d610bf(YAML::Emitter& out)
+{
+    out << YAML::BeginSeq;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::BeginMap;
+    out << "foo";
+    out << "bar";
+    out << YAML::EndMap;
+    out << YAML::EndSeq;
+    out << YAML::Comment("comment");
+
+    HANDLE(out.c_str());
+    EXPECT_DOC_START();
+    EXPECT_SEQ_START("?", 0);
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_MAP_START("?", 0);
+    EXPECT_SCALAR("?", 0, "foo");
+    EXPECT_SCALAR("?", 0, "bar");
+    EXPECT_MAP_END();
+    EXPECT_SEQ_END();
+    EXPECT_DOC_END();
+    DONE();
+}
+}
+#endif // YAML_GEN_TESTS
+
+void RunGenEmitterTests(int& passed, int& total)
+{
+#ifdef YAML_GEN_TESTS
+    RunGenEmitterTest(&Emitter::test02571eee35ac0cbd3777, "test02571eee35ac0cbd3777", passed, total);
+    RunGenEmitterTest(&Emitter::test71b969ca18898d226320, "test71b969ca18898d226320", passed, total);
+    RunGenEmitterTest(&Emitter::testd69e4ea95ce6f221c6e7, "testd69e4ea95ce6f221c6e7", passed, total);
+    RunGenEmitterTest(&Emitter::testffbfd295ad9bef4deb00, "testffbfd295ad9bef4deb00", passed, total);
+    RunGenEmitterTest(&Emitter::test6a459b2fe1f6e961e1a7, "test6a459b2fe1f6e961e1a7", passed, total);
+    RunGenEmitterTest(&Emitter::test869ab95640c9933ed4d6, "test869ab95640c9933ed4d6", passed, total);
+    RunGenEmitterTest(&Emitter::test433c0771f40ac3ba853e, "test433c0771f40ac3ba853e", passed, total);
+    RunGenEmitterTest(&Emitter::teste181778974c4003bc5a4, "teste181778974c4003bc5a4", passed, total);
+    RunGenEmitterTest(&Emitter::testf8cb7e3f1b11791f53b8, "testf8cb7e3f1b11791f53b8", passed, total);
+    RunGenEmitterTest(&Emitter::test3c48ed06807100f0a111, "test3c48ed06807100f0a111", passed, total);
+    RunGenEmitterTest(&Emitter::testb13f7b031f425b0e383f, "testb13f7b031f425b0e383f", passed, total);
+    RunGenEmitterTest(&Emitter::testb77284234d3fbe8b24a0, "testb77284234d3fbe8b24a0", passed, total);
+    RunGenEmitterTest(&Emitter::test9c56fd285b563327a340, "test9c56fd285b563327a340", passed, total);
+    RunGenEmitterTest(&Emitter::test1c08639d56176e64c885, "test1c08639d56176e64c885", passed, total);
+    RunGenEmitterTest(&Emitter::test94c8742f8cab3cec1b4a, "test94c8742f8cab3cec1b4a", passed, total);
+    RunGenEmitterTest(&Emitter::test79d1806ceb3ecebfa60b, "test79d1806ceb3ecebfa60b", passed, total);
+    RunGenEmitterTest(&Emitter::test360afe50348ec36569d3, "test360afe50348ec36569d3", passed, total);
+    RunGenEmitterTest(&Emitter::teste599b3fc1857f4265d3b, "teste599b3fc1857f4265d3b", passed, total);
+    RunGenEmitterTest(&Emitter::test88adf7adb474ad063424, "test88adf7adb474ad063424", passed, total);
+    RunGenEmitterTest(&Emitter::test0978ca6f6358ea06e024, "test0978ca6f6358ea06e024", passed, total);
+    RunGenEmitterTest(&Emitter::testd915f57fca4b0f6d77b4, "testd915f57fca4b0f6d77b4", passed, total);
+    RunGenEmitterTest(&Emitter::test1fe1f22496f2a0ffd64e, "test1fe1f22496f2a0ffd64e", passed, total);
+    RunGenEmitterTest(&Emitter::test76422a4077d3bdd03579, "test76422a4077d3bdd03579", passed, total);
+    RunGenEmitterTest(&Emitter::test92b168a497cb0c7e3144, "test92b168a497cb0c7e3144", passed, total);
+    RunGenEmitterTest(&Emitter::testa93925b3ae311a7f11d4, "testa93925b3ae311a7f11d4", passed, total);
+    RunGenEmitterTest(&Emitter::test2dd1aaf6a1c1924557d0, "test2dd1aaf6a1c1924557d0", passed, total);
+    RunGenEmitterTest(&Emitter::test6ec0585d0f0945ad9dae, "test6ec0585d0f0945ad9dae", passed, total);
+    RunGenEmitterTest(&Emitter::test7e00bca835d55844bbfe, "test7e00bca835d55844bbfe", passed, total);
+    RunGenEmitterTest(&Emitter::test70912c7d920a0597bbb2, "test70912c7d920a0597bbb2", passed, total);
+    RunGenEmitterTest(&Emitter::test16eacbf77bccde360e54, "test16eacbf77bccde360e54", passed, total);
+    RunGenEmitterTest(&Emitter::test556e0c86efb0716d2778, "test556e0c86efb0716d2778", passed, total);
+    RunGenEmitterTest(&Emitter::test71b64326d72fe100e6ad, "test71b64326d72fe100e6ad", passed, total);
+    RunGenEmitterTest(&Emitter::test0c7bb03fbd6b52ea3ad6, "test0c7bb03fbd6b52ea3ad6", passed, total);
+    RunGenEmitterTest(&Emitter::testb819efb5742c1176df98, "testb819efb5742c1176df98", passed, total);
+    RunGenEmitterTest(&Emitter::test1f7b7cd5a13070c723d3, "test1f7b7cd5a13070c723d3", passed, total);
+    RunGenEmitterTest(&Emitter::test32126a88cb2b7311e779, "test32126a88cb2b7311e779", passed, total);
+    RunGenEmitterTest(&Emitter::testd7f952713bde5ce2f9e7, "testd7f952713bde5ce2f9e7", passed, total);
+    RunGenEmitterTest(&Emitter::test5030b4f2d1efb798f320, "test5030b4f2d1efb798f320", passed, total);
+    RunGenEmitterTest(&Emitter::testb9015537b9a9e09b8ec8, "testb9015537b9a9e09b8ec8", passed, total);
+    RunGenEmitterTest(&Emitter::test03229f6d33fa9007a65d, "test03229f6d33fa9007a65d", passed, total);
+    RunGenEmitterTest(&Emitter::testf998264dcfd0dba06c0a, "testf998264dcfd0dba06c0a", passed, total);
+    RunGenEmitterTest(&Emitter::test7defadc52eddfbf766aa, "test7defadc52eddfbf766aa", passed, total);
+    RunGenEmitterTest(&Emitter::test55a7c58211689c7815b2, "test55a7c58211689c7815b2", passed, total);
+    RunGenEmitterTest(&Emitter::testc3873d954433175e0143, "testc3873d954433175e0143", passed, total);
+    RunGenEmitterTest(&Emitter::test81fb6bf1f976e0ad3fba, "test81fb6bf1f976e0ad3fba", passed, total);
+    RunGenEmitterTest(&Emitter::test29e7ff04645f56a7ea2f, "test29e7ff04645f56a7ea2f", passed, total);
+    RunGenEmitterTest(&Emitter::testce0089a55f926d311ff4, "testce0089a55f926d311ff4", passed, total);
+    RunGenEmitterTest(&Emitter::testd1d301bbc73ec11cd49b, "testd1d301bbc73ec11cd49b", passed, total);
+    RunGenEmitterTest(&Emitter::test4640bfb42711b7209ef9, "test4640bfb42711b7209ef9", passed, total);
+    RunGenEmitterTest(&Emitter::test1133d19fc3a4ec9fb3e8, "test1133d19fc3a4ec9fb3e8", passed, total);
+    RunGenEmitterTest(&Emitter::test4a6d083241180899f7ed, "test4a6d083241180899f7ed", passed, total);
+    RunGenEmitterTest(&Emitter::testbadb5b228a4db78efac0, "testbadb5b228a4db78efac0", passed, total);
+    RunGenEmitterTest(&Emitter::test5c6d607ed1ad046568e1, "test5c6d607ed1ad046568e1", passed, total);
+    RunGenEmitterTest(&Emitter::testac34cde109884bb6876b, "testac34cde109884bb6876b", passed, total);
+    RunGenEmitterTest(&Emitter::test5c19597d5336d541f990, "test5c19597d5336d541f990", passed, total);
+    RunGenEmitterTest(&Emitter::test39e174ed33d5508a61ce, "test39e174ed33d5508a61ce", passed, total);
+    RunGenEmitterTest(&Emitter::test43e26cf94441cee4a0c4, "test43e26cf94441cee4a0c4", passed, total);
+    RunGenEmitterTest(&Emitter::test06afa8e5b516630fc8da, "test06afa8e5b516630fc8da", passed, total);
+    RunGenEmitterTest(&Emitter::test4d109db0282a7797cdcb, "test4d109db0282a7797cdcb", passed, total);
+    RunGenEmitterTest(&Emitter::test0c1c00113c20dfa650a9, "test0c1c00113c20dfa650a9", passed, total);
+    RunGenEmitterTest(&Emitter::testccd7f2183f06483ee5e0, "testccd7f2183f06483ee5e0", passed, total);
+    RunGenEmitterTest(&Emitter::test52e25e363a17f37c296f, "test52e25e363a17f37c296f", passed, total);
+    RunGenEmitterTest(&Emitter::testdd81d16d3bdd8636af16, "testdd81d16d3bdd8636af16", passed, total);
+    RunGenEmitterTest(&Emitter::testd76e8eb5043431c3434e, "testd76e8eb5043431c3434e", passed, total);
+    RunGenEmitterTest(&Emitter::teste03be55aff3dc08f07a1, "teste03be55aff3dc08f07a1", passed, total);
+    RunGenEmitterTest(&Emitter::test8ba3e94c45f696c5027b, "test8ba3e94c45f696c5027b", passed, total);
+    RunGenEmitterTest(&Emitter::test90e45bcf67b89e31fd12, "test90e45bcf67b89e31fd12", passed, total);
+    RunGenEmitterTest(&Emitter::test0b7c4e535bfebfa3c85d, "test0b7c4e535bfebfa3c85d", passed, total);
+    RunGenEmitterTest(&Emitter::test3a1c08f490683d254cda, "test3a1c08f490683d254cda", passed, total);
+    RunGenEmitterTest(&Emitter::test926cd343d3999525d9ce, "test926cd343d3999525d9ce", passed, total);
+    RunGenEmitterTest(&Emitter::test1e5dd6b1e4dfb59f0346, "test1e5dd6b1e4dfb59f0346", passed, total);
+    RunGenEmitterTest(&Emitter::test0f064b30c1187ff2dd4b, "test0f064b30c1187ff2dd4b", passed, total);
+    RunGenEmitterTest(&Emitter::test58fd20c1736964e12b53, "test58fd20c1736964e12b53", passed, total);
+    RunGenEmitterTest(&Emitter::testbddd187d973b632dc188, "testbddd187d973b632dc188", passed, total);
+    RunGenEmitterTest(&Emitter::test5bc168e49ab7503fd2e1, "test5bc168e49ab7503fd2e1", passed, total);
+    RunGenEmitterTest(&Emitter::test712e139d81db4e14196d, "test712e139d81db4e14196d", passed, total);
+    RunGenEmitterTest(&Emitter::test48130bfdef5d192b888e, "test48130bfdef5d192b888e", passed, total);
+    RunGenEmitterTest(&Emitter::test27552de54635da852895, "test27552de54635da852895", passed, total);
+    RunGenEmitterTest(&Emitter::test6529691d17594d5abeb6, "test6529691d17594d5abeb6", passed, total);
+    RunGenEmitterTest(&Emitter::test46b8a7b9d2461d80e0c0, "test46b8a7b9d2461d80e0c0", passed, total);
+    RunGenEmitterTest(&Emitter::testbd1cb845de056e97a301, "testbd1cb845de056e97a301", passed, total);
+    RunGenEmitterTest(&Emitter::testfe1f94c842b37340db76, "testfe1f94c842b37340db76", passed, total);
+    RunGenEmitterTest(&Emitter::teste3c7fbf8af4d82e891e3, "teste3c7fbf8af4d82e891e3", passed, total);
+    RunGenEmitterTest(&Emitter::testd6800d90d6d037d02ace, "testd6800d90d6d037d02ace", passed, total);
+    RunGenEmitterTest(&Emitter::testdf987230fa431b7a8f1b, "testdf987230fa431b7a8f1b", passed, total);
+    RunGenEmitterTest(&Emitter::testcd22b774448a8b15345e, "testcd22b774448a8b15345e", passed, total);
+    RunGenEmitterTest(&Emitter::test591a370a1ce302d23688, "test591a370a1ce302d23688", passed, total);
+    RunGenEmitterTest(&Emitter::test5e56c5800a9f2c4591ff, "test5e56c5800a9f2c4591ff", passed, total);
+    RunGenEmitterTest(&Emitter::test72f6d368cc2f52b488bd, "test72f6d368cc2f52b488bd", passed, total);
+    RunGenEmitterTest(&Emitter::test6786da34791cbab71591, "test6786da34791cbab71591", passed, total);
+    RunGenEmitterTest(&Emitter::test6d53136f35632180e2e8, "test6d53136f35632180e2e8", passed, total);
+    RunGenEmitterTest(&Emitter::test01020a01f84721d7fb07, "test01020a01f84721d7fb07", passed, total);
+    RunGenEmitterTest(&Emitter::testc3ab223703ef17e47ec7, "testc3ab223703ef17e47ec7", passed, total);
+    RunGenEmitterTest(&Emitter::test033db6218db214ae5ef9, "test033db6218db214ae5ef9", passed, total);
+    RunGenEmitterTest(&Emitter::test38fe09343ac97f51b38f, "test38fe09343ac97f51b38f", passed, total);
+    RunGenEmitterTest(&Emitter::test99eb29693d619703a052, "test99eb29693d619703a052", passed, total);
+    RunGenEmitterTest(&Emitter::teste9e58998a49132e15fb4, "teste9e58998a49132e15fb4", passed, total);
+    RunGenEmitterTest(&Emitter::testc1b4fba9280329b30583, "testc1b4fba9280329b30583", passed, total);
+    RunGenEmitterTest(&Emitter::test2f8651438d44de183d22, "test2f8651438d44de183d22", passed, total);
+    RunGenEmitterTest(&Emitter::test4c506bf0bc7a972cb62d, "test4c506bf0bc7a972cb62d", passed, total);
+    RunGenEmitterTest(&Emitter::test6a42214b8698a0e87f5f, "test6a42214b8698a0e87f5f", passed, total);
+    RunGenEmitterTest(&Emitter::teste0b5020ccbc0cbc7f699, "teste0b5020ccbc0cbc7f699", passed, total);
+    RunGenEmitterTest(&Emitter::test3fb453ac1de7a2d37a16, "test3fb453ac1de7a2d37a16", passed, total);
+    RunGenEmitterTest(&Emitter::test4d3236ecd88c5faa74e8, "test4d3236ecd88c5faa74e8", passed, total);
+    RunGenEmitterTest(&Emitter::test116230234c38c68eb060, "test116230234c38c68eb060", passed, total);
+    RunGenEmitterTest(&Emitter::testb7c63d73350b11bf4a56, "testb7c63d73350b11bf4a56", passed, total);
+    RunGenEmitterTest(&Emitter::test26ae0a3b97fb1c7743bf, "test26ae0a3b97fb1c7743bf", passed, total);
+    RunGenEmitterTest(&Emitter::testeabf01d5500c4f5c9de5, "testeabf01d5500c4f5c9de5", passed, total);
+    RunGenEmitterTest(&Emitter::testf9195cd2fb4c57783870, "testf9195cd2fb4c57783870", passed, total);
+    RunGenEmitterTest(&Emitter::test8c7159f70888a6c5548e, "test8c7159f70888a6c5548e", passed, total);
+    RunGenEmitterTest(&Emitter::testba96c9cdf5e82c9ebd0f, "testba96c9cdf5e82c9ebd0f", passed, total);
+    RunGenEmitterTest(&Emitter::test6cbb2232cc1e43752958, "test6cbb2232cc1e43752958", passed, total);
+    RunGenEmitterTest(&Emitter::test2bc126cc8be9e3d0a5bb, "test2bc126cc8be9e3d0a5bb", passed, total);
+    RunGenEmitterTest(&Emitter::testb053b9b6ee7c7eecc798, "testb053b9b6ee7c7eecc798", passed, total);
+    RunGenEmitterTest(&Emitter::testda8339179085c81ac7a9, "testda8339179085c81ac7a9", passed, total);
+    RunGenEmitterTest(&Emitter::testf38e7a065a9bda416bf0, "testf38e7a065a9bda416bf0", passed, total);
+    RunGenEmitterTest(&Emitter::test5345180f2a8a65af5b72, "test5345180f2a8a65af5b72", passed, total);
+    RunGenEmitterTest(&Emitter::test7aee5968853276b78e65, "test7aee5968853276b78e65", passed, total);
+    RunGenEmitterTest(&Emitter::test1c20b15f6680fd1fa304, "test1c20b15f6680fd1fa304", passed, total);
+    RunGenEmitterTest(&Emitter::test3ad355d8aa94a80ed9d0, "test3ad355d8aa94a80ed9d0", passed, total);
+    RunGenEmitterTest(&Emitter::test717b89ec9b7b004e5c17, "test717b89ec9b7b004e5c17", passed, total);
+    RunGenEmitterTest(&Emitter::testc540c8d6d92913953ef8, "testc540c8d6d92913953ef8", passed, total);
+    RunGenEmitterTest(&Emitter::test805391f6964c07b1fc51, "test805391f6964c07b1fc51", passed, total);
+    RunGenEmitterTest(&Emitter::testafc978dbd9b5d8005968, "testafc978dbd9b5d8005968", passed, total);
+    RunGenEmitterTest(&Emitter::testf137897e42e659d45548, "testf137897e42e659d45548", passed, total);
+    RunGenEmitterTest(&Emitter::test41c10a5f012922d6d240, "test41c10a5f012922d6d240", passed, total);
+    RunGenEmitterTest(&Emitter::test6d46af9b0e1bab6eefd2, "test6d46af9b0e1bab6eefd2", passed, total);
+    RunGenEmitterTest(&Emitter::test6908c1e71bca5b5a09b6, "test6908c1e71bca5b5a09b6", passed, total);
+    RunGenEmitterTest(&Emitter::test158d6160ee94d7f929c0, "test158d6160ee94d7f929c0", passed, total);
+    RunGenEmitterTest(&Emitter::test07186666318de7b13975, "test07186666318de7b13975", passed, total);
+    RunGenEmitterTest(&Emitter::testdcb6011d1dbc47e024b4, "testdcb6011d1dbc47e024b4", passed, total);
+    RunGenEmitterTest(&Emitter::test998e6b11c32e19f91a43, "test998e6b11c32e19f91a43", passed, total);
+    RunGenEmitterTest(&Emitter::test7b009b420c34f753e2dc, "test7b009b420c34f753e2dc", passed, total);
+    RunGenEmitterTest(&Emitter::testba4c5b4eedf23c16ab44, "testba4c5b4eedf23c16ab44", passed, total);
+    RunGenEmitterTest(&Emitter::test022d120061a5c77c6640, "test022d120061a5c77c6640", passed, total);
+    RunGenEmitterTest(&Emitter::testeb346f4b70732835631f, "testeb346f4b70732835631f", passed, total);
+    RunGenEmitterTest(&Emitter::testade70114082f144726ee, "testade70114082f144726ee", passed, total);
+    RunGenEmitterTest(&Emitter::testf2b68aae6173ab6ad66d, "testf2b68aae6173ab6ad66d", passed, total);
+    RunGenEmitterTest(&Emitter::teste9a962c26a72ea4d3f8d, "teste9a962c26a72ea4d3f8d", passed, total);
+    RunGenEmitterTest(&Emitter::testa9603ff993f8a8d47b5d, "testa9603ff993f8a8d47b5d", passed, total);
+    RunGenEmitterTest(&Emitter::test2b70cf1579b37e0fb086, "test2b70cf1579b37e0fb086", passed, total);
+    RunGenEmitterTest(&Emitter::test3790d77103bac72dc302, "test3790d77103bac72dc302", passed, total);
+    RunGenEmitterTest(&Emitter::testadfa25cb2fd5a9346102, "testadfa25cb2fd5a9346102", passed, total);
+    RunGenEmitterTest(&Emitter::test9764ad298ba1fe9ecfa8, "test9764ad298ba1fe9ecfa8", passed, total);
+    RunGenEmitterTest(&Emitter::test22f20fac5e02211edadc, "test22f20fac5e02211edadc", passed, total);
+    RunGenEmitterTest(&Emitter::test8b3b22c8ffd679b15623, "test8b3b22c8ffd679b15623", passed, total);
+    RunGenEmitterTest(&Emitter::test438d1581dec9088389d7, "test438d1581dec9088389d7", passed, total);
+    RunGenEmitterTest(&Emitter::test0b417297c8e11f038c7c, "test0b417297c8e11f038c7c", passed, total);
+    RunGenEmitterTest(&Emitter::testa3686f0b87652d4640c2, "testa3686f0b87652d4640c2", passed, total);
+    RunGenEmitterTest(&Emitter::testd6f021791f2162c85174, "testd6f021791f2162c85174", passed, total);
+    RunGenEmitterTest(&Emitter::test3d34018a42371ab9fbcd, "test3d34018a42371ab9fbcd", passed, total);
+    RunGenEmitterTest(&Emitter::test7a9287f053731d912e63, "test7a9287f053731d912e63", passed, total);
+    RunGenEmitterTest(&Emitter::testa9aa047a659d330a4a8b, "testa9aa047a659d330a4a8b", passed, total);
+    RunGenEmitterTest(&Emitter::test74e66203a050c2ce6c17, "test74e66203a050c2ce6c17", passed, total);
+    RunGenEmitterTest(&Emitter::test7338d0bbe29dd57fab54, "test7338d0bbe29dd57fab54", passed, total);
+    RunGenEmitterTest(&Emitter::testbd4f6be8cdb35c6f251d, "testbd4f6be8cdb35c6f251d", passed, total);
+    RunGenEmitterTest(&Emitter::test8f0d1345830b83dfc1b7, "test8f0d1345830b83dfc1b7", passed, total);
+    RunGenEmitterTest(&Emitter::testa4e1c63bc2832a9ffb90, "testa4e1c63bc2832a9ffb90", passed, total);
+    RunGenEmitterTest(&Emitter::test9d5abf8cc60b9bd0d314, "test9d5abf8cc60b9bd0d314", passed, total);
+    RunGenEmitterTest(&Emitter::test332175e66c385ed1a97e, "test332175e66c385ed1a97e", passed, total);
+    RunGenEmitterTest(&Emitter::test34238765b14f93c81e57, "test34238765b14f93c81e57", passed, total);
+    RunGenEmitterTest(&Emitter::test10797ce06190a3866a08, "test10797ce06190a3866a08", passed, total);
+    RunGenEmitterTest(&Emitter::teste92cd495aff9e502a1ca, "teste92cd495aff9e502a1ca", passed, total);
+    RunGenEmitterTest(&Emitter::testf02ffda4a54ad1390ab6, "testf02ffda4a54ad1390ab6", passed, total);
+    RunGenEmitterTest(&Emitter::test252e5030af4f0ab7bf2b, "test252e5030af4f0ab7bf2b", passed, total);
+    RunGenEmitterTest(&Emitter::testfe3d96e64a5db1098e2d, "testfe3d96e64a5db1098e2d", passed, total);
+    RunGenEmitterTest(&Emitter::test94c9f1a9c03f970dde84, "test94c9f1a9c03f970dde84", passed, total);
+    RunGenEmitterTest(&Emitter::testd16f010f550e384c3e59, "testd16f010f550e384c3e59", passed, total);
+    RunGenEmitterTest(&Emitter::test9b6529d7a517cd7dbc13, "test9b6529d7a517cd7dbc13", passed, total);
+    RunGenEmitterTest(&Emitter::test706fdc6bcd111cd4de81, "test706fdc6bcd111cd4de81", passed, total);
+    RunGenEmitterTest(&Emitter::test7ce41e86a2afa55d59d7, "test7ce41e86a2afa55d59d7", passed, total);
+    RunGenEmitterTest(&Emitter::test14aebe584c51e7c2a682, "test14aebe584c51e7c2a682", passed, total);
+    RunGenEmitterTest(&Emitter::testb9987fabfcd184f82c65, "testb9987fabfcd184f82c65", passed, total);
+    RunGenEmitterTest(&Emitter::testbe1a5e58793366c0c07a, "testbe1a5e58793366c0c07a", passed, total);
+    RunGenEmitterTest(&Emitter::test1eac7fa4e151174d20c5, "test1eac7fa4e151174d20c5", passed, total);
+    RunGenEmitterTest(&Emitter::test5a372a31cdbea0111962, "test5a372a31cdbea0111962", passed, total);
+    RunGenEmitterTest(&Emitter::testcc1a35b80f0b02e1255e, "testcc1a35b80f0b02e1255e", passed, total);
+    RunGenEmitterTest(&Emitter::testb04cc0e338c9b30cffa3, "testb04cc0e338c9b30cffa3", passed, total);
+    RunGenEmitterTest(&Emitter::testb0a82e7bf3b5bdebdd9c, "testb0a82e7bf3b5bdebdd9c", passed, total);
+    RunGenEmitterTest(&Emitter::test0d883c1652c0b59e6643, "test0d883c1652c0b59e6643", passed, total);
+    RunGenEmitterTest(&Emitter::testa38bc626fc7e3454333b, "testa38bc626fc7e3454333b", passed, total);
+    RunGenEmitterTest(&Emitter::test8bea94aa1202a12d9ae9, "test8bea94aa1202a12d9ae9", passed, total);
+    RunGenEmitterTest(&Emitter::test24a263a0eb80caaaea4b, "test24a263a0eb80caaaea4b", passed, total);
+    RunGenEmitterTest(&Emitter::testb86b045d63884140fd1d, "testb86b045d63884140fd1d", passed, total);
+    RunGenEmitterTest(&Emitter::test9d261e666ae24a9cfc70, "test9d261e666ae24a9cfc70", passed, total);
+    RunGenEmitterTest(&Emitter::test331919d746512b1bd2dd, "test331919d746512b1bd2dd", passed, total);
+    RunGenEmitterTest(&Emitter::test58b5cb1c0a14ca820fa0, "test58b5cb1c0a14ca820fa0", passed, total);
+    RunGenEmitterTest(&Emitter::testfcc5a2d53d8b78bff00e, "testfcc5a2d53d8b78bff00e", passed, total);
+    RunGenEmitterTest(&Emitter::test4e18e90b6551c4af46b7, "test4e18e90b6551c4af46b7", passed, total);
+    RunGenEmitterTest(&Emitter::testfd0cdd7da5ea80def96c, "testfd0cdd7da5ea80def96c", passed, total);
+    RunGenEmitterTest(&Emitter::test31fa2c218bc9f47d31b5, "test31fa2c218bc9f47d31b5", passed, total);
+    RunGenEmitterTest(&Emitter::test486f1defd8f55e9519a9, "test486f1defd8f55e9519a9", passed, total);
+    RunGenEmitterTest(&Emitter::testbd67707be3be50792791, "testbd67707be3be50792791", passed, total);
+    RunGenEmitterTest(&Emitter::test1a5d67d4591ad4c8d1e7, "test1a5d67d4591ad4c8d1e7", passed, total);
+    RunGenEmitterTest(&Emitter::testd1b42a0d7e5156b00706, "testd1b42a0d7e5156b00706", passed, total);
+    RunGenEmitterTest(&Emitter::test120e16514220d9f1b114, "test120e16514220d9f1b114", passed, total);
+    RunGenEmitterTest(&Emitter::testf3200a3148254d3357d3, "testf3200a3148254d3357d3", passed, total);
+    RunGenEmitterTest(&Emitter::test291bb8d225b135c1f926, "test291bb8d225b135c1f926", passed, total);
+    RunGenEmitterTest(&Emitter::testd89446599f31a400dcec, "testd89446599f31a400dcec", passed, total);
+    RunGenEmitterTest(&Emitter::test10810f50a49dfe065bfa, "test10810f50a49dfe065bfa", passed, total);
+    RunGenEmitterTest(&Emitter::testb1f754216d575a8cc3af, "testb1f754216d575a8cc3af", passed, total);
+    RunGenEmitterTest(&Emitter::testb9d82396ef66bed18aed, "testb9d82396ef66bed18aed", passed, total);
+    RunGenEmitterTest(&Emitter::test5469f77f98702583e6ea, "test5469f77f98702583e6ea", passed, total);
+    RunGenEmitterTest(&Emitter::testea4d055788f9af327d2e, "testea4d055788f9af327d2e", passed, total);
+    RunGenEmitterTest(&Emitter::test08ac3b6e6f8814cdc77a, "test08ac3b6e6f8814cdc77a", passed, total);
+    RunGenEmitterTest(&Emitter::test9e8e5ac1687da916f607, "test9e8e5ac1687da916f607", passed, total);
+    RunGenEmitterTest(&Emitter::test6265b47bba1fd6839697, "test6265b47bba1fd6839697", passed, total);
+    RunGenEmitterTest(&Emitter::testa78aad03d3d6c0cd9810, "testa78aad03d3d6c0cd9810", passed, total);
+    RunGenEmitterTest(&Emitter::test050fb21ac4e0ec123acc, "test050fb21ac4e0ec123acc", passed, total);
+    RunGenEmitterTest(&Emitter::test41e74fd70f88555712db, "test41e74fd70f88555712db", passed, total);
+    RunGenEmitterTest(&Emitter::testc066eeba93b49bfd475e, "testc066eeba93b49bfd475e", passed, total);
+    RunGenEmitterTest(&Emitter::testba918d828779830ff775, "testba918d828779830ff775", passed, total);
+    RunGenEmitterTest(&Emitter::test9fc69104bdb595977460, "test9fc69104bdb595977460", passed, total);
+    RunGenEmitterTest(&Emitter::test0dd65e43cc41ad032d71, "test0dd65e43cc41ad032d71", passed, total);
+    RunGenEmitterTest(&Emitter::test324295b9fb6b58411e30, "test324295b9fb6b58411e30", passed, total);
+    RunGenEmitterTest(&Emitter::test8aebc8d0e0485dfeb252, "test8aebc8d0e0485dfeb252", passed, total);
+    RunGenEmitterTest(&Emitter::testd222de940e9a99d43cdd, "testd222de940e9a99d43cdd", passed, total);
+    RunGenEmitterTest(&Emitter::test9b7e3c531ced5ced7f08, "test9b7e3c531ced5ced7f08", passed, total);
+    RunGenEmitterTest(&Emitter::testcfc4d3d407725683e731, "testcfc4d3d407725683e731", passed, total);
+    RunGenEmitterTest(&Emitter::test76848f10a77db08e038e, "test76848f10a77db08e038e", passed, total);
+    RunGenEmitterTest(&Emitter::testa4c728e62357ca05c45c, "testa4c728e62357ca05c45c", passed, total);
+    RunGenEmitterTest(&Emitter::test666ae3bb483cb7d83170, "test666ae3bb483cb7d83170", passed, total);
+    RunGenEmitterTest(&Emitter::test6ec557a6e48fd6900cb1, "test6ec557a6e48fd6900cb1", passed, total);
+    RunGenEmitterTest(&Emitter::test18a5d0db57d08d737b99, "test18a5d0db57d08d737b99", passed, total);
+    RunGenEmitterTest(&Emitter::testd974ded8f39d6b77c0a1, "testd974ded8f39d6b77c0a1", passed, total);
+    RunGenEmitterTest(&Emitter::test6c6d47297f6ea03c588b, "test6c6d47297f6ea03c588b", passed, total);
+    RunGenEmitterTest(&Emitter::testfb543650c644777c82ec, "testfb543650c644777c82ec", passed, total);
+    RunGenEmitterTest(&Emitter::test85cf601a990a9689b6c2, "test85cf601a990a9689b6c2", passed, total);
+    RunGenEmitterTest(&Emitter::testae2c05021a270e7e6ce6, "testae2c05021a270e7e6ce6", passed, total);
+    RunGenEmitterTest(&Emitter::testceebe4a07ec516cb5a7a, "testceebe4a07ec516cb5a7a", passed, total);
+    RunGenEmitterTest(&Emitter::test1a2b24646720aa998cbb, "test1a2b24646720aa998cbb", passed, total);
+    RunGenEmitterTest(&Emitter::testf415efe81b5c2c8112a2, "testf415efe81b5c2c8112a2", passed, total);
+    RunGenEmitterTest(&Emitter::test0f1b297a0cb08c094411, "test0f1b297a0cb08c094411", passed, total);
+    RunGenEmitterTest(&Emitter::test1b49cc3347751dcb09a9, "test1b49cc3347751dcb09a9", passed, total);
+    RunGenEmitterTest(&Emitter::testffe72c176661d48910bd, "testffe72c176661d48910bd", passed, total);
+    RunGenEmitterTest(&Emitter::testf3f2d1d0e79f326b3d2f, "testf3f2d1d0e79f326b3d2f", passed, total);
+    RunGenEmitterTest(&Emitter::testeb66a6725a958bb76923, "testeb66a6725a958bb76923", passed, total);
+    RunGenEmitterTest(&Emitter::test0a8fc83bac630f116c86, "test0a8fc83bac630f116c86", passed, total);
+    RunGenEmitterTest(&Emitter::test6c62ccca61f383967d91, "test6c62ccca61f383967d91", passed, total);
+    RunGenEmitterTest(&Emitter::test6ba9e6495bef38087e7f, "test6ba9e6495bef38087e7f", passed, total);
+    RunGenEmitterTest(&Emitter::test643e77d887ec7390c1c9, "test643e77d887ec7390c1c9", passed, total);
+    RunGenEmitterTest(&Emitter::testa9725ffe34acd33603c4, "testa9725ffe34acd33603c4", passed, total);
+    RunGenEmitterTest(&Emitter::test1a65df7ae90ac6ba1f22, "test1a65df7ae90ac6ba1f22", passed, total);
+    RunGenEmitterTest(&Emitter::test7f982251b9a09ebb1059, "test7f982251b9a09ebb1059", passed, total);
+    RunGenEmitterTest(&Emitter::test4b2138b3eafc346d6bd3, "test4b2138b3eafc346d6bd3", passed, total);
+    RunGenEmitterTest(&Emitter::testa316e26e6b940d585005, "testa316e26e6b940d585005", passed, total);
+    RunGenEmitterTest(&Emitter::testda2e0d2a6fd2a83cb298, "testda2e0d2a6fd2a83cb298", passed, total);
+    RunGenEmitterTest(&Emitter::test54aac276524c0baaecd1, "test54aac276524c0baaecd1", passed, total);
+    RunGenEmitterTest(&Emitter::testd1fb3fd39f4a2fda5c6a, "testd1fb3fd39f4a2fda5c6a", passed, total);
+    RunGenEmitterTest(&Emitter::test4aaf20817b31a62e905f, "test4aaf20817b31a62e905f", passed, total);
+    RunGenEmitterTest(&Emitter::test446f00cbeee81a34d936, "test446f00cbeee81a34d936", passed, total);
+    RunGenEmitterTest(&Emitter::testb13663976ee52dac5370, "testb13663976ee52dac5370", passed, total);
+    RunGenEmitterTest(&Emitter::testd245994f89c881efef06, "testd245994f89c881efef06", passed, total);
+    RunGenEmitterTest(&Emitter::testb6e7c5ee86f3c0559fe3, "testb6e7c5ee86f3c0559fe3", passed, total);
+    RunGenEmitterTest(&Emitter::testee28e38a088388ee5d9f, "testee28e38a088388ee5d9f", passed, total);
+    RunGenEmitterTest(&Emitter::test9b40d68cb65d34934b50, "test9b40d68cb65d34934b50", passed, total);
+    RunGenEmitterTest(&Emitter::test045fac0048d3cfc15d88, "test045fac0048d3cfc15d88", passed, total);
+    RunGenEmitterTest(&Emitter::test85c3ad95991be29b3aff, "test85c3ad95991be29b3aff", passed, total);
+    RunGenEmitterTest(&Emitter::test2abfed1da9a2ab365c18, "test2abfed1da9a2ab365c18", passed, total);
+    RunGenEmitterTest(&Emitter::testa999e4a9d0199bf463ec, "testa999e4a9d0199bf463ec", passed, total);
+    RunGenEmitterTest(&Emitter::test8452a26a810950ad47b2, "test8452a26a810950ad47b2", passed, total);
+    RunGenEmitterTest(&Emitter::test1e2b3a261f435a0f6316, "test1e2b3a261f435a0f6316", passed, total);
+    RunGenEmitterTest(&Emitter::test1423ee4cd0795e6ef646, "test1423ee4cd0795e6ef646", passed, total);
+    RunGenEmitterTest(&Emitter::testf95070e81f8def8ceec9, "testf95070e81f8def8ceec9", passed, total);
+    RunGenEmitterTest(&Emitter::testf533a12940040f665761, "testf533a12940040f665761", passed, total);
+    RunGenEmitterTest(&Emitter::test51bd09a609a537b79c8a, "test51bd09a609a537b79c8a", passed, total);
+    RunGenEmitterTest(&Emitter::testc10b994394aa86a1789b, "testc10b994394aa86a1789b", passed, total);
+    RunGenEmitterTest(&Emitter::testc5de3511ef8fa1e5841e, "testc5de3511ef8fa1e5841e", passed, total);
+    RunGenEmitterTest(&Emitter::test0e957613f266e5693f83, "test0e957613f266e5693f83", passed, total);
+    RunGenEmitterTest(&Emitter::testf36b8fb2ec772e02a48c, "testf36b8fb2ec772e02a48c", passed, total);
+    RunGenEmitterTest(&Emitter::test249b4ee9b0e6936bdfcf, "test249b4ee9b0e6936bdfcf", passed, total);
+    RunGenEmitterTest(&Emitter::testdae669b09d29d1d05e81, "testdae669b09d29d1d05e81", passed, total);
+    RunGenEmitterTest(&Emitter::testa3645755a60c69fe8af4, "testa3645755a60c69fe8af4", passed, total);
+    RunGenEmitterTest(&Emitter::test5500c0af0cbb6a8efc04, "test5500c0af0cbb6a8efc04", passed, total);
+    RunGenEmitterTest(&Emitter::test6528fe35c2b993cbd28b, "test6528fe35c2b993cbd28b", passed, total);
+    RunGenEmitterTest(&Emitter::test072a41bf81e5b4dcd7d2, "test072a41bf81e5b4dcd7d2", passed, total);
+    RunGenEmitterTest(&Emitter::test3b47e24ba197ca8f686b, "test3b47e24ba197ca8f686b", passed, total);
+    RunGenEmitterTest(&Emitter::test938c1c274b5ebf36c6b2, "test938c1c274b5ebf36c6b2", passed, total);
+    RunGenEmitterTest(&Emitter::testeea818614d4fbef183a8, "testeea818614d4fbef183a8", passed, total);
+    RunGenEmitterTest(&Emitter::test18533eabe468baceac59, "test18533eabe468baceac59", passed, total);
+    RunGenEmitterTest(&Emitter::teste239cd01ef68ce26375d, "teste239cd01ef68ce26375d", passed, total);
+    RunGenEmitterTest(&Emitter::testd3a9b36f8218cd633402, "testd3a9b36f8218cd633402", passed, total);
+    RunGenEmitterTest(&Emitter::testa899f4512569981104e8, "testa899f4512569981104e8", passed, total);
+    RunGenEmitterTest(&Emitter::test230a8fd0d19c5e15963b, "test230a8fd0d19c5e15963b", passed, total);
+    RunGenEmitterTest(&Emitter::test4fa431a3bea1c616f8d0, "test4fa431a3bea1c616f8d0", passed, total);
+    RunGenEmitterTest(&Emitter::testdd05d8f0df4f1ba79b8f, "testdd05d8f0df4f1ba79b8f", passed, total);
+    RunGenEmitterTest(&Emitter::test0cb381d8a384434a2646, "test0cb381d8a384434a2646", passed, total);
+    RunGenEmitterTest(&Emitter::testeadefbe24693d510ac03, "testeadefbe24693d510ac03", passed, total);
+    RunGenEmitterTest(&Emitter::test0b43e898410a9da3db1a, "test0b43e898410a9da3db1a", passed, total);
+    RunGenEmitterTest(&Emitter::test450ed0f6d19326bab043, "test450ed0f6d19326bab043", passed, total);
+    RunGenEmitterTest(&Emitter::test38b7c3f09ffb6f4e73a5, "test38b7c3f09ffb6f4e73a5", passed, total);
+    RunGenEmitterTest(&Emitter::testab434195f62ee39997ae, "testab434195f62ee39997ae", passed, total);
+    RunGenEmitterTest(&Emitter::testdce4c351d6c426d24f14, "testdce4c351d6c426d24f14", passed, total);
+    RunGenEmitterTest(&Emitter::test2363249f46e86ae9bd64, "test2363249f46e86ae9bd64", passed, total);
+    RunGenEmitterTest(&Emitter::test6225a910ac0a5ce7304f, "test6225a910ac0a5ce7304f", passed, total);
+    RunGenEmitterTest(&Emitter::testf7898be54854e4587c54, "testf7898be54854e4587c54", passed, total);
+    RunGenEmitterTest(&Emitter::test1ab55f98773e2e58c659, "test1ab55f98773e2e58c659", passed, total);
+    RunGenEmitterTest(&Emitter::testf116d0bf1446d5e989db, "testf116d0bf1446d5e989db", passed, total);
+    RunGenEmitterTest(&Emitter::test90df709c20ab5305b5b0, "test90df709c20ab5305b5b0", passed, total);
+    RunGenEmitterTest(&Emitter::test37e041f7726819b98004, "test37e041f7726819b98004", passed, total);
+    RunGenEmitterTest(&Emitter::test5c13c8d0762eb77abbbe, "test5c13c8d0762eb77abbbe", passed, total);
+    RunGenEmitterTest(&Emitter::test3c9ec0009e080492d6a0, "test3c9ec0009e080492d6a0", passed, total);
+    RunGenEmitterTest(&Emitter::testd016b2610a9701c799be, "testd016b2610a9701c799be", passed, total);
+    RunGenEmitterTest(&Emitter::test12e858bf6ec981811cc8, "test12e858bf6ec981811cc8", passed, total);
+    RunGenEmitterTest(&Emitter::test0e09fd8b6ac12a309a36, "test0e09fd8b6ac12a309a36", passed, total);
+    RunGenEmitterTest(&Emitter::testca30dc12961feab24a33, "testca30dc12961feab24a33", passed, total);
+    RunGenEmitterTest(&Emitter::test162ca62af5cdf9d02507, "test162ca62af5cdf9d02507", passed, total);
+    RunGenEmitterTest(&Emitter::teste3a7658df7a81c1ce8e5, "teste3a7658df7a81c1ce8e5", passed, total);
+    RunGenEmitterTest(&Emitter::test9dac5e4f0e78f96fcaad, "test9dac5e4f0e78f96fcaad", passed, total);
+    RunGenEmitterTest(&Emitter::testaf2e952791b73c6bf78c, "testaf2e952791b73c6bf78c", passed, total);
+    RunGenEmitterTest(&Emitter::test82b161574e0926b9c854, "test82b161574e0926b9c854", passed, total);
+    RunGenEmitterTest(&Emitter::test13c3f29be0e6b7bc92b1, "test13c3f29be0e6b7bc92b1", passed, total);
+    RunGenEmitterTest(&Emitter::teste87c7e9ce16fd2ac5f0e, "teste87c7e9ce16fd2ac5f0e", passed, total);
+    RunGenEmitterTest(&Emitter::testeed7f7f244221932d32f, "testeed7f7f244221932d32f", passed, total);
+    RunGenEmitterTest(&Emitter::test31a5563bfa532571339f, "test31a5563bfa532571339f", passed, total);
+    RunGenEmitterTest(&Emitter::test502ab92aab5195ff4759, "test502ab92aab5195ff4759", passed, total);
+    RunGenEmitterTest(&Emitter::testdbe2ce5bc02435009b2c, "testdbe2ce5bc02435009b2c", passed, total);
+    RunGenEmitterTest(&Emitter::test06b8d2cc9bbb233d55d5, "test06b8d2cc9bbb233d55d5", passed, total);
+    RunGenEmitterTest(&Emitter::test9adf48ae5d6dff37e89a, "test9adf48ae5d6dff37e89a", passed, total);
+    RunGenEmitterTest(&Emitter::test398282871dcc1c7f8dbe, "test398282871dcc1c7f8dbe", passed, total);
+    RunGenEmitterTest(&Emitter::test2e2b3c35732210898be1, "test2e2b3c35732210898be1", passed, total);
+    RunGenEmitterTest(&Emitter::test155697ae715940b6d804, "test155697ae715940b6d804", passed, total);
+    RunGenEmitterTest(&Emitter::testb01c87881d846bb10ecd, "testb01c87881d846bb10ecd", passed, total);
+    RunGenEmitterTest(&Emitter::test84a9d3d2ae4eaacc9c98, "test84a9d3d2ae4eaacc9c98", passed, total);
+    RunGenEmitterTest(&Emitter::testb836cd5dc876cf6eb204, "testb836cd5dc876cf6eb204", passed, total);
+    RunGenEmitterTest(&Emitter::test4aa81dc715c5e5c53de1, "test4aa81dc715c5e5c53de1", passed, total);
+    RunGenEmitterTest(&Emitter::testfa8ba9d405de1af93537, "testfa8ba9d405de1af93537", passed, total);
+    RunGenEmitterTest(&Emitter::test3c07c460dae114d3f278, "test3c07c460dae114d3f278", passed, total);
+    RunGenEmitterTest(&Emitter::testf513330011b92283e713, "testf513330011b92283e713", passed, total);
+    RunGenEmitterTest(&Emitter::test88667a8fe856748b4dc6, "test88667a8fe856748b4dc6", passed, total);
+    RunGenEmitterTest(&Emitter::test7cbc7ae88a6b60d3cb54, "test7cbc7ae88a6b60d3cb54", passed, total);
+    RunGenEmitterTest(&Emitter::test8b126d00ee878273f3e9, "test8b126d00ee878273f3e9", passed, total);
+    RunGenEmitterTest(&Emitter::test414dcec883b2fb2668d9, "test414dcec883b2fb2668d9", passed, total);
+    RunGenEmitterTest(&Emitter::test41754fe2ab40560f1afe, "test41754fe2ab40560f1afe", passed, total);
+    RunGenEmitterTest(&Emitter::test39b7a9ee0ccb5580ef60, "test39b7a9ee0ccb5580ef60", passed, total);
+    RunGenEmitterTest(&Emitter::test1f4cbfdb2f53d041fb74, "test1f4cbfdb2f53d041fb74", passed, total);
+    RunGenEmitterTest(&Emitter::testc20612e8922a8eeba24d, "testc20612e8922a8eeba24d", passed, total);
+    RunGenEmitterTest(&Emitter::test693f48133cf726f1e05c, "test693f48133cf726f1e05c", passed, total);
+    RunGenEmitterTest(&Emitter::test12b26bfed7a24736dd8b, "test12b26bfed7a24736dd8b", passed, total);
+    RunGenEmitterTest(&Emitter::test41d6ec7f045897841e9c, "test41d6ec7f045897841e9c", passed, total);
+    RunGenEmitterTest(&Emitter::test2bc8d1d6e4ec042ede3e, "test2bc8d1d6e4ec042ede3e", passed, total);
+    RunGenEmitterTest(&Emitter::test647ff876c844ad7540ff, "test647ff876c844ad7540ff", passed, total);
+    RunGenEmitterTest(&Emitter::test844c1bcb896dde8ea51b, "test844c1bcb896dde8ea51b", passed, total);
+    RunGenEmitterTest(&Emitter::testbcf04a5174e8505d1891, "testbcf04a5174e8505d1891", passed, total);
+    RunGenEmitterTest(&Emitter::testdb6c8ca130035d7a271f, "testdb6c8ca130035d7a271f", passed, total);
+    RunGenEmitterTest(&Emitter::testa0db96f3d93a255f2201, "testa0db96f3d93a255f2201", passed, total);
+    RunGenEmitterTest(&Emitter::test4fb3eaac714942122715, "test4fb3eaac714942122715", passed, total);
+    RunGenEmitterTest(&Emitter::test634678f31daa20127d6c, "test634678f31daa20127d6c", passed, total);
+    RunGenEmitterTest(&Emitter::test1dd395a1149e46dcc208, "test1dd395a1149e46dcc208", passed, total);
+    RunGenEmitterTest(&Emitter::testebc585cbde90d10a0af1, "testebc585cbde90d10a0af1", passed, total);
+    RunGenEmitterTest(&Emitter::testd1ecec189e73f8932485, "testd1ecec189e73f8932485", passed, total);
+    RunGenEmitterTest(&Emitter::testf8fc72597f0a41b22daa, "testf8fc72597f0a41b22daa", passed, total);
+    RunGenEmitterTest(&Emitter::testd01959c5c228946c8759, "testd01959c5c228946c8759", passed, total);
+    RunGenEmitterTest(&Emitter::teste8236a9672d9244ca486, "teste8236a9672d9244ca486", passed, total);
+    RunGenEmitterTest(&Emitter::test22bd5d24dbd3f0670f97, "test22bd5d24dbd3f0670f97", passed, total);
+    RunGenEmitterTest(&Emitter::test0f2c6cac0ce0e624eb08, "test0f2c6cac0ce0e624eb08", passed, total);
+    RunGenEmitterTest(&Emitter::test2ed2eef7f03696ca3c94, "test2ed2eef7f03696ca3c94", passed, total);
+    RunGenEmitterTest(&Emitter::test6fe33177e10d14328a14, "test6fe33177e10d14328a14", passed, total);
+    RunGenEmitterTest(&Emitter::test0ea79e93c3439d90bdb8, "test0ea79e93c3439d90bdb8", passed, total);
+    RunGenEmitterTest(&Emitter::test2ab970621d7e037153c9, "test2ab970621d7e037153c9", passed, total);
+    RunGenEmitterTest(&Emitter::test4229059ec3d639faf4b2, "test4229059ec3d639faf4b2", passed, total);
+    RunGenEmitterTest(&Emitter::test6df809b4712b73c8577f, "test6df809b4712b73c8577f", passed, total);
+    RunGenEmitterTest(&Emitter::test37a0a34b2bef743d8241, "test37a0a34b2bef743d8241", passed, total);
+    RunGenEmitterTest(&Emitter::testd6c37c1e50617419a37d, "testd6c37c1e50617419a37d", passed, total);
+    RunGenEmitterTest(&Emitter::test2fb71689fb176533159c, "test2fb71689fb176533159c", passed, total);
+    RunGenEmitterTest(&Emitter::testa91d7999dd9b43fb5827, "testa91d7999dd9b43fb5827", passed, total);
+    RunGenEmitterTest(&Emitter::test8dfd4533e2891d3861ec, "test8dfd4533e2891d3861ec", passed, total);
+    RunGenEmitterTest(&Emitter::test0a9b0c29dfcf4f071eb9, "test0a9b0c29dfcf4f071eb9", passed, total);
+    RunGenEmitterTest(&Emitter::test3882a796318e573b115d, "test3882a796318e573b115d", passed, total);
+    RunGenEmitterTest(&Emitter::test1ade39a1572a12eda7b8, "test1ade39a1572a12eda7b8", passed, total);
+    RunGenEmitterTest(&Emitter::testd308c7e19671725523cd, "testd308c7e19671725523cd", passed, total);
+    RunGenEmitterTest(&Emitter::test1ac58dc569ce7b4eebdf, "test1ac58dc569ce7b4eebdf", passed, total);
+    RunGenEmitterTest(&Emitter::test5fe4c34b163d0efa12d5, "test5fe4c34b163d0efa12d5", passed, total);
+    RunGenEmitterTest(&Emitter::test78433ff7edf3224ce58b, "test78433ff7edf3224ce58b", passed, total);
+    RunGenEmitterTest(&Emitter::test089ed50cafddf39653d6, "test089ed50cafddf39653d6", passed, total);
+    RunGenEmitterTest(&Emitter::test809723ec7bdea45cf562, "test809723ec7bdea45cf562", passed, total);
+    RunGenEmitterTest(&Emitter::test953cf821d2acc7898582, "test953cf821d2acc7898582", passed, total);
+    RunGenEmitterTest(&Emitter::test0f1db947e4627596eace, "test0f1db947e4627596eace", passed, total);
+    RunGenEmitterTest(&Emitter::test52f3b0674f30d955eea7, "test52f3b0674f30d955eea7", passed, total);
+    RunGenEmitterTest(&Emitter::testf95a488631e07f6ca914, "testf95a488631e07f6ca914", passed, total);
+    RunGenEmitterTest(&Emitter::test9b7a916f4c1e2a1ae6ee, "test9b7a916f4c1e2a1ae6ee", passed, total);
+    RunGenEmitterTest(&Emitter::test54ea34948e814ef79607, "test54ea34948e814ef79607", passed, total);
+    RunGenEmitterTest(&Emitter::testcef62af7508e0a1e3ee3, "testcef62af7508e0a1e3ee3", passed, total);
+    RunGenEmitterTest(&Emitter::testffcfb27f0c904fae7833, "testffcfb27f0c904fae7833", passed, total);
+    RunGenEmitterTest(&Emitter::test31ed1460205bbc5a4a68, "test31ed1460205bbc5a4a68", passed, total);
+    RunGenEmitterTest(&Emitter::test7d04c8d923b046159db0, "test7d04c8d923b046159db0", passed, total);
+    RunGenEmitterTest(&Emitter::test31b396851023614cf9fd, "test31b396851023614cf9fd", passed, total);
+    RunGenEmitterTest(&Emitter::test5befd800aa07d83e2df7, "test5befd800aa07d83e2df7", passed, total);
+    RunGenEmitterTest(&Emitter::test2df4f378f687fd80b98c, "test2df4f378f687fd80b98c", passed, total);
+    RunGenEmitterTest(&Emitter::test232f5aa6ea7e85e186c4, "test232f5aa6ea7e85e186c4", passed, total);
+    RunGenEmitterTest(&Emitter::test011421ad7da175099088, "test011421ad7da175099088", passed, total);
+    RunGenEmitterTest(&Emitter::testf50217feca0ae03a0b03, "testf50217feca0ae03a0b03", passed, total);
+    RunGenEmitterTest(&Emitter::teste4b49044063dd3c8a7ff, "teste4b49044063dd3c8a7ff", passed, total);
+    RunGenEmitterTest(&Emitter::testbe9295522ec1f0bc9de5, "testbe9295522ec1f0bc9de5", passed, total);
+    RunGenEmitterTest(&Emitter::test7a18055f1e3a49f93d40, "test7a18055f1e3a49f93d40", passed, total);
+    RunGenEmitterTest(&Emitter::testd8eebabad65b8ef02375, "testd8eebabad65b8ef02375", passed, total);
+    RunGenEmitterTest(&Emitter::test948f36e3182f3c1aa800, "test948f36e3182f3c1aa800", passed, total);
+    RunGenEmitterTest(&Emitter::testde02b69600e5931c39ab, "testde02b69600e5931c39ab", passed, total);
+    RunGenEmitterTest(&Emitter::test5fdab21609e7017c3b86, "test5fdab21609e7017c3b86", passed, total);
+    RunGenEmitterTest(&Emitter::testfb52965f57b912ec23a4, "testfb52965f57b912ec23a4", passed, total);
+    RunGenEmitterTest(&Emitter::testa3f220ead85b78154f89, "testa3f220ead85b78154f89", passed, total);
+    RunGenEmitterTest(&Emitter::test0ef1b1c26e8a1fa34ccd, "test0ef1b1c26e8a1fa34ccd", passed, total);
+    RunGenEmitterTest(&Emitter::test7661db62a921285da885, "test7661db62a921285da885", passed, total);
+    RunGenEmitterTest(&Emitter::test9382f466be3e19ca395f, "test9382f466be3e19ca395f", passed, total);
+    RunGenEmitterTest(&Emitter::test33c4f45355dc7df2e2a8, "test33c4f45355dc7df2e2a8", passed, total);
+    RunGenEmitterTest(&Emitter::testc55c40f32c34c890acce, "testc55c40f32c34c890acce", passed, total);
+    RunGenEmitterTest(&Emitter::testb06ba64c5895f218175d, "testb06ba64c5895f218175d", passed, total);
+    RunGenEmitterTest(&Emitter::test14adb5374833871b2d0c, "test14adb5374833871b2d0c", passed, total);
+    RunGenEmitterTest(&Emitter::test7ff7826c0f0563ce5a65, "test7ff7826c0f0563ce5a65", passed, total);
+    RunGenEmitterTest(&Emitter::test394e607327447b08e729, "test394e607327447b08e729", passed, total);
+    RunGenEmitterTest(&Emitter::testdf03e1437e901976c2c8, "testdf03e1437e901976c2c8", passed, total);
+    RunGenEmitterTest(&Emitter::test77467fcda467dd063050, "test77467fcda467dd063050", passed, total);
+    RunGenEmitterTest(&Emitter::test5bcea73651331a2357d0, "test5bcea73651331a2357d0", passed, total);
+    RunGenEmitterTest(&Emitter::test2956b3f097a16a4cd951, "test2956b3f097a16a4cd951", passed, total);
+    RunGenEmitterTest(&Emitter::test3170422d0cad24cd602a, "test3170422d0cad24cd602a", passed, total);
+    RunGenEmitterTest(&Emitter::testb37f0cd80f138e8f2622, "testb37f0cd80f138e8f2622", passed, total);
+    RunGenEmitterTest(&Emitter::test3e00cce71da4636fa1f7, "test3e00cce71da4636fa1f7", passed, total);
+    RunGenEmitterTest(&Emitter::testfd184c04759685f21abb, "testfd184c04759685f21abb", passed, total);
+    RunGenEmitterTest(&Emitter::test14ab4965eff0a569da16, "test14ab4965eff0a569da16", passed, total);
+    RunGenEmitterTest(&Emitter::test271811f2df7210366780, "test271811f2df7210366780", passed, total);
+    RunGenEmitterTest(&Emitter::testfcfe8657dffc21f6cd45, "testfcfe8657dffc21f6cd45", passed, total);
+    RunGenEmitterTest(&Emitter::test609e44eab4ab95f31e33, "test609e44eab4ab95f31e33", passed, total);
+    RunGenEmitterTest(&Emitter::test7841fc715275a45a2770, "test7841fc715275a45a2770", passed, total);
+    RunGenEmitterTest(&Emitter::test662c03de87ca40bd943e, "test662c03de87ca40bd943e", passed, total);
+    RunGenEmitterTest(&Emitter::test0a9475ec3c946fe11991, "test0a9475ec3c946fe11991", passed, total);
+    RunGenEmitterTest(&Emitter::test94d28ebdbee90f430eb1, "test94d28ebdbee90f430eb1", passed, total);
+    RunGenEmitterTest(&Emitter::testd5035afc82e23b67ce03, "testd5035afc82e23b67ce03", passed, total);
+    RunGenEmitterTest(&Emitter::testcc9788c342da4454758f, "testcc9788c342da4454758f", passed, total);
+    RunGenEmitterTest(&Emitter::test140974453293fdb1155d, "test140974453293fdb1155d", passed, total);
+    RunGenEmitterTest(&Emitter::testdc0b80a131730e98d735, "testdc0b80a131730e98d735", passed, total);
+    RunGenEmitterTest(&Emitter::test1c5225b07d746c2bd331, "test1c5225b07d746c2bd331", passed, total);
+    RunGenEmitterTest(&Emitter::testa49a0be204cd2b57f17b, "testa49a0be204cd2b57f17b", passed, total);
+    RunGenEmitterTest(&Emitter::testbe08cc0a08cf2cb5e7ec, "testbe08cc0a08cf2cb5e7ec", passed, total);
+    RunGenEmitterTest(&Emitter::test4d2a2e12689655edd77c, "test4d2a2e12689655edd77c", passed, total);
+    RunGenEmitterTest(&Emitter::test4d4a25a54401f0282ceb, "test4d4a25a54401f0282ceb", passed, total);
+    RunGenEmitterTest(&Emitter::test91f55feebb012ce89a93, "test91f55feebb012ce89a93", passed, total);
+    RunGenEmitterTest(&Emitter::test1f3d0b19c6a346b087e0, "test1f3d0b19c6a346b087e0", passed, total);
+    RunGenEmitterTest(&Emitter::test4e26682c2daf8ded04a6, "test4e26682c2daf8ded04a6", passed, total);
+    RunGenEmitterTest(&Emitter::test6f24e6df03922bba0d8a, "test6f24e6df03922bba0d8a", passed, total);
+    RunGenEmitterTest(&Emitter::test60849eca7dc178908ff1, "test60849eca7dc178908ff1", passed, total);
+    RunGenEmitterTest(&Emitter::test28b7db2ac68bb806e143, "test28b7db2ac68bb806e143", passed, total);
+    RunGenEmitterTest(&Emitter::test8db156db7065942bc260, "test8db156db7065942bc260", passed, total);
+    RunGenEmitterTest(&Emitter::teste240aced6e2292a9b091, "teste240aced6e2292a9b091", passed, total);
+    RunGenEmitterTest(&Emitter::test468628a845426ce4a106, "test468628a845426ce4a106", passed, total);
+    RunGenEmitterTest(&Emitter::testa3a2d467766b74acd6fd, "testa3a2d467766b74acd6fd", passed, total);
+    RunGenEmitterTest(&Emitter::test5bf63d8ed606d688d869, "test5bf63d8ed606d688d869", passed, total);
+    RunGenEmitterTest(&Emitter::test0d35c1487237ba7d8bdc, "test0d35c1487237ba7d8bdc", passed, total);
+    RunGenEmitterTest(&Emitter::testb1fddc2897760d60e733, "testb1fddc2897760d60e733", passed, total);
+    RunGenEmitterTest(&Emitter::testbaf845554a46f088bf71, "testbaf845554a46f088bf71", passed, total);
+    RunGenEmitterTest(&Emitter::test6383f28d62ad9ce3c075, "test6383f28d62ad9ce3c075", passed, total);
+    RunGenEmitterTest(&Emitter::test88a4c1cc11b99a61eccd, "test88a4c1cc11b99a61eccd", passed, total);
+    RunGenEmitterTest(&Emitter::test4716a2cf58a70705987b, "test4716a2cf58a70705987b", passed, total);
+    RunGenEmitterTest(&Emitter::test75222084929bd0f9d38f, "test75222084929bd0f9d38f", passed, total);
+    RunGenEmitterTest(&Emitter::test2fb23c79eec625216523, "test2fb23c79eec625216523", passed, total);
+    RunGenEmitterTest(&Emitter::testb1699a6b7c5ded480677, "testb1699a6b7c5ded480677", passed, total);
+    RunGenEmitterTest(&Emitter::testd7de744a20ca1dc099db, "testd7de744a20ca1dc099db", passed, total);
+    RunGenEmitterTest(&Emitter::test900b2dcf20981b44ea65, "test900b2dcf20981b44ea65", passed, total);
+    RunGenEmitterTest(&Emitter::test20cc330b6d1171584aed, "test20cc330b6d1171584aed", passed, total);
+    RunGenEmitterTest(&Emitter::test5ea8e3642fab864fb09d, "test5ea8e3642fab864fb09d", passed, total);
+    RunGenEmitterTest(&Emitter::test42e21cbc65f534972ead, "test42e21cbc65f534972ead", passed, total);
+    RunGenEmitterTest(&Emitter::test14e3b5dca1d7a5a0c957, "test14e3b5dca1d7a5a0c957", passed, total);
+    RunGenEmitterTest(&Emitter::test9bd4800a58394b172738, "test9bd4800a58394b172738", passed, total);
+    RunGenEmitterTest(&Emitter::testb715a2b66987a872ced8, "testb715a2b66987a872ced8", passed, total);
+    RunGenEmitterTest(&Emitter::teste9b56880009cc6899131, "teste9b56880009cc6899131", passed, total);
+    RunGenEmitterTest(&Emitter::test21f96f767e38471c9d4d, "test21f96f767e38471c9d4d", passed, total);
+    RunGenEmitterTest(&Emitter::testa8aebba05fc1858c0a6c, "testa8aebba05fc1858c0a6c", passed, total);
+    RunGenEmitterTest(&Emitter::teste6e7442377049b17ee9e, "teste6e7442377049b17ee9e", passed, total);
+    RunGenEmitterTest(&Emitter::test428b593e283163fee752, "test428b593e283163fee752", passed, total);
+    RunGenEmitterTest(&Emitter::test0b6c63323da4bf9798c2, "test0b6c63323da4bf9798c2", passed, total);
+    RunGenEmitterTest(&Emitter::test0f4c45c39fe39dfc8a1d, "test0f4c45c39fe39dfc8a1d", passed, total);
+    RunGenEmitterTest(&Emitter::testb8043a7ae1de42dd81db, "testb8043a7ae1de42dd81db", passed, total);
+    RunGenEmitterTest(&Emitter::test4d9b278579ffb76fc56d, "test4d9b278579ffb76fc56d", passed, total);
+    RunGenEmitterTest(&Emitter::test672fc8b6d281f82b9332, "test672fc8b6d281f82b9332", passed, total);
+    RunGenEmitterTest(&Emitter::testb406d378fa0df952b051, "testb406d378fa0df952b051", passed, total);
+    RunGenEmitterTest(&Emitter::test68a227d03f20863f37e4, "test68a227d03f20863f37e4", passed, total);
+    RunGenEmitterTest(&Emitter::testcee8582fd340377bda46, "testcee8582fd340377bda46", passed, total);
+    RunGenEmitterTest(&Emitter::test06fd48e8c86baf6fc05b, "test06fd48e8c86baf6fc05b", passed, total);
+    RunGenEmitterTest(&Emitter::test70b4ccbf71c0716bf8e4, "test70b4ccbf71c0716bf8e4", passed, total);
+    RunGenEmitterTest(&Emitter::test449c2b349be8da36682b, "test449c2b349be8da36682b", passed, total);
+    RunGenEmitterTest(&Emitter::test9620fa69718e3b4fe391, "test9620fa69718e3b4fe391", passed, total);
+    RunGenEmitterTest(&Emitter::test3faaebe701bea6f8ee39, "test3faaebe701bea6f8ee39", passed, total);
+    RunGenEmitterTest(&Emitter::test763ee61808091c7a354d, "test763ee61808091c7a354d", passed, total);
+    RunGenEmitterTest(&Emitter::test81b0d6b575228cde91e5, "test81b0d6b575228cde91e5", passed, total);
+    RunGenEmitterTest(&Emitter::testb607ae3c5d560092e37b, "testb607ae3c5d560092e37b", passed, total);
+    RunGenEmitterTest(&Emitter::testa53c54726737df14a5dd, "testa53c54726737df14a5dd", passed, total);
+    RunGenEmitterTest(&Emitter::test071d73b309a1365e0b07, "test071d73b309a1365e0b07", passed, total);
+    RunGenEmitterTest(&Emitter::testf8f45511528fa28cddcb, "testf8f45511528fa28cddcb", passed, total);
+    RunGenEmitterTest(&Emitter::testabdd2bf3bdf550e3dd60, "testabdd2bf3bdf550e3dd60", passed, total);
+    RunGenEmitterTest(&Emitter::test53424b35498a73fbede9, "test53424b35498a73fbede9", passed, total);
+    RunGenEmitterTest(&Emitter::testf0c6c1a1afced157d6a5, "testf0c6c1a1afced157d6a5", passed, total);
+    RunGenEmitterTest(&Emitter::teste45dbac33918e0fee74f, "teste45dbac33918e0fee74f", passed, total);
+    RunGenEmitterTest(&Emitter::test903c7ab3d09d4323107f, "test903c7ab3d09d4323107f", passed, total);
+    RunGenEmitterTest(&Emitter::test5d39d351680dba4be04b, "test5d39d351680dba4be04b", passed, total);
+    RunGenEmitterTest(&Emitter::testaa1e8d6d4385aab47bcd, "testaa1e8d6d4385aab47bcd", passed, total);
+    RunGenEmitterTest(&Emitter::test9bd238b748ced1db588b, "test9bd238b748ced1db588b", passed, total);
+    RunGenEmitterTest(&Emitter::testec1cdffaae8842854947, "testec1cdffaae8842854947", passed, total);
+    RunGenEmitterTest(&Emitter::test30727d97de63c1ad395a, "test30727d97de63c1ad395a", passed, total);
+    RunGenEmitterTest(&Emitter::test7adafdc8be65a5d610bf, "test7adafdc8be65a5d610bf", passed, total);
+#else // YAML_GEN_TESTS
+   (void)passed; (void)total;
+#endif // YAML_GEN_TESTS
+}
diff --git a/test/handlermacros.h b/test/handlermacros.h
new file mode 100644 (file)
index 0000000..db2019c
--- /dev/null
@@ -0,0 +1,190 @@
+#include "teststruct.h"
+#pragma once
+
+#include "yaml-cpp/yaml.h"
+#include "yaml-cpp/eventhandler.h"
+#include <string>
+#include <cassert>
+
+namespace Test {
+    inline std::string Quote(const std::string& text) {
+        YAML::Emitter out;
+        out << YAML::DoubleQuoted << text;
+        return out.c_str();
+    }
+    
+    struct Event {
+        enum Type { DocStart, DocEnd, Null, Alias, Scalar, SeqStart, SeqEnd, MapStart, MapEnd };
+        
+        typedef YAML::Mark Mark;
+        typedef YAML::anchor_t anchor_t;
+        
+        Event(Type type_, const std::string& tag_, anchor_t anchor_, const std::string& scalar_): type(type_), tag(tag_), anchor(anchor_), scalar(scalar_) {}
+        
+        Type type;
+        std::string tag;
+        anchor_t anchor;
+        std::string scalar;
+        
+        std::ostream& write(std::ostream& out) const {
+            switch(type) {
+                case DocStart:
+                    return out << "DocStart";
+                case DocEnd:
+                    return out << "DocEnd";
+                case Null:
+                    return out << "Null(" << anchor << ")";
+                case Alias:
+                    return out << "Alias(" << anchor << ")";
+                case Scalar:
+                    return out << "Scalar(" << Quote(tag) << ", " << anchor << ", " << Quote(scalar) << ")";
+                case SeqStart:
+                    return out << "SeqStart(" << Quote(tag) << ", " << anchor << ")";
+                case SeqEnd:
+                    return out << "SeqEnd";
+                case MapStart:
+                    return out << "MapStart(" << Quote(tag) << ", " << anchor << ")";
+                case MapEnd:
+                    return out << "MapEnd";
+            }
+            assert(false);
+            return out;
+        }
+    };
+    
+    inline std::ostream& operator << (std::ostream& out, const Event& event) {
+        return event.write(out);
+    }
+    
+    inline bool operator == (const Event& a, const Event& b) {
+        return a.type == b.type && a.tag == b.tag && a.anchor == b.anchor && a.scalar == b.scalar;
+    }
+    
+    inline bool operator != (const Event& a, const Event& b) {
+        return !(a == b);
+    }
+    
+       class MockEventHandler: public YAML::EventHandler
+       {
+       public:
+        typedef YAML::Mark Mark;
+        typedef YAML::anchor_t anchor_t;
+        
+        MockEventHandler() {}
+        
+               virtual void OnDocumentStart(const Mark&) {
+            m_actualEvents.push_back(Event(Event::DocStart, "", 0, ""));
+        }
+        
+               virtual void OnDocumentEnd() {
+            m_actualEvents.push_back(Event(Event::DocEnd, "", 0, ""));
+        }
+               
+               virtual void OnNull(const Mark&, anchor_t anchor) {
+            m_actualEvents.push_back(Event(Event::Null, "", anchor, ""));
+        }
+        
+               virtual void OnAlias(const Mark&, anchor_t anchor) {
+            m_actualEvents.push_back(Event(Event::Alias, "", anchor, ""));
+        }
+        
+               virtual void OnScalar(const Mark&, const std::string& tag, anchor_t anchor, const std::string& value) {
+            m_actualEvents.push_back(Event(Event::Scalar, tag, anchor, value));
+        }
+        
+               virtual void OnSequenceStart(const Mark&, const std::string& tag, anchor_t anchor) {
+            m_actualEvents.push_back(Event(Event::SeqStart, tag, anchor, ""));
+        }
+        
+               virtual void OnSequenceEnd() {
+            m_actualEvents.push_back(Event(Event::SeqEnd, "", 0, ""));
+        }
+        
+               virtual void OnMapStart(const Mark&, const std::string& tag, anchor_t anchor) {
+            m_actualEvents.push_back(Event(Event::MapStart, tag, anchor, ""));
+        }
+        
+               virtual void OnMapEnd() {
+            m_actualEvents.push_back(Event(Event::MapEnd, "", 0, ""));
+        }
+        
+        void Expect(const Event& event) { m_expectedEvents.push_back(event); }
+        
+        Test::TEST Check() const {
+            std::size_t N = std::max(m_expectedEvents.size(), m_actualEvents.size());
+            for(std::size_t i=0;i<N;i++) {
+                if(i >= m_expectedEvents.size()) {
+                    std::stringstream out;
+                    for(std::size_t j=0;j<i;j++) {
+                        out << "  " << m_expectedEvents[j] << "\n";
+                    }
+                    out << "  EXPECTED: (no event expected)\n";
+                    out << "  ACTUAL  : " << m_actualEvents[i] << "\n";
+                    return out.str().c_str();
+                }
+                
+                if(i >= m_actualEvents.size()) {
+                    std::stringstream out;
+                    for(std::size_t j=0;j<i;j++) {
+                        out << "  " << m_expectedEvents[j] << "\n";
+                    }
+                    out << "  EXPECTED: " << m_expectedEvents[i] << "\n";
+                    out << "  ACTUAL  : (no event recorded)\n";
+                    return out.str().c_str();
+                }
+                
+                if(m_expectedEvents[i] != m_actualEvents[i]) {
+                    std::stringstream out;
+                    for(std::size_t j=0;j<i;j++) {
+                        out << "  " <<  m_expectedEvents[j] << "\n";
+                    }
+                    out << "  EXPECTED: " << m_expectedEvents[i] << "\n";
+                    out << "  ACTUAL  : " << m_actualEvents[i] << "\n";
+                    return out.str().c_str();
+                }
+            }
+            
+            return true;
+        }
+        
+        std::vector<Event> m_expectedEvents;
+        std::vector<Event> m_actualEvents;
+       };
+    
+#define HANDLE(ex)\
+MockEventHandler handler;\
+std::stringstream stream(ex);\
+YAML::Parser parser(stream);\
+while(parser.HandleNextDocument(handler)) {}
+
+#define EXPECT_DOC_START()\
+handler.Expect(Event(Event::DocStart, "", 0, ""))
+    
+#define EXPECT_DOC_END()\
+handler.Expect(Event(Event::DocEnd, "", 0, ""))
+    
+#define EXPECT_NULL(anchor)\
+handler.Expect(Event(Event::Null, "", anchor, ""))
+    
+#define EXPECT_ALIAS(anchor)\
+handler.Expect(Event(Event::Alias, "", anchor, ""))
+    
+#define EXPECT_SCALAR(tag, anchor, value)\
+handler.Expect(Event(Event::Scalar, tag, anchor, value))
+    
+#define EXPECT_SEQ_START(tag, anchor)\
+handler.Expect(Event(Event::SeqStart, tag, anchor, ""))
+    
+#define EXPECT_SEQ_END()\
+handler.Expect(Event(Event::SeqEnd, "", 0, ""))
+    
+#define EXPECT_MAP_START(tag, anchor)\
+handler.Expect(Event(Event::MapStart, tag, anchor, ""))
+    
+#define EXPECT_MAP_END()\
+handler.Expect(Event(Event::MapEnd, "", 0, ""))
+    
+#define DONE()\
+return handler.Check()
+    
+}
diff --git a/test/main.cpp b/test/main.cpp
new file mode 100644 (file)
index 0000000..64c69f1
--- /dev/null
@@ -0,0 +1,7 @@
+#include "tests.h"
+
+int main()
+{
+       Test::RunAll();
+       return 0;
+}
diff --git a/test/new-api/nodetests.cpp b/test/new-api/nodetests.cpp
new file mode 100644 (file)
index 0000000..e1140f8
--- /dev/null
@@ -0,0 +1,576 @@
+#include "nodetests.h"
+#include "yaml-cpp/yaml.h"
+#include <boost/foreach.hpp>
+#include <iostream>
+
+namespace {
+       struct TEST {
+               TEST(): ok(false) {}
+               TEST(bool ok_): ok(ok_) {}
+               TEST(const char *error_): ok(false), error(error_) {}
+        TEST(const std::string& error_): ok(false), error(error_) {}
+               
+               bool ok;
+               std::string error;
+       };
+}
+
+#define YAML_ASSERT(cond)\
+    do {\
+        if(!(cond))\
+            return "  Assert failed: " #cond;\
+    } while(false)
+
+#define YAML_ASSERT_THROWS(cond, exc)\
+    do {\
+        try {\
+            (cond);\
+            return "  Expression did not throw: " #cond;\
+        } catch(const exc&) {\
+        } catch(const std::runtime_error& e) {\
+            std::stringstream stream;\
+            stream << "  Expression threw runtime error ther than " #exc ":\n    " #cond "\n    " << e.what();\
+            return stream.str();\
+        } catch(...) {\
+            return "  Expression threw unknown exception, other than " #exc ":\n    " #cond;\
+        }\
+    } while(false)
+
+namespace Test
+{
+       namespace Node
+       {
+               TEST SimpleScalar()
+               {
+                       YAML::Node node = YAML::Node("Hello, World!");
+                       YAML_ASSERT(node.IsScalar());
+                       YAML_ASSERT(node.as<std::string>() == "Hello, World!");
+                       return true;
+               }
+               
+               TEST IntScalar()
+               {
+                       YAML::Node node = YAML::Node(15);
+                       YAML_ASSERT(node.IsScalar());
+                       YAML_ASSERT(node.as<int>() == 15);
+                       return true;
+               }
+
+               TEST SimpleAppendSequence()
+               {
+                       YAML::Node node;
+                       node.push_back(10);
+                       node.push_back("foo");
+                       node.push_back("monkey");
+                       YAML_ASSERT(node.IsSequence());
+                       YAML_ASSERT(node.size() == 3);
+                       YAML_ASSERT(node[0].as<int>() == 10);
+                       YAML_ASSERT(node[1].as<std::string>() == "foo");
+                       YAML_ASSERT(node[2].as<std::string>() == "monkey");
+                       YAML_ASSERT(node.IsSequence());
+                       return true;
+               }
+
+               TEST SimpleAssignSequence()
+               {
+                       YAML::Node node;
+                       node[0] = 10;
+                       node[1] = "foo";
+                       node[2] = "monkey";
+                       YAML_ASSERT(node.IsSequence());
+                       YAML_ASSERT(node.size() == 3);
+                       YAML_ASSERT(node[0].as<int>() == 10);
+                       YAML_ASSERT(node[1].as<std::string>() == "foo");
+                       YAML_ASSERT(node[2].as<std::string>() == "monkey");
+                       YAML_ASSERT(node.IsSequence());
+                       return true;
+               }
+
+               TEST SimpleMap()
+               {
+                       YAML::Node node;
+                       node["key"] = "value";
+                       YAML_ASSERT(node.IsMap());
+                       YAML_ASSERT(node["key"].as<std::string>() == "value");
+                       YAML_ASSERT(node.size() == 1);
+                       return true;
+               }
+
+               TEST MapWithUndefinedValues()
+               {
+                       YAML::Node node;
+                       node["key"] = "value";
+                       node["undefined"];
+                       YAML_ASSERT(node.IsMap());
+                       YAML_ASSERT(node["key"].as<std::string>() == "value");
+                       YAML_ASSERT(node.size() == 1);
+
+                       node["undefined"] = "monkey";
+                       YAML_ASSERT(node["undefined"].as<std::string>() == "monkey");
+                       YAML_ASSERT(node.size() == 2);
+                       
+                       return true;
+               }
+               
+               TEST MapIteratorWithUndefinedValues()
+               {
+                       YAML::Node node;
+                       node["key"] = "value";
+                       node["undefined"];
+                       
+                       std::size_t count = 0;
+                       for(YAML::const_iterator it=node.begin();it!=node.end();++it)
+                               count++;
+                       YAML_ASSERT(count == 1);
+                       return true;
+               }
+               
+               TEST SimpleSubkeys()
+               {
+                       YAML::Node node;
+                       node["device"]["udid"] = "12345";
+                       node["device"]["name"] = "iPhone";
+                       node["device"]["os"] = "4.0";
+                       node["username"] = "monkey";
+                       YAML_ASSERT(node["device"]["udid"].as<std::string>() == "12345");
+                       YAML_ASSERT(node["device"]["name"].as<std::string>() == "iPhone");
+                       YAML_ASSERT(node["device"]["os"].as<std::string>() == "4.0");
+                       YAML_ASSERT(node["username"].as<std::string>() == "monkey");
+                       return true;
+               }
+               
+               TEST StdVector()
+               {
+                       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);
+                       
+                       YAML::Node node;
+                       node["primes"] = primes;
+                       YAML_ASSERT(node["primes"].as<std::vector<int> >() == primes);
+                       return true;
+               }
+
+               TEST StdList()
+               {
+                       std::list<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);
+                       
+                       YAML::Node node;
+                       node["primes"] = primes;
+                       YAML_ASSERT(node["primes"].as<std::list<int> >() == primes);
+                       return true;
+               }
+
+               TEST StdMap()
+               {
+                       std::map<int, int> squares;
+                       squares[0] = 0;
+                       squares[1] = 1;
+                       squares[2] = 4;
+                       squares[3] = 9;
+                       squares[4] = 16;
+                       
+                       YAML::Node node;
+                       node["squares"] = squares;
+                       YAML_ASSERT((node["squares"].as<std::map<int, int> >() == squares));
+                       return true;
+               }
+               
+               TEST StdPair()
+               {
+                       std::pair<int, std::string> p;
+            p.first = 5;
+            p.second = "five";
+                       
+                       YAML::Node node;
+                       node["pair"] = p;
+                       YAML_ASSERT((node["pair"].as<std::pair<int, std::string> >() == p));
+                       return true;
+               }
+
+        TEST SimpleAlias()
+               {
+                       YAML::Node node;
+                       node["foo"] = "value";
+                       node["bar"] = node["foo"];
+                       YAML_ASSERT(node["foo"].as<std::string>() == "value");
+                       YAML_ASSERT(node["bar"].as<std::string>() == "value");
+                       YAML_ASSERT(node["foo"] == node["bar"]);
+                       YAML_ASSERT(node.size() == 2);
+                       return true;
+               }
+
+               TEST AliasAsKey()
+               {
+                       YAML::Node node;
+                       node["foo"] = "value";
+                       YAML::Node value = node["foo"];
+                       node[value] = "foo";
+                       YAML_ASSERT(node["foo"].as<std::string>() == "value");
+                       YAML_ASSERT(node[value].as<std::string>() == "foo");
+                       YAML_ASSERT(node["value"].as<std::string>() == "foo");
+                       YAML_ASSERT(node.size() == 2);
+                       return true;
+               }
+               
+               TEST SelfReferenceSequence()
+               {
+                       YAML::Node node;
+                       node[0] = node;
+                       YAML_ASSERT(node.IsSequence());
+                       YAML_ASSERT(node.size() == 1);
+                       YAML_ASSERT(node[0] == node);
+                       YAML_ASSERT(node[0][0] == node);
+                       YAML_ASSERT(node[0][0] == node[0]);
+                       return true;
+               }
+
+               TEST ValueSelfReferenceMap()
+               {
+                       YAML::Node node;
+                       node["key"] = node;
+                       YAML_ASSERT(node.IsMap());
+                       YAML_ASSERT(node.size() == 1);
+                       YAML_ASSERT(node["key"] == node);
+                       YAML_ASSERT(node["key"]["key"] == node);
+                       YAML_ASSERT(node["key"]["key"] == node["key"]);
+                       return true;
+               }
+
+               TEST KeySelfReferenceMap()
+               {
+                       YAML::Node node;
+                       node[node] = "value";
+                       YAML_ASSERT(node.IsMap());
+                       YAML_ASSERT(node.size() == 1);
+                       YAML_ASSERT(node[node].as<std::string>() == "value");
+                       return true;
+               }
+
+               TEST SelfReferenceMap()
+               {
+                       YAML::Node node;
+                       node[node] = node;
+                       YAML_ASSERT(node.IsMap());
+                       YAML_ASSERT(node.size() == 1);
+                       YAML_ASSERT(node[node] == node);
+                       YAML_ASSERT(node[node][node] == node);
+                       YAML_ASSERT(node[node][node] == node[node]);
+                       return true;
+               }
+               
+               TEST TempMapVariable()
+               {
+                       YAML::Node node;
+                       YAML::Node tmp = node["key"];
+                       tmp = "value";
+                       YAML_ASSERT(node.IsMap());
+                       YAML_ASSERT(node.size() == 1);
+                       YAML_ASSERT(node["key"].as<std::string>() == "value");
+                       return true;
+               }
+
+               TEST TempMapVariableAlias()
+               {
+                       YAML::Node node;
+                       YAML::Node tmp = node["key"];
+                       tmp = node["other"];
+                       node["other"] = "value";
+                       YAML_ASSERT(node.IsMap());
+                       YAML_ASSERT(node.size() == 2);
+                       YAML_ASSERT(node["key"].as<std::string>() == "value");
+                       YAML_ASSERT(node["other"].as<std::string>() == "value");
+                       YAML_ASSERT(node["other"] == node["key"]);
+                       return true;
+               }
+               
+               TEST Bool()
+               {
+                       YAML::Node node;
+                       node[true] = false;
+                       YAML_ASSERT(node.IsMap());
+                       YAML_ASSERT(node[true].as<bool>() == false);
+                       return true;
+               }
+               
+               TEST AutoBoolConversion()
+               {
+                       YAML::Node node;
+                       node["foo"] = "bar";
+                       YAML_ASSERT(static_cast<bool>(node["foo"]));
+                       YAML_ASSERT(!node["monkey"]);
+                       YAML_ASSERT(!!node["foo"]);
+                       return true;
+               }
+        
+        TEST Reassign()
+        {
+            YAML::Node node = YAML::Load("foo");
+            node = YAML::Node();
+            return true;
+        }
+        
+        TEST FallbackValues()
+        {
+            YAML::Node node = YAML::Load("foo: bar\nx: 2");
+            YAML_ASSERT(node["foo"].as<std::string>() == "bar");
+            YAML_ASSERT(node["foo"].as<std::string>("hello") == "bar");
+            YAML_ASSERT(node["baz"].as<std::string>("hello") == "hello");
+            YAML_ASSERT(node["x"].as<int>() == 2);
+            YAML_ASSERT(node["x"].as<int>(5) == 2);
+            YAML_ASSERT(node["y"].as<int>(5) == 5);
+            return true;
+        }
+        
+        TEST NumericConversion()
+        {
+            YAML::Node node = YAML::Load("[1.5, 1, .nan, .inf, -.inf, 0x15, 015]");
+            YAML_ASSERT(node[0].as<float>() == 1.5f);
+            YAML_ASSERT(node[0].as<double>() == 1.5);
+            YAML_ASSERT_THROWS(node[0].as<int>(), YAML::TypedBadConversion<int>);
+            YAML_ASSERT(node[1].as<int>() == 1);
+            YAML_ASSERT(node[1].as<float>() == 1.0f);
+            YAML_ASSERT(node[2].as<float>() != node[2].as<float>());
+            YAML_ASSERT(node[3].as<float>() == std::numeric_limits<float>::infinity());
+            YAML_ASSERT(node[4].as<float>() == -std::numeric_limits<float>::infinity());
+            YAML_ASSERT(node[5].as<int>() == 21);
+            YAML_ASSERT(node[6].as<int>() == 13);
+            return true;
+        }
+        
+        TEST Binary()
+        {
+            YAML::Node node = YAML::Load("[!!binary \"SGVsbG8sIFdvcmxkIQ==\", !!binary \"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4K\"]");
+            YAML_ASSERT(node[0].as<YAML::Binary>() == YAML::Binary(reinterpret_cast<const unsigned char*>("Hello, World!"), 13));
+            YAML_ASSERT(node[1].as<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 true;
+        }
+        
+        TEST IterateSequence()
+        {
+            YAML::Node node = YAML::Load("[1, 3, 5, 7]");
+            int seq[] = {1, 3, 5, 7};
+            int i=0;
+            for(YAML::const_iterator it=node.begin();it!=node.end();++it) {
+                YAML_ASSERT(i < 4);
+                int x = seq[i++];
+                YAML_ASSERT(it->as<int>() == x);
+            }
+            YAML_ASSERT(i == 4);
+            return true;
+        }
+        
+        TEST IterateMap()
+        {
+            YAML::Node node = YAML::Load("{a: A, b: B, c: C}");
+            int i=0;
+            for(YAML::const_iterator it=node.begin();it!=node.end();++it) {
+                YAML_ASSERT(i < 3);
+                i++;
+                YAML_ASSERT(it->first.as<char>() + 'A' - 'a' == it->second.as<char>());
+            }
+            YAML_ASSERT(i == 3);
+            return true;
+        }
+        
+        TEST ForEach()
+        {
+            YAML::Node node = YAML::Load("[1, 3, 5, 7]");
+            int seq[] = {1, 3, 5, 7};
+            int i = 0;
+            BOOST_FOREACH(const YAML::Node &item, node) {
+                int x = seq[i++];
+                YAML_ASSERT(item.as<int>() == x);
+            }
+            return true;
+        }
+
+        TEST ForEachMap()
+        {
+            YAML::Node node = YAML::Load("{a: A, b: B, c: C}");
+            BOOST_FOREACH(const YAML::const_iterator::value_type &p, node) {
+                YAML_ASSERT(p.first.as<char>() + 'A' - 'a' == p.second.as<char>());
+            }
+            return true;
+        }
+        
+        TEST CloneScalar()
+        {
+            YAML::Node node = YAML::Load("!foo monkey");
+            YAML::Node clone = Clone(node);
+            YAML_ASSERT(!(node == clone));
+            YAML_ASSERT(node.as<std::string>() == clone.as<std::string>());
+            YAML_ASSERT(node.Tag() == clone.Tag());
+            return true;
+        }
+
+        TEST CloneSeq()
+        {
+            YAML::Node node = YAML::Load("[1, 3, 5, 7]");
+            YAML::Node clone = Clone(node);
+            YAML_ASSERT(!(node == clone));
+            YAML_ASSERT(clone.Type() == YAML::NodeType::Sequence);
+            YAML_ASSERT(node.size() == clone.size());
+            for(std::size_t i=0;i<node.size();i++)
+                YAML_ASSERT(node[i].as<int>() == clone[i].as<int>());
+            return true;
+        }
+
+        TEST CloneMap()
+        {
+            YAML::Node node = YAML::Load("{foo: bar}");
+            YAML::Node clone = Clone(node);
+            YAML_ASSERT(!(node == clone));
+            YAML_ASSERT(clone.Type() == YAML::NodeType::Map);
+            YAML_ASSERT(node.size() == clone.size());
+            YAML_ASSERT(node["foo"].as<std::string>() == clone["foo"].as<std::string>());
+            return true;
+        }
+
+        TEST CloneAlias()
+        {
+            YAML::Node node = YAML::Load("&foo [*foo]");
+            YAML::Node clone = Clone(node);
+            YAML_ASSERT(!(node == clone));
+            YAML_ASSERT(clone.Type() == YAML::NodeType::Sequence);
+            YAML_ASSERT(node.size() == clone.size());
+            YAML_ASSERT(clone == clone[0]);
+            return true;
+        }
+        
+        TEST ForceInsertIntoMap()
+        {
+            YAML::Node node;
+            node["a"] = "b";
+            node.force_insert("x", "y");
+            node.force_insert("a", 5);
+            YAML_ASSERT(node.size() == 3);
+            YAML_ASSERT(node.Type() == YAML::NodeType::Map);
+            bool ab = false;
+            bool a5 = false;
+            bool xy = false;
+            for(YAML::const_iterator it=node.begin();it!=node.end();++it) {
+                if(it->first.as<std::string>() == "a") {
+                    if(it->second.as<std::string>() == "b")
+                        ab = true;
+                    else if(it->second.as<std::string>() == "5")
+                        a5 = true;
+                } else if(it->first.as<std::string>() == "x" && it->second.as<std::string>() == "y")
+                    xy = true;
+            }
+            YAML_ASSERT(ab);
+            YAML_ASSERT(a5);
+            YAML_ASSERT(xy);
+            return true;
+        }
+        
+        TEST ResetNode()
+        {
+            YAML::Node node = YAML::Load("[1, 2, 3]");
+            YAML_ASSERT(!node.IsNull());
+            YAML::Node other = node;
+            node.reset();
+            YAML_ASSERT(node.IsNull());
+            YAML_ASSERT(!other.IsNull());
+            node.reset(other);
+            YAML_ASSERT(!node.IsNull());
+            YAML_ASSERT(other == node);
+            return true;
+        }
+
+        TEST DereferenceIteratorError()
+        {
+            YAML::Node node = YAML::Load("[{a: b}, 1, 2]");
+            YAML_ASSERT_THROWS(node.begin()->first.as<int>(), YAML::InvalidNode);
+            YAML_ASSERT((*node.begin()).IsMap() == true);
+            YAML_ASSERT(node.begin()->IsMap() == true);
+            YAML_ASSERT_THROWS((*node.begin()->begin()).IsDefined(), YAML::InvalidNode);
+            YAML_ASSERT_THROWS(node.begin()->begin()->IsDefined(), YAML::InvalidNode);
+            return true;
+        }
+
+        TEST FloatingPrecision()
+        {
+            const double x = 0.123456789;
+            YAML::Node node = YAML::Node(x);
+            YAML_ASSERT(node.as<double>() == x);
+            return true;
+        }
+    }
+       
+       void RunNodeTest(TEST (*test)(), const std::string& name, int& passed, int& total) {
+               TEST ret;
+               try {
+                       ret = test();
+               } catch(const std::exception& e) {
+                       ret.ok = false;
+            ret.error = e.what();
+               }
+               if(ret.ok) {
+                       passed++;
+               } else {
+                       std::cout << "Node test failed: " << name << "\n";
+                       if(ret.error != "")
+                               std::cout << ret.error << "\n";
+               }
+               total++;
+       }
+       
+       bool RunNodeTests()
+       {
+               int passed = 0;
+               int total = 0;
+
+               RunNodeTest(&Node::SimpleScalar, "simple scalar", passed, total);
+               RunNodeTest(&Node::IntScalar, "int scalar", passed, total);
+               RunNodeTest(&Node::SimpleAppendSequence, "simple append sequence", passed, total);
+               RunNodeTest(&Node::SimpleAssignSequence, "simple assign sequence", passed, total);
+               RunNodeTest(&Node::SimpleMap, "simple map", passed, total);
+               RunNodeTest(&Node::MapWithUndefinedValues, "map with undefined values", passed, total);
+               RunNodeTest(&Node::MapIteratorWithUndefinedValues, "map iterator with undefined values", passed, total);
+               RunNodeTest(&Node::SimpleSubkeys, "simple subkey", passed, total);
+               RunNodeTest(&Node::StdVector, "std::vector", passed, total);
+               RunNodeTest(&Node::StdList, "std::list", passed, total);
+               RunNodeTest(&Node::StdMap, "std::map", passed, total);
+               RunNodeTest(&Node::StdPair, "std::pair", passed, total);
+               RunNodeTest(&Node::SimpleAlias, "simple alias", passed, total);
+               RunNodeTest(&Node::AliasAsKey, "alias as key", passed, total);
+               RunNodeTest(&Node::SelfReferenceSequence, "self reference sequence", passed, total);
+               RunNodeTest(&Node::ValueSelfReferenceMap, "value self reference map", passed, total);
+               RunNodeTest(&Node::KeySelfReferenceMap, "key self reference map", passed, total);
+               RunNodeTest(&Node::SelfReferenceMap, "self reference map", passed, total);
+               RunNodeTest(&Node::TempMapVariable, "temp map variable", passed, total);
+               RunNodeTest(&Node::TempMapVariableAlias, "temp map variable alias", passed, total);
+               RunNodeTest(&Node::Bool, "bool", passed, total);
+               RunNodeTest(&Node::AutoBoolConversion, "auto bool conversion", passed, total);
+               RunNodeTest(&Node::Reassign, "reassign", passed, total);
+               RunNodeTest(&Node::FallbackValues, "fallback values", passed, total);
+               RunNodeTest(&Node::NumericConversion, "numeric conversion", passed, total);
+               RunNodeTest(&Node::Binary, "binary", passed, total);
+               RunNodeTest(&Node::IterateSequence, "iterate sequence", passed, total);
+               RunNodeTest(&Node::IterateMap, "iterate map", passed, total);
+               RunNodeTest(&Node::ForEach, "for each", passed, total);
+               RunNodeTest(&Node::ForEachMap, "for each map", passed, total);
+               RunNodeTest(&Node::CloneScalar, "clone scalar", passed, total);
+               RunNodeTest(&Node::CloneSeq, "clone seq", passed, total);
+               RunNodeTest(&Node::CloneMap, "clone map", passed, total);
+               RunNodeTest(&Node::CloneAlias, "clone alias", passed, total);
+        RunNodeTest(&Node::ForceInsertIntoMap, "force insert into map", passed, total);
+        RunNodeTest(&Node::ResetNode, "reset node", passed, total);
+        RunNodeTest(&Node::DereferenceIteratorError, "dereference iterator error", passed, total);
+        RunNodeTest(&Node::FloatingPrecision, "floating precision", passed, total);
+
+               std::cout << "Node tests: " << passed << "/" << total << " passed\n";
+               return passed == total;
+       }
+}
diff --git a/test/new-api/parsertests.cpp b/test/new-api/parsertests.cpp
new file mode 100644 (file)
index 0000000..1d50ca6
--- /dev/null
@@ -0,0 +1,8 @@
+#include "parsertests.h"
+
+namespace Test {
+       bool RunParserTests()
+       {
+               return true;
+       }
+}
diff --git a/test/new-api/spectests.cpp b/test/new-api/spectests.cpp
new file mode 100644 (file)
index 0000000..328ae7a
--- /dev/null
@@ -0,0 +1,1365 @@
+#include "spectests.h"
+#include "specexamples.h"
+#include "yaml-cpp/yaml.h"
+#include <iostream>
+
+#define YAML_ASSERT(cond) do { if(!(cond)) return "  Assert failed: " #cond; } while(false)
+
+namespace Test
+{
+       namespace Spec
+       {
+               // 2.1
+               TEST SeqScalars() {
+                       YAML::Node doc = YAML::Load(ex2_1);
+                       YAML_ASSERT(doc.IsSequence());
+                       YAML_ASSERT(doc.size() == 3);
+                       YAML_ASSERT(doc[0].as<std::string>() == "Mark McGwire");
+                       YAML_ASSERT(doc[1].as<std::string>() == "Sammy Sosa");
+                       YAML_ASSERT(doc[2].as<std::string>() == "Ken Griffey");
+                       return true;
+               }
+               
+               // 2.2
+               TEST MappingScalarsToScalars() {
+                       YAML::Node doc = YAML::Load(ex2_2);
+                       YAML_ASSERT(doc.IsMap());
+                       YAML_ASSERT(doc.size() == 3);
+                       YAML_ASSERT(doc["hr"].as<std::string>() == "65");
+                       YAML_ASSERT(doc["avg"].as<std::string>() == "0.278");
+                       YAML_ASSERT(doc["rbi"].as<std::string>() == "147");
+                       return true;
+               }
+               
+               // 2.3
+               TEST MappingScalarsToSequences() {
+                       YAML::Node doc = YAML::Load(ex2_3);
+                       YAML_ASSERT(doc.IsMap());
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc["american"].size() == 3);
+                       YAML_ASSERT(doc["american"][0].as<std::string>() == "Boston Red Sox");
+                       YAML_ASSERT(doc["american"][1].as<std::string>() == "Detroit Tigers");
+                       YAML_ASSERT(doc["american"][2].as<std::string>() == "New York Yankees");
+                       YAML_ASSERT(doc["national"].size() == 3);
+                       YAML_ASSERT(doc["national"][0].as<std::string>() == "New York Mets");
+                       YAML_ASSERT(doc["national"][1].as<std::string>() == "Chicago Cubs");
+                       YAML_ASSERT(doc["national"][2].as<std::string>() == "Atlanta Braves");
+                       return true;
+               }
+               
+               // 2.4
+               TEST SequenceOfMappings() {
+                       YAML::Node doc = YAML::Load(ex2_4);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc[0].size() == 3);
+                       YAML_ASSERT(doc[0]["name"].as<std::string>() == "Mark McGwire");
+                       YAML_ASSERT(doc[0]["hr"].as<std::string>() == "65");
+                       YAML_ASSERT(doc[0]["avg"].as<std::string>() == "0.278");
+                       YAML_ASSERT(doc[1].size() == 3);
+                       YAML_ASSERT(doc[1]["name"].as<std::string>() == "Sammy Sosa");
+                       YAML_ASSERT(doc[1]["hr"].as<std::string>() == "63");
+                       YAML_ASSERT(doc[1]["avg"].as<std::string>() == "0.288");
+                       return true;
+               }
+               
+               // 2.5
+               TEST SequenceOfSequences() {
+                       YAML::Node doc = YAML::Load(ex2_5);
+                       YAML_ASSERT(doc.size() == 3);
+                       YAML_ASSERT(doc[0].size() == 3);
+                       YAML_ASSERT(doc[0][0].as<std::string>() == "name");
+                       YAML_ASSERT(doc[0][1].as<std::string>() == "hr");
+                       YAML_ASSERT(doc[0][2].as<std::string>() == "avg");
+                       YAML_ASSERT(doc[1].size() == 3);
+                       YAML_ASSERT(doc[1][0].as<std::string>() == "Mark McGwire");
+                       YAML_ASSERT(doc[1][1].as<std::string>() == "65");
+                       YAML_ASSERT(doc[1][2].as<std::string>() == "0.278");
+                       YAML_ASSERT(doc[2].size() == 3);
+                       YAML_ASSERT(doc[2][0].as<std::string>() == "Sammy Sosa");
+                       YAML_ASSERT(doc[2][1].as<std::string>() == "63");
+                       YAML_ASSERT(doc[2][2].as<std::string>() == "0.288");
+                       return true;
+               }
+               
+               // 2.6
+               TEST MappingOfMappings() {
+                       YAML::Node doc = YAML::Load(ex2_6);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc["Mark McGwire"].size() == 2);
+                       YAML_ASSERT(doc["Mark McGwire"]["hr"].as<std::string>() == "65");
+                       YAML_ASSERT(doc["Mark McGwire"]["avg"].as<std::string>() == "0.278");
+                       YAML_ASSERT(doc["Sammy Sosa"].size() == 2);
+                       YAML_ASSERT(doc["Sammy Sosa"]["hr"].as<std::string>() == "63");
+                       YAML_ASSERT(doc["Sammy Sosa"]["avg"].as<std::string>() == "0.288");
+                       return true;
+               }
+               
+               // 2.7
+               TEST TwoDocumentsInAStream() {
+                       std::vector<YAML::Node> docs = YAML::LoadAll(ex2_7);
+                       YAML_ASSERT(docs.size() == 2);
+                       
+                       {
+                               YAML::Node doc = docs[0];
+                               YAML_ASSERT(doc.size() == 3);
+                               YAML_ASSERT(doc[0].as<std::string>() == "Mark McGwire");
+                               YAML_ASSERT(doc[1].as<std::string>() == "Sammy Sosa");
+                               YAML_ASSERT(doc[2].as<std::string>() == "Ken Griffey");
+                       }
+
+                       {
+                               YAML::Node doc = docs[1];
+                               YAML_ASSERT(doc.size() == 2);
+                               YAML_ASSERT(doc[0].as<std::string>() == "Chicago Cubs");
+                               YAML_ASSERT(doc[1].as<std::string>() == "St Louis Cardinals");
+                       }
+                       return true;
+               }
+               
+               // 2.8
+               TEST PlayByPlayFeed() {
+                       std::vector<YAML::Node> docs = YAML::LoadAll(ex2_8);
+                       YAML_ASSERT(docs.size() == 2);
+                       
+                       {
+                               YAML::Node doc = docs[0];
+                               YAML_ASSERT(doc.size() == 3);
+                               YAML_ASSERT(doc["time"].as<std::string>() == "20:03:20");
+                               YAML_ASSERT(doc["player"].as<std::string>() == "Sammy Sosa");
+                               YAML_ASSERT(doc["action"].as<std::string>() == "strike (miss)");
+                       }
+
+                       {
+                               YAML::Node doc = docs[1];
+                               YAML_ASSERT(doc.size() == 3);
+                               YAML_ASSERT(doc["time"].as<std::string>() == "20:03:47");
+                               YAML_ASSERT(doc["player"].as<std::string>() == "Sammy Sosa");
+                               YAML_ASSERT(doc["action"].as<std::string>() == "grand slam");
+                       }
+                       return true;
+               }
+               
+               // 2.9
+               TEST SingleDocumentWithTwoComments() {
+                       YAML::Node doc = YAML::Load(ex2_9);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc["hr"].size() == 2);
+                       YAML_ASSERT(doc["hr"][0].as<std::string>() == "Mark McGwire");
+                       YAML_ASSERT(doc["hr"][1].as<std::string>() == "Sammy Sosa");
+                       YAML_ASSERT(doc["rbi"].size() == 2);
+                       YAML_ASSERT(doc["rbi"][0].as<std::string>() == "Sammy Sosa");
+                       YAML_ASSERT(doc["rbi"][1].as<std::string>() == "Ken Griffey");
+                       return true;
+               }
+               
+               // 2.10
+               TEST SimpleAnchor() {
+                       YAML::Node doc = YAML::Load(ex2_10);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc["hr"].size() == 2);
+                       YAML_ASSERT(doc["hr"][0].as<std::string>() == "Mark McGwire");
+                       YAML_ASSERT(doc["hr"][1].as<std::string>() == "Sammy Sosa");
+                       YAML_ASSERT(doc["rbi"].size() == 2);
+                       YAML_ASSERT(doc["rbi"][0].as<std::string>() == "Sammy Sosa");
+                       YAML_ASSERT(doc["rbi"][1].as<std::string>() == "Ken Griffey");
+                       return true;
+               }
+               
+               // 2.11
+               TEST MappingBetweenSequences() {
+                       YAML::Node doc = YAML::Load(ex2_11);
+
+                       std::vector<std::string> tigers_cubs;
+                       tigers_cubs.push_back("Detroit Tigers");
+                       tigers_cubs.push_back("Chicago cubs");
+                       
+                       std::vector<std::string> yankees_braves;
+                       yankees_braves.push_back("New York Yankees");
+                       yankees_braves.push_back("Atlanta Braves");
+                       
+                       
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc[tigers_cubs].size() == 1);
+                       YAML_ASSERT(doc[tigers_cubs][0].as<std::string>() == "2001-07-23");
+                       YAML_ASSERT(doc[yankees_braves].size() == 3);
+                       YAML_ASSERT(doc[yankees_braves][0].as<std::string>() == "2001-07-02");
+                       YAML_ASSERT(doc[yankees_braves][1].as<std::string>() == "2001-08-12");
+                       YAML_ASSERT(doc[yankees_braves][2].as<std::string>() == "2001-08-14");
+                       return true;
+               }
+               
+               // 2.12
+               TEST CompactNestedMapping() {
+                       YAML::Node doc = YAML::Load(ex2_12);
+                       YAML_ASSERT(doc.size() == 3);
+                       YAML_ASSERT(doc[0].size() == 2);
+                       YAML_ASSERT(doc[0]["item"].as<std::string>() == "Super Hoop");
+                       YAML_ASSERT(doc[0]["quantity"].as<int>() == 1);
+                       YAML_ASSERT(doc[1].size() == 2);
+                       YAML_ASSERT(doc[1]["item"].as<std::string>() == "Basketball");
+                       YAML_ASSERT(doc[1]["quantity"].as<int>() == 4);
+                       YAML_ASSERT(doc[2].size() == 2);
+                       YAML_ASSERT(doc[2]["item"].as<std::string>() == "Big Shoes");
+                       YAML_ASSERT(doc[2]["quantity"].as<int>() == 1);
+                       return true;
+               }
+               
+               // 2.13
+               TEST InLiteralsNewlinesArePreserved() {
+                       YAML::Node doc = YAML::Load(ex2_13);
+                       YAML_ASSERT(doc.as<std::string>() ==
+                                               "\\//||\\/||\n"
+                                               "// ||  ||__");
+                       return true;
+               }
+               
+               // 2.14
+               TEST InFoldedScalarsNewlinesBecomeSpaces() {
+                       YAML::Node doc = YAML::Load(ex2_14);
+                       YAML_ASSERT(doc.as<std::string>() == "Mark McGwire's year was crippled by a knee injury.");
+                       return true;
+               }
+               
+               // 2.15
+               TEST FoldedNewlinesArePreservedForMoreIndentedAndBlankLines() {
+                       YAML::Node doc = YAML::Load(ex2_15);
+                       YAML_ASSERT(doc.as<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() {
+                       YAML::Node doc = YAML::Load(ex2_16);
+                       YAML_ASSERT(doc.size() == 3);
+                       YAML_ASSERT(doc["name"].as<std::string>() == "Mark McGwire");
+                       YAML_ASSERT(doc["accomplishment"].as<std::string>() == "Mark set a major league home run record in 1998.\n");
+                       YAML_ASSERT(doc["stats"].as<std::string>() == "65 Home Runs\n0.278 Batting Average\n");
+                       return true;
+               }
+               
+               // 2.17
+               TEST QuotedScalars() {
+                       YAML::Node doc = YAML::Load(ex2_17);
+                       YAML_ASSERT(doc.size() == 6);
+                       YAML_ASSERT(doc["unicode"].as<std::string>() == "Sosa did fine.\xe2\x98\xba");
+                       YAML_ASSERT(doc["control"].as<std::string>() == "\b1998\t1999\t2000\n");
+                       YAML_ASSERT(doc["hex esc"].as<std::string>() == "\x0d\x0a is \r\n");
+                       YAML_ASSERT(doc["single"].as<std::string>() == "\"Howdy!\" he cried.");
+                       YAML_ASSERT(doc["quoted"].as<std::string>() == " # Not a 'comment'.");
+                       YAML_ASSERT(doc["tie-fighter"].as<std::string>() == "|\\-*-/|");
+                       return true;
+               }
+               
+               // 2.18
+               TEST MultiLineFlowScalars() {
+                       YAML::Node doc = YAML::Load(ex2_18);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc["plain"].as<std::string>() == "This unquoted scalar spans many lines.");
+                       YAML_ASSERT(doc["quoted"].as<std::string>() == "So does this quoted scalar.\n");
+                       return true;
+               }
+               
+               // TODO: 2.19 - 2.22 schema tags
+               
+               // 2.23
+               TEST VariousExplicitTags() {
+                       YAML::Node doc = YAML::Load(ex2_23);
+                       YAML_ASSERT(doc.size() == 3);
+                       YAML_ASSERT(doc["not-date"].Tag() == "tag:yaml.org,2002:str");
+                       YAML_ASSERT(doc["not-date"].as<std::string>() == "2002-04-28");
+                       YAML_ASSERT(doc["picture"].Tag() == "tag:yaml.org,2002:binary");
+                       YAML_ASSERT(doc["picture"].as<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"].as<std::string>() ==
+                                               "The semantics of the tag\n"
+                                               "above may be different for\n"
+                                               "different documents."
+                                               );
+                       return true;
+               }
+               
+               // 2.24
+               TEST GlobalTags() {
+                       YAML::Node doc = YAML::Load(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"].as<int>() == 73);
+                       YAML_ASSERT(doc[0]["center"]["y"].as<int>() == 129);
+                       YAML_ASSERT(doc[0]["radius"].as<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"].as<int>() == 73);
+                       YAML_ASSERT(doc[1]["start"]["y"].as<int>() == 129);
+                       YAML_ASSERT(doc[1]["finish"].size() == 2);
+                       YAML_ASSERT(doc[1]["finish"]["x"].as<int>() == 89);
+                       YAML_ASSERT(doc[1]["finish"]["y"].as<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"].as<int>() == 73);
+                       YAML_ASSERT(doc[2]["start"]["y"].as<int>() == 129);
+                       YAML_ASSERT(doc[2]["color"].as<std::string>() == "0xFFEEBB");
+                       YAML_ASSERT(doc[2]["text"].as<std::string>() == "Pretty vector drawing.");
+                       return true;
+               }
+               
+               // 2.25
+               TEST UnorderedSets() {
+                       YAML::Node doc = YAML::Load(ex2_25);
+                       YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:set");
+                       YAML_ASSERT(doc.size() == 3);
+                       YAML_ASSERT(doc["Mark McGwire"].IsNull());
+                       YAML_ASSERT(doc["Sammy Sosa"].IsNull());
+                       YAML_ASSERT(doc["Ken Griffey"].IsNull());
+                       return true;
+               }
+               
+               // 2.26
+               TEST OrderedMappings() {
+                       YAML::Node doc = YAML::Load(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"].as<int>() == 65);
+                       YAML_ASSERT(doc[1].size() == 1);
+                       YAML_ASSERT(doc[1]["Sammy Sosa"].as<int>() == 63);
+                       YAML_ASSERT(doc[2].size() == 1);
+                       YAML_ASSERT(doc[2]["Ken Griffey"].as<int>() == 58);
+                       return true;
+               }
+               
+               // 2.27
+               TEST Invoice() {
+                       YAML::Node doc = YAML::Load(ex2_27);
+                       YAML_ASSERT(doc.Tag() == "tag:clarkevans.com,2002:invoice");
+                       YAML_ASSERT(doc.size() == 8);
+                       YAML_ASSERT(doc["invoice"].as<int>() == 34843);
+                       YAML_ASSERT(doc["date"].as<std::string>() == "2001-01-23");
+                       YAML_ASSERT(doc["bill-to"].size() == 3);
+                       YAML_ASSERT(doc["bill-to"]["given"].as<std::string>() == "Chris");
+                       YAML_ASSERT(doc["bill-to"]["family"].as<std::string>() == "Dumars");
+                       YAML_ASSERT(doc["bill-to"]["address"].size() == 4);
+                       YAML_ASSERT(doc["bill-to"]["address"]["lines"].as<std::string>() == "458 Walkman Dr.\nSuite #292\n");
+                       YAML_ASSERT(doc["bill-to"]["address"]["city"].as<std::string>() == "Royal Oak");
+                       YAML_ASSERT(doc["bill-to"]["address"]["state"].as<std::string>() == "MI");
+                       YAML_ASSERT(doc["bill-to"]["address"]["postal"].as<std::string>() == "48046");
+                       YAML_ASSERT(doc["ship-to"].size() == 3);
+                       YAML_ASSERT(doc["ship-to"]["given"].as<std::string>() == "Chris");
+                       YAML_ASSERT(doc["ship-to"]["family"].as<std::string>() == "Dumars");
+                       YAML_ASSERT(doc["ship-to"]["address"].size() == 4);
+                       YAML_ASSERT(doc["ship-to"]["address"]["lines"].as<std::string>() == "458 Walkman Dr.\nSuite #292\n");
+                       YAML_ASSERT(doc["ship-to"]["address"]["city"].as<std::string>() == "Royal Oak");
+                       YAML_ASSERT(doc["ship-to"]["address"]["state"].as<std::string>() == "MI");
+                       YAML_ASSERT(doc["ship-to"]["address"]["postal"].as<std::string>() == "48046");
+                       YAML_ASSERT(doc["product"].size() == 2);
+                       YAML_ASSERT(doc["product"][0].size() == 4);
+                       YAML_ASSERT(doc["product"][0]["sku"].as<std::string>() == "BL394D");
+                       YAML_ASSERT(doc["product"][0]["quantity"].as<int>() == 4);
+                       YAML_ASSERT(doc["product"][0]["description"].as<std::string>() == "Basketball");
+                       YAML_ASSERT(doc["product"][0]["price"].as<std::string>() == "450.00");
+                       YAML_ASSERT(doc["product"][1].size() == 4);
+                       YAML_ASSERT(doc["product"][1]["sku"].as<std::string>() == "BL4438H");
+                       YAML_ASSERT(doc["product"][1]["quantity"].as<int>() == 1);
+                       YAML_ASSERT(doc["product"][1]["description"].as<std::string>() == "Super Hoop");
+                       YAML_ASSERT(doc["product"][1]["price"].as<std::string>() == "2392.00");
+                       YAML_ASSERT(doc["tax"].as<std::string>() == "251.42");
+                       YAML_ASSERT(doc["total"].as<std::string>() == "4443.52");
+                       YAML_ASSERT(doc["comments"].as<std::string>() == "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.");
+                       return true;
+               }
+               
+               // 2.28
+               TEST LogFile() {
+                       std::vector<YAML::Node> docs = YAML::LoadAll(ex2_28);
+                       YAML_ASSERT(docs.size() == 3);
+
+                       {
+                               YAML::Node doc = docs[0];
+                               YAML_ASSERT(doc.size() == 3);
+                               YAML_ASSERT(doc["Time"].as<std::string>() == "2001-11-23 15:01:42 -5");
+                               YAML_ASSERT(doc["User"].as<std::string>() == "ed");
+                               YAML_ASSERT(doc["Warning"].as<std::string>() == "This is an error message for the log file");
+                       }
+
+                       {
+                               YAML::Node doc = docs[1];
+                               YAML_ASSERT(doc.size() == 3);
+                               YAML_ASSERT(doc["Time"].as<std::string>() == "2001-11-23 15:02:31 -5");
+                               YAML_ASSERT(doc["User"].as<std::string>() == "ed");
+                               YAML_ASSERT(doc["Warning"].as<std::string>() == "A slightly different error message.");
+                       }
+
+                       {
+                               YAML::Node doc = docs[2];
+                               YAML_ASSERT(doc.size() == 4);
+                               YAML_ASSERT(doc["Date"].as<std::string>() == "2001-11-23 15:03:17 -5");
+                               YAML_ASSERT(doc["User"].as<std::string>() == "ed");
+                               YAML_ASSERT(doc["Fatal"].as<std::string>() == "Unknown variable \"bar\"");
+                               YAML_ASSERT(doc["Stack"].size() == 2);
+                               YAML_ASSERT(doc["Stack"][0].size() == 3);
+                               YAML_ASSERT(doc["Stack"][0]["file"].as<std::string>() == "TopClass.py");
+                               YAML_ASSERT(doc["Stack"][0]["line"].as<std::string>() == "23");
+                               YAML_ASSERT(doc["Stack"][0]["code"].as<std::string>() == "x = MoreObject(\"345\\n\")\n");
+                               YAML_ASSERT(doc["Stack"][1].size() == 3);
+                               YAML_ASSERT(doc["Stack"][1]["file"].as<std::string>() == "MoreClass.py");
+                               YAML_ASSERT(doc["Stack"][1]["line"].as<std::string>() == "58");
+                               YAML_ASSERT(doc["Stack"][1]["code"].as<std::string>() == "foo = bar");
+                       }
+                       return true;
+               }
+               
+               // TODO: 5.1 - 5.2 BOM
+               
+               // 5.3
+               TEST BlockStructureIndicators() {
+                       YAML::Node doc = YAML::Load(ex5_3);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc["sequence"].size() == 2);
+                       YAML_ASSERT(doc["sequence"][0].as<std::string>() == "one");
+                       YAML_ASSERT(doc["sequence"][1].as<std::string>() == "two");
+                       YAML_ASSERT(doc["mapping"].size() == 2);
+                       YAML_ASSERT(doc["mapping"]["sky"].as<std::string>() == "blue");
+                       YAML_ASSERT(doc["mapping"]["sea"].as<std::string>() == "green");
+                       return true;
+               }
+               
+               // 5.4
+               TEST FlowStructureIndicators() {
+                       YAML::Node doc = YAML::Load(ex5_4);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc["sequence"].size() == 2);
+                       YAML_ASSERT(doc["sequence"][0].as<std::string>() == "one");
+                       YAML_ASSERT(doc["sequence"][1].as<std::string>() == "two");
+                       YAML_ASSERT(doc["mapping"].size() == 2);
+                       YAML_ASSERT(doc["mapping"]["sky"].as<std::string>() == "blue");
+                       YAML_ASSERT(doc["mapping"]["sea"].as<std::string>() == "green");
+                       return true;
+               }
+               
+               // 5.5
+               TEST CommentIndicator() {
+                       YAML::Node doc = YAML::Load(ex5_5);
+                       YAML_ASSERT(doc.IsNull());
+                       return true;
+               }
+               
+               // 5.6
+               TEST NodePropertyIndicators() {
+                       YAML::Node doc = YAML::Load(ex5_6);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc["anchored"].as<std::string>() == "value"); // TODO: assert tag
+                       YAML_ASSERT(doc["alias"].as<std::string>() == "value");
+                       return true;
+               }
+               
+               // 5.7
+               TEST BlockScalarIndicators() {
+                       YAML::Node doc = YAML::Load(ex5_7);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc["literal"].as<std::string>() == "some\ntext\n");
+                       YAML_ASSERT(doc["folded"].as<std::string>() == "some text\n");
+                       return true;
+               }
+               
+               // 5.8
+               TEST QuotedScalarIndicators() {
+                       YAML::Node doc = YAML::Load(ex5_8);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc["single"].as<std::string>() == "text");
+                       YAML_ASSERT(doc["double"].as<std::string>() == "text");
+                       return true;
+               }
+               
+               // TODO: 5.9 directive
+               // TODO: 5.10 reserved indicator
+               
+               // 5.11
+               TEST LineBreakCharacters() {
+                       YAML::Node doc = YAML::Load(ex5_11);
+                       YAML_ASSERT(doc.as<std::string>() == "Line break (no glyph)\nLine break (glyphed)\n");
+                       return true;
+               }
+               
+               // 5.12
+               TEST TabsAndSpaces() {
+                       YAML::Node doc = YAML::Load(ex5_12);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc["quoted"].as<std::string>() == "Quoted\t");
+                       YAML_ASSERT(doc["block"].as<std::string>() ==
+                                               "void main() {\n"
+                                               "\tprintf(\"Hello, world!\\n\");\n"
+                                               "}");
+                       return true;
+               }
+               
+               // 5.13
+               TEST EscapedCharacters() {
+                       YAML::Node doc = YAML::Load(ex5_13);
+                       YAML_ASSERT(doc.as<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() {
+                       try {
+                               YAML::Load(ex5_14);
+                       } catch(const YAML::ParserException& e) {
+                               YAML_ASSERT(e.msg == std::string(YAML::ErrorMsg::INVALID_ESCAPE) + "c");
+                               return true;
+                       }
+                       
+                       return false;
+               }
+               
+               // 6.1
+               TEST IndentationSpaces() {
+                       YAML::Node doc = YAML::Load(ex6_1);
+                       YAML_ASSERT(doc.size() == 1);
+                       YAML_ASSERT(doc["Not indented"].size() == 2);
+                       YAML_ASSERT(doc["Not indented"]["By one space"].as<std::string>() == "By four\n  spaces\n");
+                       YAML_ASSERT(doc["Not indented"]["Flow style"].size() == 3);
+                       YAML_ASSERT(doc["Not indented"]["Flow style"][0].as<std::string>() == "By two");
+                       YAML_ASSERT(doc["Not indented"]["Flow style"][1].as<std::string>() == "Also by two");
+                       YAML_ASSERT(doc["Not indented"]["Flow style"][2].as<std::string>() == "Still by two");
+                       return true;
+               }
+               
+               // 6.2
+               TEST IndentationIndicators() {
+                       YAML::Node doc = YAML::Load(ex6_2);
+                       YAML_ASSERT(doc.size() == 1);
+                       YAML_ASSERT(doc["a"].size() == 2);
+                       YAML_ASSERT(doc["a"][0].as<std::string>() == "b");
+                       YAML_ASSERT(doc["a"][1].size() == 2);
+                       YAML_ASSERT(doc["a"][1][0].as<std::string>() == "c");
+                       YAML_ASSERT(doc["a"][1][1].as<std::string>() == "d");
+                       return true;
+               }
+               
+               // 6.3
+               TEST SeparationSpaces() {
+                       YAML::Node doc = YAML::Load(ex6_3);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc[0].size() == 1);
+                       YAML_ASSERT(doc[0]["foo"].as<std::string>() == "bar");
+                       YAML_ASSERT(doc[1].size() == 2);
+                       YAML_ASSERT(doc[1][0].as<std::string>() == "baz");
+                       YAML_ASSERT(doc[1][1].as<std::string>() == "baz");
+                       return true;
+               }
+               
+               // 6.4
+               TEST LinePrefixes() {
+                       YAML::Node doc = YAML::Load(ex6_4);
+                       YAML_ASSERT(doc.size() == 3);
+                       YAML_ASSERT(doc["plain"].as<std::string>() == "text lines");
+                       YAML_ASSERT(doc["quoted"].as<std::string>() == "text lines");
+                       YAML_ASSERT(doc["block"].as<std::string>() == "text\n \tlines\n");
+                       return true;
+               }
+               
+               // 6.5
+               TEST EmptyLines() {
+                       YAML::Node doc = YAML::Load(ex6_5);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc["Folding"].as<std::string>() == "Empty line\nas a line feed");
+                       YAML_ASSERT(doc["Chomping"].as<std::string>() == "Clipped empty lines\n");
+                       return true;
+               }
+               
+               // 6.6
+               TEST LineFolding() {
+                       YAML::Node doc = YAML::Load(ex6_6);
+                       YAML_ASSERT(doc.as<std::string>() == "trimmed\n\n\nas space");
+                       return true;
+               }
+               
+               // 6.7
+               TEST BlockFolding() {
+                       YAML::Node doc = YAML::Load(ex6_7);
+                       YAML_ASSERT(doc.as<std::string>() == "foo \n\n\t bar\n\nbaz\n");
+                       return true;
+               }
+               
+               // 6.8
+               TEST FlowFolding() {
+                       YAML::Node doc = YAML::Load(ex6_8);
+                       YAML_ASSERT(doc.as<std::string>() == " foo\nbar\nbaz ");
+                       return true;
+               }
+               
+               // 6.9
+               TEST SeparatedComment() {
+                       YAML::Node doc = YAML::Load(ex6_9);
+                       YAML_ASSERT(doc.size() == 1);
+                       YAML_ASSERT(doc["key"].as<std::string>() == "value");
+                       return true;
+               }
+               
+               // 6.10
+               TEST CommentLines() {
+                       YAML::Node doc = YAML::Load(ex6_10);
+                       YAML_ASSERT(doc.IsNull());
+                       return true;
+               }
+               
+               // 6.11
+               TEST MultiLineComments() {
+                       YAML::Node doc = YAML::Load(ex6_11);
+                       YAML_ASSERT(doc.size() == 1);
+                       YAML_ASSERT(doc["key"].as<std::string>() == "value");
+                       return true;
+               }
+               
+               // 6.12
+               TEST SeparationSpacesII() {
+                       YAML::Node doc = YAML::Load(ex6_12);
+                       
+                       std::map<std::string, std::string> sammy;
+                       sammy["first"] = "Sammy";
+                       sammy["last"] = "Sosa";
+                       
+                       YAML_ASSERT(doc.size() == 1);
+                       YAML_ASSERT(doc[sammy].size() == 2);
+                       YAML_ASSERT(doc[sammy]["hr"].as<int>() == 65);
+                       YAML_ASSERT(doc[sammy]["avg"].as<std::string>() == "0.278");
+                       return true;
+               }
+               
+               // 6.13
+               TEST ReservedDirectives() {
+                       YAML::Node doc = YAML::Load(ex6_13);
+                       YAML_ASSERT(doc.as<std::string>() == "foo");
+                       return true;
+               }
+               
+               // 6.14
+               TEST YAMLDirective() {
+                       YAML::Node doc = YAML::Load(ex6_14);
+                       YAML_ASSERT(doc.as<std::string>() == "foo");
+                       return true;
+               }
+               
+               // 6.15
+               TEST InvalidRepeatedYAMLDirective() {
+                       try {
+                               YAML::Load(ex6_15);
+                       } catch(const YAML::ParserException& e) {
+                               YAML_ASSERT(e.msg == YAML::ErrorMsg::REPEATED_YAML_DIRECTIVE);
+                               return true;
+                       }
+                       
+                       return "  No exception was thrown";
+               }
+               
+               // 6.16
+               TEST TagDirective() {
+                       YAML::Node doc = YAML::Load(ex6_16);
+                       YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:str");
+                       YAML_ASSERT(doc.as<std::string>() == "foo");
+                       return true;
+               }
+               
+               // 6.17
+               TEST InvalidRepeatedTagDirective() {
+                       try {
+                               YAML::Load(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() {
+                       std::vector<YAML::Node> docs = YAML::LoadAll(ex6_18);
+                       YAML_ASSERT(docs.size() == 2);
+                       
+                       {
+                               YAML::Node doc = docs[0];
+                               YAML_ASSERT(doc.Tag() == "!foo");
+                               YAML_ASSERT(doc.as<std::string>() == "bar");
+                       }
+
+                       {
+                               YAML::Node doc = docs[1];
+                               YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo");
+                               YAML_ASSERT(doc.as<std::string>() == "bar");
+                       }
+                       return true;
+               }
+               
+               // 6.19
+               TEST SecondaryTagHandle() {
+                       YAML::Node doc = YAML::Load(ex6_19);
+                       YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/int");
+                       YAML_ASSERT(doc.as<std::string>() == "1 - 3");
+                       return true;
+               }
+               
+               // 6.20
+               TEST TagHandles() {
+                       YAML::Node doc = YAML::Load(ex6_20);
+                       YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo");
+                       YAML_ASSERT(doc.as<std::string>() == "bar");
+                       return true;
+               }
+               
+               // 6.21
+               TEST LocalTagPrefix() {
+                       std::vector<YAML::Node> docs = YAML::LoadAll(ex6_21);
+                       YAML_ASSERT(docs.size() == 2);
+                       
+                       {
+                               YAML::Node doc = docs[0];
+                               YAML_ASSERT(doc.Tag() == "!my-light");
+                               YAML_ASSERT(doc.as<std::string>() == "fluorescent");
+                       }
+
+                       {
+                               YAML::Node doc = docs[1];
+                               YAML_ASSERT(doc.Tag() == "!my-light");
+                               YAML_ASSERT(doc.as<std::string>() == "green");
+                       }
+                       return true;
+               }
+               
+               // 6.22
+               TEST GlobalTagPrefix() {
+                       YAML::Node doc = YAML::Load(ex6_22);
+                       YAML_ASSERT(doc.size() == 1);
+                       YAML_ASSERT(doc[0].Tag() == "tag:example.com,2000:app/foo");
+                       YAML_ASSERT(doc[0].as<std::string>() == "bar");
+                       return true;
+               }
+               
+               // 6.23
+               TEST NodeProperties() {
+                       YAML::Node doc = YAML::Load(ex6_23);
+                       YAML_ASSERT(doc.size() == 2);
+                       for(YAML::const_iterator it=doc.begin();it!=doc.end();++it) {
+                               if(it->first.as<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.as<std::string>() == "bar");
+                               } else if(it->first.as<std::string>() == "baz") {
+                                       YAML_ASSERT(it->second.as<std::string>() == "foo");
+                               } else
+                                       return "  unknown key";
+                       }
+                       
+                       return true;
+               }
+               
+               // 6.24
+               TEST VerbatimTags() {
+                       YAML::Node doc = YAML::Load(ex6_24);
+                       YAML_ASSERT(doc.size() == 1);
+                       for(YAML::const_iterator it=doc.begin();it!=doc.end();++it) {
+                               YAML_ASSERT(it->first.Tag() == "tag:yaml.org,2002:str");
+                               YAML_ASSERT(it->first.as<std::string>() == "foo");
+                               YAML_ASSERT(it->second.Tag() == "!bar");
+                               YAML_ASSERT(it->second.as<std::string>() == "baz");
+                       }
+                       return true;
+               }
+               
+               // 6.25
+               TEST InvalidVerbatimTags() {
+                       YAML::Node doc = YAML::Load(ex6_25);
+                       return "  not implemented yet"; // TODO: check tags (but we probably will say these are valid, I think)
+               }
+               
+               // 6.26
+               TEST TagShorthands() {
+                       YAML::Node doc = YAML::Load(ex6_26);
+                       YAML_ASSERT(doc.size() == 3);
+                       YAML_ASSERT(doc[0].Tag() == "!local");
+                       YAML_ASSERT(doc[0].as<std::string>() == "foo");
+                       YAML_ASSERT(doc[1].Tag() == "tag:yaml.org,2002:str");
+                       YAML_ASSERT(doc[1].as<std::string>() == "bar");
+                       YAML_ASSERT(doc[2].Tag() == "tag:example.com,2000:app/tag%21");
+                       YAML_ASSERT(doc[2].as<std::string>() == "baz");
+                       return true;
+               }
+               
+               // 6.27
+               TEST InvalidTagShorthands() {
+                       bool threw = false;
+                       try {
+                               YAML::Load(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";
+                       
+                       YAML::Load(ex6_27b); // TODO: should we reject this one (since !h! is not declared)?
+                       return "  not implemented yet";
+               }
+               
+               // 6.28
+               TEST NonSpecificTags() {
+                       YAML::Node doc = YAML::Load(ex6_28);
+                       YAML_ASSERT(doc.size() == 3);
+                       YAML_ASSERT(doc[0].as<std::string>() == "12"); // TODO: check tags. How?
+                       YAML_ASSERT(doc[1].as<int>() == 12);
+                       YAML_ASSERT(doc[2].as<std::string>() == "12");
+                       return true;
+               }
+               
+               // 6.29
+               TEST NodeAnchors() {
+                       YAML::Node doc = YAML::Load(ex6_29);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc["First occurrence"].as<std::string>() == "Value");
+                       YAML_ASSERT(doc["Second occurrence"].as<std::string>() == "Value");
+                       return true;
+               }
+               
+               // 7.1
+               TEST AliasNodes() {
+                       YAML::Node doc = YAML::Load(ex7_1);
+                       YAML_ASSERT(doc.size() == 4);
+                       YAML_ASSERT(doc["First occurrence"].as<std::string>() == "Foo");
+                       YAML_ASSERT(doc["Second occurrence"].as<std::string>() == "Foo");
+                       YAML_ASSERT(doc["Override anchor"].as<std::string>() == "Bar");
+                       YAML_ASSERT(doc["Reuse anchor"].as<std::string>() == "Bar");
+                       return true;
+               }
+               
+               // 7.2
+               TEST EmptyNodes() {
+                       YAML::Node doc = YAML::Load(ex7_2);
+                       YAML_ASSERT(doc.size() == 2);
+                       for(YAML::const_iterator it=doc.begin();it!=doc.end();++it) {
+                               if(it->first.as<std::string>() == "foo") {
+                                       YAML_ASSERT(it->second.Tag() == "tag:yaml.org,2002:str");
+                                       YAML_ASSERT(it->second.as<std::string>() == "");
+                               } else if(it->first.as<std::string>() == "") {
+                                       YAML_ASSERT(it->first.Tag() == "tag:yaml.org,2002:str");
+                                       YAML_ASSERT(it->second.as<std::string>() == "bar");
+                               } else
+                                       return "  unexpected key";
+                       }
+                       return true;
+               }
+               
+               // 7.3
+               TEST CompletelyEmptyNodes() {
+                       YAML::Node doc = YAML::Load(ex7_3);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc["foo"].IsNull());
+                       YAML_ASSERT(doc[YAML::Null].as<std::string>() == "bar");
+                       return true;
+               }
+               
+               // 7.4
+               TEST DoubleQuotedImplicitKeys() {
+                       YAML::Node doc = YAML::Load(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"].as<std::string>() == "value");
+                       return true;
+               }
+               
+               // 7.5
+               TEST DoubleQuotedLineBreaks() {
+                       YAML::Node doc = YAML::Load(ex7_5);
+                       YAML_ASSERT(doc.as<std::string>() == "folded to a space,\nto a line feed, or \t \tnon-content");
+                       return true;
+               }
+               
+               // 7.6
+               TEST DoubleQuotedLines() {
+                       YAML::Node doc = YAML::Load(ex7_6);
+                       YAML_ASSERT(doc.as<std::string>() == " 1st non-empty\n2nd non-empty 3rd non-empty ");
+                       return true;
+               }
+               
+               // 7.7
+               TEST SingleQuotedCharacters() {
+                       YAML::Node doc = YAML::Load(ex7_7);
+                       YAML_ASSERT(doc.as<std::string>() == "here's to \"quotes\"");
+                       return true;
+               }
+               
+               // 7.8
+               TEST SingleQuotedImplicitKeys() {
+                       YAML::Node doc = YAML::Load(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"].as<std::string>() == "value");
+                       return true;
+               }
+               
+               // 7.9
+               TEST SingleQuotedLines() {
+                       YAML::Node doc = YAML::Load(ex7_9);
+                       YAML_ASSERT(doc.as<std::string>() == " 1st non-empty\n2nd non-empty 3rd non-empty ");
+                       return true;
+               }
+               
+               // 7.10
+               TEST PlainCharacters() {
+                       YAML::Node doc = YAML::Load(ex7_10);
+                       YAML_ASSERT(doc.size() == 6);
+                       YAML_ASSERT(doc[0].as<std::string>() == "::vector");
+                       YAML_ASSERT(doc[1].as<std::string>() == ": - ()");
+                       YAML_ASSERT(doc[2].as<std::string>() == "Up, up, and away!");
+                       YAML_ASSERT(doc[3].as<int>() == -123);
+                       YAML_ASSERT(doc[4].as<std::string>() == "http://example.com/foo#bar");
+                       YAML_ASSERT(doc[5].size() == 5);
+                       YAML_ASSERT(doc[5][0].as<std::string>() == "::vector");
+                       YAML_ASSERT(doc[5][1].as<std::string>() == ": - ()");
+                       YAML_ASSERT(doc[5][2].as<std::string>() == "Up, up, and away!");
+                       YAML_ASSERT(doc[5][3].as<int>() == -123);
+                       YAML_ASSERT(doc[5][4].as<std::string>() == "http://example.com/foo#bar");
+                       return true;
+               }
+               
+               // 7.11
+               TEST PlainImplicitKeys() {
+                       YAML::Node doc = YAML::Load(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"].as<std::string>() == "value");
+                       return true;
+               }
+               
+               // 7.12
+               TEST PlainLines() {
+                       YAML::Node doc = YAML::Load(ex7_12);
+                       YAML_ASSERT(doc.as<std::string>() == "1st non-empty\n2nd non-empty 3rd non-empty");
+                       return true;
+               }
+               
+               // 7.13
+               TEST FlowSequence() {
+                       YAML::Node doc = YAML::Load(ex7_13);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc[0].size() == 2);
+                       YAML_ASSERT(doc[0][0].as<std::string>() == "one");
+                       YAML_ASSERT(doc[0][1].as<std::string>() == "two");
+                       YAML_ASSERT(doc[1].size() == 2);
+                       YAML_ASSERT(doc[1][0].as<std::string>() == "three");
+                       YAML_ASSERT(doc[1][1].as<std::string>() == "four");
+                       return true;
+               }
+               
+               // 7.14
+               TEST FlowSequenceEntries() {
+                       YAML::Node doc = YAML::Load(ex7_14);
+                       YAML_ASSERT(doc.size() == 5);
+                       YAML_ASSERT(doc[0].as<std::string>() == "double quoted");
+                       YAML_ASSERT(doc[1].as<std::string>() == "single quoted");
+                       YAML_ASSERT(doc[2].as<std::string>() == "plain text");
+                       YAML_ASSERT(doc[3].size() == 1);
+                       YAML_ASSERT(doc[3][0].as<std::string>() == "nested");
+                       YAML_ASSERT(doc[4].size() == 1);
+                       YAML_ASSERT(doc[4]["single"].as<std::string>() == "pair");
+                       return true;
+               }
+               
+               // 7.15
+               TEST FlowMappings() {
+                       YAML::Node doc = YAML::Load(ex7_15);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc[0].size() == 2);
+                       YAML_ASSERT(doc[0]["one"].as<std::string>() == "two");
+                       YAML_ASSERT(doc[0]["three"].as<std::string>() == "four");
+                       YAML_ASSERT(doc[1].size() == 2);
+                       YAML_ASSERT(doc[1]["five"].as<std::string>() == "six");
+                       YAML_ASSERT(doc[1]["seven"].as<std::string>() == "eight");
+                       return true;
+               }
+               
+               // 7.16
+               TEST FlowMappingEntries() {
+                       YAML::Node doc = YAML::Load(ex7_16);
+                       YAML_ASSERT(doc.size() == 3);
+                       YAML_ASSERT(doc["explicit"].as<std::string>() == "entry");
+                       YAML_ASSERT(doc["implicit"].as<std::string>() == "entry");
+                       YAML_ASSERT(doc[YAML::Null].IsNull());
+                       return true;
+               }
+               
+               // 7.17
+               TEST FlowMappingSeparateValues() {
+                       YAML::Node doc = YAML::Load(ex7_17);
+                       YAML_ASSERT(doc.size() == 4);
+                       YAML_ASSERT(doc["unquoted"].as<std::string>() == "separate");
+                       YAML_ASSERT(doc["http://foo.com"].IsNull());
+                       YAML_ASSERT(doc["omitted value"].IsNull());
+                       YAML_ASSERT(doc[YAML::Null].as<std::string>() == "omitted key");
+                       return true;
+               }
+               
+               // 7.18
+               TEST FlowMappingAdjacentValues() {
+                       YAML::Node doc = YAML::Load(ex7_18);
+                       YAML_ASSERT(doc.size() == 3);
+                       YAML_ASSERT(doc["adjacent"].as<std::string>() == "value");
+                       YAML_ASSERT(doc["readable"].as<std::string>() == "value");
+                       YAML_ASSERT(doc["empty"].IsNull());
+                       return true;
+               }
+               
+               // 7.19
+               TEST SinglePairFlowMappings() {
+                       YAML::Node doc = YAML::Load(ex7_19);
+                       YAML_ASSERT(doc.size() == 1);
+                       YAML_ASSERT(doc[0].size() == 1);
+                       YAML_ASSERT(doc[0]["foo"].as<std::string>() == "bar");
+                       return true;
+               }
+               
+               // 7.20
+               TEST SinglePairExplicitEntry() {
+                       YAML::Node doc = YAML::Load(ex7_20);
+                       YAML_ASSERT(doc.size() == 1);
+                       YAML_ASSERT(doc[0].size() == 1);
+                       YAML_ASSERT(doc[0]["foo bar"].as<std::string>() == "baz");
+                       return true;
+               }
+               
+               // 7.21
+               TEST SinglePairImplicitEntries() {
+                       YAML::Node doc = YAML::Load(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"].as<std::string>() == "separate");
+                       YAML_ASSERT(doc[1].size() == 1);
+                       YAML_ASSERT(doc[1][0].size() == 1);
+                       YAML_ASSERT(doc[1][0][YAML::Null].as<std::string>() == "empty key entry");
+                       YAML_ASSERT(doc[2].size() == 1);
+                       YAML_ASSERT(doc[2][0].size() == 1);
+                       
+                       std::map<std::string, std::string> key;
+                       key["JSON"] = "like";
+                       YAML_ASSERT(doc[2][0][key].as<std::string>() == "adjacent");
+                       return true;
+               }
+               
+               // 7.22
+               TEST InvalidImplicitKeys() {
+                       try {
+                               YAML::Load(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() {
+                       YAML::Node doc = YAML::Load(ex7_23);
+                       YAML_ASSERT(doc.size() == 5);
+                       YAML_ASSERT(doc[0].size() == 2);
+                       YAML_ASSERT(doc[0][0].as<std::string>() == "a");
+                       YAML_ASSERT(doc[0][1].as<std::string>() == "b");
+                       YAML_ASSERT(doc[1].size() == 1);
+                       YAML_ASSERT(doc[1]["a"].as<std::string>() == "b");
+                       YAML_ASSERT(doc[2].as<std::string>() == "a");
+                       YAML_ASSERT(doc[3].as<char>() == 'b');
+                       YAML_ASSERT(doc[4].as<std::string>() == "c");
+                       return true;
+               }
+               
+               // 7.24
+               TEST FlowNodes() {
+                       YAML::Node doc = YAML::Load(ex7_24);
+                       YAML_ASSERT(doc.size() == 5);
+                       YAML_ASSERT(doc[0].Tag() == "tag:yaml.org,2002:str");
+                       YAML_ASSERT(doc[0].as<std::string>() == "a");
+                       YAML_ASSERT(doc[1].as<char>() == 'b');
+                       YAML_ASSERT(doc[2].as<std::string>() == "c");
+                       YAML_ASSERT(doc[3].as<std::string>() == "c");
+                       YAML_ASSERT(doc[4].Tag() == "tag:yaml.org,2002:str");
+                       YAML_ASSERT(doc[4].as<std::string>() == "");
+                       return true;
+               }
+
+               // 8.1
+               TEST BlockScalarHeader() {
+                       YAML::Node doc = YAML::Load(ex8_1);
+                       YAML_ASSERT(doc.size() == 4);
+                       YAML_ASSERT(doc[0].as<std::string>() == "literal\n");
+                       YAML_ASSERT(doc[1].as<std::string>() == " folded\n");
+                       YAML_ASSERT(doc[2].as<std::string>() == "keep\n\n");
+                       YAML_ASSERT(doc[3].as<std::string>() == " strip");
+                       return true;
+               }
+               
+               // 8.2
+               TEST BlockIndentationHeader() {
+                       YAML::Node doc = YAML::Load(ex8_2);
+                       YAML_ASSERT(doc.size() == 4);
+                       YAML_ASSERT(doc[0].as<std::string>() == "detected\n");
+                       YAML_ASSERT(doc[1].as<std::string>() == "\n\n# detected\n");
+                       YAML_ASSERT(doc[2].as<std::string>() == " explicit\n");
+                       YAML_ASSERT(doc[3].as<std::string>() == "\t\ndetected\n");
+                       return true;
+               }
+               
+               // 8.3
+               TEST InvalidBlockScalarIndentationIndicators() {
+                       {
+                               bool threw = false;
+                               try {
+                                       YAML::Load(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 {
+                                       YAML::Load(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 {
+                                       YAML::Load(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() {
+                       YAML::Node doc = YAML::Load(ex8_4);
+                       YAML_ASSERT(doc.size() == 3);
+                       YAML_ASSERT(doc["strip"].as<std::string>() == "text");
+                       YAML_ASSERT(doc["clip"].as<std::string>() == "text\n");
+                       YAML_ASSERT(doc["keep"].as<std::string>() == "text\n");
+                       return true;
+               }
+               
+               // 8.5
+               TEST ChompingTrailingLines() {
+                       YAML::Node doc = YAML::Load(ex8_5);
+                       YAML_ASSERT(doc.size() == 3);
+                       YAML_ASSERT(doc["strip"].as<std::string>() == "# text");
+                       YAML_ASSERT(doc["clip"].as<std::string>() == "# text\n");
+                       YAML_ASSERT(doc["keep"].as<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() {
+                       YAML::Node doc = YAML::Load(ex8_6);
+                       YAML_ASSERT(doc.size() == 3);
+                       YAML_ASSERT(doc["strip"].as<std::string>() == "");
+                       YAML_ASSERT(doc["clip"].as<std::string>() == "");
+                       YAML_ASSERT(doc["keep"].as<std::string>() == "\n");
+                       return true;
+               }
+               
+               // 8.7
+               TEST LiteralScalar() {
+                       YAML::Node doc = YAML::Load(ex8_7);
+                       YAML_ASSERT(doc.as<std::string>() == "literal\n\ttext\n");
+                       return true;
+               }
+               
+               // 8.8
+               TEST LiteralContent() {
+                       YAML::Node doc = YAML::Load(ex8_8);
+                       YAML_ASSERT(doc.as<std::string>() == "\n\nliteral\n \n\ntext\n");
+                       return true;
+               }
+               
+               // 8.9
+               TEST FoldedScalar() {
+                       YAML::Node doc = YAML::Load(ex8_9);
+                       YAML_ASSERT(doc.as<std::string>() == "folded text\n");
+                       return true;
+               }
+               
+               // 8.10
+               TEST FoldedLines() {
+                       YAML::Node doc = YAML::Load(ex8_10);
+                       YAML_ASSERT(doc.as<std::string>() == "\nfolded line\nnext line\n  * bullet\n\n  * list\n  * lines\n\nlast line\n");
+                       return true;
+               }
+               
+               // 8.11
+               TEST MoreIndentedLines() {
+                       YAML::Node doc = YAML::Load(ex8_11);
+                       YAML_ASSERT(doc.as<std::string>() == "\nfolded line\nnext line\n  * bullet\n\n  * list\n  * lines\n\nlast line\n");
+                       return true;
+               }
+               
+               // 8.12
+               TEST EmptySeparationLines() {
+                       YAML::Node doc = YAML::Load(ex8_12);
+                       YAML_ASSERT(doc.as<std::string>() == "\nfolded line\nnext line\n  * bullet\n\n  * list\n  * lines\n\nlast line\n");
+                       return true;
+               }
+               
+               // 8.13
+               TEST FinalEmptyLines() {
+                       YAML::Node doc = YAML::Load(ex8_13);
+                       YAML_ASSERT(doc.as<std::string>() == "\nfolded line\nnext line\n  * bullet\n\n  * list\n  * lines\n\nlast line\n");
+                       return true;
+               }
+               
+               // 8.14
+               TEST BlockSequence() {
+                       YAML::Node doc = YAML::Load(ex8_14);
+                       YAML_ASSERT(doc.size() == 1);
+                       YAML_ASSERT(doc["block sequence"].size() == 2);
+                       YAML_ASSERT(doc["block sequence"][0].as<std::string>() == "one");
+                       YAML_ASSERT(doc["block sequence"][1].size() == 1);
+                       YAML_ASSERT(doc["block sequence"][1]["two"].as<std::string>() == "three");
+                       return true;
+               }
+               
+               // 8.15
+               TEST BlockSequenceEntryTypes() {
+                       YAML::Node doc = YAML::Load(ex8_15);
+                       YAML_ASSERT(doc.size() == 4);
+                       YAML_ASSERT(doc[0].IsNull());
+                       YAML_ASSERT(doc[1].as<std::string>() == "block node\n");
+                       YAML_ASSERT(doc[2].size() == 2);
+                       YAML_ASSERT(doc[2][0].as<std::string>() == "one");
+                       YAML_ASSERT(doc[2][1].as<std::string>() == "two");
+                       YAML_ASSERT(doc[3].size() == 1);
+                       YAML_ASSERT(doc[3]["one"].as<std::string>() == "two");
+                       return true;
+               }
+               
+               // 8.16
+               TEST BlockMappings() {
+                       YAML::Node doc = YAML::Load(ex8_16);
+                       YAML_ASSERT(doc.size() == 1);
+                       YAML_ASSERT(doc["block mapping"].size() == 1);
+                       YAML_ASSERT(doc["block mapping"]["key"].as<std::string>() == "value");
+                       return true;
+               }
+               
+               // 8.17
+               TEST ExplicitBlockMappingEntries() {
+                       YAML::Node doc = YAML::Load(ex8_17);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc["explicit key"].IsNull());
+                       YAML_ASSERT(doc["block key\n"].size() == 2);
+                       YAML_ASSERT(doc["block key\n"][0].as<std::string>() == "one");
+                       YAML_ASSERT(doc["block key\n"][1].as<std::string>() == "two");
+                       return true;
+               }
+               
+               // 8.18
+               TEST ImplicitBlockMappingEntries() {
+                       YAML::Node doc = YAML::Load(ex8_18);
+                       YAML_ASSERT(doc.size() == 3);
+                       YAML_ASSERT(doc["plain key"].as<std::string>() == "in-line value");
+                       YAML_ASSERT(doc[YAML::Null].IsNull());
+                       YAML_ASSERT(doc["quoted key"].size() == 1);
+                       YAML_ASSERT(doc["quoted key"][0].as<std::string>() == "entry");
+                       return true;
+               }
+               
+               // 8.19
+               TEST CompactBlockMappings() {
+                       YAML::Node doc = YAML::Load(ex8_19);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc[0].size() == 1);
+                       YAML_ASSERT(doc[0]["sun"].as<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"].as<std::string>() == "white");
+                       return true;
+               }
+               
+               // 8.20
+               TEST BlockNodeTypes() {
+                       YAML::Node doc = YAML::Load(ex8_20);
+                       YAML_ASSERT(doc.size() == 3);
+                       YAML_ASSERT(doc[0].as<std::string>() == "flow in block");
+                       YAML_ASSERT(doc[1].as<std::string>() == "Block scalar\n");
+                       YAML_ASSERT(doc[2].size() == 1);
+                       YAML_ASSERT(doc[2]["foo"].as<std::string>() == "bar");
+                       return true;
+               }
+               
+               // 8.21
+               TEST BlockScalarNodes() {
+                       YAML::Node doc = YAML::Load(ex8_21);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc["literal"].as<std::string>() == "value"); // Note: I believe this is a bug in the YAML spec - it should be "value\n"
+                       YAML_ASSERT(doc["folded"].as<std::string>() == "value");
+                       YAML_ASSERT(doc["folded"].Tag() == "!foo");
+                       return true;
+               }
+               
+               // 8.22
+               TEST BlockCollectionNodes() {
+                       YAML::Node doc = YAML::Load(ex8_22);
+                       YAML_ASSERT(doc.size() == 2);
+                       YAML_ASSERT(doc["sequence"].size() == 2);
+                       YAML_ASSERT(doc["sequence"][0].as<std::string>() == "entry");
+                       YAML_ASSERT(doc["sequence"][1].size() == 1);
+                       YAML_ASSERT(doc["sequence"][1][0].as<std::string>() == "nested");
+                       YAML_ASSERT(doc["mapping"].size() == 1);
+                       YAML_ASSERT(doc["mapping"]["foo"].as<std::string>() == "bar");
+                       return true;
+               }
+       }
+}
diff --git a/test/nodetests.h b/test/nodetests.h
new file mode 100644 (file)
index 0000000..733e782
--- /dev/null
@@ -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/test/parsertests.h b/test/parsertests.h
new file mode 100644 (file)
index 0000000..f3de1b8
--- /dev/null
@@ -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/test/specexamples.h b/test/specexamples.h
new file mode 100644 (file)
index 0000000..4688bdc
--- /dev/null
@@ -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/test/spectests.cpp b/test/spectests.cpp
new file mode 100644 (file)
index 0000000..bffc506
--- /dev/null
@@ -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/test/spectests.h b/test/spectests.h
new file mode 100644 (file)
index 0000000..611f3c0
--- /dev/null
@@ -0,0 +1,351 @@
+#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 "teststruct.h"
+
+namespace Test {
+       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/test/tests.cpp b/test/tests.cpp
new file mode 100644 (file)
index 0000000..efe82fc
--- /dev/null
@@ -0,0 +1,33 @@
+#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(!RunNodeTests())
+                       passed = false;
+
+               if(passed)
+                       std::cout << "All tests passed!\n";
+       }
+}
+
diff --git a/test/tests.h b/test/tests.h
new file mode 100644 (file)
index 0000000..757dbc5
--- /dev/null
@@ -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/test/teststruct.h b/test/teststruct.h
new file mode 100644 (file)
index 0000000..2d563e5
--- /dev/null
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <string>
+
+#define YAML_ASSERT(cond) do { if(!(cond)) return "  Assert failed: " #cond; } while(false)
+
+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;
+       };
+    
+}
diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt
new file mode 100644 (file)
index 0000000..28a3603
--- /dev/null
@@ -0,0 +1,8 @@
+add_executable(parse parse.cpp)
+target_link_libraries(parse yaml-cpp)
+
+add_executable(sandbox sandbox.cpp)
+target_link_libraries(sandbox yaml-cpp)
+
+add_executable(read read.cpp)
+target_link_libraries(read yaml-cpp)
diff --git a/util/api.cpp b/util/api.cpp
new file mode 100644 (file)
index 0000000..e5180a8
--- /dev/null
@@ -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/util/parse.cpp b/util/parse.cpp
new file mode 100644 (file)
index 0000000..ca112e0
--- /dev/null
@@ -0,0 +1,60 @@
+#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::Node doc = YAML::Load(input);
+               std::cout << doc << "\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/util/read.cpp b/util/read.cpp
new file mode 100644 (file)
index 0000000..f82cb7e
--- /dev/null
@@ -0,0 +1,30 @@
+#include "yaml-cpp/yaml.h"
+#include "yaml-cpp/eventhandler.h"
+#include <iostream>
+
+class NullEventHandler: public YAML::EventHandler
+{
+public:
+    typedef YAML::Mark Mark;
+    typedef YAML::anchor_t anchor_t;
+    
+    NullEventHandler() {}
+    
+    virtual void OnDocumentStart(const Mark&) {}
+    virtual void OnDocumentEnd() {}
+    virtual void OnNull(const Mark&, anchor_t) {}
+    virtual void OnAlias(const Mark&, anchor_t) {}
+    virtual void OnScalar(const Mark&, const std::string&, anchor_t, const std::string&) {}
+    virtual void OnSequenceStart(const Mark&, const std::string&, anchor_t) {}
+    virtual void OnSequenceEnd() {}
+    virtual void OnMapStart(const Mark&, const std::string&, anchor_t) {}
+    virtual void OnMapEnd() {}
+};
+
+int main()
+{
+    YAML::Parser parser(std::cin);
+    NullEventHandler handler;
+    parser.HandleNextDocument(handler);
+    return 0;
+}
diff --git a/util/sandbox.cpp b/util/sandbox.cpp
new file mode 100644 (file)
index 0000000..9b48738
--- /dev/null
@@ -0,0 +1,32 @@
+#include "yaml-cpp/yaml.h"
+#include "yaml-cpp/eventhandler.h"
+#include <iostream>
+
+class NullEventHandler: public YAML::EventHandler
+{
+public:
+    typedef YAML::Mark Mark;
+    typedef YAML::anchor_t anchor_t;
+    
+    NullEventHandler() {}
+    
+    virtual void OnDocumentStart(const Mark&) {}
+    virtual void OnDocumentEnd() {}
+    virtual void OnNull(const Mark&, anchor_t) {}
+    virtual void OnAlias(const Mark&, anchor_t) {}
+    virtual void OnScalar(const Mark&, const std::string&, anchor_t, const std::string&) {}
+    virtual void OnSequenceStart(const Mark&, const std::string&, anchor_t) {}
+    virtual void OnSequenceEnd() {}
+    virtual void OnMapStart(const Mark&, const std::string&, anchor_t) {}
+    virtual void OnMapEnd() {}
+};
+
+int main()
+{
+    std::stringstream stream("---{header: {id: 1");
+    YAML::Parser parser(stream);
+//    parser.PrintTokens(std::cout);
+    NullEventHandler handler;
+    parser.HandleNextDocument(handler);
+    return 0;
+}
diff --git a/yaml-cpp.pc.cmake b/yaml-cpp.pc.cmake
new file mode 100644 (file)
index 0000000..04d343f
--- /dev/null
@@ -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}