mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2025-09-09 20:51:16 +00:00
Compare commits
108 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 | ||
![]() |
326899815f | ||
![]() |
083a97b171 | ||
![]() |
2226987442 | ||
![]() |
bca7737463 | ||
![]() |
6f40b09525 | ||
![]() |
3a755de572 | ||
![]() |
9718e58120 | ||
![]() |
8723b8f358 | ||
![]() |
03df73a7b0 | ||
![]() |
3307f0941c | ||
![]() |
54b68230ae | ||
![]() |
32491166ac | ||
![]() |
6f94f954bb | ||
![]() |
90fd24d149 | ||
![]() |
9a21a3ec8d | ||
![]() |
3779e4255d | ||
![]() |
ec62dc547e | ||
![]() |
a9b9e1ccec | ||
![]() |
e04be7890a | ||
![]() |
ecb30132e9 | ||
![]() |
52be1ccfb9 | ||
![]() |
3405a6fe01 | ||
![]() |
d372729b92 | ||
![]() |
fadc2ad39f | ||
![]() |
a5607f82a3 | ||
![]() |
f4c683ac22 | ||
![]() |
8c9c9d90da | ||
![]() |
a372bfdc60 | ||
![]() |
fe57829aca | ||
![]() |
b5c53d9e3a | ||
![]() |
f2a2d25ec0 | ||
![]() |
a706ffaf62 | ||
![]() |
8f48e693fe | ||
![]() |
a0bf12e7a1 | ||
![]() |
2314c04d5d | ||
![]() |
22410f46f5 | ||
![]() |
9559a661aa |
4
.hgeol
Normal file
4
.hgeol
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
**.h = native
|
||||||
|
**.c = native
|
||||||
|
**.cpp = native
|
||||||
|
**.txt = native
|
273
CMakeLists.txt
273
CMakeLists.txt
@@ -1,62 +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)
|
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)
|
### Project settings
|
||||||
set(LIB_TYPE)
|
###
|
||||||
endif(IPHONE)
|
project(YAML_CPP)
|
||||||
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCC)
|
|
||||||
set(CMAKE_CXX_FLAGS "-O2 -Wall -pedantic -Wextra ${CMAKE_CXX_FLAGS}")
|
|
||||||
endif(CMAKE_COMPILER_IS_GNUCC)
|
|
||||||
|
|
||||||
set(YAML_CPP_VERSION_MAJOR "0")
|
set(YAML_CPP_VERSION_MAJOR "0")
|
||||||
set(YAML_CPP_VERSION_MINOR "2")
|
set(YAML_CPP_VERSION_MINOR "2")
|
||||||
set(YAML_CPP_VERSION_PATCH "2")
|
set(YAML_CPP_VERSION_PATCH "7")
|
||||||
set(YAML_CPP_VERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}.${YAML_CPP_VERSION_PATCH}")
|
set(YAML_CPP_VERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}.${YAML_CPP_VERSION_PATCH}")
|
||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
|
||||||
option(YAML_CPP_BUILD_TOOLS "Enables or disables yaml-reader 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)
|
if(WIN32)
|
||||||
set(_library_dir bin) # .dll are in PATH, like executables
|
if(BUILD_SHARED_LIBS)
|
||||||
else(WIN32)
|
add_definitions(-D${PROJECT_NAME}_DLL) # use or build Windows DLL
|
||||||
set(_library_dir lib)
|
endif()
|
||||||
endif(WIN32)
|
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||||
|
set(CMAKE_INSTALL_PREFIX "C:/")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
set(INCLUDE_INSTALL_DIR include/yaml-cpp)
|
# GCC specialities
|
||||||
set(LIB_INSTALL_DIR ${_library_dir}${LIB_SUFFIX})
|
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
|
set(_INSTALL_DESTINATIONS
|
||||||
RUNTIME DESTINATION bin
|
RUNTIME DESTINATION bin
|
||||||
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
|
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
|
||||||
ARCHIVE DESTINATION lib${LIB_SUFFIX}
|
ARCHIVE DESTINATION "lib${LIB_SUFFIX}"
|
||||||
)
|
)
|
||||||
#
|
|
||||||
file(GLOB public_headers include/*.h)
|
|
||||||
file(GLOB private_headers src/*.h)
|
|
||||||
file(GLOB sources src/*.cpp)
|
|
||||||
|
|
||||||
include_directories(${YAML_CPP_SOURCE_DIR}/include)
|
|
||||||
|
###
|
||||||
|
### Library
|
||||||
|
###
|
||||||
add_library(yaml-cpp
|
add_library(yaml-cpp
|
||||||
${LIB_TYPE}
|
${sources}
|
||||||
${public_headers}
|
${public_headers}
|
||||||
${private_headers}
|
${private_headers}
|
||||||
${sources}
|
${contrib_sources}
|
||||||
|
${contrib_public_headers}
|
||||||
|
${contrib_private_headers}
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(yaml-cpp PROPERTIES
|
set_target_properties(yaml-cpp PROPERTIES
|
||||||
VERSION "${YAML_CPP_VERSION}"
|
VERSION "${YAML_CPP_VERSION}"
|
||||||
SOVERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}"
|
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(TARGETS yaml-cpp ${_INSTALL_DESTINATIONS})
|
||||||
install(
|
install(
|
||||||
FILES ${public_headers}
|
FILES
|
||||||
|
${public_headers}
|
||||||
|
${contrib_public_headers}
|
||||||
DESTINATION ${INCLUDE_INSTALL_DIR}
|
DESTINATION ${INCLUDE_INSTALL_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -64,9 +269,13 @@ if(UNIX)
|
|||||||
set(PC_FILE ${CMAKE_BINARY_DIR}/yaml-cpp.pc)
|
set(PC_FILE ${CMAKE_BINARY_DIR}/yaml-cpp.pc)
|
||||||
configure_file("yaml-cpp.pc.cmake" ${PC_FILE} @ONLY)
|
configure_file("yaml-cpp.pc.cmake" ${PC_FILE} @ONLY)
|
||||||
install(FILES ${PC_FILE} DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
|
install(FILES ${PC_FILE} DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
|
||||||
endif(UNIX)
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
###
|
||||||
|
### Extras
|
||||||
|
###
|
||||||
if(YAML_CPP_BUILD_TOOLS)
|
if(YAML_CPP_BUILD_TOOLS)
|
||||||
add_subdirectory (yaml-reader)
|
add_subdirectory(test)
|
||||||
add_subdirectory (util)
|
add_subdirectory(util)
|
||||||
endif(YAML_CPP_BUILD_TOOLS)
|
endif()
|
||||||
|
@@ -1,43 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef CONVERSION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
||||||
#define CONVERSION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
||||||
|
|
||||||
|
|
||||||
#include "null.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);
|
|
||||||
|
|
||||||
#define YAML_MAKE_STREAM_CONVERT(type) \
|
|
||||||
inline bool Convert(const std::string& input, type& output) { \
|
|
||||||
std::stringstream stream(input); \
|
|
||||||
stream >> output; \
|
|
||||||
return !stream.fail(); \
|
|
||||||
}
|
|
||||||
|
|
||||||
YAML_MAKE_STREAM_CONVERT(char)
|
|
||||||
YAML_MAKE_STREAM_CONVERT(unsigned char)
|
|
||||||
YAML_MAKE_STREAM_CONVERT(int)
|
|
||||||
YAML_MAKE_STREAM_CONVERT(unsigned int)
|
|
||||||
YAML_MAKE_STREAM_CONVERT(short)
|
|
||||||
YAML_MAKE_STREAM_CONVERT(unsigned short)
|
|
||||||
YAML_MAKE_STREAM_CONVERT(long)
|
|
||||||
YAML_MAKE_STREAM_CONVERT(unsigned long)
|
|
||||||
YAML_MAKE_STREAM_CONVERT(float)
|
|
||||||
YAML_MAKE_STREAM_CONVERT(double)
|
|
||||||
YAML_MAKE_STREAM_CONVERT(long double)
|
|
||||||
|
|
||||||
#undef YAML_MAKE_STREAM_CONVERT
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // CONVERSION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
@@ -1,17 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef CRT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
||||||
#define CRT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
||||||
|
|
||||||
|
|
||||||
// for detecting memory leaks
|
|
||||||
#ifdef _DEBUG
|
|
||||||
|
|
||||||
#define _CRTDBG_MAP_ALLOC
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <crtdbg.h>
|
|
||||||
|
|
||||||
#endif // _DEBUG
|
|
||||||
|
|
||||||
|
|
||||||
#endif // CRT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
@@ -1,95 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
||||||
#define EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
||||||
|
|
||||||
|
|
||||||
#include "emittermanip.h"
|
|
||||||
#include "ostream.h"
|
|
||||||
#include "null.h"
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace YAML
|
|
||||||
{
|
|
||||||
class EmitterState;
|
|
||||||
|
|
||||||
class Emitter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Emitter();
|
|
||||||
~Emitter();
|
|
||||||
|
|
||||||
// output
|
|
||||||
const char *c_str() const;
|
|
||||||
unsigned size() const;
|
|
||||||
|
|
||||||
// state checking
|
|
||||||
bool good() const;
|
|
||||||
const std::string GetLastError() const;
|
|
||||||
|
|
||||||
// global setters
|
|
||||||
bool SetOutputCharset(EMITTER_MANIP value);
|
|
||||||
bool SetStringFormat(EMITTER_MANIP value);
|
|
||||||
bool SetBoolFormat(EMITTER_MANIP value);
|
|
||||||
bool SetIntBase(EMITTER_MANIP value);
|
|
||||||
bool SetSeqFormat(EMITTER_MANIP value);
|
|
||||||
bool SetMapFormat(EMITTER_MANIP value);
|
|
||||||
bool SetIndent(unsigned n);
|
|
||||||
bool SetPreCommentIndent(unsigned n);
|
|
||||||
bool SetPostCommentIndent(unsigned n);
|
|
||||||
|
|
||||||
// local setters
|
|
||||||
Emitter& SetLocalValue(EMITTER_MANIP value);
|
|
||||||
Emitter& SetLocalIndent(const _Indent& indent);
|
|
||||||
|
|
||||||
// overloads of write
|
|
||||||
Emitter& Write(const std::string& str);
|
|
||||||
Emitter& Write(const char *str);
|
|
||||||
Emitter& Write(int i);
|
|
||||||
Emitter& Write(bool b);
|
|
||||||
Emitter& Write(float f);
|
|
||||||
Emitter& Write(double d);
|
|
||||||
Emitter& Write(const _Alias& alias);
|
|
||||||
Emitter& Write(const _Anchor& anchor);
|
|
||||||
Emitter& Write(const _Comment& comment);
|
|
||||||
Emitter& Write(const _Null& null);
|
|
||||||
|
|
||||||
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 EmitBeginSeq();
|
|
||||||
void EmitEndSeq();
|
|
||||||
void EmitBeginMap();
|
|
||||||
void EmitEndMap();
|
|
||||||
void EmitKey();
|
|
||||||
void EmitValue();
|
|
||||||
|
|
||||||
private:
|
|
||||||
ostream m_stream;
|
|
||||||
std::auto_ptr <EmitterState> m_pState;
|
|
||||||
};
|
|
||||||
|
|
||||||
// overloads of insertion
|
|
||||||
template <typename T>
|
|
||||||
inline Emitter& operator << (Emitter& emitter, T v) {
|
|
||||||
return emitter.Write(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline Emitter& operator << (Emitter& emitter, EMITTER_MANIP value) {
|
|
||||||
return emitter.SetLocalValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline Emitter& operator << (Emitter& emitter, _Indent indent) {
|
|
||||||
return emitter.SetLocalIndent(indent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
@@ -1,137 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
||||||
#define EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
||||||
|
|
||||||
|
|
||||||
#include "mark.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 TAG_DIRECTIVE_ARGS = "TAG directives must have exactly two arguments";
|
|
||||||
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 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";
|
|
||||||
}
|
|
||||||
|
|
||||||
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:
|
|
||||||
KeyNotFound(const Mark& mark_)
|
|
||||||
: RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class TypedKeyNotFound: public KeyNotFound {
|
|
||||||
public:
|
|
||||||
TypedKeyNotFound(const Mark& mark_, const T& key_)
|
|
||||||
: KeyNotFound(mark_), key(key_) {}
|
|
||||||
~TypedKeyNotFound() throw() {}
|
|
||||||
|
|
||||||
T key;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
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
|
|
138
include/node.h
138
include/node.h
@@ -1,138 +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 "parserstate.h"
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace YAML
|
|
||||||
{
|
|
||||||
class Content;
|
|
||||||
class Scanner;
|
|
||||||
class Emitter;
|
|
||||||
|
|
||||||
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, const 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; }
|
|
||||||
|
|
||||||
// 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, const ParserState& state);
|
|
||||||
void ParseTag(Scanner *pScanner, const ParserState& state);
|
|
||||||
void ParseAnchor(Scanner *pScanner, const ParserState& state);
|
|
||||||
void ParseAlias(Scanner *pScanner, const 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,46 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
||||||
#define PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
||||||
|
|
||||||
|
|
||||||
#include "node.h"
|
|
||||||
#include "parserstate.h"
|
|
||||||
#include "noncopyable.h"
|
|
||||||
#include <ios>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace YAML
|
|
||||||
{
|
|
||||||
class Scanner;
|
|
||||||
struct Token;
|
|
||||||
|
|
||||||
class Parser: private noncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Parser();
|
|
||||||
Parser(std::istream& in);
|
|
||||||
~Parser();
|
|
||||||
|
|
||||||
operator bool() const;
|
|
||||||
|
|
||||||
void Load(std::istream& in);
|
|
||||||
bool GetNextDocument(Node& document);
|
|
||||||
void PrintTokens(std::ostream& out);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void ParseDirectives();
|
|
||||||
void HandleDirective(Token *pToken);
|
|
||||||
void HandleYamlDirective(Token *pToken);
|
|
||||||
void HandleTagDirective(Token *pToken);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::auto_ptr<Scanner> m_pScanner;
|
|
||||||
ParserState m_state;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
@@ -1,26 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef PARSERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
||||||
#define PARSERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
||||||
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
namespace YAML
|
|
||||||
{
|
|
||||||
struct Version {
|
|
||||||
int major, minor;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ParserState
|
|
||||||
{
|
|
||||||
Version version;
|
|
||||||
std::map <std::string, std::string> tags;
|
|
||||||
|
|
||||||
void Reset();
|
|
||||||
std::string TranslateTag(const std::string& handle) const;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // PARSERSTATE_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
|
158
include/yaml-cpp/emitter.h
Normal file
158
include/yaml-cpp/emitter.h
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
#ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
|
#define EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "yaml-cpp/dll.h"
|
||||||
|
#include "yaml-cpp/emittermanip.h"
|
||||||
|
#include "yaml-cpp/ostream.h"
|
||||||
|
#include "yaml-cpp/noncopyable.h"
|
||||||
|
#include "yaml-cpp/null.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace YAML
|
||||||
|
{
|
||||||
|
class EmitterState;
|
||||||
|
|
||||||
|
class YAML_CPP_API Emitter: private noncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Emitter();
|
||||||
|
~Emitter();
|
||||||
|
|
||||||
|
// output
|
||||||
|
const char *c_str() const;
|
||||||
|
unsigned size() const;
|
||||||
|
|
||||||
|
// state checking
|
||||||
|
bool good() const;
|
||||||
|
const std::string GetLastError() const;
|
||||||
|
|
||||||
|
// global setters
|
||||||
|
bool SetOutputCharset(EMITTER_MANIP value);
|
||||||
|
bool SetStringFormat(EMITTER_MANIP value);
|
||||||
|
bool SetBoolFormat(EMITTER_MANIP value);
|
||||||
|
bool SetIntBase(EMITTER_MANIP value);
|
||||||
|
bool SetSeqFormat(EMITTER_MANIP value);
|
||||||
|
bool SetMapFormat(EMITTER_MANIP value);
|
||||||
|
bool SetIndent(unsigned n);
|
||||||
|
bool SetPreCommentIndent(unsigned n);
|
||||||
|
bool SetPostCommentIndent(unsigned n);
|
||||||
|
|
||||||
|
// local setters
|
||||||
|
Emitter& SetLocalValue(EMITTER_MANIP value);
|
||||||
|
Emitter& SetLocalIndent(const _Indent& indent);
|
||||||
|
|
||||||
|
// overloads of write
|
||||||
|
Emitter& Write(const std::string& str);
|
||||||
|
Emitter& Write(bool b);
|
||||||
|
Emitter& Write(const _Alias& alias);
|
||||||
|
Emitter& Write(const _Anchor& anchor);
|
||||||
|
Emitter& Write(const _Tag& tag);
|
||||||
|
Emitter& Write(const _Comment& comment);
|
||||||
|
Emitter& Write(const _Null& null);
|
||||||
|
Emitter& Write(const _Binary& binary);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Emitter& WriteIntegralType(T value);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Emitter& WriteStreamable(T value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void PreWriteIntegralType(std::stringstream& str);
|
||||||
|
void PreWriteStreamable(std::stringstream& str);
|
||||||
|
void PostWriteIntegralType(const std::stringstream& str);
|
||||||
|
void PostWriteStreamable(const std::stringstream& str);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void PreAtomicWrite();
|
||||||
|
bool GotoNextPreAtomicState();
|
||||||
|
void PostAtomicWrite();
|
||||||
|
void EmitSeparationIfNecessary();
|
||||||
|
|
||||||
|
void EmitBeginDoc();
|
||||||
|
void EmitEndDoc();
|
||||||
|
void EmitBeginSeq();
|
||||||
|
void EmitEndSeq();
|
||||||
|
void EmitBeginMap();
|
||||||
|
void EmitEndMap();
|
||||||
|
void EmitKey();
|
||||||
|
void EmitValue();
|
||||||
|
void EmitNewline();
|
||||||
|
void EmitKindTag();
|
||||||
|
void EmitTag(bool verbatim, const _Tag& tag);
|
||||||
|
|
||||||
|
const char *ComputeFullBoolName(bool b) const;
|
||||||
|
bool CanEmitNewline() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ostream m_stream;
|
||||||
|
std::auto_ptr <EmitterState> m_pState;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline Emitter& Emitter::WriteIntegralType(T value)
|
||||||
|
{
|
||||||
|
if(!good())
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
PreWriteIntegralType(str);
|
||||||
|
str << value;
|
||||||
|
PostWriteIntegralType(str);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline Emitter& Emitter::WriteStreamable(T value)
|
||||||
|
{
|
||||||
|
if(!good())
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
PreWriteStreamable(str);
|
||||||
|
str << value;
|
||||||
|
PostWriteStreamable(str);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// overloads of insertion
|
||||||
|
inline Emitter& operator << (Emitter& emitter, const std::string& v) { return emitter.Write(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, bool v) { return emitter.Write(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, const _Alias& v) { return emitter.Write(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, const _Anchor& v) { return emitter.Write(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, const _Tag& v) { return emitter.Write(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, const _Comment& v) { return emitter.Write(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, const _Null& v) { return emitter.Write(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, const _Binary& b) { return emitter.Write(b); }
|
||||||
|
|
||||||
|
inline Emitter& operator << (Emitter& emitter, const char *v) { return emitter.Write(std::string(v)); }
|
||||||
|
|
||||||
|
inline Emitter& operator << (Emitter& emitter, int v) { return emitter.WriteIntegralType(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, unsigned int v) { return emitter.WriteIntegralType(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, short v) { return emitter.WriteIntegralType(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, unsigned short v) { return emitter.WriteIntegralType(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, long v) { return emitter.WriteIntegralType(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, unsigned long v) { return emitter.WriteIntegralType(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, long long v) { return emitter.WriteIntegralType(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, unsigned long long v) { return emitter.WriteIntegralType(v); }
|
||||||
|
|
||||||
|
inline Emitter& operator << (Emitter& emitter, float v) { return emitter.WriteStreamable(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, double v) { return emitter.WriteStreamable(v); }
|
||||||
|
|
||||||
|
inline Emitter& operator << (Emitter& emitter, EMITTER_MANIP value) {
|
||||||
|
return emitter.SetLocalValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Emitter& operator << (Emitter& emitter, _Indent indent) {
|
||||||
|
return emitter.SetLocalIndent(indent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,8 +1,10 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
#ifndef EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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>
|
#include <string>
|
||||||
|
|
||||||
@@ -11,6 +13,8 @@ namespace YAML
|
|||||||
enum EMITTER_MANIP {
|
enum EMITTER_MANIP {
|
||||||
// general manipulators
|
// general manipulators
|
||||||
Auto,
|
Auto,
|
||||||
|
TagByKind,
|
||||||
|
Newline,
|
||||||
|
|
||||||
// output character set
|
// output character set
|
||||||
EmitNonAscii,
|
EmitNonAscii,
|
||||||
@@ -37,6 +41,10 @@ namespace YAML
|
|||||||
Hex,
|
Hex,
|
||||||
Oct,
|
Oct,
|
||||||
|
|
||||||
|
// document manipulators
|
||||||
|
BeginDoc,
|
||||||
|
EndDoc,
|
||||||
|
|
||||||
// sequence manipulators
|
// sequence manipulators
|
||||||
BeginSeq,
|
BeginSeq,
|
||||||
EndSeq,
|
EndSeq,
|
||||||
@@ -81,6 +89,34 @@ namespace YAML
|
|||||||
return _Anchor(content);
|
return _Anchor(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct _Tag {
|
||||||
|
struct Type { enum value { Verbatim, PrimaryHandle, NamedHandle }; };
|
||||||
|
|
||||||
|
explicit _Tag(const std::string& prefix_, const std::string& content_, Type::value type_)
|
||||||
|
: prefix(prefix_), content(content_), type(type_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
std::string prefix;
|
||||||
|
std::string content;
|
||||||
|
Type::value type;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline _Tag VerbatimTag(const std::string content) {
|
||||||
|
return _Tag("", content, _Tag::Type::Verbatim);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline _Tag LocalTag(const std::string content) {
|
||||||
|
return _Tag("", content, _Tag::Type::PrimaryHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline _Tag LocalTag(const std::string& prefix, const std::string content) {
|
||||||
|
return _Tag(prefix, content, _Tag::Type::NamedHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline _Tag SecondaryTag(const std::string content) {
|
||||||
|
return _Tag("", content, _Tag::Type::NamedHandle);
|
||||||
|
}
|
||||||
|
|
||||||
struct _Comment {
|
struct _Comment {
|
||||||
_Comment(const std::string& content_): content(content_) {}
|
_Comment(const std::string& content_): content(content_) {}
|
||||||
std::string content;
|
std::string content;
|
||||||
@@ -89,6 +125,16 @@ namespace YAML
|
|||||||
inline _Comment Comment(const std::string content) {
|
inline _Comment Comment(const std::string content) {
|
||||||
return _Comment(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
|
#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
|
#ifndef ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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
|
namespace YAML
|
||||||
{
|
{
|
||||||
class Node;
|
class Node;
|
||||||
struct IterPriv;
|
struct IterPriv;
|
||||||
|
|
||||||
class Iterator
|
class YAML_CPP_API Iterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Iterator();
|
Iterator();
|
||||||
Iterator(IterPriv *pData);
|
Iterator(std::auto_ptr<IterPriv> pData);
|
||||||
Iterator(const Iterator& rhs);
|
Iterator(const Iterator& rhs);
|
||||||
~Iterator();
|
~Iterator();
|
||||||
|
|
||||||
@@ -25,11 +29,11 @@ namespace YAML
|
|||||||
const Node& first() const;
|
const Node& first() const;
|
||||||
const Node& second() const;
|
const Node& second() const;
|
||||||
|
|
||||||
friend bool operator == (const Iterator& it, const Iterator& jt);
|
friend YAML_CPP_API 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);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IterPriv *m_pData;
|
std::auto_ptr<IterPriv> m_pData;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@@ -1,8 +1,10 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef LTNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
#ifndef LTNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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
|
namespace YAML
|
||||||
{
|
{
|
@@ -1,12 +1,16 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
#ifndef MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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
|
namespace YAML
|
||||||
{
|
{
|
||||||
struct Mark {
|
struct YAML_CPP_API Mark {
|
||||||
Mark(): pos(0), line(0), column(0) {}
|
Mark(): pos(0), line(0), column(0) {}
|
||||||
|
|
||||||
static const Mark null() { return Mark(-1, -1, -1); }
|
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
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
@@ -52,9 +58,10 @@ namespace YAML
|
|||||||
int operator,(flag, flag);
|
int operator,(flag, flag);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void operator,(flag, T const&);
|
char operator,(flag, T const&);
|
||||||
|
|
||||||
char operator,(int, flag);
|
char operator,(int, flag);
|
||||||
|
int operator,(char, flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@@ -75,3 +82,5 @@ namespace YAML
|
|||||||
return Convert(scalar, value);
|
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
|
#ifndef NODEUTIL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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
|
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
|
#ifndef NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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
|
namespace YAML
|
||||||
{
|
{
|
||||||
class Node;
|
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 true; }
|
||||||
inline bool operator != (const _Null&, const _Null&) { return false; }
|
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
|
#endif // NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,8 +1,10 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef OSTREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
#ifndef OSTREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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>
|
#include <string>
|
||||||
|
|
50
include/yaml-cpp/parser.h
Normal file
50
include/yaml-cpp/parser.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#ifndef PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
|
#define PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "yaml-cpp/dll.h"
|
||||||
|
#include "yaml-cpp/noncopyable.h"
|
||||||
|
#include <ios>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace YAML
|
||||||
|
{
|
||||||
|
struct Directives;
|
||||||
|
struct Mark;
|
||||||
|
struct Token;
|
||||||
|
class EventHandler;
|
||||||
|
class Node;
|
||||||
|
class Scanner;
|
||||||
|
|
||||||
|
class YAML_CPP_API Parser: private noncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Parser();
|
||||||
|
Parser(std::istream& in);
|
||||||
|
~Parser();
|
||||||
|
|
||||||
|
operator bool() const;
|
||||||
|
|
||||||
|
void Load(std::istream& in);
|
||||||
|
bool HandleNextDocument(EventHandler& eventHandler);
|
||||||
|
|
||||||
|
bool GetNextDocument(Node& document);
|
||||||
|
void PrintTokens(std::ostream& out);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ParseDirectives();
|
||||||
|
void HandleDirective(const Token& token);
|
||||||
|
void HandleYamlDirective(const Token& token);
|
||||||
|
void HandleTagDirective(const Token& token);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::auto_ptr<Scanner> m_pScanner;
|
||||||
|
std::auto_ptr<Directives> m_pDirectives;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
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
|
38
include/yaml-cpp/stlnode.h
Normal file
38
include/yaml-cpp/stlnode.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef STLNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
|
#define STLNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace YAML
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
void operator >> (const Node& node, std::vector<T>& v)
|
||||||
|
{
|
||||||
|
v.clear();
|
||||||
|
v.resize(node.size());
|
||||||
|
for(unsigned i=0;i<node.size();++i)
|
||||||
|
node[i] >> v[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename K, typename V>
|
||||||
|
void operator >> (const Node& node, std::map<K, V>& m)
|
||||||
|
{
|
||||||
|
m.clear();
|
||||||
|
for(Iterator it=node.begin();it!=node.end();++it) {
|
||||||
|
K k;
|
||||||
|
V v;
|
||||||
|
it.first() >> k;
|
||||||
|
it.second() >> v;
|
||||||
|
m[k] = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // STLNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
57
include/yaml-cpp/traits.h
Normal file
57
include/yaml-cpp/traits.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#ifndef TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
|
#define TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
namespace YAML
|
||||||
|
{
|
||||||
|
template <typename>
|
||||||
|
struct is_numeric { enum { value = false }; };
|
||||||
|
|
||||||
|
template <> struct is_numeric <char> { enum { value = true }; };
|
||||||
|
template <> struct is_numeric <unsigned char> { enum { value = true }; };
|
||||||
|
template <> struct is_numeric <int> { enum { value = true }; };
|
||||||
|
template <> struct is_numeric <unsigned int> { enum { value = true }; };
|
||||||
|
template <> struct is_numeric <long int> { enum { value = true }; };
|
||||||
|
template <> struct is_numeric <unsigned long int> { enum { value = true }; };
|
||||||
|
template <> struct is_numeric <short int> { enum { value = true }; };
|
||||||
|
template <> struct is_numeric <unsigned short int> { enum { value = true }; };
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER < 1310)
|
||||||
|
template <> struct is_numeric <__int64> { enum { value = true }; };
|
||||||
|
template <> struct is_numeric <unsigned __int64> { enum { value = true }; };
|
||||||
|
#else
|
||||||
|
template <> struct is_numeric <long long> { enum { value = true }; };
|
||||||
|
template <> struct is_numeric <unsigned long long> { enum { value = true }; };
|
||||||
|
#endif
|
||||||
|
template <> struct is_numeric <float> { enum { value = true }; };
|
||||||
|
template <> struct is_numeric <double> { enum { value = true }; };
|
||||||
|
template <> struct is_numeric <long double> { enum { value = true }; };
|
||||||
|
|
||||||
|
template <bool, class T = void>
|
||||||
|
struct enable_if_c {
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct enable_if_c<false, T> {};
|
||||||
|
|
||||||
|
template <class Cond, class T = void>
|
||||||
|
struct enable_if : public enable_if_c<Cond::value, T> {};
|
||||||
|
|
||||||
|
template <bool, class T = void>
|
||||||
|
struct disable_if_c {
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct disable_if_c<true, T> {};
|
||||||
|
|
||||||
|
template <class Cond, class T = void>
|
||||||
|
struct disable_if : public disable_if_c<Cond::value, T> {};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
|
|
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 "crt.h"
|
|
||||||
#include "parser.h"
|
|
||||||
#include "node.h"
|
|
||||||
#include "iterator.h"
|
|
||||||
#include "emitter.h"
|
|
||||||
#include "stlemitter.h"
|
|
||||||
#include "exceptions.h"
|
|
||||||
|
|
||||||
#endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
@@ -1,94 +0,0 @@
|
|||||||
#include "crt.h"
|
|
||||||
#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*/, const 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, const 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,13 +0,0 @@
|
|||||||
#include "crt.h"
|
|
||||||
#include "content.h"
|
|
||||||
|
|
||||||
namespace YAML
|
|
||||||
{
|
|
||||||
Content::Content()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Content::~Content()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
@@ -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, const 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>
|
#include <algorithm>
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
24
src/directives.cpp
Normal file
24
src/directives.cpp
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#include "directives.h"
|
||||||
|
|
||||||
|
namespace YAML
|
||||||
|
{
|
||||||
|
Directives::Directives()
|
||||||
|
{
|
||||||
|
// version
|
||||||
|
version.isDefault = true;
|
||||||
|
version.major = 1;
|
||||||
|
version.minor = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string Directives::TranslateTagHandle(const std::string& handle) const
|
||||||
|
{
|
||||||
|
std::map <std::string, std::string>::const_iterator it = tags.find(handle);
|
||||||
|
if(it == tags.end()) {
|
||||||
|
if(handle == "!!")
|
||||||
|
return "tag:yaml.org,2002:";
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
}
|
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));
|
||||||
|
}
|
||||||
|
}
|
332
src/emitter.cpp
332
src/emitter.cpp
@@ -1,8 +1,8 @@
|
|||||||
#include "emitter.h"
|
#include "yaml-cpp/emitter.h"
|
||||||
#include "emitterstate.h"
|
#include "emitterstate.h"
|
||||||
#include "emitterutils.h"
|
#include "emitterutils.h"
|
||||||
#include "indentation.h"
|
#include "indentation.h"
|
||||||
#include "exceptions.h"
|
#include "yaml-cpp/exceptions.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
@@ -102,6 +102,12 @@ namespace YAML
|
|||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
switch(value) {
|
switch(value) {
|
||||||
|
case BeginDoc:
|
||||||
|
EmitBeginDoc();
|
||||||
|
break;
|
||||||
|
case EndDoc:
|
||||||
|
EmitEndDoc();
|
||||||
|
break;
|
||||||
case BeginSeq:
|
case BeginSeq:
|
||||||
EmitBeginSeq();
|
EmitBeginSeq();
|
||||||
break;
|
break;
|
||||||
@@ -120,6 +126,12 @@ namespace YAML
|
|||||||
case Value:
|
case Value:
|
||||||
EmitValue();
|
EmitValue();
|
||||||
break;
|
break;
|
||||||
|
case TagByKind:
|
||||||
|
EmitKindTag();
|
||||||
|
break;
|
||||||
|
case Newline:
|
||||||
|
EmitNewline();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
m_pState->SetLocalValue(value);
|
m_pState->SetLocalValue(value);
|
||||||
break;
|
break;
|
||||||
@@ -150,11 +162,14 @@ namespace YAML
|
|||||||
return true;
|
return true;
|
||||||
case ES_WRITING_DOC:
|
case ES_WRITING_DOC:
|
||||||
return true;
|
return true;
|
||||||
|
case ES_DONE_WITH_DOC:
|
||||||
|
EmitBeginDoc();
|
||||||
|
return false;
|
||||||
|
|
||||||
// block sequence
|
// block sequence
|
||||||
case ES_WAITING_FOR_BLOCK_SEQ_ENTRY:
|
case ES_WAITING_FOR_BLOCK_SEQ_ENTRY:
|
||||||
m_stream << IndentTo(curIndent) << "-";
|
m_stream << IndentTo(curIndent) << "-";
|
||||||
m_pState->RequireSeparation();
|
m_pState->RequireSoftSeparation();
|
||||||
m_pState->SwitchState(ES_WRITING_BLOCK_SEQ_ENTRY);
|
m_pState->SwitchState(ES_WRITING_BLOCK_SEQ_ENTRY);
|
||||||
return true;
|
return true;
|
||||||
case ES_WRITING_BLOCK_SEQ_ENTRY:
|
case ES_WRITING_BLOCK_SEQ_ENTRY:
|
||||||
@@ -171,8 +186,9 @@ namespace YAML
|
|||||||
case ES_WRITING_FLOW_SEQ_ENTRY:
|
case ES_WRITING_FLOW_SEQ_ENTRY:
|
||||||
return true;
|
return true;
|
||||||
case ES_DONE_WITH_FLOW_SEQ_ENTRY:
|
case ES_DONE_WITH_FLOW_SEQ_ENTRY:
|
||||||
|
EmitSeparationIfNecessary();
|
||||||
m_stream << ',';
|
m_stream << ',';
|
||||||
m_pState->RequireSeparation();
|
m_pState->RequireSoftSeparation();
|
||||||
m_pState->SwitchState(ES_WAITING_FOR_FLOW_SEQ_ENTRY);
|
m_pState->SwitchState(ES_WAITING_FOR_FLOW_SEQ_ENTRY);
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -183,7 +199,7 @@ namespace YAML
|
|||||||
case ES_WAITING_FOR_BLOCK_MAP_KEY:
|
case ES_WAITING_FOR_BLOCK_MAP_KEY:
|
||||||
if(m_pState->CurrentlyInLongKey()) {
|
if(m_pState->CurrentlyInLongKey()) {
|
||||||
m_stream << IndentTo(curIndent) << '?';
|
m_stream << IndentTo(curIndent) << '?';
|
||||||
m_pState->RequireSeparation();
|
m_pState->RequireSoftSeparation();
|
||||||
}
|
}
|
||||||
m_pState->SwitchState(ES_WRITING_BLOCK_MAP_KEY);
|
m_pState->SwitchState(ES_WRITING_BLOCK_MAP_KEY);
|
||||||
return true;
|
return true;
|
||||||
@@ -193,10 +209,6 @@ namespace YAML
|
|||||||
m_pState->SetError(ErrorMsg::EXPECTED_VALUE_TOKEN);
|
m_pState->SetError(ErrorMsg::EXPECTED_VALUE_TOKEN);
|
||||||
return true;
|
return true;
|
||||||
case ES_WAITING_FOR_BLOCK_MAP_VALUE:
|
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);
|
m_pState->SwitchState(ES_WRITING_BLOCK_MAP_VALUE);
|
||||||
return true;
|
return true;
|
||||||
case ES_WRITING_BLOCK_MAP_VALUE:
|
case ES_WRITING_BLOCK_MAP_VALUE:
|
||||||
@@ -210,11 +222,11 @@ namespace YAML
|
|||||||
m_pState->SetError(ErrorMsg::EXPECTED_KEY_TOKEN);
|
m_pState->SetError(ErrorMsg::EXPECTED_KEY_TOKEN);
|
||||||
return true;
|
return true;
|
||||||
case ES_WAITING_FOR_FLOW_MAP_KEY:
|
case ES_WAITING_FOR_FLOW_MAP_KEY:
|
||||||
|
EmitSeparationIfNecessary();
|
||||||
m_pState->SwitchState(ES_WRITING_FLOW_MAP_KEY);
|
m_pState->SwitchState(ES_WRITING_FLOW_MAP_KEY);
|
||||||
if(m_pState->CurrentlyInLongKey()) {
|
if(m_pState->CurrentlyInLongKey()) {
|
||||||
EmitSeparationIfNecessary();
|
|
||||||
m_stream << '?';
|
m_stream << '?';
|
||||||
m_pState->RequireSeparation();
|
m_pState->RequireSoftSeparation();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case ES_WRITING_FLOW_MAP_KEY:
|
case ES_WRITING_FLOW_MAP_KEY:
|
||||||
@@ -223,8 +235,9 @@ namespace YAML
|
|||||||
m_pState->SetError(ErrorMsg::EXPECTED_VALUE_TOKEN);
|
m_pState->SetError(ErrorMsg::EXPECTED_VALUE_TOKEN);
|
||||||
return true;
|
return true;
|
||||||
case ES_WAITING_FOR_FLOW_MAP_VALUE:
|
case ES_WAITING_FOR_FLOW_MAP_VALUE:
|
||||||
|
EmitSeparationIfNecessary();
|
||||||
m_stream << ':';
|
m_stream << ':';
|
||||||
m_pState->RequireSeparation();
|
m_pState->RequireSoftSeparation();
|
||||||
m_pState->SwitchState(ES_WRITING_FLOW_MAP_VALUE);
|
m_pState->SwitchState(ES_WRITING_FLOW_MAP_VALUE);
|
||||||
return true;
|
return true;
|
||||||
case ES_WRITING_FLOW_MAP_VALUE:
|
case ES_WRITING_FLOW_MAP_VALUE:
|
||||||
@@ -278,6 +291,10 @@ namespace YAML
|
|||||||
|
|
||||||
// block map
|
// block map
|
||||||
case ES_WRITING_BLOCK_MAP_KEY:
|
case ES_WRITING_BLOCK_MAP_KEY:
|
||||||
|
if(!m_pState->CurrentlyInLongKey()) {
|
||||||
|
m_stream << ':';
|
||||||
|
m_pState->RequireSoftSeparation();
|
||||||
|
}
|
||||||
m_pState->SwitchState(ES_DONE_WITH_BLOCK_MAP_KEY);
|
m_pState->SwitchState(ES_DONE_WITH_BLOCK_MAP_KEY);
|
||||||
break;
|
break;
|
||||||
case ES_WRITING_BLOCK_MAP_VALUE:
|
case ES_WRITING_BLOCK_MAP_VALUE:
|
||||||
@@ -304,11 +321,54 @@ namespace YAML
|
|||||||
if(!good())
|
if(!good())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(m_pState->RequiresSeparation())
|
if(m_pState->RequiresSoftSeparation())
|
||||||
m_stream << ' ';
|
m_stream << ' ';
|
||||||
|
else if(m_pState->RequiresHardSeparation())
|
||||||
|
m_stream << '\n';
|
||||||
m_pState->UnsetSeparation();
|
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
|
// EmitBeginSeq
|
||||||
void Emitter::EmitBeginSeq()
|
void Emitter::EmitBeginSeq()
|
||||||
{
|
{
|
||||||
@@ -323,9 +383,14 @@ namespace YAML
|
|||||||
EMITTER_STATE curState = m_pState->GetCurState();
|
EMITTER_STATE curState = m_pState->GetCurState();
|
||||||
EMITTER_MANIP flowType = m_pState->GetFlowType(GT_SEQ);
|
EMITTER_MANIP flowType = m_pState->GetFlowType(GT_SEQ);
|
||||||
if(flowType == Block) {
|
if(flowType == Block) {
|
||||||
if(curState == ES_WRITING_BLOCK_SEQ_ENTRY || curState == ES_WRITING_BLOCK_MAP_KEY || curState == ES_WRITING_BLOCK_MAP_VALUE) {
|
if(curState == ES_WRITING_BLOCK_SEQ_ENTRY ||
|
||||||
m_stream << "\n";
|
curState == ES_WRITING_BLOCK_MAP_KEY || curState == ES_WRITING_BLOCK_MAP_VALUE ||
|
||||||
m_pState->UnsetSeparation();
|
curState == ES_WRITING_DOC
|
||||||
|
) {
|
||||||
|
if(m_pState->RequiresHardSeparation() || curState != ES_WRITING_DOC) {
|
||||||
|
m_stream << "\n";
|
||||||
|
m_pState->UnsetSeparation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_pState->PushState(ES_WAITING_FOR_BLOCK_SEQ_ENTRY);
|
m_pState->PushState(ES_WAITING_FOR_BLOCK_SEQ_ENTRY);
|
||||||
} else if(flowType == Flow) {
|
} else if(flowType == Flow) {
|
||||||
@@ -354,8 +419,12 @@ namespace YAML
|
|||||||
// to a flow sequence if it is
|
// to a flow sequence if it is
|
||||||
assert(curState == ES_DONE_WITH_BLOCK_SEQ_ENTRY || curState == ES_WAITING_FOR_BLOCK_SEQ_ENTRY);
|
assert(curState == ES_DONE_WITH_BLOCK_SEQ_ENTRY || curState == ES_WAITING_FOR_BLOCK_SEQ_ENTRY);
|
||||||
if(curState == ES_WAITING_FOR_BLOCK_SEQ_ENTRY) {
|
if(curState == ES_WAITING_FOR_BLOCK_SEQ_ENTRY) {
|
||||||
|
// Note: only one of these will actually output anything for a given situation
|
||||||
|
EmitSeparationIfNecessary();
|
||||||
unsigned curIndent = m_pState->GetCurIndent();
|
unsigned curIndent = m_pState->GetCurIndent();
|
||||||
m_stream << IndentTo(curIndent) << "[]";
|
m_stream << IndentTo(curIndent);
|
||||||
|
|
||||||
|
m_stream << "[]";
|
||||||
}
|
}
|
||||||
} else if(flowType == FT_FLOW) {
|
} else if(flowType == FT_FLOW) {
|
||||||
// Note: flow sequences are allowed to be empty
|
// Note: flow sequences are allowed to be empty
|
||||||
@@ -384,9 +453,14 @@ namespace YAML
|
|||||||
EMITTER_STATE curState = m_pState->GetCurState();
|
EMITTER_STATE curState = m_pState->GetCurState();
|
||||||
EMITTER_MANIP flowType = m_pState->GetFlowType(GT_MAP);
|
EMITTER_MANIP flowType = m_pState->GetFlowType(GT_MAP);
|
||||||
if(flowType == Block) {
|
if(flowType == Block) {
|
||||||
if(curState == ES_WRITING_BLOCK_SEQ_ENTRY || curState == ES_WRITING_BLOCK_MAP_KEY || curState == ES_WRITING_BLOCK_MAP_VALUE) {
|
if(curState == ES_WRITING_BLOCK_SEQ_ENTRY ||
|
||||||
m_stream << "\n";
|
curState == ES_WRITING_BLOCK_MAP_KEY || curState == ES_WRITING_BLOCK_MAP_VALUE ||
|
||||||
m_pState->UnsetSeparation();
|
curState == ES_WRITING_DOC
|
||||||
|
) {
|
||||||
|
if(m_pState->RequiresHardSeparation() || (curState != ES_WRITING_DOC && curState != ES_WRITING_BLOCK_SEQ_ENTRY)) {
|
||||||
|
m_stream << "\n";
|
||||||
|
m_pState->UnsetSeparation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_pState->PushState(ES_WAITING_FOR_BLOCK_MAP_ENTRY);
|
m_pState->PushState(ES_WAITING_FOR_BLOCK_MAP_ENTRY);
|
||||||
} else if(flowType == Flow) {
|
} else if(flowType == Flow) {
|
||||||
@@ -415,12 +489,16 @@ namespace YAML
|
|||||||
// to a flow sequence if it is
|
// to a flow sequence if it is
|
||||||
assert(curState == ES_DONE_WITH_BLOCK_MAP_VALUE || curState == ES_WAITING_FOR_BLOCK_MAP_ENTRY);
|
assert(curState == ES_DONE_WITH_BLOCK_MAP_VALUE || curState == ES_WAITING_FOR_BLOCK_MAP_ENTRY);
|
||||||
if(curState == ES_WAITING_FOR_BLOCK_MAP_ENTRY) {
|
if(curState == ES_WAITING_FOR_BLOCK_MAP_ENTRY) {
|
||||||
|
// Note: only one of these will actually output anything for a given situation
|
||||||
|
EmitSeparationIfNecessary();
|
||||||
unsigned curIndent = m_pState->GetCurIndent();
|
unsigned curIndent = m_pState->GetCurIndent();
|
||||||
m_stream << IndentTo(curIndent) << "{}";
|
m_stream << IndentTo(curIndent);
|
||||||
|
m_stream << "{}";
|
||||||
}
|
}
|
||||||
} else if(flowType == FT_FLOW) {
|
} else if(flowType == FT_FLOW) {
|
||||||
// Note: flow maps are allowed to be empty
|
// Note: flow maps are allowed to be empty
|
||||||
assert(curState == ES_DONE_WITH_FLOW_MAP_VALUE || curState == ES_WAITING_FOR_FLOW_MAP_ENTRY);
|
assert(curState == ES_DONE_WITH_FLOW_MAP_VALUE || curState == ES_WAITING_FOR_FLOW_MAP_ENTRY);
|
||||||
|
EmitSeparationIfNecessary();
|
||||||
m_stream << "}";
|
m_stream << "}";
|
||||||
} else
|
} else
|
||||||
assert(false);
|
assert(false);
|
||||||
@@ -448,11 +526,13 @@ namespace YAML
|
|||||||
m_stream << '\n';
|
m_stream << '\n';
|
||||||
unsigned curIndent = m_pState->GetCurIndent();
|
unsigned curIndent = m_pState->GetCurIndent();
|
||||||
m_stream << IndentTo(curIndent);
|
m_stream << IndentTo(curIndent);
|
||||||
|
m_pState->UnsetSeparation();
|
||||||
m_pState->SwitchState(ES_WAITING_FOR_BLOCK_MAP_KEY);
|
m_pState->SwitchState(ES_WAITING_FOR_BLOCK_MAP_KEY);
|
||||||
} else if(flowType == FT_FLOW) {
|
} else if(flowType == FT_FLOW) {
|
||||||
|
EmitSeparationIfNecessary();
|
||||||
if(curState == ES_DONE_WITH_FLOW_MAP_VALUE) {
|
if(curState == ES_DONE_WITH_FLOW_MAP_VALUE) {
|
||||||
m_stream << ',';
|
m_stream << ',';
|
||||||
m_pState->RequireSeparation();
|
m_pState->RequireSoftSeparation();
|
||||||
}
|
}
|
||||||
m_pState->SwitchState(ES_WAITING_FOR_FLOW_MAP_KEY);
|
m_pState->SwitchState(ES_WAITING_FOR_FLOW_MAP_KEY);
|
||||||
} else
|
} else
|
||||||
@@ -478,8 +558,12 @@ namespace YAML
|
|||||||
return m_pState->SetError(ErrorMsg::UNEXPECTED_VALUE_TOKEN);
|
return m_pState->SetError(ErrorMsg::UNEXPECTED_VALUE_TOKEN);
|
||||||
|
|
||||||
if(flowType == FT_BLOCK) {
|
if(flowType == FT_BLOCK) {
|
||||||
if(m_pState->CurrentlyInLongKey())
|
if(m_pState->CurrentlyInLongKey()) {
|
||||||
m_stream << '\n';
|
m_stream << '\n';
|
||||||
|
m_stream << IndentTo(m_pState->GetCurIndent());
|
||||||
|
m_stream << ':';
|
||||||
|
m_pState->RequireSoftSeparation();
|
||||||
|
}
|
||||||
m_pState->SwitchState(ES_WAITING_FOR_BLOCK_MAP_VALUE);
|
m_pState->SwitchState(ES_WAITING_FOR_BLOCK_MAP_VALUE);
|
||||||
} else if(flowType == FT_FLOW) {
|
} else if(flowType == FT_FLOW) {
|
||||||
m_pState->SwitchState(ES_WAITING_FOR_FLOW_MAP_VALUE);
|
m_pState->SwitchState(ES_WAITING_FOR_FLOW_MAP_VALUE);
|
||||||
@@ -487,6 +571,28 @@ namespace YAML
|
|||||||
assert(false);
|
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
|
// overloads of Write
|
||||||
|
|
||||||
@@ -534,24 +640,12 @@ namespace YAML
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Emitter& Emitter::Write(const char *str)
|
void Emitter::PreWriteIntegralType(std::stringstream& str)
|
||||||
{
|
{
|
||||||
if(!good())
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
return Write(std::string(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
Emitter& Emitter::Write(int i)
|
|
||||||
{
|
|
||||||
if(!good())
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
PreAtomicWrite();
|
PreAtomicWrite();
|
||||||
EmitSeparationIfNecessary();
|
EmitSeparationIfNecessary();
|
||||||
|
|
||||||
EMITTER_MANIP intFmt = m_pState->GetIntFormat();
|
EMITTER_MANIP intFmt = m_pState->GetIntFormat();
|
||||||
std::stringstream str;
|
|
||||||
switch(intFmt) {
|
switch(intFmt) {
|
||||||
case Dec:
|
case Dec:
|
||||||
str << std::dec;
|
str << std::dec;
|
||||||
@@ -559,18 +653,66 @@ namespace YAML
|
|||||||
case Hex:
|
case Hex:
|
||||||
str << std::hex;
|
str << std::hex;
|
||||||
break;
|
break;
|
||||||
case Oct:
|
case Oct:
|
||||||
str << std::oct;
|
str << std::oct;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
str << i;
|
void Emitter::PreWriteStreamable(std::stringstream& str)
|
||||||
|
{
|
||||||
|
PreAtomicWrite();
|
||||||
|
EmitSeparationIfNecessary();
|
||||||
|
str.precision(15);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Emitter::PostWriteIntegralType(const std::stringstream& str)
|
||||||
|
{
|
||||||
m_stream << str.str();
|
m_stream << str.str();
|
||||||
|
|
||||||
PostAtomicWrite();
|
PostAtomicWrite();
|
||||||
return *this;
|
}
|
||||||
|
|
||||||
|
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)
|
Emitter& Emitter::Write(bool b)
|
||||||
@@ -581,29 +723,8 @@ namespace YAML
|
|||||||
PreAtomicWrite();
|
PreAtomicWrite();
|
||||||
EmitSeparationIfNecessary();
|
EmitSeparationIfNecessary();
|
||||||
|
|
||||||
// set up all possible bools to write
|
const char *name = ComputeFullBoolName(b);
|
||||||
struct BoolName { std::string trueName, falseName; };
|
if(m_pState->GetBoolLengthFormat() == ShortBool)
|
||||||
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)
|
|
||||||
m_stream << name[0];
|
m_stream << name[0];
|
||||||
else
|
else
|
||||||
m_stream << name;
|
m_stream << name;
|
||||||
@@ -612,38 +733,6 @@ namespace YAML
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Emitter& Emitter::Write(float f)
|
|
||||||
{
|
|
||||||
if(!good())
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
PreAtomicWrite();
|
|
||||||
EmitSeparationIfNecessary();
|
|
||||||
|
|
||||||
std::stringstream str;
|
|
||||||
str << f;
|
|
||||||
m_stream << str.str();
|
|
||||||
|
|
||||||
PostAtomicWrite();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Emitter& Emitter::Write(double d)
|
|
||||||
{
|
|
||||||
if(!good())
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
PreAtomicWrite();
|
|
||||||
EmitSeparationIfNecessary();
|
|
||||||
|
|
||||||
std::stringstream str;
|
|
||||||
str << d;
|
|
||||||
m_stream << str.str();
|
|
||||||
|
|
||||||
PostAtomicWrite();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Emitter& Emitter::Write(const _Alias& alias)
|
Emitter& Emitter::Write(const _Alias& alias)
|
||||||
{
|
{
|
||||||
if(!good())
|
if(!good())
|
||||||
@@ -670,18 +759,53 @@ namespace YAML
|
|||||||
m_pState->SetError(ErrorMsg::INVALID_ANCHOR);
|
m_pState->SetError(ErrorMsg::INVALID_ANCHOR);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
m_pState->RequireSeparation();
|
m_pState->RequireHardSeparation();
|
||||||
// Note: no PostAtomicWrite() because we need another value for this node
|
// Note: no PostAtomicWrite() because we need another value for this node
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Emitter& Emitter::Write(const _Tag& tag)
|
||||||
|
{
|
||||||
|
if(!good())
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
PreAtomicWrite();
|
||||||
|
EmitSeparationIfNecessary();
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
|
if(tag.type == _Tag::Type::Verbatim)
|
||||||
|
success = Utils::WriteTag(m_stream, tag.content, true);
|
||||||
|
else if(tag.type == _Tag::Type::PrimaryHandle)
|
||||||
|
success = Utils::WriteTag(m_stream, tag.content, false);
|
||||||
|
else
|
||||||
|
success = Utils::WriteTagWithPrefix(m_stream, tag.prefix, tag.content);
|
||||||
|
|
||||||
|
if(!success) {
|
||||||
|
m_pState->SetError(ErrorMsg::INVALID_TAG);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pState->RequireHardSeparation();
|
||||||
|
// Note: no PostAtomicWrite() because we need another value for this node
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Emitter::EmitKindTag()
|
||||||
|
{
|
||||||
|
Write(LocalTag(""));
|
||||||
|
}
|
||||||
|
|
||||||
Emitter& Emitter::Write(const _Comment& comment)
|
Emitter& Emitter::Write(const _Comment& comment)
|
||||||
{
|
{
|
||||||
if(!good())
|
if(!good())
|
||||||
return *this;
|
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());
|
Utils::WriteComment(m_stream, comment.content, m_pState->GetPostCommentIndent());
|
||||||
|
m_pState->RequireHardSeparation();
|
||||||
|
m_pState->ForceHardSeparation();
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -696,5 +820,19 @@ namespace YAML
|
|||||||
PostAtomicWrite();
|
PostAtomicWrite();
|
||||||
return *this;
|
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 "emitterstate.h"
|
||||||
#include "exceptions.h"
|
#include "yaml-cpp/exceptions.h"
|
||||||
|
|
||||||
namespace YAML
|
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
|
// start up
|
||||||
m_stateStack.push(ES_WAITING_FOR_DOC);
|
m_stateStack.push(ES_WAITING_FOR_DOC);
|
||||||
@@ -25,18 +25,6 @@ namespace YAML
|
|||||||
|
|
||||||
EmitterState::~EmitterState()
|
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
|
// SetLocalValue
|
||||||
@@ -57,10 +45,10 @@ namespace YAML
|
|||||||
|
|
||||||
void EmitterState::BeginGroup(GROUP_TYPE type)
|
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;
|
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)
|
// transfer settings (which last until this group is done)
|
||||||
pGroup->modifiedSettings = m_modifiedSettings;
|
pGroup->modifiedSettings = m_modifiedSettings;
|
||||||
@@ -70,7 +58,7 @@ namespace YAML
|
|||||||
pGroup->indent = GetIndent();
|
pGroup->indent = GetIndent();
|
||||||
pGroup->usingLongKey = (GetMapKeyFormat() == LongKey ? true : false);
|
pGroup->usingLongKey = (GetMapKeyFormat() == LongKey ? true : false);
|
||||||
|
|
||||||
m_groups.push(pGroup.release());
|
m_groups.push(pGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitterState::EndGroup(GROUP_TYPE type)
|
void EmitterState::EndGroup(GROUP_TYPE type)
|
||||||
@@ -80,13 +68,13 @@ namespace YAML
|
|||||||
|
|
||||||
// get rid of the current group
|
// get rid of the current group
|
||||||
{
|
{
|
||||||
std::auto_ptr <Group> pFinishedGroup = _PopGroup();
|
std::auto_ptr<Group> pFinishedGroup = m_groups.pop();
|
||||||
if(pFinishedGroup->type != type)
|
if(pFinishedGroup->type != type)
|
||||||
return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
|
return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset old settings
|
// 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);
|
assert(m_curIndent >= lastIndent);
|
||||||
m_curIndent -= lastIndent;
|
m_curIndent -= lastIndent;
|
||||||
|
|
||||||
@@ -100,7 +88,7 @@ namespace YAML
|
|||||||
if(m_groups.empty())
|
if(m_groups.empty())
|
||||||
return GT_NONE;
|
return GT_NONE;
|
||||||
|
|
||||||
return m_groups.top()->type;
|
return m_groups.top().type;
|
||||||
}
|
}
|
||||||
|
|
||||||
FLOW_TYPE EmitterState::GetCurGroupFlowType() const
|
FLOW_TYPE EmitterState::GetCurGroupFlowType() const
|
||||||
@@ -108,26 +96,26 @@ namespace YAML
|
|||||||
if(m_groups.empty())
|
if(m_groups.empty())
|
||||||
return FT_NONE;
|
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()
|
bool EmitterState::CurrentlyInLongKey()
|
||||||
{
|
{
|
||||||
if(m_groups.empty())
|
if(m_groups.empty())
|
||||||
return false;
|
return false;
|
||||||
return m_groups.top()->usingLongKey;
|
return m_groups.top().usingLongKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitterState::StartLongKey()
|
void EmitterState::StartLongKey()
|
||||||
{
|
{
|
||||||
if(!m_groups.empty())
|
if(!m_groups.empty())
|
||||||
m_groups.top()->usingLongKey = true;
|
m_groups.top().usingLongKey = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitterState::StartSimpleKey()
|
void EmitterState::StartSimpleKey()
|
||||||
{
|
{
|
||||||
if(!m_groups.empty())
|
if(!m_groups.empty())
|
||||||
m_groups.top()->usingLongKey = false;
|
m_groups.top().usingLongKey = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitterState::ClearModifiedSettings()
|
void EmitterState::ClearModifiedSettings()
|
||||||
|
@@ -1,11 +1,14 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
#ifndef EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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 "setting.h"
|
||||||
#include "emittermanip.h"
|
#include "yaml-cpp/emittermanip.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
@@ -101,9 +104,12 @@ namespace YAML
|
|||||||
void StartLongKey();
|
void StartLongKey();
|
||||||
void StartSimpleKey();
|
void StartSimpleKey();
|
||||||
|
|
||||||
bool RequiresSeparation() const { return m_requiresSeparation; }
|
bool RequiresSoftSeparation() const { return m_requiresSoftSeparation; }
|
||||||
void RequireSeparation() { m_requiresSeparation = true; }
|
bool RequiresHardSeparation() const { return m_requiresHardSeparation; }
|
||||||
void UnsetSeparation() { m_requiresSeparation = false; }
|
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();
|
void ClearModifiedSettings();
|
||||||
|
|
||||||
@@ -150,19 +156,19 @@ namespace YAML
|
|||||||
std::string m_lastError;
|
std::string m_lastError;
|
||||||
|
|
||||||
// other state
|
// other state
|
||||||
std::stack <EMITTER_STATE> m_stateStack;
|
std::stack<EMITTER_STATE> m_stateStack;
|
||||||
|
|
||||||
Setting <EMITTER_MANIP> m_charset;
|
Setting<EMITTER_MANIP> m_charset;
|
||||||
Setting <EMITTER_MANIP> m_strFmt;
|
Setting<EMITTER_MANIP> m_strFmt;
|
||||||
Setting <EMITTER_MANIP> m_boolFmt;
|
Setting<EMITTER_MANIP> m_boolFmt;
|
||||||
Setting <EMITTER_MANIP> m_boolLengthFmt;
|
Setting<EMITTER_MANIP> m_boolLengthFmt;
|
||||||
Setting <EMITTER_MANIP> m_boolCaseFmt;
|
Setting<EMITTER_MANIP> m_boolCaseFmt;
|
||||||
Setting <EMITTER_MANIP> m_intFmt;
|
Setting<EMITTER_MANIP> m_intFmt;
|
||||||
Setting <unsigned> m_indent;
|
Setting<unsigned> m_indent;
|
||||||
Setting <unsigned> m_preCommentIndent, m_postCommentIndent;
|
Setting<unsigned> m_preCommentIndent, m_postCommentIndent;
|
||||||
Setting <EMITTER_MANIP> m_seqFmt;
|
Setting<EMITTER_MANIP> m_seqFmt;
|
||||||
Setting <EMITTER_MANIP> m_mapFmt;
|
Setting<EMITTER_MANIP> m_mapFmt;
|
||||||
Setting <EMITTER_MANIP> m_mapKeyFmt;
|
Setting<EMITTER_MANIP> m_mapKeyFmt;
|
||||||
|
|
||||||
SettingChanges m_modifiedSettings;
|
SettingChanges m_modifiedSettings;
|
||||||
SettingChanges m_globalModifiedSettings;
|
SettingChanges m_globalModifiedSettings;
|
||||||
@@ -178,11 +184,10 @@ namespace YAML
|
|||||||
SettingChanges modifiedSettings;
|
SettingChanges modifiedSettings;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::auto_ptr <Group> _PopGroup();
|
ptr_stack<Group> m_groups;
|
||||||
|
|
||||||
std::stack <Group *> m_groups;
|
|
||||||
unsigned m_curIndent;
|
unsigned m_curIndent;
|
||||||
bool m_requiresSeparation;
|
bool m_requiresSoftSeparation;
|
||||||
|
bool m_requiresHardSeparation;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
#include "emitterutils.h"
|
#include "emitterutils.h"
|
||||||
#include "exp.h"
|
#include "exp.h"
|
||||||
#include "indentation.h"
|
#include "indentation.h"
|
||||||
#include "exceptions.h"
|
#include "yaml-cpp/exceptions.h"
|
||||||
#include "stringsource.h"
|
#include "stringsource.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
@@ -128,8 +128,11 @@ namespace YAML
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool IsValidPlainScalar(const std::string& str, bool inFlow, bool allowOnlyAscii) {
|
bool IsValidPlainScalar(const std::string& str, bool inFlow, bool allowOnlyAscii) {
|
||||||
|
if(str.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
// first check the start
|
// first check the start
|
||||||
const RegEx& start = (inFlow ? Exp::PlainScalarInFlow : Exp::PlainScalar);
|
const RegEx& start = (inFlow ? Exp::PlainScalarInFlow() : Exp::PlainScalar());
|
||||||
if(!start.Matches(str))
|
if(!start.Matches(str))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -138,12 +141,12 @@ namespace YAML
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// then check until something is disallowed
|
// then check until something is disallowed
|
||||||
const RegEx& disallowed = (inFlow ? Exp::EndScalarInFlow : Exp::EndScalar)
|
const RegEx& disallowed = (inFlow ? Exp::EndScalarInFlow() : Exp::EndScalar())
|
||||||
|| (Exp::BlankOrBreak + Exp::Comment)
|
|| (Exp::BlankOrBreak() + Exp::Comment())
|
||||||
|| Exp::NotPrintable
|
|| Exp::NotPrintable()
|
||||||
|| Exp::Utf8_ByteOrderMark
|
|| Exp::Utf8_ByteOrderMark()
|
||||||
|| Exp::Break
|
|| Exp::Break()
|
||||||
|| Exp::Tab;
|
|| Exp::Tab();
|
||||||
StringCharSource buffer(str.c_str(), str.size());
|
StringCharSource buffer(str.c_str(), str.size());
|
||||||
while(buffer) {
|
while(buffer) {
|
||||||
if(disallowed.Matches(buffer))
|
if(disallowed.Matches(buffer))
|
||||||
@@ -267,7 +270,7 @@ namespace YAML
|
|||||||
|
|
||||||
bool WriteComment(ostream& out, const std::string& str, int postCommentIndent)
|
bool WriteComment(ostream& out, const std::string& str, int postCommentIndent)
|
||||||
{
|
{
|
||||||
unsigned curIndent = out.col();
|
const unsigned curIndent = out.col();
|
||||||
out << "#" << Indentation(postCommentIndent);
|
out << "#" << Indentation(postCommentIndent);
|
||||||
int codePoint;
|
int codePoint;
|
||||||
for(std::string::const_iterator i = str.begin();
|
for(std::string::const_iterator i = str.begin();
|
||||||
@@ -293,6 +296,93 @@ namespace YAML
|
|||||||
out << "&";
|
out << "&";
|
||||||
return WriteAliasName(out, str);
|
return WriteAliasName(out, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WriteTag(ostream& out, const std::string& str, bool verbatim)
|
||||||
|
{
|
||||||
|
out << (verbatim ? "!<" : "!");
|
||||||
|
StringCharSource buffer(str.c_str(), str.size());
|
||||||
|
const RegEx& reValid = verbatim ? Exp::URI() : Exp::Tag();
|
||||||
|
while(buffer) {
|
||||||
|
int n = reValid.Match(buffer);
|
||||||
|
if(n <= 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while(--n >= 0) {
|
||||||
|
out << buffer[0];
|
||||||
|
++buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (verbatim)
|
||||||
|
out << ">";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WriteTagWithPrefix(ostream& out, const std::string& prefix, const std::string& tag)
|
||||||
|
{
|
||||||
|
out << "!";
|
||||||
|
StringCharSource prefixBuffer(prefix.c_str(), prefix.size());
|
||||||
|
while(prefixBuffer) {
|
||||||
|
int n = Exp::URI().Match(prefixBuffer);
|
||||||
|
if(n <= 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while(--n >= 0) {
|
||||||
|
out << prefixBuffer[0];
|
||||||
|
++prefixBuffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out << "!";
|
||||||
|
StringCharSource tagBuffer(tag.c_str(), tag.size());
|
||||||
|
while(tagBuffer) {
|
||||||
|
int n = Exp::Tag().Match(tagBuffer);
|
||||||
|
if(n <= 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while(--n >= 0) {
|
||||||
|
out << tagBuffer[0];
|
||||||
|
++tagBuffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WriteBinary(ostream& out, const 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
|
#ifndef EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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>
|
#include <string>
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
@@ -18,6 +20,9 @@ namespace YAML
|
|||||||
bool WriteComment(ostream& out, const std::string& str, int postCommentIndent);
|
bool WriteComment(ostream& out, const std::string& str, int postCommentIndent);
|
||||||
bool WriteAlias(ostream& out, const std::string& str);
|
bool WriteAlias(ostream& out, const std::string& str);
|
||||||
bool WriteAnchor(ostream& out, const std::string& str);
|
bool WriteAnchor(ostream& out, const std::string& str);
|
||||||
|
bool WriteTag(ostream& out, const std::string& str, bool verbatim);
|
||||||
|
bool WriteTagWithPrefix(ostream& out, const std::string& prefix, const std::string& tag);
|
||||||
|
bool WriteBinary(ostream& out, const unsigned char *data, std::size_t size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
#include "crt.h"
|
|
||||||
#include "exp.h"
|
#include "exp.h"
|
||||||
#include "exceptions.h"
|
#include "yaml-cpp/exceptions.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
@@ -108,7 +107,7 @@ namespace YAML
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::stringstream msg;
|
std::stringstream msg;
|
||||||
throw ParserException(in.mark(), ErrorMsg::INVALID_ESCAPE + ch);
|
throw ParserException(in.mark(), std::string(ErrorMsg::INVALID_ESCAPE) + ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
179
src/exp.h
179
src/exp.h
@@ -1,8 +1,10 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
#ifndef EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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 "regex.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -17,50 +19,157 @@ namespace YAML
|
|||||||
namespace Exp
|
namespace Exp
|
||||||
{
|
{
|
||||||
// misc
|
// misc
|
||||||
const RegEx Space = RegEx(' ');
|
inline const RegEx& Space() {
|
||||||
const RegEx Tab = RegEx('\t');
|
static const RegEx e = RegEx(' ');
|
||||||
const RegEx Blank = Space || Tab;
|
return e;
|
||||||
const RegEx Break = RegEx('\n') || RegEx("\r\n");
|
}
|
||||||
const RegEx BlankOrBreak = Blank || Break;
|
inline const RegEx& Tab() {
|
||||||
const RegEx Digit = RegEx('0', '9');
|
static const RegEx e = RegEx('\t');
|
||||||
const RegEx Alpha = RegEx('a', 'z') || RegEx('A', 'Z');
|
return e;
|
||||||
const RegEx AlphaNumeric = Alpha || Digit;
|
}
|
||||||
const RegEx Hex = Digit || RegEx('A', 'F') || RegEx('a', 'f');
|
inline const RegEx& Blank() {
|
||||||
|
static const RegEx e = Space() || Tab();
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& Break() {
|
||||||
|
static const RegEx e = RegEx('\n') || RegEx("\r\n");
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& BlankOrBreak() {
|
||||||
|
static const RegEx e = Blank() || Break();
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& Digit() {
|
||||||
|
static const RegEx e = RegEx('0', '9');
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& Alpha() {
|
||||||
|
static const RegEx e = RegEx('a', 'z') || RegEx('A', 'Z');
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& AlphaNumeric() {
|
||||||
|
static const RegEx e = Alpha() || Digit();
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& Word() {
|
||||||
|
static const RegEx e = AlphaNumeric() || RegEx('-');
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& Hex() {
|
||||||
|
static const RegEx e = Digit() || RegEx('A', 'F') || RegEx('a', 'f');
|
||||||
|
return e;
|
||||||
|
}
|
||||||
// Valid Unicode code points that are not part of c-printable (YAML 1.2, sec. 5.1)
|
// Valid Unicode code points that are not part of c-printable (YAML 1.2, sec. 5.1)
|
||||||
const RegEx NotPrintable = RegEx(0) ||
|
inline const RegEx& NotPrintable() {
|
||||||
RegEx("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) ||
|
static const RegEx e = RegEx(0) ||
|
||||||
RegEx(0x0E, 0x1F) ||
|
RegEx("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) ||
|
||||||
(RegEx('\xC2') + (RegEx('\x80', '\x84') || RegEx('\x86', '\x9F')));
|
RegEx(0x0E, 0x1F) ||
|
||||||
const RegEx Utf8_ByteOrderMark = RegEx("\xEF\xBB\xBF");
|
(RegEx('\xC2') + (RegEx('\x80', '\x84') || RegEx('\x86', '\x9F')));
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& Utf8_ByteOrderMark() {
|
||||||
|
static const RegEx e = RegEx("\xEF\xBB\xBF");
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
// actual tags
|
// actual tags
|
||||||
|
|
||||||
const RegEx DocStart = RegEx("---") + (BlankOrBreak || RegEx());
|
inline const RegEx& DocStart() {
|
||||||
const RegEx DocEnd = RegEx("...") + (BlankOrBreak || RegEx());
|
static const RegEx e = RegEx("---") + (BlankOrBreak() || RegEx());
|
||||||
const RegEx DocIndicator = DocStart || DocEnd;
|
return e;
|
||||||
const RegEx BlockEntry = RegEx('-') + (BlankOrBreak || RegEx());
|
}
|
||||||
const RegEx Key = RegEx('?'),
|
inline const RegEx& DocEnd() {
|
||||||
KeyInFlow = RegEx('?') + BlankOrBreak;
|
static const RegEx e = RegEx("...") + (BlankOrBreak() || RegEx());
|
||||||
const RegEx Value = RegEx(':') + (BlankOrBreak || RegEx()),
|
return e;
|
||||||
ValueInFlow = RegEx(':') + (BlankOrBreak || RegEx(",}", REGEX_OR));
|
}
|
||||||
const RegEx Comment = RegEx('#');
|
inline const RegEx& DocIndicator() {
|
||||||
const RegEx AnchorEnd = RegEx("?:,]}%@`", REGEX_OR) || BlankOrBreak;
|
static const RegEx e = DocStart() || DocEnd();
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& BlockEntry() {
|
||||||
|
static const RegEx e = RegEx('-') + (BlankOrBreak() || RegEx());
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& Key() {
|
||||||
|
static const RegEx e = RegEx('?');
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& KeyInFlow() {
|
||||||
|
static const RegEx e = RegEx('?') + BlankOrBreak();
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& Value() {
|
||||||
|
static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx());
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& ValueInFlow() {
|
||||||
|
static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx(",}", REGEX_OR));
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& ValueInJSONFlow() {
|
||||||
|
static const RegEx e = RegEx(':');
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx Comment() {
|
||||||
|
static const RegEx e = RegEx('#');
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& Anchor() {
|
||||||
|
static const RegEx e = !(RegEx("[]{},", REGEX_OR) || BlankOrBreak());
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& AnchorEnd() {
|
||||||
|
static const RegEx e = RegEx("?:,]}%@`", REGEX_OR) || BlankOrBreak();
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& URI() {
|
||||||
|
static const RegEx e = Word() || RegEx("#;/?:@&=+$,_.!~*'()[]", REGEX_OR) || (RegEx('%') + Hex() + Hex());
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& Tag() {
|
||||||
|
static const RegEx e = Word() || RegEx("#;/?:@&=+$_.~*'", REGEX_OR) || (RegEx('%') + Hex() + Hex());
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
// Plain scalar rules:
|
// Plain scalar rules:
|
||||||
// . Cannot start with a blank.
|
// . Cannot start with a blank.
|
||||||
// . Can never start with any of , [ ] { } # & * ! | > \' \" % @ `
|
// . Can never start with any of , [ ] { } # & * ! | > \' \" % @ `
|
||||||
// . In the block context - ? : must be not be followed with a space.
|
// . In the block context - ? : must be not be followed with a space.
|
||||||
// . In the flow context ? is illegal and : and - must not be followed with a space.
|
// . In the flow context ? is illegal and : and - must not be followed with a space.
|
||||||
const RegEx PlainScalar = !(BlankOrBreak || RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-?:", REGEX_OR) + Blank)),
|
inline const RegEx& PlainScalar() {
|
||||||
PlainScalarInFlow = !(BlankOrBreak || RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-:", REGEX_OR) + Blank));
|
static const RegEx e = !(BlankOrBreak() || RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-?:", REGEX_OR) + Blank()));
|
||||||
const RegEx EndScalar = RegEx(':') + (BlankOrBreak || RegEx()),
|
return e;
|
||||||
EndScalarInFlow = (RegEx(':') + (BlankOrBreak || RegEx(",]}", REGEX_OR))) || RegEx(",?[]{}", REGEX_OR);
|
}
|
||||||
|
inline const RegEx& PlainScalarInFlow() {
|
||||||
|
static const RegEx e = !(BlankOrBreak() || RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-:", REGEX_OR) + Blank()));
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& EndScalar() {
|
||||||
|
static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx());
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& EndScalarInFlow() {
|
||||||
|
static const RegEx e = (RegEx(':') + (BlankOrBreak() || RegEx(",]}", REGEX_OR))) || RegEx(",?[]{}", REGEX_OR);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
const RegEx EscSingleQuote = RegEx("\'\'");
|
inline const RegEx& EscSingleQuote() {
|
||||||
const RegEx EscBreak = RegEx('\\') + Break;
|
static const RegEx e = RegEx("\'\'");
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& EscBreak() {
|
||||||
|
static const RegEx e = RegEx('\\') + Break();
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
const RegEx ChompIndicator = RegEx("+-", REGEX_OR);
|
inline const RegEx& ChompIndicator() {
|
||||||
const RegEx Chomp = (ChompIndicator + Digit) || (Digit + ChompIndicator) || ChompIndicator || Digit;
|
static const RegEx e = RegEx("+-", REGEX_OR);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
inline const RegEx& Chomp() {
|
||||||
|
static const RegEx e = (ChompIndicator() + Digit()) || (Digit() + ChompIndicator()) || ChompIndicator() || Digit();
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
// and some functions
|
// and some functions
|
||||||
std::string Escape(Stream& in);
|
std::string Escape(Stream& in);
|
||||||
@@ -79,6 +188,8 @@ namespace YAML
|
|||||||
const char Tag = '!';
|
const char Tag = '!';
|
||||||
const char LiteralScalar = '|';
|
const char LiteralScalar = '|';
|
||||||
const char FoldedScalar = '>';
|
const char FoldedScalar = '>';
|
||||||
|
const char VerbatimTagStart = '<';
|
||||||
|
const char VerbatimTagEnd = '>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,10 +1,12 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
#ifndef INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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>
|
#include <iostream>
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
|
@@ -1,22 +1,19 @@
|
|||||||
#include "crt.h"
|
#include "yaml-cpp/node.h"
|
||||||
#include "node.h"
|
#include "yaml-cpp/exceptions.h"
|
||||||
#include "exceptions.h"
|
|
||||||
#include "iterpriv.h"
|
#include "iterpriv.h"
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
Iterator::Iterator(): m_pData(0)
|
Iterator::Iterator(): m_pData(new IterPriv)
|
||||||
{
|
|
||||||
m_pData = new IterPriv;
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator::Iterator(IterPriv *pData): m_pData(pData)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
Iterator& Iterator::operator = (const Iterator& rhs)
|
||||||
@@ -24,14 +21,12 @@ namespace YAML
|
|||||||
if(this == &rhs)
|
if(this == &rhs)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
delete m_pData;
|
m_pData.reset(new IterPriv(*rhs.m_pData));
|
||||||
m_pData = new IterPriv(*rhs.m_pData);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator::~Iterator()
|
Iterator::~Iterator()
|
||||||
{
|
{
|
||||||
delete m_pData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator& Iterator::operator ++ ()
|
Iterator& Iterator::operator ++ ()
|
||||||
|
@@ -1,10 +1,12 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef ITERPRIV_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
#ifndef ITERPRIV_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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 <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
189
src/map.cpp
189
src/map.cpp
@@ -1,189 +0,0 @@
|
|||||||
#include "crt.h"
|
|
||||||
#include "map.h"
|
|
||||||
#include "node.h"
|
|
||||||
#include "scanner.h"
|
|
||||||
#include "token.h"
|
|
||||||
#include "exceptions.h"
|
|
||||||
#include "emitter.h"
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
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();
|
|
||||||
m_data[pKey.release()] = pValue.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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, const 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;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Map::ParseBlock(Scanner *pScanner, const ParserState& state)
|
|
||||||
{
|
|
||||||
// eat start token
|
|
||||||
pScanner->pop();
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// assign the map with the actual pointers
|
|
||||||
m_data[pKey.release()] = pValue.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Map::ParseFlow(Scanner *pScanner, const ParserState& state)
|
|
||||||
{
|
|
||||||
// eat start token
|
|
||||||
pScanner->pop();
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// assign the map with the actual pointers
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
50
src/map.h
50
src/map.h
@@ -1,50 +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>
|
|
||||||
|
|
||||||
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, const 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, const ParserState& state);
|
|
||||||
void ParseFlow(Scanner *pScanner, const ParserState& state);
|
|
||||||
|
|
||||||
private:
|
|
||||||
node_map m_data;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // MAP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
373
src/node.cpp
373
src/node.cpp
@@ -1,34 +1,29 @@
|
|||||||
#include "crt.h"
|
#include "yaml-cpp/node.h"
|
||||||
#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 "iterpriv.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>
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace YAML
|
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;
|
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)
|
Node::Node(NodeOwnership& owner): m_pOwnership(new NodeOwnership(&owner)), m_type(NodeType::Null)
|
||||||
: m_mark(mark), m_anchor(anchor), m_tag(tag), m_pContent(0), m_alias(false), m_pIdentity(this), m_referenced(false)
|
|
||||||
{
|
{
|
||||||
if(m_pContent)
|
|
||||||
m_pContent = pContent->Clone();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Node::~Node()
|
Node::~Node()
|
||||||
@@ -38,167 +33,124 @@ namespace YAML
|
|||||||
|
|
||||||
void Node::Clear()
|
void Node::Clear()
|
||||||
{
|
{
|
||||||
delete m_pContent;
|
m_pOwnership.reset(new NodeOwnership);
|
||||||
m_pContent = 0;
|
m_type = NodeType::Null;
|
||||||
m_alias = false;
|
|
||||||
m_referenced = false;
|
|
||||||
m_anchor.clear();
|
|
||||||
m_tag.clear();
|
m_tag.clear();
|
||||||
|
m_scalarData.clear();
|
||||||
|
m_seqData.clear();
|
||||||
|
m_mapData.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Node::IsAliased() const
|
||||||
|
{
|
||||||
|
return m_pOwnership->IsAliased(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node& Node::CreateNode()
|
||||||
|
{
|
||||||
|
return m_pOwnership->Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::auto_ptr<Node> Node::Clone() const
|
std::auto_ptr<Node> Node::Clone() const
|
||||||
{
|
{
|
||||||
if(m_alias)
|
std::auto_ptr<Node> pNode(new Node);
|
||||||
throw std::runtime_error("yaml-cpp: Can't clone alias"); // TODO: what to do about aliases?
|
NodeBuilder nodeBuilder(*pNode);
|
||||||
|
EmitEvents(nodeBuilder);
|
||||||
return std::auto_ptr<Node> (new Node(m_mark, m_anchor, m_tag, m_pContent));
|
return pNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::Parse(Scanner *pScanner, const 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();
|
Clear();
|
||||||
|
m_mark = mark;
|
||||||
// an empty node *is* a possibility
|
m_type = type;
|
||||||
if(pScanner->empty())
|
m_tag = tag;
|
||||||
return;
|
|
||||||
|
|
||||||
// save location
|
|
||||||
m_mark = pScanner->peek().mark;
|
|
||||||
|
|
||||||
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;
|
|
||||||
default:
|
|
||||||
// std::stringstream str;
|
|
||||||
// str << TokenNames[pScanner->peek().type];
|
|
||||||
// throw std::runtime_error(str.str());
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseHeader
|
void Node::MarkAsAliased()
|
||||||
// . Grabs any tag, alias, or anchor tokens and deals with them.
|
|
||||||
void Node::ParseHeader(Scanner *pScanner, const ParserState& state)
|
|
||||||
{
|
{
|
||||||
while(1) {
|
m_pOwnership->MarkAsAliased(*this);
|
||||||
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, const ParserState& state)
|
void Node::SetScalarData(const std::string& data)
|
||||||
{
|
{
|
||||||
Token& token = pScanner->peek();
|
assert(m_type == NodeType::Scalar); // TODO: throw?
|
||||||
if(m_tag != "")
|
m_scalarData = data;
|
||||||
throw ParserException(token.mark, ErrorMsg::MULTIPLE_TAGS);
|
|
||||||
|
|
||||||
m_tag = state.TranslateTag(token.value);
|
|
||||||
|
|
||||||
for(std::size_t i=0;i<token.params.size();i++)
|
|
||||||
m_tag += token.params[i];
|
|
||||||
pScanner->pop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::ParseAnchor(Scanner *pScanner, const ParserState& /*state*/)
|
void Node::Append(Node& node)
|
||||||
{
|
{
|
||||||
Token& token = pScanner->peek();
|
assert(m_type == NodeType::Sequence); // TODO: throw?
|
||||||
if(m_anchor != "")
|
m_seqData.push_back(&node);
|
||||||
throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS);
|
|
||||||
|
|
||||||
m_anchor = token.value;
|
|
||||||
m_alias = false;
|
|
||||||
pScanner->pop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::ParseAlias(Scanner *pScanner, const ParserState& /*state*/)
|
void Node::Insert(Node& key, Node& value)
|
||||||
{
|
{
|
||||||
Token& token = pScanner->peek();
|
assert(m_type == NodeType::Map); // TODO: throw?
|
||||||
if(m_anchor != "")
|
m_mapData[&key] = &value;
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
CONTENT_TYPE Node::GetType() const
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// begin
|
// begin
|
||||||
// Returns an iterator to the beginning of this (sequence or map).
|
// Returns an iterator to the beginning of this (sequence or map).
|
||||||
Iterator Node::begin() const
|
Iterator Node::begin() const
|
||||||
{
|
{
|
||||||
if(!m_pContent)
|
switch(m_type) {
|
||||||
return Iterator();
|
case NodeType::Null:
|
||||||
|
case NodeType::Scalar:
|
||||||
std::vector <Node *>::const_iterator seqIter;
|
return Iterator();
|
||||||
if(m_pContent->GetBegin(seqIter))
|
case NodeType::Sequence:
|
||||||
return Iterator(new IterPriv(seqIter));
|
return Iterator(std::auto_ptr<IterPriv>(new IterPriv(m_seqData.begin())));
|
||||||
|
case NodeType::Map:
|
||||||
std::map <Node *, Node *, ltnode>::const_iterator mapIter;
|
return Iterator(std::auto_ptr<IterPriv>(new IterPriv(m_mapData.begin())));
|
||||||
if(m_pContent->GetBegin(mapIter))
|
}
|
||||||
return Iterator(new IterPriv(mapIter));
|
|
||||||
|
|
||||||
|
assert(false);
|
||||||
return Iterator();
|
return Iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,83 +158,108 @@ namespace YAML
|
|||||||
// . Returns an iterator to the end of this (sequence or map).
|
// . Returns an iterator to the end of this (sequence or map).
|
||||||
Iterator Node::end() const
|
Iterator Node::end() const
|
||||||
{
|
{
|
||||||
if(!m_pContent)
|
switch(m_type) {
|
||||||
return Iterator();
|
case NodeType::Null:
|
||||||
|
case NodeType::Scalar:
|
||||||
std::vector <Node *>::const_iterator seqIter;
|
return Iterator();
|
||||||
if(m_pContent->GetEnd(seqIter))
|
case NodeType::Sequence:
|
||||||
return Iterator(new IterPriv(seqIter));
|
return Iterator(std::auto_ptr<IterPriv>(new IterPriv(m_seqData.end())));
|
||||||
|
case NodeType::Map:
|
||||||
std::map <Node *, Node *, ltnode>::const_iterator mapIter;
|
return Iterator(std::auto_ptr<IterPriv>(new IterPriv(m_mapData.end())));
|
||||||
if(m_pContent->GetEnd(mapIter))
|
}
|
||||||
return Iterator(new IterPriv(mapIter));
|
|
||||||
|
|
||||||
|
assert(false);
|
||||||
return Iterator();
|
return Iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
// size
|
// 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.
|
// . Otherwise, returns zero.
|
||||||
std::size_t Node::size() const
|
std::size_t Node::size() const
|
||||||
{
|
{
|
||||||
if(!m_pContent)
|
switch(m_type) {
|
||||||
return 0;
|
case NodeType::Null:
|
||||||
|
case NodeType::Scalar:
|
||||||
|
return 0;
|
||||||
|
case NodeType::Sequence:
|
||||||
|
return m_seqData.size();
|
||||||
|
case NodeType::Map:
|
||||||
|
return m_mapData.size();
|
||||||
|
}
|
||||||
|
|
||||||
return m_pContent->GetSize();
|
assert(false);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Node *Node::FindAtIndex(std::size_t i) const
|
const Node *Node::FindAtIndex(std::size_t i) const
|
||||||
{
|
{
|
||||||
if(!m_pContent)
|
if(m_type == NodeType::Sequence)
|
||||||
return 0;
|
return m_seqData[i];
|
||||||
|
return 0;
|
||||||
return m_pContent->GetNode(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Node::GetScalar(std::string& s) const
|
bool Node::GetScalar(std::string& s) const
|
||||||
{
|
{
|
||||||
if(!m_pContent) {
|
switch(m_type) {
|
||||||
s = "~";
|
case NodeType::Null:
|
||||||
return true;
|
s = "~";
|
||||||
|
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)
|
Emitter& operator << (Emitter& out, const Node& node)
|
||||||
{
|
{
|
||||||
// write anchor/alias
|
EmitFromEvents emitFromEvents(out);
|
||||||
if(node.m_anchor != "") {
|
node.EmitEvents(emitFromEvents);
|
||||||
if(node.m_alias)
|
|
||||||
out << Alias(node.m_anchor);
|
|
||||||
else
|
|
||||||
out << Anchor(node.m_anchor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: write tag
|
|
||||||
|
|
||||||
// write content
|
|
||||||
if(node.m_pContent)
|
|
||||||
node.m_pContent->Write(out);
|
|
||||||
else if(!node.m_alias)
|
|
||||||
out << Null;
|
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Node::Compare(const Node& rhs) const
|
int Node::Compare(const Node& rhs) const
|
||||||
{
|
{
|
||||||
// Step 1: no content is the smallest
|
if(m_type != rhs.m_type)
|
||||||
if(!m_pContent) {
|
return rhs.m_type - m_type;
|
||||||
if(rhs.m_pContent)
|
|
||||||
return -1;
|
switch(m_type) {
|
||||||
else
|
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;
|
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)
|
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 "yaml-cpp/null.h"
|
||||||
#include "node.h"
|
#include "yaml-cpp/node.h"
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
#include "ostream.h"
|
#include "yaml-cpp/ostream.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
|
111
src/parser.cpp
111
src/parser.cpp
@@ -1,8 +1,13 @@
|
|||||||
#include "crt.h"
|
#include "yaml-cpp/parser.h"
|
||||||
#include "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 "scanner.h"
|
||||||
|
#include "singledocparser.h"
|
||||||
|
#include "tag.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
#include "exceptions.h"
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
@@ -29,7 +34,25 @@ namespace YAML
|
|||||||
void Parser::Load(std::istream& in)
|
void Parser::Load(std::istream& in)
|
||||||
{
|
{
|
||||||
m_pScanner.reset(new Scanner(in));
|
m_pScanner.reset(new Scanner(in));
|
||||||
m_state.Reset();
|
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
|
// GetNextDocument
|
||||||
@@ -37,34 +60,8 @@ namespace YAML
|
|||||||
// . Throws a ParserException on error.
|
// . Throws a ParserException on error.
|
||||||
bool Parser::GetNextDocument(Node& document)
|
bool Parser::GetNextDocument(Node& document)
|
||||||
{
|
{
|
||||||
if(!m_pScanner.get())
|
NodeBuilder builder(document);
|
||||||
return false;
|
return HandleNextDocument(builder);
|
||||||
|
|
||||||
// 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_state);
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseDirectives
|
// ParseDirectives
|
||||||
@@ -84,51 +81,59 @@ namespace YAML
|
|||||||
// we keep the directives from the last document if none are specified;
|
// we keep the directives from the last document if none are specified;
|
||||||
// but if any directives are specific, then we reset them
|
// but if any directives are specific, then we reset them
|
||||||
if(!readDirective)
|
if(!readDirective)
|
||||||
m_state.Reset();
|
m_pDirectives.reset(new Directives);
|
||||||
|
|
||||||
readDirective = true;
|
readDirective = true;
|
||||||
HandleDirective(&token);
|
HandleDirective(token);
|
||||||
m_pScanner->pop();
|
m_pScanner->pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::HandleDirective(Token *pToken)
|
void Parser::HandleDirective(const Token& token)
|
||||||
{
|
{
|
||||||
if(pToken->value == "YAML")
|
if(token.value == "YAML")
|
||||||
HandleYamlDirective(pToken);
|
HandleYamlDirective(token);
|
||||||
else if(pToken->value == "TAG")
|
else if(token.value == "TAG")
|
||||||
HandleTagDirective(pToken);
|
HandleTagDirective(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleYamlDirective
|
// HandleYamlDirective
|
||||||
// . Should be of the form 'major.minor' (like a version number)
|
// . Should be of the form 'major.minor' (like a version number)
|
||||||
void Parser::HandleYamlDirective(Token *pToken)
|
void Parser::HandleYamlDirective(const Token& token)
|
||||||
{
|
{
|
||||||
if(pToken->params.size() != 1)
|
if(token.params.size() != 1)
|
||||||
throw ParserException(pToken->mark, ErrorMsg::YAML_DIRECTIVE_ARGS);
|
throw ParserException(token.mark, ErrorMsg::YAML_DIRECTIVE_ARGS);
|
||||||
|
|
||||||
std::stringstream str(pToken->params[0]);
|
if(!m_pDirectives->version.isDefault)
|
||||||
str >> m_state.version.major;
|
throw ParserException(token.mark, ErrorMsg::REPEATED_YAML_DIRECTIVE);
|
||||||
|
|
||||||
|
std::stringstream str(token.params[0]);
|
||||||
|
str >> m_pDirectives->version.major;
|
||||||
str.get();
|
str.get();
|
||||||
str >> m_state.version.minor;
|
str >> m_pDirectives->version.minor;
|
||||||
if(!str || str.peek() != EOF)
|
if(!str || str.peek() != EOF)
|
||||||
throw ParserException(pToken->mark, ErrorMsg::YAML_VERSION + pToken->params[0]);
|
throw ParserException(token.mark, std::string(ErrorMsg::YAML_VERSION) + token.params[0]);
|
||||||
|
|
||||||
if(m_state.version.major > 1)
|
if(m_pDirectives->version.major > 1)
|
||||||
throw ParserException(pToken->mark, ErrorMsg::YAML_MAJOR_VERSION);
|
throw ParserException(token.mark, ErrorMsg::YAML_MAJOR_VERSION);
|
||||||
|
|
||||||
|
m_pDirectives->version.isDefault = false;
|
||||||
// TODO: warning on major == 1, minor > 2?
|
// TODO: warning on major == 1, minor > 2?
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleTagDirective
|
// HandleTagDirective
|
||||||
// . Should be of the form 'handle prefix', where 'handle' is converted to 'prefix' in the file.
|
// . Should be of the form 'handle prefix', where 'handle' is converted to 'prefix' in the file.
|
||||||
void Parser::HandleTagDirective(Token *pToken)
|
void Parser::HandleTagDirective(const Token& token)
|
||||||
{
|
{
|
||||||
if(pToken->params.size() != 2)
|
if(token.params.size() != 2)
|
||||||
throw ParserException(pToken->mark, ErrorMsg::TAG_DIRECTIVE_ARGS);
|
throw ParserException(token.mark, ErrorMsg::TAG_DIRECTIVE_ARGS);
|
||||||
|
|
||||||
std::string handle = pToken->params[0], prefix = pToken->params[1];
|
const std::string& handle = token.params[0];
|
||||||
m_state.tags[handle] = prefix;
|
const std::string& prefix = token.params[1];
|
||||||
|
if(m_pDirectives->tags.find(handle) != m_pDirectives->tags.end())
|
||||||
|
throw ParserException(token.mark, ErrorMsg::REPEATED_TAG_DIRECTIVE);
|
||||||
|
|
||||||
|
m_pDirectives->tags[handle] = prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::PrintTokens(std::ostream& out)
|
void Parser::PrintTokens(std::ostream& out)
|
||||||
|
@@ -1,26 +0,0 @@
|
|||||||
#include "crt.h"
|
|
||||||
#include "parserstate.h"
|
|
||||||
|
|
||||||
namespace YAML
|
|
||||||
{
|
|
||||||
void ParserState::Reset()
|
|
||||||
{
|
|
||||||
// version
|
|
||||||
version.major = 1;
|
|
||||||
version.minor = 2;
|
|
||||||
|
|
||||||
// and tags
|
|
||||||
tags.clear();
|
|
||||||
tags["!"] = "!";
|
|
||||||
tags["!!"] = "tag:yaml.org,2002:";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ParserState::TranslateTag(const std::string& handle) const
|
|
||||||
{
|
|
||||||
std::map <std::string, std::string>::const_iterator it = tags.find(handle);
|
|
||||||
if(it == tags.end())
|
|
||||||
return handle;
|
|
||||||
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
}
|
|
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,4 +1,3 @@
|
|||||||
#include "crt.h"
|
|
||||||
#include "regex.h"
|
#include "regex.h"
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
#ifndef REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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 <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -37,12 +39,12 @@ namespace YAML
|
|||||||
|
|
||||||
int Match(const std::string& str) const;
|
int Match(const std::string& str) const;
|
||||||
int Match(const Stream& in) const;
|
int Match(const Stream& in) const;
|
||||||
|
template <typename Source> int Match(const Source& source) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RegEx(REGEX_OP op);
|
RegEx(REGEX_OP op);
|
||||||
|
|
||||||
template <typename Source> bool IsValidSource(const Source& source) const;
|
template <typename Source> bool IsValidSource(const Source& source) const;
|
||||||
template <typename Source> int Match(const Source& source) const;
|
|
||||||
template <typename Source> int MatchUnchecked(const Source& source) const;
|
template <typename Source> int MatchUnchecked(const Source& source) const;
|
||||||
|
|
||||||
template <typename Source> int MatchOpEmpty(const Source& source) const;
|
template <typename Source> int MatchOpEmpty(const Source& source) const;
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
#ifndef REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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 "stream.h"
|
||||||
#include "stringsource.h"
|
#include "stringsource.h"
|
||||||
@@ -58,7 +60,13 @@ namespace YAML
|
|||||||
template<>
|
template<>
|
||||||
inline bool RegEx::IsValidSource<StringCharSource>(const StringCharSource&source) const
|
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>
|
template <typename Source>
|
||||||
|
@@ -1,55 +0,0 @@
|
|||||||
#include "crt.h"
|
|
||||||
#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, const 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, const 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
|
|
||||||
|
|
136
src/scanner.cpp
136
src/scanner.cpp
@@ -1,14 +1,14 @@
|
|||||||
#include "crt.h"
|
|
||||||
#include "scanner.h"
|
#include "scanner.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
#include "exceptions.h"
|
#include "yaml-cpp/exceptions.h"
|
||||||
#include "exp.h"
|
#include "exp.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
Scanner::Scanner(std::istream& in)
|
Scanner::Scanner(std::istream& in)
|
||||||
: INPUT(in), m_startedStream(false), m_endedStream(false), m_simpleKeyAllowed(false)
|
: INPUT(in), m_startedStream(false), m_endedStream(false), m_simpleKeyAllowed(false), m_canBeJSONFlow(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,13 +29,8 @@ namespace YAML
|
|||||||
void Scanner::pop()
|
void Scanner::pop()
|
||||||
{
|
{
|
||||||
EnsureTokensInQueue();
|
EnsureTokensInQueue();
|
||||||
if(!m_tokens.empty()) {
|
if(!m_tokens.empty())
|
||||||
// Saved anchors shouldn't survive popping the document end marker
|
|
||||||
if (m_tokens.front().type == Token::DOC_END) {
|
|
||||||
ClearAnchors();
|
|
||||||
}
|
|
||||||
m_tokens.pop();
|
m_tokens.pop();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// peek
|
// peek
|
||||||
@@ -116,10 +111,10 @@ namespace YAML
|
|||||||
return ScanDirective();
|
return ScanDirective();
|
||||||
|
|
||||||
// document token
|
// document token
|
||||||
if(INPUT.column() == 0 && Exp::DocStart.Matches(INPUT))
|
if(INPUT.column() == 0 && Exp::DocStart().Matches(INPUT))
|
||||||
return ScanDocStart();
|
return ScanDocStart();
|
||||||
|
|
||||||
if(INPUT.column() == 0 && Exp::DocEnd.Matches(INPUT))
|
if(INPUT.column() == 0 && Exp::DocEnd().Matches(INPUT))
|
||||||
return ScanDocEnd();
|
return ScanDocEnd();
|
||||||
|
|
||||||
// flow start/end/entry
|
// flow start/end/entry
|
||||||
@@ -133,13 +128,13 @@ namespace YAML
|
|||||||
return ScanFlowEntry();
|
return ScanFlowEntry();
|
||||||
|
|
||||||
// block/map stuff
|
// block/map stuff
|
||||||
if(Exp::BlockEntry.Matches(INPUT))
|
if(Exp::BlockEntry().Matches(INPUT))
|
||||||
return ScanBlockEntry();
|
return ScanBlockEntry();
|
||||||
|
|
||||||
if((InBlockContext() ? Exp::Key : Exp::KeyInFlow).Matches(INPUT))
|
if((InBlockContext() ? Exp::Key() : Exp::KeyInFlow()).Matches(INPUT))
|
||||||
return ScanKey();
|
return ScanKey();
|
||||||
|
|
||||||
if((InBlockContext() ? Exp::Value : Exp::ValueInFlow).Matches(INPUT))
|
if(GetValueRegex().Matches(INPUT))
|
||||||
return ScanValue();
|
return ScanValue();
|
||||||
|
|
||||||
// alias/anchor
|
// alias/anchor
|
||||||
@@ -158,7 +153,7 @@ namespace YAML
|
|||||||
return ScanQuotedScalar();
|
return ScanQuotedScalar();
|
||||||
|
|
||||||
// plain scalars
|
// plain scalars
|
||||||
if((InBlockContext() ? Exp::PlainScalar : Exp::PlainScalarInFlow).Matches(INPUT))
|
if((InBlockContext() ? Exp::PlainScalar() : Exp::PlainScalarInFlow()).Matches(INPUT))
|
||||||
return ScanPlainScalar();
|
return ScanPlainScalar();
|
||||||
|
|
||||||
// don't know what it is!
|
// don't know what it is!
|
||||||
@@ -172,24 +167,24 @@ namespace YAML
|
|||||||
while(1) {
|
while(1) {
|
||||||
// first eat whitespace
|
// first eat whitespace
|
||||||
while(INPUT && IsWhitespaceToBeEaten(INPUT.peek())) {
|
while(INPUT && IsWhitespaceToBeEaten(INPUT.peek())) {
|
||||||
if(InBlockContext() && Exp::Tab.Matches(INPUT))
|
if(InBlockContext() && Exp::Tab().Matches(INPUT))
|
||||||
m_simpleKeyAllowed = false;
|
m_simpleKeyAllowed = false;
|
||||||
INPUT.eat(1);
|
INPUT.eat(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// then eat a comment
|
// then eat a comment
|
||||||
if(Exp::Comment.Matches(INPUT)) {
|
if(Exp::Comment().Matches(INPUT)) {
|
||||||
// eat until line break
|
// eat until line break
|
||||||
while(INPUT && !Exp::Break.Matches(INPUT))
|
while(INPUT && !Exp::Break().Matches(INPUT))
|
||||||
INPUT.eat(1);
|
INPUT.eat(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if it's NOT a line break, then we're done!
|
// if it's NOT a line break, then we're done!
|
||||||
if(!Exp::Break.Matches(INPUT))
|
if(!Exp::Break().Matches(INPUT))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// otherwise, let's eat the line break and keep going
|
// otherwise, let's eat the line break and keep going
|
||||||
int n = Exp::Break.Match(INPUT);
|
int n = Exp::Break().Match(INPUT);
|
||||||
INPUT.eat(n);
|
INPUT.eat(n);
|
||||||
|
|
||||||
// oh yeah, and let's get rid of that simple key
|
// oh yeah, and let's get rid of that simple key
|
||||||
@@ -223,14 +218,25 @@ namespace YAML
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetValueRegex
|
||||||
|
// . Get the appropriate regex to check if it's a value token
|
||||||
|
const RegEx& Scanner::GetValueRegex() const
|
||||||
|
{
|
||||||
|
if(InBlockContext())
|
||||||
|
return Exp::Value();
|
||||||
|
|
||||||
|
return m_canBeJSONFlow ? Exp::ValueInJSONFlow() : Exp::ValueInFlow();
|
||||||
|
}
|
||||||
|
|
||||||
// StartStream
|
// StartStream
|
||||||
// . Set the initial conditions for starting a stream.
|
// . Set the initial conditions for starting a stream.
|
||||||
void Scanner::StartStream()
|
void Scanner::StartStream()
|
||||||
{
|
{
|
||||||
m_startedStream = true;
|
m_startedStream = true;
|
||||||
m_simpleKeyAllowed = true;
|
m_simpleKeyAllowed = true;
|
||||||
m_indents.push(IndentMarker(-1, IndentMarker::NONE));
|
std::auto_ptr<IndentMarker> pIndent(new IndentMarker(-1, IndentMarker::NONE));
|
||||||
m_anchors.clear();
|
m_indentRefs.push_back(pIndent);
|
||||||
|
m_indents.push(&m_indentRefs.back());
|
||||||
}
|
}
|
||||||
|
|
||||||
// EndStream
|
// EndStream
|
||||||
@@ -248,6 +254,23 @@ namespace YAML
|
|||||||
m_endedStream = true;
|
m_endedStream = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Token *Scanner::PushToken(Token::TYPE type)
|
||||||
|
{
|
||||||
|
m_tokens.push(Token(type, INPUT.mark()));
|
||||||
|
return &m_tokens.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
Token::TYPE Scanner::GetStartTokenFor(IndentMarker::INDENT_TYPE type) const
|
||||||
|
{
|
||||||
|
switch(type) {
|
||||||
|
case IndentMarker::SEQ: return Token::BLOCK_SEQ_START;
|
||||||
|
case IndentMarker::MAP: return Token::BLOCK_MAP_START;
|
||||||
|
case IndentMarker::NONE: assert(false); break;
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
|
throw std::runtime_error("yaml-cpp: internal error, invalid indent type");
|
||||||
|
}
|
||||||
|
|
||||||
// PushIndentTo
|
// PushIndentTo
|
||||||
// . Pushes an indentation onto the stack, and enqueues the
|
// . Pushes an indentation onto the stack, and enqueues the
|
||||||
// proper token (sequence start or mapping start).
|
// proper token (sequence start or mapping start).
|
||||||
@@ -258,8 +281,9 @@ namespace YAML
|
|||||||
if(InFlowContext())
|
if(InFlowContext())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
IndentMarker indent(column, type);
|
std::auto_ptr<IndentMarker> pIndent(new IndentMarker(column, type));
|
||||||
const IndentMarker& lastIndent = m_indents.top();
|
IndentMarker& indent = *pIndent;
|
||||||
|
const IndentMarker& lastIndent = *m_indents.top();
|
||||||
|
|
||||||
// is this actually an indentation?
|
// is this actually an indentation?
|
||||||
if(indent.column < lastIndent.column)
|
if(indent.column < lastIndent.column)
|
||||||
@@ -268,22 +292,18 @@ namespace YAML
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// push a start token
|
// push a start token
|
||||||
if(type == IndentMarker::SEQ)
|
indent.pStartToken = PushToken(GetStartTokenFor(type));
|
||||||
m_tokens.push(Token(Token::BLOCK_SEQ_START, INPUT.mark()));
|
|
||||||
else if(type == IndentMarker::MAP)
|
|
||||||
m_tokens.push(Token(Token::BLOCK_MAP_START, INPUT.mark()));
|
|
||||||
else
|
|
||||||
assert(false);
|
|
||||||
indent.pStartToken = &m_tokens.back();
|
|
||||||
|
|
||||||
// and then the indent
|
// and then the indent
|
||||||
m_indents.push(indent);
|
m_indents.push(&indent);
|
||||||
return &m_indents.top();
|
m_indentRefs.push_back(pIndent);
|
||||||
|
return &m_indentRefs.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
// PopIndentToHere
|
// PopIndentToHere
|
||||||
// . Pops indentations off the stack until we reach the current indentation level,
|
// . Pops indentations off the stack until we reach the current indentation level,
|
||||||
// and enqueues the proper token each time.
|
// and enqueues the proper token each time.
|
||||||
|
// . Then pops all invalid indentations off.
|
||||||
void Scanner::PopIndentToHere()
|
void Scanner::PopIndentToHere()
|
||||||
{
|
{
|
||||||
// are we in flow?
|
// are we in flow?
|
||||||
@@ -292,14 +312,17 @@ namespace YAML
|
|||||||
|
|
||||||
// now pop away
|
// now pop away
|
||||||
while(!m_indents.empty()) {
|
while(!m_indents.empty()) {
|
||||||
const IndentMarker& indent = m_indents.top();
|
const IndentMarker& indent = *m_indents.top();
|
||||||
if(indent.column < INPUT.column())
|
if(indent.column < INPUT.column())
|
||||||
break;
|
break;
|
||||||
if(indent.column == INPUT.column() && !(indent.type == IndentMarker::SEQ && !Exp::BlockEntry.Matches(INPUT)))
|
if(indent.column == INPUT.column() && !(indent.type == IndentMarker::SEQ && !Exp::BlockEntry().Matches(INPUT)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
PopIndent();
|
PopIndent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while(!m_indents.empty() && m_indents.top()->status == IndentMarker::INVALID)
|
||||||
|
PopIndent();
|
||||||
}
|
}
|
||||||
|
|
||||||
// PopAllIndents
|
// PopAllIndents
|
||||||
@@ -313,7 +336,7 @@ namespace YAML
|
|||||||
|
|
||||||
// now pop away
|
// now pop away
|
||||||
while(!m_indents.empty()) {
|
while(!m_indents.empty()) {
|
||||||
const IndentMarker& indent = m_indents.top();
|
const IndentMarker& indent = *m_indents.top();
|
||||||
if(indent.type == IndentMarker::NONE)
|
if(indent.type == IndentMarker::NONE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -325,17 +348,17 @@ namespace YAML
|
|||||||
// . Pops a single indent, pushing the proper token
|
// . Pops a single indent, pushing the proper token
|
||||||
void Scanner::PopIndent()
|
void Scanner::PopIndent()
|
||||||
{
|
{
|
||||||
IndentMarker indent = m_indents.top();
|
const IndentMarker& indent = *m_indents.top();
|
||||||
IndentMarker::INDENT_TYPE type = indent.type;
|
|
||||||
m_indents.pop();
|
m_indents.pop();
|
||||||
if(!indent.isValid) {
|
|
||||||
|
if(indent.status != IndentMarker::VALID) {
|
||||||
InvalidateSimpleKey();
|
InvalidateSimpleKey();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(type == IndentMarker::SEQ)
|
if(indent.type == IndentMarker::SEQ)
|
||||||
m_tokens.push(Token(Token::BLOCK_SEQ_END, INPUT.mark()));
|
m_tokens.push(Token(Token::BLOCK_SEQ_END, INPUT.mark()));
|
||||||
else if(type == IndentMarker::MAP)
|
else if(indent.type == IndentMarker::MAP)
|
||||||
m_tokens.push(Token(Token::BLOCK_MAP_END, INPUT.mark()));
|
m_tokens.push(Token(Token::BLOCK_MAP_END, INPUT.mark()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,30 +367,7 @@ namespace YAML
|
|||||||
{
|
{
|
||||||
if(m_indents.empty())
|
if(m_indents.empty())
|
||||||
return 0;
|
return 0;
|
||||||
return m_indents.top().column;
|
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
|
// ThrowParserException
|
||||||
@@ -383,9 +383,5 @@ namespace YAML
|
|||||||
}
|
}
|
||||||
throw ParserException(mark, msg);
|
throw ParserException(mark, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scanner::ClearAnchors()
|
|
||||||
{
|
|
||||||
m_anchors.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
#ifndef SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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 <ios>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -10,12 +12,14 @@
|
|||||||
#include <stack>
|
#include <stack>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include "ptr_vector.h"
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
class Node;
|
class Node;
|
||||||
|
class RegEx;
|
||||||
|
|
||||||
class Scanner
|
class Scanner
|
||||||
{
|
{
|
||||||
@@ -28,19 +32,15 @@ namespace YAML
|
|||||||
void pop();
|
void pop();
|
||||||
Token& peek();
|
Token& peek();
|
||||||
|
|
||||||
// anchor management
|
|
||||||
void Save(const std::string& anchor, Node* value);
|
|
||||||
const Node *Retrieve(const std::string& anchor) const;
|
|
||||||
void ClearAnchors();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct IndentMarker {
|
struct IndentMarker {
|
||||||
enum INDENT_TYPE { MAP, SEQ, NONE };
|
enum INDENT_TYPE { MAP, SEQ, NONE };
|
||||||
IndentMarker(int column_, INDENT_TYPE type_): column(column_), type(type_), isValid(true), pStartToken(0) {}
|
enum STATUS { VALID, INVALID, UNKNOWN };
|
||||||
|
IndentMarker(int column_, INDENT_TYPE type_): column(column_), type(type_), status(VALID), pStartToken(0) {}
|
||||||
|
|
||||||
int column;
|
int column;
|
||||||
INDENT_TYPE type;
|
INDENT_TYPE type;
|
||||||
bool isValid;
|
STATUS status;
|
||||||
Token *pStartToken;
|
Token *pStartToken;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -53,11 +53,13 @@ namespace YAML
|
|||||||
void ScanToNextToken();
|
void ScanToNextToken();
|
||||||
void StartStream();
|
void StartStream();
|
||||||
void EndStream();
|
void EndStream();
|
||||||
|
Token *PushToken(Token::TYPE type);
|
||||||
|
|
||||||
bool InFlowContext() const { return !m_flows.empty(); }
|
bool InFlowContext() const { return !m_flows.empty(); }
|
||||||
bool InBlockContext() const { return m_flows.empty(); }
|
bool InBlockContext() const { return m_flows.empty(); }
|
||||||
int GetFlowLevel() const { return m_flows.size(); }
|
int GetFlowLevel() const { return m_flows.size(); }
|
||||||
|
|
||||||
|
Token::TYPE GetStartTokenFor(IndentMarker::INDENT_TYPE type) const;
|
||||||
IndentMarker *PushIndentTo(int column, IndentMarker::INDENT_TYPE type);
|
IndentMarker *PushIndentTo(int column, IndentMarker::INDENT_TYPE type);
|
||||||
void PopIndentToHere();
|
void PopIndentToHere();
|
||||||
void PopAllIndents();
|
void PopAllIndents();
|
||||||
@@ -75,6 +77,7 @@ namespace YAML
|
|||||||
void ThrowParserException(const std::string& msg) const;
|
void ThrowParserException(const std::string& msg) const;
|
||||||
|
|
||||||
bool IsWhitespaceToBeEaten(char ch);
|
bool IsWhitespaceToBeEaten(char ch);
|
||||||
|
const RegEx& GetValueRegex() const;
|
||||||
|
|
||||||
struct SimpleKey {
|
struct SimpleKey {
|
||||||
SimpleKey(const Mark& mark_, int flowLevel_);
|
SimpleKey(const Mark& mark_, int flowLevel_);
|
||||||
@@ -112,16 +115,18 @@ namespace YAML
|
|||||||
Stream INPUT;
|
Stream INPUT;
|
||||||
|
|
||||||
// the output (tokens)
|
// the output (tokens)
|
||||||
std::queue <Token> m_tokens;
|
std::queue<Token> m_tokens;
|
||||||
|
|
||||||
// state info
|
// state info
|
||||||
bool m_startedStream, m_endedStream;
|
bool m_startedStream, m_endedStream;
|
||||||
bool m_simpleKeyAllowed;
|
bool m_simpleKeyAllowed;
|
||||||
std::stack <SimpleKey> m_simpleKeys;
|
bool m_canBeJSONFlow;
|
||||||
std::stack <IndentMarker> m_indents;
|
std::stack<SimpleKey> m_simpleKeys;
|
||||||
std::stack <FLOW_MARKER> m_flows;
|
std::stack<IndentMarker *> m_indents;
|
||||||
std::map <std::string, const Node *> m_anchors;
|
ptr_vector<IndentMarker> m_indentRefs; // for "garbage collection"
|
||||||
|
std::stack<FLOW_MARKER> m_flows;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
#endif // SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
|
|
||||||
|
@@ -1,8 +1,7 @@
|
|||||||
#include "crt.h"
|
|
||||||
#include "scanscalar.h"
|
#include "scanscalar.h"
|
||||||
#include "scanner.h"
|
#include "scanner.h"
|
||||||
#include "exp.h"
|
#include "exp.h"
|
||||||
#include "exceptions.h"
|
#include "yaml-cpp/exceptions.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
@@ -32,12 +31,13 @@ namespace YAML
|
|||||||
// Phase #1: scan until line ending
|
// Phase #1: scan until line ending
|
||||||
|
|
||||||
std::size_t lastNonWhitespaceChar = scalar.size();
|
std::size_t lastNonWhitespaceChar = scalar.size();
|
||||||
while(!params.end.Matches(INPUT) && !Exp::Break.Matches(INPUT)) {
|
bool escapedNewline = false;
|
||||||
|
while(!params.end.Matches(INPUT) && !Exp::Break().Matches(INPUT)) {
|
||||||
if(!INPUT)
|
if(!INPUT)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// document indicator?
|
// document indicator?
|
||||||
if(INPUT.column() == 0 && Exp::DocIndicator.Matches(INPUT)) {
|
if(INPUT.column() == 0 && Exp::DocIndicator().Matches(INPUT)) {
|
||||||
if(params.onDocIndicator == BREAK)
|
if(params.onDocIndicator == BREAK)
|
||||||
break;
|
break;
|
||||||
else if(params.onDocIndicator == THROW)
|
else if(params.onDocIndicator == THROW)
|
||||||
@@ -48,11 +48,12 @@ namespace YAML
|
|||||||
pastOpeningBreak = true;
|
pastOpeningBreak = true;
|
||||||
|
|
||||||
// escaped newline? (only if we're escaping on slash)
|
// escaped newline? (only if we're escaping on slash)
|
||||||
if(params.escape == '\\' && Exp::EscBreak.Matches(INPUT)) {
|
if(params.escape == '\\' && Exp::EscBreak().Matches(INPUT)) {
|
||||||
int n = Exp::EscBreak.Match(INPUT);
|
// eat escape character and get out (but preserve trailing whitespace!)
|
||||||
INPUT.eat(n);
|
INPUT.get();
|
||||||
lastNonWhitespaceChar = scalar.size();
|
lastNonWhitespaceChar = scalar.size();
|
||||||
continue;
|
escapedNewline = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// escape this?
|
// escape this?
|
||||||
@@ -77,7 +78,7 @@ namespace YAML
|
|||||||
}
|
}
|
||||||
|
|
||||||
// doc indicator?
|
// doc indicator?
|
||||||
if(params.onDocIndicator == BREAK && INPUT.column() == 0 && Exp::DocIndicator.Matches(INPUT))
|
if(params.onDocIndicator == BREAK && INPUT.column() == 0 && Exp::DocIndicator().Matches(INPUT))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// are we done via character match?
|
// are we done via character match?
|
||||||
@@ -94,7 +95,7 @@ namespace YAML
|
|||||||
|
|
||||||
// ********************************
|
// ********************************
|
||||||
// Phase #2: eat line ending
|
// Phase #2: eat line ending
|
||||||
n = Exp::Break.Match(INPUT);
|
n = Exp::Break().Match(INPUT);
|
||||||
INPUT.eat(n);
|
INPUT.eat(n);
|
||||||
|
|
||||||
// ********************************
|
// ********************************
|
||||||
@@ -109,7 +110,7 @@ namespace YAML
|
|||||||
params.indent = std::max(params.indent, INPUT.column());
|
params.indent = std::max(params.indent, INPUT.column());
|
||||||
|
|
||||||
// and then the rest of the whitespace
|
// and then the rest of the whitespace
|
||||||
while(Exp::Blank.Matches(INPUT)) {
|
while(Exp::Blank().Matches(INPUT)) {
|
||||||
// we check for tabs that masquerade as indentation
|
// we check for tabs that masquerade as indentation
|
||||||
if(INPUT.peek() == '\t'&& INPUT.column() < params.indent && params.onTabInIndentation == THROW)
|
if(INPUT.peek() == '\t'&& INPUT.column() < params.indent && params.onTabInIndentation == THROW)
|
||||||
throw ParserException(INPUT.mark(), ErrorMsg::TAB_IN_INDENTATION);
|
throw ParserException(INPUT.mark(), ErrorMsg::TAB_IN_INDENTATION);
|
||||||
@@ -121,8 +122,8 @@ namespace YAML
|
|||||||
}
|
}
|
||||||
|
|
||||||
// was this an empty line?
|
// was this an empty line?
|
||||||
bool nextEmptyLine = Exp::Break.Matches(INPUT);
|
bool nextEmptyLine = Exp::Break().Matches(INPUT);
|
||||||
bool nextMoreIndented = Exp::Blank.Matches(INPUT);
|
bool nextMoreIndented = Exp::Blank().Matches(INPUT);
|
||||||
if(params.fold == FOLD_BLOCK && foldedNewlineCount == 0 && nextEmptyLine)
|
if(params.fold == FOLD_BLOCK && foldedNewlineCount == 0 && nextEmptyLine)
|
||||||
foldedNewlineStartedMoreIndented = moreIndented;
|
foldedNewlineStartedMoreIndented = moreIndented;
|
||||||
|
|
||||||
@@ -142,7 +143,7 @@ namespace YAML
|
|||||||
|
|
||||||
if(!nextEmptyLine && foldedNewlineCount > 0) {
|
if(!nextEmptyLine && foldedNewlineCount > 0) {
|
||||||
scalar += std::string(foldedNewlineCount - 1, '\n');
|
scalar += std::string(foldedNewlineCount - 1, '\n');
|
||||||
if(foldedNewlineStartedMoreIndented || nextMoreIndented)
|
if(foldedNewlineStartedMoreIndented || nextMoreIndented | !foundNonEmptyLine)
|
||||||
scalar += "\n";
|
scalar += "\n";
|
||||||
foldedNewlineCount = 0;
|
foldedNewlineCount = 0;
|
||||||
}
|
}
|
||||||
@@ -150,7 +151,7 @@ namespace YAML
|
|||||||
case FOLD_FLOW:
|
case FOLD_FLOW:
|
||||||
if(nextEmptyLine)
|
if(nextEmptyLine)
|
||||||
scalar += "\n";
|
scalar += "\n";
|
||||||
else if(!emptyLine && !nextEmptyLine)
|
else if(!emptyLine && !nextEmptyLine && !escapedNewline)
|
||||||
scalar += " ";
|
scalar += " ";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -174,12 +175,23 @@ namespace YAML
|
|||||||
scalar.erase(pos + 1);
|
scalar.erase(pos + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(params.chomp == STRIP || params.chomp == CLIP) {
|
switch(params.chomp) {
|
||||||
std::size_t pos = scalar.find_last_not_of('\n');
|
case CLIP: {
|
||||||
if(params.chomp == CLIP && pos + 1 < scalar.size())
|
const std::size_t pos = scalar.find_last_not_of('\n');
|
||||||
scalar.erase(pos + 2);
|
if(pos == std::string::npos)
|
||||||
else if(params.chomp == STRIP && pos < scalar.size())
|
scalar.erase();
|
||||||
scalar.erase(pos + 1);
|
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;
|
return scalar;
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
#ifndef SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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 <string>
|
||||||
#include "regex.h"
|
#include "regex.h"
|
||||||
@@ -40,3 +42,4 @@ namespace YAML
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif // SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
#endif // SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
|
|
||||||
|
84
src/scantag.cpp
Normal file
84
src/scantag.cpp
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
#include "scanner.h"
|
||||||
|
#include "regex.h"
|
||||||
|
#include "exp.h"
|
||||||
|
#include "yaml-cpp/exceptions.h"
|
||||||
|
|
||||||
|
namespace YAML
|
||||||
|
{
|
||||||
|
const std::string ScanVerbatimTag(Stream& INPUT)
|
||||||
|
{
|
||||||
|
std::string tag;
|
||||||
|
|
||||||
|
// eat the start character
|
||||||
|
INPUT.get();
|
||||||
|
|
||||||
|
while(INPUT) {
|
||||||
|
if(INPUT.peek() == Keys::VerbatimTagEnd) {
|
||||||
|
// eat the end character
|
||||||
|
INPUT.get();
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
int n = Exp::URI().Match(INPUT);
|
||||||
|
if(n <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
tag += INPUT.get(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw ParserException(INPUT.mark(), ErrorMsg::END_OF_VERBATIM_TAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle)
|
||||||
|
{
|
||||||
|
std::string tag;
|
||||||
|
canBeHandle = true;
|
||||||
|
Mark firstNonWordChar;
|
||||||
|
|
||||||
|
while(INPUT) {
|
||||||
|
if(INPUT.peek() == Keys::Tag) {
|
||||||
|
if(!canBeHandle)
|
||||||
|
throw ParserException(firstNonWordChar, ErrorMsg::CHAR_IN_TAG_HANDLE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int n = 0;
|
||||||
|
if(canBeHandle) {
|
||||||
|
n = Exp::Word().Match(INPUT);
|
||||||
|
if(n <= 0) {
|
||||||
|
canBeHandle = false;
|
||||||
|
firstNonWordChar = INPUT.mark();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!canBeHandle)
|
||||||
|
n = Exp::Tag().Match(INPUT);
|
||||||
|
|
||||||
|
if(n <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
tag += INPUT.get(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string ScanTagSuffix(Stream& INPUT)
|
||||||
|
{
|
||||||
|
std::string tag;
|
||||||
|
|
||||||
|
while(INPUT) {
|
||||||
|
int n = Exp::Tag().Match(INPUT);
|
||||||
|
if(n <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
tag += INPUT.get(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tag.empty())
|
||||||
|
throw ParserException(INPUT.mark(), ErrorMsg::TAG_WITH_NO_SUFFIX);
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
20
src/scantag.h
Normal file
20
src/scantag.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
|
#define SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "stream.h"
|
||||||
|
|
||||||
|
namespace YAML
|
||||||
|
{
|
||||||
|
const std::string ScanVerbatimTag(Stream& INPUT);
|
||||||
|
const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle);
|
||||||
|
const std::string ScanTagSuffix(Stream& INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
|
|
@@ -1,9 +1,10 @@
|
|||||||
#include "crt.h"
|
|
||||||
#include "scanner.h"
|
#include "scanner.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
#include "exceptions.h"
|
#include "yaml-cpp/exceptions.h"
|
||||||
#include "exp.h"
|
#include "exp.h"
|
||||||
#include "scanscalar.h"
|
#include "scanscalar.h"
|
||||||
|
#include "scantag.h"
|
||||||
|
#include "tag.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
@@ -23,36 +24,34 @@ namespace YAML
|
|||||||
PopAllSimpleKeys();
|
PopAllSimpleKeys();
|
||||||
|
|
||||||
m_simpleKeyAllowed = false;
|
m_simpleKeyAllowed = false;
|
||||||
|
m_canBeJSONFlow = false;
|
||||||
|
|
||||||
// store pos and eat indicator
|
// store pos and eat indicator
|
||||||
Mark mark = INPUT.mark();
|
Token token(Token::DIRECTIVE, INPUT.mark());
|
||||||
INPUT.eat(1);
|
INPUT.eat(1);
|
||||||
|
|
||||||
// read name
|
// read name
|
||||||
while(INPUT && !Exp::BlankOrBreak.Matches(INPUT))
|
while(INPUT && !Exp::BlankOrBreak().Matches(INPUT))
|
||||||
name += INPUT.get();
|
token.value += INPUT.get();
|
||||||
|
|
||||||
// read parameters
|
// read parameters
|
||||||
while(1) {
|
while(1) {
|
||||||
// first get rid of whitespace
|
// first get rid of whitespace
|
||||||
while(Exp::Blank.Matches(INPUT))
|
while(Exp::Blank().Matches(INPUT))
|
||||||
INPUT.eat(1);
|
INPUT.eat(1);
|
||||||
|
|
||||||
// break on newline or comment
|
// break on newline or comment
|
||||||
if(!INPUT || Exp::Break.Matches(INPUT) || Exp::Comment.Matches(INPUT))
|
if(!INPUT || Exp::Break().Matches(INPUT) || Exp::Comment().Matches(INPUT))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// now read parameter
|
// now read parameter
|
||||||
std::string param;
|
std::string param;
|
||||||
while(INPUT && !Exp::BlankOrBreak.Matches(INPUT))
|
while(INPUT && !Exp::BlankOrBreak().Matches(INPUT))
|
||||||
param += INPUT.get();
|
param += INPUT.get();
|
||||||
|
|
||||||
params.push_back(param);
|
token.params.push_back(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
Token token(Token::DIRECTIVE, mark);
|
|
||||||
token.value = name;
|
|
||||||
token.params = params;
|
|
||||||
m_tokens.push(token);
|
m_tokens.push(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,6 +61,7 @@ namespace YAML
|
|||||||
PopAllIndents();
|
PopAllIndents();
|
||||||
PopAllSimpleKeys();
|
PopAllSimpleKeys();
|
||||||
m_simpleKeyAllowed = false;
|
m_simpleKeyAllowed = false;
|
||||||
|
m_canBeJSONFlow = false;
|
||||||
|
|
||||||
// eat
|
// eat
|
||||||
Mark mark = INPUT.mark();
|
Mark mark = INPUT.mark();
|
||||||
@@ -75,6 +75,7 @@ namespace YAML
|
|||||||
PopAllIndents();
|
PopAllIndents();
|
||||||
PopAllSimpleKeys();
|
PopAllSimpleKeys();
|
||||||
m_simpleKeyAllowed = false;
|
m_simpleKeyAllowed = false;
|
||||||
|
m_canBeJSONFlow = false;
|
||||||
|
|
||||||
// eat
|
// eat
|
||||||
Mark mark = INPUT.mark();
|
Mark mark = INPUT.mark();
|
||||||
@@ -88,6 +89,7 @@ namespace YAML
|
|||||||
// flows can be simple keys
|
// flows can be simple keys
|
||||||
InsertPotentialSimpleKey();
|
InsertPotentialSimpleKey();
|
||||||
m_simpleKeyAllowed = true;
|
m_simpleKeyAllowed = true;
|
||||||
|
m_canBeJSONFlow = false;
|
||||||
|
|
||||||
// eat
|
// eat
|
||||||
Mark mark = INPUT.mark();
|
Mark mark = INPUT.mark();
|
||||||
@@ -105,10 +107,15 @@ namespace YAML
|
|||||||
throw ParserException(INPUT.mark(), ErrorMsg::FLOW_END);
|
throw ParserException(INPUT.mark(), ErrorMsg::FLOW_END);
|
||||||
|
|
||||||
// we might have a solo entry in the flow context
|
// we might have a solo entry in the flow context
|
||||||
if(VerifySimpleKey())
|
if(InFlowContext()) {
|
||||||
m_tokens.push(Token(Token::VALUE, INPUT.mark()));
|
if(m_flows.top() == FLOW_MAP && VerifySimpleKey())
|
||||||
|
m_tokens.push(Token(Token::VALUE, INPUT.mark()));
|
||||||
|
else if(m_flows.top() == FLOW_SEQ)
|
||||||
|
InvalidateSimpleKey();
|
||||||
|
}
|
||||||
|
|
||||||
m_simpleKeyAllowed = false;
|
m_simpleKeyAllowed = false;
|
||||||
|
m_canBeJSONFlow = true;
|
||||||
|
|
||||||
// eat
|
// eat
|
||||||
Mark mark = INPUT.mark();
|
Mark mark = INPUT.mark();
|
||||||
@@ -127,11 +134,16 @@ namespace YAML
|
|||||||
// FlowEntry
|
// FlowEntry
|
||||||
void Scanner::ScanFlowEntry()
|
void Scanner::ScanFlowEntry()
|
||||||
{
|
{
|
||||||
// we might have a solo entry in the flow context
|
// we might have a solo entry in the flow context
|
||||||
if(VerifySimpleKey())
|
if(InFlowContext()) {
|
||||||
m_tokens.push(Token(Token::VALUE, INPUT.mark()));
|
if(m_flows.top() == FLOW_MAP && VerifySimpleKey())
|
||||||
|
m_tokens.push(Token(Token::VALUE, INPUT.mark()));
|
||||||
|
else if(m_flows.top() == FLOW_SEQ)
|
||||||
|
InvalidateSimpleKey();
|
||||||
|
}
|
||||||
|
|
||||||
m_simpleKeyAllowed = true;
|
m_simpleKeyAllowed = true;
|
||||||
|
m_canBeJSONFlow = false;
|
||||||
|
|
||||||
// eat
|
// eat
|
||||||
Mark mark = INPUT.mark();
|
Mark mark = INPUT.mark();
|
||||||
@@ -152,6 +164,7 @@ namespace YAML
|
|||||||
|
|
||||||
PushIndentTo(INPUT.column(), IndentMarker::SEQ);
|
PushIndentTo(INPUT.column(), IndentMarker::SEQ);
|
||||||
m_simpleKeyAllowed = true;
|
m_simpleKeyAllowed = true;
|
||||||
|
m_canBeJSONFlow = false;
|
||||||
|
|
||||||
// eat
|
// eat
|
||||||
Mark mark = INPUT.mark();
|
Mark mark = INPUT.mark();
|
||||||
@@ -184,6 +197,7 @@ namespace YAML
|
|||||||
{
|
{
|
||||||
// and check that simple key
|
// and check that simple key
|
||||||
bool isSimpleKey = VerifySimpleKey();
|
bool isSimpleKey = VerifySimpleKey();
|
||||||
|
m_canBeJSONFlow = false;
|
||||||
|
|
||||||
if(isSimpleKey) {
|
if(isSimpleKey) {
|
||||||
// can't follow a simple key with another simple key (dunno why, though - it seems fine)
|
// can't follow a simple key with another simple key (dunno why, though - it seems fine)
|
||||||
@@ -216,6 +230,7 @@ namespace YAML
|
|||||||
// insert a potential simple key
|
// insert a potential simple key
|
||||||
InsertPotentialSimpleKey();
|
InsertPotentialSimpleKey();
|
||||||
m_simpleKeyAllowed = false;
|
m_simpleKeyAllowed = false;
|
||||||
|
m_canBeJSONFlow = false;
|
||||||
|
|
||||||
// eat the indicator
|
// eat the indicator
|
||||||
Mark mark = INPUT.mark();
|
Mark mark = INPUT.mark();
|
||||||
@@ -223,7 +238,7 @@ namespace YAML
|
|||||||
alias = (indicator == Keys::Alias);
|
alias = (indicator == Keys::Alias);
|
||||||
|
|
||||||
// now eat the content
|
// now eat the content
|
||||||
while(Exp::AlphaNumeric.Matches(INPUT))
|
while(INPUT && Exp::Anchor().Matches(INPUT))
|
||||||
name += INPUT.get();
|
name += INPUT.get();
|
||||||
|
|
||||||
// we need to have read SOMETHING!
|
// we need to have read SOMETHING!
|
||||||
@@ -231,7 +246,7 @@ namespace YAML
|
|||||||
throw ParserException(INPUT.mark(), alias ? ErrorMsg::ALIAS_NOT_FOUND : ErrorMsg::ANCHOR_NOT_FOUND);
|
throw ParserException(INPUT.mark(), alias ? ErrorMsg::ALIAS_NOT_FOUND : ErrorMsg::ANCHOR_NOT_FOUND);
|
||||||
|
|
||||||
// and needs to end correctly
|
// and needs to end correctly
|
||||||
if(INPUT && !Exp::AnchorEnd.Matches(INPUT))
|
if(INPUT && !Exp::AnchorEnd().Matches(INPUT))
|
||||||
throw ParserException(INPUT.mark(), alias ? ErrorMsg::CHAR_IN_ALIAS : ErrorMsg::CHAR_IN_ANCHOR);
|
throw ParserException(INPUT.mark(), alias ? ErrorMsg::CHAR_IN_ALIAS : ErrorMsg::CHAR_IN_ANCHOR);
|
||||||
|
|
||||||
// and we're done
|
// and we're done
|
||||||
@@ -243,37 +258,40 @@ namespace YAML
|
|||||||
// Tag
|
// Tag
|
||||||
void Scanner::ScanTag()
|
void Scanner::ScanTag()
|
||||||
{
|
{
|
||||||
std::string handle, suffix;
|
|
||||||
|
|
||||||
// insert a potential simple key
|
// insert a potential simple key
|
||||||
InsertPotentialSimpleKey();
|
InsertPotentialSimpleKey();
|
||||||
m_simpleKeyAllowed = false;
|
m_simpleKeyAllowed = false;
|
||||||
|
m_canBeJSONFlow = false;
|
||||||
|
|
||||||
|
Token token(Token::TAG, INPUT.mark());
|
||||||
|
|
||||||
// eat the indicator
|
// eat the indicator
|
||||||
Mark mark = INPUT.mark();
|
INPUT.get();
|
||||||
handle += INPUT.get();
|
|
||||||
|
|
||||||
// read the handle
|
if(INPUT && INPUT.peek() == Keys::VerbatimTagStart){
|
||||||
while(INPUT && INPUT.peek() != Keys::Tag && !Exp::BlankOrBreak.Matches(INPUT))
|
std::string tag = ScanVerbatimTag(INPUT);
|
||||||
handle += INPUT.get();
|
|
||||||
|
|
||||||
// is there a suffix?
|
token.value = tag;
|
||||||
if(INPUT.peek() == Keys::Tag) {
|
token.data = Tag::VERBATIM;
|
||||||
// eat the indicator
|
|
||||||
handle += INPUT.get();
|
|
||||||
|
|
||||||
// then read it
|
|
||||||
while(INPUT && !Exp::BlankOrBreak.Matches(INPUT))
|
|
||||||
suffix += INPUT.get();
|
|
||||||
} else {
|
} else {
|
||||||
// this is a bit weird: we keep just the '!' as the handle and move the rest to the suffix
|
bool canBeHandle;
|
||||||
suffix = handle.substr(1);
|
token.value = ScanTagHandle(INPUT, canBeHandle);
|
||||||
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) {
|
||||||
|
// eat the indicator
|
||||||
|
INPUT.get();
|
||||||
|
token.params.push_back(ScanTagSuffix(INPUT));
|
||||||
|
token.data = Tag::NAMED_HANDLE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Token token(Token::TAG, mark);
|
|
||||||
token.value = handle;
|
|
||||||
token.params.push_back(suffix);
|
|
||||||
m_tokens.push(token);
|
m_tokens.push(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,7 +302,7 @@ namespace YAML
|
|||||||
|
|
||||||
// set up the scanning parameters
|
// set up the scanning parameters
|
||||||
ScanScalarParams params;
|
ScanScalarParams params;
|
||||||
params.end = (InFlowContext() ? Exp::EndScalarInFlow : Exp::EndScalar) || (Exp::BlankOrBreak + Exp::Comment);
|
params.end = (InFlowContext() ? Exp::EndScalarInFlow() : Exp::EndScalar()) || (Exp::BlankOrBreak() + Exp::Comment());
|
||||||
params.eatEnd = false;
|
params.eatEnd = false;
|
||||||
params.indent = (InFlowContext() ? 0 : GetTopIndent() + 1);
|
params.indent = (InFlowContext() ? 0 : GetTopIndent() + 1);
|
||||||
params.fold = FOLD_FLOW;
|
params.fold = FOLD_FLOW;
|
||||||
@@ -302,12 +320,13 @@ namespace YAML
|
|||||||
|
|
||||||
// can have a simple key only if we ended the scalar by starting a new line
|
// can have a simple key only if we ended the scalar by starting a new line
|
||||||
m_simpleKeyAllowed = params.leadingSpaces;
|
m_simpleKeyAllowed = params.leadingSpaces;
|
||||||
|
m_canBeJSONFlow = false;
|
||||||
|
|
||||||
// finally, check and see if we ended on an illegal character
|
// finally, check and see if we ended on an illegal character
|
||||||
//if(Exp::IllegalCharInScalar.Matches(INPUT))
|
//if(Exp::IllegalCharInScalar.Matches(INPUT))
|
||||||
// throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_SCALAR);
|
// throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_SCALAR);
|
||||||
|
|
||||||
Token token(Token::SCALAR, mark);
|
Token token(Token::PLAIN_SCALAR, mark);
|
||||||
token.value = scalar;
|
token.value = scalar;
|
||||||
m_tokens.push(token);
|
m_tokens.push(token);
|
||||||
}
|
}
|
||||||
@@ -323,7 +342,7 @@ namespace YAML
|
|||||||
|
|
||||||
// setup the scanning parameters
|
// setup the scanning parameters
|
||||||
ScanScalarParams params;
|
ScanScalarParams params;
|
||||||
params.end = (single ? RegEx(quote) && !Exp::EscSingleQuote : RegEx(quote));
|
params.end = (single ? RegEx(quote) && !Exp::EscSingleQuote() : RegEx(quote));
|
||||||
params.eatEnd = true;
|
params.eatEnd = true;
|
||||||
params.escape = (single ? '\'' : '\\');
|
params.escape = (single ? '\'' : '\\');
|
||||||
params.indent = 0;
|
params.indent = 0;
|
||||||
@@ -344,8 +363,9 @@ namespace YAML
|
|||||||
// and scan
|
// and scan
|
||||||
scalar = ScanScalar(INPUT, params);
|
scalar = ScanScalar(INPUT, params);
|
||||||
m_simpleKeyAllowed = false;
|
m_simpleKeyAllowed = false;
|
||||||
|
m_canBeJSONFlow = true;
|
||||||
|
|
||||||
Token token(Token::SCALAR, mark);
|
Token token(Token::NON_PLAIN_SCALAR, mark);
|
||||||
token.value = scalar;
|
token.value = scalar;
|
||||||
m_tokens.push(token);
|
m_tokens.push(token);
|
||||||
}
|
}
|
||||||
@@ -369,14 +389,14 @@ namespace YAML
|
|||||||
|
|
||||||
// eat chomping/indentation indicators
|
// eat chomping/indentation indicators
|
||||||
params.chomp = CLIP;
|
params.chomp = CLIP;
|
||||||
int n = Exp::Chomp.Match(INPUT);
|
int n = Exp::Chomp().Match(INPUT);
|
||||||
for(int i=0;i<n;i++) {
|
for(int i=0;i<n;i++) {
|
||||||
char ch = INPUT.get();
|
char ch = INPUT.get();
|
||||||
if(ch == '+')
|
if(ch == '+')
|
||||||
params.chomp = KEEP;
|
params.chomp = KEEP;
|
||||||
else if(ch == '-')
|
else if(ch == '-')
|
||||||
params.chomp = STRIP;
|
params.chomp = STRIP;
|
||||||
else if(Exp::Digit.Matches(ch)) {
|
else if(Exp::Digit().Matches(ch)) {
|
||||||
if(ch == '0')
|
if(ch == '0')
|
||||||
throw ParserException(INPUT.mark(), ErrorMsg::ZERO_INDENT_IN_BLOCK);
|
throw ParserException(INPUT.mark(), ErrorMsg::ZERO_INDENT_IN_BLOCK);
|
||||||
|
|
||||||
@@ -386,16 +406,16 @@ namespace YAML
|
|||||||
}
|
}
|
||||||
|
|
||||||
// now eat whitespace
|
// now eat whitespace
|
||||||
while(Exp::Blank.Matches(INPUT))
|
while(Exp::Blank().Matches(INPUT))
|
||||||
INPUT.eat(1);
|
INPUT.eat(1);
|
||||||
|
|
||||||
// and comments to the end of the line
|
// and comments to the end of the line
|
||||||
if(Exp::Comment.Matches(INPUT))
|
if(Exp::Comment().Matches(INPUT))
|
||||||
while(INPUT && !Exp::Break.Matches(INPUT))
|
while(INPUT && !Exp::Break().Matches(INPUT))
|
||||||
INPUT.eat(1);
|
INPUT.eat(1);
|
||||||
|
|
||||||
// if it's not a line break, then we ran into a bad character inline
|
// if it's not a line break, then we ran into a bad character inline
|
||||||
if(INPUT && !Exp::Break.Matches(INPUT))
|
if(INPUT && !Exp::Break().Matches(INPUT))
|
||||||
throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_BLOCK);
|
throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_BLOCK);
|
||||||
|
|
||||||
// set the initial indentation
|
// set the initial indentation
|
||||||
@@ -410,8 +430,9 @@ namespace YAML
|
|||||||
|
|
||||||
// simple keys always ok after block scalars (since we're gonna start a new line anyways)
|
// simple keys always ok after block scalars (since we're gonna start a new line anyways)
|
||||||
m_simpleKeyAllowed = true;
|
m_simpleKeyAllowed = true;
|
||||||
|
m_canBeJSONFlow = false;
|
||||||
|
|
||||||
Token token(Token::SCALAR, mark);
|
Token token(Token::NON_PLAIN_SCALAR, mark);
|
||||||
token.value = scalar;
|
token.value = scalar;
|
||||||
m_tokens.push(token);
|
m_tokens.push(token);
|
||||||
}
|
}
|
||||||
|
164
src/sequence.cpp
164
src/sequence.cpp
@@ -1,164 +0,0 @@
|
|||||||
#include "crt.h"
|
|
||||||
#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, const 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, const ParserState& state)
|
|
||||||
{
|
|
||||||
// eat start token
|
|
||||||
pScanner->pop();
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sequence::ParseFlow(Scanner *pScanner, const ParserState& state)
|
|
||||||
{
|
|
||||||
// eat start token
|
|
||||||
pScanner->pop();
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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, const 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, const ParserState& state);
|
|
||||||
void ParseFlow(Scanner *pScanner, const 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
|
#ifndef SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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 <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "noncopyable.h"
|
#include "yaml-cpp/noncopyable.h"
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
#include "crt.h"
|
|
||||||
#include "scanner.h"
|
#include "scanner.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
#include "exceptions.h"
|
#include "yaml-cpp/exceptions.h"
|
||||||
#include "exp.h"
|
#include "exp.h"
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
@@ -13,9 +12,11 @@ namespace YAML
|
|||||||
|
|
||||||
void Scanner::SimpleKey::Validate()
|
void Scanner::SimpleKey::Validate()
|
||||||
{
|
{
|
||||||
// Note: pIndent will *not* be garbage here; see below
|
// Note: pIndent will *not* be garbage here;
|
||||||
|
// we "garbage collect" them so we can
|
||||||
|
// always refer to them
|
||||||
if(pIndent)
|
if(pIndent)
|
||||||
pIndent->isValid = true;
|
pIndent->status = IndentMarker::VALID;
|
||||||
if(pMapStart)
|
if(pMapStart)
|
||||||
pMapStart->status = Token::VALID;
|
pMapStart->status = Token::VALID;
|
||||||
if(pKey)
|
if(pKey)
|
||||||
@@ -24,8 +25,8 @@ namespace YAML
|
|||||||
|
|
||||||
void Scanner::SimpleKey::Invalidate()
|
void Scanner::SimpleKey::Invalidate()
|
||||||
{
|
{
|
||||||
// Note: pIndent might be a garbage pointer here, but that's ok
|
if(pIndent)
|
||||||
// An indent will only be popped if the simple key is invalid
|
pIndent->status = IndentMarker::INVALID;
|
||||||
if(pMapStart)
|
if(pMapStart)
|
||||||
pMapStart->status = Token::INVALID;
|
pMapStart->status = Token::INVALID;
|
||||||
if(pKey)
|
if(pKey)
|
||||||
@@ -38,9 +39,6 @@ namespace YAML
|
|||||||
if(!m_simpleKeyAllowed)
|
if(!m_simpleKeyAllowed)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(InFlowContext() && m_flows.top() != FLOW_MAP)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return !ExistsActiveSimpleKey();
|
return !ExistsActiveSimpleKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,11 +65,13 @@ namespace YAML
|
|||||||
SimpleKey key(INPUT.mark(), GetFlowLevel());
|
SimpleKey key(INPUT.mark(), GetFlowLevel());
|
||||||
|
|
||||||
// first add a map start, if necessary
|
// first add a map start, if necessary
|
||||||
key.pIndent = PushIndentTo(INPUT.column(), IndentMarker::MAP);
|
if(InBlockContext()) {
|
||||||
if(key.pIndent) {
|
key.pIndent = PushIndentTo(INPUT.column(), IndentMarker::MAP);
|
||||||
key.pIndent->isValid = false;
|
if(key.pIndent) {
|
||||||
key.pMapStart = key.pIndent->pStartToken;
|
key.pIndent->status = IndentMarker::UNKNOWN;
|
||||||
key.pMapStart->status = Token::UNVERIFIED;
|
key.pMapStart = key.pIndent->pStartToken;
|
||||||
|
key.pMapStart->status = Token::UNVERIFIED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// then add the (now unverified) key
|
// then add the (now unverified) key
|
||||||
@@ -136,3 +136,4 @@ namespace YAML
|
|||||||
m_simpleKeys.pop();
|
m_simpleKeys.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
@@ -1,4 +1,3 @@
|
|||||||
#include "crt.h"
|
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "exp.h"
|
#include "exp.h"
|
||||||
|
13
src/stream.h
13
src/stream.h
@@ -1,16 +1,19 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
#ifndef STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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 <deque>
|
||||||
#include <ios>
|
#include <ios>
|
||||||
#include <string>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
|
@@ -1,10 +1,12 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
#ifndef STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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>
|
#include <cstddef>
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
#ifndef STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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>
|
#include <cstddef>
|
||||||
|
|
||||||
@@ -30,6 +32,11 @@ namespace YAML
|
|||||||
++m_offset;
|
++m_offset;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StringCharSource& operator += (std::size_t offset) {
|
||||||
|
m_offset += offset;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
const char *m_str;
|
const char *m_str;
|
||||||
std::size_t m_size;
|
std::size_t m_size;
|
||||||
|
52
src/tag.cpp
Normal file
52
src/tag.cpp
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#include "tag.h"
|
||||||
|
#include "directives.h"
|
||||||
|
#include "token.h"
|
||||||
|
#include <cassert>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace YAML
|
||||||
|
{
|
||||||
|
Tag::Tag(const Token& token): type(static_cast<TYPE>(token.data))
|
||||||
|
{
|
||||||
|
switch(type) {
|
||||||
|
case VERBATIM:
|
||||||
|
value = token.value;
|
||||||
|
break;
|
||||||
|
case PRIMARY_HANDLE:
|
||||||
|
value = token.value;
|
||||||
|
break;
|
||||||
|
case SECONDARY_HANDLE:
|
||||||
|
value = token.value;
|
||||||
|
break;
|
||||||
|
case NAMED_HANDLE:
|
||||||
|
handle = token.value;
|
||||||
|
value = token.params[0];
|
||||||
|
break;
|
||||||
|
case NON_SPECIFIC:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string Tag::Translate(const Directives& directives)
|
||||||
|
{
|
||||||
|
switch(type) {
|
||||||
|
case VERBATIM:
|
||||||
|
return value;
|
||||||
|
case PRIMARY_HANDLE:
|
||||||
|
return directives.TranslateTagHandle("!") + value;
|
||||||
|
case SECONDARY_HANDLE:
|
||||||
|
return directives.TranslateTagHandle("!!") + value;
|
||||||
|
case NAMED_HANDLE:
|
||||||
|
return directives.TranslateTagHandle("!" + handle + "!") + value;
|
||||||
|
case NON_SPECIFIC:
|
||||||
|
// TODO:
|
||||||
|
return "!";
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
throw std::runtime_error("yaml-cpp: internal error, bad tag type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
28
src/tag.h
Normal file
28
src/tag.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
|
#define TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace YAML
|
||||||
|
{
|
||||||
|
struct Token;
|
||||||
|
struct Directives;
|
||||||
|
|
||||||
|
struct Tag {
|
||||||
|
enum TYPE {
|
||||||
|
VERBATIM, PRIMARY_HANDLE, SECONDARY_HANDLE, NAMED_HANDLE, NON_SPECIFIC
|
||||||
|
};
|
||||||
|
|
||||||
|
Tag(const Token& token);
|
||||||
|
const std::string Translate(const Directives& directives);
|
||||||
|
|
||||||
|
TYPE type;
|
||||||
|
std::string handle, value;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
18
src/token.h
18
src/token.h
@@ -1,11 +1,13 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
#ifndef TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
#define 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 <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -24,6 +26,7 @@ namespace YAML
|
|||||||
"FLOW_MAP_START",
|
"FLOW_MAP_START",
|
||||||
"FLOW_SEQ_END",
|
"FLOW_SEQ_END",
|
||||||
"FLOW_MAP_END",
|
"FLOW_MAP_END",
|
||||||
|
"FLOW_MAP_COMPACT",
|
||||||
"FLOW_ENTRY",
|
"FLOW_ENTRY",
|
||||||
"KEY",
|
"KEY",
|
||||||
"VALUE",
|
"VALUE",
|
||||||
@@ -49,17 +52,19 @@ namespace YAML
|
|||||||
FLOW_MAP_START,
|
FLOW_MAP_START,
|
||||||
FLOW_SEQ_END,
|
FLOW_SEQ_END,
|
||||||
FLOW_MAP_END,
|
FLOW_MAP_END,
|
||||||
|
FLOW_MAP_COMPACT,
|
||||||
FLOW_ENTRY,
|
FLOW_ENTRY,
|
||||||
KEY,
|
KEY,
|
||||||
VALUE,
|
VALUE,
|
||||||
ANCHOR,
|
ANCHOR,
|
||||||
ALIAS,
|
ALIAS,
|
||||||
TAG,
|
TAG,
|
||||||
SCALAR
|
PLAIN_SCALAR,
|
||||||
|
NON_PLAIN_SCALAR
|
||||||
};
|
};
|
||||||
|
|
||||||
// data
|
// data
|
||||||
Token(TYPE type_, const Mark& mark_): status(VALID), type(type_), mark(mark_) {}
|
Token(TYPE type_, const Mark& mark_): status(VALID), type(type_), mark(mark_), data(0) {}
|
||||||
|
|
||||||
friend std::ostream& operator << (std::ostream& out, const Token& token) {
|
friend std::ostream& operator << (std::ostream& out, const Token& token) {
|
||||||
out << TokenNames[token.type] << std::string(": ") << token.value;
|
out << TokenNames[token.type] << std::string(": ") << token.value;
|
||||||
@@ -73,6 +78,7 @@ namespace YAML
|
|||||||
Mark mark;
|
Mark mark;
|
||||||
std::string value;
|
std::string value;
|
||||||
std::vector <std::string> params;
|
std::vector <std::string> params;
|
||||||
|
int data;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user