mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2025-09-09 12:41:17 +00:00
Compare commits
71 Commits
release-0.
...
release-0.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
976e8b184c | ||
![]() |
c1d75dd4f7 | ||
![]() |
dd1eb715c4 | ||
![]() |
fadca5a89d | ||
![]() |
7e129c9b64 | ||
![]() |
3e94c0a037 | ||
![]() |
8ba5e3fbf6 | ||
![]() |
857c7d93a0 | ||
![]() |
b690648308 | ||
![]() |
d904b600a9 | ||
![]() |
bacb74e8ec | ||
![]() |
b1ac3289b8 | ||
![]() |
835b86d9f7 | ||
![]() |
94dc63af04 | ||
![]() |
50474b6b9f | ||
![]() |
4c3926a5c7 | ||
![]() |
9fbcfe9ec5 | ||
![]() |
d98687afc3 | ||
![]() |
f42580be41 | ||
![]() |
6e0e9554c6 | ||
![]() |
dc5bd4afce | ||
![]() |
c67b41c966 | ||
![]() |
221d17b0c6 | ||
![]() |
9a72702a61 | ||
![]() |
ebdfeb0349 | ||
![]() |
6152fb345e | ||
![]() |
f9e1a882e8 | ||
![]() |
681c862f54 | ||
![]() |
bb463d8d8b | ||
![]() |
943d000ab3 | ||
![]() |
cb632b3968 | ||
![]() |
b9d4ccd254 | ||
![]() |
d6aeb16450 | ||
![]() |
a518d87cfc | ||
![]() |
27617ec2be | ||
![]() |
1f9cc2d327 | ||
![]() |
9128d841f5 | ||
![]() |
ca5992b971 | ||
![]() |
ced50538fe | ||
![]() |
1371fc446c | ||
![]() |
7998db8397 | ||
![]() |
39c396ab01 | ||
![]() |
1e0c36c5cc | ||
![]() |
f34d60ca65 | ||
![]() |
4caedfda74 | ||
![]() |
2faeb76e2d | ||
![]() |
75a2fbe564 | ||
![]() |
4d95e4da74 | ||
![]() |
802cc6bcd6 | ||
![]() |
04bc13caf8 | ||
![]() |
c65a7dfc7c | ||
![]() |
d1cb1aa74f | ||
![]() |
be1b14f369 | ||
![]() |
337cb553d0 | ||
![]() |
99089bf218 | ||
![]() |
e293d4af8a | ||
![]() |
a6afaabcb0 | ||
![]() |
d508203ed8 | ||
![]() |
f1697dea15 | ||
![]() |
6b7cb45ac8 | ||
![]() |
1e4210401f | ||
![]() |
a04e2da1ff | ||
![]() |
51c84f1c02 | ||
![]() |
18a805e46c | ||
![]() |
a19336fd98 | ||
![]() |
9ad3a1b905 | ||
![]() |
21be19d493 | ||
![]() |
5b8ca9ce01 | ||
![]() |
a71c03a18b | ||
![]() |
0a02403fb0 | ||
![]() |
9820d13840 |
4
.hgeol
Normal file
4
.hgeol
Normal file
@@ -0,0 +1,4 @@
|
||||
**.h = native
|
||||
**.c = native
|
||||
**.cpp = native
|
||||
**.txt = native
|
278
CMakeLists.txt
278
CMakeLists.txt
@@ -1,67 +1,267 @@
|
||||
###
|
||||
### 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()
|
||||
|
||||
project (YAML_CPP)
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
set(LIB_TYPE SHARED)
|
||||
|
||||
if(IPHONE)
|
||||
set(CMAKE_OSX_SYSROOT iphoneos2.2.1)
|
||||
set(LIB_TYPE)
|
||||
endif(IPHONE)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
set(CMAKE_CXX_FLAGS "-O2 -Wall -Wextra -pedantic -Wno-long-long ${CMAKE_CXX_FLAGS}")
|
||||
endif(CMAKE_COMPILER_IS_GNUCC)
|
||||
|
||||
if(MSVC)
|
||||
set(LIB_TYPE) # I can't figure out how CMake handles Windows shared libraries
|
||||
set(CMAKE_CXX_FLAGS "/W3 /wd4127 /wd4355 /D_SCL_SECURE_NO_WARNINGS ${CMAKE_CXX_FLAGS}")
|
||||
endif(MSVC)
|
||||
###
|
||||
### Project settings
|
||||
###
|
||||
project(YAML_CPP)
|
||||
|
||||
set(YAML_CPP_VERSION_MAJOR "0")
|
||||
set(YAML_CPP_VERSION_MINOR "2")
|
||||
set(YAML_CPP_VERSION_PATCH "4")
|
||||
set(YAML_CPP_VERSION_PATCH "7")
|
||||
set(YAML_CPP_VERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}.${YAML_CPP_VERSION_PATCH}")
|
||||
|
||||
enable_testing()
|
||||
|
||||
option(YAML_CPP_BUILD_TOOLS "Enables or disables testing and parse tools" true)
|
||||
|
||||
###
|
||||
### 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
|
||||
###
|
||||
file(GLOB sources "src/[a-zA-Z]*.cpp")
|
||||
file(GLOB public_headers "include/yaml-cpp/[a-zA-Z]*.h")
|
||||
file(GLOB private_headers "src/[a-zA-Z]*.h")
|
||||
|
||||
if(YAML_CPP_BUILD_CONTRIB)
|
||||
file(GLOB contrib_sources "src/contrib/[a-zA-Z]*.cpp")
|
||||
file(GLOB contrib_public_headers "include/yaml-cpp/contrib/[a-zA-Z]*.h")
|
||||
file(GLOB contrib_private_headers "src/contrib/[a-zA-Z]*.h")
|
||||
else()
|
||||
add_definitions(-DYAML_CPP_NO_CONTRIB)
|
||||
endif()
|
||||
|
||||
if(VERBOSE)
|
||||
message(STATUS "sources: ${sources}")
|
||||
message(STATUS "public_headers: ${public_headers}")
|
||||
message(STATUS "private_headers: ${private_headers}")
|
||||
message(STATUS "contrib_sources: ${contrib_sources}")
|
||||
message(STATUS "contrib_public_headers: ${contrib_public_headers}")
|
||||
message(STATUS "contrib_private_headers: ${contrib_private_headers}")
|
||||
endif()
|
||||
|
||||
include_directories(${YAML_CPP_SOURCE_DIR}/include)
|
||||
|
||||
|
||||
###
|
||||
### 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)
|
||||
set(_library_dir bin) # .dll are in PATH, like executables
|
||||
else(WIN32)
|
||||
set(_library_dir lib)
|
||||
endif(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()
|
||||
|
||||
set(INCLUDE_INSTALL_DIR include/yaml-cpp)
|
||||
set(LIB_INSTALL_DIR ${_library_dir}${LIB_SUFFIX})
|
||||
# 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}
|
||||
ARCHIVE DESTINATION "lib${LIB_SUFFIX}"
|
||||
)
|
||||
#
|
||||
file(GLOB public_headers include/[a-z]*.h)
|
||||
file(GLOB private_headers src/[a-z]*.h)
|
||||
file(GLOB sources src/[a-z]*.cpp)
|
||||
|
||||
include_directories(${YAML_CPP_SOURCE_DIR}/include)
|
||||
|
||||
###
|
||||
### Library
|
||||
###
|
||||
add_library(yaml-cpp
|
||||
${LIB_TYPE}
|
||||
${sources}
|
||||
${public_headers}
|
||||
${private_headers}
|
||||
${sources}
|
||||
${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(
|
||||
FILES ${public_headers}
|
||||
FILES
|
||||
${public_headers}
|
||||
${contrib_public_headers}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}
|
||||
)
|
||||
|
||||
@@ -69,9 +269,13 @@ 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(UNIX)
|
||||
endif()
|
||||
|
||||
|
||||
###
|
||||
### Extras
|
||||
###
|
||||
if(YAML_CPP_BUILD_TOOLS)
|
||||
add_subdirectory (test)
|
||||
add_subdirectory (util)
|
||||
endif(YAML_CPP_BUILD_TOOLS)
|
||||
add_subdirectory(test)
|
||||
add_subdirectory(util)
|
||||
endif()
|
||||
|
@@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef CONVERSION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define CONVERSION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "null.h"
|
||||
#include "traits.h"
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
inline bool Convert(const std::string& input, std::string& output) {
|
||||
output = input;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Convert(const std::string& input, bool& output);
|
||||
bool Convert(const std::string& input, _Null& output);
|
||||
|
||||
template <typename T>
|
||||
inline bool Convert(const std::string& input, T& output, typename enable_if<is_numeric<T> >::type * = 0) {
|
||||
std::stringstream stream(input);
|
||||
stream.unsetf(std::ios::dec);
|
||||
stream >> output;
|
||||
return !!stream;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CONVERSION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,161 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "mark.h"
|
||||
#include "traits.h"
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
// error messages
|
||||
namespace ErrorMsg
|
||||
{
|
||||
const std::string YAML_DIRECTIVE_ARGS = "YAML directives must have exactly one argument";
|
||||
const std::string YAML_VERSION = "bad YAML version: ";
|
||||
const std::string YAML_MAJOR_VERSION = "YAML major version too large";
|
||||
const std::string REPEATED_YAML_DIRECTIVE= "repeated YAML directive";
|
||||
const std::string TAG_DIRECTIVE_ARGS = "TAG directives must have exactly two arguments";
|
||||
const std::string REPEATED_TAG_DIRECTIVE = "repeated TAG directive";
|
||||
const std::string CHAR_IN_TAG_HANDLE = "illegal character found while scanning tag handle";
|
||||
const std::string TAG_WITH_NO_SUFFIX = "tag handle with no suffix";
|
||||
const std::string END_OF_VERBATIM_TAG = "end of verbatim tag not found";
|
||||
const std::string END_OF_MAP = "end of map not found";
|
||||
const std::string END_OF_MAP_FLOW = "end of map flow not found";
|
||||
const std::string END_OF_SEQ = "end of sequence not found";
|
||||
const std::string END_OF_SEQ_FLOW = "end of sequence flow not found";
|
||||
const std::string MULTIPLE_TAGS = "cannot assign multiple tags to the same node";
|
||||
const std::string MULTIPLE_ANCHORS = "cannot assign multiple anchors to the same node";
|
||||
const std::string MULTIPLE_ALIASES = "cannot assign multiple aliases to the same node";
|
||||
const std::string ALIAS_CONTENT = "aliases can't have any content, *including* tags";
|
||||
const std::string INVALID_HEX = "bad character found while scanning hex number";
|
||||
const std::string INVALID_UNICODE = "invalid unicode: ";
|
||||
const std::string INVALID_ESCAPE = "unknown escape character: ";
|
||||
const std::string UNKNOWN_TOKEN = "unknown token";
|
||||
const std::string DOC_IN_SCALAR = "illegal document indicator in scalar";
|
||||
const std::string EOF_IN_SCALAR = "illegal EOF in scalar";
|
||||
const std::string CHAR_IN_SCALAR = "illegal character in scalar";
|
||||
const std::string TAB_IN_INDENTATION = "illegal tab when looking for indentation";
|
||||
const std::string FLOW_END = "illegal flow end";
|
||||
const std::string BLOCK_ENTRY = "illegal block entry";
|
||||
const std::string MAP_KEY = "illegal map key";
|
||||
const std::string MAP_VALUE = "illegal map value";
|
||||
const std::string ALIAS_NOT_FOUND = "alias not found after *";
|
||||
const std::string ANCHOR_NOT_FOUND = "anchor not found after &";
|
||||
const std::string CHAR_IN_ALIAS = "illegal character found while scanning alias";
|
||||
const std::string CHAR_IN_ANCHOR = "illegal character found while scanning anchor";
|
||||
const std::string ZERO_INDENT_IN_BLOCK = "cannot set zero indentation for a block scalar";
|
||||
const std::string CHAR_IN_BLOCK = "unexpected character in block scalar";
|
||||
const std::string AMBIGUOUS_ANCHOR = "cannot assign the same alias to multiple nodes";
|
||||
const std::string UNKNOWN_ANCHOR = "the referenced anchor is not defined";
|
||||
|
||||
const std::string INVALID_SCALAR = "invalid scalar";
|
||||
const std::string KEY_NOT_FOUND = "key not found";
|
||||
const std::string BAD_DEREFERENCE = "bad dereference";
|
||||
|
||||
const std::string UNMATCHED_GROUP_TAG = "unmatched group tag";
|
||||
const std::string UNEXPECTED_END_SEQ = "unexpected end sequence token";
|
||||
const std::string UNEXPECTED_END_MAP = "unexpected end map token";
|
||||
const std::string SINGLE_QUOTED_CHAR = "invalid character in single-quoted string";
|
||||
const std::string INVALID_ANCHOR = "invalid anchor";
|
||||
const std::string INVALID_ALIAS = "invalid alias";
|
||||
const std::string INVALID_TAG = "invalid tag";
|
||||
const std::string EXPECTED_KEY_TOKEN = "expected key token";
|
||||
const std::string EXPECTED_VALUE_TOKEN = "expected value token";
|
||||
const std::string UNEXPECTED_KEY_TOKEN = "unexpected key token";
|
||||
const std::string UNEXPECTED_VALUE_TOKEN = "unexpected value token";
|
||||
|
||||
template <typename T>
|
||||
inline const std::string KEY_NOT_FOUND_WITH_KEY(const T&, typename disable_if<is_numeric<T> >::type * = 0) {
|
||||
return KEY_NOT_FOUND;
|
||||
}
|
||||
|
||||
inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) {
|
||||
return KEY_NOT_FOUND + ": " + key;
|
||||
}
|
||||
|
||||
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::exception {
|
||||
public:
|
||||
Exception(const Mark& mark_, const std::string& msg_)
|
||||
: mark(mark_), msg(msg_) {
|
||||
std::stringstream output;
|
||||
output << "yaml-cpp: error at line " << mark.line+1 << ", column " << mark.column+1 << ": " << msg;
|
||||
what_ = output.str();
|
||||
}
|
||||
virtual ~Exception() throw() {}
|
||||
virtual const char *what() const throw() { return what_.c_str(); }
|
||||
|
||||
Mark mark;
|
||||
std::string msg;
|
||||
|
||||
private:
|
||||
std::string what_;
|
||||
};
|
||||
|
||||
class ParserException: public Exception {
|
||||
public:
|
||||
ParserException(const Mark& mark_, const std::string& msg_)
|
||||
: Exception(mark_, msg_) {}
|
||||
};
|
||||
|
||||
class RepresentationException: public Exception {
|
||||
public:
|
||||
RepresentationException(const Mark& mark_, const std::string& msg_)
|
||||
: Exception(mark_, msg_) {}
|
||||
};
|
||||
|
||||
// representation exceptions
|
||||
class InvalidScalar: public RepresentationException {
|
||||
public:
|
||||
InvalidScalar(const Mark& mark_)
|
||||
: RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {}
|
||||
};
|
||||
|
||||
class KeyNotFound: public RepresentationException {
|
||||
public:
|
||||
template <typename T>
|
||||
KeyNotFound(const Mark& mark_, const T& key_)
|
||||
: RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class TypedKeyNotFound: public KeyNotFound {
|
||||
public:
|
||||
TypedKeyNotFound(const Mark& mark_, const T& key_)
|
||||
: KeyNotFound(mark_, key_), key(key_) {}
|
||||
virtual ~TypedKeyNotFound() throw() {}
|
||||
|
||||
T key;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline TypedKeyNotFound <T> MakeTypedKeyNotFound(const Mark& mark, const T& key) {
|
||||
return TypedKeyNotFound <T> (mark, key);
|
||||
}
|
||||
|
||||
class BadDereference: public RepresentationException {
|
||||
public:
|
||||
BadDereference()
|
||||
: RepresentationException(Mark::null(), ErrorMsg::BAD_DEREFERENCE) {}
|
||||
};
|
||||
|
||||
class EmitterException: public Exception {
|
||||
public:
|
||||
EmitterException(const std::string& msg_)
|
||||
: Exception(Mark::null(), msg_) {}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
141
include/node.h
141
include/node.h
@@ -1,141 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "conversion.h"
|
||||
#include "exceptions.h"
|
||||
#include "iterator.h"
|
||||
#include "mark.h"
|
||||
#include "noncopyable.h"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Content;
|
||||
class Scanner;
|
||||
class Emitter;
|
||||
struct ParserState;
|
||||
|
||||
enum CONTENT_TYPE { CT_NONE, CT_SCALAR, CT_SEQUENCE, CT_MAP };
|
||||
|
||||
class Node: private noncopyable
|
||||
{
|
||||
public:
|
||||
Node();
|
||||
~Node();
|
||||
|
||||
void Clear();
|
||||
std::auto_ptr<Node> Clone() const;
|
||||
void Parse(Scanner *pScanner, ParserState& state);
|
||||
|
||||
CONTENT_TYPE GetType() const;
|
||||
|
||||
// file location of start of this node
|
||||
const Mark GetMark() const { return m_mark; }
|
||||
|
||||
// accessors
|
||||
Iterator begin() const;
|
||||
Iterator end() const;
|
||||
std::size_t size() const;
|
||||
|
||||
// extraction of scalars
|
||||
bool GetScalar(std::string& s) const;
|
||||
|
||||
// we can specialize this for other values
|
||||
template <typename T>
|
||||
bool Read(T& value) const;
|
||||
|
||||
template <typename T>
|
||||
const T Read() const;
|
||||
|
||||
template <typename T>
|
||||
operator T() const;
|
||||
|
||||
template <typename T>
|
||||
friend void operator >> (const Node& node, T& value);
|
||||
|
||||
// retrieval for maps and sequences
|
||||
template <typename T>
|
||||
const Node *FindValue(const T& key) const;
|
||||
|
||||
template <typename T>
|
||||
const Node& operator [] (const T& key) const;
|
||||
|
||||
// specific to maps
|
||||
const Node *FindValue(const char *key) const;
|
||||
const Node& operator [] (const char *key) const;
|
||||
|
||||
// for anchors/aliases
|
||||
const Node *Identity() const { return m_pIdentity; }
|
||||
bool IsAlias() const { return m_alias; }
|
||||
bool IsReferenced() const { return m_referenced; }
|
||||
|
||||
// for tags
|
||||
const std::string GetTag() const { return IsAlias() ? m_pIdentity->GetTag() : m_tag; }
|
||||
|
||||
// emitting
|
||||
friend Emitter& operator << (Emitter& out, const Node& node);
|
||||
|
||||
// ordering
|
||||
int Compare(const Node& rhs) const;
|
||||
friend bool operator < (const Node& n1, const Node& n2);
|
||||
|
||||
private:
|
||||
// helper for sequences
|
||||
template <typename, bool> friend struct _FindFromNodeAtIndex;
|
||||
const Node *FindAtIndex(std::size_t i) const;
|
||||
|
||||
// helper for maps
|
||||
template <typename T>
|
||||
const Node& GetValue(const T& key) const;
|
||||
|
||||
template <typename T>
|
||||
const Node *FindValueForKey(const T& key) const;
|
||||
|
||||
// helper for cloning
|
||||
Node(const Mark& mark, const std::string& anchor, const std::string& tag, const Content *pContent);
|
||||
|
||||
// helpers for parsing
|
||||
void ParseHeader(Scanner *pScanner, ParserState& state);
|
||||
void ParseTag(Scanner *pScanner, ParserState& state);
|
||||
void ParseAnchor(Scanner *pScanner, ParserState& state);
|
||||
void ParseAlias(Scanner *pScanner, ParserState& state);
|
||||
|
||||
private:
|
||||
Mark m_mark;
|
||||
std::string m_anchor, m_tag;
|
||||
Content *m_pContent;
|
||||
bool m_alias;
|
||||
const Node *m_pIdentity;
|
||||
mutable bool m_referenced;
|
||||
};
|
||||
|
||||
// comparisons with auto-conversion
|
||||
template <typename T>
|
||||
bool operator == (const T& value, const Node& node);
|
||||
|
||||
template <typename T>
|
||||
bool operator == (const Node& node, const T& value);
|
||||
|
||||
template <typename T>
|
||||
bool operator != (const T& value, const Node& node);
|
||||
|
||||
template <typename T>
|
||||
bool operator != (const Node& node, const T& value);
|
||||
|
||||
bool operator == (const char *value, const Node& node);
|
||||
bool operator == (const Node& node, const char *value);
|
||||
bool operator != (const char *value, const Node& node);
|
||||
bool operator != (const Node& node, const char *value);
|
||||
}
|
||||
|
||||
#include "nodeimpl.h"
|
||||
#include "nodereadimpl.h"
|
||||
|
||||
#endif // NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,118 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef NODEIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODEIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "nodeutil.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
// implementation of templated things
|
||||
template <typename T>
|
||||
inline const T Node::Read() const {
|
||||
T value;
|
||||
*this >> value;
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Node::operator T() const {
|
||||
return Read<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void operator >> (const Node& node, T& value) {
|
||||
if(!ConvertScalar(node, value))
|
||||
throw InvalidScalar(node.m_mark);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const Node *Node::FindValue(const T& key) const {
|
||||
switch(GetType()) {
|
||||
case CT_MAP:
|
||||
return FindValueForKey(key);
|
||||
case CT_SEQUENCE:
|
||||
return FindFromNodeAtIndex(*this, key);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const Node *Node::FindValueForKey(const T& key) const {
|
||||
for(Iterator it=begin();it!=end();++it) {
|
||||
T t;
|
||||
if(it.first().Read(t)) {
|
||||
if(key == t)
|
||||
return &it.second();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const Node& Node::GetValue(const T& key) const {
|
||||
if(!m_pContent)
|
||||
throw BadDereference();
|
||||
|
||||
const Node *pValue = FindValue(key);
|
||||
if(!pValue)
|
||||
throw MakeTypedKeyNotFound(m_mark, key);
|
||||
|
||||
return *pValue;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const Node& Node::operator [] (const T& key) const {
|
||||
return GetValue(key);
|
||||
}
|
||||
|
||||
inline const Node *Node::FindValue(const char *key) const {
|
||||
return FindValue(std::string(key));
|
||||
}
|
||||
|
||||
inline const Node& Node::operator [] (const char *key) const {
|
||||
return GetValue(std::string(key));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator == (const T& value, const Node& node) {
|
||||
return value == node.operator T();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator == (const Node& node, const T& value) {
|
||||
return value == node.operator T();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator != (const T& value, const Node& node) {
|
||||
return value != node.operator T();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator != (const Node& node, const T& value) {
|
||||
return value != node.operator T();
|
||||
}
|
||||
|
||||
inline bool operator == (const char *value, const Node& node) {
|
||||
return std::string(value) == node;
|
||||
}
|
||||
|
||||
inline bool operator == (const Node& node, const char *value) {
|
||||
return std::string(value) == node;
|
||||
}
|
||||
|
||||
inline bool operator != (const char *value, const Node& node) {
|
||||
return std::string(value) != node;
|
||||
}
|
||||
|
||||
inline bool operator != (const Node& node, const char *value) {
|
||||
return std::string(value) != node;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // NODEIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
// this is basically boost::noncopyable
|
||||
class noncopyable
|
||||
{
|
||||
protected:
|
||||
noncopyable() {}
|
||||
~noncopyable() {}
|
||||
|
||||
private:
|
||||
noncopyable(const noncopyable&);
|
||||
const noncopyable& operator = (const noncopyable&);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,44 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
template <typename T>
|
||||
inline Emitter& operator << (Emitter& emitter, const std::vector <T>& v) {
|
||||
typedef typename std::vector <T> vec;
|
||||
emitter << BeginSeq;
|
||||
for(typename vec::const_iterator it=v.begin();it!=v.end();++it)
|
||||
emitter << *it;
|
||||
emitter << EndSeq;
|
||||
return emitter;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Emitter& operator << (Emitter& emitter, const std::list <T>& v) {
|
||||
typedef typename std::list <T> list;
|
||||
emitter << BeginSeq;
|
||||
for(typename list::const_iterator it=v.begin();it!=v.end();++it)
|
||||
emitter << *it;
|
||||
emitter << EndSeq;
|
||||
return emitter;
|
||||
}
|
||||
|
||||
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
|
34
include/yaml-cpp/aliasmanager.h
Normal file
34
include/yaml-cpp/aliasmanager.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef ALIASMANAGER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define ALIASMANAGER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "yaml-cpp/anchor.h"
|
||||
#include <map>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Node;
|
||||
|
||||
class AliasManager
|
||||
{
|
||||
public:
|
||||
AliasManager();
|
||||
|
||||
void RegisterReference(const Node& node);
|
||||
anchor_t LookupAnchor(const Node& node) const;
|
||||
|
||||
private:
|
||||
anchor_t _CreateNewAnchor();
|
||||
|
||||
private:
|
||||
typedef std::map<const Node*, anchor_t> AnchorByIdentity;
|
||||
AnchorByIdentity m_anchorByIdentity;
|
||||
|
||||
anchor_t m_curAnchor;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ALIASMANAGER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
16
include/yaml-cpp/anchor.h
Normal file
16
include/yaml-cpp/anchor.h
Normal file
@@ -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
|
42
include/yaml-cpp/contrib/anchordict.h
Normal file
42
include/yaml-cpp/contrib/anchordict.h
Normal file
@@ -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
|
133
include/yaml-cpp/contrib/graphbuilder.h
Normal file
133
include/yaml-cpp/contrib/graphbuilder.h
Normal file
@@ -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
|
65
include/yaml-cpp/conversion.h
Normal file
65
include/yaml-cpp/conversion.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#ifndef CONVERSION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define CONVERSION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "yaml-cpp/null.h"
|
||||
#include "yaml-cpp/traits.h"
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
inline bool Convert(const std::string& input, std::string& output) {
|
||||
output = input;
|
||||
return true;
|
||||
}
|
||||
|
||||
YAML_CPP_API bool Convert(const std::string& input, bool& output);
|
||||
YAML_CPP_API bool Convert(const std::string& input, _Null& output);
|
||||
|
||||
inline bool IsInfinity(const std::string& input) {
|
||||
return input == ".inf" || input == ".Inf" || input == ".INF" || input == "+.inf" || input == "+.Inf" || input == "+.INF";
|
||||
}
|
||||
|
||||
inline bool IsNegativeInfinity(const std::string& input) {
|
||||
return input == "-.inf" || input == "-.Inf" || input == "-.INF";
|
||||
}
|
||||
|
||||
inline bool IsNaN(const std::string& input) {
|
||||
return input == ".nan" || input == ".NaN" || input == ".NAN";
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline bool Convert(const std::string& input, T& output, typename enable_if<is_numeric<T> >::type * = 0) {
|
||||
std::stringstream stream(input);
|
||||
stream.unsetf(std::ios::dec);
|
||||
stream >> output;
|
||||
if(!!stream)
|
||||
return true;
|
||||
|
||||
if(std::numeric_limits<T>::has_infinity) {
|
||||
if(IsInfinity(input)) {
|
||||
output = std::numeric_limits<T>::infinity();
|
||||
return true;
|
||||
} else if(IsNegativeInfinity(input)) {
|
||||
output = -std::numeric_limits<T>::infinity();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(std::numeric_limits<T>::has_quiet_NaN && IsNaN(input)) {
|
||||
output = std::numeric_limits<T>::quiet_NaN();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CONVERSION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
28
include/yaml-cpp/dll.h
Normal file
28
include/yaml-cpp/dll.h
Normal file
@@ -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
|
45
include/yaml-cpp/emitfromevents.h
Normal file
45
include/yaml-cpp/emitfromevents.h
Normal file
@@ -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
|
@@ -1,12 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#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 "emittermanip.h"
|
||||
#include "ostream.h"
|
||||
#include "null.h"
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
#include "yaml-cpp/emittermanip.h"
|
||||
#include "yaml-cpp/ostream.h"
|
||||
#include "yaml-cpp/noncopyable.h"
|
||||
#include "yaml-cpp/null.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
@@ -15,7 +19,7 @@ namespace YAML
|
||||
{
|
||||
class EmitterState;
|
||||
|
||||
class Emitter
|
||||
class YAML_CPP_API Emitter: private noncopyable
|
||||
{
|
||||
public:
|
||||
Emitter();
|
||||
@@ -52,6 +56,7 @@ namespace YAML
|
||||
Emitter& Write(const _Tag& tag);
|
||||
Emitter& Write(const _Comment& comment);
|
||||
Emitter& Write(const _Null& null);
|
||||
Emitter& Write(const _Binary& binary);
|
||||
|
||||
template <typename T>
|
||||
Emitter& WriteIntegralType(T value);
|
||||
@@ -61,22 +66,30 @@ namespace YAML
|
||||
|
||||
private:
|
||||
void PreWriteIntegralType(std::stringstream& str);
|
||||
void PreWriteStreamable(std::stringstream& str);
|
||||
void PostWriteIntegralType(const std::stringstream& str);
|
||||
void PostWriteStreamable(const std::stringstream& str);
|
||||
|
||||
private:
|
||||
enum ATOMIC_TYPE { AT_SCALAR, AT_SEQ, AT_BLOCK_SEQ, AT_FLOW_SEQ, AT_MAP, AT_BLOCK_MAP, AT_FLOW_MAP };
|
||||
|
||||
void PreAtomicWrite();
|
||||
bool GotoNextPreAtomicState();
|
||||
void PostAtomicWrite();
|
||||
void EmitSeparationIfNecessary();
|
||||
|
||||
void EmitBeginDoc();
|
||||
void EmitEndDoc();
|
||||
void EmitBeginSeq();
|
||||
void EmitEndSeq();
|
||||
void EmitBeginMap();
|
||||
void EmitEndMap();
|
||||
void EmitKey();
|
||||
void EmitValue();
|
||||
void EmitNewline();
|
||||
void EmitKindTag();
|
||||
void EmitTag(bool verbatim, const _Tag& tag);
|
||||
|
||||
const char *ComputeFullBoolName(bool b) const;
|
||||
bool CanEmitNewline() const;
|
||||
|
||||
private:
|
||||
ostream m_stream;
|
||||
@@ -102,14 +115,10 @@ namespace YAML
|
||||
if(!good())
|
||||
return *this;
|
||||
|
||||
PreAtomicWrite();
|
||||
EmitSeparationIfNecessary();
|
||||
|
||||
std::stringstream str;
|
||||
PreWriteStreamable(str);
|
||||
str << value;
|
||||
m_stream << str.str();
|
||||
|
||||
PostAtomicWrite();
|
||||
PostWriteStreamable(str);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -121,6 +130,7 @@ namespace YAML
|
||||
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)); }
|
||||
|
||||
@@ -130,6 +140,8 @@ namespace YAML
|
||||
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); }
|
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#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>
|
||||
|
||||
@@ -11,6 +13,8 @@ namespace YAML
|
||||
enum EMITTER_MANIP {
|
||||
// general manipulators
|
||||
Auto,
|
||||
TagByKind,
|
||||
Newline,
|
||||
|
||||
// output character set
|
||||
EmitNonAscii,
|
||||
@@ -37,6 +41,10 @@ namespace YAML
|
||||
Hex,
|
||||
Oct,
|
||||
|
||||
// document manipulators
|
||||
BeginDoc,
|
||||
EndDoc,
|
||||
|
||||
// sequence manipulators
|
||||
BeginSeq,
|
||||
EndSeq,
|
||||
@@ -82,13 +90,31 @@ namespace YAML
|
||||
}
|
||||
|
||||
struct _Tag {
|
||||
_Tag(const std::string& content_): content(content_), verbatim(true) {}
|
||||
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;
|
||||
bool verbatim;
|
||||
Type::value type;
|
||||
};
|
||||
|
||||
inline _Tag VerbatimTag(const std::string& content) {
|
||||
return _Tag(content);
|
||||
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 {
|
||||
@@ -99,6 +125,16 @@ namespace YAML
|
||||
inline _Comment Comment(const std::string content) {
|
||||
return _Comment(content);
|
||||
}
|
||||
|
||||
struct _Binary {
|
||||
_Binary(const unsigned char *data_, std::size_t size_): data(data_), size(size_) {}
|
||||
const unsigned char *data;
|
||||
std::size_t size;
|
||||
};
|
||||
|
||||
inline _Binary Binary(const unsigned char *data, std::size_t size) {
|
||||
return _Binary(data, size);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
36
include/yaml-cpp/eventhandler.h
Normal file
36
include/yaml-cpp/eventhandler.h
Normal file
@@ -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
|
||||
|
164
include/yaml-cpp/exceptions.h
Normal file
164
include/yaml-cpp/exceptions.h
Normal file
@@ -0,0 +1,164 @@
|
||||
#ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "yaml-cpp/mark.h"
|
||||
#include "yaml-cpp/traits.h"
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
// error messages
|
||||
namespace ErrorMsg
|
||||
{
|
||||
const char * const YAML_DIRECTIVE_ARGS = "YAML directives must have exactly one argument";
|
||||
const char * const YAML_VERSION = "bad YAML version: ";
|
||||
const char * const YAML_MAJOR_VERSION = "YAML major version too large";
|
||||
const char * const REPEATED_YAML_DIRECTIVE= "repeated YAML directive";
|
||||
const char * const TAG_DIRECTIVE_ARGS = "TAG directives must have exactly two arguments";
|
||||
const char * const REPEATED_TAG_DIRECTIVE = "repeated TAG directive";
|
||||
const char * const CHAR_IN_TAG_HANDLE = "illegal character found while scanning tag handle";
|
||||
const char * const TAG_WITH_NO_SUFFIX = "tag handle with no suffix";
|
||||
const char * const END_OF_VERBATIM_TAG = "end of verbatim tag not found";
|
||||
const char * const END_OF_MAP = "end of map not found";
|
||||
const char * const END_OF_MAP_FLOW = "end of map flow not found";
|
||||
const char * const END_OF_SEQ = "end of sequence not found";
|
||||
const char * const END_OF_SEQ_FLOW = "end of sequence flow not found";
|
||||
const char * const MULTIPLE_TAGS = "cannot assign multiple tags to the same node";
|
||||
const char * const MULTIPLE_ANCHORS = "cannot assign multiple anchors to the same node";
|
||||
const char * const MULTIPLE_ALIASES = "cannot assign multiple aliases to the same node";
|
||||
const char * const ALIAS_CONTENT = "aliases can't have any content, *including* tags";
|
||||
const char * const INVALID_HEX = "bad character found while scanning hex number";
|
||||
const char * const INVALID_UNICODE = "invalid unicode: ";
|
||||
const char * const INVALID_ESCAPE = "unknown escape character: ";
|
||||
const char * const UNKNOWN_TOKEN = "unknown token";
|
||||
const char * const DOC_IN_SCALAR = "illegal document indicator in scalar";
|
||||
const char * const EOF_IN_SCALAR = "illegal EOF in scalar";
|
||||
const char * const CHAR_IN_SCALAR = "illegal character in scalar";
|
||||
const char * const TAB_IN_INDENTATION = "illegal tab when looking for indentation";
|
||||
const char * const FLOW_END = "illegal flow end";
|
||||
const char * const BLOCK_ENTRY = "illegal block entry";
|
||||
const char * const MAP_KEY = "illegal map key";
|
||||
const char * const MAP_VALUE = "illegal map value";
|
||||
const char * const ALIAS_NOT_FOUND = "alias not found after *";
|
||||
const char * const ANCHOR_NOT_FOUND = "anchor not found after &";
|
||||
const char * const CHAR_IN_ALIAS = "illegal character found while scanning alias";
|
||||
const char * const CHAR_IN_ANCHOR = "illegal character found while scanning anchor";
|
||||
const char * const ZERO_INDENT_IN_BLOCK = "cannot set zero indentation for a block scalar";
|
||||
const char * const CHAR_IN_BLOCK = "unexpected character in block scalar";
|
||||
const char * const AMBIGUOUS_ANCHOR = "cannot assign the same alias to multiple nodes";
|
||||
const char * const UNKNOWN_ANCHOR = "the referenced anchor is not defined";
|
||||
|
||||
const char * const INVALID_SCALAR = "invalid scalar";
|
||||
const char * const KEY_NOT_FOUND = "key not found";
|
||||
const char * const BAD_DEREFERENCE = "bad dereference";
|
||||
|
||||
const char * const UNMATCHED_GROUP_TAG = "unmatched group tag";
|
||||
const char * const UNEXPECTED_END_SEQ = "unexpected end sequence token";
|
||||
const char * const UNEXPECTED_END_MAP = "unexpected end map token";
|
||||
const char * const SINGLE_QUOTED_CHAR = "invalid character in single-quoted string";
|
||||
const char * const INVALID_ANCHOR = "invalid anchor";
|
||||
const char * const INVALID_ALIAS = "invalid alias";
|
||||
const char * const INVALID_TAG = "invalid tag";
|
||||
const char * const EXPECTED_KEY_TOKEN = "expected key token";
|
||||
const char * const EXPECTED_VALUE_TOKEN = "expected value token";
|
||||
const char * const UNEXPECTED_KEY_TOKEN = "unexpected key token";
|
||||
const char * const UNEXPECTED_VALUE_TOKEN = "unexpected value token";
|
||||
|
||||
template <typename T>
|
||||
inline const std::string KEY_NOT_FOUND_WITH_KEY(const T&, typename disable_if<is_numeric<T> >::type * = 0) {
|
||||
return KEY_NOT_FOUND;
|
||||
}
|
||||
|
||||
inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) {
|
||||
std::stringstream stream;
|
||||
stream << KEY_NOT_FOUND << ": " << key;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const std::string KEY_NOT_FOUND_WITH_KEY(const T& key, typename enable_if<is_numeric<T> >::type * = 0) {
|
||||
std::stringstream stream;
|
||||
stream << KEY_NOT_FOUND << ": " << key;
|
||||
return stream.str();
|
||||
}
|
||||
}
|
||||
|
||||
class Exception: public std::runtime_error {
|
||||
public:
|
||||
Exception(const Mark& mark_, const std::string& msg_)
|
||||
: std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {}
|
||||
virtual ~Exception() throw() {}
|
||||
|
||||
Mark mark;
|
||||
std::string msg;
|
||||
|
||||
private:
|
||||
static const std::string build_what(const Mark& mark, const std::string& msg) {
|
||||
std::stringstream output;
|
||||
output << "yaml-cpp: error at line " << mark.line+1 << ", column " << mark.column+1 << ": " << msg;
|
||||
return output.str();
|
||||
}
|
||||
};
|
||||
|
||||
class ParserException: public Exception {
|
||||
public:
|
||||
ParserException(const Mark& mark_, const std::string& msg_)
|
||||
: Exception(mark_, msg_) {}
|
||||
};
|
||||
|
||||
class RepresentationException: public Exception {
|
||||
public:
|
||||
RepresentationException(const Mark& mark_, const std::string& msg_)
|
||||
: Exception(mark_, msg_) {}
|
||||
};
|
||||
|
||||
// representation exceptions
|
||||
class InvalidScalar: public RepresentationException {
|
||||
public:
|
||||
InvalidScalar(const Mark& mark_)
|
||||
: RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {}
|
||||
};
|
||||
|
||||
class KeyNotFound: public RepresentationException {
|
||||
public:
|
||||
template <typename T>
|
||||
KeyNotFound(const Mark& mark_, const T& key_)
|
||||
: RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class TypedKeyNotFound: public KeyNotFound {
|
||||
public:
|
||||
TypedKeyNotFound(const Mark& mark_, const T& key_)
|
||||
: KeyNotFound(mark_, key_), key(key_) {}
|
||||
virtual ~TypedKeyNotFound() throw() {}
|
||||
|
||||
T key;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline TypedKeyNotFound <T> MakeTypedKeyNotFound(const Mark& mark, const T& key) {
|
||||
return TypedKeyNotFound <T> (mark, key);
|
||||
}
|
||||
|
||||
class BadDereference: public RepresentationException {
|
||||
public:
|
||||
BadDereference()
|
||||
: RepresentationException(Mark::null(), ErrorMsg::BAD_DEREFERENCE) {}
|
||||
};
|
||||
|
||||
class EmitterException: public Exception {
|
||||
public:
|
||||
EmitterException(const std::string& msg_)
|
||||
: Exception(Mark::null(), msg_) {}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,19 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
#include <memory>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Node;
|
||||
struct IterPriv;
|
||||
|
||||
class Iterator
|
||||
class YAML_CPP_API Iterator
|
||||
{
|
||||
public:
|
||||
Iterator();
|
||||
Iterator(IterPriv *pData);
|
||||
Iterator(std::auto_ptr<IterPriv> pData);
|
||||
Iterator(const Iterator& rhs);
|
||||
~Iterator();
|
||||
|
||||
@@ -25,11 +29,11 @@ namespace YAML
|
||||
const Node& first() const;
|
||||
const Node& second() const;
|
||||
|
||||
friend bool operator == (const Iterator& it, const Iterator& jt);
|
||||
friend bool operator != (const Iterator& it, const Iterator& jt);
|
||||
friend YAML_CPP_API bool operator == (const Iterator& it, const Iterator& jt);
|
||||
friend YAML_CPP_API bool operator != (const Iterator& it, const Iterator& jt);
|
||||
|
||||
private:
|
||||
IterPriv *m_pData;
|
||||
std::auto_ptr<IterPriv> m_pData;
|
||||
};
|
||||
}
|
||||
|
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef LTNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define LTNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
namespace YAML
|
||||
{
|
@@ -1,12 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#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 Mark {
|
||||
struct YAML_CPP_API Mark {
|
||||
Mark(): pos(0), line(0), column(0) {}
|
||||
|
||||
static const Mark null() { return Mark(-1, -1, -1); }
|
135
include/yaml-cpp/node.h
Normal file
135
include/yaml-cpp/node.h
Normal file
@@ -0,0 +1,135 @@
|
||||
#ifndef NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "yaml-cpp/conversion.h"
|
||||
#include "yaml-cpp/dll.h"
|
||||
#include "yaml-cpp/exceptions.h"
|
||||
#include "yaml-cpp/iterator.h"
|
||||
#include "yaml-cpp/ltnode.h"
|
||||
#include "yaml-cpp/mark.h"
|
||||
#include "yaml-cpp/noncopyable.h"
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class AliasManager;
|
||||
class Content;
|
||||
class NodeOwnership;
|
||||
class Scanner;
|
||||
class Emitter;
|
||||
class EventHandler;
|
||||
|
||||
struct NodeType { enum value { Null, Scalar, Sequence, Map }; };
|
||||
|
||||
class YAML_CPP_API Node: private noncopyable
|
||||
{
|
||||
public:
|
||||
friend class NodeOwnership;
|
||||
friend class NodeBuilder;
|
||||
|
||||
Node();
|
||||
~Node();
|
||||
|
||||
void Clear();
|
||||
std::auto_ptr<Node> Clone() const;
|
||||
void EmitEvents(EventHandler& eventHandler) const;
|
||||
void EmitEvents(AliasManager& am, EventHandler& eventHandler) const;
|
||||
|
||||
NodeType::value Type() const { return m_type; }
|
||||
bool IsAliased() const;
|
||||
|
||||
// file location of start of this node
|
||||
const Mark GetMark() const { return m_mark; }
|
||||
|
||||
// accessors
|
||||
Iterator begin() const;
|
||||
Iterator end() const;
|
||||
std::size_t size() const;
|
||||
|
||||
// extraction of scalars
|
||||
bool GetScalar(std::string& s) const;
|
||||
|
||||
// we can specialize this for other values
|
||||
template <typename T>
|
||||
bool Read(T& value) const;
|
||||
|
||||
template <typename T>
|
||||
const T to() const;
|
||||
|
||||
template <typename T>
|
||||
friend YAML_CPP_API void operator >> (const Node& node, T& value);
|
||||
|
||||
// retrieval for maps and sequences
|
||||
template <typename T>
|
||||
const Node *FindValue(const T& key) const;
|
||||
|
||||
template <typename T>
|
||||
const Node& operator [] (const T& key) const;
|
||||
|
||||
// specific to maps
|
||||
const Node *FindValue(const char *key) const;
|
||||
const Node *FindValue(char *key) const;
|
||||
const Node& operator [] (const char *key) const;
|
||||
const Node& operator [] (char *key) const;
|
||||
|
||||
// for tags
|
||||
const std::string& Tag() const { return m_tag; }
|
||||
|
||||
// emitting
|
||||
friend YAML_CPP_API Emitter& operator << (Emitter& out, const Node& node);
|
||||
|
||||
// ordering
|
||||
int Compare(const Node& rhs) const;
|
||||
friend bool operator < (const Node& n1, const Node& n2);
|
||||
|
||||
private:
|
||||
explicit Node(NodeOwnership& owner);
|
||||
Node& CreateNode();
|
||||
|
||||
void Init(NodeType::value type, const Mark& mark, const std::string& tag);
|
||||
|
||||
void MarkAsAliased();
|
||||
void SetScalarData(const std::string& data);
|
||||
void Append(Node& node);
|
||||
void Insert(Node& key, Node& value);
|
||||
|
||||
// helper for sequences
|
||||
template <typename, bool> friend struct _FindFromNodeAtIndex;
|
||||
const Node *FindAtIndex(std::size_t i) const;
|
||||
|
||||
// helper for maps
|
||||
template <typename T>
|
||||
const Node& GetValue(const T& key) const;
|
||||
|
||||
template <typename T>
|
||||
const Node *FindValueForKey(const T& key) const;
|
||||
|
||||
private:
|
||||
std::auto_ptr<NodeOwnership> m_pOwnership;
|
||||
|
||||
Mark m_mark;
|
||||
std::string m_tag;
|
||||
|
||||
typedef std::vector<Node *> node_seq;
|
||||
typedef std::map<Node *, Node *, ltnode> node_map;
|
||||
|
||||
NodeType::value m_type;
|
||||
std::string m_scalarData;
|
||||
node_seq m_seqData;
|
||||
node_map m_mapData;
|
||||
};
|
||||
}
|
||||
|
||||
#include "yaml-cpp/nodeimpl.h"
|
||||
#include "yaml-cpp/nodereadimpl.h"
|
||||
|
||||
#endif // NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
85
include/yaml-cpp/nodeimpl.h
Normal file
85
include/yaml-cpp/nodeimpl.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#ifndef NODEIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODEIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "yaml-cpp/nodeutil.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
// implementation of templated things
|
||||
template <typename T>
|
||||
inline const T Node::to() const {
|
||||
T value;
|
||||
*this >> value;
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void operator >> (const Node& node, T& value) {
|
||||
if(!ConvertScalar(node, value))
|
||||
throw InvalidScalar(node.m_mark);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const Node *Node::FindValue(const T& key) const {
|
||||
switch(m_type) {
|
||||
case NodeType::Null:
|
||||
case NodeType::Scalar:
|
||||
throw BadDereference();
|
||||
case NodeType::Sequence:
|
||||
return FindFromNodeAtIndex(*this, key);
|
||||
case NodeType::Map:
|
||||
return FindValueForKey(key);
|
||||
}
|
||||
assert(false);
|
||||
throw BadDereference();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const Node *Node::FindValueForKey(const T& key) const {
|
||||
for(Iterator it=begin();it!=end();++it) {
|
||||
T t;
|
||||
if(it.first().Read(t)) {
|
||||
if(key == t)
|
||||
return &it.second();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const Node& Node::GetValue(const T& key) const {
|
||||
if(const Node *pValue = FindValue(key))
|
||||
return *pValue;
|
||||
throw MakeTypedKeyNotFound(m_mark, key);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const Node& Node::operator [] (const T& key) const {
|
||||
return GetValue(key);
|
||||
}
|
||||
|
||||
inline const Node *Node::FindValue(const char *key) const {
|
||||
return FindValue(std::string(key));
|
||||
}
|
||||
|
||||
inline const Node *Node::FindValue(char *key) const {
|
||||
return FindValue(std::string(key));
|
||||
}
|
||||
|
||||
inline const Node& Node::operator [] (const char *key) const {
|
||||
return GetValue(std::string(key));
|
||||
}
|
||||
|
||||
inline const Node& Node::operator [] (char *key) const {
|
||||
return GetValue(std::string(key));
|
||||
}
|
||||
}
|
||||
|
||||
#endif // NODEIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,4 +1,10 @@
|
||||
#ifndef NODEREADIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODEREADIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
@@ -76,3 +82,5 @@ namespace YAML
|
||||
return Convert(scalar, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // NODEREADIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef NODEUTIL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODEUTIL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
namespace YAML
|
||||
{
|
25
include/yaml-cpp/noncopyable.h
Normal file
25
include/yaml-cpp/noncopyable.h
Normal file
@@ -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
|
@@ -1,20 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#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 _Null {};
|
||||
struct YAML_CPP_API _Null {};
|
||||
inline bool operator == (const _Null&, const _Null&) { return true; }
|
||||
inline bool operator != (const _Null&, const _Null&) { return false; }
|
||||
|
||||
bool IsNull(const Node& node);
|
||||
YAML_CPP_API bool IsNull(const Node& node);
|
||||
|
||||
extern _Null Null;
|
||||
extern YAML_CPP_API _Null Null;
|
||||
}
|
||||
|
||||
#endif // NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef OSTREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define OSTREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include <string>
|
||||
|
@@ -1,24 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#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 "node.h"
|
||||
#include "noncopyable.h"
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
#include "yaml-cpp/noncopyable.h"
|
||||
#include <ios>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Scanner;
|
||||
struct ParserState;
|
||||
struct Directives;
|
||||
struct Mark;
|
||||
struct Token;
|
||||
class EventHandler;
|
||||
class Node;
|
||||
class Scanner;
|
||||
|
||||
class Parser: private noncopyable
|
||||
class YAML_CPP_API Parser: private noncopyable
|
||||
{
|
||||
public:
|
||||
Parser();
|
||||
@@ -28,6 +30,8 @@ namespace YAML
|
||||
operator bool() const;
|
||||
|
||||
void Load(std::istream& in);
|
||||
bool HandleNextDocument(EventHandler& eventHandler);
|
||||
|
||||
bool GetNextDocument(Node& document);
|
||||
void PrintTokens(std::ostream& out);
|
||||
|
||||
@@ -36,10 +40,10 @@ namespace YAML
|
||||
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<ParserState> m_pState;
|
||||
std::auto_ptr<Directives> m_pDirectives;
|
||||
};
|
||||
}
|
||||
|
51
include/yaml-cpp/stlemitter.h
Normal file
51
include/yaml-cpp/stlemitter.h
Normal file
@@ -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
|
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef STLNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define STLNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#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
|
||||
{
|
||||
@@ -17,8 +19,13 @@ namespace YAML
|
||||
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 }; };
|
17
include/yaml-cpp/yaml.h
Normal file
17
include/yaml-cpp/yaml.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#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/node.h"
|
||||
#include "yaml-cpp/stlnode.h"
|
||||
#include "yaml-cpp/iterator.h"
|
||||
#include "yaml-cpp/emitter.h"
|
||||
#include "yaml-cpp/stlemitter.h"
|
||||
#include "yaml-cpp/exceptions.h"
|
||||
|
||||
#endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "parser.h"
|
||||
#include "node.h"
|
||||
#include "stlnode.h"
|
||||
#include "iterator.h"
|
||||
#include "emitter.h"
|
||||
#include "stlemitter.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
#endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
36
license.txt
36
license.txt
@@ -1,19 +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
|
||||
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.
|
||||
|
194
parse.vcproj
194
parse.vcproj
@@ -1,194 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="parse"
|
||||
ProjectGUID="{CD007B57-7812-4930-A5E2-6E5E56338814}"
|
||||
RootNamespace="parse"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/D_SCL_SECURE_NO_WARNINGS"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="include"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
DisableSpecificWarnings="4127;4355"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="yamlcppd.lib"
|
||||
AdditionalLibraryDirectories="lib"
|
||||
GenerateDebugInformation="true"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/D_SCL_SECURE_NO_WARNINGS"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="include"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4127;4355"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="yamlcpp.lib"
|
||||
AdditionalLibraryDirectories="lib"
|
||||
GenerateDebugInformation="true"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\util\parse.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
@@ -1,93 +0,0 @@
|
||||
#include "aliascontent.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
AliasContent::AliasContent(Content* pNodeContent)
|
||||
: m_pRef(pNodeContent)
|
||||
{
|
||||
}
|
||||
|
||||
Content *AliasContent::Clone() const
|
||||
{
|
||||
return 0; // TODO: how to clone an alias?
|
||||
}
|
||||
|
||||
void AliasContent::Parse(Scanner * /*pScanner*/, ParserState& /*state*/)
|
||||
{
|
||||
}
|
||||
|
||||
void AliasContent::Write(Emitter&) const
|
||||
{
|
||||
// no content (just an alias)
|
||||
}
|
||||
|
||||
bool AliasContent::GetBegin(std::vector <Node *>::const_iterator& i) const
|
||||
{
|
||||
return m_pRef->GetBegin(i);
|
||||
}
|
||||
|
||||
bool AliasContent::GetBegin(std::map <Node *, Node *, ltnode>::const_iterator& i) const
|
||||
{
|
||||
return m_pRef->GetBegin(i);
|
||||
}
|
||||
|
||||
bool AliasContent::GetEnd(std::vector <Node *>::const_iterator& i) const
|
||||
{
|
||||
return m_pRef->GetEnd(i);
|
||||
}
|
||||
|
||||
bool AliasContent::GetEnd(std::map <Node *, Node *, ltnode>::const_iterator& i) const
|
||||
{
|
||||
return m_pRef->GetEnd(i);
|
||||
}
|
||||
|
||||
Node* AliasContent::GetNode(std::size_t n) const
|
||||
{
|
||||
return m_pRef->GetNode(n);
|
||||
}
|
||||
|
||||
std::size_t AliasContent::GetSize() const
|
||||
{
|
||||
return m_pRef->GetSize();
|
||||
}
|
||||
|
||||
bool AliasContent::IsScalar() const
|
||||
{
|
||||
return m_pRef->IsScalar();
|
||||
}
|
||||
|
||||
bool AliasContent::IsMap() const
|
||||
{
|
||||
return m_pRef->IsMap();
|
||||
}
|
||||
|
||||
bool AliasContent::IsSequence() const
|
||||
{
|
||||
return m_pRef->IsSequence();
|
||||
}
|
||||
|
||||
bool AliasContent::GetScalar(std::string& scalar) const
|
||||
{
|
||||
return m_pRef->GetScalar(scalar);
|
||||
}
|
||||
|
||||
int AliasContent::Compare(Content *pContent)
|
||||
{
|
||||
return m_pRef->Compare(pContent);
|
||||
}
|
||||
|
||||
int AliasContent::Compare(Scalar *pScalar)
|
||||
{
|
||||
return m_pRef->Compare(pScalar);
|
||||
}
|
||||
|
||||
int AliasContent::Compare(Sequence *pSequence)
|
||||
{
|
||||
return m_pRef->Compare(pSequence);
|
||||
}
|
||||
|
||||
int AliasContent::Compare(Map *pMap)
|
||||
{
|
||||
return m_pRef->Compare(pMap);
|
||||
}
|
||||
}
|
@@ -1,43 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef ALIASCONTENT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define ALIASCONTENT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "content.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class AliasContent : public Content
|
||||
{
|
||||
public:
|
||||
AliasContent(Content *pNodeContent);
|
||||
|
||||
virtual Content *Clone() const;
|
||||
|
||||
virtual void Parse(Scanner* pScanner, ParserState& state);
|
||||
virtual void Write(Emitter&) const;
|
||||
|
||||
virtual bool GetBegin(std::vector <Node *>::const_iterator&) const;
|
||||
virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator&) const;
|
||||
virtual bool GetEnd(std::vector <Node *>::const_iterator&) const;
|
||||
virtual bool GetEnd(std::map <Node *, Node *, ltnode>::const_iterator&) const;
|
||||
virtual Node* GetNode(std::size_t) const;
|
||||
virtual std::size_t GetSize() const;
|
||||
virtual bool IsScalar() const;
|
||||
virtual bool IsMap() const;
|
||||
virtual bool IsSequence() const;
|
||||
|
||||
virtual bool GetScalar(std::string& s) const;
|
||||
|
||||
virtual int Compare(Content *);
|
||||
virtual int Compare(Scalar *);
|
||||
virtual int Compare(Sequence *);
|
||||
virtual int Compare(Map *);
|
||||
|
||||
private:
|
||||
Content* m_pRef;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ALIASCONTENT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
29
src/aliasmanager.cpp
Normal file
29
src/aliasmanager.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#include "yaml-cpp/aliasmanager.h"
|
||||
#include "yaml-cpp/node.h"
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
AliasManager::AliasManager(): m_curAnchor(0)
|
||||
{
|
||||
}
|
||||
|
||||
void AliasManager::RegisterReference(const Node& node)
|
||||
{
|
||||
m_anchorByIdentity.insert(std::make_pair(&node, _CreateNewAnchor()));
|
||||
}
|
||||
|
||||
anchor_t AliasManager::LookupAnchor(const Node& node) const
|
||||
{
|
||||
AnchorByIdentity::const_iterator it = m_anchorByIdentity.find(&node);
|
||||
if(it == m_anchorByIdentity.end())
|
||||
return 0;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
anchor_t AliasManager::_CreateNewAnchor()
|
||||
{
|
||||
return ++m_curAnchor;
|
||||
}
|
||||
}
|
35
src/collectionstack.h
Normal file
35
src/collectionstack.h
Normal file
@@ -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
|
@@ -1,57 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef CONTENT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define CONTENT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "parserstate.h"
|
||||
#include "exceptions.h"
|
||||
#include "ltnode.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Scanner;
|
||||
class Parser;
|
||||
class Node;
|
||||
class Scalar;
|
||||
class Sequence;
|
||||
class Map;
|
||||
class Emitter;
|
||||
|
||||
class Content
|
||||
{
|
||||
public:
|
||||
Content() {}
|
||||
virtual ~Content() {}
|
||||
|
||||
virtual Content *Clone() const = 0;
|
||||
|
||||
virtual void Parse(Scanner *pScanner, ParserState& state) = 0;
|
||||
virtual void Write(Emitter& out) const = 0;
|
||||
|
||||
virtual bool GetBegin(std::vector <Node *>::const_iterator&) const { return false; }
|
||||
virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator&) const { return false; }
|
||||
virtual bool GetEnd(std::vector <Node *>::const_iterator&) const { return false; }
|
||||
virtual bool GetEnd(std::map <Node *, Node *, ltnode>::const_iterator&) const { return false; }
|
||||
virtual Node *GetNode(std::size_t) const { return 0; }
|
||||
virtual std::size_t GetSize() const { return 0; }
|
||||
virtual bool IsScalar() const { return false; }
|
||||
virtual bool IsMap() const { return false; }
|
||||
virtual bool IsSequence() const { return false; }
|
||||
|
||||
// extraction
|
||||
virtual bool GetScalar(std::string&) const { return false; }
|
||||
|
||||
// ordering
|
||||
virtual int Compare(Content *) { return 0; }
|
||||
virtual int Compare(Scalar *) { return 0; }
|
||||
virtual int Compare(Sequence *) { return 0; }
|
||||
virtual int Compare(Map *) { return 0; }
|
||||
|
||||
protected:
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CONTENT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
16
src/contrib/graphbuilder.cpp
Normal file
16
src/contrib/graphbuilder.cpp
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
96
src/contrib/graphbuilderadapter.cpp
Normal file
96
src/contrib/graphbuilderadapter.cpp
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
73
src/contrib/graphbuilderadapter.h
Normal file
73
src/contrib/graphbuilderadapter.h
Normal file
@@ -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
|
@@ -1,4 +1,4 @@
|
||||
#include "conversion.h"
|
||||
#include "yaml-cpp/conversion.h"
|
||||
#include <algorithm>
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
@@ -1,16 +1,16 @@
|
||||
#include "parserstate.h"
|
||||
#include "directives.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
ParserState::ParserState()
|
||||
Directives::Directives()
|
||||
{
|
||||
// version
|
||||
version.isDefault = true;
|
||||
version.major = 1;
|
||||
version.minor = 2;
|
||||
}
|
||||
|
||||
const std::string ParserState::TranslateTagHandle(const std::string& handle) const
|
||||
|
||||
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()) {
|
||||
@@ -18,7 +18,7 @@ namespace YAML
|
||||
return "tag:yaml.org,2002:";
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
return it->second;
|
||||
}
|
||||
}
|
29
src/directives.h
Normal file
29
src/directives.h
Normal file
@@ -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
|
105
src/emitfromevents.cpp
Normal file
105
src/emitfromevents.cpp
Normal file
@@ -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));
|
||||
}
|
||||
}
|
259
src/emitter.cpp
259
src/emitter.cpp
@@ -1,8 +1,8 @@
|
||||
#include "emitter.h"
|
||||
#include "yaml-cpp/emitter.h"
|
||||
#include "emitterstate.h"
|
||||
#include "emitterutils.h"
|
||||
#include "indentation.h"
|
||||
#include "exceptions.h"
|
||||
#include "yaml-cpp/exceptions.h"
|
||||
#include <sstream>
|
||||
|
||||
namespace YAML
|
||||
@@ -102,6 +102,12 @@ namespace YAML
|
||||
return *this;
|
||||
|
||||
switch(value) {
|
||||
case BeginDoc:
|
||||
EmitBeginDoc();
|
||||
break;
|
||||
case EndDoc:
|
||||
EmitEndDoc();
|
||||
break;
|
||||
case BeginSeq:
|
||||
EmitBeginSeq();
|
||||
break;
|
||||
@@ -120,6 +126,12 @@ namespace YAML
|
||||
case Value:
|
||||
EmitValue();
|
||||
break;
|
||||
case TagByKind:
|
||||
EmitKindTag();
|
||||
break;
|
||||
case Newline:
|
||||
EmitNewline();
|
||||
break;
|
||||
default:
|
||||
m_pState->SetLocalValue(value);
|
||||
break;
|
||||
@@ -146,17 +158,18 @@ namespace YAML
|
||||
switch(curState) {
|
||||
// document-level
|
||||
case ES_WAITING_FOR_DOC:
|
||||
m_stream << "---";
|
||||
m_pState->RequireSeparation();
|
||||
m_pState->SwitchState(ES_WRITING_DOC);
|
||||
return true;
|
||||
case ES_WRITING_DOC:
|
||||
return true;
|
||||
case ES_DONE_WITH_DOC:
|
||||
EmitBeginDoc();
|
||||
return false;
|
||||
|
||||
// block sequence
|
||||
case ES_WAITING_FOR_BLOCK_SEQ_ENTRY:
|
||||
m_stream << IndentTo(curIndent) << "-";
|
||||
m_pState->RequireSeparation();
|
||||
m_pState->RequireSoftSeparation();
|
||||
m_pState->SwitchState(ES_WRITING_BLOCK_SEQ_ENTRY);
|
||||
return true;
|
||||
case ES_WRITING_BLOCK_SEQ_ENTRY:
|
||||
@@ -173,8 +186,9 @@ namespace YAML
|
||||
case ES_WRITING_FLOW_SEQ_ENTRY:
|
||||
return true;
|
||||
case ES_DONE_WITH_FLOW_SEQ_ENTRY:
|
||||
EmitSeparationIfNecessary();
|
||||
m_stream << ',';
|
||||
m_pState->RequireSeparation();
|
||||
m_pState->RequireSoftSeparation();
|
||||
m_pState->SwitchState(ES_WAITING_FOR_FLOW_SEQ_ENTRY);
|
||||
return false;
|
||||
|
||||
@@ -185,7 +199,7 @@ namespace YAML
|
||||
case ES_WAITING_FOR_BLOCK_MAP_KEY:
|
||||
if(m_pState->CurrentlyInLongKey()) {
|
||||
m_stream << IndentTo(curIndent) << '?';
|
||||
m_pState->RequireSeparation();
|
||||
m_pState->RequireSoftSeparation();
|
||||
}
|
||||
m_pState->SwitchState(ES_WRITING_BLOCK_MAP_KEY);
|
||||
return true;
|
||||
@@ -195,10 +209,6 @@ namespace YAML
|
||||
m_pState->SetError(ErrorMsg::EXPECTED_VALUE_TOKEN);
|
||||
return true;
|
||||
case ES_WAITING_FOR_BLOCK_MAP_VALUE:
|
||||
if(m_pState->CurrentlyInLongKey())
|
||||
m_stream << IndentTo(curIndent);
|
||||
m_stream << ':';
|
||||
m_pState->RequireSeparation();
|
||||
m_pState->SwitchState(ES_WRITING_BLOCK_MAP_VALUE);
|
||||
return true;
|
||||
case ES_WRITING_BLOCK_MAP_VALUE:
|
||||
@@ -212,11 +222,11 @@ namespace YAML
|
||||
m_pState->SetError(ErrorMsg::EXPECTED_KEY_TOKEN);
|
||||
return true;
|
||||
case ES_WAITING_FOR_FLOW_MAP_KEY:
|
||||
EmitSeparationIfNecessary();
|
||||
m_pState->SwitchState(ES_WRITING_FLOW_MAP_KEY);
|
||||
if(m_pState->CurrentlyInLongKey()) {
|
||||
EmitSeparationIfNecessary();
|
||||
m_stream << '?';
|
||||
m_pState->RequireSeparation();
|
||||
m_pState->RequireSoftSeparation();
|
||||
}
|
||||
return true;
|
||||
case ES_WRITING_FLOW_MAP_KEY:
|
||||
@@ -225,8 +235,9 @@ namespace YAML
|
||||
m_pState->SetError(ErrorMsg::EXPECTED_VALUE_TOKEN);
|
||||
return true;
|
||||
case ES_WAITING_FOR_FLOW_MAP_VALUE:
|
||||
EmitSeparationIfNecessary();
|
||||
m_stream << ':';
|
||||
m_pState->RequireSeparation();
|
||||
m_pState->RequireSoftSeparation();
|
||||
m_pState->SwitchState(ES_WRITING_FLOW_MAP_VALUE);
|
||||
return true;
|
||||
case ES_WRITING_FLOW_MAP_VALUE:
|
||||
@@ -280,6 +291,10 @@ namespace YAML
|
||||
|
||||
// block map
|
||||
case ES_WRITING_BLOCK_MAP_KEY:
|
||||
if(!m_pState->CurrentlyInLongKey()) {
|
||||
m_stream << ':';
|
||||
m_pState->RequireSoftSeparation();
|
||||
}
|
||||
m_pState->SwitchState(ES_DONE_WITH_BLOCK_MAP_KEY);
|
||||
break;
|
||||
case ES_WRITING_BLOCK_MAP_VALUE:
|
||||
@@ -306,11 +321,54 @@ namespace YAML
|
||||
if(!good())
|
||||
return;
|
||||
|
||||
if(m_pState->RequiresSeparation())
|
||||
if(m_pState->RequiresSoftSeparation())
|
||||
m_stream << ' ';
|
||||
else if(m_pState->RequiresHardSeparation())
|
||||
m_stream << '\n';
|
||||
m_pState->UnsetSeparation();
|
||||
}
|
||||
|
||||
// EmitBeginDoc
|
||||
void Emitter::EmitBeginDoc()
|
||||
{
|
||||
if(!good())
|
||||
return;
|
||||
|
||||
EMITTER_STATE curState = m_pState->GetCurState();
|
||||
if(curState != ES_WAITING_FOR_DOC && curState != ES_WRITING_DOC && curState != ES_DONE_WITH_DOC) {
|
||||
m_pState->SetError("Unexpected begin document");
|
||||
return;
|
||||
}
|
||||
|
||||
if(curState == ES_WRITING_DOC || curState == ES_DONE_WITH_DOC)
|
||||
m_stream << '\n';
|
||||
m_stream << "---\n";
|
||||
|
||||
m_pState->UnsetSeparation();
|
||||
m_pState->SwitchState(ES_WAITING_FOR_DOC);
|
||||
}
|
||||
|
||||
// EmitEndDoc
|
||||
void Emitter::EmitEndDoc()
|
||||
{
|
||||
if(!good())
|
||||
return;
|
||||
|
||||
|
||||
EMITTER_STATE curState = m_pState->GetCurState();
|
||||
if(curState != ES_WAITING_FOR_DOC && curState != ES_WRITING_DOC && curState != ES_DONE_WITH_DOC) {
|
||||
m_pState->SetError("Unexpected end document");
|
||||
return;
|
||||
}
|
||||
|
||||
if(curState == ES_WRITING_DOC || curState == ES_DONE_WITH_DOC)
|
||||
m_stream << '\n';
|
||||
m_stream << "...\n";
|
||||
|
||||
m_pState->UnsetSeparation();
|
||||
m_pState->SwitchState(ES_WAITING_FOR_DOC);
|
||||
}
|
||||
|
||||
// EmitBeginSeq
|
||||
void Emitter::EmitBeginSeq()
|
||||
{
|
||||
@@ -329,8 +387,10 @@ namespace YAML
|
||||
curState == ES_WRITING_BLOCK_MAP_KEY || curState == ES_WRITING_BLOCK_MAP_VALUE ||
|
||||
curState == ES_WRITING_DOC
|
||||
) {
|
||||
m_stream << "\n";
|
||||
m_pState->UnsetSeparation();
|
||||
if(m_pState->RequiresHardSeparation() || curState != ES_WRITING_DOC) {
|
||||
m_stream << "\n";
|
||||
m_pState->UnsetSeparation();
|
||||
}
|
||||
}
|
||||
m_pState->PushState(ES_WAITING_FOR_BLOCK_SEQ_ENTRY);
|
||||
} else if(flowType == Flow) {
|
||||
@@ -397,8 +457,10 @@ namespace YAML
|
||||
curState == ES_WRITING_BLOCK_MAP_KEY || curState == ES_WRITING_BLOCK_MAP_VALUE ||
|
||||
curState == ES_WRITING_DOC
|
||||
) {
|
||||
m_stream << "\n";
|
||||
m_pState->UnsetSeparation();
|
||||
if(m_pState->RequiresHardSeparation() || (curState != ES_WRITING_DOC && curState != ES_WRITING_BLOCK_SEQ_ENTRY)) {
|
||||
m_stream << "\n";
|
||||
m_pState->UnsetSeparation();
|
||||
}
|
||||
}
|
||||
m_pState->PushState(ES_WAITING_FOR_BLOCK_MAP_ENTRY);
|
||||
} else if(flowType == Flow) {
|
||||
@@ -436,6 +498,7 @@ namespace YAML
|
||||
} else if(flowType == FT_FLOW) {
|
||||
// Note: flow maps are allowed to be empty
|
||||
assert(curState == ES_DONE_WITH_FLOW_MAP_VALUE || curState == ES_WAITING_FOR_FLOW_MAP_ENTRY);
|
||||
EmitSeparationIfNecessary();
|
||||
m_stream << "}";
|
||||
} else
|
||||
assert(false);
|
||||
@@ -463,11 +526,13 @@ namespace YAML
|
||||
m_stream << '\n';
|
||||
unsigned curIndent = m_pState->GetCurIndent();
|
||||
m_stream << IndentTo(curIndent);
|
||||
m_pState->UnsetSeparation();
|
||||
m_pState->SwitchState(ES_WAITING_FOR_BLOCK_MAP_KEY);
|
||||
} else if(flowType == FT_FLOW) {
|
||||
EmitSeparationIfNecessary();
|
||||
if(curState == ES_DONE_WITH_FLOW_MAP_VALUE) {
|
||||
m_stream << ',';
|
||||
m_pState->RequireSeparation();
|
||||
m_pState->RequireSoftSeparation();
|
||||
}
|
||||
m_pState->SwitchState(ES_WAITING_FOR_FLOW_MAP_KEY);
|
||||
} else
|
||||
@@ -493,8 +558,12 @@ namespace YAML
|
||||
return m_pState->SetError(ErrorMsg::UNEXPECTED_VALUE_TOKEN);
|
||||
|
||||
if(flowType == FT_BLOCK) {
|
||||
if(m_pState->CurrentlyInLongKey())
|
||||
if(m_pState->CurrentlyInLongKey()) {
|
||||
m_stream << '\n';
|
||||
m_stream << IndentTo(m_pState->GetCurIndent());
|
||||
m_stream << ':';
|
||||
m_pState->RequireSoftSeparation();
|
||||
}
|
||||
m_pState->SwitchState(ES_WAITING_FOR_BLOCK_MAP_VALUE);
|
||||
} else if(flowType == FT_FLOW) {
|
||||
m_pState->SwitchState(ES_WAITING_FOR_FLOW_MAP_VALUE);
|
||||
@@ -502,6 +571,28 @@ namespace YAML
|
||||
assert(false);
|
||||
}
|
||||
|
||||
// EmitNewline
|
||||
void Emitter::EmitNewline()
|
||||
{
|
||||
if(!good())
|
||||
return;
|
||||
|
||||
if(CanEmitNewline()) {
|
||||
m_stream << '\n';
|
||||
m_pState->UnsetSeparation();
|
||||
}
|
||||
}
|
||||
|
||||
bool Emitter::CanEmitNewline() const
|
||||
{
|
||||
FLOW_TYPE flowType = m_pState->GetCurGroupFlowType();
|
||||
if(flowType == FT_BLOCK && m_pState->CurrentlyInLongKey())
|
||||
return true;
|
||||
|
||||
EMITTER_STATE curState = m_pState->GetCurState();
|
||||
return curState != ES_DONE_WITH_BLOCK_MAP_KEY && curState != ES_WAITING_FOR_BLOCK_MAP_VALUE && curState != ES_WRITING_BLOCK_MAP_VALUE;
|
||||
}
|
||||
|
||||
// *******************************************************************************************
|
||||
// overloads of Write
|
||||
|
||||
@@ -548,7 +639,7 @@ namespace YAML
|
||||
PostAtomicWrite();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void Emitter::PreWriteIntegralType(std::stringstream& str)
|
||||
{
|
||||
PreAtomicWrite();
|
||||
@@ -569,13 +660,61 @@ namespace YAML
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Emitter::PreWriteStreamable(std::stringstream& str)
|
||||
{
|
||||
PreAtomicWrite();
|
||||
EmitSeparationIfNecessary();
|
||||
str.precision(15);
|
||||
}
|
||||
|
||||
void Emitter::PostWriteIntegralType(const std::stringstream& str)
|
||||
{
|
||||
m_stream << str.str();
|
||||
PostAtomicWrite();
|
||||
}
|
||||
|
||||
|
||||
void Emitter::PostWriteStreamable(const std::stringstream& str)
|
||||
{
|
||||
m_stream << str.str();
|
||||
PostAtomicWrite();
|
||||
}
|
||||
|
||||
const char *Emitter::ComputeFullBoolName(bool b) const
|
||||
{
|
||||
const EMITTER_MANIP mainFmt = (m_pState->GetBoolLengthFormat() == ShortBool ? YesNoBool : m_pState->GetBoolFormat());
|
||||
const EMITTER_MANIP caseFmt = m_pState->GetBoolCaseFormat();
|
||||
switch(mainFmt) {
|
||||
case YesNoBool:
|
||||
switch(caseFmt) {
|
||||
case UpperCase: return b ? "YES" : "NO";
|
||||
case CamelCase: return b ? "Yes" : "No";
|
||||
case LowerCase: return b ? "yes" : "no";
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
case OnOffBool:
|
||||
switch(caseFmt) {
|
||||
case UpperCase: return b ? "ON" : "OFF";
|
||||
case CamelCase: return b ? "On" : "Off";
|
||||
case LowerCase: return b ? "on" : "off";
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
case TrueFalseBool:
|
||||
switch(caseFmt) {
|
||||
case UpperCase: return b ? "TRUE" : "FALSE";
|
||||
case CamelCase: return b ? "True" : "False";
|
||||
case LowerCase: return b ? "true" : "false";
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return b ? "y" : "n"; // should never get here, but it can't hurt to give these answers
|
||||
}
|
||||
|
||||
Emitter& Emitter::Write(bool b)
|
||||
{
|
||||
if(!good())
|
||||
@@ -583,34 +722,13 @@ namespace YAML
|
||||
|
||||
PreAtomicWrite();
|
||||
EmitSeparationIfNecessary();
|
||||
|
||||
// set up all possible bools to write
|
||||
struct BoolName { std::string trueName, falseName; };
|
||||
struct BoolFormatNames { BoolName upper, lower, camel; };
|
||||
struct BoolTypes { BoolFormatNames yesNo, trueFalse, onOff; };
|
||||
|
||||
static const BoolTypes boolTypes = {
|
||||
{ { "YES", "NO" }, { "yes", "no" }, { "Yes", "No" } },
|
||||
{ { "TRUE", "FALSE" }, { "true", "false" }, { "True", "False" } },
|
||||
{ { "ON", "OFF" }, { "on", "off" }, { "On", "Off" } }
|
||||
};
|
||||
|
||||
// select the right one
|
||||
EMITTER_MANIP boolFmt = m_pState->GetBoolFormat();
|
||||
EMITTER_MANIP boolLengthFmt = m_pState->GetBoolLengthFormat();
|
||||
EMITTER_MANIP boolCaseFmt = m_pState->GetBoolCaseFormat();
|
||||
|
||||
const BoolFormatNames& fmtNames = (boolFmt == YesNoBool ? boolTypes.yesNo : boolFmt == TrueFalseBool ? boolTypes.trueFalse : boolTypes.onOff);
|
||||
const BoolName& boolName = (boolCaseFmt == UpperCase ? fmtNames.upper : boolCaseFmt == LowerCase ? fmtNames.lower : fmtNames.camel);
|
||||
const std::string& name = (b ? boolName.trueName : boolName.falseName);
|
||||
|
||||
// and say it!
|
||||
// TODO: should we disallow writing OnOffBool with ShortBool? (it'll just print "o" for both, which is silly)
|
||||
if(boolLengthFmt == ShortBool)
|
||||
|
||||
const char *name = ComputeFullBoolName(b);
|
||||
if(m_pState->GetBoolLengthFormat() == ShortBool)
|
||||
m_stream << name[0];
|
||||
else
|
||||
m_stream << name;
|
||||
|
||||
|
||||
PostAtomicWrite();
|
||||
return *this;
|
||||
}
|
||||
@@ -641,7 +759,7 @@ namespace YAML
|
||||
m_pState->SetError(ErrorMsg::INVALID_ANCHOR);
|
||||
return *this;
|
||||
}
|
||||
m_pState->RequireSeparation();
|
||||
m_pState->RequireHardSeparation();
|
||||
// Note: no PostAtomicWrite() because we need another value for this node
|
||||
return *this;
|
||||
}
|
||||
@@ -650,25 +768,44 @@ namespace YAML
|
||||
{
|
||||
if(!good())
|
||||
return *this;
|
||||
|
||||
|
||||
PreAtomicWrite();
|
||||
EmitSeparationIfNecessary();
|
||||
if(!Utils::WriteTag(m_stream, tag.content)) {
|
||||
|
||||
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->RequireSeparation();
|
||||
|
||||
m_pState->RequireHardSeparation();
|
||||
// Note: no PostAtomicWrite() because we need another value for this node
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Emitter::EmitKindTag()
|
||||
{
|
||||
Write(LocalTag(""));
|
||||
}
|
||||
|
||||
Emitter& Emitter::Write(const _Comment& comment)
|
||||
{
|
||||
if(!good())
|
||||
return *this;
|
||||
|
||||
m_stream << Indentation(m_pState->GetPreCommentIndent());
|
||||
if(m_stream.col() > 0)
|
||||
m_stream << Indentation(m_pState->GetPreCommentIndent());
|
||||
Utils::WriteComment(m_stream, comment.content, m_pState->GetPostCommentIndent());
|
||||
m_pState->RequireHardSeparation();
|
||||
m_pState->ForceHardSeparation();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -683,5 +820,19 @@ namespace YAML
|
||||
PostAtomicWrite();
|
||||
return *this;
|
||||
}
|
||||
|
||||
Emitter& Emitter::Write(const _Binary& binary)
|
||||
{
|
||||
Write(SecondaryTag("binary"));
|
||||
|
||||
if(!good())
|
||||
return *this;
|
||||
|
||||
PreAtomicWrite();
|
||||
EmitSeparationIfNecessary();
|
||||
Utils::WriteBinary(m_stream, binary.data, binary.size);
|
||||
PostAtomicWrite();
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,9 +1,9 @@
|
||||
#include "emitterstate.h"
|
||||
#include "exceptions.h"
|
||||
#include "yaml-cpp/exceptions.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
EmitterState::EmitterState(): m_isGood(true), m_curIndent(0), m_requiresSeparation(false)
|
||||
EmitterState::EmitterState(): m_isGood(true), m_curIndent(0), m_requiresSoftSeparation(false), m_requiresHardSeparation(false)
|
||||
{
|
||||
// start up
|
||||
m_stateStack.push(ES_WAITING_FOR_DOC);
|
||||
@@ -25,18 +25,6 @@ namespace YAML
|
||||
|
||||
EmitterState::~EmitterState()
|
||||
{
|
||||
while(!m_groups.empty())
|
||||
_PopGroup();
|
||||
}
|
||||
|
||||
std::auto_ptr <EmitterState::Group> EmitterState::_PopGroup()
|
||||
{
|
||||
if(m_groups.empty())
|
||||
return std::auto_ptr <Group> (0);
|
||||
|
||||
std::auto_ptr <Group> pGroup(m_groups.top());
|
||||
m_groups.pop();
|
||||
return pGroup;
|
||||
}
|
||||
|
||||
// SetLocalValue
|
||||
@@ -57,10 +45,10 @@ namespace YAML
|
||||
|
||||
void EmitterState::BeginGroup(GROUP_TYPE type)
|
||||
{
|
||||
unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top()->indent);
|
||||
unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
|
||||
m_curIndent += lastIndent;
|
||||
|
||||
std::auto_ptr <Group> pGroup(new Group(type));
|
||||
std::auto_ptr<Group> pGroup(new Group(type));
|
||||
|
||||
// transfer settings (which last until this group is done)
|
||||
pGroup->modifiedSettings = m_modifiedSettings;
|
||||
@@ -70,7 +58,7 @@ namespace YAML
|
||||
pGroup->indent = GetIndent();
|
||||
pGroup->usingLongKey = (GetMapKeyFormat() == LongKey ? true : false);
|
||||
|
||||
m_groups.push(pGroup.release());
|
||||
m_groups.push(pGroup);
|
||||
}
|
||||
|
||||
void EmitterState::EndGroup(GROUP_TYPE type)
|
||||
@@ -80,13 +68,13 @@ namespace YAML
|
||||
|
||||
// get rid of the current group
|
||||
{
|
||||
std::auto_ptr <Group> pFinishedGroup = _PopGroup();
|
||||
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);
|
||||
unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
|
||||
assert(m_curIndent >= lastIndent);
|
||||
m_curIndent -= lastIndent;
|
||||
|
||||
@@ -100,7 +88,7 @@ namespace YAML
|
||||
if(m_groups.empty())
|
||||
return GT_NONE;
|
||||
|
||||
return m_groups.top()->type;
|
||||
return m_groups.top().type;
|
||||
}
|
||||
|
||||
FLOW_TYPE EmitterState::GetCurGroupFlowType() const
|
||||
@@ -108,26 +96,26 @@ namespace YAML
|
||||
if(m_groups.empty())
|
||||
return FT_NONE;
|
||||
|
||||
return (m_groups.top()->flow == Flow ? FT_FLOW : FT_BLOCK);
|
||||
return (m_groups.top().flow == Flow ? FT_FLOW : FT_BLOCK);
|
||||
}
|
||||
|
||||
bool EmitterState::CurrentlyInLongKey()
|
||||
{
|
||||
if(m_groups.empty())
|
||||
return false;
|
||||
return m_groups.top()->usingLongKey;
|
||||
return m_groups.top().usingLongKey;
|
||||
}
|
||||
|
||||
void EmitterState::StartLongKey()
|
||||
{
|
||||
if(!m_groups.empty())
|
||||
m_groups.top()->usingLongKey = true;
|
||||
m_groups.top().usingLongKey = true;
|
||||
}
|
||||
|
||||
void EmitterState::StartSimpleKey()
|
||||
{
|
||||
if(!m_groups.empty())
|
||||
m_groups.top()->usingLongKey = false;
|
||||
m_groups.top().usingLongKey = false;
|
||||
}
|
||||
|
||||
void EmitterState::ClearModifiedSettings()
|
||||
|
@@ -1,11 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#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 "emittermanip.h"
|
||||
#include "yaml-cpp/emittermanip.h"
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
@@ -101,9 +104,12 @@ namespace YAML
|
||||
void StartLongKey();
|
||||
void StartSimpleKey();
|
||||
|
||||
bool RequiresSeparation() const { return m_requiresSeparation; }
|
||||
void RequireSeparation() { m_requiresSeparation = true; }
|
||||
void UnsetSeparation() { m_requiresSeparation = false; }
|
||||
bool RequiresSoftSeparation() const { return m_requiresSoftSeparation; }
|
||||
bool RequiresHardSeparation() const { return m_requiresHardSeparation; }
|
||||
void RequireSoftSeparation() { m_requiresSoftSeparation = true; }
|
||||
void RequireHardSeparation() { m_requiresSoftSeparation = true; m_requiresHardSeparation = true; }
|
||||
void ForceHardSeparation() { m_requiresSoftSeparation = false; }
|
||||
void UnsetSeparation() { m_requiresSoftSeparation = false; m_requiresHardSeparation = false; }
|
||||
|
||||
void ClearModifiedSettings();
|
||||
|
||||
@@ -150,19 +156,19 @@ namespace YAML
|
||||
std::string m_lastError;
|
||||
|
||||
// other state
|
||||
std::stack <EMITTER_STATE> m_stateStack;
|
||||
std::stack<EMITTER_STATE> m_stateStack;
|
||||
|
||||
Setting <EMITTER_MANIP> m_charset;
|
||||
Setting <EMITTER_MANIP> m_strFmt;
|
||||
Setting <EMITTER_MANIP> m_boolFmt;
|
||||
Setting <EMITTER_MANIP> m_boolLengthFmt;
|
||||
Setting <EMITTER_MANIP> m_boolCaseFmt;
|
||||
Setting <EMITTER_MANIP> m_intFmt;
|
||||
Setting <unsigned> m_indent;
|
||||
Setting <unsigned> m_preCommentIndent, m_postCommentIndent;
|
||||
Setting <EMITTER_MANIP> m_seqFmt;
|
||||
Setting <EMITTER_MANIP> m_mapFmt;
|
||||
Setting <EMITTER_MANIP> m_mapKeyFmt;
|
||||
Setting<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;
|
||||
|
||||
SettingChanges m_modifiedSettings;
|
||||
SettingChanges m_globalModifiedSettings;
|
||||
@@ -177,12 +183,11 @@ namespace YAML
|
||||
|
||||
SettingChanges modifiedSettings;
|
||||
};
|
||||
|
||||
std::auto_ptr <Group> _PopGroup();
|
||||
|
||||
std::stack <Group *> m_groups;
|
||||
|
||||
ptr_stack<Group> m_groups;
|
||||
unsigned m_curIndent;
|
||||
bool m_requiresSeparation;
|
||||
bool m_requiresSoftSeparation;
|
||||
bool m_requiresHardSeparation;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#include "emitterutils.h"
|
||||
#include "exp.h"
|
||||
#include "indentation.h"
|
||||
#include "exceptions.h"
|
||||
#include "yaml-cpp/exceptions.h"
|
||||
#include "stringsource.h"
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
@@ -128,6 +128,9 @@ namespace YAML
|
||||
}
|
||||
|
||||
bool IsValidPlainScalar(const std::string& str, bool inFlow, bool allowOnlyAscii) {
|
||||
if(str.empty())
|
||||
return false;
|
||||
|
||||
// first check the start
|
||||
const RegEx& start = (inFlow ? Exp::PlainScalarInFlow() : Exp::PlainScalar());
|
||||
if(!start.Matches(str))
|
||||
@@ -267,7 +270,7 @@ namespace YAML
|
||||
|
||||
bool WriteComment(ostream& out, const std::string& str, int postCommentIndent)
|
||||
{
|
||||
unsigned curIndent = out.col();
|
||||
const unsigned curIndent = out.col();
|
||||
out << "#" << Indentation(postCommentIndent);
|
||||
int codePoint;
|
||||
for(std::string::const_iterator i = str.begin();
|
||||
@@ -294,12 +297,13 @@ namespace YAML
|
||||
return WriteAliasName(out, str);
|
||||
}
|
||||
|
||||
bool WriteTag(ostream& out, const std::string& str)
|
||||
bool WriteTag(ostream& out, const std::string& str, bool verbatim)
|
||||
{
|
||||
out << "!<";
|
||||
out << (verbatim ? "!<" : "!");
|
||||
StringCharSource buffer(str.c_str(), str.size());
|
||||
const RegEx& reValid = verbatim ? Exp::URI() : Exp::Tag();
|
||||
while(buffer) {
|
||||
int n = Exp::URI().Match(buffer);
|
||||
int n = reValid.Match(buffer);
|
||||
if(n <= 0)
|
||||
return false;
|
||||
|
||||
@@ -308,7 +312,75 @@ namespace YAML
|
||||
++buffer;
|
||||
}
|
||||
}
|
||||
out << ">";
|
||||
if (verbatim)
|
||||
out << ">";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteTagWithPrefix(ostream& out, const std::string& prefix, const std::string& tag)
|
||||
{
|
||||
out << "!";
|
||||
StringCharSource prefixBuffer(prefix.c_str(), prefix.size());
|
||||
while(prefixBuffer) {
|
||||
int n = Exp::URI().Match(prefixBuffer);
|
||||
if(n <= 0)
|
||||
return false;
|
||||
|
||||
while(--n >= 0) {
|
||||
out << prefixBuffer[0];
|
||||
++prefixBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
out << "!";
|
||||
StringCharSource tagBuffer(tag.c_str(), tag.size());
|
||||
while(tagBuffer) {
|
||||
int n = Exp::Tag().Match(tagBuffer);
|
||||
if(n <= 0)
|
||||
return false;
|
||||
|
||||
while(--n >= 0) {
|
||||
out << tagBuffer[0];
|
||||
++tagBuffer;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteBinary(ostream& out, const unsigned char *data, std::size_t size)
|
||||
{
|
||||
static const char encoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
const char PAD = '=';
|
||||
|
||||
out << "\"";
|
||||
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;
|
||||
}
|
||||
|
||||
out << "\"";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@@ -1,10 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#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 "ostream.h"
|
||||
|
||||
#include "yaml-cpp/ostream.h"
|
||||
#include <string>
|
||||
|
||||
namespace YAML
|
||||
@@ -18,7 +20,9 @@ namespace YAML
|
||||
bool WriteComment(ostream& out, const std::string& str, int postCommentIndent);
|
||||
bool WriteAlias(ostream& out, const std::string& str);
|
||||
bool WriteAnchor(ostream& out, const std::string& str);
|
||||
bool WriteTag(ostream& out, const std::string& str);
|
||||
bool WriteTag(ostream& out, const std::string& str, bool verbatim);
|
||||
bool WriteTagWithPrefix(ostream& out, const std::string& prefix, const std::string& tag);
|
||||
bool WriteBinary(ostream& out, const unsigned char *data, std::size_t size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#include "exp.h"
|
||||
#include "exceptions.h"
|
||||
#include "yaml-cpp/exceptions.h"
|
||||
#include <sstream>
|
||||
|
||||
namespace YAML
|
||||
@@ -107,7 +107,7 @@ namespace YAML
|
||||
}
|
||||
|
||||
std::stringstream msg;
|
||||
throw ParserException(in.mark(), ErrorMsg::INVALID_ESCAPE + ch);
|
||||
throw ParserException(in.mark(), std::string(ErrorMsg::INVALID_ESCAPE) + ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
10
src/exp.h
10
src/exp.h
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#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>
|
||||
@@ -112,6 +114,10 @@ namespace YAML
|
||||
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;
|
||||
|
@@ -1,10 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#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 "ostream.h"
|
||||
|
||||
#include "yaml-cpp/ostream.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace YAML
|
||||
|
@@ -1,21 +1,19 @@
|
||||
#include "node.h"
|
||||
#include "exceptions.h"
|
||||
#include "yaml-cpp/node.h"
|
||||
#include "yaml-cpp/exceptions.h"
|
||||
#include "iterpriv.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
Iterator::Iterator(): m_pData(0)
|
||||
{
|
||||
m_pData = new IterPriv;
|
||||
}
|
||||
|
||||
Iterator::Iterator(IterPriv *pData): m_pData(pData)
|
||||
Iterator::Iterator(): m_pData(new IterPriv)
|
||||
{
|
||||
}
|
||||
|
||||
Iterator::Iterator(const Iterator& rhs): m_pData(0)
|
||||
Iterator::Iterator(std::auto_ptr<IterPriv> pData): m_pData(pData)
|
||||
{
|
||||
}
|
||||
|
||||
Iterator::Iterator(const Iterator& rhs): m_pData(new IterPriv(*rhs.m_pData))
|
||||
{
|
||||
m_pData = new IterPriv(*rhs.m_pData);
|
||||
}
|
||||
|
||||
Iterator& Iterator::operator = (const Iterator& rhs)
|
||||
@@ -23,14 +21,12 @@ namespace YAML
|
||||
if(this == &rhs)
|
||||
return *this;
|
||||
|
||||
delete m_pData;
|
||||
m_pData = new IterPriv(*rhs.m_pData);
|
||||
m_pData.reset(new IterPriv(*rhs.m_pData));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator::~Iterator()
|
||||
{
|
||||
delete m_pData;
|
||||
}
|
||||
|
||||
Iterator& Iterator::operator ++ ()
|
||||
|
@@ -1,10 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef ITERPRIV_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define ITERPRIV_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "ltnode.h"
|
||||
|
||||
#include "yaml-cpp/ltnode.h"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
|
238
src/map.cpp
238
src/map.cpp
@@ -1,238 +0,0 @@
|
||||
#include "map.h"
|
||||
#include "node.h"
|
||||
#include "scanner.h"
|
||||
#include "token.h"
|
||||
#include "exceptions.h"
|
||||
#include "emitter.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
Map::Map()
|
||||
{
|
||||
}
|
||||
|
||||
Map::Map(const node_map& data)
|
||||
{
|
||||
for(node_map::const_iterator it=data.begin();it!=data.end();++it) {
|
||||
std::auto_ptr<Node> pKey = it->first->Clone();
|
||||
std::auto_ptr<Node> pValue = it->second->Clone();
|
||||
AddEntry(pKey, pValue);
|
||||
}
|
||||
}
|
||||
|
||||
Map::~Map()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void Map::Clear()
|
||||
{
|
||||
for(node_map::const_iterator it=m_data.begin();it!=m_data.end();++it) {
|
||||
delete it->first;
|
||||
delete it->second;
|
||||
}
|
||||
m_data.clear();
|
||||
}
|
||||
|
||||
Content *Map::Clone() const
|
||||
{
|
||||
return new Map(m_data);
|
||||
}
|
||||
|
||||
bool Map::GetBegin(std::map <Node *, Node *, ltnode>::const_iterator& it) const
|
||||
{
|
||||
it = m_data.begin();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Map::GetEnd(std::map <Node *, Node *, ltnode>::const_iterator& it) const
|
||||
{
|
||||
it = m_data.end();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::size_t Map::GetSize() const
|
||||
{
|
||||
return m_data.size();
|
||||
}
|
||||
|
||||
void Map::Parse(Scanner *pScanner, ParserState& state)
|
||||
{
|
||||
Clear();
|
||||
|
||||
// split based on start token
|
||||
switch(pScanner->peek().type) {
|
||||
case Token::BLOCK_MAP_START: ParseBlock(pScanner, state); break;
|
||||
case Token::FLOW_MAP_START: ParseFlow(pScanner, state); break;
|
||||
case Token::KEY: ParseCompact(pScanner, state); break;
|
||||
case Token::VALUE: ParseCompactWithNoKey(pScanner, state); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void Map::ParseBlock(Scanner *pScanner, ParserState& state)
|
||||
{
|
||||
// eat start token
|
||||
pScanner->pop();
|
||||
state.PushCollectionType(ParserState::BLOCK_MAP);
|
||||
|
||||
while(1) {
|
||||
if(pScanner->empty())
|
||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP);
|
||||
|
||||
Token token = pScanner->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) {
|
||||
pScanner->pop();
|
||||
break;
|
||||
}
|
||||
|
||||
std::auto_ptr <Node> pKey(new Node), pValue(new Node);
|
||||
|
||||
// grab key (if non-null)
|
||||
if(token.type == Token::KEY) {
|
||||
pScanner->pop();
|
||||
pKey->Parse(pScanner, state);
|
||||
}
|
||||
|
||||
// now grab value (optional)
|
||||
if(!pScanner->empty() && pScanner->peek().type == Token::VALUE) {
|
||||
pScanner->pop();
|
||||
pValue->Parse(pScanner, state);
|
||||
}
|
||||
|
||||
AddEntry(pKey, pValue);
|
||||
}
|
||||
|
||||
state.PopCollectionType(ParserState::BLOCK_MAP);
|
||||
}
|
||||
|
||||
void Map::ParseFlow(Scanner *pScanner, ParserState& state)
|
||||
{
|
||||
// eat start token
|
||||
pScanner->pop();
|
||||
state.PushCollectionType(ParserState::FLOW_MAP);
|
||||
|
||||
while(1) {
|
||||
if(pScanner->empty())
|
||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP_FLOW);
|
||||
|
||||
Token& token = pScanner->peek();
|
||||
// first check for end
|
||||
if(token.type == Token::FLOW_MAP_END) {
|
||||
pScanner->pop();
|
||||
break;
|
||||
}
|
||||
|
||||
std::auto_ptr <Node> pKey(new Node), pValue(new Node);
|
||||
|
||||
// grab key (if non-null)
|
||||
if(token.type == Token::KEY) {
|
||||
pScanner->pop();
|
||||
pKey->Parse(pScanner, state);
|
||||
}
|
||||
|
||||
// now grab value (optional)
|
||||
if(!pScanner->empty() && pScanner->peek().type == Token::VALUE) {
|
||||
pScanner->pop();
|
||||
pValue->Parse(pScanner, state);
|
||||
}
|
||||
|
||||
// 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 = pScanner->peek();
|
||||
if(nextToken.type == Token::FLOW_ENTRY)
|
||||
pScanner->pop();
|
||||
else if(nextToken.type != Token::FLOW_MAP_END)
|
||||
throw ParserException(nextToken.mark, ErrorMsg::END_OF_MAP_FLOW);
|
||||
|
||||
AddEntry(pKey, pValue);
|
||||
}
|
||||
|
||||
state.PopCollectionType(ParserState::FLOW_MAP);
|
||||
}
|
||||
|
||||
// ParseCompact
|
||||
// . Single "key: value" pair in a flow sequence
|
||||
void Map::ParseCompact(Scanner *pScanner, ParserState& state)
|
||||
{
|
||||
state.PushCollectionType(ParserState::COMPACT_MAP);
|
||||
std::auto_ptr <Node> pKey(new Node), pValue(new Node);
|
||||
|
||||
// grab key
|
||||
pScanner->pop();
|
||||
pKey->Parse(pScanner, state);
|
||||
|
||||
// now grab value (optional)
|
||||
if(!pScanner->empty() && pScanner->peek().type == Token::VALUE) {
|
||||
pScanner->pop();
|
||||
pValue->Parse(pScanner, state);
|
||||
}
|
||||
|
||||
AddEntry(pKey, pValue);
|
||||
state.PopCollectionType(ParserState::COMPACT_MAP);
|
||||
}
|
||||
|
||||
// ParseCompactWithNoKey
|
||||
// . Single ": value" pair in a flow sequence
|
||||
void Map::ParseCompactWithNoKey(Scanner *pScanner, ParserState& state)
|
||||
{
|
||||
state.PushCollectionType(ParserState::COMPACT_MAP);
|
||||
std::auto_ptr <Node> pKey(new Node), pValue(new Node);
|
||||
|
||||
// grab value
|
||||
pScanner->pop();
|
||||
pValue->Parse(pScanner, state);
|
||||
|
||||
AddEntry(pKey, pValue);
|
||||
state.PopCollectionType(ParserState::COMPACT_MAP);
|
||||
}
|
||||
|
||||
void Map::AddEntry(std::auto_ptr<Node> pKey, std::auto_ptr<Node> pValue)
|
||||
{
|
||||
node_map::const_iterator it = m_data.find(pKey.get());
|
||||
if(it != m_data.end())
|
||||
return;
|
||||
|
||||
m_data[pKey.release()] = pValue.release();
|
||||
}
|
||||
|
||||
void Map::Write(Emitter& out) const
|
||||
{
|
||||
out << BeginMap;
|
||||
for(node_map::const_iterator it=m_data.begin();it!=m_data.end();++it)
|
||||
out << Key << *it->first << Value << *it->second;
|
||||
out << EndMap;
|
||||
}
|
||||
|
||||
int Map::Compare(Content *pContent)
|
||||
{
|
||||
return -pContent->Compare(this);
|
||||
}
|
||||
|
||||
int Map::Compare(Map *pMap)
|
||||
{
|
||||
node_map::const_iterator it = m_data.begin(), jt = pMap->m_data.begin();
|
||||
while(1) {
|
||||
if(it == m_data.end()) {
|
||||
if(jt == pMap->m_data.end())
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
if(jt == pMap->m_data.end())
|
||||
return 1;
|
||||
|
||||
int cmp = it->first->Compare(*jt->first);
|
||||
if(cmp != 0)
|
||||
return cmp;
|
||||
|
||||
cmp = it->second->Compare(*jt->second);
|
||||
if(cmp != 0)
|
||||
return cmp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
55
src/map.h
55
src/map.h
@@ -1,55 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef MAP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define MAP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "content.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Node;
|
||||
|
||||
class Map: public Content
|
||||
{
|
||||
private:
|
||||
typedef std::map <Node *, Node *, ltnode> node_map;
|
||||
|
||||
public:
|
||||
Map();
|
||||
Map(const node_map& data);
|
||||
virtual ~Map();
|
||||
|
||||
void Clear();
|
||||
virtual Content *Clone() const;
|
||||
|
||||
virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator& it) const;
|
||||
virtual bool GetEnd(std::map <Node *, Node *, ltnode>::const_iterator& it) const;
|
||||
virtual std::size_t GetSize() const;
|
||||
virtual void Parse(Scanner *pScanner, ParserState& state);
|
||||
virtual void Write(Emitter& out) const;
|
||||
|
||||
virtual bool IsMap() const { return true; }
|
||||
|
||||
// ordering
|
||||
virtual int Compare(Content *pContent);
|
||||
virtual int Compare(Scalar *) { return 1; }
|
||||
virtual int Compare(Sequence *) { return 1; }
|
||||
virtual int Compare(Map *pMap);
|
||||
|
||||
private:
|
||||
void ParseBlock(Scanner *pScanner, ParserState& state);
|
||||
void ParseFlow(Scanner *pScanner, ParserState& state);
|
||||
void ParseCompact(Scanner *pScanner, ParserState& state);
|
||||
void ParseCompactWithNoKey(Scanner *pScanner, ParserState& state);
|
||||
|
||||
void AddEntry(std::auto_ptr<Node> pKey, std::auto_ptr<Node> pValue);
|
||||
|
||||
private:
|
||||
node_map m_data;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MAP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
390
src/node.cpp
390
src/node.cpp
@@ -1,34 +1,29 @@
|
||||
#include "node.h"
|
||||
#include "token.h"
|
||||
#include "scanner.h"
|
||||
#include "content.h"
|
||||
#include "parser.h"
|
||||
#include "scalar.h"
|
||||
#include "sequence.h"
|
||||
#include "map.h"
|
||||
#include "aliascontent.h"
|
||||
#include "yaml-cpp/node.h"
|
||||
#include "iterpriv.h"
|
||||
#include "emitter.h"
|
||||
#include "nodebuilder.h"
|
||||
#include "nodeownership.h"
|
||||
#include "scanner.h"
|
||||
#include "tag.h"
|
||||
#include "token.h"
|
||||
#include "yaml-cpp/aliasmanager.h"
|
||||
#include "yaml-cpp/emitfromevents.h"
|
||||
#include "yaml-cpp/emitter.h"
|
||||
#include "yaml-cpp/eventhandler.h"
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
// the ordering!
|
||||
bool ltnode::operator ()(const Node *pNode1, const Node *pNode2) const
|
||||
{
|
||||
bool ltnode::operator()(const Node *pNode1, const Node *pNode2) const {
|
||||
return *pNode1 < *pNode2;
|
||||
}
|
||||
|
||||
Node::Node(): m_pContent(0), m_alias(false), m_pIdentity(this), m_referenced(true)
|
||||
Node::Node(): m_pOwnership(new NodeOwnership), m_type(NodeType::Null)
|
||||
{
|
||||
}
|
||||
|
||||
Node::Node(const Mark& mark, const std::string& anchor, const std::string& tag, const Content *pContent)
|
||||
: m_mark(mark), m_anchor(anchor), m_tag(tag), m_pContent(0), m_alias(false), m_pIdentity(this), m_referenced(false)
|
||||
Node::Node(NodeOwnership& owner): m_pOwnership(new NodeOwnership(&owner)), m_type(NodeType::Null)
|
||||
{
|
||||
if(pContent)
|
||||
m_pContent = pContent->Clone();
|
||||
}
|
||||
|
||||
Node::~Node()
|
||||
@@ -38,174 +33,124 @@ namespace YAML
|
||||
|
||||
void Node::Clear()
|
||||
{
|
||||
delete m_pContent;
|
||||
m_pContent = 0;
|
||||
m_alias = false;
|
||||
m_referenced = false;
|
||||
m_anchor.clear();
|
||||
m_pOwnership.reset(new NodeOwnership);
|
||||
m_type = NodeType::Null;
|
||||
m_tag.clear();
|
||||
m_scalarData.clear();
|
||||
m_seqData.clear();
|
||||
m_mapData.clear();
|
||||
}
|
||||
|
||||
bool Node::IsAliased() const
|
||||
{
|
||||
return m_pOwnership->IsAliased(*this);
|
||||
}
|
||||
|
||||
Node& Node::CreateNode()
|
||||
{
|
||||
return m_pOwnership->Create();
|
||||
}
|
||||
|
||||
std::auto_ptr<Node> Node::Clone() const
|
||||
{
|
||||
if(m_alias)
|
||||
throw std::runtime_error("yaml-cpp: Can't clone alias"); // TODO: what to do about aliases?
|
||||
|
||||
return std::auto_ptr<Node> (new Node(m_mark, m_anchor, m_tag, m_pContent));
|
||||
std::auto_ptr<Node> pNode(new Node);
|
||||
NodeBuilder nodeBuilder(*pNode);
|
||||
EmitEvents(nodeBuilder);
|
||||
return pNode;
|
||||
}
|
||||
|
||||
void Node::Parse(Scanner *pScanner, ParserState& state)
|
||||
void Node::EmitEvents(EventHandler& eventHandler) const
|
||||
{
|
||||
eventHandler.OnDocumentStart(m_mark);
|
||||
AliasManager am;
|
||||
EmitEvents(am, eventHandler);
|
||||
eventHandler.OnDocumentEnd();
|
||||
}
|
||||
|
||||
void Node::EmitEvents(AliasManager& am, EventHandler& eventHandler) const
|
||||
{
|
||||
anchor_t anchor = NullAnchor;
|
||||
if(IsAliased()) {
|
||||
anchor = am.LookupAnchor(*this);
|
||||
if(anchor) {
|
||||
eventHandler.OnAlias(m_mark, anchor);
|
||||
return;
|
||||
}
|
||||
|
||||
am.RegisterReference(*this);
|
||||
anchor = am.LookupAnchor(*this);
|
||||
}
|
||||
|
||||
switch(m_type) {
|
||||
case NodeType::Null:
|
||||
eventHandler.OnNull(m_mark, anchor);
|
||||
break;
|
||||
case NodeType::Scalar:
|
||||
eventHandler.OnScalar(m_mark, m_tag, anchor, m_scalarData);
|
||||
break;
|
||||
case NodeType::Sequence:
|
||||
eventHandler.OnSequenceStart(m_mark, m_tag, anchor);
|
||||
for(std::size_t i=0;i<m_seqData.size();i++)
|
||||
m_seqData[i]->EmitEvents(am, eventHandler);
|
||||
eventHandler.OnSequenceEnd();
|
||||
break;
|
||||
case NodeType::Map:
|
||||
eventHandler.OnMapStart(m_mark, m_tag, anchor);
|
||||
for(node_map::const_iterator it=m_mapData.begin();it!=m_mapData.end();++it) {
|
||||
it->first->EmitEvents(am, eventHandler);
|
||||
it->second->EmitEvents(am, eventHandler);
|
||||
}
|
||||
eventHandler.OnMapEnd();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Node::Init(NodeType::value type, const Mark& mark, const std::string& tag)
|
||||
{
|
||||
Clear();
|
||||
|
||||
// an empty node *is* a possibility
|
||||
if(pScanner->empty())
|
||||
return;
|
||||
|
||||
// save location
|
||||
m_mark = pScanner->peek().mark;
|
||||
|
||||
// special case: a value node by itself must be a map, with no header
|
||||
if(pScanner->peek().type == Token::VALUE) {
|
||||
m_pContent = new Map;
|
||||
m_pContent->Parse(pScanner, state);
|
||||
return;
|
||||
}
|
||||
|
||||
ParseHeader(pScanner, state);
|
||||
|
||||
// is this an alias? if so, its contents are an alias to
|
||||
// a previously defined anchor
|
||||
if(m_alias) {
|
||||
// the scanner throws an exception if it doesn't know this anchor name
|
||||
const Node *pReferencedNode = pScanner->Retrieve(m_anchor);
|
||||
m_pIdentity = pReferencedNode;
|
||||
|
||||
// mark the referenced node for the sake of the client code
|
||||
pReferencedNode->m_referenced = true;
|
||||
|
||||
// use of an Alias object keeps the referenced content from
|
||||
// being deleted twice
|
||||
Content *pAliasedContent = pReferencedNode->m_pContent;
|
||||
if(pAliasedContent)
|
||||
m_pContent = new AliasContent(pAliasedContent);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// now split based on what kind of node we should be
|
||||
switch(pScanner->peek().type) {
|
||||
case Token::SCALAR:
|
||||
m_pContent = new Scalar;
|
||||
break;
|
||||
case Token::FLOW_SEQ_START:
|
||||
case Token::BLOCK_SEQ_START:
|
||||
m_pContent = new Sequence;
|
||||
break;
|
||||
case Token::FLOW_MAP_START:
|
||||
case Token::BLOCK_MAP_START:
|
||||
m_pContent = new Map;
|
||||
break;
|
||||
case Token::KEY:
|
||||
// compact maps can only go in a flow sequence
|
||||
if(state.GetCurCollectionType() == ParserState::FLOW_SEQ)
|
||||
m_pContent = new Map;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Have to save anchor before parsing to allow for aliases as
|
||||
// contained node (recursive structure)
|
||||
if(!m_anchor.empty())
|
||||
pScanner->Save(m_anchor, this);
|
||||
|
||||
if(m_pContent)
|
||||
m_pContent->Parse(pScanner, state);
|
||||
m_mark = mark;
|
||||
m_type = type;
|
||||
m_tag = tag;
|
||||
}
|
||||
|
||||
// ParseHeader
|
||||
// . Grabs any tag, alias, or anchor tokens and deals with them.
|
||||
void Node::ParseHeader(Scanner *pScanner, ParserState& state)
|
||||
void Node::MarkAsAliased()
|
||||
{
|
||||
while(1) {
|
||||
if(pScanner->empty())
|
||||
return;
|
||||
|
||||
switch(pScanner->peek().type) {
|
||||
case Token::TAG: ParseTag(pScanner, state); break;
|
||||
case Token::ANCHOR: ParseAnchor(pScanner, state); break;
|
||||
case Token::ALIAS: ParseAlias(pScanner, state); break;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Node::ParseTag(Scanner *pScanner, ParserState& state)
|
||||
{
|
||||
Token& token = pScanner->peek();
|
||||
if(m_tag != "")
|
||||
throw ParserException(token.mark, ErrorMsg::MULTIPLE_TAGS);
|
||||
|
||||
Tag tag(token);
|
||||
m_tag = tag.Translate(state);
|
||||
pScanner->pop();
|
||||
m_pOwnership->MarkAsAliased(*this);
|
||||
}
|
||||
|
||||
void Node::ParseAnchor(Scanner *pScanner, ParserState& /*state*/)
|
||||
void Node::SetScalarData(const std::string& data)
|
||||
{
|
||||
Token& token = pScanner->peek();
|
||||
if(m_anchor != "")
|
||||
throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS);
|
||||
|
||||
m_anchor = token.value;
|
||||
m_alias = false;
|
||||
pScanner->pop();
|
||||
assert(m_type == NodeType::Scalar); // TODO: throw?
|
||||
m_scalarData = data;
|
||||
}
|
||||
|
||||
void Node::ParseAlias(Scanner *pScanner, ParserState& /*state*/)
|
||||
void Node::Append(Node& node)
|
||||
{
|
||||
Token& token = pScanner->peek();
|
||||
if(m_anchor != "")
|
||||
throw ParserException(token.mark, ErrorMsg::MULTIPLE_ALIASES);
|
||||
if(m_tag != "")
|
||||
throw ParserException(token.mark, ErrorMsg::ALIAS_CONTENT);
|
||||
|
||||
m_anchor = token.value;
|
||||
m_alias = true;
|
||||
pScanner->pop();
|
||||
assert(m_type == NodeType::Sequence); // TODO: throw?
|
||||
m_seqData.push_back(&node);
|
||||
}
|
||||
|
||||
CONTENT_TYPE Node::GetType() const
|
||||
|
||||
void Node::Insert(Node& key, Node& value)
|
||||
{
|
||||
if(!m_pContent)
|
||||
return CT_NONE;
|
||||
|
||||
if(m_pContent->IsScalar())
|
||||
return CT_SCALAR;
|
||||
else if(m_pContent->IsSequence())
|
||||
return CT_SEQUENCE;
|
||||
else if(m_pContent->IsMap())
|
||||
return CT_MAP;
|
||||
|
||||
return CT_NONE;
|
||||
assert(m_type == NodeType::Map); // TODO: throw?
|
||||
m_mapData[&key] = &value;
|
||||
}
|
||||
|
||||
// begin
|
||||
// Returns an iterator to the beginning of this (sequence or map).
|
||||
Iterator Node::begin() const
|
||||
{
|
||||
if(!m_pContent)
|
||||
return Iterator();
|
||||
|
||||
std::vector <Node *>::const_iterator seqIter;
|
||||
if(m_pContent->GetBegin(seqIter))
|
||||
return Iterator(new IterPriv(seqIter));
|
||||
|
||||
std::map <Node *, Node *, ltnode>::const_iterator mapIter;
|
||||
if(m_pContent->GetBegin(mapIter))
|
||||
return Iterator(new IterPriv(mapIter));
|
||||
|
||||
switch(m_type) {
|
||||
case NodeType::Null:
|
||||
case NodeType::Scalar:
|
||||
return Iterator();
|
||||
case NodeType::Sequence:
|
||||
return Iterator(std::auto_ptr<IterPriv>(new IterPriv(m_seqData.begin())));
|
||||
case NodeType::Map:
|
||||
return Iterator(std::auto_ptr<IterPriv>(new IterPriv(m_mapData.begin())));
|
||||
}
|
||||
|
||||
assert(false);
|
||||
return Iterator();
|
||||
}
|
||||
|
||||
@@ -213,87 +158,108 @@ namespace YAML
|
||||
// . Returns an iterator to the end of this (sequence or map).
|
||||
Iterator Node::end() const
|
||||
{
|
||||
if(!m_pContent)
|
||||
return Iterator();
|
||||
|
||||
std::vector <Node *>::const_iterator seqIter;
|
||||
if(m_pContent->GetEnd(seqIter))
|
||||
return Iterator(new IterPriv(seqIter));
|
||||
|
||||
std::map <Node *, Node *, ltnode>::const_iterator mapIter;
|
||||
if(m_pContent->GetEnd(mapIter))
|
||||
return Iterator(new IterPriv(mapIter));
|
||||
|
||||
switch(m_type) {
|
||||
case NodeType::Null:
|
||||
case NodeType::Scalar:
|
||||
return Iterator();
|
||||
case NodeType::Sequence:
|
||||
return Iterator(std::auto_ptr<IterPriv>(new IterPriv(m_seqData.end())));
|
||||
case NodeType::Map:
|
||||
return Iterator(std::auto_ptr<IterPriv>(new IterPriv(m_mapData.end())));
|
||||
}
|
||||
|
||||
assert(false);
|
||||
return Iterator();
|
||||
}
|
||||
|
||||
// size
|
||||
// . Returns the size of this node, if it's a sequence node.
|
||||
// . Returns the size of a sequence or map node
|
||||
// . Otherwise, returns zero.
|
||||
std::size_t Node::size() const
|
||||
{
|
||||
if(!m_pContent)
|
||||
return 0;
|
||||
|
||||
return m_pContent->GetSize();
|
||||
switch(m_type) {
|
||||
case NodeType::Null:
|
||||
case NodeType::Scalar:
|
||||
return 0;
|
||||
case NodeType::Sequence:
|
||||
return m_seqData.size();
|
||||
case NodeType::Map:
|
||||
return m_mapData.size();
|
||||
}
|
||||
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Node *Node::FindAtIndex(std::size_t i) const
|
||||
{
|
||||
if(!m_pContent)
|
||||
return 0;
|
||||
|
||||
return m_pContent->GetNode(i);
|
||||
if(m_type == NodeType::Sequence)
|
||||
return m_seqData[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Node::GetScalar(std::string& s) const
|
||||
{
|
||||
if(!m_pContent) {
|
||||
if(m_tag.empty())
|
||||
switch(m_type) {
|
||||
case NodeType::Null:
|
||||
s = "~";
|
||||
else
|
||||
s = "";
|
||||
return true;
|
||||
return true;
|
||||
case NodeType::Scalar:
|
||||
s = m_scalarData;
|
||||
return true;
|
||||
case NodeType::Sequence:
|
||||
case NodeType::Map:
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_pContent->GetScalar(s);
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
Emitter& operator << (Emitter& out, const Node& node)
|
||||
{
|
||||
// write anchor/alias
|
||||
if(node.m_anchor != "") {
|
||||
if(node.m_alias)
|
||||
out << Alias(node.m_anchor);
|
||||
else
|
||||
out << Anchor(node.m_anchor);
|
||||
}
|
||||
|
||||
if(node.m_tag != "")
|
||||
out << VerbatimTag(node.m_tag);
|
||||
|
||||
// write content
|
||||
if(node.m_pContent)
|
||||
node.m_pContent->Write(out);
|
||||
else if(!node.m_alias)
|
||||
out << Null;
|
||||
|
||||
EmitFromEvents emitFromEvents(out);
|
||||
node.EmitEvents(emitFromEvents);
|
||||
return out;
|
||||
}
|
||||
|
||||
int Node::Compare(const Node& rhs) const
|
||||
{
|
||||
// Step 1: no content is the smallest
|
||||
if(!m_pContent) {
|
||||
if(rhs.m_pContent)
|
||||
return -1;
|
||||
else
|
||||
if(m_type != rhs.m_type)
|
||||
return rhs.m_type - m_type;
|
||||
|
||||
switch(m_type) {
|
||||
case NodeType::Null:
|
||||
return 0;
|
||||
case NodeType::Scalar:
|
||||
return m_scalarData.compare(rhs.m_scalarData);
|
||||
case NodeType::Sequence:
|
||||
if(m_seqData.size() < rhs.m_seqData.size())
|
||||
return 1;
|
||||
else if(m_seqData.size() > rhs.m_seqData.size())
|
||||
return -1;
|
||||
for(std::size_t i=0;i<m_seqData.size();i++)
|
||||
if(int cmp = m_seqData[i]->Compare(*rhs.m_seqData[i]))
|
||||
return cmp;
|
||||
return 0;
|
||||
case NodeType::Map:
|
||||
if(m_mapData.size() < rhs.m_mapData.size())
|
||||
return 1;
|
||||
else if(m_mapData.size() > rhs.m_mapData.size())
|
||||
return -1;
|
||||
node_map::const_iterator it = m_mapData.begin();
|
||||
node_map::const_iterator jt = rhs.m_mapData.begin();
|
||||
for(;it!=m_mapData.end() && jt!=rhs.m_mapData.end();it++, jt++) {
|
||||
if(int cmp = it->first->Compare(*jt->first))
|
||||
return cmp;
|
||||
if(int cmp = it->second->Compare(*jt->second))
|
||||
return cmp;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(!rhs.m_pContent)
|
||||
return 1;
|
||||
|
||||
return m_pContent->Compare(rhs.m_pContent);
|
||||
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool operator < (const Node& n1, const Node& n2)
|
||||
|
145
src/nodebuilder.cpp
Normal file
145
src/nodebuilder.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
#include "nodebuilder.h"
|
||||
#include "yaml-cpp/mark.h"
|
||||
#include "yaml-cpp/node.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
NodeBuilder::NodeBuilder(Node& root): m_root(root), m_initializedRoot(false), m_finished(false)
|
||||
{
|
||||
m_root.Clear();
|
||||
m_anchors.push_back(0); // since the anchors start at 1
|
||||
}
|
||||
|
||||
NodeBuilder::~NodeBuilder()
|
||||
{
|
||||
}
|
||||
|
||||
void NodeBuilder::OnDocumentStart(const Mark&)
|
||||
{
|
||||
}
|
||||
|
||||
void NodeBuilder::OnDocumentEnd()
|
||||
{
|
||||
assert(m_finished);
|
||||
}
|
||||
|
||||
void NodeBuilder::OnNull(const Mark& mark, anchor_t anchor)
|
||||
{
|
||||
Node& node = Push(anchor);
|
||||
node.Init(NodeType::Null, mark, "");
|
||||
Pop();
|
||||
}
|
||||
|
||||
void NodeBuilder::OnAlias(const Mark& /*mark*/, anchor_t anchor)
|
||||
{
|
||||
Node& node = *m_anchors[anchor];
|
||||
Insert(node);
|
||||
node.MarkAsAliased();
|
||||
}
|
||||
|
||||
void NodeBuilder::OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value)
|
||||
{
|
||||
Node& node = Push(anchor);
|
||||
node.Init(NodeType::Scalar, mark, tag);
|
||||
node.SetScalarData(value);
|
||||
Pop();
|
||||
}
|
||||
|
||||
void NodeBuilder::OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor)
|
||||
{
|
||||
Node& node = Push(anchor);
|
||||
node.Init(NodeType::Sequence, mark, tag);
|
||||
}
|
||||
|
||||
void NodeBuilder::OnSequenceEnd()
|
||||
{
|
||||
Pop();
|
||||
}
|
||||
|
||||
void NodeBuilder::OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor)
|
||||
{
|
||||
Node& node = Push(anchor);
|
||||
node.Init(NodeType::Map, mark, tag);
|
||||
m_didPushKey.push(false);
|
||||
}
|
||||
|
||||
void NodeBuilder::OnMapEnd()
|
||||
{
|
||||
m_didPushKey.pop();
|
||||
Pop();
|
||||
}
|
||||
|
||||
Node& NodeBuilder::Push(anchor_t anchor)
|
||||
{
|
||||
Node& node = Push();
|
||||
RegisterAnchor(anchor, node);
|
||||
return node;
|
||||
}
|
||||
|
||||
Node& NodeBuilder::Push()
|
||||
{
|
||||
if(!m_initializedRoot) {
|
||||
m_initializedRoot = true;
|
||||
return m_root;
|
||||
}
|
||||
|
||||
Node& node = m_root.CreateNode();
|
||||
m_stack.push(&node);
|
||||
return node;
|
||||
}
|
||||
|
||||
Node& NodeBuilder::Top()
|
||||
{
|
||||
return m_stack.empty() ? m_root : *m_stack.top();
|
||||
}
|
||||
|
||||
void NodeBuilder::Pop()
|
||||
{
|
||||
assert(!m_finished);
|
||||
if(m_stack.empty()) {
|
||||
m_finished = true;
|
||||
return;
|
||||
}
|
||||
|
||||
Node& node = *m_stack.top();
|
||||
m_stack.pop();
|
||||
Insert(node);
|
||||
}
|
||||
|
||||
void NodeBuilder::Insert(Node& node)
|
||||
{
|
||||
Node& curTop = Top();
|
||||
switch(curTop.Type()) {
|
||||
case NodeType::Null:
|
||||
case NodeType::Scalar:
|
||||
assert(false);
|
||||
break;
|
||||
case NodeType::Sequence:
|
||||
curTop.Append(node);
|
||||
break;
|
||||
case NodeType::Map:
|
||||
assert(!m_didPushKey.empty());
|
||||
if(m_didPushKey.top()) {
|
||||
assert(!m_pendingKeys.empty());
|
||||
|
||||
Node& key = *m_pendingKeys.top();
|
||||
m_pendingKeys.pop();
|
||||
curTop.Insert(key, node);
|
||||
m_didPushKey.top() = false;
|
||||
} else {
|
||||
m_pendingKeys.push(&node);
|
||||
m_didPushKey.top() = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeBuilder::RegisterAnchor(anchor_t anchor, Node& node)
|
||||
{
|
||||
if(anchor) {
|
||||
assert(anchor == m_anchors.size());
|
||||
m_anchors.push_back(&node);
|
||||
}
|
||||
}
|
||||
}
|
61
src/nodebuilder.h
Normal file
61
src/nodebuilder.h
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "yaml-cpp/eventhandler.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Node;
|
||||
|
||||
class NodeBuilder: public EventHandler
|
||||
{
|
||||
public:
|
||||
explicit NodeBuilder(Node& root);
|
||||
virtual ~NodeBuilder();
|
||||
|
||||
virtual void OnDocumentStart(const Mark& mark);
|
||||
virtual void OnDocumentEnd();
|
||||
|
||||
virtual void OnNull(const Mark& mark, anchor_t anchor);
|
||||
virtual void OnAlias(const Mark& mark, anchor_t anchor);
|
||||
virtual void OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value);
|
||||
|
||||
virtual void OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor);
|
||||
virtual void OnSequenceEnd();
|
||||
|
||||
virtual void OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor);
|
||||
virtual void OnMapEnd();
|
||||
|
||||
private:
|
||||
Node& Push(anchor_t anchor);
|
||||
Node& Push();
|
||||
Node& Top();
|
||||
void Pop();
|
||||
|
||||
void Insert(Node& node);
|
||||
void RegisterAnchor(anchor_t anchor, Node& node);
|
||||
|
||||
private:
|
||||
Node& m_root;
|
||||
bool m_initializedRoot;
|
||||
bool m_finished;
|
||||
|
||||
std::stack<Node *> m_stack;
|
||||
std::stack<Node *> m_pendingKeys;
|
||||
std::stack<bool> m_didPushKey;
|
||||
|
||||
typedef std::vector<Node *> Anchors;
|
||||
Anchors m_anchors;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
31
src/nodeownership.cpp
Normal file
31
src/nodeownership.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "nodeownership.h"
|
||||
#include "yaml-cpp/node.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
NodeOwnership::NodeOwnership(NodeOwnership *pOwner): m_pOwner(pOwner)
|
||||
{
|
||||
if(!m_pOwner)
|
||||
m_pOwner = this;
|
||||
}
|
||||
|
||||
NodeOwnership::~NodeOwnership()
|
||||
{
|
||||
}
|
||||
|
||||
Node& NodeOwnership::_Create()
|
||||
{
|
||||
m_nodes.push_back(std::auto_ptr<Node>(new Node));
|
||||
return m_nodes.back();
|
||||
}
|
||||
|
||||
void NodeOwnership::_MarkAsAliased(const Node& node)
|
||||
{
|
||||
m_aliasedNodes.insert(&node);
|
||||
}
|
||||
|
||||
bool NodeOwnership::_IsAliased(const Node& node) const
|
||||
{
|
||||
return m_aliasedNodes.count(&node) > 0;
|
||||
}
|
||||
}
|
39
src/nodeownership.h
Normal file
39
src/nodeownership.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef NODE_OWNERSHIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODE_OWNERSHIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "yaml-cpp/noncopyable.h"
|
||||
#include "ptr_vector.h"
|
||||
#include <set>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Node;
|
||||
|
||||
class NodeOwnership: private noncopyable
|
||||
{
|
||||
public:
|
||||
explicit NodeOwnership(NodeOwnership *pOwner = 0);
|
||||
~NodeOwnership();
|
||||
|
||||
Node& Create() { return m_pOwner->_Create(); }
|
||||
void MarkAsAliased(const Node& node) { m_pOwner->_MarkAsAliased(node); }
|
||||
bool IsAliased(const Node& node) const { return m_pOwner->_IsAliased(node); }
|
||||
|
||||
private:
|
||||
Node& _Create();
|
||||
void _MarkAsAliased(const Node& node);
|
||||
bool _IsAliased(const Node& node) const;
|
||||
|
||||
private:
|
||||
ptr_vector<Node> m_nodes;
|
||||
std::set<const Node *> m_aliasedNodes;
|
||||
NodeOwnership *m_pOwner;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // NODE_OWNERSHIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,5 +1,5 @@
|
||||
#include "null.h"
|
||||
#include "node.h"
|
||||
#include "yaml-cpp/null.h"
|
||||
#include "yaml-cpp/node.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
|
@@ -1,4 +1,4 @@
|
||||
#include "ostream.h"
|
||||
#include "yaml-cpp/ostream.h"
|
||||
#include <cstring>
|
||||
|
||||
namespace YAML
|
||||
|
@@ -1,8 +1,13 @@
|
||||
#include "parser.h"
|
||||
#include "yaml-cpp/parser.h"
|
||||
#include "directives.h"
|
||||
#include "yaml-cpp/eventhandler.h"
|
||||
#include "yaml-cpp/exceptions.h"
|
||||
#include "yaml-cpp/node.h"
|
||||
#include "nodebuilder.h"
|
||||
#include "scanner.h"
|
||||
#include "singledocparser.h"
|
||||
#include "tag.h"
|
||||
#include "token.h"
|
||||
#include "exceptions.h"
|
||||
#include "parserstate.h"
|
||||
#include <sstream>
|
||||
#include <cstdio>
|
||||
|
||||
@@ -29,7 +34,25 @@ namespace YAML
|
||||
void Parser::Load(std::istream& in)
|
||||
{
|
||||
m_pScanner.reset(new Scanner(in));
|
||||
m_pState.reset(new ParserState);
|
||||
m_pDirectives.reset(new Directives);
|
||||
}
|
||||
|
||||
// HandleNextDocument
|
||||
// . Handles the next document
|
||||
// . Throws a ParserException on error.
|
||||
// . Returns false if there are no more documents
|
||||
bool Parser::HandleNextDocument(EventHandler& eventHandler)
|
||||
{
|
||||
if(!m_pScanner.get())
|
||||
return false;
|
||||
|
||||
ParseDirectives();
|
||||
if(m_pScanner->empty())
|
||||
return false;
|
||||
|
||||
SingleDocParser sdp(*m_pScanner, *m_pDirectives);
|
||||
sdp.HandleDocument(eventHandler);
|
||||
return true;
|
||||
}
|
||||
|
||||
// GetNextDocument
|
||||
@@ -37,34 +60,8 @@ namespace YAML
|
||||
// . Throws a ParserException on error.
|
||||
bool Parser::GetNextDocument(Node& document)
|
||||
{
|
||||
if(!m_pScanner.get())
|
||||
return false;
|
||||
|
||||
// clear node
|
||||
document.Clear();
|
||||
|
||||
// first read directives
|
||||
ParseDirectives();
|
||||
|
||||
// we better have some tokens in the queue
|
||||
if(m_pScanner->empty())
|
||||
return false;
|
||||
|
||||
// first eat doc start (optional)
|
||||
if(m_pScanner->peek().type == Token::DOC_START)
|
||||
m_pScanner->pop();
|
||||
|
||||
// now parse our root node
|
||||
document.Parse(m_pScanner.get(), *m_pState);
|
||||
|
||||
// and finally eat any doc ends we see
|
||||
while(!m_pScanner->empty() && m_pScanner->peek().type == Token::DOC_END)
|
||||
m_pScanner->pop();
|
||||
|
||||
// clear anchors from the scanner, which are no longer relevant
|
||||
m_pScanner->ClearAnchors();
|
||||
|
||||
return true;
|
||||
NodeBuilder builder(document);
|
||||
return HandleNextDocument(builder);
|
||||
}
|
||||
|
||||
// ParseDirectives
|
||||
@@ -84,7 +81,7 @@ namespace YAML
|
||||
// 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_pState.reset(new ParserState);
|
||||
m_pDirectives.reset(new Directives);
|
||||
|
||||
readDirective = true;
|
||||
HandleDirective(token);
|
||||
@@ -107,20 +104,20 @@ namespace YAML
|
||||
if(token.params.size() != 1)
|
||||
throw ParserException(token.mark, ErrorMsg::YAML_DIRECTIVE_ARGS);
|
||||
|
||||
if(!m_pState->version.isDefault)
|
||||
if(!m_pDirectives->version.isDefault)
|
||||
throw ParserException(token.mark, ErrorMsg::REPEATED_YAML_DIRECTIVE);
|
||||
|
||||
std::stringstream str(token.params[0]);
|
||||
str >> m_pState->version.major;
|
||||
str >> m_pDirectives->version.major;
|
||||
str.get();
|
||||
str >> m_pState->version.minor;
|
||||
str >> m_pDirectives->version.minor;
|
||||
if(!str || str.peek() != EOF)
|
||||
throw ParserException(token.mark, ErrorMsg::YAML_VERSION + token.params[0]);
|
||||
throw ParserException(token.mark, std::string(ErrorMsg::YAML_VERSION) + token.params[0]);
|
||||
|
||||
if(m_pState->version.major > 1)
|
||||
if(m_pDirectives->version.major > 1)
|
||||
throw ParserException(token.mark, ErrorMsg::YAML_MAJOR_VERSION);
|
||||
|
||||
m_pState->version.isDefault = false;
|
||||
m_pDirectives->version.isDefault = false;
|
||||
// TODO: warning on major == 1, minor > 2?
|
||||
}
|
||||
|
||||
@@ -133,10 +130,10 @@ namespace YAML
|
||||
|
||||
const std::string& handle = token.params[0];
|
||||
const std::string& prefix = token.params[1];
|
||||
if(m_pState->tags.find(handle) != m_pState->tags.end())
|
||||
if(m_pDirectives->tags.find(handle) != m_pDirectives->tags.end())
|
||||
throw ParserException(token.mark, ErrorMsg::REPEATED_TAG_DIRECTIVE);
|
||||
|
||||
m_pState->tags[handle] = prefix;
|
||||
m_pDirectives->tags[handle] = prefix;
|
||||
}
|
||||
|
||||
void Parser::PrintTokens(std::ostream& out)
|
||||
|
@@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef PARSERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define PARSERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <stack>
|
||||
#include <cassert>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
struct Version {
|
||||
bool isDefault;
|
||||
int major, minor;
|
||||
};
|
||||
|
||||
struct ParserState
|
||||
{
|
||||
enum COLLECTION_TYPE { NONE, BLOCK_MAP, BLOCK_SEQ, FLOW_MAP, FLOW_SEQ, COMPACT_MAP };
|
||||
|
||||
ParserState();
|
||||
|
||||
const std::string TranslateTagHandle(const std::string& handle) const;
|
||||
COLLECTION_TYPE GetCurCollectionType() const { if(collectionStack.empty()) return NONE; return collectionStack.top(); }
|
||||
|
||||
void PushCollectionType(COLLECTION_TYPE type) { collectionStack.push(type); }
|
||||
void PopCollectionType(COLLECTION_TYPE type) { assert(type == GetCurCollectionType()); collectionStack.pop(); }
|
||||
|
||||
Version version;
|
||||
std::map <std::string, std::string> tags;
|
||||
std::stack <COLLECTION_TYPE> collectionStack;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // PARSERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
46
src/ptr_stack.h
Normal file
46
src/ptr_stack.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef PTR_STACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define PTR_STACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "yaml-cpp/noncopyable.h"
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
template <typename T>
|
||||
class ptr_stack: private YAML::noncopyable
|
||||
{
|
||||
public:
|
||||
ptr_stack() {}
|
||||
~ptr_stack() { clear(); }
|
||||
|
||||
void clear() {
|
||||
for(unsigned i=0;i<m_data.size();i++)
|
||||
delete m_data[i];
|
||||
m_data.clear();
|
||||
}
|
||||
|
||||
std::size_t size() const { return m_data.size(); }
|
||||
bool empty() const { return m_data.empty(); }
|
||||
|
||||
void push(std::auto_ptr<T> t) {
|
||||
m_data.push_back(NULL);
|
||||
m_data.back() = t.release();
|
||||
}
|
||||
std::auto_ptr<T> pop() {
|
||||
std::auto_ptr<T> t(m_data.back());
|
||||
m_data.pop_back();
|
||||
return t;
|
||||
}
|
||||
T& top() { return *m_data.back(); }
|
||||
const T& top() const { return *m_data.back(); }
|
||||
|
||||
private:
|
||||
std::vector<T*> m_data;
|
||||
};
|
||||
|
||||
#endif // PTR_STACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
47
src/ptr_vector.h
Normal file
47
src/ptr_vector.h
Normal file
@@ -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
|
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#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>
|
||||
|
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#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"
|
||||
@@ -58,7 +60,13 @@ namespace YAML
|
||||
template<>
|
||||
inline bool RegEx::IsValidSource<StringCharSource>(const StringCharSource&source) const
|
||||
{
|
||||
return source || m_op == REGEX_EMPTY;
|
||||
switch(m_op) {
|
||||
case REGEX_MATCH:
|
||||
case REGEX_RANGE:
|
||||
return source;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Source>
|
||||
|
@@ -1,54 +0,0 @@
|
||||
#include "scalar.h"
|
||||
#include "scanner.h"
|
||||
#include "token.h"
|
||||
#include "exceptions.h"
|
||||
#include "node.h"
|
||||
#include "emitter.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
Scalar::Scalar()
|
||||
{
|
||||
}
|
||||
|
||||
Scalar::Scalar(const std::string& data): m_data(data)
|
||||
{
|
||||
}
|
||||
|
||||
Scalar::~Scalar()
|
||||
{
|
||||
}
|
||||
|
||||
Content *Scalar::Clone() const
|
||||
{
|
||||
return new Scalar(m_data);
|
||||
}
|
||||
|
||||
void Scalar::Parse(Scanner *pScanner, ParserState& /*state*/)
|
||||
{
|
||||
Token& token = pScanner->peek();
|
||||
m_data = token.value;
|
||||
pScanner->pop();
|
||||
}
|
||||
|
||||
void Scalar::Write(Emitter& out) const
|
||||
{
|
||||
out << m_data;
|
||||
}
|
||||
|
||||
int Scalar::Compare(Content *pContent)
|
||||
{
|
||||
return -pContent->Compare(this);
|
||||
}
|
||||
|
||||
int Scalar::Compare(Scalar *pScalar)
|
||||
{
|
||||
if(m_data < pScalar->m_data)
|
||||
return -1;
|
||||
else if(m_data > pScalar->m_data)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
44
src/scalar.h
44
src/scalar.h
@@ -1,44 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef SCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define SCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "content.h"
|
||||
#include <string>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Scalar: public Content
|
||||
{
|
||||
public:
|
||||
Scalar();
|
||||
Scalar(const std::string& data);
|
||||
virtual ~Scalar();
|
||||
|
||||
virtual Content *Clone() const;
|
||||
|
||||
virtual void Parse(Scanner *pScanner, ParserState& state);
|
||||
virtual void Write(Emitter& out) const;
|
||||
|
||||
virtual bool IsScalar() const { return true; }
|
||||
|
||||
// extraction
|
||||
virtual bool GetScalar(std::string& scalar) const {
|
||||
scalar = m_data;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ordering
|
||||
virtual int Compare(Content *pContent);
|
||||
virtual int Compare(Scalar *pScalar);
|
||||
virtual int Compare(Sequence *) { return -1; }
|
||||
virtual int Compare(Map *) { return -1; }
|
||||
|
||||
protected:
|
||||
std::string m_data;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#include "scanner.h"
|
||||
#include "token.h"
|
||||
#include "exceptions.h"
|
||||
#include "yaml-cpp/exceptions.h"
|
||||
#include "exp.h"
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
@@ -14,9 +14,6 @@ namespace YAML
|
||||
|
||||
Scanner::~Scanner()
|
||||
{
|
||||
for(unsigned i=0;i<m_indentRefs.size();i++)
|
||||
delete m_indentRefs[i];
|
||||
m_indentRefs.clear();
|
||||
}
|
||||
|
||||
// empty
|
||||
@@ -32,13 +29,8 @@ namespace YAML
|
||||
void Scanner::pop()
|
||||
{
|
||||
EnsureTokensInQueue();
|
||||
if(!m_tokens.empty()) {
|
||||
// Saved anchors shouldn't survive popping the document end marker
|
||||
if (m_tokens.front().type == Token::DOC_END) {
|
||||
ClearAnchors();
|
||||
}
|
||||
if(!m_tokens.empty())
|
||||
m_tokens.pop();
|
||||
}
|
||||
}
|
||||
|
||||
// peek
|
||||
@@ -242,10 +234,9 @@ namespace YAML
|
||||
{
|
||||
m_startedStream = true;
|
||||
m_simpleKeyAllowed = true;
|
||||
IndentMarker *pIndent = new IndentMarker(-1, IndentMarker::NONE);
|
||||
std::auto_ptr<IndentMarker> pIndent(new IndentMarker(-1, IndentMarker::NONE));
|
||||
m_indentRefs.push_back(pIndent);
|
||||
m_indents.push(pIndent);
|
||||
m_anchors.clear();
|
||||
m_indents.push(&m_indentRefs.back());
|
||||
}
|
||||
|
||||
// EndStream
|
||||
@@ -277,6 +268,7 @@ namespace YAML
|
||||
case IndentMarker::NONE: assert(false); break;
|
||||
}
|
||||
assert(false);
|
||||
throw std::runtime_error("yaml-cpp: internal error, invalid indent type");
|
||||
}
|
||||
|
||||
// PushIndentTo
|
||||
@@ -304,8 +296,8 @@ namespace YAML
|
||||
|
||||
// and then the indent
|
||||
m_indents.push(&indent);
|
||||
m_indentRefs.push_back(pIndent.release());
|
||||
return m_indentRefs.back();
|
||||
m_indentRefs.push_back(pIndent);
|
||||
return &m_indentRefs.back();
|
||||
}
|
||||
|
||||
// PopIndentToHere
|
||||
@@ -378,29 +370,6 @@ namespace YAML
|
||||
return m_indents.top()->column;
|
||||
}
|
||||
|
||||
// Save
|
||||
// . Saves a pointer to the Node object referenced by a particular anchor
|
||||
// name.
|
||||
void Scanner::Save(const std::string& anchor, Node* value)
|
||||
{
|
||||
m_anchors[anchor] = value;
|
||||
}
|
||||
|
||||
// Retrieve
|
||||
// . Retrieves a pointer previously saved for an anchor name.
|
||||
// . Throws an exception if the anchor has not been defined.
|
||||
const Node *Scanner::Retrieve(const std::string& anchor) const
|
||||
{
|
||||
typedef std::map<std::string, const Node *> map;
|
||||
|
||||
map::const_iterator itNode = m_anchors.find(anchor);
|
||||
|
||||
if(m_anchors.end() == itNode)
|
||||
ThrowParserException(ErrorMsg::UNKNOWN_ANCHOR);
|
||||
|
||||
return itNode->second;
|
||||
}
|
||||
|
||||
// ThrowParserException
|
||||
// . Throws a ParserException with the current token location
|
||||
// (if available).
|
||||
@@ -414,10 +383,5 @@ namespace YAML
|
||||
}
|
||||
throw ParserException(mark, msg);
|
||||
}
|
||||
|
||||
void Scanner::ClearAnchors()
|
||||
{
|
||||
m_anchors.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#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>
|
||||
@@ -10,6 +12,7 @@
|
||||
#include <stack>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include "ptr_vector.h"
|
||||
#include "stream.h"
|
||||
#include "token.h"
|
||||
|
||||
@@ -29,11 +32,6 @@ namespace YAML
|
||||
void pop();
|
||||
Token& peek();
|
||||
|
||||
// anchor management
|
||||
void Save(const std::string& anchor, Node* value);
|
||||
const Node *Retrieve(const std::string& anchor) const;
|
||||
void ClearAnchors();
|
||||
|
||||
private:
|
||||
struct IndentMarker {
|
||||
enum INDENT_TYPE { MAP, SEQ, NONE };
|
||||
@@ -117,17 +115,16 @@ namespace YAML
|
||||
Stream INPUT;
|
||||
|
||||
// the output (tokens)
|
||||
std::queue <Token> m_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;
|
||||
std::vector <IndentMarker *> m_indentRefs; // for "garbage collection"
|
||||
std::stack <FLOW_MARKER> m_flows;
|
||||
std::map <std::string, const Node *> m_anchors;
|
||||
std::stack<SimpleKey> m_simpleKeys;
|
||||
std::stack<IndentMarker *> m_indents;
|
||||
ptr_vector<IndentMarker> m_indentRefs; // for "garbage collection"
|
||||
std::stack<FLOW_MARKER> m_flows;
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#include "scanscalar.h"
|
||||
#include "scanner.h"
|
||||
#include "exp.h"
|
||||
#include "exceptions.h"
|
||||
#include "yaml-cpp/exceptions.h"
|
||||
#include "token.h"
|
||||
|
||||
namespace YAML
|
||||
@@ -143,7 +143,7 @@ namespace YAML
|
||||
|
||||
if(!nextEmptyLine && foldedNewlineCount > 0) {
|
||||
scalar += std::string(foldedNewlineCount - 1, '\n');
|
||||
if(foldedNewlineStartedMoreIndented || nextMoreIndented)
|
||||
if(foldedNewlineStartedMoreIndented || nextMoreIndented | !foundNonEmptyLine)
|
||||
scalar += "\n";
|
||||
foldedNewlineCount = 0;
|
||||
}
|
||||
@@ -175,12 +175,23 @@ namespace YAML
|
||||
scalar.erase(pos + 1);
|
||||
}
|
||||
|
||||
if(params.chomp == STRIP || params.chomp == CLIP) {
|
||||
std::size_t pos = scalar.find_last_not_of('\n');
|
||||
if(params.chomp == CLIP && pos + 1 < scalar.size())
|
||||
scalar.erase(pos + 2);
|
||||
else if(params.chomp == STRIP && pos < scalar.size())
|
||||
scalar.erase(pos + 1);
|
||||
switch(params.chomp) {
|
||||
case CLIP: {
|
||||
const std::size_t pos = scalar.find_last_not_of('\n');
|
||||
if(pos == std::string::npos)
|
||||
scalar.erase();
|
||||
else if(pos + 1 < scalar.size())
|
||||
scalar.erase(pos + 2);
|
||||
} break;
|
||||
case STRIP: {
|
||||
const std::size_t pos = scalar.find_last_not_of('\n');
|
||||
if(pos == std::string::npos)
|
||||
scalar.erase();
|
||||
else if(pos < scalar.size())
|
||||
scalar.erase(pos + 1);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return scalar;
|
||||
|
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#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"
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#include "scanner.h"
|
||||
#include "regex.h"
|
||||
#include "exp.h"
|
||||
#include "exceptions.h"
|
||||
#include "yaml-cpp/exceptions.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
|
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#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"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#include "scanner.h"
|
||||
#include "token.h"
|
||||
#include "exceptions.h"
|
||||
#include "yaml-cpp/exceptions.h"
|
||||
#include "exp.h"
|
||||
#include "scanscalar.h"
|
||||
#include "scantag.h"
|
||||
@@ -238,7 +238,7 @@ namespace YAML
|
||||
alias = (indicator == Keys::Alias);
|
||||
|
||||
// now eat the content
|
||||
while(Exp::AlphaNumeric().Matches(INPUT))
|
||||
while(INPUT && Exp::Anchor().Matches(INPUT))
|
||||
name += INPUT.get();
|
||||
|
||||
// we need to have read SOMETHING!
|
||||
@@ -276,7 +276,12 @@ namespace YAML
|
||||
} else {
|
||||
bool canBeHandle;
|
||||
token.value = ScanTagHandle(INPUT, canBeHandle);
|
||||
token.data = (token.value.empty() ? Tag::SECONDARY_HANDLE : Tag::PRIMARY_HANDLE);
|
||||
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) {
|
||||
@@ -321,7 +326,7 @@ namespace YAML
|
||||
//if(Exp::IllegalCharInScalar.Matches(INPUT))
|
||||
// throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_SCALAR);
|
||||
|
||||
Token token(Token::SCALAR, mark);
|
||||
Token token(Token::PLAIN_SCALAR, mark);
|
||||
token.value = scalar;
|
||||
m_tokens.push(token);
|
||||
}
|
||||
@@ -360,7 +365,7 @@ namespace YAML
|
||||
m_simpleKeyAllowed = false;
|
||||
m_canBeJSONFlow = true;
|
||||
|
||||
Token token(Token::SCALAR, mark);
|
||||
Token token(Token::NON_PLAIN_SCALAR, mark);
|
||||
token.value = scalar;
|
||||
m_tokens.push(token);
|
||||
}
|
||||
@@ -427,7 +432,7 @@ namespace YAML
|
||||
m_simpleKeyAllowed = true;
|
||||
m_canBeJSONFlow = false;
|
||||
|
||||
Token token(Token::SCALAR, mark);
|
||||
Token token(Token::NON_PLAIN_SCALAR, mark);
|
||||
token.value = scalar;
|
||||
m_tokens.push(token);
|
||||
}
|
||||
|
169
src/sequence.cpp
169
src/sequence.cpp
@@ -1,169 +0,0 @@
|
||||
#include "sequence.h"
|
||||
#include "node.h"
|
||||
#include "scanner.h"
|
||||
#include "token.h"
|
||||
#include "emitter.h"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
Sequence::Sequence()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Sequence::Sequence(const std::vector<Node *>& data)
|
||||
{
|
||||
for(std::size_t i=0;i<data.size();i++)
|
||||
m_data.push_back(data[i]->Clone().release());
|
||||
}
|
||||
|
||||
Sequence::~Sequence()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void Sequence::Clear()
|
||||
{
|
||||
for(std::size_t i=0;i<m_data.size();i++)
|
||||
delete m_data[i];
|
||||
m_data.clear();
|
||||
}
|
||||
|
||||
Content *Sequence::Clone() const
|
||||
{
|
||||
return new Sequence(m_data);
|
||||
}
|
||||
|
||||
bool Sequence::GetBegin(std::vector <Node *>::const_iterator& it) const
|
||||
{
|
||||
it = m_data.begin();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Sequence::GetEnd(std::vector <Node *>::const_iterator& it) const
|
||||
{
|
||||
it = m_data.end();
|
||||
return true;
|
||||
}
|
||||
|
||||
Node *Sequence::GetNode(std::size_t i) const
|
||||
{
|
||||
if(i < m_data.size())
|
||||
return m_data[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::size_t Sequence::GetSize() const
|
||||
{
|
||||
return m_data.size();
|
||||
}
|
||||
|
||||
void Sequence::Parse(Scanner *pScanner, ParserState& state)
|
||||
{
|
||||
Clear();
|
||||
|
||||
// split based on start token
|
||||
switch(pScanner->peek().type) {
|
||||
case Token::BLOCK_SEQ_START: ParseBlock(pScanner, state); break;
|
||||
case Token::FLOW_SEQ_START: ParseFlow(pScanner, state); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void Sequence::ParseBlock(Scanner *pScanner, ParserState& state)
|
||||
{
|
||||
// eat start token
|
||||
pScanner->pop();
|
||||
state.PushCollectionType(ParserState::BLOCK_SEQ);
|
||||
|
||||
while(1) {
|
||||
if(pScanner->empty())
|
||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_SEQ);
|
||||
|
||||
Token token = pScanner->peek();
|
||||
if(token.type != Token::BLOCK_ENTRY && token.type != Token::BLOCK_SEQ_END)
|
||||
throw ParserException(token.mark, ErrorMsg::END_OF_SEQ);
|
||||
|
||||
pScanner->pop();
|
||||
if(token.type == Token::BLOCK_SEQ_END)
|
||||
break;
|
||||
|
||||
Node *pNode = new Node;
|
||||
m_data.push_back(pNode);
|
||||
|
||||
// check for null
|
||||
if(!pScanner->empty()) {
|
||||
const Token& token = pScanner->peek();
|
||||
if(token.type == Token::BLOCK_ENTRY || token.type == Token::BLOCK_SEQ_END)
|
||||
continue;
|
||||
}
|
||||
|
||||
pNode->Parse(pScanner, state);
|
||||
}
|
||||
|
||||
state.PopCollectionType(ParserState::BLOCK_SEQ);
|
||||
}
|
||||
|
||||
void Sequence::ParseFlow(Scanner *pScanner, ParserState& state)
|
||||
{
|
||||
// eat start token
|
||||
pScanner->pop();
|
||||
state.PushCollectionType(ParserState::FLOW_SEQ);
|
||||
|
||||
while(1) {
|
||||
if(pScanner->empty())
|
||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_SEQ_FLOW);
|
||||
|
||||
// first check for end
|
||||
if(pScanner->peek().type == Token::FLOW_SEQ_END) {
|
||||
pScanner->pop();
|
||||
break;
|
||||
}
|
||||
|
||||
// then read the node
|
||||
Node *pNode = new Node;
|
||||
m_data.push_back(pNode);
|
||||
pNode->Parse(pScanner, state);
|
||||
|
||||
// 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 = pScanner->peek();
|
||||
if(token.type == Token::FLOW_ENTRY)
|
||||
pScanner->pop();
|
||||
else if(token.type != Token::FLOW_SEQ_END)
|
||||
throw ParserException(token.mark, ErrorMsg::END_OF_SEQ_FLOW);
|
||||
}
|
||||
|
||||
state.PopCollectionType(ParserState::FLOW_SEQ);
|
||||
}
|
||||
|
||||
void Sequence::Write(Emitter& out) const
|
||||
{
|
||||
out << BeginSeq;
|
||||
for(std::size_t i=0;i<m_data.size();i++)
|
||||
out << *m_data[i];
|
||||
out << EndSeq;
|
||||
}
|
||||
|
||||
int Sequence::Compare(Content *pContent)
|
||||
{
|
||||
return -pContent->Compare(this);
|
||||
}
|
||||
|
||||
int Sequence::Compare(Sequence *pSeq)
|
||||
{
|
||||
std::size_t n = m_data.size(), m = pSeq->m_data.size();
|
||||
if(n < m)
|
||||
return -1;
|
||||
else if(n > m)
|
||||
return 1;
|
||||
|
||||
for(std::size_t i=0;i<n;i++) {
|
||||
int cmp = m_data[i]->Compare(*pSeq->m_data[i]);
|
||||
if(cmp != 0)
|
||||
return cmp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
@@ -1,49 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef SEQUENCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define SEQUENCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "content.h"
|
||||
#include <vector>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Node;
|
||||
|
||||
class Sequence: public Content
|
||||
{
|
||||
public:
|
||||
Sequence();
|
||||
Sequence(const std::vector<Node *>& data);
|
||||
virtual ~Sequence();
|
||||
|
||||
void Clear();
|
||||
virtual Content *Clone() const;
|
||||
|
||||
virtual bool GetBegin(std::vector <Node *>::const_iterator& it) const;
|
||||
virtual bool GetEnd(std::vector <Node *>::const_iterator& it) const;
|
||||
virtual Node *GetNode(std::size_t i) const;
|
||||
virtual std::size_t GetSize() const;
|
||||
|
||||
virtual void Parse(Scanner *pScanner, ParserState& state);
|
||||
virtual void Write(Emitter& out) const;
|
||||
|
||||
virtual bool IsSequence() const { return true; }
|
||||
|
||||
// ordering
|
||||
virtual int Compare(Content *pContent);
|
||||
virtual int Compare(Scalar *) { return 1; }
|
||||
virtual int Compare(Sequence *pSeq);
|
||||
virtual int Compare(Map *) { return -1; }
|
||||
|
||||
private:
|
||||
void ParseBlock(Scanner *pScanner, ParserState& state);
|
||||
void ParseFlow(Scanner *pScanner, ParserState& state);
|
||||
|
||||
protected:
|
||||
std::vector <Node *> m_data;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SEQUENCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,12 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#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 "noncopyable.h"
|
||||
#include "yaml-cpp/noncopyable.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#include "scanner.h"
|
||||
#include "token.h"
|
||||
#include "exceptions.h"
|
||||
#include "yaml-cpp/exceptions.h"
|
||||
#include "exp.h"
|
||||
|
||||
namespace YAML
|
||||
|
381
src/singledocparser.cpp
Normal file
381
src/singledocparser.cpp
Normal file
@@ -0,0 +1,381 @@
|
||||
#include "singledocparser.h"
|
||||
#include "collectionstack.h"
|
||||
#include "directives.h"
|
||||
#include "yaml-cpp/eventhandler.h"
|
||||
#include "yaml-cpp/exceptions.h"
|
||||
#include "scanner.h"
|
||||
#include "tag.h"
|
||||
#include "token.h"
|
||||
#include <sstream>
|
||||
#include <cstdio>
|
||||
#include <algorithm>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
SingleDocParser::SingleDocParser(Scanner& scanner, const Directives& directives): m_scanner(scanner), m_directives(directives), m_pCollectionStack(new CollectionStack), m_curAnchor(0)
|
||||
{
|
||||
}
|
||||
|
||||
SingleDocParser::~SingleDocParser()
|
||||
{
|
||||
}
|
||||
|
||||
// HandleDocument
|
||||
// . Handles the next document
|
||||
// . Throws a ParserException on error.
|
||||
void SingleDocParser::HandleDocument(EventHandler& eventHandler)
|
||||
{
|
||||
assert(!m_scanner.empty()); // guaranteed that there are tokens
|
||||
assert(!m_curAnchor);
|
||||
|
||||
eventHandler.OnDocumentStart(m_scanner.peek().mark);
|
||||
|
||||
// eat doc start
|
||||
if(m_scanner.peek().type == Token::DOC_START)
|
||||
m_scanner.pop();
|
||||
|
||||
// recurse!
|
||||
HandleNode(eventHandler);
|
||||
|
||||
eventHandler.OnDocumentEnd();
|
||||
|
||||
// and finally eat any doc ends we see
|
||||
while(!m_scanner.empty() && m_scanner.peek().type == Token::DOC_END)
|
||||
m_scanner.pop();
|
||||
}
|
||||
|
||||
void SingleDocParser::HandleNode(EventHandler& eventHandler)
|
||||
{
|
||||
// an empty node *is* a possibility
|
||||
if(m_scanner.empty()) {
|
||||
eventHandler.OnNull(Mark::null(), NullAnchor);
|
||||
return;
|
||||
}
|
||||
|
||||
// save location
|
||||
Mark mark = m_scanner.peek().mark;
|
||||
|
||||
// special case: a value node by itself must be a map, with no header
|
||||
if(m_scanner.peek().type == Token::VALUE) {
|
||||
eventHandler.OnMapStart(mark, "", NullAnchor);
|
||||
HandleMap(eventHandler);
|
||||
eventHandler.OnMapEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
// special case: an alias node
|
||||
if(m_scanner.peek().type == Token::ALIAS) {
|
||||
eventHandler.OnAlias(mark, LookupAnchor(mark, m_scanner.peek().value));
|
||||
m_scanner.pop();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string tag;
|
||||
anchor_t anchor;
|
||||
ParseProperties(tag, anchor);
|
||||
|
||||
const Token& token = m_scanner.peek();
|
||||
|
||||
// add non-specific tags
|
||||
if(tag.empty())
|
||||
tag = (token.type == Token::NON_PLAIN_SCALAR ? "!" : "?");
|
||||
|
||||
// now split based on what kind of node we should be
|
||||
switch(token.type) {
|
||||
case Token::PLAIN_SCALAR:
|
||||
case Token::NON_PLAIN_SCALAR:
|
||||
eventHandler.OnScalar(mark, tag, anchor, token.value);
|
||||
m_scanner.pop();
|
||||
return;
|
||||
case Token::FLOW_SEQ_START:
|
||||
case Token::BLOCK_SEQ_START:
|
||||
eventHandler.OnSequenceStart(mark, tag, anchor);
|
||||
HandleSequence(eventHandler);
|
||||
eventHandler.OnSequenceEnd();
|
||||
return;
|
||||
case Token::FLOW_MAP_START:
|
||||
case Token::BLOCK_MAP_START:
|
||||
eventHandler.OnMapStart(mark, tag, anchor);
|
||||
HandleMap(eventHandler);
|
||||
eventHandler.OnMapEnd();
|
||||
return;
|
||||
case Token::KEY:
|
||||
// compact maps can only go in a flow sequence
|
||||
if(m_pCollectionStack->GetCurCollectionType() == CollectionType::FlowSeq) {
|
||||
eventHandler.OnMapStart(mark, tag, anchor);
|
||||
HandleMap(eventHandler);
|
||||
eventHandler.OnMapEnd();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(tag == "?")
|
||||
eventHandler.OnNull(mark, anchor);
|
||||
else
|
||||
eventHandler.OnScalar(mark, tag, anchor, "");
|
||||
}
|
||||
|
||||
void SingleDocParser::HandleSequence(EventHandler& eventHandler)
|
||||
{
|
||||
// split based on start token
|
||||
switch(m_scanner.peek().type) {
|
||||
case Token::BLOCK_SEQ_START: HandleBlockSequence(eventHandler); break;
|
||||
case Token::FLOW_SEQ_START: HandleFlowSequence(eventHandler); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void SingleDocParser::HandleBlockSequence(EventHandler& eventHandler)
|
||||
{
|
||||
// eat start token
|
||||
m_scanner.pop();
|
||||
m_pCollectionStack->PushCollectionType(CollectionType::BlockSeq);
|
||||
|
||||
while(1) {
|
||||
if(m_scanner.empty())
|
||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_SEQ);
|
||||
|
||||
Token token = m_scanner.peek();
|
||||
if(token.type != Token::BLOCK_ENTRY && token.type != Token::BLOCK_SEQ_END)
|
||||
throw ParserException(token.mark, ErrorMsg::END_OF_SEQ);
|
||||
|
||||
m_scanner.pop();
|
||||
if(token.type == Token::BLOCK_SEQ_END)
|
||||
break;
|
||||
|
||||
// check for null
|
||||
if(!m_scanner.empty()) {
|
||||
const Token& token = m_scanner.peek();
|
||||
if(token.type == Token::BLOCK_ENTRY || token.type == Token::BLOCK_SEQ_END) {
|
||||
eventHandler.OnNull(token.mark, NullAnchor);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
HandleNode(eventHandler);
|
||||
}
|
||||
|
||||
m_pCollectionStack->PopCollectionType(CollectionType::BlockSeq);
|
||||
}
|
||||
|
||||
void SingleDocParser::HandleFlowSequence(EventHandler& eventHandler)
|
||||
{
|
||||
// eat start token
|
||||
m_scanner.pop();
|
||||
m_pCollectionStack->PushCollectionType(CollectionType::FlowSeq);
|
||||
|
||||
while(1) {
|
||||
if(m_scanner.empty())
|
||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_SEQ_FLOW);
|
||||
|
||||
// first check for end
|
||||
if(m_scanner.peek().type == Token::FLOW_SEQ_END) {
|
||||
m_scanner.pop();
|
||||
break;
|
||||
}
|
||||
|
||||
// then read the node
|
||||
HandleNode(eventHandler);
|
||||
|
||||
// now eat the separator (or could be a sequence end, which we ignore - but if it's neither, then it's a bad node)
|
||||
Token& token = m_scanner.peek();
|
||||
if(token.type == Token::FLOW_ENTRY)
|
||||
m_scanner.pop();
|
||||
else if(token.type != Token::FLOW_SEQ_END)
|
||||
throw ParserException(token.mark, ErrorMsg::END_OF_SEQ_FLOW);
|
||||
}
|
||||
|
||||
m_pCollectionStack->PopCollectionType(CollectionType::FlowSeq);
|
||||
}
|
||||
|
||||
void SingleDocParser::HandleMap(EventHandler& eventHandler)
|
||||
{
|
||||
// split based on start token
|
||||
switch(m_scanner.peek().type) {
|
||||
case Token::BLOCK_MAP_START: HandleBlockMap(eventHandler); break;
|
||||
case Token::FLOW_MAP_START: HandleFlowMap(eventHandler); break;
|
||||
case Token::KEY: HandleCompactMap(eventHandler); break;
|
||||
case Token::VALUE: HandleCompactMapWithNoKey(eventHandler); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void SingleDocParser::HandleBlockMap(EventHandler& eventHandler)
|
||||
{
|
||||
// eat start token
|
||||
m_scanner.pop();
|
||||
m_pCollectionStack->PushCollectionType(CollectionType::BlockMap);
|
||||
|
||||
while(1) {
|
||||
if(m_scanner.empty())
|
||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP);
|
||||
|
||||
Token token = m_scanner.peek();
|
||||
if(token.type != Token::KEY && token.type != Token::VALUE && token.type != Token::BLOCK_MAP_END)
|
||||
throw ParserException(token.mark, ErrorMsg::END_OF_MAP);
|
||||
|
||||
if(token.type == Token::BLOCK_MAP_END) {
|
||||
m_scanner.pop();
|
||||
break;
|
||||
}
|
||||
|
||||
// grab key (if non-null)
|
||||
if(token.type == Token::KEY) {
|
||||
m_scanner.pop();
|
||||
HandleNode(eventHandler);
|
||||
} else {
|
||||
eventHandler.OnNull(token.mark, NullAnchor);
|
||||
}
|
||||
|
||||
// now grab value (optional)
|
||||
if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
|
||||
m_scanner.pop();
|
||||
HandleNode(eventHandler);
|
||||
} else {
|
||||
eventHandler.OnNull(token.mark, NullAnchor);
|
||||
}
|
||||
}
|
||||
|
||||
m_pCollectionStack->PopCollectionType(CollectionType::BlockMap);
|
||||
}
|
||||
|
||||
void SingleDocParser::HandleFlowMap(EventHandler& eventHandler)
|
||||
{
|
||||
// eat start token
|
||||
m_scanner.pop();
|
||||
m_pCollectionStack->PushCollectionType(CollectionType::FlowMap);
|
||||
|
||||
while(1) {
|
||||
if(m_scanner.empty())
|
||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP_FLOW);
|
||||
|
||||
Token& token = m_scanner.peek();
|
||||
// first check for end
|
||||
if(token.type == Token::FLOW_MAP_END) {
|
||||
m_scanner.pop();
|
||||
break;
|
||||
}
|
||||
|
||||
// grab key (if non-null)
|
||||
if(token.type == Token::KEY) {
|
||||
m_scanner.pop();
|
||||
HandleNode(eventHandler);
|
||||
} else {
|
||||
eventHandler.OnNull(token.mark, NullAnchor);
|
||||
}
|
||||
|
||||
// now grab value (optional)
|
||||
if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
|
||||
m_scanner.pop();
|
||||
HandleNode(eventHandler);
|
||||
} else {
|
||||
eventHandler.OnNull(token.mark, NullAnchor);
|
||||
}
|
||||
|
||||
// now eat the separator (or could be a map end, which we ignore - but if it's neither, then it's a bad node)
|
||||
Token& nextToken = m_scanner.peek();
|
||||
if(nextToken.type == Token::FLOW_ENTRY)
|
||||
m_scanner.pop();
|
||||
else if(nextToken.type != Token::FLOW_MAP_END)
|
||||
throw ParserException(nextToken.mark, ErrorMsg::END_OF_MAP_FLOW);
|
||||
}
|
||||
|
||||
m_pCollectionStack->PopCollectionType(CollectionType::FlowMap);
|
||||
}
|
||||
|
||||
// . Single "key: value" pair in a flow sequence
|
||||
void SingleDocParser::HandleCompactMap(EventHandler& eventHandler)
|
||||
{
|
||||
m_pCollectionStack->PushCollectionType(CollectionType::CompactMap);
|
||||
|
||||
// grab key
|
||||
Mark mark = m_scanner.peek().mark;
|
||||
m_scanner.pop();
|
||||
HandleNode(eventHandler);
|
||||
|
||||
// now grab value (optional)
|
||||
if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
|
||||
m_scanner.pop();
|
||||
HandleNode(eventHandler);
|
||||
} else {
|
||||
eventHandler.OnNull(mark, NullAnchor);
|
||||
}
|
||||
|
||||
m_pCollectionStack->PopCollectionType(CollectionType::CompactMap);
|
||||
}
|
||||
|
||||
// . Single ": value" pair in a flow sequence
|
||||
void SingleDocParser::HandleCompactMapWithNoKey(EventHandler& eventHandler)
|
||||
{
|
||||
m_pCollectionStack->PushCollectionType(CollectionType::CompactMap);
|
||||
|
||||
// null key
|
||||
eventHandler.OnNull(m_scanner.peek().mark, NullAnchor);
|
||||
|
||||
// grab value
|
||||
m_scanner.pop();
|
||||
HandleNode(eventHandler);
|
||||
|
||||
m_pCollectionStack->PopCollectionType(CollectionType::CompactMap);
|
||||
}
|
||||
|
||||
// ParseProperties
|
||||
// . Grabs any tag or anchor tokens and deals with them.
|
||||
void SingleDocParser::ParseProperties(std::string& tag, anchor_t& anchor)
|
||||
{
|
||||
tag.clear();
|
||||
anchor = NullAnchor;
|
||||
|
||||
while(1) {
|
||||
if(m_scanner.empty())
|
||||
return;
|
||||
|
||||
switch(m_scanner.peek().type) {
|
||||
case Token::TAG: ParseTag(tag); break;
|
||||
case Token::ANCHOR: ParseAnchor(anchor); break;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SingleDocParser::ParseTag(std::string& tag)
|
||||
{
|
||||
Token& token = m_scanner.peek();
|
||||
if(!tag.empty())
|
||||
throw ParserException(token.mark, ErrorMsg::MULTIPLE_TAGS);
|
||||
|
||||
Tag tagInfo(token);
|
||||
tag = tagInfo.Translate(m_directives);
|
||||
m_scanner.pop();
|
||||
}
|
||||
|
||||
void SingleDocParser::ParseAnchor(anchor_t& anchor)
|
||||
{
|
||||
Token& token = m_scanner.peek();
|
||||
if(anchor)
|
||||
throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS);
|
||||
|
||||
anchor = RegisterAnchor(token.value);
|
||||
m_scanner.pop();
|
||||
}
|
||||
|
||||
anchor_t SingleDocParser::RegisterAnchor(const std::string& name)
|
||||
{
|
||||
if(name.empty())
|
||||
return NullAnchor;
|
||||
|
||||
return m_anchors[name] = ++m_curAnchor;
|
||||
}
|
||||
|
||||
anchor_t SingleDocParser::LookupAnchor(const Mark& mark, const std::string& name) const
|
||||
{
|
||||
Anchors::const_iterator it = m_anchors.find(name);
|
||||
if(it == m_anchors.end())
|
||||
throw ParserException(mark, ErrorMsg::UNKNOWN_ANCHOR);
|
||||
|
||||
return it->second;
|
||||
}
|
||||
}
|
65
src/singledocparser.h
Normal file
65
src/singledocparser.h
Normal file
@@ -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
|
13
src/stream.h
13
src/stream.h
@@ -1,16 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#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 "noncopyable.h"
|
||||
#include "mark.h"
|
||||
|
||||
#include "yaml-cpp/noncopyable.h"
|
||||
#include "yaml-cpp/mark.h"
|
||||
#include <cstddef>
|
||||
#include <deque>
|
||||
#include <ios>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
|
@@ -1,10 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#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 "noncopyable.h"
|
||||
|
||||
#include "yaml-cpp/noncopyable.h"
|
||||
#include <cstddef>
|
||||
|
||||
namespace YAML
|
||||
|
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#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>
|
||||
|
||||
|
12
src/tag.cpp
12
src/tag.cpp
@@ -1,7 +1,8 @@
|
||||
#include "tag.h"
|
||||
#include "directives.h"
|
||||
#include "token.h"
|
||||
#include "parserstate.h"
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
@@ -28,23 +29,24 @@ namespace YAML
|
||||
}
|
||||
}
|
||||
|
||||
const std::string Tag::Translate(const ParserState& state)
|
||||
const std::string Tag::Translate(const Directives& directives)
|
||||
{
|
||||
switch(type) {
|
||||
case VERBATIM:
|
||||
return value;
|
||||
case PRIMARY_HANDLE:
|
||||
return state.TranslateTagHandle("!") + value;
|
||||
return directives.TranslateTagHandle("!") + value;
|
||||
case SECONDARY_HANDLE:
|
||||
return state.TranslateTagHandle("!!") + value;
|
||||
return directives.TranslateTagHandle("!!") + value;
|
||||
case NAMED_HANDLE:
|
||||
return state.TranslateTagHandle("!" + handle + "!") + value;
|
||||
return directives.TranslateTagHandle("!" + handle + "!") + value;
|
||||
case NON_SPECIFIC:
|
||||
// TODO:
|
||||
return "!";
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
throw std::runtime_error("yaml-cpp: internal error, bad tag type");
|
||||
}
|
||||
}
|
||||
|
||||
|
10
src/tag.h
10
src/tag.h
@@ -1,14 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#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 ParserState;
|
||||
struct Directives;
|
||||
|
||||
struct Tag {
|
||||
enum TYPE {
|
||||
@@ -16,7 +18,7 @@ namespace YAML
|
||||
};
|
||||
|
||||
Tag(const Token& token);
|
||||
const std::string Translate(const ParserState& state);
|
||||
const std::string Translate(const Directives& directives);
|
||||
|
||||
TYPE type;
|
||||
std::string handle, value;
|
||||
|
15
src/token.h
15
src/token.h
@@ -1,11 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#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 "mark.h"
|
||||
#include <ios>
|
||||
|
||||
#include "yaml-cpp/mark.h"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -57,9 +59,10 @@ namespace YAML
|
||||
ANCHOR,
|
||||
ALIAS,
|
||||
TAG,
|
||||
SCALAR
|
||||
PLAIN_SCALAR,
|
||||
NON_PLAIN_SCALAR
|
||||
};
|
||||
|
||||
|
||||
// data
|
||||
Token(TYPE type_, const Mark& mark_): status(VALID), type(type_), mark(mark_), data(0) {}
|
||||
|
||||
|
226
test.vcproj
226
test.vcproj
@@ -1,226 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="test"
|
||||
ProjectGUID="{D1108F40-6ADF-467E-A95A-236C39A515C5}"
|
||||
RootNamespace="test"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/D_SCL_SECURE_NO_WARNINGS"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="include"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
DisableSpecificWarnings="4127;4355"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="yamlcppd.lib"
|
||||
AdditionalLibraryDirectories="lib"
|
||||
GenerateDebugInformation="true"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/D_SCL_SECURE_NO_WARNINGS"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="include"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4127;4355"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="yamlcpp.lib"
|
||||
AdditionalLibraryDirectories="lib"
|
||||
GenerateDebugInformation="true"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\test\emittertests.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\test\main.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\test\parsertests.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\test\spectests.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\test\tests.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\test\emittertests.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\test\parsertests.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\test\spectests.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\test\tests.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
@@ -1,5 +1,5 @@
|
||||
#include "tests.h"
|
||||
#include "yaml.h"
|
||||
#include "yaml-cpp/yaml.h"
|
||||
|
||||
namespace Test
|
||||
{
|
||||
@@ -9,7 +9,7 @@ namespace Test
|
||||
|
||||
void SimpleScalar(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
out << "Hello, World!";
|
||||
desiredOutput = "--- Hello, World!";
|
||||
desiredOutput = "Hello, World!";
|
||||
}
|
||||
|
||||
void SimpleSeq(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -19,7 +19,7 @@ namespace Test
|
||||
out << "milk";
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- eggs\n- bread\n- milk";
|
||||
desiredOutput = "- eggs\n- bread\n- milk";
|
||||
}
|
||||
|
||||
void SimpleFlowSeq(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -30,7 +30,7 @@ namespace Test
|
||||
out << "Moe";
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "--- [Larry, Curly, Moe]";
|
||||
desiredOutput = "[Larry, Curly, Moe]";
|
||||
}
|
||||
|
||||
void EmptyFlowSeq(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -38,7 +38,7 @@ namespace Test
|
||||
out << YAML::BeginSeq;
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "--- []";
|
||||
desiredOutput = "[]";
|
||||
}
|
||||
|
||||
void NestedBlockSeq(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -47,7 +47,7 @@ namespace Test
|
||||
out << YAML::BeginSeq << "subitem 1" << "subitem 2" << YAML::EndSeq;
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- item 1\n-\n - subitem 1\n - subitem 2";
|
||||
desiredOutput = "- item 1\n-\n - subitem 1\n - subitem 2";
|
||||
}
|
||||
|
||||
void NestedFlowSeq(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -56,7 +56,7 @@ namespace Test
|
||||
out << YAML::Flow << YAML::BeginSeq << "two" << "three" << YAML::EndSeq;
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- one\n- [two, three]";
|
||||
desiredOutput = "- one\n- [two, three]";
|
||||
}
|
||||
|
||||
void SimpleMap(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -67,7 +67,7 @@ namespace Test
|
||||
out << YAML::Value << "3B";
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\nname: Ryan Braun\nposition: 3B";
|
||||
desiredOutput = "name: Ryan Braun\nposition: 3B";
|
||||
}
|
||||
|
||||
void SimpleFlowMap(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -79,7 +79,7 @@ namespace Test
|
||||
out << YAML::Value << "blue";
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "--- {shape: square, color: blue}";
|
||||
desiredOutput = "{shape: square, color: blue}";
|
||||
}
|
||||
|
||||
void MapAndList(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -90,7 +90,7 @@ namespace Test
|
||||
out << YAML::Value << YAML::BeginSeq << "Sasha" << "Malia" << YAML::EndSeq;
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\nname: Barack Obama\nchildren:\n - Sasha\n - Malia";
|
||||
desiredOutput = "name: Barack Obama\nchildren:\n - Sasha\n - Malia";
|
||||
}
|
||||
|
||||
void ListAndMap(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -103,7 +103,7 @@ namespace Test
|
||||
out << "item 2";
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- item 1\n-\n pens: 8\n pencils: 14\n- item 2";
|
||||
desiredOutput = "- item 1\n- pens: 8\n pencils: 14\n- item 2";
|
||||
}
|
||||
|
||||
void NestedBlockMap(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -119,7 +119,7 @@ namespace Test
|
||||
out << YAML::EndMap;
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\nname: Fred\ngrades:\n algebra: A\n physics: C+\n literature: B";
|
||||
desiredOutput = "name: Fred\ngrades:\n algebra: A\n physics: C+\n literature: B";
|
||||
}
|
||||
|
||||
void NestedFlowMap(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -136,7 +136,7 @@ namespace Test
|
||||
out << YAML::EndMap;
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "--- {name: Fred, grades: {algebra: A, physics: C+, literature: B}}";
|
||||
desiredOutput = "{name: Fred, grades: {algebra: A, physics: C+, literature: B}}";
|
||||
}
|
||||
|
||||
void MapListMix(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -149,7 +149,7 @@ namespace Test
|
||||
out << YAML::Key << "invincible" << YAML::Value << YAML::OnOffBool << false;
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\nname: Bob\nposition: [2, 4]\ninvincible: off";
|
||||
desiredOutput = "name: Bob\nposition: [2, 4]\ninvincible: off";
|
||||
}
|
||||
|
||||
void SimpleLongKey(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -162,7 +162,7 @@ namespace Test
|
||||
out << YAML::Value << 145;
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\n? height\n: 5'9\"\n? weight\n: 145";
|
||||
desiredOutput = "? height\n: 5'9\"\n? weight\n: 145";
|
||||
}
|
||||
|
||||
void SingleLongKey(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -176,7 +176,7 @@ namespace Test
|
||||
out << YAML::Value << 145;
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\nage: 24\n? height\n: 5'9\"\nweight: 145";
|
||||
desiredOutput = "age: 24\n? height\n: 5'9\"\nweight: 145";
|
||||
}
|
||||
|
||||
void ComplexLongKey(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -189,7 +189,7 @@ namespace Test
|
||||
out << YAML::Value << "demon";
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\n?\n - 1\n - 3\n: monster\n? [2, 0]\n: demon";
|
||||
desiredOutput = "?\n - 1\n - 3\n: monster\n? [2, 0]\n: demon";
|
||||
}
|
||||
|
||||
void AutoLongKey(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -203,7 +203,7 @@ namespace Test
|
||||
out << YAML::Value << "angel";
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\n?\n - 1\n - 3\n: monster\n? [2, 0]\n: demon\nthe origin: angel";
|
||||
desiredOutput = "?\n - 1\n - 3\n: monster\n? [2, 0]\n: demon\nthe origin: angel";
|
||||
}
|
||||
|
||||
void ScalarFormat(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -217,7 +217,7 @@ namespace Test
|
||||
out << YAML::Literal << "literal scalar\nthat may span\nmany, many\nlines and have \"whatever\" crazy\tsymbols that we like";
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- simple scalar\n- 'explicit single-quoted scalar'\n- \"explicit double-quoted scalar\"\n- \"auto-detected\\x0adouble-quoted scalar\"\n- a non-\"auto-detected\" double-quoted scalar\n- |\n literal scalar\n that may span\n many, many\n lines and have \"whatever\" crazy\tsymbols that we like";
|
||||
desiredOutput = "- simple scalar\n- 'explicit single-quoted scalar'\n- \"explicit double-quoted scalar\"\n- \"auto-detected\\x0adouble-quoted scalar\"\n- a non-\"auto-detected\" double-quoted scalar\n- |\n literal scalar\n that may span\n many, many\n lines and have \"whatever\" crazy\tsymbols that we like";
|
||||
}
|
||||
|
||||
void AutoLongKeyScalar(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -227,7 +227,7 @@ namespace Test
|
||||
out << YAML::Value << "and its value";
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\n? |\n multi-line\n scalar\n: and its value";
|
||||
desiredOutput = "? |\n multi-line\n scalar\n: and its value";
|
||||
}
|
||||
|
||||
void LongKeyFlowMap(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -240,7 +240,7 @@ namespace Test
|
||||
out << YAML::Value << "and its value";
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "--- {simple key: and value, ? long key: and its value}";
|
||||
desiredOutput = "{simple key: and value, ? long key: and its value}";
|
||||
}
|
||||
|
||||
void BlockMapAsKey(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -255,7 +255,7 @@ namespace Test
|
||||
out << "total value";
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\n?\n key: value\n next key: next value\n: total value";
|
||||
desiredOutput = "?\n key: value\n next key: next value\n: total value";
|
||||
}
|
||||
|
||||
void AliasAndAnchor(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -269,7 +269,7 @@ namespace Test
|
||||
out << YAML::Alias("fred");
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- &fred\n name: Fred\n age: 42\n- *fred";
|
||||
desiredOutput = "- &fred\n name: Fred\n age: 42\n- *fred";
|
||||
}
|
||||
|
||||
void AliasAndAnchorWithNull(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -279,14 +279,28 @@ namespace Test
|
||||
out << YAML::Alias("fred");
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- &fred ~\n- *fred";
|
||||
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";
|
||||
desiredOutput = "!<!foo> bar";
|
||||
}
|
||||
|
||||
void VerbatimTagInBlockSeq(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -296,7 +310,7 @@ namespace Test
|
||||
out << "baz";
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- !<!foo> bar\n- baz";
|
||||
desiredOutput = "- !<!foo> bar\n- baz";
|
||||
}
|
||||
|
||||
void VerbatimTagInFlowSeq(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -306,7 +320,7 @@ namespace Test
|
||||
out << "baz";
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "--- [!<!foo> bar, baz]";
|
||||
desiredOutput = "[!<!foo> bar, baz]";
|
||||
}
|
||||
|
||||
void VerbatimTagInFlowSeqWithNull(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -316,7 +330,7 @@ namespace Test
|
||||
out << "baz";
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "--- [!<!foo> ~, baz]";
|
||||
desiredOutput = "[!<!foo> ~, baz]";
|
||||
}
|
||||
|
||||
void VerbatimTagInBlockMap(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -326,7 +340,7 @@ namespace Test
|
||||
out << YAML::Value << YAML::VerbatimTag("!waz") << "baz";
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\n!<!foo> bar: !<!waz> baz";
|
||||
desiredOutput = "!<!foo> bar: !<!waz> baz";
|
||||
}
|
||||
|
||||
void VerbatimTagInFlowMap(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -336,7 +350,7 @@ namespace Test
|
||||
out << YAML::Value << "baz";
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "--- {!<!foo> bar: baz}";
|
||||
desiredOutput = "{!<!foo> bar: baz}";
|
||||
}
|
||||
|
||||
void VerbatimTagInFlowMapWithNull(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -346,21 +360,21 @@ namespace Test
|
||||
out << YAML::Value << "baz";
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "--- {!<!foo> ~: baz}";
|
||||
desiredOutput = "{!<!foo> ~: baz}";
|
||||
}
|
||||
|
||||
void VerbatimTagWithEmptySeq(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << YAML::VerbatimTag("!foo") << YAML::BeginSeq << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "--- !<!foo>\n[]";
|
||||
desiredOutput = "!<!foo>\n[]";
|
||||
}
|
||||
|
||||
void VerbatimTagWithEmptyMap(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << YAML::VerbatimTag("!bar") << YAML::BeginMap << YAML::EndMap;
|
||||
|
||||
desiredOutput = "--- !<!bar>\n{}";
|
||||
desiredOutput = "!<!bar>\n{}";
|
||||
}
|
||||
|
||||
void VerbatimTagWithEmptySeqAndMap(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -370,7 +384,32 @@ namespace Test
|
||||
out << YAML::VerbatimTag("!bar") << YAML::BeginMap << YAML::EndMap;
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- !<!foo>\n []\n- !<!bar>\n {}";
|
||||
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)
|
||||
@@ -426,7 +465,7 @@ namespace Test
|
||||
out << YAML::Value << YAML::Alias("id001");
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\nreceipt: Oz-Ware Purchase Invoice\ndate: 2007-08-06\ncustomer:\n given: Dorothy\n family: Gale\nitems:\n -\n part_no: A4786\n descrip: Water Bucket (Filled)\n price: 1.47\n quantity: 4\n -\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";
|
||||
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)
|
||||
@@ -446,7 +485,7 @@ namespace Test
|
||||
out << ages;
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- [2, 3, 5, 7, 11, 13]\n-\n Daniel: 26\n Jesse: 24";
|
||||
desiredOutput = "- [2, 3, 5, 7, 11, 13]\n- Daniel: 26\n Jesse: 24";
|
||||
}
|
||||
|
||||
void SimpleComment(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -456,7 +495,7 @@ namespace Test
|
||||
out << YAML::Value << "least squares" << YAML::Comment("should we change this method?");
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\nmethod: least squares # should we change this method?";
|
||||
desiredOutput = "method: least squares # should we change this method?";
|
||||
}
|
||||
|
||||
void MultiLineComment(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -466,7 +505,7 @@ namespace Test
|
||||
out << "item 2";
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- item 1 # really really long\n # comment that couldn't possibly\n # fit on one line\n- item 2";
|
||||
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)
|
||||
@@ -476,7 +515,41 @@ namespace Test
|
||||
out << YAML::Value << "value";
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\n? long key # long key\n: value";
|
||||
desiredOutput = "? long key # long key\n: value";
|
||||
}
|
||||
|
||||
void InitialComment(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << YAML::Comment("A comment describing the purpose of the file.");
|
||||
out << YAML::BeginMap << YAML::Key << "key" << YAML::Value << "value" << YAML::EndMap;
|
||||
|
||||
desiredOutput = "# A comment describing the purpose of the file.\nkey: value";
|
||||
}
|
||||
|
||||
void InitialCommentWithDocIndicator(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << YAML::BeginDoc << YAML::Comment("A comment describing the purpose of the file.");
|
||||
out << YAML::BeginMap << YAML::Key << "key" << YAML::Value << "value" << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\n# A comment describing the purpose of the file.\nkey: value";
|
||||
}
|
||||
|
||||
void CommentInFlowSeq(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << YAML::Flow << YAML::BeginSeq << "foo" << YAML::Comment("foo!") << "bar" << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "[foo # foo!\n, bar]";
|
||||
}
|
||||
|
||||
void CommentInFlowMap(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << YAML::Flow << YAML::BeginMap;
|
||||
out << YAML::Key << "foo" << YAML::Comment("foo!") << YAML::Value << "foo value";
|
||||
out << YAML::Key << "bar" << YAML::Value << "bar value" << YAML::Comment("bar!");
|
||||
out << YAML::Key << "baz" << YAML::Comment("baz!") << YAML::Value << "baz value" << YAML::Comment("baz!");
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "{foo # foo!\n: foo value, bar: bar value # bar!\n, baz # baz!\n: baz value # baz!\n}";
|
||||
}
|
||||
|
||||
void Indentation(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -489,7 +562,7 @@ namespace Test
|
||||
out << YAML::EndMap;
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n-\n key 1: value 1\n key 2:\n - a\n - b\n - c";
|
||||
desiredOutput = "- key 1: value 1\n key 2:\n - a\n - b\n - c";
|
||||
}
|
||||
|
||||
void SimpleGlobalSettings(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -504,7 +577,7 @@ namespace Test
|
||||
out << YAML::EndMap;
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n-\n ? key 1\n : value 1\n ? key 2\n : [a, b, c]";
|
||||
desiredOutput = "- ? key 1\n : value 1\n ? key 2\n : [a, b, c]";
|
||||
}
|
||||
|
||||
void ComplexGlobalSettings(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -523,7 +596,7 @@ namespace Test
|
||||
out << YAML::EndMap;
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n-\n key 1: value 1\n key 2: [a, b, c]\n-\n ? [1, 2]\n :\n a: b";
|
||||
desiredOutput = "- key 1: value 1\n key 2: [a, b, c]\n- ? [1, 2]\n :\n a: b";
|
||||
}
|
||||
|
||||
void Null(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -536,26 +609,26 @@ namespace Test
|
||||
out << YAML::EndMap;
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- ~\n-\n null value: ~\n ~: null key";
|
||||
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\"";
|
||||
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";
|
||||
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\"";
|
||||
desiredOutput = "\"\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2\"";
|
||||
}
|
||||
|
||||
struct Foo {
|
||||
@@ -581,7 +654,7 @@ namespace Test
|
||||
out << Foo(3, "goodbye");
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n-\n x: 5\n bar: hello\n-\n x: 3\n bar: goodbye";
|
||||
desiredOutput = "- x: 5\n bar: hello\n- x: 3\n bar: goodbye";
|
||||
}
|
||||
|
||||
void UserTypeInContainer(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -591,7 +664,7 @@ namespace Test
|
||||
fv.push_back(Foo(3, "goodbye"));
|
||||
out << fv;
|
||||
|
||||
desiredOutput = "---\n-\n x: 5\n bar: hello\n-\n x: 3\n bar: goodbye";
|
||||
desiredOutput = "- x: 5\n bar: hello\n- x: 3\n bar: goodbye";
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@@ -612,7 +685,7 @@ namespace Test
|
||||
out << bar << baz;
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- 5\n- ~";
|
||||
desiredOutput = "- 5\n- ~";
|
||||
}
|
||||
|
||||
void PointerToUserType(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -624,7 +697,162 @@ namespace Test
|
||||
out << bar << baz;
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n-\n x: 5\n bar: hello\n- ~";
|
||||
desiredOutput = "- x: 5\n bar: hello\n- ~";
|
||||
}
|
||||
|
||||
void NewlineAtEnd(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << "Hello" << YAML::Newline << YAML::Newline;
|
||||
desiredOutput = "Hello\n\n";
|
||||
}
|
||||
|
||||
void NewlineInBlockSequence(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << YAML::BeginSeq;
|
||||
out << "a" << YAML::Newline << "b" << "c" << YAML::Newline << "d";
|
||||
out << YAML::EndSeq;
|
||||
desiredOutput = "- a\n\n- b\n- c\n\n- d";
|
||||
}
|
||||
|
||||
void NewlineInFlowSequence(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << YAML::Flow << YAML::BeginSeq;
|
||||
out << "a" << YAML::Newline << "b" << "c" << YAML::Newline << "d";
|
||||
out << YAML::EndSeq;
|
||||
desiredOutput = "[a\n, b, c\n, d]";
|
||||
}
|
||||
|
||||
void NewlineInBlockMap(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << YAML::BeginMap;
|
||||
out << YAML::Key << "a" << YAML::Value << "foo" << YAML::Newline;
|
||||
out << YAML::Key << "b" << YAML::Newline << YAML::Value << "bar";
|
||||
out << YAML::LongKey << YAML::Key << "c" << YAML::Newline << YAML::Value << "car";
|
||||
out << YAML::EndMap;
|
||||
desiredOutput = "a: foo\n\nb: bar\n? c\n\n: car";
|
||||
}
|
||||
|
||||
void NewlineInFlowMap(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << YAML::Flow << YAML::BeginMap;
|
||||
out << YAML::Key << "a" << YAML::Value << "foo" << YAML::Newline;
|
||||
out << YAML::Key << "b" << YAML::Newline << YAML::Value << "bar";
|
||||
out << YAML::EndMap;
|
||||
desiredOutput = "{a: foo\n, b\n: bar}";
|
||||
}
|
||||
|
||||
void LotsOfNewlines(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << YAML::BeginSeq;
|
||||
out << "a" << YAML::Newline;
|
||||
out << YAML::BeginSeq;
|
||||
out << "b" << "c" << YAML::Newline;
|
||||
out << YAML::EndSeq;
|
||||
out << YAML::Newline;
|
||||
out << YAML::BeginMap;
|
||||
out << YAML::Newline << YAML::Key << "d" << YAML::Value << YAML::Newline << "e";
|
||||
out << YAML::LongKey << YAML::Key << "f" << YAML::Newline << YAML::Value << "foo";
|
||||
out << YAML::EndMap;
|
||||
out << YAML::EndSeq;
|
||||
desiredOutput = "- a\n\n-\n - b\n - c\n\n\n-\n d: e\n ? f\n\n : foo";
|
||||
}
|
||||
|
||||
void Binary(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << YAML::Binary(reinterpret_cast<const unsigned char*>("Hello, World!"), 13);
|
||||
desiredOutput = "!!binary \"SGVsbG8sIFdvcmxkIQ==\"";
|
||||
}
|
||||
|
||||
void LongBinary(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << YAML::Binary(reinterpret_cast<const unsigned char*>("Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.\n"), 270);
|
||||
desiredOutput = "!!binary \"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4K\"";
|
||||
}
|
||||
|
||||
void EmptyBinary(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << YAML::Binary(reinterpret_cast<const unsigned char *>(""), 0);
|
||||
desiredOutput = "!!binary \"\"";
|
||||
}
|
||||
|
||||
void ColonAtEndOfScalar(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << "a:";
|
||||
desiredOutput = "\"a:\"";
|
||||
}
|
||||
|
||||
void ColonAsScalar(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << YAML::BeginMap;
|
||||
out << YAML::Key << "apple" << YAML::Value << ":";
|
||||
out << YAML::Key << "banana" << YAML::Value << ":";
|
||||
out << YAML::EndMap;
|
||||
desiredOutput = "apple: \":\"\nbanana: \":\"";
|
||||
}
|
||||
|
||||
void 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: \"\"";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -720,15 +948,27 @@ namespace Test
|
||||
std::string desiredOutput;
|
||||
test(out, desiredOutput);
|
||||
std::string output = out.c_str();
|
||||
std::string lastError = out.GetLastError();
|
||||
|
||||
if(output == desiredOutput) {
|
||||
passed++;
|
||||
try {
|
||||
std::stringstream stream(output);
|
||||
YAML::Parser parser;
|
||||
YAML::Node node;
|
||||
parser.GetNextDocument(node);
|
||||
passed++;
|
||||
} catch(const YAML::Exception& e) {
|
||||
std::cout << "Emitter test failed: " << name << "\n";
|
||||
std::cout << "Parsing output error: " << e.what() << "\n";
|
||||
}
|
||||
} else {
|
||||
std::cout << "Emitter test failed: " << name << "\n";
|
||||
std::cout << "Output:\n";
|
||||
std::cout << output << "<<<\n";
|
||||
std::cout << "Desired output:\n";
|
||||
std::cout << desiredOutput << "<<<\n";
|
||||
if(!out.good())
|
||||
std::cout << "Emitter error: " << lastError << "\n";
|
||||
}
|
||||
total++;
|
||||
}
|
||||
@@ -779,6 +1019,7 @@ namespace Test
|
||||
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);
|
||||
@@ -789,11 +1030,17 @@ namespace Test
|
||||
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);
|
||||
@@ -805,6 +1052,21 @@ namespace Test
|
||||
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::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);
|
||||
|
||||
RunEmitterErrorTest(&Emitter::ExtraEndSeq, "extra EndSeq", passed, total);
|
||||
RunEmitterErrorTest(&Emitter::ExtraEndMap, "extra EndMap", passed, total);
|
||||
@@ -815,6 +1077,7 @@ namespace Test
|
||||
RunEmitterErrorTest(&Emitter::MissingValue, "missing value", passed, total);
|
||||
RunEmitterErrorTest(&Emitter::UnexpectedKey, "unexpected key", passed, total);
|
||||
RunEmitterErrorTest(&Emitter::UnexpectedValue, "unexpected value", passed, total);
|
||||
RunEmitterErrorTest(&Emitter::BadLocalTag, "bad local tag", passed, total);
|
||||
|
||||
std::cout << "Emitter tests: " << passed << "/" << total << " passed\n";
|
||||
return passed == total;
|
||||
|
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#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();
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#include "tests.h"
|
||||
#include "yaml.h"
|
||||
#include "yaml-cpp/yaml.h"
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -132,14 +132,11 @@ namespace Test
|
||||
parser.GetNextDocument(doc);
|
||||
|
||||
std::string output;
|
||||
doc[0] >> output;
|
||||
if(output != "eggs")
|
||||
if(doc[0].to<std::string>() != "eggs")
|
||||
return false;
|
||||
doc[1] >> output;
|
||||
if(output != "bread")
|
||||
if(doc[1].to<std::string>() != "bread")
|
||||
return false;
|
||||
doc[2] >> output;
|
||||
if(output != "milk")
|
||||
if(doc[2].to<std::string>() != "milk")
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -472,7 +469,7 @@ namespace Test
|
||||
|
||||
bool AliasAsSimpleKey()
|
||||
{
|
||||
std::string input = "- &a b\n- *a: c";
|
||||
std::string input = "- &a b\n- *a : c";
|
||||
|
||||
std::stringstream stream(input);
|
||||
YAML::Parser parser(stream);
|
||||
@@ -626,7 +623,7 @@ namespace Test
|
||||
return false;
|
||||
if(!IsNull(doc["key"]))
|
||||
return false;
|
||||
if(doc["just a key"] != "value")
|
||||
if(doc["just a key"].to<std::string>() != "value")
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -647,13 +644,13 @@ namespace Test
|
||||
parser.GetNextDocument(doc);
|
||||
if(doc.size() != 4)
|
||||
return false;
|
||||
if(doc[0] != 15)
|
||||
if(doc[0].to<int>() != 15)
|
||||
return false;
|
||||
if(doc[1] != 0x10)
|
||||
if(doc[1].to<int>() != 0x10)
|
||||
return false;
|
||||
if(doc[2] != 030)
|
||||
if(doc[2].to<int>() != 030)
|
||||
return false;
|
||||
if(doc[3] != 0xffffffff)
|
||||
if(doc[3].to<unsigned>() != 0xffffffff)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@@ -669,21 +666,21 @@ namespace Test
|
||||
try {
|
||||
doc["bad key"];
|
||||
} catch(const YAML::Exception& e) {
|
||||
if(e.msg != YAML::ErrorMsg::KEY_NOT_FOUND + ": bad key")
|
||||
if(e.msg != std::string(YAML::ErrorMsg::KEY_NOT_FOUND) + ": bad key")
|
||||
throw;
|
||||
}
|
||||
|
||||
try {
|
||||
doc[5];
|
||||
} catch(const YAML::Exception& e) {
|
||||
if(e.msg != YAML::ErrorMsg::KEY_NOT_FOUND + ": 5")
|
||||
if(e.msg != std::string(YAML::ErrorMsg::KEY_NOT_FOUND) + ": 5")
|
||||
throw;
|
||||
}
|
||||
|
||||
try {
|
||||
doc[2.5];
|
||||
} catch(const YAML::Exception& e) {
|
||||
if(e.msg != YAML::ErrorMsg::KEY_NOT_FOUND + ": 2.5")
|
||||
if(e.msg != std::string(YAML::ErrorMsg::KEY_NOT_FOUND) + ": 2.5")
|
||||
throw;
|
||||
}
|
||||
|
||||
@@ -698,11 +695,188 @@ namespace Test
|
||||
YAML::Node doc;
|
||||
parser.GetNextDocument(doc);
|
||||
|
||||
if(doc["a"] != 1)
|
||||
if(doc["a"].to<int>() != 4)
|
||||
return false;
|
||||
if(doc["b"] != 2)
|
||||
if(doc["b"].to<int>() != 2)
|
||||
return false;
|
||||
if(doc["c"] != 3)
|
||||
if(doc["c"].to<int>() != 3)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PrepareNodeForTagExam(YAML::Node& doc, const std::string& input)
|
||||
{
|
||||
std::stringstream stream(input);
|
||||
YAML::Parser parser(stream);
|
||||
parser.GetNextDocument(doc);
|
||||
}
|
||||
|
||||
struct TagMismatch: public std::exception {
|
||||
TagMismatch(const std::string& actualTag, const std::string& expectedTag) {
|
||||
std::stringstream output;
|
||||
output << "Tag has value \"" << actualTag << "\" but \"" << expectedTag << "\" was expected";
|
||||
what_ = output.str();
|
||||
}
|
||||
virtual ~TagMismatch() throw() {}
|
||||
virtual const char *what() const throw() { return what_.c_str(); }
|
||||
|
||||
private:
|
||||
std::string what_;
|
||||
};
|
||||
|
||||
bool ExpectedTagValue(YAML::Node& node, const char* tag)
|
||||
{
|
||||
if(node.Tag() == tag)
|
||||
return true;
|
||||
|
||||
throw TagMismatch(node.Tag(), tag);
|
||||
}
|
||||
|
||||
bool DefaultPlainScalarTag()
|
||||
{
|
||||
YAML::Node node;
|
||||
PrepareNodeForTagExam(node, "--- 12");
|
||||
|
||||
return ExpectedTagValue(node, "?");
|
||||
}
|
||||
|
||||
bool DefaultSingleQuotedScalarTag()
|
||||
{
|
||||
YAML::Node node;
|
||||
PrepareNodeForTagExam(node, "--- '12'");
|
||||
|
||||
return ExpectedTagValue(node, "!");
|
||||
}
|
||||
|
||||
bool ExplicitNonSpecificPlainScalarTag()
|
||||
{
|
||||
YAML::Node node;
|
||||
PrepareNodeForTagExam(node, "--- ! 12");
|
||||
|
||||
return ExpectedTagValue(node, "!");
|
||||
}
|
||||
|
||||
bool BasicLocalTag()
|
||||
{
|
||||
YAML::Node node;
|
||||
PrepareNodeForTagExam(node, "--- !foo 12");
|
||||
|
||||
return ExpectedTagValue(node, "!foo");
|
||||
}
|
||||
|
||||
bool VerbatimLocalTag()
|
||||
{
|
||||
YAML::Node node;
|
||||
PrepareNodeForTagExam(node, "--- !<!foo> 12");
|
||||
|
||||
return ExpectedTagValue(node, "!foo");
|
||||
}
|
||||
|
||||
bool StandardShortcutTag()
|
||||
{
|
||||
YAML::Node node;
|
||||
PrepareNodeForTagExam(node, "--- !!int 12");
|
||||
|
||||
return ExpectedTagValue(node, "tag:yaml.org,2002:int");
|
||||
}
|
||||
|
||||
bool VerbatimURITag()
|
||||
{
|
||||
YAML::Node node;
|
||||
PrepareNodeForTagExam(node, "--- !<tag:yaml.org,2002:int> 12");
|
||||
|
||||
return ExpectedTagValue(node, "tag:yaml.org,2002:int");
|
||||
}
|
||||
|
||||
bool DefaultSequenceTag()
|
||||
{
|
||||
YAML::Node node;
|
||||
PrepareNodeForTagExam(node, "--- [12]");
|
||||
|
||||
return ExpectedTagValue(node, "?");
|
||||
}
|
||||
|
||||
bool ExplicitNonSpecificSequenceTag()
|
||||
{
|
||||
YAML::Node node;
|
||||
PrepareNodeForTagExam(node, "--- ! [12]");
|
||||
|
||||
return ExpectedTagValue(node, "!");
|
||||
}
|
||||
|
||||
bool Infinity()
|
||||
{
|
||||
std::string input =
|
||||
"- .inf\n"
|
||||
"- .Inf\n"
|
||||
"- .INF\n"
|
||||
"- +.inf\n"
|
||||
"- +.Inf\n"
|
||||
"- +.INF\n"
|
||||
"- -.inf\n"
|
||||
"- -.Inf\n"
|
||||
"- -.INF\n";
|
||||
std::stringstream stream(input);
|
||||
YAML::Parser parser(stream);
|
||||
YAML::Node doc;
|
||||
parser.GetNextDocument(doc);
|
||||
|
||||
for(unsigned i=0;i<doc.size();i++)
|
||||
if(doc[i].to<double>() != (i < 6 ? +1 : -1) * std::numeric_limits<double>::infinity())
|
||||
return false;
|
||||
for(unsigned i=0;i<doc.size();i++)
|
||||
if(doc[i].to<long double>() != (i < 6 ? +1 : -1) * std::numeric_limits<long double>::infinity())
|
||||
return false;
|
||||
for(unsigned i=0;i<doc.size();i++)
|
||||
if(doc[i].to<float>() != (i < 6 ? +1 : -1) * std::numeric_limits<float>::infinity())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NaN()
|
||||
{
|
||||
std::string input =
|
||||
"- .nan\n"
|
||||
"- .NaN\n"
|
||||
"- .NAN\n";
|
||||
std::stringstream stream(input);
|
||||
YAML::Parser parser(stream);
|
||||
YAML::Node doc;
|
||||
parser.GetNextDocument(doc);
|
||||
|
||||
for(unsigned i=0;i<doc.size();i++) {
|
||||
double d;
|
||||
doc[i] >> d;
|
||||
if(d == d)
|
||||
return false;
|
||||
}
|
||||
for(unsigned i=0;i<doc.size();i++) {
|
||||
long double d;
|
||||
doc[i] >> d;
|
||||
if(d == d)
|
||||
return false;
|
||||
}
|
||||
for(unsigned i=0;i<doc.size();i++) {
|
||||
float d;
|
||||
doc[i] >> d;
|
||||
if(d == d)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NonConstKey()
|
||||
{
|
||||
std::string input = "{a: 1}";
|
||||
std::stringstream stream(input);
|
||||
YAML::Parser parser(stream);
|
||||
YAML::Node doc;
|
||||
parser.GetNextDocument(doc);
|
||||
|
||||
std::vector<char> key(2);
|
||||
key[0] = 'a';
|
||||
key[1] = '\0';
|
||||
if(doc[&key[0]].to<int>() != 1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@@ -746,7 +920,10 @@ namespace Test
|
||||
ok = test();
|
||||
} catch(const YAML::Exception& e) {
|
||||
ok = false;
|
||||
error = e.msg;
|
||||
error = e.what();
|
||||
} catch(const Parser::TagMismatch& e) {
|
||||
ok = false;
|
||||
error = e.what();
|
||||
}
|
||||
if(ok) {
|
||||
passed++;
|
||||
@@ -969,6 +1146,19 @@ namespace Test
|
||||
RunParserTest(&Parser::Bases, "bases", passed, total);
|
||||
RunParserTest(&Parser::KeyNotFound, "key not found", passed, total);
|
||||
RunParserTest(&Parser::DuplicateKey, "duplicate key", passed, total);
|
||||
RunParserTest(&Parser::DefaultPlainScalarTag, "default plain scalar tag", passed, total);
|
||||
RunParserTest(&Parser::DefaultSingleQuotedScalarTag, "default single-quoted scalar tag", passed, total);
|
||||
RunParserTest(&Parser::ExplicitNonSpecificPlainScalarTag, "explicit, non-specific plain scalar tag", passed, total);
|
||||
RunParserTest(&Parser::BasicLocalTag, "basic local tag", passed, total);
|
||||
RunParserTest(&Parser::VerbatimLocalTag, "verbatim local tag", passed, total);
|
||||
RunParserTest(&Parser::StandardShortcutTag, "standard shortcut tag", passed, total);
|
||||
RunParserTest(&Parser::VerbatimURITag, "verbatim URI tag", passed, total);
|
||||
RunParserTest(&Parser::DefaultPlainScalarTag, "default plain scalar tag", passed, total);
|
||||
RunParserTest(&Parser::DefaultSequenceTag, "default sequence tag", passed, total);
|
||||
RunParserTest(&Parser::ExplicitNonSpecificSequenceTag, "explicit, non-specific sequence tag", passed, total);
|
||||
RunParserTest(&Parser::Infinity, "infinity", passed, total);
|
||||
RunParserTest(&Parser::NaN, "NaN", passed, total);
|
||||
RunParserTest(&Parser::NonConstKey, "non const key", passed, total);
|
||||
|
||||
RunEncodingTest(&EncodeToUtf8, false, "UTF-8, no BOM", passed, total);
|
||||
RunEncodingTest(&EncodeToUtf8, true, "UTF-8 with BOM", passed, total);
|
||||
|
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#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();
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user