Compare commits

...

65 Commits

Author SHA1 Message Date
Nekotekina Aux1 c45a06b67c Fix compilation on MSVC 2020-03-09 20:13:58 +03:00
Nekotekina a9ed6daea7 Move throw out of include headers 2020-03-09 20:13:58 +03:00
Néstor Subirón 1bfbd2be4c Allow including yaml-cpp as system headers (#829) 2020-02-29 22:27:16 -06:00
Anton Onishchenko de8253fcb0 Fix storing inf and NaN (#817) 2020-02-14 18:03:21 -06:00
JeffWegher 29dcf92f87 Fix Node::size() after removing node from sequence (#820) 2020-02-14 14:38:58 -06:00
Ted Lyngmo ce056acab7 Add IsNull() check in test after reassignment (#814) 2020-02-07 10:52:43 -06:00
Ted Lyngmo 9ab22ef493 Make SettingChange and StreamCharSourcemove constructors and assignment operators noexcept (#808)
The explicitly defaulted or implemented move constructors and assignment
operators are made "noexcept".

Bugfix:
* src/stream.cpp Stream::Stream() char_traits::int_type intro[4] is
  now aggregate-initialized (to zero) to avoid UB.

Minor changes:
* Using std::isinf() and std::signbit() instead of comparing for
  equality with infinity.
* src/streamcharsource.h: Added #include "stream.h".
* src/stream.h: Forward declaring "class StreamCharSource".
* Some implicit casting changed into static_cast's.

Signed-off-by: Ted Lyngmo <ted@lyncon.se>
2020-02-04 16:58:00 -06:00
Ted Lyngmo 1928bca4a4 Move the YAML_CPP_NOEXCEPT macro to include/yaml-cpp/noexcept.h (#813)
This is in preparation for other patches that will make use of the
macro. The patch also removes #undef:ing the macro after its been
used to not make the header inclusion order critical. Otherwise,
the new header would always have to be the last of the yaml-cpp
headers to be included.
2020-02-04 13:24:37 -06:00
Jesse Beder c9460110e0 Fix reading empty token stack with a node with properties but no scalar.
E.g. `!2`.
2020-01-20 18:16:08 -06:00
Ted Lyngmo 3dca8668b1 Change NULL to nullptr (#805) 2020-01-20 17:14:55 -06:00
Carlos Gomes Martinho 587b24e2ee Use de-facto standard CMake namespace convention (#792)
Change the namespace from yaml::yaml to yaml-cpp::yaml-cpp.
2019-11-29 17:02:21 -06:00
Igor [hyperxor] 5b3e30bfe9 Small readability improvements in Parser
Also add a test for a parser with no data
2019-11-23 13:17:02 -06:00
Igor [hyperxor] 72f699f5ce Remove redundant checks and add more unit tests (#783) 2019-11-04 10:19:02 -06:00
Mike Egger a8ba6a8dca Adapt label postfix to fix build with Visual Studio (#782) 2019-10-31 09:35:12 -05:00
Romain Geissler @ Amadeus 14c87258cd Fix -Wmisleading-indentation warning when using gcc >= 6. (#779)
This happens whenever in a macro you use some "if" block, and don't use curly braces {},
as the macro is expanded on a single line, not on several lines. So just add the missing
curly braces to please gcc.

In file included from /remote/users/mlamesch/CloneFromPlatinum/yamlcpp/osp/Yamlcpp/18-0-0-5/include/yaml-cpp/yaml.h:18,
                 from src/TestYaml.cpp:2:
/remote/users/mlamesch/CloneFromPlatinum/yamlcpp/osp/Yamlcpp/18-0-0-5/include/yaml-cpp/node/convert.h: In static member function static bool YAML::convert<int>::decode(const YAML::Node&, int&):
/remote/users/mlamesch/CloneFromPlatinum/yamlcpp/osp/Yamlcpp/18-0-0-5/include/yaml-cpp/node/convert.h:139:1: error: this if clause does not guard... [-Werror=misleading-indentation]
 YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(int);
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2019-10-23 14:45:27 -05:00
carmeli-tamir f531f8a8c3 Show test output on CI in Travis (#777)
* Showing test output only on failure

* Test commit to see the failed test

* Now making sure that the tests pass with no output
2019-10-16 09:44:33 -05:00
Isabella Muerte 52a1378e48 Default YAML_BUILD_SHARED_LIBS to BUILD_SHARED_LIBS
🐛 Fixes #748 (#770)
2019-10-13 15:50:40 -05:00
Rasmus c9a0077024 Add documentation to readme (#768) 2019-10-11 08:12:48 -05:00
Andy Maloney b650bc8287 Modernize: Use range-based for loops for readability (#762)
Also run clang-format on these files as requested
2019-10-05 14:20:17 -05:00
Fatih YAZICI 21d75fa4cd Fix CMake 3.10 and below compatibility (#763)
Add empty list of sources to add_library and add_executable.
2019-10-04 14:46:18 -05:00
Andy Maloney 848091124d Replace node's YAML_CPP_OPERATOR_BOOL macro with an explicit bool operator (#755) 2019-10-02 14:14:07 -05:00
Andy Maloney 6e87b37034 Modernize: Use "using" instead of "typedef" (#754) 2019-10-02 11:14:49 -05:00
Andy Maloney 0fddd1e5bd Modernization: Use "override" when overriding base class methods (#753) 2019-10-02 09:21:17 -05:00
Andy Maloney 99d95d8edc Pass std::string by const ref (#749) 2019-10-02 08:39:41 -05:00
Andy Maloney a6ed66abca Modernize: Use "default" for destructors and copy constructors (#751) 2019-10-02 08:38:49 -05:00
Andy Maloney e6b3a92e67 Use cassert instead of old assert.h (#750) 2019-10-02 08:37:38 -05:00
Andy Maloney 47d32aadf0 CMake: Remove unused option YAML_APPLE_UNIVERSAL_BIN (#744) 2019-09-27 12:26:35 -05:00
Isabella Muerte 9d7e556ed5 Fix DEBUG_POSTFIX property (#746)
The generator expressions here are actually unnecessary, now that I think about it.

This should fix #745
2019-09-27 12:25:27 -05:00
Ezekiel Warren 62ff351432 Add bazel Support (#724)
Example of how someone might consume yaml-cpp with bazel:

cc_binary(
    name = "example",
    srcs = ["example.cc"],
    deps = ["@com_github_jbeder_yaml_cpp//:yaml-cpp"],
)
2019-09-27 10:11:38 -05:00
Isabella Muerte 5e9cb0128d Refactor CMake to use more modern paradigms (#741)
Remove 2.6-isms
Remove 2.8-isms
Bump CMake minimum version to 3.4

Disable some options when used as a subdirectory

Use `CONFIGURE_DEPENDS` with `file(GLOB)` when possible

Backport CMake 3.15's MSVC_RUNTIME_LIBRARY setting.
Set all compile options as generator expressions.
Set all find-package files to be installed to the correct file.

Remove `export(PACKAGE)`, as this has been deprecated.
Remove fat binary support
Remove manual setting of iPhone settings. These should be set by parent
projects.
Remove use of ExternalProject for a local use
Conditionally remove format target unless clang-format is found
2019-09-27 09:59:53 -05:00
Jesse Beder 9a3624205e Update version to 0.6.3. 2019-09-25 09:56:00 -07:00
Andy Maloney 968e0c1f02 Fix shared lib build with new YAML_BUILD_SHARED_LIBS option (#737) 2019-09-14 21:21:35 -04:00
Andy Maloney b218787b98 Remove extraneous conversion from string -> c_str -> string (#739) 2019-09-14 20:24:17 -04:00
Andy Maloney db0bda7087 Static analysis fix: replace 0 and NULL with nullptr (#738) 2019-09-14 20:23:22 -04:00
Andy Maloney 6cdf363625 CMake: Prefix options with "YAML" and hide platform-specific options (#734)
* CMake: Prefix options with "YAML" and hide platform-specific options

When including yaml-cpp as a subproject, some option names can conflict with other projects.

(1) Make sure the yaml-cpp options are prefixed with YAML
(2) Hide platform-specific options when possible to avoid cluttering the cmake option list

* Update docs for change from BUILD_SHARED_LIBS to YAML_BUILD_SHARED_LIBS
2019-09-10 10:00:07 -07:00
Andy Maloney d638508d33 Set C++ standard options in CMake per-target instead of globally (#735)
Setting CMAKE_CXX_STANDARD and CMAKE_CXX_STANDARD_REQUIRED directly is problematic when including yaml-cpp as a subproject.

The proper way is to set these per-target.
2019-09-10 07:51:13 -07:00
Andy Maloney 90350662c9 Use VERSION on the CMake project (#733)
This sets the other variables:

 https://cmake.org/cmake/help/latest/command/project.html
2019-09-10 07:50:10 -07:00
Jeppe Blicher Tarp e0e01d53c2 Make sure output of NaN, Infinity and -Infinity is identical on all platforms (#717)
Specifically, printing `.nan`, `.inf`, and `-.inf`, respectively, as per the spec section 10.2.1.4.
2019-08-03 21:41:45 -04:00
bedapisl 0122697561 Improve error messages on operator[] or as<> (#656)
Invalid access via operator[] or as<> will now print the offending key, if possible.

For example:

a:
  x: 1
  y: 2

node["a"]["z"].as<int>()

will say that the key "z" was invalid.
2019-04-17 08:44:09 -05:00
Jesse Beder bd7f8c60c8 Disallow moving for the Parser.
It wouldn't have compiled anyways, since the Scanner and Directive objects inside it are incomplete types at the time of the move definitions.
2019-03-24 17:01:14 -05:00
peterchen-cp 82e9571213 Add MSVC Debugger Visualizer config for YAML::Node (#693) 2019-03-24 16:02:09 -05:00
Ted Lyngmo 0d5c57150c Apply formatting/style tweaks to comply with compile time diagnostics for g++ and clang++ (#686)
* Add compilation flags: -Wshadow -Weffc++ -pedantic -pedantic-errors
* Delete implicit copy & move constructors & assignment operators
  in classes with pointer data members.
* An exception to the above: Add default copy & move constructors &
  assignment operators for the Binary class.
* Convert boolean RegEx operators to binary operators.
* Initialize all members in all classes in ctors.
* Let default ctor delegate to the converting ctor in
  Binary and RegEx
* Don't change any tests except regex_test (as a result of the change
  to binary operators).

Note: https://bugzilla.redhat.com/show_bug.cgi?id=1544675 makes
-Weffc++ report a false positive in "include/yaml-cpp/node/impl.h".
2019-03-13 15:18:34 -07:00
caryoscelus eca9cfd648 Add optional OnAnchor method to EventHandler (#530)
ref #110
2019-03-12 15:24:32 -07:00
Olli Wang a2a113c6ff Fix ninja build error. (#677)
NDK now uses ninja for building but yaml-cpp would emit the “ninja: error: build.ninja:326: bad $-escape (literal $ must be written as $$)” error due to syntax error in the generated build.ninja file. Related issue: https://github.com/jbeder/yaml-cpp/issues/630
2019-02-27 14:58:45 -06:00
tt4g 283d06f9f7 Fix warning C4127 on Visual Studio (#672)
Splitting the condition of the if statement containing `constant expression` eliminates warnings in Visual Studio with /W4.
2019-02-13 09:39:59 -06:00
pent0 b87c76a2ef Fix GCC-types flags appended on Clang-cl (#659) 2019-01-06 00:23:52 -06:00
Simon Gene Gottlieb abf941b20d Fix float precision (#649)
The issue is that numbers like
2.01 or 3.01 can not be precisely represented with binary floating point
numbers.

This replaces all occurrences of 'std::numeric_limits<T>::digits10 + 1' with
'std::numeric_limits<T>::max_digits10'.

Background:
Using 'std::numeric_limits<T>::digits10 + 1' is not precise enough.
Converting a 'float' into a 'string' and back to a 'float' will not always
produce the original 'float' value. To guarantee that the 'string'
representation has sufficient precision the value
'std::numeric_limits<T>::max_digits10' has to be used.
2018-12-21 09:05:19 -05:00
Alexander Anokhin b659858b19 Some small changes as a result of using a static analyzer (#643)
* Removed an expression which is always true
* The second expression (ch is space) is removed because the first one contains space 0x20
* nextEmptyLine is always false so it is removed from the expression
2018-11-23 11:12:55 -06:00
Joel Frederico 2443da5224 Don't stomp on build flags (#635)
Let CMake handle the default optimizations for various configurations. We don't need to override them. In fact, overriding them makes it impossible for users to override them themselves.
2018-11-19 09:10:10 -06:00
Lassi Hämäläinen 54fc4dadbb Add YAML_CPP_INSTALL option for disabling install target (#624) (#625)
- Option defaults to ON and setting it to OFF, disables install
  target generation
2018-11-18 11:27:15 -06:00
dand-oss 774f25800e fix up static, so works as DLL (#559)
* fix up static, so works as DLL
2018-09-25 10:12:12 -04:00
Florian Eich ca77ef716e Fix -Wmaybe-uninitialized warning (#600) 2018-09-23 19:40:53 -04:00
Andy Maloney ee99c4151c Fix a warning from -Wshadow (#627)
Variable "it" was shadowed
2018-09-05 23:16:02 -05:00
Stefan Reinhold d0da14404e Fix include for std::isspace, fixes #621 (#622) 2018-09-04 08:34:18 -05:00
Stefan Reinhold 45d9035a33 Skip newlines in binary decoding (Fix #387) (#616)
* Skip newlines in binary decoding
This fixes #387

* Skip all whitespace characters

This also removes spaces and tabs in addition to newlines.
2018-09-03 15:55:45 -05:00
Antony Polukhin b71e672caf Suppress unused variable warning in release builds (#611) 2018-09-03 10:37:47 -05:00
Azamat H. Hackimov 5e79f5eed3 Improvements to CMake buildsystem
Roll-forward of c90c08ccc9 "Revert "Improvements to CMake buildsystem (#563)""

NEW:

* Replace CMAKE_SOURCE_DIR with CMAKE_CURRENT_SOURCE_DIR

Fixes #612 when yaml-cpp is used as a git submodule.

ORIGINAL:

* Move enable_testing() into proper place

* Added CMake's checks for C++11 standards

Raised minimal version of CMake to 3.1, since on old systems there no
decent compilers that supports c++11.

Closes #377.

* Externalize googletest project

Externalize gtest to avoid installation, fixes #539.

* Remove defined cmake_policies

CMP0012 - OLD marked as deprecated for >=cmake-3.1 and will be removed
CMP0015 - does not affect to build process
CMP0042 - already NEW for >=cmake-3.1

Fixes #505

* Fix compiling in Windows MSVC
2018-09-03 10:37:06 -05:00
Jesse Beder c90c08ccc9 Revert "Improvements to CMake buildsystem (#563)"
This reverts commit 3e33bb3166.

The original commit broke the build (#612) when yaml-cpp is used as a git submodule.
2018-08-09 10:05:07 -05:00
Azamat H. Hackimov 3e33bb3166 Improvements to CMake buildsystem (#563)
* Move enable_testing() into proper place

* Added CMake's checks for C++11 standards

Raised minimal version of CMake to 3.1, since on old systems there no
decent compilers that supports c++11.

Closes #377.

* Externalize googletest project

Externalize gtest to avoid installation, fixes #539.

* Remove defined cmake_policies

CMP0012 - OLD marked as deprecated for >=cmake-3.1 and will be removed
CMP0015 - does not affect to build process
CMP0042 - already NEW for >=cmake-3.1

Fixes #505

* Fix compiling in Windows MSVC
2018-08-09 07:11:50 -05:00
Alexander 1698b47b65 Use nullptr instead of 0 or NULL (clang-tidy warns) (#603) 2018-07-02 23:59:04 -05:00
Alexander Karatarakis 0f9a586ca1 Fix _NOEXCEPT not available in VS2017 15.8. Use noexcept for VS2015+ (#597) 2018-06-30 16:23:28 -05:00
Jiao 4fb1c4b92b Enable items to be removed from a sequence (#582) 2018-05-14 08:50:28 -05:00
Patrick Stotko ab5f9259a4 Use target-based include_directories to enable modern CMake usage (#583) 2018-05-05 11:03:13 -05:00
Tanki Zhang 124ae47600 Update the iterator implementation for C++17 (#575)
Fix the compiler error which prevents deriving from std::iterator in C++17
2018-04-10 23:47:23 -05:00
maek f996468a6a Fix UTF-8 code points emitting (#571) 2018-03-24 10:48:39 -05:00
90 changed files with 2259 additions and 1619 deletions
+2
View File
@@ -1 +1,3 @@
build/ build/
/tags
/bazel-*
+5 -3
View File
@@ -14,14 +14,16 @@ before_install:
sudo apt-get install -qq g++-4.7 && export CXX="g++-4.7" CC="gcc-4.7" sudo apt-get install -qq g++-4.7 && export CXX="g++-4.7" CC="gcc-4.7"
fi fi
fi fi
env:
- CTEST_OUTPUT_ON_FAILURE=1
before_script: before_script:
- mkdir build - mkdir build
- cd build - cd build
- cmake .. - cmake ..
- cd ..
script: script:
- make - cmake --build build
- test/run-tests - cmake --build build --target test
matrix: matrix:
exclude: exclude:
- os: linux - os: linux
+14
View File
@@ -0,0 +1,14 @@
cc_library(
name = "yaml-cpp_internal",
visibility = ["//:__subpackages__"],
strip_include_prefix = "src",
hdrs = glob(["src/**/*.h"]),
)
cc_library(
name = "yaml-cpp",
visibility = ["//visibility:public"],
includes = ["include"],
hdrs = glob(["include/**/*.h"]),
srcs = glob(["src/**/*.cpp", "src/**/*.h"]),
)
+129 -333
View File
@@ -1,365 +1,161 @@
### # 3.5 is actually available almost everywhere, but this a good minimum
### CMake settings cmake_minimum_required(VERSION 3.4)
### project(YAML_CPP VERSION 0.6.3 LANGUAGES CXX)
## Due to Mac OSX we need to keep compatibility with CMake 2.6
# see http://www.cmake.org/Wiki/CMake_Policies
cmake_minimum_required(VERSION 2.6)
# see http://www.cmake.org/cmake/help/cmake-2-8-docs.html#policy:CMP0012
if(POLICY CMP0012)
cmake_policy(SET CMP0012 OLD)
endif()
# see http://www.cmake.org/cmake/help/cmake-2-8-docs.html#policy:CMP0015
if(POLICY CMP0015)
cmake_policy(SET CMP0015 OLD)
endif()
# see https://cmake.org/cmake/help/latest/policy/CMP0042.html
if(POLICY CMP0042)
# Enable MACOSX_RPATH by default.
cmake_policy(SET CMP0042 NEW)
endif()
include(CMakePackageConfigHelpers)
include(CMakeDependentOption)
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
include(GNUInstallDirs)
include(CTest)
find_program(YAML_CPP_CLANG_FORMAT_EXE NAMES clang-format)
### option(YAML_CPP_BUILD_CONTRIB "Enable yaml-cpp contrib in library" ON)
### Project settings
###
project(YAML_CPP)
set(YAML_CPP_VERSION_MAJOR "0")
set(YAML_CPP_VERSION_MINOR "6")
set(YAML_CPP_VERSION_PATCH "2")
set(YAML_CPP_VERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}.${YAML_CPP_VERSION_PATCH}")
enable_testing()
###
### Project options
###
## Project stuff
option(YAML_CPP_BUILD_TESTS "Enable testing" ON)
option(YAML_CPP_BUILD_TOOLS "Enable parse tools" ON) option(YAML_CPP_BUILD_TOOLS "Enable parse tools" ON)
option(YAML_CPP_BUILD_CONTRIB "Enable contrib stuff in library" ON) option(YAML_BUILD_SHARED_LIBS "Build yaml-cpp shared library" ${BUILD_SHARED_LIBS})
## Build options cmake_dependent_option(YAML_CPP_BUILD_TESTS
# --> General "Enable yaml-cpp tests" ON
# see http://www.cmake.org/cmake/help/cmake2.6docs.html#variable:BUILD_SHARED_LIBS "BUILD_TESTING;CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
# http://www.cmake.org/cmake/help/cmake2.6docs.html#command:add_library cmake_dependent_option(YAML_CPP_INSTALL
option(BUILD_SHARED_LIBS "Build Shared Libraries" OFF) "Enable generation of yaml-cpp install targets" ON
"CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
cmake_dependent_option(YAML_MSVC_SHARED_RT
"MSVC: Build yaml-cpp with shared runtime libs (/MD)" ON
"MSVC" OFF)
# --> Apple set(yaml-cpp-type STATIC)
option(APPLE_UNIVERSAL_BIN "Apple: Build universal binary" OFF) set(yaml-cpp-label-postfix "static")
if (YAML_BUILD_SHARED_LIBS)
# --> Microsoft Visual C++ set(yaml-cpp-type SHARED)
# see http://msdn.microsoft.com/en-us/library/aa278396(v=VS.60).aspx set(yaml-cpp-label-postfix "shared")
# 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
###
# From http://www.cmake.org/pipermail/cmake/2010-March/035992.html:
# function to collect all the sources from sub-directories
# into a single list
function(add_sources)
get_property(is_defined GLOBAL PROPERTY SRCS_LIST DEFINED)
if(NOT is_defined)
define_property(GLOBAL PROPERTY SRCS_LIST
BRIEF_DOCS "List of source files"
FULL_DOCS "List of all source files in the entire project")
endif()
# make absolute paths
set(SRCS)
foreach(s IN LISTS ARGN)
if(NOT IS_ABSOLUTE "${s}")
get_filename_component(s "${s}" ABSOLUTE)
endif()
list(APPEND SRCS "${s}")
endforeach()
# append to global list
set_property(GLOBAL APPEND PROPERTY SRCS_LIST "${SRCS}")
endfunction(add_sources)
set(header_directory "include/yaml-cpp/")
file(GLOB sources "src/[a-zA-Z]*.cpp")
file(GLOB_RECURSE public_headers "include/yaml-cpp/[a-zA-Z]*.h")
file(GLOB private_headers "src/[a-zA-Z]*.h")
if(YAML_CPP_BUILD_CONTRIB)
file(GLOB contrib_sources "src/contrib/[a-zA-Z]*.cpp")
file(GLOB contrib_public_headers "include/yaml-cpp/contrib/[a-zA-Z]*.h")
file(GLOB contrib_private_headers "src/contrib/[a-zA-Z]*.h")
else()
add_definitions(-DYAML_CPP_NO_CONTRIB)
endif() endif()
set(library_sources set(build-shared $<BOOL:${YAML_BUILD_SHARED_LIBS}>)
${sources} set(build-windows-dll $<AND:$<BOOL:${CMAKE_HOST_WIN32}>,${build-shared}>)
${public_headers} set(not-msvc $<NOT:$<CXX_COMPILER_ID:MSVC>>)
${private_headers}
${contrib_sources}
${contrib_public_headers}
${contrib_private_headers}
)
add_sources(${library_sources})
if(VERBOSE) if (NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
message(STATUS "sources: ${sources}") set(CMAKE_MSVC_RUNTIME_LIBRARY
message(STATUS "public_headers: ${public_headers}") MultiThreaded$<$<CONFIG:Debug>:Debug>$<${build-shared}:DLL>)
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() endif()
include_directories(${YAML_CPP_SOURCE_DIR}/src) set(contrib-pattern "src/contrib/*.cpp")
include_directories(${YAML_CPP_SOURCE_DIR}/include) set(src-pattern "src/*.cpp")
if (CMAKE_VERSION VERSION_GREATER 3.12)
list(INSERT contrib-pattern 0 CONFIGURE_DEPENDS)
list(INSERT src-pattern 0 CONFIGURE_DEPENDS)
###
### General compilation settings
###
set(yaml_c_flags ${CMAKE_C_FLAGS})
set(yaml_cxx_flags ${CMAKE_CXX_FLAGS})
if(BUILD_SHARED_LIBS)
set(LABEL_SUFFIX "shared")
else()
set(LABEL_SUFFIX "static")
endif() endif()
if(APPLE) file(GLOB yaml-cpp-contrib-sources ${contrib-pattern})
if(APPLE_UNIVERSAL_BIN) file(GLOB yaml-cpp-sources ${src-pattern})
set(CMAKE_OSX_ARCHITECTURES ppc;i386)
endif() set(msvc-rt $<TARGET_PROPERTY:MSVC_RUNTIME_LIBRARY>)
set(msvc-rt-mtd-static $<STREQUAL:${msvc-rt},MultiThreadedDebug>)
set(msvc-rt-mt-static $<STREQUAL:${msvc-rt},MultiThreaded>)
set(msvc-rt-mtd-dll $<STREQUAL:${msvc-rt},MultiThreadedDebugDLL>)
set(msvc-rt-mt-dll $<STREQUAL:${msvc-rt},MultiThreadedDLL>)
set(backport-msvc-runtime $<VERSION_LESS:${CMAKE_VERSION},3.15>)
add_library(yaml-cpp ${yaml-cpp-type} "")
add_library(yaml-cpp::yaml-cpp ALIAS yaml-cpp)
set_property(TARGET yaml-cpp
PROPERTY
MSVC_RUNTIME_LIBRARY ${CMAKE_MSVC_RUNTIME_LIBRARY})
set_property(TARGET yaml-cpp
PROPERTY
CXX_STANDARD_REQUIRED ON)
target_include_directories(yaml-cpp
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
PRIVATE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>)
if (NOT DEFINED CMAKE_CXX_STANDARD)
set_target_properties(yaml-cpp
PROPERTIES
CXX_STANDARD 11)
endif() endif()
if(IPHONE) target_compile_options(yaml-cpp
set(CMAKE_OSX_SYSROOT "iphoneos4.2") PRIVATE
set(CMAKE_OSX_ARCHITECTURES "armv6;armv7") $<${not-msvc}:-Wall -Wextra -Wshadow -Weffc++ -Wno-long-long>
endif() $<${not-msvc}:-pedantic -pedantic-errors>
if(WIN32) $<$<AND:${backport-msvc-runtime},${msvc-rt-mtd-static}>:-MTd>
if(BUILD_SHARED_LIBS) $<$<AND:${backport-msvc-runtime},${msvc-rt-mt-static}>:-MT>
add_definitions(-D${PROJECT_NAME}_DLL) # use or build Windows DLL $<$<AND:${backport-msvc-runtime},${msvc-rt-mtd-dll}>:-MDd>
endif() $<$<AND:${backport-msvc-runtime},${msvc-rt-mt-dll}>:-MD>
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "C:/")
endif()
endif()
# GCC or Clang or Intel Compiler specialities # /wd4127 = disable warning C4127 "conditional expression is constant"
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR # http://msdn.microsoft.com/en-us/library/6t66728h.aspx
CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR # /wd4355 = disable warning C4355 "'this' : used in base member initializer list
CMAKE_CXX_COMPILER_ID MATCHES "Intel") # http://msdn.microsoft.com/en-us/library/3c594ae3.aspx
$<$<CXX_COMPILER_ID:MSVC>:/W3 /wd4127 /wd4355>)
### General stuff target_compile_definitions(yaml-cpp
if(WIN32) PRIVATE
set(CMAKE_SHARED_LIBRARY_PREFIX "") # DLLs do not have a "lib" prefix $<${build-windows-dll}:${PROJECT_NAME}_DLL>
set(CMAKE_IMPORT_LIBRARY_PREFIX "") # same for DLL import libs $<$<NOT:$<BOOL:${YAML_CPP_BUILD_CONTRIB}>>:YAML_CPP_NO_CONTRIB>)
set(CMAKE_LINK_DEF_FILE_FLAG "") # CMake workaround (2.8.3)
endif()
### Project stuff target_sources(yaml-cpp
if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) PRIVATE
set(CMAKE_BUILD_TYPE Release) $<$<BOOL:${YAML_CPP_BUILD_CONTRIB}>:${yaml-cpp-contrib-sources}>
endif() ${yaml-cpp-sources})
#
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 "")
#
if(BUILD_SHARED_LIBS)
set(GCC_EXTRA_OPTIONS "${GCC_EXTRA_OPTIONS} -fPIC")
endif()
#
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(yaml_cxx_flags "-Wall ${GCC_EXTRA_OPTIONS} -pedantic -Wno-long-long -std=c++11 ${yaml_cxx_flags}")
### Make specific
if(${CMAKE_BUILD_TOOL} MATCHES make OR ${CMAKE_BUILD_TOOL} MATCHES gmake)
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()
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}}")
set(${var_name} "${${var_name}}" CACHE STRING "" FORCE)
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(yaml_cxx_flags "/W3 /wd4127 /wd4355 ${yaml_cxx_flags}")
endif()
###
### General install settings
###
set(INCLUDE_INSTALL_ROOT_DIR include)
set(INCLUDE_INSTALL_DIR ${INCLUDE_INSTALL_ROOT_DIR}/yaml-cpp)
set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}")
set(_INSTALL_DESTINATIONS
RUNTIME DESTINATION bin
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
)
###
### Library
###
add_library(yaml-cpp ${library_sources})
set_target_properties(yaml-cpp PROPERTIES
COMPILE_FLAGS "${yaml_c_flags} ${yaml_cxx_flags}"
)
set_target_properties(yaml-cpp PROPERTIES set_target_properties(yaml-cpp PROPERTIES
VERSION "${YAML_CPP_VERSION}" VERSION "${PROJECT_VERSION}"
SOVERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}" SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}"
PROJECT_LABEL "yaml-cpp ${LABEL_SUFFIX}" PROJECT_LABEL "yaml-cpp ${yaml-cpp-label-postfix}"
) DEBUG_POSTFIX d)
if(IPHONE) configure_package_config_file(
set_target_properties(yaml-cpp PROPERTIES "${PROJECT_SOURCE_DIR}/yaml-cpp-config.cmake.in"
XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "3.0" "${PROJECT_BINARY_DIR}/yaml-cpp-config.cmake"
) INSTALL_DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/yaml-cpp")
write_basic_package_version_file(
"${PROJECT_BINARY_DIR}/yaml-cpp-config-version.cmake"
COMPATIBILITY AnyNewerVersion)
configure_file(yaml-cpp.pc.in yaml-cpp.pc @ONLY)
if (YAML_CPP_INSTALL)
install(TARGETS yaml-cpp
EXPORT yaml-cpp-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN "*.h")
install(EXPORT yaml-cpp-targets
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/yaml-cpp")
install(FILES
"${PROJECT_BINARY_DIR}/yaml-cpp-config.cmake"
"${PROJECT_BINARY_DIR}/yaml-cpp-config-version.cmake"
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/yaml-cpp")
install(FILES "${PROJECT_BINARY_DIR}/yaml-cpp.pc"
DESTINATION ${CMAKE_INSTALL_DATADIR}/pkgconfig)
endif() 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 EXPORT yaml-cpp-targets ${_INSTALL_DESTINATIONS})
install(
DIRECTORY ${header_directory}
DESTINATION ${INCLUDE_INSTALL_DIR}
FILES_MATCHING PATTERN "*.h"
)
export(
TARGETS yaml-cpp
FILE "${PROJECT_BINARY_DIR}/yaml-cpp-targets.cmake")
export(PACKAGE yaml-cpp)
set(EXPORT_TARGETS yaml-cpp CACHE INTERNAL "export targets")
set(CONFIG_INCLUDE_DIRS "${YAML_CPP_SOURCE_DIR}/include")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/yaml-cpp-config.cmake.in
"${PROJECT_BINARY_DIR}/yaml-cpp-config.cmake" @ONLY)
if(WIN32 AND NOT CYGWIN)
set(INSTALL_CMAKE_DIR CMake)
else()
set(INSTALL_CMAKE_DIR ${LIB_INSTALL_DIR}/cmake/yaml-cpp)
endif()
file(RELATIVE_PATH REL_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}/${INSTALL_CMAKE_DIR}" "${CMAKE_INSTALL_PREFIX}/${INCLUDE_INSTALL_ROOT_DIR}")
set(CONFIG_INCLUDE_DIRS "\${YAML_CPP_CMAKE_DIR}/${REL_INCLUDE_DIR}")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/yaml-cpp-config.cmake.in
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/yaml-cpp-config.cmake" @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/yaml-cpp-config-version.cmake.in
"${PROJECT_BINARY_DIR}/yaml-cpp-config-version.cmake" @ONLY)
install(FILES
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/yaml-cpp-config.cmake"
"${PROJECT_BINARY_DIR}/yaml-cpp-config-version.cmake"
DESTINATION "${INSTALL_CMAKE_DIR}" COMPONENT dev)
install(EXPORT yaml-cpp-targets DESTINATION ${INSTALL_CMAKE_DIR})
if(UNIX)
set(PC_FILE ${CMAKE_BINARY_DIR}/yaml-cpp.pc)
configure_file("yaml-cpp.pc.cmake" ${PC_FILE} @ONLY)
install(FILES ${PC_FILE} DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
endif()
###
### Extras
###
if(YAML_CPP_BUILD_TESTS) if(YAML_CPP_BUILD_TESTS)
add_subdirectory(test) add_subdirectory(test)
endif() endif()
if(YAML_CPP_BUILD_TOOLS) if(YAML_CPP_BUILD_TOOLS)
add_subdirectory(util) add_subdirectory(util)
endif() endif()
### Formatting if (YAML_CPP_CLANG_FORMAT_EXE)
get_property(all_sources GLOBAL PROPERTY SRCS_LIST) add_custom_target(format
add_custom_target(format COMMAND clang-format --style=file -i $<TARGET_PROPERTY:yaml-cpp,SOURCES>
COMMAND clang-format --style=file -i ${all_sources} COMMENT "Running clang-format"
COMMENT "Running clang-format" VERBATIM)
VERBATIM) endif()
+6 -2
View File
@@ -26,7 +26,7 @@ cd build
3. Run CMake. The basic syntax is: 3. Run CMake. The basic syntax is:
``` ```
cmake [-G generator] [-DBUILD_SHARED_LIBS=ON|OFF] .. cmake [-G generator] [-DYAML_BUILD_SHARED_LIBS=ON|OFF] ..
``` ```
* The `generator` is whatever type of build system you'd like to use. To see a full list of generators on your platform, just run `cmake` (with no arguments). For example: * The `generator` is whatever type of build system you'd like to use. To see a full list of generators on your platform, just run `cmake` (with no arguments). For example:
@@ -34,7 +34,7 @@ cmake [-G generator] [-DBUILD_SHARED_LIBS=ON|OFF] ..
* On OS X, you might use "Xcode" to generate an Xcode project * On OS X, you might use "Xcode" to generate an Xcode project
* On a UNIX-y system, simply omit the option to generate a makefile * On a UNIX-y system, simply omit the option to generate a makefile
* yaml-cpp defaults to building a static library, but you may build a shared library by specifying `-DBUILD_SHARED_LIBS=ON`. * yaml-cpp defaults to building a static library, but you may build a shared library by specifying `-DYAML_BUILD_SHARED_LIBS=ON`.
* For more options on customizing the build, see the [CMakeLists.txt](https://github.com/jbeder/yaml-cpp/blob/master/CMakeLists.txt) file. * For more options on customizing the build, see the [CMakeLists.txt](https://github.com/jbeder/yaml-cpp/blob/master/CMakeLists.txt) file.
@@ -49,3 +49,7 @@ cmake [-G generator] [-DBUILD_SHARED_LIBS=ON|OFF] ..
[yaml-cpp 0.3.0](https://github.com/jbeder/yaml-cpp/releases/tag/release-0.3.0) is still available if you want the old API. [yaml-cpp 0.3.0](https://github.com/jbeder/yaml-cpp/releases/tag/release-0.3.0) is still available if you want the old API.
**The old API will continue to be supported, and will still receive bugfixes!** The 0.3.x and 0.4.x versions will be old API releases, and 0.5.x and above will all be new API releases. **The old API will continue to be supported, and will still receive bugfixes!** The 0.3.x and 0.4.x versions will be old API releases, and 0.5.x and above will all be new API releases.
# API Documentation
The autogenerated API reference is hosted on [CodeDocs](https://codedocs.xyz/jbeder/yaml-cpp/index.html)
+10
View File
@@ -0,0 +1,10 @@
workspace(name = "com_github_jbeder_yaml_cpp")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "com_google_googletest",
strip_prefix = "googletest-release-1.8.1",
url = "https://github.com/google/googletest/archive/release-1.8.1.tar.gz",
sha256 = "9bf1fe5182a604b4135edc1a425ae356c9ad15e9b23f9f12a02e80184c3a249c",
)
+1 -1
View File
@@ -10,7 +10,7 @@
#include <cstddef> #include <cstddef>
namespace YAML { namespace YAML {
typedef std::size_t anchor_t; using anchor_t = std::size_t;
const anchor_t NullAnchor = 0; const anchor_t NullAnchor = 0;
} }
+8 -4
View File
@@ -19,9 +19,13 @@ YAML_CPP_API std::vector<unsigned char> DecodeBase64(const std::string &input);
class YAML_CPP_API Binary { class YAML_CPP_API Binary {
public: public:
Binary() : m_unownedData(0), m_unownedSize(0) {}
Binary(const unsigned char *data_, std::size_t size_) Binary(const unsigned char *data_, std::size_t size_)
: m_unownedData(data_), m_unownedSize(size_) {} : m_data{}, m_unownedData(data_), m_unownedSize(size_) {}
Binary() : Binary(nullptr, 0) {}
Binary(const Binary &) = default;
Binary(Binary &&) = default;
Binary &operator=(const Binary &) = default;
Binary &operator=(Binary &&) = default;
bool owned() const { return !m_unownedData; } bool owned() const { return !m_unownedData; }
std::size_t size() const { return owned() ? m_data.size() : m_unownedSize; } std::size_t size() const { return owned() ? m_data.size() : m_unownedSize; }
@@ -35,7 +39,7 @@ class YAML_CPP_API Binary {
rhs.clear(); rhs.clear();
rhs.resize(m_unownedSize); rhs.resize(m_unownedSize);
std::copy(m_unownedData, m_unownedData + m_unownedSize, rhs.begin()); std::copy(m_unownedData, m_unownedData + m_unownedSize, rhs.begin());
m_unownedData = 0; m_unownedData = nullptr;
m_unownedSize = 0; m_unownedSize = 0;
} else { } else {
m_data.swap(rhs); m_data.swap(rhs);
@@ -62,6 +66,6 @@ class YAML_CPP_API Binary {
const unsigned char *m_unownedData; const unsigned char *m_unownedData;
std::size_t m_unownedSize; std::size_t m_unownedSize;
}; };
} } // namespace YAML
#endif // BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+2 -1
View File
@@ -22,6 +22,7 @@ namespace YAML {
template <class T> template <class T>
class AnchorDict { class AnchorDict {
public: public:
AnchorDict() : m_data{} {}
void Register(anchor_t anchor, T value) { void Register(anchor_t anchor, T value) {
if (anchor > m_data.size()) { if (anchor > m_data.size()) {
m_data.resize(anchor); m_data.resize(anchor);
@@ -34,6 +35,6 @@ class AnchorDict {
private: private:
std::vector<T> m_data; std::vector<T> m_data;
}; };
} } // namespace YAML
#endif // ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+4 -4
View File
@@ -15,7 +15,7 @@ class Parser;
// GraphBuilderInterface // GraphBuilderInterface
// . Abstraction of node creation // . Abstraction of node creation
// . pParentNode is always NULL or the return value of one of the NewXXX() // . pParentNode is always nullptr or the return value of one of the NewXXX()
// functions. // functions.
class GraphBuilderInterface { class GraphBuilderInterface {
public: public:
@@ -73,9 +73,9 @@ class GraphBuilder : public GraphBuilderInterface {
typedef typename Impl::Map Map; typedef typename Impl::Map Map;
GraphBuilder(Impl &impl) : m_impl(impl) { GraphBuilder(Impl &impl) : m_impl(impl) {
Map *pMap = NULL; Map *pMap = nullptr;
Sequence *pSeq = NULL; Sequence *pSeq = nullptr;
Node *pNode = NULL; Node *pNode = nullptr;
// Type consistency checks // Type consistency checks
pNode = pMap; pNode = pMap;
+12 -12
View File
@@ -24,21 +24,21 @@ class EmitFromEvents : public EventHandler {
public: public:
EmitFromEvents(Emitter& emitter); EmitFromEvents(Emitter& emitter);
virtual void OnDocumentStart(const Mark& mark); void OnDocumentStart(const Mark& mark) override;
virtual void OnDocumentEnd(); void OnDocumentEnd() override;
virtual void OnNull(const Mark& mark, anchor_t anchor); void OnNull(const Mark& mark, anchor_t anchor) override;
virtual void OnAlias(const Mark& mark, anchor_t anchor); void OnAlias(const Mark& mark, anchor_t anchor) override;
virtual void OnScalar(const Mark& mark, const std::string& tag, void OnScalar(const Mark& mark, const std::string& tag,
anchor_t anchor, const std::string& value); anchor_t anchor, const std::string& value) override;
virtual void OnSequenceStart(const Mark& mark, const std::string& tag, void OnSequenceStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style); anchor_t anchor, EmitterStyle::value style) override;
virtual void OnSequenceEnd(); void OnSequenceEnd() override;
virtual void OnMapStart(const Mark& mark, const std::string& tag, void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style); anchor_t anchor, EmitterStyle::value style) override;
virtual void OnMapEnd(); void OnMapEnd() override;
private: private:
void BeginNode(); void BeginNode();
+28 -4
View File
@@ -7,16 +7,18 @@
#pragma once #pragma once
#endif #endif
#include <cmath>
#include <cstddef> #include <cstddef>
#include <limits>
#include <memory> #include <memory>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <type_traits>
#include "yaml-cpp/binary.h" #include "yaml-cpp/binary.h"
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/emitterdef.h" #include "yaml-cpp/emitterdef.h"
#include "yaml-cpp/emittermanip.h" #include "yaml-cpp/emittermanip.h"
#include "yaml-cpp/noncopyable.h"
#include "yaml-cpp/null.h" #include "yaml-cpp/null.h"
#include "yaml-cpp/ostream_wrapper.h" #include "yaml-cpp/ostream_wrapper.h"
@@ -28,10 +30,12 @@ struct _Null;
namespace YAML { namespace YAML {
class EmitterState; class EmitterState;
class YAML_CPP_API Emitter : private noncopyable { class YAML_CPP_API Emitter {
public: public:
Emitter(); Emitter();
explicit Emitter(std::ostream& stream); explicit Emitter(std::ostream& stream);
Emitter(const Emitter&) = delete;
Emitter& operator=(const Emitter&) = delete;
~Emitter(); ~Emitter();
// output // output
@@ -152,7 +156,27 @@ inline Emitter& Emitter::WriteStreamable(T value) {
std::stringstream stream; std::stringstream stream;
SetStreamablePrecision<T>(stream); SetStreamablePrecision<T>(stream);
stream << value;
bool special = false;
if (std::is_floating_point<T>::value) {
if ((std::numeric_limits<T>::has_quiet_NaN ||
std::numeric_limits<T>::has_signaling_NaN) &&
std::isnan(value)) {
special = true;
stream << ".nan";
} else if (std::numeric_limits<T>::has_infinity && std::isinf(value)) {
special = true;
if (std::signbit(value)) {
stream << "-.inf";
} else {
stream << ".inf";
}
}
}
if (!special) {
stream << value;
}
m_stream << stream.str(); m_stream << stream.str();
StartedScalar(); StartedScalar();
@@ -249,6 +273,6 @@ inline Emitter& operator<<(Emitter& emitter, _Indent indent) {
inline Emitter& operator<<(Emitter& emitter, _Precision precision) { inline Emitter& operator<<(Emitter& emitter, _Precision precision) {
return emitter.SetLocalPrecision(precision); return emitter.SetLocalPrecision(precision);
} }
} } // namespace YAML
#endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+6 -6
View File
@@ -74,14 +74,14 @@ struct _Alias {
std::string content; std::string content;
}; };
inline _Alias Alias(const std::string content) { return _Alias(content); } inline _Alias Alias(const std::string& content) { return _Alias(content); }
struct _Anchor { struct _Anchor {
_Anchor(const std::string& content_) : content(content_) {} _Anchor(const std::string& content_) : content(content_) {}
std::string content; std::string content;
}; };
inline _Anchor Anchor(const std::string content) { return _Anchor(content); } inline _Anchor Anchor(const std::string& content) { return _Anchor(content); }
struct _Tag { struct _Tag {
struct Type { struct Type {
@@ -96,11 +96,11 @@ struct _Tag {
Type::value type; Type::value type;
}; };
inline _Tag VerbatimTag(const std::string content) { inline _Tag VerbatimTag(const std::string& content) {
return _Tag("", content, _Tag::Type::Verbatim); return _Tag("", content, _Tag::Type::Verbatim);
} }
inline _Tag LocalTag(const std::string content) { inline _Tag LocalTag(const std::string& content) {
return _Tag("", content, _Tag::Type::PrimaryHandle); return _Tag("", content, _Tag::Type::PrimaryHandle);
} }
@@ -108,7 +108,7 @@ inline _Tag LocalTag(const std::string& prefix, const std::string content) {
return _Tag(prefix, content, _Tag::Type::NamedHandle); return _Tag(prefix, content, _Tag::Type::NamedHandle);
} }
inline _Tag SecondaryTag(const std::string content) { inline _Tag SecondaryTag(const std::string& content) {
return _Tag("", content, _Tag::Type::NamedHandle); return _Tag("", content, _Tag::Type::NamedHandle);
} }
@@ -117,7 +117,7 @@ struct _Comment {
std::string content; std::string content;
}; };
inline _Comment Comment(const std::string content) { return _Comment(content); } inline _Comment Comment(const std::string& content) { return _Comment(content); }
struct _Precision { struct _Precision {
_Precision(int floatPrecision_, int doublePrecision_) _Precision(int floatPrecision_, int doublePrecision_)
+7 -2
View File
@@ -17,7 +17,7 @@ struct Mark;
class EventHandler { class EventHandler {
public: public:
virtual ~EventHandler() {} virtual ~EventHandler() = default;
virtual void OnDocumentStart(const Mark& mark) = 0; virtual void OnDocumentStart(const Mark& mark) = 0;
virtual void OnDocumentEnd() = 0; virtual void OnDocumentEnd() = 0;
@@ -34,7 +34,12 @@ class EventHandler {
virtual void OnMapStart(const Mark& mark, const std::string& tag, virtual void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style) = 0; anchor_t anchor, EmitterStyle::value style) = 0;
virtual void OnMapEnd() = 0; virtual void OnMapEnd() = 0;
virtual void OnAnchor(const Mark& /*mark*/,
const std::string& /*anchor_name*/) {
// empty default implementation for compatibility
}
}; };
} } // namespace YAML
#endif // EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+52 -29
View File
@@ -8,19 +8,12 @@
#endif #endif
#include "yaml-cpp/mark.h" #include "yaml-cpp/mark.h"
#include "yaml-cpp/noexcept.h"
#include "yaml-cpp/traits.h" #include "yaml-cpp/traits.h"
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
// This is here for compatibility with older versions of Visual Studio
// which don't support noexcept
#ifdef _MSC_VER
#define YAML_CPP_NOEXCEPT _NOEXCEPT
#else
#define YAML_CPP_NOEXCEPT noexcept
#endif
namespace YAML { namespace YAML {
// error messages // error messages
namespace ErrorMsg { namespace ErrorMsg {
@@ -114,13 +107,42 @@ inline const std::string KEY_NOT_FOUND_WITH_KEY(
stream << KEY_NOT_FOUND << ": " << key; stream << KEY_NOT_FOUND << ": " << key;
return stream.str(); return stream.str();
} }
template <typename T>
inline const std::string BAD_SUBSCRIPT_WITH_KEY(
const T&, typename disable_if<is_numeric<T>>::type* = nullptr) {
return BAD_SUBSCRIPT;
}
inline const std::string BAD_SUBSCRIPT_WITH_KEY(const std::string& key) {
std::stringstream stream;
stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")";
return stream.str();
}
template <typename T>
inline const std::string BAD_SUBSCRIPT_WITH_KEY(
const T& key, typename enable_if<is_numeric<T>>::type* = nullptr) {
std::stringstream stream;
stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")";
return stream.str();
}
inline const std::string INVALID_NODE_WITH_KEY(const std::string& key) {
std::stringstream stream;
if (key.empty()) {
return INVALID_NODE;
}
stream << "invalid node; first invalid key: \"" << key << "\"";
return stream.str();
}
} }
class YAML_CPP_API Exception : public std::runtime_error { class YAML_CPP_API Exception : public std::runtime_error {
public: public:
Exception(const Mark& mark_, const std::string& msg_) Exception(const Mark& mark_, const std::string& msg_)
: std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {} : std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {}
virtual ~Exception() YAML_CPP_NOEXCEPT; ~Exception() YAML_CPP_NOEXCEPT override;
Exception(const Exception&) = default; Exception(const Exception&) = default;
@@ -131,7 +153,7 @@ class YAML_CPP_API Exception : public std::runtime_error {
static const std::string build_what(const Mark& mark, static const std::string build_what(const Mark& mark,
const std::string& msg) { const std::string& msg) {
if (mark.is_null()) { if (mark.is_null()) {
return msg.c_str(); return msg;
} }
std::stringstream output; std::stringstream output;
@@ -146,7 +168,7 @@ class YAML_CPP_API ParserException : public Exception {
ParserException(const Mark& mark_, const std::string& msg_) ParserException(const Mark& mark_, const std::string& msg_)
: Exception(mark_, msg_) {} : Exception(mark_, msg_) {}
ParserException(const ParserException&) = default; ParserException(const ParserException&) = default;
virtual ~ParserException() YAML_CPP_NOEXCEPT; ~ParserException() YAML_CPP_NOEXCEPT override;
}; };
class YAML_CPP_API RepresentationException : public Exception { class YAML_CPP_API RepresentationException : public Exception {
@@ -154,7 +176,7 @@ class YAML_CPP_API RepresentationException : public Exception {
RepresentationException(const Mark& mark_, const std::string& msg_) RepresentationException(const Mark& mark_, const std::string& msg_)
: Exception(mark_, msg_) {} : Exception(mark_, msg_) {}
RepresentationException(const RepresentationException&) = default; RepresentationException(const RepresentationException&) = default;
virtual ~RepresentationException() YAML_CPP_NOEXCEPT; ~RepresentationException() YAML_CPP_NOEXCEPT override;
}; };
// representation exceptions // representation exceptions
@@ -163,7 +185,7 @@ class YAML_CPP_API InvalidScalar : public RepresentationException {
InvalidScalar(const Mark& mark_) InvalidScalar(const Mark& mark_)
: RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {} : RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {}
InvalidScalar(const InvalidScalar&) = default; InvalidScalar(const InvalidScalar&) = default;
virtual ~InvalidScalar() YAML_CPP_NOEXCEPT; ~InvalidScalar() YAML_CPP_NOEXCEPT override;
}; };
class YAML_CPP_API KeyNotFound : public RepresentationException { class YAML_CPP_API KeyNotFound : public RepresentationException {
@@ -173,7 +195,7 @@ class YAML_CPP_API KeyNotFound : public RepresentationException {
: RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) { : RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) {
} }
KeyNotFound(const KeyNotFound&) = default; KeyNotFound(const KeyNotFound&) = default;
virtual ~KeyNotFound() YAML_CPP_NOEXCEPT; ~KeyNotFound() YAML_CPP_NOEXCEPT override;
}; };
template <typename T> template <typename T>
@@ -181,7 +203,7 @@ class YAML_CPP_API TypedKeyNotFound : public KeyNotFound {
public: public:
TypedKeyNotFound(const Mark& mark_, const T& key_) TypedKeyNotFound(const Mark& mark_, const T& key_)
: KeyNotFound(mark_, key_), key(key_) {} : KeyNotFound(mark_, key_), key(key_) {}
virtual ~TypedKeyNotFound() YAML_CPP_NOEXCEPT {} ~TypedKeyNotFound() YAML_CPP_NOEXCEPT override = default;
T key; T key;
}; };
@@ -194,10 +216,11 @@ inline TypedKeyNotFound<T> MakeTypedKeyNotFound(const Mark& mark,
class YAML_CPP_API InvalidNode : public RepresentationException { class YAML_CPP_API InvalidNode : public RepresentationException {
public: public:
InvalidNode() InvalidNode(const std::string& key)
: RepresentationException(Mark::null_mark(), ErrorMsg::INVALID_NODE) {} : RepresentationException(Mark::null_mark(),
ErrorMsg::INVALID_NODE_WITH_KEY(key)) {}
InvalidNode(const InvalidNode&) = default; InvalidNode(const InvalidNode&) = default;
virtual ~InvalidNode() YAML_CPP_NOEXCEPT; ~InvalidNode() YAML_CPP_NOEXCEPT override;
}; };
class YAML_CPP_API BadConversion : public RepresentationException { class YAML_CPP_API BadConversion : public RepresentationException {
@@ -205,7 +228,7 @@ class YAML_CPP_API BadConversion : public RepresentationException {
explicit BadConversion(const Mark& mark_) explicit BadConversion(const Mark& mark_)
: RepresentationException(mark_, ErrorMsg::BAD_CONVERSION) {} : RepresentationException(mark_, ErrorMsg::BAD_CONVERSION) {}
BadConversion(const BadConversion&) = default; BadConversion(const BadConversion&) = default;
virtual ~BadConversion() YAML_CPP_NOEXCEPT; ~BadConversion() YAML_CPP_NOEXCEPT override;
}; };
template <typename T> template <typename T>
@@ -219,15 +242,17 @@ class YAML_CPP_API BadDereference : public RepresentationException {
BadDereference() BadDereference()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_DEREFERENCE) {} : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_DEREFERENCE) {}
BadDereference(const BadDereference&) = default; BadDereference(const BadDereference&) = default;
virtual ~BadDereference() YAML_CPP_NOEXCEPT; ~BadDereference() YAML_CPP_NOEXCEPT override;
}; };
class YAML_CPP_API BadSubscript : public RepresentationException { class YAML_CPP_API BadSubscript : public RepresentationException {
public: public:
BadSubscript() template <typename Key>
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_SUBSCRIPT) {} BadSubscript(const Key& key)
: RepresentationException(Mark::null_mark(),
ErrorMsg::BAD_SUBSCRIPT_WITH_KEY(key)) {}
BadSubscript(const BadSubscript&) = default; BadSubscript(const BadSubscript&) = default;
virtual ~BadSubscript() YAML_CPP_NOEXCEPT; ~BadSubscript() YAML_CPP_NOEXCEPT override;
}; };
class YAML_CPP_API BadPushback : public RepresentationException { class YAML_CPP_API BadPushback : public RepresentationException {
@@ -235,7 +260,7 @@ class YAML_CPP_API BadPushback : public RepresentationException {
BadPushback() BadPushback()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_PUSHBACK) {} : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_PUSHBACK) {}
BadPushback(const BadPushback&) = default; BadPushback(const BadPushback&) = default;
virtual ~BadPushback() YAML_CPP_NOEXCEPT; ~BadPushback() YAML_CPP_NOEXCEPT override;
}; };
class YAML_CPP_API BadInsert : public RepresentationException { class YAML_CPP_API BadInsert : public RepresentationException {
@@ -243,7 +268,7 @@ class YAML_CPP_API BadInsert : public RepresentationException {
BadInsert() BadInsert()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_INSERT) {} : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_INSERT) {}
BadInsert(const BadInsert&) = default; BadInsert(const BadInsert&) = default;
virtual ~BadInsert() YAML_CPP_NOEXCEPT; ~BadInsert() YAML_CPP_NOEXCEPT override;
}; };
class YAML_CPP_API EmitterException : public Exception { class YAML_CPP_API EmitterException : public Exception {
@@ -251,17 +276,15 @@ class YAML_CPP_API EmitterException : public Exception {
EmitterException(const std::string& msg_) EmitterException(const std::string& msg_)
: Exception(Mark::null_mark(), msg_) {} : Exception(Mark::null_mark(), msg_) {}
EmitterException(const EmitterException&) = default; EmitterException(const EmitterException&) = default;
virtual ~EmitterException() YAML_CPP_NOEXCEPT; ~EmitterException() YAML_CPP_NOEXCEPT override;
}; };
class YAML_CPP_API BadFile : public Exception { class YAML_CPP_API BadFile : public Exception {
public: public:
BadFile() : Exception(Mark::null_mark(), ErrorMsg::BAD_FILE) {} BadFile() : Exception(Mark::null_mark(), ErrorMsg::BAD_FILE) {}
BadFile(const BadFile&) = default; BadFile(const BadFile&) = default;
virtual ~BadFile() YAML_CPP_NOEXCEPT; ~BadFile() YAML_CPP_NOEXCEPT override;
}; };
} }
#undef YAML_CPP_NOEXCEPT
#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+82 -36
View File
@@ -8,10 +8,12 @@
#endif #endif
#include <array> #include <array>
#include <cmath>
#include <limits> #include <limits>
#include <list> #include <list>
#include <map> #include <map>
#include <sstream> #include <sstream>
#include <type_traits>
#include <vector> #include <vector>
#include "yaml-cpp/binary.h" #include "yaml-cpp/binary.h"
@@ -88,42 +90,86 @@ struct convert<_Null> {
} }
}; };
#define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op) \ template <typename T>
template <> \ bool careful_isnan(T arg)
struct convert<type> { \ {
static Node encode(const type& rhs) { \ if constexpr (std::is_floating_point_v<T>)
std::stringstream stream; \ return std::isnan(arg);
stream.precision(std::numeric_limits<type>::digits10 + 1); \ else
stream << rhs; \ return false;
return Node(stream.str()); \ }
} \
\ template <typename T>
static bool decode(const Node& node, type& rhs) { \ bool careful_isinf(T arg)
if (node.Type() != NodeType::Scalar) \ {
return false; \ if constexpr (std::is_floating_point_v<T>)
const std::string& input = node.Scalar(); \ return std::isinf(arg);
std::stringstream stream(input); \ else
stream.unsetf(std::ios::dec); \ return false;
if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) \ }
return true; \
if (std::numeric_limits<type>::has_infinity) { \ template <typename T>
if (conversion::IsInfinity(input)) { \ bool careful_sign(T arg)
rhs = std::numeric_limits<type>::infinity(); \ {
return true; \ if constexpr (std::is_floating_point_v<T>)
} else if (conversion::IsNegativeInfinity(input)) { \ return std::signbit(arg);
rhs = negative_op std::numeric_limits<type>::infinity(); \ else
return true; \ return false;
} \ }
} \
\ #define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op) \
if (std::numeric_limits<type>::has_quiet_NaN && \ template <> \
conversion::IsNaN(input)) { \ struct convert<type> { \
rhs = std::numeric_limits<type>::quiet_NaN(); \ static Node encode(const type& rhs) { \
return true; \ std::stringstream stream; \
} \ stream.precision(std::numeric_limits<type>::max_digits10); \
\ if (std::is_floating_point<type>::value) { \
return false; \ if (careful_isnan(rhs)) { \
} \ stream << ".nan"; \
} else if (careful_isinf(rhs)) { \
if (careful_sign(rhs)) { \
stream << "-.inf"; \
} else { \
stream << ".inf"; \
} \
} else { \
stream << rhs; \
} \
} else { \
stream << rhs; \
} \
return Node(stream.str()); \
} \
\
static bool decode(const Node& node, type& rhs) { \
if (node.Type() != NodeType::Scalar) { \
return false; \
} \
const std::string& input = node.Scalar(); \
std::stringstream stream(input); \
stream.unsetf(std::ios::dec); \
if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) { \
return true; \
} \
if (std::numeric_limits<type>::has_infinity) { \
if (conversion::IsInfinity(input)) { \
rhs = std::numeric_limits<type>::infinity(); \
return true; \
} else if (conversion::IsNegativeInfinity(input)) { \
rhs = negative_op std::numeric_limits<type>::infinity(); \
return true; \
} \
} \
\
if (std::numeric_limits<type>::has_quiet_NaN) { \
if (conversion::IsNaN(input)) { \
rhs = std::numeric_limits<type>::quiet_NaN(); \
return true; \
} \
} \
\
return false; \
} \
} }
#define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type) \ #define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type) \
-26
View File
@@ -1,26 +0,0 @@
#ifndef NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
namespace YAML {
namespace detail {
struct unspecified_bool {
struct NOT_ALLOWED;
static void true_value(NOT_ALLOWED*) {}
};
typedef void (*unspecified_bool_type)(unspecified_bool::NOT_ALLOWED*);
}
}
#define YAML_CPP_OPERATOR_BOOL() \
operator YAML::detail::unspecified_bool_type() const { \
return this->operator!() ? 0 \
: &YAML::detail::unspecified_bool::true_value; \
}
#endif // NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+69 -26
View File
@@ -12,12 +12,13 @@
#include <type_traits> #include <type_traits>
namespace YAML { namespace YAML {
[[noreturn]] void throw_bad_subscript();
namespace detail { namespace detail {
template <typename Key, typename Enable = void> template <typename Key, typename Enable = void>
struct get_idx { struct get_idx {
static node* get(const std::vector<node*>& /* sequence */, static node* get(const std::vector<node*>& /* sequence */,
const Key& /* key */, shared_memory_holder /* pMemory */) { const Key& /* key */, shared_memory_holder /* pMemory */) {
return 0; return nullptr;
} }
}; };
@@ -27,13 +28,13 @@ struct get_idx<Key,
!std::is_same<Key, bool>::value>::type> { !std::is_same<Key, bool>::value>::type> {
static node* get(const std::vector<node*>& sequence, const Key& key, static node* get(const std::vector<node*>& sequence, const Key& key,
shared_memory_holder /* pMemory */) { shared_memory_holder /* pMemory */) {
return key < sequence.size() ? sequence[key] : 0; return key < sequence.size() ? sequence[key] : nullptr;
} }
static node* get(std::vector<node*>& sequence, const Key& key, static node* get(std::vector<node*>& sequence, const Key& key,
shared_memory_holder pMemory) { shared_memory_holder pMemory) {
if (key > sequence.size() || (key > 0 && !sequence[key-1]->is_defined())) if (key > sequence.size() || (key > 0 && !sequence[key - 1]->is_defined()))
return 0; return nullptr;
if (key == sequence.size()) if (key == sequence.size())
sequence.push_back(&pMemory->create_node()); sequence.push_back(&pMemory->create_node());
return sequence[key]; return sequence[key];
@@ -46,13 +47,51 @@ struct get_idx<Key, typename std::enable_if<std::is_signed<Key>::value>::type> {
shared_memory_holder pMemory) { shared_memory_holder pMemory) {
return key >= 0 ? get_idx<std::size_t>::get( return key >= 0 ? get_idx<std::size_t>::get(
sequence, static_cast<std::size_t>(key), pMemory) sequence, static_cast<std::size_t>(key), pMemory)
: 0; : nullptr;
} }
static node* get(std::vector<node*>& sequence, const Key& key, static node* get(std::vector<node*>& sequence, const Key& key,
shared_memory_holder pMemory) { shared_memory_holder pMemory) {
return key >= 0 ? get_idx<std::size_t>::get( return key >= 0 ? get_idx<std::size_t>::get(
sequence, static_cast<std::size_t>(key), pMemory) sequence, static_cast<std::size_t>(key), pMemory)
: 0; : nullptr;
}
};
template <typename Key, typename Enable = void>
struct remove_idx {
static bool remove(std::vector<node*>&, const Key&, std::size_t&) {
return false;
}
};
template <typename Key>
struct remove_idx<
Key, typename std::enable_if<std::is_unsigned<Key>::value &&
!std::is_same<Key, bool>::value>::type> {
static bool remove(std::vector<node*>& sequence, const Key& key,
std::size_t& seqSize) {
if (key >= sequence.size()) {
return false;
} else {
sequence.erase(sequence.begin() + key);
if (seqSize > key) {
--seqSize;
}
return true;
}
}
};
template <typename Key>
struct remove_idx<Key,
typename std::enable_if<std::is_signed<Key>::value>::type> {
static bool remove(std::vector<node*>& sequence, const Key& key,
std::size_t& seqSize) {
return key >= 0 ? remove_idx<std::size_t>::remove(
sequence, static_cast<std::size_t>(key), seqSize)
: false;
} }
}; };
@@ -78,13 +117,13 @@ inline node* node_data::get(const Key& key,
break; break;
case NodeType::Undefined: case NodeType::Undefined:
case NodeType::Null: case NodeType::Null:
return NULL; return nullptr;
case NodeType::Sequence: case NodeType::Sequence:
if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory)) if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory))
return pNode; return pNode;
return NULL; return nullptr;
case NodeType::Scalar: case NodeType::Scalar:
throw BadSubscript(); throw_bad_subscript();
} }
for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
@@ -93,7 +132,7 @@ inline node* node_data::get(const Key& key,
} }
} }
return NULL; return nullptr;
} }
template <typename Key> template <typename Key>
@@ -112,7 +151,7 @@ inline node& node_data::get(const Key& key, shared_memory_holder pMemory) {
convert_to_map(pMemory); convert_to_map(pMemory);
break; break;
case NodeType::Scalar: case NodeType::Scalar:
throw BadSubscript(); throw_bad_subscript();
} }
for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
@@ -129,27 +168,31 @@ inline node& node_data::get(const Key& key, shared_memory_holder pMemory) {
template <typename Key> template <typename Key>
inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) { inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) {
if (m_type != NodeType::Map) if (m_type == NodeType::Sequence) {
return false; return remove_idx<Key>::remove(m_sequence, key, m_seqSize);
} else if (m_type == NodeType::Map) {
kv_pairs::iterator it = m_undefinedPairs.begin();
while (it != m_undefinedPairs.end()) {
kv_pairs::iterator jt = std::next(it);
if (it->first->equals(key, pMemory)) {
m_undefinedPairs.erase(it);
}
it = jt;
}
for (kv_pairs::iterator it = m_undefinedPairs.begin(); for (node_map::iterator iter = m_map.begin(); iter != m_map.end(); ++iter) {
it != m_undefinedPairs.end();) { if (iter->first->equals(key, pMemory)) {
kv_pairs::iterator jt = std::next(it); m_map.erase(iter);
if (it->first->equals(key, pMemory)) return true;
m_undefinedPairs.erase(it); }
it = jt;
}
for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) {
if (it->first->equals(key, pMemory)) {
m_map.erase(it);
return true;
} }
} }
return false; return false;
} }
[[nodiscard]] void throw_bad_insert();
// map // map
template <typename Key, typename Value> template <typename Key, typename Value>
inline void node_data::force_insert(const Key& key, const Value& value, inline void node_data::force_insert(const Key& key, const Value& value,
@@ -163,7 +206,7 @@ inline void node_data::force_insert(const Key& key, const Value& value,
convert_to_map(pMemory); convert_to_map(pMemory);
break; break;
case NodeType::Scalar: case NodeType::Scalar:
throw BadInsert(); throw_bad_insert();
} }
node& k = convert_to_node(key, pMemory); node& k = convert_to_node(key, pMemory);
+11 -7
View File
@@ -8,25 +8,25 @@
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/node/detail/node_iterator.h"
#include "yaml-cpp/node/node.h" #include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/detail/node_iterator.h"
#include <cstddef> #include <cstddef>
#include <iterator> #include <iterator>
namespace YAML { namespace YAML {
namespace detail { namespace detail {
struct iterator_value; struct iterator_value;
template <typename V> template <typename V>
class iterator_base : public std::iterator<std::forward_iterator_tag, V, class iterator_base {
std::ptrdiff_t, V*, V> {
private: private:
template <typename> template <typename>
friend class iterator_base; friend class iterator_base;
struct enabler {}; struct enabler {};
typedef node_iterator base_type; using base_type = node_iterator;
struct proxy { struct proxy {
explicit proxy(const V& x) : m_ref(x) {} explicit proxy(const V& x) : m_ref(x) {}
@@ -37,7 +37,11 @@ class iterator_base : public std::iterator<std::forward_iterator_tag, V,
}; };
public: public:
typedef typename iterator_base::value_type value_type; using iterator_category = std::forward_iterator_tag;
using value_type = V;
using difference_type = std::ptrdiff_t;
using pointer = V*;
using reference = V;
public: public:
iterator_base() : m_iterator(), m_pMemory() {} iterator_base() : m_iterator(), m_pMemory() {}
@@ -86,7 +90,7 @@ class iterator_base : public std::iterator<std::forward_iterator_tag, V,
base_type m_iterator; base_type m_iterator;
shared_memory_holder m_pMemory; shared_memory_holder m_pMemory;
}; };
} } // namespace detail
} } // namespace YAML
#endif // VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+2 -2
View File
@@ -20,8 +20,8 @@ template <typename V>
class iterator_base; class iterator_base;
} }
typedef detail::iterator_base<detail::iterator_value> iterator; using iterator = detail::iterator_base<detail::iterator_value>;
typedef detail::iterator_base<const detail::iterator_value> const_iterator; using const_iterator = detail::iterator_base<const detail::iterator_value>;
} }
#endif // VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+4 -3
View File
@@ -22,11 +22,12 @@ namespace YAML {
namespace detail { namespace detail {
class YAML_CPP_API memory { class YAML_CPP_API memory {
public: public:
memory() : m_nodes{} {}
node& create_node(); node& create_node();
void merge(const memory& rhs); void merge(const memory& rhs);
private: private:
typedef std::set<shared_node> Nodes; using Nodes = std::set<shared_node>;
Nodes m_nodes; Nodes m_nodes;
}; };
@@ -40,7 +41,7 @@ class YAML_CPP_API memory_holder {
private: private:
shared_memory m_pMemory; shared_memory m_pMemory;
}; };
} } // namespace detail
} } // namespace YAML
#endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+11 -12
View File
@@ -7,18 +7,18 @@
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/node/type.h" #include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/detail/node_ref.h" #include "yaml-cpp/node/detail/node_ref.h"
#include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/type.h"
#include <set> #include <set>
namespace YAML { namespace YAML {
namespace detail { namespace detail {
class node { class node {
public: public:
node() : m_pRef(new node_ref) {} node() : m_pRef(new node_ref), m_dependencies{} {}
node(const node&) = delete; node(const node&) = delete;
node& operator=(const node&) = delete; node& operator=(const node&) = delete;
@@ -42,9 +42,8 @@ class node {
return; return;
m_pRef->mark_defined(); m_pRef->mark_defined();
for (nodes::iterator it = m_dependencies.begin(); for (node* dependency : m_dependencies)
it != m_dependencies.end(); ++it) dependency->mark_defined();
(*it)->mark_defined();
m_dependencies.clear(); m_dependencies.clear();
} }
@@ -120,7 +119,7 @@ class node {
template <typename Key> template <typename Key>
node* get(const Key& key, shared_memory_holder pMemory) const { node* get(const Key& key, shared_memory_holder pMemory) const {
// NOTE: this returns a non-const node so that the top-level Node can wrap // NOTE: this returns a non-const node so that the top-level Node can wrap
// it, and returns a pointer so that it can be NULL (if there is no such // it, and returns a pointer so that it can be nullptr (if there is no such
// key). // key).
return static_cast<const node_ref&>(*m_pRef).get(key, pMemory); return static_cast<const node_ref&>(*m_pRef).get(key, pMemory);
} }
@@ -137,7 +136,7 @@ class node {
node* get(node& key, shared_memory_holder pMemory) const { node* get(node& key, shared_memory_holder pMemory) const {
// NOTE: this returns a non-const node so that the top-level Node can wrap // NOTE: this returns a non-const node so that the top-level Node can wrap
// it, and returns a pointer so that it can be NULL (if there is no such // it, and returns a pointer so that it can be nullptr (if there is no such
// key). // key).
return static_cast<const node_ref&>(*m_pRef).get(key, pMemory); return static_cast<const node_ref&>(*m_pRef).get(key, pMemory);
} }
@@ -160,10 +159,10 @@ class node {
private: private:
shared_node_ref m_pRef; shared_node_ref m_pRef;
typedef std::set<node*> nodes; using nodes = std::set<node*>;
nodes m_dependencies; nodes m_dependencies;
}; };
} } // namespace detail
} } // namespace YAML
#endif // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+5 -5
View File
@@ -81,7 +81,7 @@ class YAML_CPP_API node_data {
shared_memory_holder pMemory); shared_memory_holder pMemory);
public: public:
static std::string empty_scalar; static const std::string& empty_scalar();
private: private:
void compute_seq_size() const; void compute_seq_size() const;
@@ -108,17 +108,17 @@ class YAML_CPP_API node_data {
std::string m_scalar; std::string m_scalar;
// sequence // sequence
typedef std::vector<node*> node_seq; using node_seq = std::vector<node *>;
node_seq m_sequence; node_seq m_sequence;
mutable std::size_t m_seqSize; mutable std::size_t m_seqSize;
// map // map
typedef std::vector<std::pair<node*, node*>> node_map; using node_map = std::vector<std::pair<node*, node*>>;
node_map m_map; node_map m_map;
typedef std::pair<node*, node*> kv_pair; using kv_pair = std::pair<node*, node*>;
typedef std::list<kv_pair> kv_pairs; using kv_pairs = std::list<kv_pair>;
mutable kv_pairs m_undefinedPairs; mutable kv_pairs m_undefinedPairs;
}; };
} }
+14 -14
View File
@@ -24,11 +24,11 @@ struct iterator_type {
template <typename V> template <typename V>
struct node_iterator_value : public std::pair<V*, V*> { struct node_iterator_value : public std::pair<V*, V*> {
typedef std::pair<V*, V*> kv; using kv = std::pair<V*, V*>;
node_iterator_value() : kv(), pNode(0) {} node_iterator_value() : kv(), pNode(nullptr) {}
explicit node_iterator_value(V& rhs) : kv(), pNode(&rhs) {} explicit node_iterator_value(V& rhs) : kv(), pNode(&rhs) {}
explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(0) {} explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(nullptr) {}
V& operator*() const { return *pNode; } V& operator*() const { return *pNode; }
V& operator->() const { return *pNode; } V& operator->() const { return *pNode; }
@@ -36,19 +36,19 @@ struct node_iterator_value : public std::pair<V*, V*> {
V* pNode; V* pNode;
}; };
typedef std::vector<node*> node_seq; using node_seq = std::vector<node *>;
typedef std::vector<std::pair<node*, node*>> node_map; using node_map = std::vector<std::pair<node*, node*>>;
template <typename V> template <typename V>
struct node_iterator_type { struct node_iterator_type {
typedef node_seq::iterator seq; using seq = node_seq::iterator;
typedef node_map::iterator map; using map = node_map::iterator;
}; };
template <typename V> template <typename V>
struct node_iterator_type<const V> { struct node_iterator_type<const V> {
typedef node_seq::const_iterator seq; using seq = node_seq::const_iterator;
typedef node_map::const_iterator map; using map = node_map::const_iterator;
}; };
template <typename V> template <typename V>
@@ -68,9 +68,9 @@ class node_iterator_base
}; };
public: public:
typedef typename node_iterator_type<V>::seq SeqIter; using SeqIter = typename node_iterator_type<V>::seq;
typedef typename node_iterator_type<V>::map MapIter; using MapIter = typename node_iterator_type<V>::map;
typedef node_iterator_value<V> value_type; using value_type = node_iterator_value<V>;
node_iterator_base() node_iterator_base()
: m_type(iterator_type::NoneType), m_seqIt(), m_mapIt(), m_mapEnd() {} : m_type(iterator_type::NoneType), m_seqIt(), m_mapIt(), m_mapEnd() {}
@@ -172,8 +172,8 @@ class node_iterator_base
MapIter m_mapIt, m_mapEnd; MapIter m_mapIt, m_mapEnd;
}; };
typedef node_iterator_base<node> node_iterator; using node_iterator = node_iterator_base<node>;
typedef node_iterator_base<const node> const_node_iterator; using const_node_iterator = node_iterator_base<const node>;
} }
} }
+59 -78
View File
@@ -7,18 +7,23 @@
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/node/node.h" #include "yaml-cpp/exceptions.h"
#include "yaml-cpp/node/iterator.h"
#include "yaml-cpp/node/detail/memory.h" #include "yaml-cpp/node/detail/memory.h"
#include "yaml-cpp/node/detail/node.h" #include "yaml-cpp/node/detail/node.h"
#include "yaml-cpp/exceptions.h" #include "yaml-cpp/node/iterator.h"
#include "yaml-cpp/node/node.h"
#include <sstream>
#include <string> #include <string>
namespace YAML { namespace YAML {
inline Node::Node() : m_isValid(true), m_pNode(NULL) {} [[noreturn]] extern void throw_invalid_node(const std::string& key);
[[noreturn]] extern void throw_bad_conversion(const YAML::Mark& mark);
inline Node::Node()
: m_isValid(true), m_invalidKey{}, m_pMemory(nullptr), m_pNode(nullptr) {}
inline Node::Node(NodeType::value type) inline Node::Node(NodeType::value type)
: m_isValid(true), : m_isValid(true),
m_invalidKey{},
m_pMemory(new detail::memory_holder), m_pMemory(new detail::memory_holder),
m_pNode(&m_pMemory->create_node()) { m_pNode(&m_pMemory->create_node()) {
m_pNode->set_type(type); m_pNode->set_type(type);
@@ -27,6 +32,7 @@ inline Node::Node(NodeType::value type)
template <typename T> template <typename T>
inline Node::Node(const T& rhs) inline Node::Node(const T& rhs)
: m_isValid(true), : m_isValid(true),
m_invalidKey{},
m_pMemory(new detail::memory_holder), m_pMemory(new detail::memory_holder),
m_pNode(&m_pMemory->create_node()) { m_pNode(&m_pMemory->create_node()) {
Assign(rhs); Assign(rhs);
@@ -34,24 +40,26 @@ inline Node::Node(const T& rhs)
inline Node::Node(const detail::iterator_value& rhs) inline Node::Node(const detail::iterator_value& rhs)
: m_isValid(rhs.m_isValid), : m_isValid(rhs.m_isValid),
m_invalidKey(rhs.m_invalidKey),
m_pMemory(rhs.m_pMemory), m_pMemory(rhs.m_pMemory),
m_pNode(rhs.m_pNode) {} m_pNode(rhs.m_pNode) {}
inline Node::Node(const Node& rhs) inline Node::Node(const Node& rhs) = default;
: m_isValid(rhs.m_isValid),
m_pMemory(rhs.m_pMemory),
m_pNode(rhs.m_pNode) {}
inline Node::Node(Zombie) : m_isValid(false), m_pNode(NULL) {} inline Node::Node(Zombie)
: m_isValid(false), m_invalidKey{}, m_pMemory{}, m_pNode(nullptr) {}
inline Node::Node(Zombie, const std::string& key)
: m_isValid(false), m_invalidKey(key), m_pMemory{}, m_pNode(nullptr) {}
inline Node::Node(detail::node& node, detail::shared_memory_holder pMemory) inline Node::Node(detail::node& node, detail::shared_memory_holder pMemory)
: m_isValid(true), m_pMemory(pMemory), m_pNode(&node) {} : m_isValid(true), m_invalidKey{}, m_pMemory(pMemory), m_pNode(&node) {}
inline Node::~Node() {} inline Node::~Node() = default;
inline void Node::EnsureNodeExists() const { inline void Node::EnsureNodeExists() const {
if (!m_isValid) if (!m_isValid)
throw InvalidNode(); throw_invalid_node(m_invalidKey);
if (!m_pNode) { if (!m_pNode) {
m_pMemory.reset(new detail::memory_holder); m_pMemory.reset(new detail::memory_holder);
m_pNode = &m_pMemory->create_node(); m_pNode = &m_pMemory->create_node();
@@ -68,14 +76,14 @@ inline bool Node::IsDefined() const {
inline Mark Node::Mark() const { inline Mark Node::Mark() const {
if (!m_isValid) { if (!m_isValid) {
throw InvalidNode(); throw_invalid_node(m_invalidKey);
} }
return m_pNode ? m_pNode->mark() : Mark::null_mark(); return m_pNode ? m_pNode->mark() : Mark::null_mark();
} }
inline NodeType::value Node::Type() const { inline NodeType::value Node::Type() const {
if (!m_isValid) if (!m_isValid)
throw InvalidNode(); throw_invalid_node(m_invalidKey);
return m_pNode ? m_pNode->type() : NodeType::Null; return m_pNode ? m_pNode->type() : NodeType::Null;
} }
@@ -117,12 +125,12 @@ struct as_if<T, void> {
T operator()() const { T operator()() const {
if (!node.m_pNode) if (!node.m_pNode)
throw TypedBadConversion<T>(node.Mark()); throw_bad_conversion(node.Mark()); // <T>
T t; T t;
if (convert<T>::decode(node, t)) if (convert<T>::decode(node, t))
return t; return t;
throw TypedBadConversion<T>(node.Mark()); throw_bad_conversion(node.Mark()); // <T>
} }
}; };
@@ -133,7 +141,7 @@ struct as_if<std::string, void> {
std::string operator()() const { std::string operator()() const {
if (node.Type() != NodeType::Scalar) if (node.Type() != NodeType::Scalar)
throw TypedBadConversion<std::string>(node.Mark()); throw_bad_conversion(node.Mark()); // <std::string>
return node.Scalar(); return node.Scalar();
} }
}; };
@@ -142,7 +150,7 @@ struct as_if<std::string, void> {
template <typename T> template <typename T>
inline T Node::as() const { inline T Node::as() const {
if (!m_isValid) if (!m_isValid)
throw InvalidNode(); throw_invalid_node(m_invalidKey);
return as_if<T, void>(*this)(); return as_if<T, void>(*this)();
} }
@@ -155,32 +163,28 @@ inline T Node::as(const S& fallback) const {
inline const std::string& Node::Scalar() const { inline const std::string& Node::Scalar() const {
if (!m_isValid) if (!m_isValid)
throw InvalidNode(); throw_invalid_node(m_invalidKey);
return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar; return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar();
} }
inline const std::string& Node::Tag() const { inline const std::string& Node::Tag() const {
if (!m_isValid) if (!m_isValid)
throw InvalidNode(); throw_invalid_node(m_invalidKey);
return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar; return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar();
} }
inline void Node::SetTag(const std::string& tag) { inline void Node::SetTag(const std::string& tag) {
if (!m_isValid)
throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
m_pNode->set_tag(tag); m_pNode->set_tag(tag);
} }
inline EmitterStyle::value Node::Style() const { inline EmitterStyle::value Node::Style() const {
if (!m_isValid) if (!m_isValid)
throw InvalidNode(); throw_invalid_node(m_invalidKey);
return m_pNode ? m_pNode->style() : EmitterStyle::Default; return m_pNode ? m_pNode->style() : EmitterStyle::Default;
} }
inline void Node::SetStyle(EmitterStyle::value style) { inline void Node::SetStyle(EmitterStyle::value style) {
if (!m_isValid)
throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
m_pNode->set_style(style); m_pNode->set_style(style);
} }
@@ -188,7 +192,7 @@ inline void Node::SetStyle(EmitterStyle::value style) {
// assignment // assignment
inline bool Node::is(const Node& rhs) const { inline bool Node::is(const Node& rhs) const {
if (!m_isValid || !rhs.m_isValid) if (!m_isValid || !rhs.m_isValid)
throw InvalidNode(); throw_invalid_node(m_invalidKey);
if (!m_pNode || !rhs.m_pNode) if (!m_pNode || !rhs.m_pNode)
return false; return false;
return m_pNode->is(*rhs.m_pNode); return m_pNode->is(*rhs.m_pNode);
@@ -196,15 +200,20 @@ inline bool Node::is(const Node& rhs) const {
template <typename T> template <typename T>
inline Node& Node::operator=(const T& rhs) { inline Node& Node::operator=(const T& rhs) {
if (!m_isValid)
throw InvalidNode();
Assign(rhs); Assign(rhs);
return *this; return *this;
} }
inline Node& Node::operator=(const Node& rhs) {
if (is(rhs))
return *this;
AssignNode(rhs);
return *this;
}
inline void Node::reset(const YAML::Node& rhs) { inline void Node::reset(const YAML::Node& rhs) {
if (!m_isValid || !rhs.m_isValid) if (!m_isValid || !rhs.m_isValid)
throw InvalidNode(); throw_invalid_node(m_invalidKey);
m_pMemory = rhs.m_pMemory; m_pMemory = rhs.m_pMemory;
m_pNode = rhs.m_pNode; m_pNode = rhs.m_pNode;
} }
@@ -212,44 +221,27 @@ inline void Node::reset(const YAML::Node& rhs) {
template <typename T> template <typename T>
inline void Node::Assign(const T& rhs) { inline void Node::Assign(const T& rhs) {
if (!m_isValid) if (!m_isValid)
throw InvalidNode(); throw_invalid_node(m_invalidKey);
AssignData(convert<T>::encode(rhs)); AssignData(convert<T>::encode(rhs));
} }
template <> template <>
inline void Node::Assign(const std::string& rhs) { inline void Node::Assign(const std::string& rhs) {
if (!m_isValid)
throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
m_pNode->set_scalar(rhs); m_pNode->set_scalar(rhs);
} }
inline void Node::Assign(const char* rhs) { inline void Node::Assign(const char* rhs) {
if (!m_isValid)
throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
m_pNode->set_scalar(rhs); m_pNode->set_scalar(rhs);
} }
inline void Node::Assign(char* rhs) { inline void Node::Assign(char* rhs) {
if (!m_isValid)
throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
m_pNode->set_scalar(rhs); m_pNode->set_scalar(rhs);
} }
inline Node& Node::operator=(const Node& rhs) {
if (!m_isValid || !rhs.m_isValid)
throw InvalidNode();
if (is(rhs))
return *this;
AssignNode(rhs);
return *this;
}
inline void Node::AssignData(const Node& rhs) { inline void Node::AssignData(const Node& rhs) {
if (!m_isValid || !rhs.m_isValid)
throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
rhs.EnsureNodeExists(); rhs.EnsureNodeExists();
@@ -258,8 +250,8 @@ inline void Node::AssignData(const Node& rhs) {
} }
inline void Node::AssignNode(const Node& rhs) { inline void Node::AssignNode(const Node& rhs) {
if (!m_isValid || !rhs.m_isValid) if (!m_isValid)
throw InvalidNode(); throw_invalid_node(m_invalidKey);
rhs.EnsureNodeExists(); rhs.EnsureNodeExists();
if (!m_pNode) { if (!m_pNode) {
@@ -276,7 +268,7 @@ inline void Node::AssignNode(const Node& rhs) {
// size/iterator // size/iterator
inline std::size_t Node::size() const { inline std::size_t Node::size() const {
if (!m_isValid) if (!m_isValid)
throw InvalidNode(); throw_invalid_node(m_invalidKey);
return m_pNode ? m_pNode->size() : 0; return m_pNode ? m_pNode->size() : 0;
} }
@@ -309,13 +301,11 @@ inline iterator Node::end() {
template <typename T> template <typename T>
inline void Node::push_back(const T& rhs) { inline void Node::push_back(const T& rhs) {
if (!m_isValid) if (!m_isValid)
throw InvalidNode(); throw_invalid_node(m_invalidKey);
push_back(Node(rhs)); push_back(Node(rhs));
} }
inline void Node::push_back(const Node& rhs) { inline void Node::push_back(const Node& rhs) {
if (!m_isValid || !rhs.m_isValid)
throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
rhs.EnsureNodeExists(); rhs.EnsureNodeExists();
@@ -329,7 +319,7 @@ template <typename T>
struct to_value_t { struct to_value_t {
explicit to_value_t(const T& t_) : t(t_) {} explicit to_value_t(const T& t_) : t(t_) {}
const T& t; const T& t;
typedef const T& return_type; using return_type = const T &;
const T& operator()() const { return t; } const T& operator()() const { return t; }
}; };
@@ -338,7 +328,7 @@ template <>
struct to_value_t<const char*> { struct to_value_t<const char*> {
explicit to_value_t(const char* t_) : t(t_) {} explicit to_value_t(const char* t_) : t(t_) {}
const char* t; const char* t;
typedef std::string return_type; using return_type = std::string;
const std::string operator()() const { return t; } const std::string operator()() const { return t; }
}; };
@@ -347,7 +337,7 @@ template <>
struct to_value_t<char*> { struct to_value_t<char*> {
explicit to_value_t(char* t_) : t(t_) {} explicit to_value_t(char* t_) : t(t_) {}
const char* t; const char* t;
typedef std::string return_type; using return_type = std::string;
const std::string operator()() const { return t; } const std::string operator()() const { return t; }
}; };
@@ -356,7 +346,7 @@ template <std::size_t N>
struct to_value_t<char[N]> { struct to_value_t<char[N]> {
explicit to_value_t(const char* t_) : t(t_) {} explicit to_value_t(const char* t_) : t(t_) {}
const char* t; const char* t;
typedef std::string return_type; using return_type = std::string;
const std::string operator()() const { return t; } const std::string operator()() const { return t; }
}; };
@@ -366,26 +356,27 @@ template <typename T>
inline typename to_value_t<T>::return_type to_value(const T& t) { inline typename to_value_t<T>::return_type to_value(const T& t) {
return to_value_t<T>(t)(); return to_value_t<T>(t)();
} }
} // namespace detail
template<typename Key>
std::string key_to_string(const Key& key) {
return streamable_to_string<Key, is_streamable<std::stringstream, Key>::value>().impl(key);
} }
// indexing // indexing
template <typename Key> template <typename Key>
inline const Node Node::operator[](const Key& key) const { inline const Node Node::operator[](const Key& key) const {
if (!m_isValid)
throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
detail::node* value = static_cast<const detail::node&>(*m_pNode) detail::node* value = static_cast<const detail::node&>(*m_pNode).get(
.get(detail::to_value(key), m_pMemory); detail::to_value(key), m_pMemory);
if (!value) { if (!value) {
return Node(ZombieNode); return Node(ZombieNode, key_to_string(key));
} }
return Node(*value, m_pMemory); return Node(*value, m_pMemory);
} }
template <typename Key> template <typename Key>
inline Node Node::operator[](const Key& key) { inline Node Node::operator[](const Key& key) {
if (!m_isValid)
throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
detail::node& value = m_pNode->get(detail::to_value(key), m_pMemory); detail::node& value = m_pNode->get(detail::to_value(key), m_pMemory);
return Node(value, m_pMemory); return Node(value, m_pMemory);
@@ -393,29 +384,23 @@ inline Node Node::operator[](const Key& key) {
template <typename Key> template <typename Key>
inline bool Node::remove(const Key& key) { inline bool Node::remove(const Key& key) {
if (!m_isValid)
throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
return m_pNode->remove(detail::to_value(key), m_pMemory); return m_pNode->remove(detail::to_value(key), m_pMemory);
} }
inline const Node Node::operator[](const Node& key) const { inline const Node Node::operator[](const Node& key) const {
if (!m_isValid || !key.m_isValid)
throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
key.EnsureNodeExists(); key.EnsureNodeExists();
m_pMemory->merge(*key.m_pMemory); m_pMemory->merge(*key.m_pMemory);
detail::node* value = detail::node* value =
static_cast<const detail::node&>(*m_pNode).get(*key.m_pNode, m_pMemory); static_cast<const detail::node&>(*m_pNode).get(*key.m_pNode, m_pMemory);
if (!value) { if (!value) {
return Node(ZombieNode); return Node(ZombieNode, key_to_string(key));
} }
return Node(*value, m_pMemory); return Node(*value, m_pMemory);
} }
inline Node Node::operator[](const Node& key) { inline Node Node::operator[](const Node& key) {
if (!m_isValid || !key.m_isValid)
throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
key.EnsureNodeExists(); key.EnsureNodeExists();
m_pMemory->merge(*key.m_pMemory); m_pMemory->merge(*key.m_pMemory);
@@ -424,8 +409,6 @@ inline Node Node::operator[](const Node& key) {
} }
inline bool Node::remove(const Node& key) { inline bool Node::remove(const Node& key) {
if (!m_isValid || !key.m_isValid)
throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
key.EnsureNodeExists(); key.EnsureNodeExists();
return m_pNode->remove(*key.m_pNode, m_pMemory); return m_pNode->remove(*key.m_pNode, m_pMemory);
@@ -434,8 +417,6 @@ inline bool Node::remove(const Node& key) {
// map // map
template <typename Key, typename Value> template <typename Key, typename Value>
inline void Node::force_insert(const Key& key, const Value& value) { inline void Node::force_insert(const Key& key, const Value& value) {
if (!m_isValid)
throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
m_pNode->force_insert(detail::to_value(key), detail::to_value(value), m_pNode->force_insert(detail::to_value(key), detail::to_value(value),
m_pMemory); m_pMemory);
@@ -443,6 +424,6 @@ inline void Node::force_insert(const Key& key, const Value& value) {
// free functions // free functions
inline bool operator==(const Node& lhs, const Node& rhs) { return lhs.is(rhs); } inline bool operator==(const Node& lhs, const Node& rhs) { return lhs.is(rhs); }
} } // namespace YAML
#endif // NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+1 -1
View File
@@ -18,7 +18,7 @@
namespace YAML { namespace YAML {
namespace detail { namespace detail {
struct iterator_value : public Node, std::pair<Node, Node> { struct iterator_value : public Node, std::pair<Node, Node> {
iterator_value() {} iterator_value() = default;
explicit iterator_value(const Node& rhs) explicit iterator_value(const Node& rhs)
: Node(rhs), : Node(rhs),
std::pair<Node, Node>(Node(Node::ZombieNode), Node(Node::ZombieNode)) {} std::pair<Node, Node>(Node(Node::ZombieNode), Node(Node::ZombieNode)) {}
+7 -4
View File
@@ -8,11 +8,11 @@
#endif #endif
#include <stdexcept> #include <stdexcept>
#include <string>
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/emitterstyle.h" #include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/mark.h" #include "yaml-cpp/mark.h"
#include "yaml-cpp/node/detail/bool_type.h"
#include "yaml-cpp/node/detail/iterator_fwd.h" #include "yaml-cpp/node/detail/iterator_fwd.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/type.h" #include "yaml-cpp/node/type.h"
@@ -38,8 +38,8 @@ class YAML_CPP_API Node {
template <typename T, typename S> template <typename T, typename S>
friend struct as_if; friend struct as_if;
typedef YAML::iterator iterator; using iterator = YAML::iterator;
typedef YAML::const_iterator const_iterator; using const_iterator = YAML::const_iterator;
Node(); Node();
explicit Node(NodeType::value type); explicit Node(NodeType::value type);
@@ -58,7 +58,7 @@ class YAML_CPP_API Node {
bool IsMap() const { return Type() == NodeType::Map; } bool IsMap() const { return Type() == NodeType::Map; }
// bool conversions // bool conversions
YAML_CPP_OPERATOR_BOOL() explicit operator bool() const { return IsDefined(); }
bool operator!() const { return !IsDefined(); } bool operator!() const { return !IsDefined(); }
// access // access
@@ -116,6 +116,7 @@ class YAML_CPP_API Node {
private: private:
enum Zombie { ZombieNode }; enum Zombie { ZombieNode };
explicit Node(Zombie); explicit Node(Zombie);
explicit Node(Zombie, const std::string&);
explicit Node(detail::node& node, detail::shared_memory_holder pMemory); explicit Node(detail::node& node, detail::shared_memory_holder pMemory);
void EnsureNodeExists() const; void EnsureNodeExists() const;
@@ -130,6 +131,8 @@ class YAML_CPP_API Node {
private: private:
bool m_isValid; bool m_isValid;
// String representation of invalid key, if the node is invalid.
std::string m_invalidKey;
mutable detail::shared_memory_holder m_pMemory; mutable detail::shared_memory_holder m_pMemory;
mutable detail::node* m_pNode; mutable detail::node* m_pNode;
}; };
+5 -5
View File
@@ -18,11 +18,11 @@ class node_data;
class memory; class memory;
class memory_holder; class memory_holder;
typedef std::shared_ptr<node> shared_node; using shared_node = std::shared_ptr<node>;
typedef std::shared_ptr<node_ref> shared_node_ref; using shared_node_ref = std::shared_ptr<node_ref>;
typedef std::shared_ptr<node_data> shared_node_data; using shared_node_data = std::shared_ptr<node_data>;
typedef std::shared_ptr<memory_holder> shared_memory_holder; using shared_memory_holder = std::shared_ptr<memory_holder>;
typedef std::shared_ptr<memory> shared_memory; using shared_memory = std::shared_ptr<memory>;
} }
} }
+18
View File
@@ -0,0 +1,18 @@
#ifndef NOEXCEPT_H_768872DA_476C_11EA_88B8_90B11C0C0FF8
#define NOEXCEPT_H_768872DA_476C_11EA_88B8_90B11C0C0FF8
#if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
// This is here for compatibility with older versions of Visual Studio
// which don't support noexcept.
#if defined(_MSC_VER) && _MSC_VER < 1900
#define YAML_CPP_NOEXCEPT _NOEXCEPT
#else
#define YAML_CPP_NOEXCEPT noexcept
#endif
#endif
-25
View File
@@ -1,25 +0,0 @@
#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
+7 -3
View File
@@ -17,6 +17,10 @@ class YAML_CPP_API ostream_wrapper {
public: public:
ostream_wrapper(); ostream_wrapper();
explicit ostream_wrapper(std::ostream& stream); explicit ostream_wrapper(std::ostream& stream);
ostream_wrapper(const ostream_wrapper&) = delete;
ostream_wrapper(ostream_wrapper&&) = delete;
ostream_wrapper& operator=(const ostream_wrapper&) = delete;
ostream_wrapper& operator=(ostream_wrapper&&) = delete;
~ostream_wrapper(); ~ostream_wrapper();
void write(const std::string& str); void write(const std::string& str);
@@ -26,7 +30,7 @@ class YAML_CPP_API ostream_wrapper {
const char* str() const { const char* str() const {
if (m_pStream) { if (m_pStream) {
return 0; return nullptr;
} else { } else {
m_buffer[m_pos] = '\0'; m_buffer[m_pos] = '\0';
return &m_buffer[0]; return &m_buffer[0];
@@ -52,7 +56,7 @@ class YAML_CPP_API ostream_wrapper {
template <std::size_t N> template <std::size_t N>
inline ostream_wrapper& operator<<(ostream_wrapper& stream, inline ostream_wrapper& operator<<(ostream_wrapper& stream,
const char(&str)[N]) { const char (&str)[N]) {
stream.write(str, N - 1); stream.write(str, N - 1);
return stream; return stream;
} }
@@ -67,6 +71,6 @@ inline ostream_wrapper& operator<<(ostream_wrapper& stream, char ch) {
stream.write(&ch, 1); stream.write(&ch, 1);
return stream; return stream;
} }
} } // namespace YAML
#endif // OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+7 -3
View File
@@ -11,7 +11,6 @@
#include <memory> #include <memory>
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/noncopyable.h"
namespace YAML { namespace YAML {
class EventHandler; class EventHandler;
@@ -24,11 +23,16 @@ struct Token;
* A parser turns a stream of bytes into one stream of "events" per YAML * A parser turns a stream of bytes into one stream of "events" per YAML
* document in the input stream. * document in the input stream.
*/ */
class YAML_CPP_API Parser : private noncopyable { class YAML_CPP_API Parser {
public: public:
/** Constructs an empty parser (with no input. */ /** Constructs an empty parser (with no input. */
Parser(); Parser();
Parser(const Parser&) = delete;
Parser(Parser&&) = delete;
Parser& operator=(const Parser&) = delete;
Parser& operator=(Parser&&) = delete;
/** /**
* Constructs a parser from the given input stream. The input stream must * Constructs a parser from the given input stream. The input stream must
* live as long as the parser. * live as long as the parser.
@@ -81,6 +85,6 @@ class YAML_CPP_API Parser : private noncopyable {
std::unique_ptr<Scanner> m_pScanner; std::unique_ptr<Scanner> m_pScanner;
std::unique_ptr<Directives> m_pDirectives; std::unique_ptr<Directives> m_pDirectives;
}; };
} } // namespace YAML
#endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+34 -2
View File
@@ -7,6 +7,11 @@
#pragma once #pragma once
#endif #endif
#include <type_traits>
#include <utility>
#include <string>
#include <sstream>
namespace YAML { namespace YAML {
template <typename> template <typename>
struct is_numeric { struct is_numeric {
@@ -79,7 +84,7 @@ struct is_numeric<long double> {
template <bool, class T = void> template <bool, class T = void>
struct enable_if_c { struct enable_if_c {
typedef T type; using type = T;
}; };
template <class T> template <class T>
@@ -90,7 +95,7 @@ struct enable_if : public enable_if_c<Cond::value, T> {};
template <bool, class T = void> template <bool, class T = void>
struct disable_if_c { struct disable_if_c {
typedef T type; using type = T;
}; };
template <class T> template <class T>
@@ -100,4 +105,31 @@ template <class Cond, class T = void>
struct disable_if : public disable_if_c<Cond::value, T> {}; struct disable_if : public disable_if_c<Cond::value, T> {};
} }
template <typename S, typename T>
struct is_streamable {
template <typename SS, typename TT>
static auto test(int)
-> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
template <typename, typename>
static auto test(...) -> std::false_type;
static const bool value = decltype(test<S, T>(0))::value;
};
template<typename Key, bool Streamable>
struct streamable_to_string {
static std::string impl(const Key& key) {
std::stringstream ss;
ss << key;
return ss.str();
}
};
template<typename Key>
struct streamable_to_string<Key, false> {
static std::string impl(const Key&) {
return "";
}
};
#endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+10 -3
View File
@@ -1,5 +1,7 @@
#include "yaml-cpp/binary.h" #include "yaml-cpp/binary.h"
#include <cctype>
namespace YAML { namespace YAML {
static const char encoding[] = static const char encoding[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@@ -64,7 +66,7 @@ static const unsigned char decoding[] = {
}; };
std::vector<unsigned char> DecodeBase64(const std::string &input) { std::vector<unsigned char> DecodeBase64(const std::string &input) {
typedef std::vector<unsigned char> ret_type; using ret_type = std::vector<unsigned char>;
if (input.empty()) if (input.empty())
return ret_type(); return ret_type();
@@ -72,19 +74,24 @@ std::vector<unsigned char> DecodeBase64(const std::string &input) {
unsigned char *out = &ret[0]; unsigned char *out = &ret[0];
unsigned value = 0; unsigned value = 0;
for (std::size_t i = 0; i < input.size(); i++) { for (std::size_t i = 0, cnt = 0; i < input.size(); i++) {
if (std::isspace(input[i])) {
// skip newlines
continue;
}
unsigned char d = decoding[static_cast<unsigned>(input[i])]; unsigned char d = decoding[static_cast<unsigned>(input[i])];
if (d == 255) if (d == 255)
return ret_type(); return ret_type();
value = (value << 6) | d; value = (value << 6) | d;
if (i % 4 == 3) { if (cnt % 4 == 3) {
*out++ = value >> 16; *out++ = value >> 16;
if (i > 0 && input[i - 1] != '=') if (i > 0 && input[i - 1] != '=')
*out++ = value >> 8; *out++ = value >> 8;
if (input[i] != '=') if (input[i] != '=')
*out++ = value; *out++ = value;
} }
++cnt;
} }
ret.resize(out - &ret[0]); ret.resize(out - &ret[0]);
+4 -2
View File
@@ -7,8 +7,8 @@
#pragma once #pragma once
#endif #endif
#include <stack>
#include <cassert> #include <cassert>
#include <stack>
namespace YAML { namespace YAML {
struct CollectionType { struct CollectionType {
@@ -17,6 +17,7 @@ struct CollectionType {
class CollectionStack { class CollectionStack {
public: public:
CollectionStack() : collectionStack{} {}
CollectionType::value GetCurCollectionType() const { CollectionType::value GetCurCollectionType() const {
if (collectionStack.empty()) if (collectionStack.empty())
return CollectionType::NoCollection; return CollectionType::NoCollection;
@@ -28,12 +29,13 @@ class CollectionStack {
} }
void PopCollectionType(CollectionType::value type) { void PopCollectionType(CollectionType::value type) {
assert(type == GetCurCollectionType()); assert(type == GetCurCollectionType());
(void)type;
collectionStack.pop(); collectionStack.pop();
} }
private: private:
std::stack<CollectionType::value> collectionStack; std::stack<CollectionType::value> collectionStack;
}; };
} } // namespace YAML
#endif // COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+1 -1
View File
@@ -11,7 +11,7 @@ void* BuildGraphOfNextDocument(Parser& parser,
if (parser.HandleNextDocument(eventHandler)) { if (parser.HandleNextDocument(eventHandler)) {
return eventHandler.RootNode(); return eventHandler.RootNode();
} else { } else {
return NULL; return nullptr;
} }
} }
} }
+3 -3
View File
@@ -49,7 +49,7 @@ void GraphBuilderAdapter::OnMapStart(const Mark &mark, const std::string &tag,
EmitterStyle::value /* style */) { EmitterStyle::value /* style */) {
void *pNode = m_builder.NewMap(mark, tag, GetCurrentParent()); void *pNode = m_builder.NewMap(mark, tag, GetCurrentParent());
m_containers.push(ContainerFrame(pNode, m_pKeyNode)); m_containers.push(ContainerFrame(pNode, m_pKeyNode));
m_pKeyNode = NULL; m_pKeyNode = nullptr;
RegisterAnchor(anchor, pNode); RegisterAnchor(anchor, pNode);
} }
@@ -62,7 +62,7 @@ void GraphBuilderAdapter::OnMapEnd() {
void *GraphBuilderAdapter::GetCurrentParent() const { void *GraphBuilderAdapter::GetCurrentParent() const {
if (m_containers.empty()) { if (m_containers.empty()) {
return NULL; return nullptr;
} }
return m_containers.top().pContainer; return m_containers.top().pContainer;
} }
@@ -83,7 +83,7 @@ void GraphBuilderAdapter::DispositionNode(void *pNode) {
if (m_containers.top().isMap()) { if (m_containers.top().isMap()) {
if (m_pKeyNode) { if (m_pKeyNode) {
m_builder.AssignInMap(pContainer, m_pKeyNode, pNode); m_builder.AssignInMap(pContainer, m_pKeyNode, pNode);
m_pKeyNode = NULL; m_pKeyNode = nullptr;
} else { } else {
m_pKeyNode = pNode; m_pKeyNode = pNode;
} }
+12 -4
View File
@@ -26,7 +26,15 @@ namespace YAML {
class GraphBuilderAdapter : public EventHandler { class GraphBuilderAdapter : public EventHandler {
public: public:
GraphBuilderAdapter(GraphBuilderInterface& builder) GraphBuilderAdapter(GraphBuilderInterface& builder)
: m_builder(builder), m_pRootNode(NULL), m_pKeyNode(NULL) {} : m_builder(builder),
m_containers{},
m_anchors{},
m_pRootNode(nullptr),
m_pKeyNode(nullptr) {}
GraphBuilderAdapter(const GraphBuilderAdapter&) = delete;
GraphBuilderAdapter(GraphBuilderAdapter&&) = delete;
GraphBuilderAdapter& operator=(const GraphBuilderAdapter&) = delete;
GraphBuilderAdapter& operator=(GraphBuilderAdapter&&) = delete;
virtual void OnDocumentStart(const Mark& mark) { (void)mark; } virtual void OnDocumentStart(const Mark& mark) { (void)mark; }
virtual void OnDocumentEnd() {} virtual void OnDocumentEnd() {}
@@ -50,8 +58,8 @@ class GraphBuilderAdapter : public EventHandler {
struct ContainerFrame { struct ContainerFrame {
ContainerFrame(void* pSequence) ContainerFrame(void* pSequence)
: pContainer(pSequence), pPrevKeyNode(&sequenceMarker) {} : pContainer(pSequence), pPrevKeyNode(&sequenceMarker) {}
ContainerFrame(void* pMap, void* pPrevKeyNode) ContainerFrame(void* pMap, void* pPreviousKeyNode)
: pContainer(pMap), pPrevKeyNode(pPrevKeyNode) {} : pContainer(pMap), pPrevKeyNode(pPreviousKeyNode) {}
void* pContainer; void* pContainer;
void* pPrevKeyNode; void* pPrevKeyNode;
@@ -74,6 +82,6 @@ class GraphBuilderAdapter : public EventHandler {
void RegisterAnchor(anchor_t anchor, void* pNode); void RegisterAnchor(anchor_t anchor, void* pNode);
void DispositionNode(void* pNode); void DispositionNode(void* pNode);
}; };
} } // namespace YAML
#endif // GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+32
View File
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- MSVC Debugger visualization hints for YAML::Node and YAML::detail::node -->
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="YAML::Node">
<DisplayString Condition="!m_isValid">{{invalid}}</DisplayString>
<DisplayString Condition="!m_pNode">{{pNode==nullptr}}</DisplayString>
<DisplayString>{{ {*m_pNode} }}</DisplayString>
<Expand>
<Item Condition="m_pNode->m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Scalar" Name="scalar">m_pNode->m_pRef._Ptr->m_pData._Ptr->m_scalar</Item>
<Item Condition="m_pNode->m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Sequence" Name="sequence">m_pNode->m_pRef._Ptr->m_pData._Ptr->m_sequence</Item>
<Item Condition="m_pNode->m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Map" Name="map">m_pNode->m_pRef._Ptr->m_pData._Ptr->m_map</Item>
<Item Name="[details]" >m_pNode->m_pRef._Ptr->m_pData._Ptr</Item>
</Expand>
</Type>
<Type Name="YAML::detail::node">
<DisplayString Condition="!m_pRef._Ptr">{{node:pRef==nullptr}}</DisplayString>
<DisplayString Condition="!m_pRef._Ptr->m_pData._Ptr">{{node:pRef->pData==nullptr}}</DisplayString>
<DisplayString Condition="!m_pRef._Ptr->m_pData._Ptr->m_isDefined">{{undefined}}</DisplayString>
<DisplayString Condition="m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Scalar">{{{m_pRef._Ptr->m_pData._Ptr->m_scalar}}}</DisplayString>
<DisplayString Condition="m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Map">{{ Map {m_pRef._Ptr->m_pData._Ptr->m_map}}}</DisplayString>
<DisplayString Condition="m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Sequence">{{ Seq {m_pRef._Ptr->m_pData._Ptr->m_sequence}}}</DisplayString>
<DisplayString>{{{m_pRef._Ptr->m_pData._Ptr->m_type}}}</DisplayString>
<Expand>
<Item Condition="m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Scalar" Name="scalar">m_pRef._Ptr->m_pData._Ptr->m_scalar</Item>
<Item Condition="m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Sequence" Name="sequence">m_pRef._Ptr->m_pData._Ptr->m_sequence</Item>
<Item Condition="m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Map" Name="map">m_pRef._Ptr->m_pData._Ptr->m_map</Item>
<Item Name="[details]" >m_pRef._Ptr->m_pData._Ptr</Item>
</Expand>
</Type>
</AutoVisualizer>
+9
View File
@@ -0,0 +1,9 @@
# MSVC debugger visualizer for YAML::Node
## How to use
Add yaml-cpp.natvis to your Visual C++ project like any other source file. It will be included in the debug information, and improve debugger display on YAML::Node and contained types.
## Compatibility and Troubleshooting
This has been tested for MSVC 2017. It is expected to be compatible with VS 2015 and VS 2019. If you have any problems, you can open an issue here: https://github.com/peterchen-cp/yaml-cpp-natvis
+11 -8
View File
@@ -16,8 +16,8 @@ std::string tolower(const std::string& str) {
template <typename T> template <typename T>
bool IsEntirely(const std::string& str, T func) { bool IsEntirely(const std::string& str, T func) {
for (std::size_t i = 0; i < str.size(); i++) for (char ch : str)
if (!func(str[i])) if (!func(ch))
return false; return false;
return true; return true;
@@ -39,7 +39,7 @@ bool IsFlexibleCase(const std::string& str) {
std::string rest = str.substr(1); std::string rest = str.substr(1);
return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper)); return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper));
} }
} } // namespace
namespace YAML { namespace YAML {
bool convert<bool>::decode(const Node& node, bool& rhs) { bool convert<bool>::decode(const Node& node, bool& rhs) {
@@ -52,19 +52,22 @@ bool convert<bool>::decode(const Node& node, bool& rhs) {
static const struct { static const struct {
std::string truename, falsename; std::string truename, falsename;
} names[] = { } names[] = {
{"y", "n"}, {"yes", "no"}, {"true", "false"}, {"on", "off"}, {"y", "n"},
{"yes", "no"},
{"true", "false"},
{"on", "off"},
}; };
if (!IsFlexibleCase(node.Scalar())) if (!IsFlexibleCase(node.Scalar()))
return false; return false;
for (unsigned i = 0; i < sizeof(names) / sizeof(names[0]); i++) { for (const auto& name : names) {
if (names[i].truename == tolower(node.Scalar())) { if (name.truename == tolower(node.Scalar())) {
rhs = true; rhs = true;
return true; return true;
} }
if (names[i].falsename == tolower(node.Scalar())) { if (name.falsename == tolower(node.Scalar())) {
rhs = false; rhs = false;
return true; return true;
} }
@@ -72,4 +75,4 @@ bool convert<bool>::decode(const Node& node, bool& rhs) {
return false; return false;
} }
} } // namespace YAML
+2 -7
View File
@@ -1,12 +1,7 @@
#include "directives.h" #include "directives.h"
namespace YAML { namespace YAML {
Directives::Directives() { Directives::Directives() : version{true, 1, 2}, tags{} {}
// version
version.isDefault = true;
version.major = 1;
version.minor = 2;
}
const std::string Directives::TranslateTagHandle( const std::string Directives::TranslateTagHandle(
const std::string& handle) const { const std::string& handle) const {
@@ -19,4 +14,4 @@ const std::string Directives::TranslateTagHandle(
return it->second; return it->second;
} }
} } // namespace YAML
+4 -3
View File
@@ -16,10 +16,11 @@ std::string ToString(YAML::anchor_t anchor) {
stream << anchor; stream << anchor;
return stream.str(); return stream.str();
} }
} } // namespace
namespace YAML { namespace YAML {
EmitFromEvents::EmitFromEvents(Emitter& emitter) : m_emitter(emitter) {} EmitFromEvents::EmitFromEvents(Emitter& emitter)
: m_emitter(emitter), m_stateStack{} {}
void EmitFromEvents::OnDocumentStart(const Mark&) {} void EmitFromEvents::OnDocumentStart(const Mark&) {}
@@ -116,4 +117,4 @@ void EmitFromEvents::EmitProps(const std::string& tag, anchor_t anchor) {
if (anchor) if (anchor)
m_emitter << Anchor(ToString(anchor)); m_emitter << Anchor(ToString(anchor));
} }
} } // namespace YAML
+5 -7
View File
@@ -11,12 +11,12 @@ namespace YAML {
class Binary; class Binary;
struct _Null; struct _Null;
Emitter::Emitter() : m_pState(new EmitterState) {} Emitter::Emitter() : m_pState(new EmitterState), m_stream{} {}
Emitter::Emitter(std::ostream& stream) Emitter::Emitter(std::ostream& stream)
: m_pState(new EmitterState), m_stream(stream) {} : m_pState(new EmitterState), m_stream(stream) {}
Emitter::~Emitter() {} Emitter::~Emitter() = default;
const char* Emitter::c_str() const { return m_stream.str(); } const char* Emitter::c_str() const { return m_stream.str(); }
@@ -285,10 +285,8 @@ void Emitter::PrepareTopNode(EmitterNodeType::value child) {
if (child == EmitterNodeType::NoType) if (child == EmitterNodeType::NoType)
return; return;
if (m_pState->CurGroupChildCount() > 0 && m_stream.col() > 0) { if (m_pState->CurGroupChildCount() > 0 && m_stream.col() > 0)
if (child != EmitterNodeType::NoType) EmitBeginDoc();
EmitBeginDoc();
}
switch (child) { switch (child) {
case EmitterNodeType::NoType: case EmitterNodeType::NoType:
@@ -908,4 +906,4 @@ Emitter& Emitter::Write(const Binary& binary) {
return *this; return *this;
} }
} } // namespace YAML
+25 -21
View File
@@ -6,29 +6,33 @@
namespace YAML { namespace YAML {
EmitterState::EmitterState() EmitterState::EmitterState()
: m_isGood(true), : m_isGood(true),
m_lastError{},
// default global manipulators
m_charset(EmitNonAscii),
m_strFmt(Auto),
m_boolFmt(TrueFalseBool),
m_boolLengthFmt(LongBool),
m_boolCaseFmt(LowerCase),
m_intFmt(Dec),
m_indent(2),
m_preCommentIndent(2),
m_postCommentIndent(1),
m_seqFmt(Block),
m_mapFmt(Block),
m_mapKeyFmt(Auto),
m_floatPrecision(std::numeric_limits<float>::max_digits10),
m_doublePrecision(std::numeric_limits<double>::max_digits10),
//
m_modifiedSettings{},
m_globalModifiedSettings{},
m_groups{},
m_curIndent(0), m_curIndent(0),
m_hasAnchor(false), m_hasAnchor(false),
m_hasTag(false), m_hasTag(false),
m_hasNonContent(false), m_hasNonContent(false),
m_docCount(0) { m_docCount(0) {}
// set default global manipulators
m_charset.set(EmitNonAscii);
m_strFmt.set(Auto);
m_boolFmt.set(TrueFalseBool);
m_boolLengthFmt.set(LongBool);
m_boolCaseFmt.set(LowerCase);
m_intFmt.set(Dec);
m_indent.set(2);
m_preCommentIndent.set(2);
m_postCommentIndent.set(1);
m_seqFmt.set(Block);
m_mapFmt.set(Block);
m_mapKeyFmt.set(Auto);
m_floatPrecision.set(std::numeric_limits<float>::digits10 + 1);
m_doublePrecision.set(std::numeric_limits<double>::digits10 + 1);
}
EmitterState::~EmitterState() {} EmitterState::~EmitterState() = default;
// SetLocalValue // SetLocalValue
// . We blindly tries to set all possible formatters to this value // . We blindly tries to set all possible formatters to this value
@@ -349,7 +353,7 @@ bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope) {
} }
bool EmitterState::SetFloatPrecision(std::size_t value, FmtScope::value scope) { bool EmitterState::SetFloatPrecision(std::size_t value, FmtScope::value scope) {
if (value > std::numeric_limits<float>::digits10 + 1) if (value > std::numeric_limits<float>::max_digits10)
return false; return false;
_Set(m_floatPrecision, value, scope); _Set(m_floatPrecision, value, scope);
return true; return true;
@@ -357,9 +361,9 @@ bool EmitterState::SetFloatPrecision(std::size_t value, FmtScope::value scope) {
bool EmitterState::SetDoublePrecision(std::size_t value, bool EmitterState::SetDoublePrecision(std::size_t value,
FmtScope::value scope) { FmtScope::value scope) {
if (value > std::numeric_limits<double>::digits10 + 1) if (value > std::numeric_limits<double>::max_digits10)
return false; return false;
_Set(m_doublePrecision, value, scope); _Set(m_doublePrecision, value, scope);
return true; return true;
} }
} } // namespace YAML
+7 -2
View File
@@ -145,7 +145,12 @@ class EmitterState {
struct Group { struct Group {
explicit Group(GroupType::value type_) explicit Group(GroupType::value type_)
: type(type_), indent(0), childCount(0), longKey(false) {} : type(type_),
flowType{},
indent(0),
childCount(0),
longKey(false),
modifiedSettings{} {}
GroupType::value type; GroupType::value type;
FlowType::value flowType; FlowType::value flowType;
@@ -198,6 +203,6 @@ void EmitterState::_Set(Setting<T>& fmt, T value, FmtScope::value scope) {
assert(false); assert(false);
} }
} }
} } // namespace YAML
#endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+19 -19
View File
@@ -8,8 +8,8 @@
#include "regeximpl.h" #include "regeximpl.h"
#include "stringsource.h" #include "stringsource.h"
#include "yaml-cpp/binary.h" // IWYU pragma: keep #include "yaml-cpp/binary.h" // IWYU pragma: keep
#include "yaml-cpp/ostream_wrapper.h"
#include "yaml-cpp/null.h" #include "yaml-cpp/null.h"
#include "yaml-cpp/ostream_wrapper.h"
namespace YAML { namespace YAML {
namespace Utils { namespace Utils {
@@ -134,12 +134,12 @@ void WriteCodePoint(ostream_wrapper& out, int codePoint) {
if (codePoint < 0 || codePoint > 0x10FFFF) { if (codePoint < 0 || codePoint > 0x10FFFF) {
codePoint = REPLACEMENT_CHARACTER; codePoint = REPLACEMENT_CHARACTER;
} }
if (codePoint < 0x7F) { if (codePoint <= 0x7F) {
out << static_cast<char>(codePoint); out << static_cast<char>(codePoint);
} else if (codePoint < 0x7FF) { } else if (codePoint <= 0x7FF) {
out << static_cast<char>(0xC0 | (codePoint >> 6)) out << static_cast<char>(0xC0 | (codePoint >> 6))
<< static_cast<char>(0x80 | (codePoint & 0x3F)); << static_cast<char>(0x80 | (codePoint & 0x3F));
} else if (codePoint < 0xFFFF) { } else if (codePoint <= 0xFFFF) {
out << static_cast<char>(0xE0 | (codePoint >> 12)) out << static_cast<char>(0xE0 | (codePoint >> 12))
<< static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F)) << static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F))
<< static_cast<char>(0x80 | (codePoint & 0x3F)); << static_cast<char>(0x80 | (codePoint & 0x3F));
@@ -173,12 +173,12 @@ bool IsValidPlainScalar(const std::string& str, FlowType::value flowType,
// then check until something is disallowed // then check until something is disallowed
static const RegEx& disallowed_flow = static const RegEx& disallowed_flow =
Exp::EndScalarInFlow() || (Exp::BlankOrBreak() + Exp::Comment()) || Exp::EndScalarInFlow() | (Exp::BlankOrBreak() + Exp::Comment()) |
Exp::NotPrintable() || Exp::Utf8_ByteOrderMark() || Exp::Break() || Exp::NotPrintable() | Exp::Utf8_ByteOrderMark() | Exp::Break() |
Exp::Tab(); Exp::Tab();
static const RegEx& disallowed_block = static const RegEx& disallowed_block =
Exp::EndScalar() || (Exp::BlankOrBreak() + Exp::Comment()) || Exp::EndScalar() | (Exp::BlankOrBreak() + Exp::Comment()) |
Exp::NotPrintable() || Exp::Utf8_ByteOrderMark() || Exp::Break() || Exp::NotPrintable() | Exp::Utf8_ByteOrderMark() | Exp::Break() |
Exp::Tab(); Exp::Tab();
const RegEx& disallowed = const RegEx& disallowed =
flowType == FlowType::Flow ? disallowed_flow : disallowed_block; flowType == FlowType::Flow ? disallowed_flow : disallowed_block;
@@ -199,11 +199,11 @@ bool IsValidPlainScalar(const std::string& str, FlowType::value flowType,
bool IsValidSingleQuotedScalar(const std::string& str, bool escapeNonAscii) { bool IsValidSingleQuotedScalar(const std::string& str, bool escapeNonAscii) {
// TODO: check for non-printable characters? // TODO: check for non-printable characters?
for (std::size_t i = 0; i < str.size(); i++) { for (char ch : str) {
if (escapeNonAscii && (0x80 <= static_cast<unsigned char>(str[i]))) { if (escapeNonAscii && (0x80 <= static_cast<unsigned char>(ch))) {
return false; return false;
} }
if (str[i] == '\n') { if (ch == '\n') {
return false; return false;
} }
} }
@@ -217,8 +217,8 @@ bool IsValidLiteralScalar(const std::string& str, FlowType::value flowType,
} }
// TODO: check for non-printable characters? // TODO: check for non-printable characters?
for (std::size_t i = 0; i < str.size(); i++) { for (char ch : str) {
if (escapeNonAscii && (0x80 <= static_cast<unsigned char>(str[i]))) { if (escapeNonAscii && (0x80 <= static_cast<unsigned char>(ch))) {
return false; return false;
} }
} }
@@ -258,7 +258,7 @@ bool WriteAliasName(ostream_wrapper& out, const std::string& str) {
} }
return true; return true;
} }
} } // namespace
StringFormat::value ComputeStringFormat(const std::string& str, StringFormat::value ComputeStringFormat(const std::string& str,
EMITTER_MANIP strFormat, EMITTER_MANIP strFormat,
@@ -382,7 +382,7 @@ bool WriteChar(ostream_wrapper& out, char ch) {
out << "\"\\b\""; out << "\"\\b\"";
} else if (ch == '\\') { } else if (ch == '\\') {
out << "\"\\\\\""; out << "\"\\\\\"";
} else if ((0x20 <= ch && ch <= 0x7e) || ch == ' ') { } else if (0x20 <= ch && ch <= 0x7e) {
out << "\"" << ch << "\""; out << "\"" << ch << "\"";
} else { } else {
out << "\""; out << "\"";
@@ -401,8 +401,8 @@ bool WriteComment(ostream_wrapper& out, const std::string& str,
for (std::string::const_iterator i = str.begin(); for (std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end());) { GetNextCodePointAndAdvance(codePoint, i, str.end());) {
if (codePoint == '\n') { if (codePoint == '\n') {
out << "\n" << IndentTo(curIndent) << "#" out << "\n"
<< Indentation(postCommentIndent); << IndentTo(curIndent) << "#" << Indentation(postCommentIndent);
out.set_comment(); out.set_comment();
} else { } else {
WriteCodePoint(out, codePoint); WriteCodePoint(out, codePoint);
@@ -479,5 +479,5 @@ bool WriteBinary(ostream_wrapper& out, const Binary& binary) {
false); false);
return true; return true;
} }
} } // namespace Utils
} } // namespace YAML
+31 -22
View File
@@ -1,31 +1,40 @@
#include "yaml-cpp/exceptions.h" #include "yaml-cpp/exceptions.h"
#include "yaml-cpp/noexcept.h"
// This is here for compatibility with older versions of Visual Studio
// which don't support noexcept
#ifdef _MSC_VER
#define YAML_CPP_NOEXCEPT _NOEXCEPT
#else
#define YAML_CPP_NOEXCEPT noexcept
#endif
namespace YAML { namespace YAML {
// These destructors are defined out-of-line so the vtable is only emitted once. // These destructors are defined out-of-line so the vtable is only emitted once.
Exception::~Exception() YAML_CPP_NOEXCEPT {} Exception::~Exception() YAML_CPP_NOEXCEPT = default;
ParserException::~ParserException() YAML_CPP_NOEXCEPT {} ParserException::~ParserException() YAML_CPP_NOEXCEPT = default;
RepresentationException::~RepresentationException() YAML_CPP_NOEXCEPT {} RepresentationException::~RepresentationException() YAML_CPP_NOEXCEPT = default;
InvalidScalar::~InvalidScalar() YAML_CPP_NOEXCEPT {} InvalidScalar::~InvalidScalar() YAML_CPP_NOEXCEPT = default;
KeyNotFound::~KeyNotFound() YAML_CPP_NOEXCEPT {} KeyNotFound::~KeyNotFound() YAML_CPP_NOEXCEPT = default;
InvalidNode::~InvalidNode() YAML_CPP_NOEXCEPT {} InvalidNode::~InvalidNode() YAML_CPP_NOEXCEPT = default;
BadConversion::~BadConversion() YAML_CPP_NOEXCEPT {} BadConversion::~BadConversion() YAML_CPP_NOEXCEPT = default;
BadDereference::~BadDereference() YAML_CPP_NOEXCEPT {} BadDereference::~BadDereference() YAML_CPP_NOEXCEPT = default;
BadSubscript::~BadSubscript() YAML_CPP_NOEXCEPT {} BadSubscript::~BadSubscript() YAML_CPP_NOEXCEPT = default;
BadPushback::~BadPushback() YAML_CPP_NOEXCEPT {} BadPushback::~BadPushback() YAML_CPP_NOEXCEPT = default;
BadInsert::~BadInsert() YAML_CPP_NOEXCEPT {} BadInsert::~BadInsert() YAML_CPP_NOEXCEPT = default;
EmitterException::~EmitterException() YAML_CPP_NOEXCEPT {} EmitterException::~EmitterException() YAML_CPP_NOEXCEPT = default;
BadFile::~BadFile() YAML_CPP_NOEXCEPT {} BadFile::~BadFile() YAML_CPP_NOEXCEPT = default;
[[noreturn]] void throw_bad_subscript()
{
throw BadSubscript(0);
} }
#undef YAML_CPP_NOEXCEPT [[noreturn]] void throw_invalid_node(const std::string& key)
{
throw InvalidNode(key);
}
[[noreturn]] void throw_bad_conversion(const YAML::Mark& mark)
{
throw BadConversion(mark);
}
[[noreturn]] void throw_bad_insert()
{
throw BadInsert();
}
}
+3 -4
View File
@@ -12,8 +12,7 @@ namespace YAML {
namespace Exp { namespace Exp {
unsigned ParseHex(const std::string& str, const Mark& mark) { unsigned ParseHex(const std::string& str, const Mark& mark) {
unsigned value = 0; unsigned value = 0;
for (std::size_t i = 0; i < str.size(); i++) { for (char ch : str) {
char ch = str[i];
int digit = 0; int digit = 0;
if ('a' <= ch && ch <= 'f') if ('a' <= ch && ch <= 'f')
digit = ch - 'a' + 10; digit = ch - 'a' + 10;
@@ -132,5 +131,5 @@ std::string Escape(Stream& in) {
std::stringstream msg; std::stringstream msg;
throw ParserException(in.mark(), std::string(ErrorMsg::INVALID_ESCAPE) + ch); throw ParserException(in.mark(), std::string(ErrorMsg::INVALID_ESCAPE) + ch);
} }
} } // namespace Exp
} } // namespace YAML
+30 -30
View File
@@ -33,15 +33,15 @@ inline const RegEx& Tab() {
return e; return e;
} }
inline const RegEx& Blank() { inline const RegEx& Blank() {
static const RegEx e = Space() || Tab(); static const RegEx e = Space() | Tab();
return e; return e;
} }
inline const RegEx& Break() { inline const RegEx& Break() {
static const RegEx e = RegEx('\n') || RegEx("\r\n"); static const RegEx e = RegEx('\n') | RegEx("\r\n");
return e; return e;
} }
inline const RegEx& BlankOrBreak() { inline const RegEx& BlankOrBreak() {
static const RegEx e = Blank() || Break(); static const RegEx e = Blank() | Break();
return e; return e;
} }
inline const RegEx& Digit() { inline const RegEx& Digit() {
@@ -49,29 +49,29 @@ inline const RegEx& Digit() {
return e; return e;
} }
inline const RegEx& Alpha() { inline const RegEx& Alpha() {
static const RegEx e = RegEx('a', 'z') || RegEx('A', 'Z'); static const RegEx e = RegEx('a', 'z') | RegEx('A', 'Z');
return e; return e;
} }
inline const RegEx& AlphaNumeric() { inline const RegEx& AlphaNumeric() {
static const RegEx e = Alpha() || Digit(); static const RegEx e = Alpha() | Digit();
return e; return e;
} }
inline const RegEx& Word() { inline const RegEx& Word() {
static const RegEx e = AlphaNumeric() || RegEx('-'); static const RegEx e = AlphaNumeric() | RegEx('-');
return e; return e;
} }
inline const RegEx& Hex() { inline const RegEx& Hex() {
static const RegEx e = Digit() || RegEx('A', 'F') || RegEx('a', 'f'); static const RegEx e = Digit() | RegEx('A', 'F') | RegEx('a', 'f');
return e; return e;
} }
// Valid Unicode code points that are not part of c-printable (YAML 1.2, sec. // Valid Unicode code points that are not part of c-printable (YAML 1.2, sec.
// 5.1) // 5.1)
inline const RegEx& NotPrintable() { inline const RegEx& NotPrintable() {
static const RegEx e = static const RegEx e =
RegEx(0) || RegEx(0) |
RegEx("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) || RegEx("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) |
RegEx(0x0E, 0x1F) || RegEx(0x0E, 0x1F) |
(RegEx('\xC2') + (RegEx('\x80', '\x84') || RegEx('\x86', '\x9F'))); (RegEx('\xC2') + (RegEx('\x80', '\x84') | RegEx('\x86', '\x9F')));
return e; return e;
} }
inline const RegEx& Utf8_ByteOrderMark() { inline const RegEx& Utf8_ByteOrderMark() {
@@ -82,19 +82,19 @@ inline const RegEx& Utf8_ByteOrderMark() {
// actual tags // actual tags
inline const RegEx& DocStart() { inline const RegEx& DocStart() {
static const RegEx e = RegEx("---") + (BlankOrBreak() || RegEx()); static const RegEx e = RegEx("---") + (BlankOrBreak() | RegEx());
return e; return e;
} }
inline const RegEx& DocEnd() { inline const RegEx& DocEnd() {
static const RegEx e = RegEx("...") + (BlankOrBreak() || RegEx()); static const RegEx e = RegEx("...") + (BlankOrBreak() | RegEx());
return e; return e;
} }
inline const RegEx& DocIndicator() { inline const RegEx& DocIndicator() {
static const RegEx e = DocStart() || DocEnd(); static const RegEx e = DocStart() | DocEnd();
return e; return e;
} }
inline const RegEx& BlockEntry() { inline const RegEx& BlockEntry() {
static const RegEx e = RegEx('-') + (BlankOrBreak() || RegEx()); static const RegEx e = RegEx('-') + (BlankOrBreak() | RegEx());
return e; return e;
} }
inline const RegEx& Key() { inline const RegEx& Key() {
@@ -106,11 +106,11 @@ inline const RegEx& KeyInFlow() {
return e; return e;
} }
inline const RegEx& Value() { inline const RegEx& Value() {
static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx()); static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx());
return e; return e;
} }
inline const RegEx& ValueInFlow() { inline const RegEx& ValueInFlow() {
static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx(",}", REGEX_OR)); static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx(",}", REGEX_OR));
return e; return e;
} }
inline const RegEx& ValueInJSONFlow() { inline const RegEx& ValueInJSONFlow() {
@@ -122,20 +122,20 @@ inline const RegEx Comment() {
return e; return e;
} }
inline const RegEx& Anchor() { inline const RegEx& Anchor() {
static const RegEx e = !(RegEx("[]{},", REGEX_OR) || BlankOrBreak()); static const RegEx e = !(RegEx("[]{},", REGEX_OR) | BlankOrBreak());
return e; return e;
} }
inline const RegEx& AnchorEnd() { inline const RegEx& AnchorEnd() {
static const RegEx e = RegEx("?:,]}%@`", REGEX_OR) || BlankOrBreak(); static const RegEx e = RegEx("?:,]}%@`", REGEX_OR) | BlankOrBreak();
return e; return e;
} }
inline const RegEx& URI() { inline const RegEx& URI() {
static const RegEx e = Word() || RegEx("#;/?:@&=+$,_.!~*'()[]", REGEX_OR) || static const RegEx e = Word() | RegEx("#;/?:@&=+$,_.!~*'()[]", REGEX_OR) |
(RegEx('%') + Hex() + Hex()); (RegEx('%') + Hex() + Hex());
return e; return e;
} }
inline const RegEx& Tag() { inline const RegEx& Tag() {
static const RegEx e = Word() || RegEx("#;/?:@&=+$_.~*'()", REGEX_OR) || static const RegEx e = Word() | RegEx("#;/?:@&=+$_.~*'()", REGEX_OR) |
(RegEx('%') + Hex() + Hex()); (RegEx('%') + Hex() + Hex());
return e; return e;
} }
@@ -148,34 +148,34 @@ inline const RegEx& Tag() {
// space. // space.
inline const RegEx& PlainScalar() { inline const RegEx& PlainScalar() {
static const RegEx e = static const RegEx e =
!(BlankOrBreak() || RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) || !(BlankOrBreak() | RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) |
(RegEx("-?:", REGEX_OR) + (BlankOrBreak() || RegEx()))); (RegEx("-?:", REGEX_OR) + (BlankOrBreak() | RegEx())));
return e; return e;
} }
inline const RegEx& PlainScalarInFlow() { inline const RegEx& PlainScalarInFlow() {
static const RegEx e = static const RegEx e =
!(BlankOrBreak() || RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) || !(BlankOrBreak() | RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) |
(RegEx("-:", REGEX_OR) + Blank())); (RegEx("-:", REGEX_OR) + Blank()));
return e; return e;
} }
inline const RegEx& EndScalar() { inline const RegEx& EndScalar() {
static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx()); static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx());
return e; return e;
} }
inline const RegEx& EndScalarInFlow() { inline const RegEx& EndScalarInFlow() {
static const RegEx e = static const RegEx e =
(RegEx(':') + (BlankOrBreak() || RegEx() || RegEx(",]}", REGEX_OR))) || (RegEx(':') + (BlankOrBreak() | RegEx() | RegEx(",]}", REGEX_OR))) |
RegEx(",?[]{}", REGEX_OR); RegEx(",?[]{}", REGEX_OR);
return e; return e;
} }
inline const RegEx& ScanScalarEndInFlow() { inline const RegEx& ScanScalarEndInFlow() {
static const RegEx e = (EndScalarInFlow() || (BlankOrBreak() + Comment())); static const RegEx e = (EndScalarInFlow() | (BlankOrBreak() + Comment()));
return e; return e;
} }
inline const RegEx& ScanScalarEnd() { inline const RegEx& ScanScalarEnd() {
static const RegEx e = EndScalar() || (BlankOrBreak() + Comment()); static const RegEx e = EndScalar() | (BlankOrBreak() + Comment());
return e; return e;
} }
inline const RegEx& EscSingleQuote() { inline const RegEx& EscSingleQuote() {
@@ -192,8 +192,8 @@ inline const RegEx& ChompIndicator() {
return e; return e;
} }
inline const RegEx& Chomp() { inline const RegEx& Chomp() {
static const RegEx e = (ChompIndicator() + Digit()) || static const RegEx e = (ChompIndicator() + Digit()) |
(Digit() + ChompIndicator()) || ChompIndicator() || (Digit() + ChompIndicator()) | ChompIndicator() |
Digit(); Digit();
return e; return e;
} }
+25 -9
View File
@@ -1,4 +1,4 @@
#include <assert.h> #include <cassert>
#include <iterator> #include <iterator>
#include <sstream> #include <sstream>
@@ -13,14 +13,22 @@
namespace YAML { namespace YAML {
namespace detail { namespace detail {
std::string node_data::empty_scalar; const std::string& node_data::empty_scalar() {
static const std::string svalue;
return svalue;
}
node_data::node_data() node_data::node_data()
: m_isDefined(false), : m_isDefined(false),
m_mark(Mark::null_mark()), m_mark(Mark::null_mark()),
m_type(NodeType::Null), m_type(NodeType::Null),
m_tag{},
m_style(EmitterStyle::Default), m_style(EmitterStyle::Default),
m_seqSize(0) {} m_scalar{},
m_sequence{},
m_seqSize(0),
m_map{},
m_undefinedPairs{} {}
void node_data::mark_defined() { void node_data::mark_defined() {
if (m_type == NodeType::Undefined) if (m_type == NodeType::Undefined)
@@ -188,7 +196,7 @@ void node_data::insert(node& key, node& value, shared_memory_holder pMemory) {
convert_to_map(pMemory); convert_to_map(pMemory);
break; break;
case NodeType::Scalar: case NodeType::Scalar:
throw BadSubscript(); throw BadSubscript(key);
} }
insert_map_pair(key, value); insert_map_pair(key, value);
@@ -197,7 +205,7 @@ void node_data::insert(node& key, node& value, shared_memory_holder pMemory) {
// indexing // indexing
node* node_data::get(node& key, shared_memory_holder /* pMemory */) const { node* node_data::get(node& key, shared_memory_holder /* pMemory */) const {
if (m_type != NodeType::Map) { if (m_type != NodeType::Map) {
return NULL; return nullptr;
} }
for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
@@ -205,7 +213,7 @@ node* node_data::get(node& key, shared_memory_holder /* pMemory */) const {
return it->second; return it->second;
} }
return NULL; return nullptr;
} }
node& node_data::get(node& key, shared_memory_holder pMemory) { node& node_data::get(node& key, shared_memory_holder pMemory) {
@@ -218,7 +226,7 @@ node& node_data::get(node& key, shared_memory_holder pMemory) {
convert_to_map(pMemory); convert_to_map(pMemory);
break; break;
case NodeType::Scalar: case NodeType::Scalar:
throw BadSubscript(); throw BadSubscript(key);
} }
for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
@@ -235,6 +243,14 @@ bool node_data::remove(node& key, shared_memory_holder /* pMemory */) {
if (m_type != NodeType::Map) if (m_type != NodeType::Map)
return false; return false;
for (kv_pairs::iterator it = m_undefinedPairs.begin();
it != m_undefinedPairs.end();) {
kv_pairs::iterator jt = std::next(it);
if (it->first->is(key))
m_undefinedPairs.erase(it);
it = jt;
}
for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) { for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) {
if (it->first->is(key)) { if (it->first->is(key)) {
m_map.erase(it); m_map.erase(it);
@@ -296,5 +312,5 @@ void node_data::convert_sequence_to_map(shared_memory_holder pMemory) {
reset_sequence(); reset_sequence();
m_type = NodeType::Map; m_type = NodeType::Map;
} }
} } // namespace detail
} } // namespace YAML
+9 -5
View File
@@ -1,4 +1,3 @@
#include <assert.h>
#include <cassert> #include <cassert>
#include "nodebuilder.h" #include "nodebuilder.h"
@@ -11,11 +10,16 @@ namespace YAML {
struct Mark; struct Mark;
NodeBuilder::NodeBuilder() NodeBuilder::NodeBuilder()
: m_pMemory(new detail::memory_holder), m_pRoot(0), m_mapDepth(0) { : m_pMemory(new detail::memory_holder),
m_anchors.push_back(0); // since the anchors start at 1 m_pRoot(nullptr),
m_stack{},
m_anchors{},
m_keys{},
m_mapDepth(0) {
m_anchors.push_back(nullptr); // since the anchors start at 1
} }
NodeBuilder::~NodeBuilder() {} NodeBuilder::~NodeBuilder() = default;
Node NodeBuilder::Root() { Node NodeBuilder::Root() {
if (!m_pRoot) if (!m_pRoot)
@@ -127,4 +131,4 @@ void NodeBuilder::RegisterAnchor(anchor_t anchor, detail::node& node) {
m_anchors.push_back(&node); m_anchors.push_back(&node);
} }
} }
} } // namespace YAML
+20 -16
View File
@@ -27,25 +27,29 @@ class Node;
class NodeBuilder : public EventHandler { class NodeBuilder : public EventHandler {
public: public:
NodeBuilder(); NodeBuilder();
virtual ~NodeBuilder(); NodeBuilder(const NodeBuilder&) = delete;
NodeBuilder(NodeBuilder&&) = delete;
NodeBuilder& operator=(const NodeBuilder&) = delete;
NodeBuilder& operator=(NodeBuilder&&) = delete;
~NodeBuilder() override;
Node Root(); Node Root();
virtual void OnDocumentStart(const Mark& mark); void OnDocumentStart(const Mark& mark) override;
virtual void OnDocumentEnd(); void OnDocumentEnd() override;
virtual void OnNull(const Mark& mark, anchor_t anchor); void OnNull(const Mark& mark, anchor_t anchor) override;
virtual void OnAlias(const Mark& mark, anchor_t anchor); void OnAlias(const Mark& mark, anchor_t anchor) override;
virtual void OnScalar(const Mark& mark, const std::string& tag, void OnScalar(const Mark& mark, const std::string& tag,
anchor_t anchor, const std::string& value); anchor_t anchor, const std::string& value) override;
virtual void OnSequenceStart(const Mark& mark, const std::string& tag, void OnSequenceStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style); anchor_t anchor, EmitterStyle::value style) override;
virtual void OnSequenceEnd(); void OnSequenceEnd() override;
virtual void OnMapStart(const Mark& mark, const std::string& tag, void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style); anchor_t anchor, EmitterStyle::value style) override;
virtual void OnMapEnd(); void OnMapEnd() override;
private: private:
detail::node& Push(const Mark& mark, anchor_t anchor); detail::node& Push(const Mark& mark, anchor_t anchor);
@@ -57,14 +61,14 @@ class NodeBuilder : public EventHandler {
detail::shared_memory_holder m_pMemory; detail::shared_memory_holder m_pMemory;
detail::node* m_pRoot; detail::node* m_pRoot;
typedef std::vector<detail::node*> Nodes; using Nodes = std::vector<detail::node *>;
Nodes m_stack; Nodes m_stack;
Nodes m_anchors; Nodes m_anchors;
typedef std::pair<detail::node*, bool> PushedKey; using PushedKey = std::pair<detail::node*, bool>;
std::vector<PushedKey> m_keys; std::vector<PushedKey> m_keys;
std::size_t m_mapDepth; std::size_t m_mapDepth;
}; };
} } // namespace YAML
#endif // NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+2 -2
View File
@@ -20,7 +20,7 @@ anchor_t NodeEvents::AliasManager::LookupAnchor(
} }
NodeEvents::NodeEvents(const Node& node) NodeEvents::NodeEvents(const Node& node)
: m_pMemory(node.m_pMemory), m_root(node.m_pNode) { : m_pMemory(node.m_pMemory), m_root(node.m_pNode), m_refCount{} {
if (m_root) if (m_root)
Setup(*m_root); Setup(*m_root);
} }
@@ -98,4 +98,4 @@ bool NodeEvents::IsAliased(const detail::node& node) const {
RefCount::const_iterator it = m_refCount.find(node.ref()); RefCount::const_iterator it = m_refCount.find(node.ref());
return it != m_refCount.end() && it->second > 1; return it != m_refCount.end() && it->second > 1;
} }
} } // namespace YAML
+8 -4
View File
@@ -26,13 +26,17 @@ class Node;
class NodeEvents { class NodeEvents {
public: public:
explicit NodeEvents(const Node& node); explicit NodeEvents(const Node& node);
NodeEvents(const NodeEvents&) = delete;
NodeEvents(NodeEvents&&) = delete;
NodeEvents& operator=(const NodeEvents&) = delete;
NodeEvents& operator=(NodeEvents&&) = delete;
void Emit(EventHandler& handler); void Emit(EventHandler& handler);
private: private:
class AliasManager { class AliasManager {
public: public:
AliasManager() : m_curAnchor(0) {} AliasManager() : m_anchorByIdentity{}, m_curAnchor(0) {}
void RegisterReference(const detail::node& node); void RegisterReference(const detail::node& node);
anchor_t LookupAnchor(const detail::node& node) const; anchor_t LookupAnchor(const detail::node& node) const;
@@ -41,7 +45,7 @@ class NodeEvents {
anchor_t _CreateNewAnchor() { return ++m_curAnchor; } anchor_t _CreateNewAnchor() { return ++m_curAnchor; }
private: private:
typedef std::map<const detail::node_ref*, anchor_t> AnchorByIdentity; using AnchorByIdentity = std::map<const detail::node_ref*, anchor_t>;
AnchorByIdentity m_anchorByIdentity; AnchorByIdentity m_anchorByIdentity;
anchor_t m_curAnchor; anchor_t m_curAnchor;
@@ -56,9 +60,9 @@ class NodeEvents {
detail::shared_memory_holder m_pMemory; detail::shared_memory_holder m_pMemory;
detail::node* m_root; detail::node* m_root;
typedef std::map<const detail::node_ref*, int> RefCount; using RefCount = std::map<const detail::node_ref*, int>;
RefCount m_refCount; RefCount m_refCount;
}; };
} } // namespace YAML
#endif // NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+11 -6
View File
@@ -7,16 +7,21 @@
namespace YAML { namespace YAML {
ostream_wrapper::ostream_wrapper() ostream_wrapper::ostream_wrapper()
: m_buffer(1, '\0'), : m_buffer(1, '\0'),
m_pStream(0), m_pStream(nullptr),
m_pos(0), m_pos(0),
m_row(0), m_row(0),
m_col(0), m_col(0),
m_comment(false) {} m_comment(false) {}
ostream_wrapper::ostream_wrapper(std::ostream& stream) ostream_wrapper::ostream_wrapper(std::ostream& stream)
: m_pStream(&stream), m_pos(0), m_row(0), m_col(0), m_comment(false) {} : m_buffer{},
m_pStream(&stream),
m_pos(0),
m_row(0),
m_col(0),
m_comment(false) {}
ostream_wrapper::~ostream_wrapper() {} ostream_wrapper::~ostream_wrapper() = default;
void ostream_wrapper::write(const std::string& str) { void ostream_wrapper::write(const std::string& str) {
if (m_pStream) { if (m_pStream) {
@@ -26,8 +31,8 @@ void ostream_wrapper::write(const std::string& str) {
std::copy(str.begin(), str.end(), m_buffer.begin() + m_pos); std::copy(str.begin(), str.end(), m_buffer.begin() + m_pos);
} }
for (std::size_t i = 0; i < str.size(); i++) { for (char ch : str) {
update_pos(str[i]); update_pos(ch);
} }
} }
@@ -54,4 +59,4 @@ void ostream_wrapper::update_pos(char ch) {
m_comment = false; m_comment = false;
} }
} }
} } // namespace YAML
+9 -17
View File
@@ -11,14 +11,14 @@
namespace YAML { namespace YAML {
class EventHandler; class EventHandler;
Parser::Parser() {} Parser::Parser() : m_pScanner{}, m_pDirectives{} {}
Parser::Parser(std::istream& in) { Load(in); } Parser::Parser(std::istream& in) : Parser() { Load(in); }
Parser::~Parser() {} Parser::~Parser() = default;
Parser::operator bool() const { Parser::operator bool() const {
return m_pScanner.get() && !m_pScanner->empty(); return m_pScanner && !m_pScanner->empty();
} }
void Parser::Load(std::istream& in) { void Parser::Load(std::istream& in) {
@@ -27,7 +27,7 @@ void Parser::Load(std::istream& in) {
} }
bool Parser::HandleNextDocument(EventHandler& eventHandler) { bool Parser::HandleNextDocument(EventHandler& eventHandler) {
if (!m_pScanner.get()) if (!m_pScanner)
return false; return false;
ParseDirectives(); ParseDirectives();
@@ -43,11 +43,7 @@ bool Parser::HandleNextDocument(EventHandler& eventHandler) {
void Parser::ParseDirectives() { void Parser::ParseDirectives() {
bool readDirective = false; bool readDirective = false;
while (1) { while (!m_pScanner->empty()) {
if (m_pScanner->empty()) {
break;
}
Token& token = m_pScanner->peek(); Token& token = m_pScanner->peek();
if (token.type != Token::DIRECTIVE) { if (token.type != Token::DIRECTIVE) {
break; break;
@@ -113,17 +109,13 @@ void Parser::HandleTagDirective(const Token& token) {
} }
void Parser::PrintTokens(std::ostream& out) { void Parser::PrintTokens(std::ostream& out) {
if (!m_pScanner.get()) { if (!m_pScanner) {
return; return;
} }
while (1) { while (!m_pScanner->empty()) {
if (m_pScanner->empty()) {
break;
}
out << m_pScanner->peek() << "\n"; out << m_pScanner->peek() << "\n";
m_pScanner->pop(); m_pScanner->pop();
} }
} }
} } // namespace YAML
+7 -5
View File
@@ -12,15 +12,17 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "yaml-cpp/noncopyable.h"
namespace YAML { namespace YAML {
// TODO: This class is no longer needed // TODO: This class is no longer needed
template <typename T> template <typename T>
class ptr_vector : private YAML::noncopyable { class ptr_vector {
public: public:
ptr_vector() {} ptr_vector() : m_data{} {}
ptr_vector(const ptr_vector&) = delete;
ptr_vector(ptr_vector&&) = default;
ptr_vector& operator=(const ptr_vector&) = delete;
ptr_vector& operator=(ptr_vector&&) = default;
void clear() { m_data.clear(); } void clear() { m_data.clear(); }
@@ -38,6 +40,6 @@ class ptr_vector : private YAML::noncopyable {
private: private:
std::vector<std::unique_ptr<T>> m_data; std::vector<std::unique_ptr<T>> m_data;
}; };
} } // namespace YAML
#endif // PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+9 -11
View File
@@ -2,18 +2,16 @@
namespace YAML { namespace YAML {
// constructors // constructors
RegEx::RegEx() : m_op(REGEX_EMPTY) {}
RegEx::RegEx(REGEX_OP op) : m_op(op) {} RegEx::RegEx(REGEX_OP op) : m_op(op), m_a(0), m_z(0), m_params{} {}
RegEx::RegEx() : RegEx(REGEX_EMPTY) {}
RegEx::RegEx(char ch) : m_op(REGEX_MATCH), m_a(ch) {} RegEx::RegEx(char ch) : m_op(REGEX_MATCH), m_a(ch), m_z(0), m_params{} {}
RegEx::RegEx(char a, char z) : m_op(REGEX_RANGE), m_a(a), m_z(z) {} RegEx::RegEx(char a, char z) : m_op(REGEX_RANGE), m_a(a), m_z(z), m_params{} {}
RegEx::RegEx(const std::string& str, REGEX_OP op) : m_op(op) { RegEx::RegEx(const std::string& str, REGEX_OP op)
for (std::size_t i = 0; i < str.size(); i++) : m_op(op), m_a(0), m_z(0), m_params(str.begin(), str.end()) {}
m_params.push_back(RegEx(str[i]));
}
// combination constructors // combination constructors
RegEx operator!(const RegEx& ex) { RegEx operator!(const RegEx& ex) {
@@ -22,14 +20,14 @@ RegEx operator!(const RegEx& ex) {
return ret; return ret;
} }
RegEx operator||(const RegEx& ex1, const RegEx& ex2) { RegEx operator|(const RegEx& ex1, const RegEx& ex2) {
RegEx ret(REGEX_OR); RegEx ret(REGEX_OR);
ret.m_params.push_back(ex1); ret.m_params.push_back(ex1);
ret.m_params.push_back(ex2); ret.m_params.push_back(ex2);
return ret; return ret;
} }
RegEx operator&&(const RegEx& ex1, const RegEx& ex2) { RegEx operator&(const RegEx& ex1, const RegEx& ex2) {
RegEx ret(REGEX_AND); RegEx ret(REGEX_AND);
ret.m_params.push_back(ex1); ret.m_params.push_back(ex1);
ret.m_params.push_back(ex2); ret.m_params.push_back(ex2);
@@ -42,4 +40,4 @@ RegEx operator+(const RegEx& ex1, const RegEx& ex2) {
ret.m_params.push_back(ex2); ret.m_params.push_back(ex2);
return ret; return ret;
} }
} } // namespace YAML
+8 -7
View File
@@ -31,14 +31,14 @@ enum REGEX_OP {
class YAML_CPP_API RegEx { class YAML_CPP_API RegEx {
public: public:
RegEx(); RegEx();
RegEx(char ch); explicit RegEx(char ch);
RegEx(char a, char z); RegEx(char a, char z);
RegEx(const std::string& str, REGEX_OP op = REGEX_SEQ); RegEx(const std::string& str, REGEX_OP op = REGEX_SEQ);
~RegEx() {} ~RegEx() = default;
friend YAML_CPP_API RegEx operator!(const RegEx& ex); friend YAML_CPP_API RegEx operator!(const RegEx& ex);
friend YAML_CPP_API RegEx operator||(const RegEx& ex1, const RegEx& ex2); friend YAML_CPP_API RegEx operator|(const RegEx& ex1, const RegEx& ex2);
friend YAML_CPP_API RegEx operator&&(const RegEx& ex1, const RegEx& ex2); friend YAML_CPP_API RegEx operator&(const RegEx& ex1, const RegEx& ex2);
friend YAML_CPP_API RegEx operator+(const RegEx& ex1, const RegEx& ex2); friend YAML_CPP_API RegEx operator+(const RegEx& ex1, const RegEx& ex2);
bool Matches(char ch) const; bool Matches(char ch) const;
@@ -53,7 +53,7 @@ class YAML_CPP_API RegEx {
int Match(const Source& source) const; int Match(const Source& source) const;
private: private:
RegEx(REGEX_OP op); explicit RegEx(REGEX_OP op);
template <typename Source> template <typename Source>
bool IsValidSource(const Source& source) const; bool IsValidSource(const Source& source) const;
@@ -77,10 +77,11 @@ class YAML_CPP_API RegEx {
private: private:
REGEX_OP m_op; REGEX_OP m_op;
char m_a, m_z; char m_a{};
char m_z{};
std::vector<RegEx> m_params; std::vector<RegEx> m_params;
}; };
} } // namespace YAML
#include "regeximpl.h" #include "regeximpl.h"
+11 -12
View File
@@ -8,8 +8,8 @@
#endif #endif
#include "stream.h" #include "stream.h"
#include "stringsource.h"
#include "streamcharsource.h" #include "streamcharsource.h"
#include "stringsource.h"
namespace YAML { namespace YAML {
// query matches // query matches
@@ -106,9 +106,8 @@ inline int RegEx::MatchOpEmpty(const Source& source) const {
template <> template <>
inline int RegEx::MatchOpEmpty<StringCharSource>( inline int RegEx::MatchOpEmpty<StringCharSource>(
const StringCharSource& source) const { const StringCharSource& source) const {
return !source return !source ? 0 : -1; // the empty regex only is successful on the empty
? 0 // string
: -1; // the empty regex only is successful on the empty string
} }
// MatchOperator // MatchOperator
@@ -130,8 +129,8 @@ inline int RegEx::MatchOpRange(const Source& source) const {
// OrOperator // OrOperator
template <typename Source> template <typename Source>
inline int RegEx::MatchOpOr(const Source& source) const { inline int RegEx::MatchOpOr(const Source& source) const {
for (std::size_t i = 0; i < m_params.size(); i++) { for (const RegEx& param : m_params) {
int n = m_params[i].MatchUnchecked(source); int n = param.MatchUnchecked(source);
if (n >= 0) if (n >= 0)
return n; return n;
} }
@@ -169,11 +168,11 @@ inline int RegEx::MatchOpNot(const Source& source) const {
template <typename Source> template <typename Source>
inline int RegEx::MatchOpSeq(const Source& source) const { inline int RegEx::MatchOpSeq(const Source& source) const {
int offset = 0; int offset = 0;
for (std::size_t i = 0; i < m_params.size(); i++) { for (const RegEx& param : m_params) {
int n = m_params[i].Match(source + offset); // note Match, not int n = param.Match(source + offset); // note Match, not
// MatchUnchecked because we // MatchUnchecked because we
// need to check validity after // need to check validity after
// the offset // the offset
if (n == -1) if (n == -1)
return -1; return -1;
offset += n; offset += n;
@@ -181,6 +180,6 @@ inline int RegEx::MatchOpSeq(const Source& source) const {
return offset; return offset;
} }
} } // namespace YAML
#endif // REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+10 -5
View File
@@ -9,12 +9,17 @@
namespace YAML { namespace YAML {
Scanner::Scanner(std::istream& in) Scanner::Scanner(std::istream& in)
: INPUT(in), : INPUT(in),
m_tokens{},
m_startedStream(false), m_startedStream(false),
m_endedStream(false), m_endedStream(false),
m_simpleKeyAllowed(false), m_simpleKeyAllowed(false),
m_canBeJSONFlow(false) {} m_canBeJSONFlow(false),
m_simpleKeys{},
m_indents{},
m_indentRefs{},
m_flows{} {}
Scanner::~Scanner() {} Scanner::~Scanner() = default;
bool Scanner::empty() { bool Scanner::empty() {
EnsureTokensInQueue(); EnsureTokensInQueue();
@@ -282,7 +287,7 @@ Scanner::IndentMarker* Scanner::PushIndentTo(int column,
IndentMarker::INDENT_TYPE type) { IndentMarker::INDENT_TYPE type) {
// are we in flow? // are we in flow?
if (InFlowContext()) { if (InFlowContext()) {
return 0; return nullptr;
} }
std::unique_ptr<IndentMarker> pIndent(new IndentMarker(column, type)); std::unique_ptr<IndentMarker> pIndent(new IndentMarker(column, type));
@@ -291,12 +296,12 @@ Scanner::IndentMarker* Scanner::PushIndentTo(int column,
// is this actually an indentation? // is this actually an indentation?
if (indent.column < lastIndent.column) { if (indent.column < lastIndent.column) {
return 0; return nullptr;
} }
if (indent.column == lastIndent.column && if (indent.column == lastIndent.column &&
!(indent.type == IndentMarker::SEQ && !(indent.type == IndentMarker::SEQ &&
lastIndent.type == IndentMarker::MAP)) { lastIndent.type == IndentMarker::MAP)) {
return 0; return nullptr;
} }
// push a start token // push a start token
+1 -1
View File
@@ -49,7 +49,7 @@ class Scanner {
enum INDENT_TYPE { MAP, SEQ, NONE }; enum INDENT_TYPE { MAP, SEQ, NONE };
enum STATUS { VALID, INVALID, UNKNOWN }; enum STATUS { VALID, INVALID, UNKNOWN };
IndentMarker(int column_, INDENT_TYPE type_) IndentMarker(int column_, INDENT_TYPE type_)
: column(column_), type(type_), status(VALID), pStartToken(0) {} : column(column_), type(type_), status(VALID), pStartToken(nullptr) {}
int column; int column;
INDENT_TYPE type; INDENT_TYPE type;
+1 -1
View File
@@ -183,7 +183,7 @@ std::string ScanScalar(Stream& INPUT, ScanScalarParams& params) {
case FOLD_FLOW: case FOLD_FLOW:
if (nextEmptyLine) { if (nextEmptyLine) {
scalar += "\n"; scalar += "\n";
} else if (!emptyLine && !nextEmptyLine && !escapedNewline) { } else if (!emptyLine && !escapedNewline) {
scalar += " "; scalar += " ";
} }
break; break;
+2 -2
View File
@@ -338,7 +338,7 @@ void Scanner::ScanQuotedScalar() {
// setup the scanning parameters // setup the scanning parameters
ScanScalarParams params; ScanScalarParams params;
RegEx end = (single ? RegEx(quote) && !Exp::EscSingleQuote() : RegEx(quote)); RegEx end = (single ? RegEx(quote) & !Exp::EscSingleQuote() : RegEx(quote));
params.end = &end; params.end = &end;
params.eatEnd = true; params.eatEnd = true;
params.escape = (single ? '\'' : '\\'); params.escape = (single ? '\'' : '\\');
@@ -434,4 +434,4 @@ void Scanner::ScanBlockScalar() {
token.value = scalar; token.value = scalar;
m_tokens.push(token); m_tokens.push(token);
} }
} } // namespace YAML
+36 -30
View File
@@ -7,17 +7,24 @@
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/noexcept.h"
#include <memory> #include <memory>
#include <utility>
#include <vector> #include <vector>
#include "yaml-cpp/noncopyable.h"
namespace YAML { namespace YAML {
class SettingChangeBase;
class SettingChangeBase {
public:
virtual ~SettingChangeBase() = default;
virtual void pop() = 0;
};
template <typename T> template <typename T>
class Setting { class Setting {
public: public:
Setting() : m_value() {} Setting() : m_value() {}
Setting(const T& value) : m_value() { set(value); }
const T get() const { return m_value; } const T get() const { return m_value; }
std::unique_ptr<SettingChangeBase> set(const T& value); std::unique_ptr<SettingChangeBase> set(const T& value);
@@ -27,21 +34,19 @@ class Setting {
T m_value; T m_value;
}; };
class SettingChangeBase {
public:
virtual ~SettingChangeBase() {}
virtual void pop() = 0;
};
template <typename T> template <typename T>
class SettingChange : public SettingChangeBase { class SettingChange : public SettingChangeBase {
public: public:
SettingChange(Setting<T>* pSetting) : m_pCurSetting(pSetting) { SettingChange(Setting<T>* pSetting)
// copy old setting to save its state : m_pCurSetting(pSetting),
m_oldSetting = *pSetting; m_oldSetting(*pSetting) // copy old setting to save its state
} {}
SettingChange(const SettingChange&) = delete;
SettingChange(SettingChange&&) = delete;
SettingChange& operator=(const SettingChange&) = delete;
SettingChange& operator=(SettingChange&&) = delete;
virtual void pop() { m_pCurSetting->restore(m_oldSetting); } void pop() override { m_pCurSetting->restore(m_oldSetting); }
private: private:
Setting<T>* m_pCurSetting; Setting<T>* m_pCurSetting;
@@ -55,17 +60,29 @@ inline std::unique_ptr<SettingChangeBase> Setting<T>::set(const T& value) {
return pChange; return pChange;
} }
class SettingChanges : private noncopyable { class SettingChanges {
public: public:
SettingChanges() {} SettingChanges() : m_settingChanges{} {}
SettingChanges(const SettingChanges&) = delete;
SettingChanges(SettingChanges&&) YAML_CPP_NOEXCEPT = default;
SettingChanges& operator=(const SettingChanges&) = delete;
SettingChanges& operator=(SettingChanges&& rhs) YAML_CPP_NOEXCEPT {
if (this == &rhs)
return *this;
clear();
std::swap(m_settingChanges, rhs.m_settingChanges);
return *this;
}
~SettingChanges() { clear(); } ~SettingChanges() { clear(); }
void clear() { void clear() YAML_CPP_NOEXCEPT {
restore(); restore();
m_settingChanges.clear(); m_settingChanges.clear();
} }
void restore() { void restore() YAML_CPP_NOEXCEPT {
for (setting_changes::const_iterator it = m_settingChanges.begin(); for (setting_changes::const_iterator it = m_settingChanges.begin();
it != m_settingChanges.end(); ++it) it != m_settingChanges.end(); ++it)
(*it)->pop(); (*it)->pop();
@@ -75,21 +92,10 @@ class SettingChanges : private noncopyable {
m_settingChanges.push_back(std::move(pSettingChange)); m_settingChanges.push_back(std::move(pSettingChange));
} }
// like std::unique_ptr - assignment is transfer of ownership
SettingChanges& operator=(SettingChanges&& rhs) {
if (this == &rhs)
return *this;
clear();
std::swap(m_settingChanges, rhs.m_settingChanges);
return *this;
}
private: private:
typedef std::vector<std::unique_ptr<SettingChangeBase>> setting_changes; using setting_changes = std::vector<std::unique_ptr<SettingChangeBase>>;
setting_changes m_settingChanges; setting_changes m_settingChanges;
}; };
} } // namespace YAML
#endif // SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+1 -1
View File
@@ -5,7 +5,7 @@ namespace YAML {
struct Mark; struct Mark;
Scanner::SimpleKey::SimpleKey(const Mark& mark_, std::size_t flowLevel_) Scanner::SimpleKey::SimpleKey(const Mark& mark_, std::size_t flowLevel_)
: mark(mark_), flowLevel(flowLevel_), pIndent(0), pMapStart(0), pKey(0) {} : mark(mark_), flowLevel(flowLevel_), pIndent(nullptr), pMapStart(nullptr), pKey(nullptr) {}
void Scanner::SimpleKey::Validate() { void Scanner::SimpleKey::Validate() {
// Note: pIndent will *not* be garbage here; // Note: pIndent will *not* be garbage here;
+24 -10
View File
@@ -18,9 +18,10 @@ SingleDocParser::SingleDocParser(Scanner& scanner, const Directives& directives)
: m_scanner(scanner), : m_scanner(scanner),
m_directives(directives), m_directives(directives),
m_pCollectionStack(new CollectionStack), m_pCollectionStack(new CollectionStack),
m_anchors{},
m_curAnchor(0) {} m_curAnchor(0) {}
SingleDocParser::~SingleDocParser() {} SingleDocParser::~SingleDocParser() = default;
// HandleDocument // HandleDocument
// . Handles the next document // . Handles the next document
@@ -71,8 +72,18 @@ void SingleDocParser::HandleNode(EventHandler& eventHandler) {
} }
std::string tag; std::string tag;
std::string anchor_name;
anchor_t anchor; anchor_t anchor;
ParseProperties(tag, anchor); ParseProperties(tag, anchor, anchor_name);
if (!anchor_name.empty())
eventHandler.OnAnchor(mark, anchor_name);
// after parsing properties, an empty node is again a possibility
if (m_scanner.empty()) {
eventHandler.OnNull(mark, anchor);
return;
}
const Token& token = m_scanner.peek(); const Token& token = m_scanner.peek();
@@ -166,10 +177,10 @@ void SingleDocParser::HandleBlockSequence(EventHandler& eventHandler) {
// check for null // check for null
if (!m_scanner.empty()) { if (!m_scanner.empty()) {
const Token& token = m_scanner.peek(); const Token& nextToken = m_scanner.peek();
if (token.type == Token::BLOCK_ENTRY || if (nextToken.type == Token::BLOCK_ENTRY ||
token.type == Token::BLOCK_SEQ_END) { nextToken.type == Token::BLOCK_SEQ_END) {
eventHandler.OnNull(token.mark, NullAnchor); eventHandler.OnNull(nextToken.mark, NullAnchor);
continue; continue;
} }
} }
@@ -356,8 +367,10 @@ void SingleDocParser::HandleCompactMapWithNoKey(EventHandler& eventHandler) {
// ParseProperties // ParseProperties
// . Grabs any tag or anchor tokens and deals with them. // . Grabs any tag or anchor tokens and deals with them.
void SingleDocParser::ParseProperties(std::string& tag, anchor_t& anchor) { void SingleDocParser::ParseProperties(std::string& tag, anchor_t& anchor,
std::string& anchor_name) {
tag.clear(); tag.clear();
anchor_name.clear();
anchor = NullAnchor; anchor = NullAnchor;
while (1) { while (1) {
@@ -369,7 +382,7 @@ void SingleDocParser::ParseProperties(std::string& tag, anchor_t& anchor) {
ParseTag(tag); ParseTag(tag);
break; break;
case Token::ANCHOR: case Token::ANCHOR:
ParseAnchor(anchor); ParseAnchor(anchor, anchor_name);
break; break;
default: default:
return; return;
@@ -387,11 +400,12 @@ void SingleDocParser::ParseTag(std::string& tag) {
m_scanner.pop(); m_scanner.pop();
} }
void SingleDocParser::ParseAnchor(anchor_t& anchor) { void SingleDocParser::ParseAnchor(anchor_t& anchor, std::string& anchor_name) {
Token& token = m_scanner.peek(); Token& token = m_scanner.peek();
if (anchor) if (anchor)
throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS); throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS);
anchor_name = token.value;
anchor = RegisterAnchor(token.value); anchor = RegisterAnchor(token.value);
m_scanner.pop(); m_scanner.pop();
} }
@@ -411,4 +425,4 @@ anchor_t SingleDocParser::LookupAnchor(const Mark& mark,
return it->second; return it->second;
} }
} } // namespace YAML
+10 -6
View File
@@ -12,7 +12,6 @@
#include <string> #include <string>
#include "yaml-cpp/anchor.h" #include "yaml-cpp/anchor.h"
#include "yaml-cpp/noncopyable.h"
namespace YAML { namespace YAML {
class CollectionStack; class CollectionStack;
@@ -23,9 +22,13 @@ struct Directives;
struct Mark; struct Mark;
struct Token; struct Token;
class SingleDocParser : private noncopyable { class SingleDocParser {
public: public:
SingleDocParser(Scanner& scanner, const Directives& directives); SingleDocParser(Scanner& scanner, const Directives& directives);
SingleDocParser(const SingleDocParser&) = delete;
SingleDocParser(SingleDocParser&&) = delete;
SingleDocParser& operator=(const SingleDocParser&) = delete;
SingleDocParser& operator=(SingleDocParser&&) = delete;
~SingleDocParser(); ~SingleDocParser();
void HandleDocument(EventHandler& eventHandler); void HandleDocument(EventHandler& eventHandler);
@@ -43,9 +46,10 @@ class SingleDocParser : private noncopyable {
void HandleCompactMap(EventHandler& eventHandler); void HandleCompactMap(EventHandler& eventHandler);
void HandleCompactMapWithNoKey(EventHandler& eventHandler); void HandleCompactMapWithNoKey(EventHandler& eventHandler);
void ParseProperties(std::string& tag, anchor_t& anchor); void ParseProperties(std::string& tag, anchor_t& anchor,
std::string& anchor_name);
void ParseTag(std::string& tag); void ParseTag(std::string& tag);
void ParseAnchor(anchor_t& anchor); void ParseAnchor(anchor_t& anchor, std::string& anchor_name);
anchor_t RegisterAnchor(const std::string& name); anchor_t RegisterAnchor(const std::string& name);
anchor_t LookupAnchor(const Mark& mark, const std::string& name) const; anchor_t LookupAnchor(const Mark& mark, const std::string& name) const;
@@ -55,11 +59,11 @@ class SingleDocParser : private noncopyable {
const Directives& m_directives; const Directives& m_directives;
std::unique_ptr<CollectionStack> m_pCollectionStack; std::unique_ptr<CollectionStack> m_pCollectionStack;
typedef std::map<std::string, anchor_t> Anchors; using Anchors = std::map<std::string, anchor_t>;
Anchors m_anchors; Anchors m_anchors;
anchor_t m_curAnchor; anchor_t m_curAnchor;
}; };
} } // namespace YAML
#endif // SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+22 -26
View File
@@ -111,24 +111,15 @@ static UtfIntroState s_introTransitions[][uictMax] = {
static char s_introUngetCount[][uictMax] = { static char s_introUngetCount[][uictMax] = {
// uict00, uictBB, uictBF, uictEF, uictFE, uictFF, uictAscii, uictOther // uict00, uictBB, uictBF, uictEF, uictFE, uictFF, uictAscii, uictOther
{0, 1, 1, 0, 0, 0, 0, 1}, {0, 1, 1, 0, 0, 0, 0, 1}, {0, 2, 2, 2, 2, 2, 2, 2},
{0, 2, 2, 2, 2, 2, 2, 2}, {3, 3, 3, 3, 0, 3, 3, 3}, {4, 4, 4, 4, 4, 0, 4, 4},
{3, 3, 3, 3, 0, 3, 3, 3}, {1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1},
{4, 4, 4, 4, 4, 0, 4, 4}, {2, 2, 2, 2, 2, 0, 2, 2}, {2, 2, 2, 2, 0, 2, 2, 2},
{1, 1, 1, 1, 1, 1, 1, 1}, {0, 1, 1, 1, 1, 1, 1, 1}, {0, 2, 2, 2, 2, 2, 2, 2},
{1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1},
{2, 2, 2, 2, 2, 0, 2, 2}, {0, 2, 2, 2, 2, 2, 2, 2}, {0, 3, 3, 3, 3, 3, 3, 3},
{2, 2, 2, 2, 0, 2, 2, 2}, {4, 4, 4, 4, 4, 4, 4, 4}, {2, 0, 2, 2, 2, 2, 2, 2},
{0, 1, 1, 1, 1, 1, 1, 1}, {3, 3, 0, 3, 3, 3, 3, 3}, {1, 1, 1, 1, 1, 1, 1, 1},
{0, 2, 2, 2, 2, 2, 2, 2},
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1},
{0, 2, 2, 2, 2, 2, 2, 2},
{0, 3, 3, 3, 3, 3, 3, 3},
{4, 4, 4, 4, 4, 4, 4, 4},
{2, 0, 2, 2, 2, 2, 2, 2},
{3, 3, 0, 3, 3, 3, 3, 3},
{1, 1, 1, 1, 1, 1, 1, 1},
}; };
inline UtfIntroCharType IntroCharTypeOf(std::istream::int_type ch) { inline UtfIntroCharType IntroCharTypeOf(std::istream::int_type ch) {
@@ -160,7 +151,7 @@ inline UtfIntroCharType IntroCharTypeOf(std::istream::int_type ch) {
inline char Utf8Adjust(unsigned long ch, unsigned char lead_bits, inline char Utf8Adjust(unsigned long ch, unsigned char lead_bits,
unsigned char rshift) { unsigned char rshift) {
const unsigned char header = ((1 << lead_bits) - 1) << (8 - lead_bits); const unsigned char header = static_cast<unsigned char>(((1 << lead_bits) - 1) << (8 - lead_bits));
const unsigned char mask = (0xFF >> (lead_bits + 1)); const unsigned char mask = (0xFF >> (lead_bits + 1));
return static_cast<char>( return static_cast<char>(
static_cast<unsigned char>(header | ((ch >> rshift) & mask))); static_cast<unsigned char>(header | ((ch >> rshift) & mask)));
@@ -192,17 +183,20 @@ inline void QueueUnicodeCodepoint(std::deque<char>& q, unsigned long ch) {
Stream::Stream(std::istream& input) Stream::Stream(std::istream& input)
: m_input(input), : m_input(input),
m_mark{},
m_charSet{},
m_readahead{},
m_pPrefetched(new unsigned char[YAML_PREFETCH_SIZE]), m_pPrefetched(new unsigned char[YAML_PREFETCH_SIZE]),
m_nPrefetchedAvailable(0), m_nPrefetchedAvailable(0),
m_nPrefetchedUsed(0) { m_nPrefetchedUsed(0) {
typedef std::istream::traits_type char_traits; using char_traits = std::istream::traits_type;
if (!input) if (!input)
return; return;
// Determine (or guess) the character-set by reading the BOM, if any. See // Determine (or guess) the character-set by reading the BOM, if any. See
// the YAML specification for the determination algorithm. // the YAML specification for the determination algorithm.
char_traits::int_type intro[4]; char_traits::int_type intro[4]{};
int nIntroUsed = 0; int nIntroUsed = 0;
UtfIntroState state = uis_start; UtfIntroState state = uis_start;
for (; !s_introFinalState[state];) { for (; !s_introFinalState[state];) {
@@ -279,9 +273,11 @@ char Stream::get() {
// . Extracts 'n' characters from the stream and updates our position // . Extracts 'n' characters from the stream and updates our position
std::string Stream::get(int n) { std::string Stream::get(int n) {
std::string ret; std::string ret;
ret.reserve(n); if(n > 0) {
for (int i = 0; i < n; i++) ret.reserve(static_cast<std::string::size_type>(n));
ret += get(); for (int i = 0; i < n; i++)
ret += get();
}
return ret; return ret;
} }
@@ -332,7 +328,7 @@ bool Stream::_ReadAheadTo(size_t i) const {
void Stream::StreamInUtf8() const { void Stream::StreamInUtf8() const {
unsigned char b = GetNextByte(); unsigned char b = GetNextByte();
if (m_input.good()) { if (m_input.good()) {
m_readahead.push_back(b); m_readahead.push_back(static_cast<char>(b));
} }
} }
@@ -445,4 +441,4 @@ void Stream::StreamInUtf32() const {
QueueUnicodeCodepoint(m_readahead, ch); QueueUnicodeCodepoint(m_readahead, ch);
} }
} } // namespace YAML
+9 -3
View File
@@ -7,7 +7,6 @@
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/noncopyable.h"
#include "yaml-cpp/mark.h" #include "yaml-cpp/mark.h"
#include <cstddef> #include <cstddef>
#include <deque> #include <deque>
@@ -17,11 +16,18 @@
#include <string> #include <string>
namespace YAML { namespace YAML {
class Stream : private noncopyable {
class StreamCharSource;
class Stream {
public: public:
friend class StreamCharSource; friend class StreamCharSource;
Stream(std::istream& input); Stream(std::istream& input);
Stream(const Stream&) = delete;
Stream(Stream&&) = delete;
Stream& operator=(const Stream&) = delete;
Stream& operator=(Stream&&) = delete;
~Stream(); ~Stream();
operator bool() const; operator bool() const;
@@ -71,6 +77,6 @@ inline bool Stream::ReadAheadTo(size_t i) const {
return true; return true;
return _ReadAheadTo(i); return _ReadAheadTo(i);
} }
} } // namespace YAML
#endif // STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+10 -8
View File
@@ -7,16 +7,20 @@
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/noncopyable.h" #include "yaml-cpp/noexcept.h"
#include "stream.h"
#include <cstddef> #include <cstddef>
namespace YAML { namespace YAML {
class StreamCharSource { class StreamCharSource {
public: public:
StreamCharSource(const Stream& stream) : m_offset(0), m_stream(stream) {} StreamCharSource(const Stream& stream) : m_offset(0), m_stream(stream) {}
StreamCharSource(const StreamCharSource& source) StreamCharSource(const StreamCharSource& source) = default;
: m_offset(source.m_offset), m_stream(source.m_stream) {} StreamCharSource(StreamCharSource&&) YAML_CPP_NOEXCEPT = default;
~StreamCharSource() {} StreamCharSource& operator=(const StreamCharSource&) = delete;
StreamCharSource& operator=(StreamCharSource&&) = delete;
~StreamCharSource() = default;
operator bool() const; operator bool() const;
char operator[](std::size_t i) const { return m_stream.CharAt(m_offset + i); } char operator[](std::size_t i) const { return m_stream.CharAt(m_offset + i); }
@@ -27,8 +31,6 @@ class StreamCharSource {
private: private:
std::size_t m_offset; std::size_t m_offset;
const Stream& m_stream; const Stream& m_stream;
StreamCharSource& operator=(const StreamCharSource&); // non-assignable
}; };
inline StreamCharSource::operator bool() const { inline StreamCharSource::operator bool() const {
@@ -38,11 +40,11 @@ inline StreamCharSource::operator bool() const {
inline const StreamCharSource StreamCharSource::operator+(int i) const { inline const StreamCharSource StreamCharSource::operator+(int i) const {
StreamCharSource source(*this); StreamCharSource source(*this);
if (static_cast<int>(source.m_offset) + i >= 0) if (static_cast<int>(source.m_offset) + i >= 0)
source.m_offset += i; source.m_offset += static_cast<std::size_t>(i);
else else
source.m_offset = 0; source.m_offset = 0;
return source; return source;
} }
} } // namespace YAML
#endif // STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+3 -2
View File
@@ -6,7 +6,8 @@
#include "token.h" #include "token.h"
namespace YAML { namespace YAML {
Tag::Tag(const Token& token) : type(static_cast<TYPE>(token.data)) { Tag::Tag(const Token& token)
: type(static_cast<TYPE>(token.data)), handle{}, value{} {
switch (type) { switch (type) {
case VERBATIM: case VERBATIM:
value = token.value; value = token.value;
@@ -46,4 +47,4 @@ const std::string Tag::Translate(const Directives& directives) {
} }
throw std::runtime_error("yaml-cpp: internal error, bad tag type"); throw std::runtime_error("yaml-cpp: internal error, bad tag type");
} }
} } // namespace YAML
+9 -8
View File
@@ -14,10 +14,11 @@
namespace YAML { namespace YAML {
const std::string TokenNames[] = { const std::string TokenNames[] = {
"DIRECTIVE", "DOC_START", "DOC_END", "BLOCK_SEQ_START", "BLOCK_MAP_START", "DIRECTIVE", "DOC_START", "DOC_END", "BLOCK_SEQ_START",
"BLOCK_SEQ_END", "BLOCK_MAP_END", "BLOCK_ENTRY", "FLOW_SEQ_START", "BLOCK_MAP_START", "BLOCK_SEQ_END", "BLOCK_MAP_END", "BLOCK_ENTRY",
"FLOW_MAP_START", "FLOW_SEQ_END", "FLOW_MAP_END", "FLOW_MAP_COMPACT", "FLOW_SEQ_START", "FLOW_MAP_START", "FLOW_SEQ_END", "FLOW_MAP_END",
"FLOW_ENTRY", "KEY", "VALUE", "ANCHOR", "ALIAS", "TAG", "SCALAR"}; "FLOW_MAP_COMPACT", "FLOW_ENTRY", "KEY", "VALUE",
"ANCHOR", "ALIAS", "TAG", "SCALAR"};
struct Token { struct Token {
// enums // enums
@@ -48,12 +49,12 @@ struct Token {
// data // data
Token(TYPE type_, const Mark& mark_) Token(TYPE type_, const Mark& mark_)
: status(VALID), type(type_), mark(mark_), data(0) {} : status(VALID), type(type_), mark(mark_), value{}, params{}, 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;
for (std::size_t i = 0; i < token.params.size(); i++) for (const std::string& param : token.params)
out << std::string(" ") << token.params[i]; out << std::string(" ") << param;
return out; return out;
} }
@@ -64,6 +65,6 @@ struct Token {
std::vector<std::string> params; std::vector<std::string> params;
int data; int data;
}; };
} } // namespace YAML
#endif // TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+14
View File
@@ -0,0 +1,14 @@
cc_test(
name = "test",
srcs = glob([
"*.cpp",
"*.h",
"integrations/*.cpp",
"node/*.cpp",
]),
deps = [
"//:yaml-cpp",
"//:yaml-cpp_internal",
"@com_google_googletest//:gtest_main",
],
)
+41 -36
View File
@@ -1,44 +1,49 @@
set(gtest_force_shared_crt ${MSVC_SHARED_RT} CACHE BOOL find_package(Threads REQUIRED)
"Use shared (DLL) run-time lib even when Google Test built as a static lib.")
add_subdirectory(gtest-1.8.0)
include_directories(SYSTEM gtest-1.8.0/googlemock/include)
include_directories(SYSTEM gtest-1.8.0/googletest/include)
if(WIN32 AND BUILD_SHARED_LIBS) set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
add_definitions("-DGTEST_LINKED_AS_SHARED_LIBRARY") set(BUILD_MOCK ON CACHE BOOL "" FORCE)
set(CMAKE_POLICY_DEFAULT_CMP0048 NEW)
add_subdirectory(
"${CMAKE_CURRENT_SOURCE_DIR}/gtest-1.8.0"
"${CMAKE_CURRENT_BINARY_DIR}/prefix")
include_directories(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/gtest-1.8.0/googletest/include")
set(test-new-api-pattern "new-api/*.cpp")
set(test-source-pattern "*.cpp" "integration/*.cpp" "node/*.cpp")
if (CMAKE_VERSION VERSION_GREATER 3.11)
list(INSERT test-new-api-pattern 0 CONFIGURE_DEPENDS)
list(INSERT test-source-pattern 0 CONFIGURE_DEPENDS)
endif() endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR file(GLOB test-new-api-sources ${test-new-api-pattern})
CMAKE_CXX_COMPILER_ID MATCHES "Clang") file(GLOB test-sources ${test-source-pattern})
set(yaml_test_flags "-Wno-variadic-macros -Wno-sign-compare")
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_executable(yaml-cpp-tests "")
set(yaml_test_flags "${yaml_test_flags} -Wno-c99-extensions") target_sources(yaml-cpp-tests
endif() PRIVATE
${test-new-api-sources}
${test-sources})
target_include_directories(yaml-cpp-tests
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/integration
${CMAKE_CURRENT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/src)
target_compile_options(yaml-cpp-tests
PRIVATE
$<$<CXX_COMPILER_ID:Clang>:-Wno-c99-extensions -Wno-variadic-macros -Wno-sign-compare>
$<$<CXX_COMPILER_ID:GNU>:-Wno-variadic-macros -Wno-sign-compare>)
target_link_libraries(yaml-cpp-tests
PRIVATE
Threads::Threads
yaml-cpp
gmock)
if(CMAKE_COMPILER_IS_GNUCXX) set_property(TARGET yaml-cpp-tests PROPERTY CXX_STANDARD_REQUIRED ON)
set(yaml_test_flags "${yaml_test_flags} -std=gnu++11") if (NOT DEFINED CMAKE_CXX_STANDARD)
else() set_target_properties(yaml-cpp-tests PROPERTIES CXX_STANDARD 11)
set(yaml_test_flags "${yaml_test_flags} -std=c++11")
endif()
endif() endif()
file(GLOB test_headers [a-z_]*.h)
file(GLOB test_sources [a-z_]*.cpp integration/[a-z_]*.cpp node/[a-z_]*.cpp)
file(GLOB test_new_api_sources new-api/[a-z]*.cpp)
list(APPEND test_sources ${test_new_api_sources}) add_test(yaml-cpp::test yaml-cpp-tests)
add_sources(${test_sources} ${test_headers})
include_directories(${YAML_CPP_SOURCE_DIR}/test)
add_executable(run-tests
${test_sources}
${test_headers}
)
set_target_properties(run-tests PROPERTIES
COMPILE_FLAGS "${yaml_c_flags} ${yaml_cxx_flags} ${yaml_test_flags}"
)
target_link_libraries(run-tests yaml-cpp gmock)
add_test(yaml-test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/run-tests)
+16 -4
View File
@@ -35,10 +35,12 @@ def doc_end(implicit=False):
def scalar(value, tag='', anchor='', anchor_id=0): def scalar(value, tag='', anchor='', anchor_id=0):
emit = [] emit = []
handle = []
if tag: if tag:
emit += ['VerbatimTag("%s")' % encode(tag)] emit += ['VerbatimTag("%s")' % encode(tag)]
if anchor: if anchor:
emit += ['Anchor("%s")' % encode(anchor)] emit += ['Anchor("%s")' % encode(anchor)]
handle += ['OnAnchor(_, "%s")' % encode(anchor)]
if tag: if tag:
out_tag = encode(tag) out_tag = encode(tag)
else: else:
@@ -47,39 +49,46 @@ def scalar(value, tag='', anchor='', anchor_id=0):
else: else:
out_tag = '!' out_tag = '!'
emit += ['"%s"' % encode(value)] emit += ['"%s"' % encode(value)]
return {'emit': emit, 'handle': 'OnScalar(_, "%s", %s, "%s")' % (out_tag, anchor_id, encode(value))} handle += ['OnScalar(_, "%s", %s, "%s")' % (out_tag, anchor_id, encode(value))]
return {'emit': emit, 'handle': handle}
def comment(value): def comment(value):
return {'emit': 'Comment("%s")' % value, 'handle': ''} return {'emit': 'Comment("%s")' % value, 'handle': ''}
def seq_start(tag='', anchor='', anchor_id=0, style='_'): def seq_start(tag='', anchor='', anchor_id=0, style='_'):
emit = [] emit = []
handle = []
if tag: if tag:
emit += ['VerbatimTag("%s")' % encode(tag)] emit += ['VerbatimTag("%s")' % encode(tag)]
if anchor: if anchor:
emit += ['Anchor("%s")' % encode(anchor)] emit += ['Anchor("%s")' % encode(anchor)]
handle += ['OnAnchor(_, "%s")' % encode(anchor)]
if tag: if tag:
out_tag = encode(tag) out_tag = encode(tag)
else: else:
out_tag = '?' out_tag = '?'
emit += ['BeginSeq'] emit += ['BeginSeq']
return {'emit': emit, 'handle': 'OnSequenceStart(_, "%s", %s, %s)' % (out_tag, anchor_id, style)} handle += ['OnSequenceStart(_, "%s", %s, %s)' % (out_tag, anchor_id, style)]
return {'emit': emit, 'handle': handle}
def seq_end(): def seq_end():
return {'emit': 'EndSeq', 'handle': 'OnSequenceEnd()'} return {'emit': 'EndSeq', 'handle': 'OnSequenceEnd()'}
def map_start(tag='', anchor='', anchor_id=0, style='_'): def map_start(tag='', anchor='', anchor_id=0, style='_'):
emit = [] emit = []
handle = []
if tag: if tag:
emit += ['VerbatimTag("%s")' % encode(tag)] emit += ['VerbatimTag("%s")' % encode(tag)]
if anchor: if anchor:
emit += ['Anchor("%s")' % encode(anchor)] emit += ['Anchor("%s")' % encode(anchor)]
handle += ['OnAnchor(_, "%s")' % encode(anchor)]
if tag: if tag:
out_tag = encode(tag) out_tag = encode(tag)
else: else:
out_tag = '?' out_tag = '?'
emit += ['BeginMap'] emit += ['BeginMap']
return {'emit': emit, 'handle': 'OnMapStart(_, "%s", %s, %s)' % (out_tag, anchor_id, style)} handle += ['OnMapStart(_, "%s", %s, %s)' % (out_tag, anchor_id, style)]
return {'emit': emit, 'handle': handle}
def map_end(): def map_end():
return {'emit': 'EndMap', 'handle': 'OnMapEnd()'} return {'emit': 'EndMap', 'handle': 'OnMapEnd()'}
@@ -202,7 +211,10 @@ def create_emitter_tests(out):
out.writeln('') out.writeln('')
for event in test['events']: for event in test['events']:
handle = event['handle'] handle = event['handle']
if handle: if isinstance(handle, list):
for e in handle:
out.writeln('EXPECT_CALL(handler, %s);' % e)
elif handle:
out.writeln('EXPECT_CALL(handler, %s);' % handle) out.writeln('EXPECT_CALL(handler, %s);' % handle)
out.writeln('Parse(out.c_str());') out.writeln('Parse(out.c_str());')
out.writeln('') out.writeln('')
+54 -13
View File
@@ -253,8 +253,9 @@ TEST_F(EmitterTest, ScalarFormat) {
out << DoubleQuoted << "explicit double-quoted scalar"; out << DoubleQuoted << "explicit double-quoted scalar";
out << "auto-detected\ndouble-quoted scalar"; out << "auto-detected\ndouble-quoted scalar";
out << "a non-\"auto-detected\" double-quoted scalar"; out << "a non-\"auto-detected\" double-quoted scalar";
out << Literal << "literal scalar\nthat may span\nmany, many\nlines " out << Literal
"and have \"whatever\" crazy\tsymbols that we like"; << "literal scalar\nthat may span\nmany, many\nlines "
"and have \"whatever\" crazy\tsymbols that we like";
out << EndSeq; out << EndSeq;
ExpectEmit( ExpectEmit(
@@ -526,9 +527,10 @@ TEST_F(EmitterTest, SimpleComment) {
TEST_F(EmitterTest, MultiLineComment) { TEST_F(EmitterTest, MultiLineComment) {
out << BeginSeq; out << BeginSeq;
out << "item 1" << Comment( out << "item 1"
"really really long\ncomment that couldn't " << Comment(
"possibly\nfit on one line"); "really really long\ncomment that couldn't "
"possibly\nfit on one line");
out << "item 2"; out << "item 2";
out << EndSeq; out << EndSeq;
@@ -901,18 +903,18 @@ TEST_F(EmitterTest, SingleChar) {
TEST_F(EmitterTest, DefaultPrecision) { TEST_F(EmitterTest, DefaultPrecision) {
out << BeginSeq; out << BeginSeq;
out << 1.234f; out << 1.3125f;
out << 3.14159265358979; out << 1.23455810546875;
out << EndSeq; out << EndSeq;
ExpectEmit("- 1.234\n- 3.14159265358979"); ExpectEmit("- 1.3125\n- 1.23455810546875");
} }
TEST_F(EmitterTest, SetPrecision) { TEST_F(EmitterTest, SetPrecision) {
out << BeginSeq; out << BeginSeq;
out << FloatPrecision(3) << 1.234f; out << FloatPrecision(3) << 1.3125f;
out << DoublePrecision(6) << 3.14159265358979; out << DoublePrecision(6) << 1.23455810546875;
out << EndSeq; out << EndSeq;
ExpectEmit("- 1.23\n- 3.14159"); ExpectEmit("- 1.31\n- 1.23456");
} }
TEST_F(EmitterTest, DashInBlockContext) { TEST_F(EmitterTest, DashInBlockContext) {
@@ -984,6 +986,45 @@ TEST_F(EmitterTest, ValueOfBackslash) {
ExpectEmit("foo: \"\\\\\""); ExpectEmit("foo: \"\\\\\"");
} }
TEST_F(EmitterTest, Infinity) {
out << YAML::BeginMap;
out << YAML::Key << "foo" << YAML::Value
<< std::numeric_limits<float>::infinity();
out << YAML::Key << "bar" << YAML::Value
<< std::numeric_limits<double>::infinity();
out << YAML::EndMap;
ExpectEmit(
"foo: .inf\n"
"bar: .inf");
}
TEST_F(EmitterTest, NegInfinity) {
out << YAML::BeginMap;
out << YAML::Key << "foo" << YAML::Value
<< -std::numeric_limits<float>::infinity();
out << YAML::Key << "bar" << YAML::Value
<< -std::numeric_limits<double>::infinity();
out << YAML::EndMap;
ExpectEmit(
"foo: -.inf\n"
"bar: -.inf");
}
TEST_F(EmitterTest, NaN) {
out << YAML::BeginMap;
out << YAML::Key << "foo" << YAML::Value
<< std::numeric_limits<float>::quiet_NaN();
out << YAML::Key << "bar" << YAML::Value
<< std::numeric_limits<double>::quiet_NaN();
out << YAML::EndMap;
ExpectEmit(
"foo: .nan\n"
"bar: .nan");
}
class EmitterErrorTest : public ::testing::Test { class EmitterErrorTest : public ::testing::Test {
protected: protected:
void ExpectEmitError(const std::string& expectedError) { void ExpectEmitError(const std::string& expectedError) {
@@ -1034,5 +1075,5 @@ TEST_F(EmitterErrorTest, InvalidAlias) {
ExpectEmitError(ErrorMsg::INVALID_ALIAS); ExpectEmitError(ErrorMsg::INVALID_ALIAS);
} }
} } // namespace
} } // namespace YAML
+61
View File
@@ -0,0 +1,61 @@
#include "yaml-cpp/yaml.h" // IWYU pragma: keep
#include "gtest/gtest.h"
#define EXPECT_THROW_EXCEPTION(exception_type, statement, message) \
ASSERT_THROW(statement, exception_type); \
try { \
statement; \
} catch (const exception_type& e) { \
EXPECT_EQ(e.msg, message); \
}
namespace YAML {
namespace {
TEST(ErrorMessageTest, BadSubscriptErrorMessage) {
const char *example_yaml = "first:\n"
" second: 1\n"
" third: 2\n";
Node doc = Load(example_yaml);
// Test that printable key is part of error message
EXPECT_THROW_EXCEPTION(YAML::BadSubscript, doc["first"]["second"]["fourth"],
"operator[] call on a scalar (key: \"fourth\")");
EXPECT_THROW_EXCEPTION(YAML::BadSubscript, doc["first"]["second"][37],
"operator[] call on a scalar (key: \"37\")");
// Non-printable key is not included in error message
EXPECT_THROW_EXCEPTION(YAML::BadSubscript,
doc["first"]["second"][std::vector<int>()],
"operator[] call on a scalar");
EXPECT_THROW_EXCEPTION(YAML::BadSubscript, doc["first"]["second"][Node()],
"operator[] call on a scalar");
}
TEST(ErrorMessageTest, Ex9_1_InvalidNodeErrorMessage) {
const char *example_yaml = "first:\n"
" second: 1\n"
" third: 2\n";
const Node doc = Load(example_yaml);
// Test that printable key is part of error message
EXPECT_THROW_EXCEPTION(YAML::InvalidNode, doc["first"]["fourth"].as<int>(),
"invalid node; first invalid key: \"fourth\"");
EXPECT_THROW_EXCEPTION(YAML::InvalidNode, doc["first"][37].as<int>(),
"invalid node; first invalid key: \"37\"");
// Non-printable key is not included in error message
EXPECT_THROW_EXCEPTION(YAML::InvalidNode,
doc["first"][std::vector<int>()].as<int>(),
"invalid node; this may result from using a map "
"iterator as a sequence iterator, or vice-versa");
}
}
}
File diff suppressed because it is too large Load Diff
+12 -2
View File
@@ -199,6 +199,7 @@ TEST_F(HandlerSpecTest, Ex2_10_SimpleAnchor) {
EXPECT_CALL(handler, OnScalar(_, "?", 0, "hr")); EXPECT_CALL(handler, OnScalar(_, "?", 0, "hr"));
EXPECT_CALL(handler, OnSequenceStart(_, "?", 0, EmitterStyle::Block)); EXPECT_CALL(handler, OnSequenceStart(_, "?", 0, EmitterStyle::Block));
EXPECT_CALL(handler, OnScalar(_, "?", 0, "Mark McGwire")); EXPECT_CALL(handler, OnScalar(_, "?", 0, "Mark McGwire"));
EXPECT_CALL(handler, OnAnchor(_, "SS"));
EXPECT_CALL(handler, OnScalar(_, "?", 1, "Sammy Sosa")); EXPECT_CALL(handler, OnScalar(_, "?", 1, "Sammy Sosa"));
EXPECT_CALL(handler, OnSequenceEnd()); EXPECT_CALL(handler, OnSequenceEnd());
EXPECT_CALL(handler, OnScalar(_, "?", 0, "rbi")); EXPECT_CALL(handler, OnScalar(_, "?", 0, "rbi"));
@@ -376,6 +377,7 @@ TEST_F(HandlerSpecTest, Ex2_24_GlobalTags) {
EXPECT_CALL(handler, OnMapStart(_, "tag:clarkevans.com,2002:circle", 0, EXPECT_CALL(handler, OnMapStart(_, "tag:clarkevans.com,2002:circle", 0,
EmitterStyle::Block)); EmitterStyle::Block));
EXPECT_CALL(handler, OnScalar(_, "?", 0, "center")); EXPECT_CALL(handler, OnScalar(_, "?", 0, "center"));
EXPECT_CALL(handler, OnAnchor(_, "ORIGIN"));
EXPECT_CALL(handler, OnMapStart(_, "?", 1, EmitterStyle::Flow)); EXPECT_CALL(handler, OnMapStart(_, "?", 1, EmitterStyle::Flow));
EXPECT_CALL(handler, OnScalar(_, "?", 0, "x")); EXPECT_CALL(handler, OnScalar(_, "?", 0, "x"));
EXPECT_CALL(handler, OnScalar(_, "?", 0, "73")); EXPECT_CALL(handler, OnScalar(_, "?", 0, "73"));
@@ -456,6 +458,7 @@ TEST_F(HandlerSpecTest, Ex2_27_Invoice) {
EXPECT_CALL(handler, OnScalar(_, "?", 0, "date")); EXPECT_CALL(handler, OnScalar(_, "?", 0, "date"));
EXPECT_CALL(handler, OnScalar(_, "?", 0, "2001-01-23")); EXPECT_CALL(handler, OnScalar(_, "?", 0, "2001-01-23"));
EXPECT_CALL(handler, OnScalar(_, "?", 0, "bill-to")); EXPECT_CALL(handler, OnScalar(_, "?", 0, "bill-to"));
EXPECT_CALL(handler, OnAnchor(_, "id001"));
EXPECT_CALL(handler, OnMapStart(_, "?", 1, EmitterStyle::Block)); EXPECT_CALL(handler, OnMapStart(_, "?", 1, EmitterStyle::Block));
EXPECT_CALL(handler, OnScalar(_, "?", 0, "given")); EXPECT_CALL(handler, OnScalar(_, "?", 0, "given"));
EXPECT_CALL(handler, OnScalar(_, "?", 0, "Chris")); EXPECT_CALL(handler, OnScalar(_, "?", 0, "Chris"));
@@ -616,6 +619,7 @@ TEST_F(HandlerSpecTest, Ex5_6_NodePropertyIndicators) {
EXPECT_CALL(handler, OnDocumentStart(_)); EXPECT_CALL(handler, OnDocumentStart(_));
EXPECT_CALL(handler, OnMapStart(_, "?", 0, EmitterStyle::Block)); EXPECT_CALL(handler, OnMapStart(_, "?", 0, EmitterStyle::Block));
EXPECT_CALL(handler, OnScalar(_, "?", 0, "anchored")); EXPECT_CALL(handler, OnScalar(_, "?", 0, "anchored"));
EXPECT_CALL(handler, OnAnchor(_, "anchor"));
EXPECT_CALL(handler, OnScalar(_, "!local", 1, "value")); EXPECT_CALL(handler, OnScalar(_, "!local", 1, "value"));
EXPECT_CALL(handler, OnScalar(_, "?", 0, "alias")); EXPECT_CALL(handler, OnScalar(_, "?", 0, "alias"));
EXPECT_CALL(handler, OnAlias(_, 1)); EXPECT_CALL(handler, OnAlias(_, 1));
@@ -909,8 +913,10 @@ TEST_F(HandlerSpecTest, Ex6_22_GlobalTagPrefix) {
TEST_F(HandlerSpecTest, Ex6_23_NodeProperties) { TEST_F(HandlerSpecTest, Ex6_23_NodeProperties) {
EXPECT_CALL(handler, OnDocumentStart(_)); EXPECT_CALL(handler, OnDocumentStart(_));
EXPECT_CALL(handler, OnMapStart(_, "?", 0, EmitterStyle::Block)); EXPECT_CALL(handler, OnMapStart(_, "?", 0, EmitterStyle::Block));
EXPECT_CALL(handler, OnAnchor(_, "a1"));
EXPECT_CALL(handler, OnScalar(_, "tag:yaml.org,2002:str", 1, "foo")); EXPECT_CALL(handler, OnScalar(_, "tag:yaml.org,2002:str", 1, "foo"));
EXPECT_CALL(handler, OnScalar(_, "tag:yaml.org,2002:str", 0, "bar")); EXPECT_CALL(handler, OnScalar(_, "tag:yaml.org,2002:str", 0, "bar"));
EXPECT_CALL(handler, OnAnchor(_, "a2"));
EXPECT_CALL(handler, OnScalar(_, "?", 2, "baz")); EXPECT_CALL(handler, OnScalar(_, "?", 2, "baz"));
EXPECT_CALL(handler, OnAlias(_, 1)); EXPECT_CALL(handler, OnAlias(_, 1));
EXPECT_CALL(handler, OnMapEnd()); EXPECT_CALL(handler, OnMapEnd());
@@ -972,6 +978,7 @@ TEST_F(HandlerSpecTest, Ex6_29_NodeAnchors) {
EXPECT_CALL(handler, OnDocumentStart(_)); EXPECT_CALL(handler, OnDocumentStart(_));
EXPECT_CALL(handler, OnMapStart(_, "?", 0, EmitterStyle::Block)); EXPECT_CALL(handler, OnMapStart(_, "?", 0, EmitterStyle::Block));
EXPECT_CALL(handler, OnScalar(_, "?", 0, "First occurrence")); EXPECT_CALL(handler, OnScalar(_, "?", 0, "First occurrence"));
EXPECT_CALL(handler, OnAnchor(_, "anchor"));
EXPECT_CALL(handler, OnScalar(_, "?", 1, "Value")); EXPECT_CALL(handler, OnScalar(_, "?", 1, "Value"));
EXPECT_CALL(handler, OnScalar(_, "?", 0, "Second occurrence")); EXPECT_CALL(handler, OnScalar(_, "?", 0, "Second occurrence"));
EXPECT_CALL(handler, OnAlias(_, 1)); EXPECT_CALL(handler, OnAlias(_, 1));
@@ -984,10 +991,12 @@ TEST_F(HandlerSpecTest, Ex7_1_AliasNodes) {
EXPECT_CALL(handler, OnDocumentStart(_)); EXPECT_CALL(handler, OnDocumentStart(_));
EXPECT_CALL(handler, OnMapStart(_, "?", 0, EmitterStyle::Block)); EXPECT_CALL(handler, OnMapStart(_, "?", 0, EmitterStyle::Block));
EXPECT_CALL(handler, OnScalar(_, "?", 0, "First occurrence")); EXPECT_CALL(handler, OnScalar(_, "?", 0, "First occurrence"));
EXPECT_CALL(handler, OnAnchor(_, "anchor"));
EXPECT_CALL(handler, OnScalar(_, "?", 1, "Foo")); EXPECT_CALL(handler, OnScalar(_, "?", 1, "Foo"));
EXPECT_CALL(handler, OnScalar(_, "?", 0, "Second occurrence")); EXPECT_CALL(handler, OnScalar(_, "?", 0, "Second occurrence"));
EXPECT_CALL(handler, OnAlias(_, 1)); EXPECT_CALL(handler, OnAlias(_, 1));
EXPECT_CALL(handler, OnScalar(_, "?", 0, "Override anchor")); EXPECT_CALL(handler, OnScalar(_, "?", 0, "Override anchor"));
EXPECT_CALL(handler, OnAnchor(_, "anchor"));
EXPECT_CALL(handler, OnScalar(_, "?", 2, "Bar")); EXPECT_CALL(handler, OnScalar(_, "?", 2, "Bar"));
EXPECT_CALL(handler, OnScalar(_, "?", 0, "Reuse anchor")); EXPECT_CALL(handler, OnScalar(_, "?", 0, "Reuse anchor"));
EXPECT_CALL(handler, OnAlias(_, 2)); EXPECT_CALL(handler, OnAlias(_, 2));
@@ -1307,6 +1316,7 @@ TEST_F(HandlerSpecTest, Ex7_24_FlowNodes) {
EXPECT_CALL(handler, OnSequenceStart(_, "?", 0, EmitterStyle::Block)); EXPECT_CALL(handler, OnSequenceStart(_, "?", 0, EmitterStyle::Block));
EXPECT_CALL(handler, OnScalar(_, "tag:yaml.org,2002:str", 0, "a")); EXPECT_CALL(handler, OnScalar(_, "tag:yaml.org,2002:str", 0, "a"));
EXPECT_CALL(handler, OnScalar(_, "!", 0, "b")); EXPECT_CALL(handler, OnScalar(_, "!", 0, "b"));
EXPECT_CALL(handler, OnAnchor(_, "anchor"));
EXPECT_CALL(handler, OnScalar(_, "!", 1, "c")); EXPECT_CALL(handler, OnScalar(_, "!", 1, "c"));
EXPECT_CALL(handler, OnAlias(_, 1)); EXPECT_CALL(handler, OnAlias(_, 1));
EXPECT_CALL(handler, OnScalar(_, "tag:yaml.org,2002:str", 0, "")); EXPECT_CALL(handler, OnScalar(_, "tag:yaml.org,2002:str", 0, ""));
@@ -1607,5 +1617,5 @@ TEST_F(HandlerSpecTest, Ex8_22_BlockCollectionNodes) {
EXPECT_CALL(handler, OnDocumentEnd()); EXPECT_CALL(handler, OnDocumentEnd());
Parse(ex8_22); Parse(ex8_22);
} }
} } // namespace
} } // namespace YAML
+26
View File
@@ -7,6 +7,7 @@ namespace {
TEST(LoadNodeTest, Reassign) { TEST(LoadNodeTest, Reassign) {
Node node = Load("foo"); Node node = Load("foo");
node = Node(); node = Node();
EXPECT_TRUE(node.IsNull());
} }
TEST(LoadNodeTest, FallbackValues) { TEST(LoadNodeTest, FallbackValues) {
@@ -55,6 +56,26 @@ TEST(LoadNodeTest, Binary) {
node[1].as<Binary>()); node[1].as<Binary>());
} }
TEST(LoadNodeTest, BinaryWithWhitespaces) {
Node node = Load(
"binaryText: !binary |-\n"
" TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieS\n"
" B0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIG\n"
" x1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbi\n"
" B0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZG\n"
" dlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS\n"
" 4K");
EXPECT_EQ(Binary(reinterpret_cast<const unsigned char*>(
"Man is distinguished, not only by his reason, "
"but by this singular passion from other "
"animals, which is a lust of the mind, that by "
"a perseverance of delight in the continued and "
"indefatigable generation of knowledge, exceeds "
"the short vehemence of any carnal pleasure.\n"),
270),
node["binaryText"].as<Binary>());
}
TEST(LoadNodeTest, IterateSequence) { TEST(LoadNodeTest, IterateSequence) {
Node node = Load("[1, 3, 5, 7]"); Node node = Load("[1, 3, 5, 7]");
int seq[] = {1, 3, 5, 7}; int seq[] = {1, 3, 5, 7};
@@ -237,5 +258,10 @@ TEST(NodeTest, LoadTagWithParenthesis) {
EXPECT_EQ(node.as<std::string>(), "foo"); EXPECT_EQ(node.as<std::string>(), "foo");
} }
TEST(NodeTest, LoadTagWithNullScalar) {
Node node = Load("!2");
EXPECT_TRUE(node.IsNull());
}
} // namespace } // namespace
} // namespace YAML } // namespace YAML
+5 -1
View File
@@ -1,8 +1,11 @@
#include "yaml-cpp/emitterstyle.h" #include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/eventhandler.h" #include "yaml-cpp/eventhandler.h"
#include "yaml-cpp/mark.h"
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include <string>
namespace YAML { namespace YAML {
class MockEventHandler : public EventHandler { class MockEventHandler : public EventHandler {
@@ -22,5 +25,6 @@ class MockEventHandler : public EventHandler {
MOCK_METHOD4(OnMapStart, void(const Mark&, const std::string&, anchor_t, MOCK_METHOD4(OnMapStart, void(const Mark&, const std::string&, anchor_t,
EmitterStyle::value)); EmitterStyle::value));
MOCK_METHOD0(OnMapEnd, void()); MOCK_METHOD0(OnMapEnd, void());
MOCK_METHOD2(OnAnchor, void(const Mark&, const std::string&));
}; };
} } // namespace YAML
+208 -42
View File
@@ -1,10 +1,10 @@
#include "yaml-cpp/emitter.h"
#include "yaml-cpp/node/emit.h"
#include "yaml-cpp/node/node.h" #include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/impl.h" #include "yaml-cpp/emitter.h"
#include "yaml-cpp/node/convert.h" #include "yaml-cpp/node/convert.h"
#include "yaml-cpp/node/iterator.h"
#include "yaml-cpp/node/detail/impl.h" #include "yaml-cpp/node/detail/impl.h"
#include "yaml-cpp/node/emit.h"
#include "yaml-cpp/node/impl.h"
#include "yaml-cpp/node/iterator.h"
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
@@ -47,6 +47,94 @@ TEST(NodeTest, SimpleAppendSequence) {
EXPECT_TRUE(node.IsSequence()); EXPECT_TRUE(node.IsSequence());
} }
TEST(NodeTest, SequenceElementRemoval) {
Node node;
node[0] = "a";
node[1] = "b";
node[2] = "c";
node.remove(1);
EXPECT_TRUE(node.IsSequence());
EXPECT_EQ(2, node.size());
EXPECT_EQ("a", node[0].as<std::string>());
EXPECT_EQ("c", node[1].as<std::string>());
}
TEST(NodeTest, SequenceElementRemovalSizeCheck) {
Node node;
node[0] = "a";
node[1] = "b";
node[2] = "c";
EXPECT_EQ(3, node.size());
node.remove(1);
EXPECT_TRUE(node.IsSequence());
EXPECT_EQ(2, node.size());
EXPECT_EQ("a", node[0].as<std::string>());
EXPECT_EQ("c", node[1].as<std::string>());
}
TEST(NodeTest, SequenceFirstElementRemoval) {
Node node;
node[0] = "a";
node[1] = "b";
node[2] = "c";
node.remove(0);
EXPECT_TRUE(node.IsSequence());
EXPECT_EQ(2, node.size());
EXPECT_EQ("b", node[0].as<std::string>());
EXPECT_EQ("c", node[1].as<std::string>());
}
TEST(NodeTest, SequenceFirstElementRemovalSizeCheck) {
Node node;
node[0] = "a";
node[1] = "b";
node[2] = "c";
EXPECT_EQ(3, node.size());
node.remove(0);
EXPECT_TRUE(node.IsSequence());
EXPECT_EQ(2, node.size());
EXPECT_EQ("b", node[0].as<std::string>());
EXPECT_EQ("c", node[1].as<std::string>());
}
TEST(NodeTest, SequenceLastElementRemoval) {
Node node;
node[0] = "a";
node[1] = "b";
node[2] = "c";
node.remove(2);
EXPECT_TRUE(node.IsSequence());
EXPECT_EQ(2, node.size());
EXPECT_EQ("a", node[0].as<std::string>());
EXPECT_EQ("b", node[1].as<std::string>());
}
TEST(NodeTest, SequenceLastElementRemovalSizeCheck) {
Node node;
node[0] = "a";
node[1] = "b";
node[2] = "c";
EXPECT_EQ(3, node.size());
node.remove(2);
EXPECT_TRUE(node.IsSequence());
EXPECT_EQ(2, node.size());
EXPECT_EQ("a", node[0].as<std::string>());
EXPECT_EQ("b", node[1].as<std::string>());
}
TEST(NodeTest, NodeAssignment) {
Node node1;
Node node2;
node1[1] = 1;
node1[2] = 2;
node1[3] = 3;
node2 = node1;
EXPECT_EQ(node1, node2);
EXPECT_EQ(node1[1], node2[1]);
EXPECT_EQ(node1[2], node2[2]);
EXPECT_EQ(node1[3], node2[3]);
}
TEST(NodeTest, MapElementRemoval) { TEST(NodeTest, MapElementRemoval) {
Node node; Node node;
node["foo"] = "bar"; node["foo"] = "bar";
@@ -54,6 +142,16 @@ TEST(NodeTest, MapElementRemoval) {
EXPECT_TRUE(!node["foo"]); EXPECT_TRUE(!node["foo"]);
} }
TEST(NodeTest, MapIntegerElementRemoval) {
Node node;
node[1] = "hello";
node[2] = 'c';
node["foo"] = "bar";
EXPECT_TRUE(node.IsMap());
node.remove(1);
EXPECT_TRUE(node.IsMap());
}
TEST(NodeTest, SimpleAssignSequence) { TEST(NodeTest, SimpleAssignSequence) {
Node node; Node node;
node[0] = 10; node[0] = 10;
@@ -106,6 +204,14 @@ TEST(NodeTest, RemoveUnassignedNode) {
EXPECT_EQ(0, node.size()); EXPECT_EQ(0, node.size());
} }
TEST(NodeTest, RemoveUnassignedNodeFromMap) {
Node node(NodeType::Map);
Node n;
node[n];
node.remove(n);
EXPECT_EQ(0, node.size());
}
TEST(NodeTest, MapForceInsert) { TEST(NodeTest, MapForceInsert) {
Node node; Node node;
Node k1("k1"); Node k1("k1");
@@ -349,12 +455,72 @@ TEST(NodeTest, AutoBoolConversion) {
EXPECT_TRUE(!!node["foo"]); EXPECT_TRUE(!!node["foo"]);
} }
TEST(NodeTest, FloatingPrecision) { TEST(NodeTest, FloatingPrecisionFloat) {
const float x = 0.123456789;
Node node = Node(x);
EXPECT_EQ(x, node.as<float>());
}
TEST(NodeTest, FloatingPrecisionPositiveInfinityFloat) {
if (!std::numeric_limits<float>::has_infinity) {
return;
}
const float x = std::numeric_limits<float>::infinity();
Node node = Node(x);
EXPECT_EQ(x, node.as<float>());
}
TEST(NodeTest, FloatingPrecisionNegativeInfinityFloat) {
if (!std::numeric_limits<float>::has_infinity) {
return;
}
const float x = -std::numeric_limits<float>::infinity();
Node node = Node(x);
EXPECT_EQ(x, node.as<float>());
}
TEST(NodeTest, FloatingPrecisionNanFloat) {
if (!std::numeric_limits<float>::has_quiet_NaN) {
return;
}
const float x = std::numeric_limits<float>::quiet_NaN();
Node node = Node(x);
EXPECT_TRUE(std::isnan(node.as<float>()));
}
TEST(NodeTest, FloatingPrecisionDouble) {
const double x = 0.123456789; const double x = 0.123456789;
Node node = Node(x); Node node = Node(x);
EXPECT_EQ(x, node.as<double>()); EXPECT_EQ(x, node.as<double>());
} }
TEST(NodeTest, FloatingPrecisionPositiveInfinityDouble) {
if (!std::numeric_limits<double>::has_infinity) {
return;
}
const double x = std::numeric_limits<double>::infinity();
Node node = Node(x);
EXPECT_EQ(x, node.as<float>());
}
TEST(NodeTest, FloatingPrecisionNegativeInfinityDouble) {
if (!std::numeric_limits<double>::has_infinity) {
return;
}
const double x = -std::numeric_limits<double>::infinity();
Node node = Node(x);
EXPECT_EQ(x, node.as<double>());
}
TEST(NodeTest, FloatingPrecisionNanDouble) {
if (!std::numeric_limits<double>::has_quiet_NaN) {
return;
}
const double x = std::numeric_limits<double>::quiet_NaN();
Node node = Node(x);
EXPECT_TRUE(std::isnan(node.as<double>()));
}
TEST(NodeTest, SpaceChar) { TEST(NodeTest, SpaceChar) {
Node node = Node(' '); Node node = Node(' ');
EXPECT_EQ(' ', node.as<char>()); EXPECT_EQ(' ', node.as<char>());
@@ -410,108 +576,108 @@ class NodeEmitterTest : public ::testing::Test {
TEST_F(NodeEmitterTest, SimpleFlowSeqNode) { TEST_F(NodeEmitterTest, SimpleFlowSeqNode) {
Node node; Node node;
node.SetStyle(EmitterStyle::Flow); node.SetStyle(EmitterStyle::Flow);
node.push_back(1.01); node.push_back(1.5);
node.push_back(2.01); node.push_back(2.25);
node.push_back(3.01); node.push_back(3.125);
ExpectOutput("[1.01, 2.01, 3.01]", node); ExpectOutput("[1.5, 2.25, 3.125]", node);
} }
TEST_F(NodeEmitterTest, NestFlowSeqNode) { TEST_F(NodeEmitterTest, NestFlowSeqNode) {
Node node, cell0, cell1; Node node, cell0, cell1;
cell0.push_back(1.01); cell0.push_back(1.5);
cell0.push_back(2.01); cell0.push_back(2.25);
cell0.push_back(3.01); cell0.push_back(3.125);
cell1.push_back(4.01); cell1.push_back(4.5);
cell1.push_back(5.01); cell1.push_back(5.25);
cell1.push_back(6.01); cell1.push_back(6.125);
node.SetStyle(EmitterStyle::Flow); node.SetStyle(EmitterStyle::Flow);
node.push_back(cell0); node.push_back(cell0);
node.push_back(cell1); node.push_back(cell1);
ExpectOutput("[[1.01, 2.01, 3.01], [4.01, 5.01, 6.01]]", node); ExpectOutput("[[1.5, 2.25, 3.125], [4.5, 5.25, 6.125]]", node);
} }
TEST_F(NodeEmitterTest, MixBlockFlowSeqNode) { TEST_F(NodeEmitterTest, MixBlockFlowSeqNode) {
Node node, cell0, cell1; Node node, cell0, cell1;
cell0.SetStyle(EmitterStyle::Flow); cell0.SetStyle(EmitterStyle::Flow);
cell0.push_back(1.01); cell0.push_back(1.5);
cell0.push_back(2.01); cell0.push_back(2.25);
cell0.push_back(3.01); cell0.push_back(3.125);
cell1.push_back(4.01); cell1.push_back(4.5);
cell1.push_back(5.01); cell1.push_back(5.25);
cell1.push_back(6.01); cell1.push_back(6.125);
node.SetStyle(EmitterStyle::Block); node.SetStyle(EmitterStyle::Block);
node.push_back(cell0); node.push_back(cell0);
node.push_back(cell1); node.push_back(cell1);
ExpectOutput("- [1.01, 2.01, 3.01]\n-\n - 4.01\n - 5.01\n - 6.01", node); ExpectOutput("- [1.5, 2.25, 3.125]\n-\n - 4.5\n - 5.25\n - 6.125", node);
} }
TEST_F(NodeEmitterTest, NestBlockFlowMapListNode) { TEST_F(NodeEmitterTest, NestBlockFlowMapListNode) {
Node node, mapNode, blockNode; Node node, mapNode, blockNode;
node.push_back(1.01); node.push_back(1.5);
node.push_back(2.01); node.push_back(2.25);
node.push_back(3.01); node.push_back(3.125);
mapNode.SetStyle(EmitterStyle::Flow); mapNode.SetStyle(EmitterStyle::Flow);
mapNode["position"] = node; mapNode["position"] = node;
blockNode.push_back(1.01); blockNode.push_back(1.0625);
blockNode.push_back(mapNode); blockNode.push_back(mapNode);
ExpectOutput("- 1.01\n- {position: [1.01, 2.01, 3.01]}", blockNode); ExpectOutput("- 1.0625\n- {position: [1.5, 2.25, 3.125]}", blockNode);
} }
TEST_F(NodeEmitterTest, NestBlockMixMapListNode) { TEST_F(NodeEmitterTest, NestBlockMixMapListNode) {
Node node, mapNode, blockNode; Node node, mapNode, blockNode;
node.push_back(1.01); node.push_back(1.5);
node.push_back(2.01); node.push_back(2.25);
node.push_back(3.01); node.push_back(3.125);
mapNode.SetStyle(EmitterStyle::Flow); mapNode.SetStyle(EmitterStyle::Flow);
mapNode["position"] = node; mapNode["position"] = node;
blockNode["scalar"] = 1.01; blockNode["scalar"] = 1.0625;
blockNode["object"] = mapNode; blockNode["object"] = mapNode;
ExpectAnyOutput(blockNode, ExpectAnyOutput(blockNode,
"scalar: 1.01\nobject: {position: [1.01, 2.01, 3.01]}", "scalar: 1.0625\nobject: {position: [1.5, 2.25, 3.125]}",
"object: {position: [1.01, 2.01, 3.01]}\nscalar: 1.01"); "object: {position: [1.5, 2.25, 3.125]}\nscalar: 1.5");
} }
TEST_F(NodeEmitterTest, NestBlockMapListNode) { TEST_F(NodeEmitterTest, NestBlockMapListNode) {
Node node, mapNode; Node node, mapNode;
node.push_back(1.01); node.push_back(1.5);
node.push_back(2.01); node.push_back(2.25);
node.push_back(3.01); node.push_back(3.125);
mapNode.SetStyle(EmitterStyle::Block); mapNode.SetStyle(EmitterStyle::Block);
mapNode["position"] = node; mapNode["position"] = node;
ExpectOutput("position:\n - 1.01\n - 2.01\n - 3.01", mapNode); ExpectOutput("position:\n - 1.5\n - 2.25\n - 3.125", mapNode);
} }
TEST_F(NodeEmitterTest, NestFlowMapListNode) { TEST_F(NodeEmitterTest, NestFlowMapListNode) {
Node node, mapNode; Node node, mapNode;
node.push_back(1.01); node.push_back(1.5);
node.push_back(2.01); node.push_back(2.25);
node.push_back(3.01); node.push_back(3.125);
mapNode.SetStyle(EmitterStyle::Flow); mapNode.SetStyle(EmitterStyle::Flow);
mapNode["position"] = node; mapNode["position"] = node;
ExpectOutput("{position: [1.01, 2.01, 3.01]}", mapNode); ExpectOutput("{position: [1.5, 2.25, 3.125]}", mapNode);
} }
} }
} }
+1 -1
View File
@@ -1,5 +1,5 @@
#include <stddef.h>
#include <sstream> #include <sstream>
#include <cstddef>
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "yaml-cpp/ostream_wrapper.h" #include "yaml-cpp/ostream_wrapper.h"
+16
View File
@@ -0,0 +1,16 @@
#include "yaml-cpp/parser.h"
#include "mock_event_handler.h"
#include "gtest/gtest.h"
using YAML::Parser;
using YAML::MockEventHandler;
using ::testing::StrictMock;
TEST(ParserTest, Empty) {
Parser parser;
EXPECT_FALSE(parser);
StrictMock<MockEventHandler> handler;
EXPECT_FALSE(parser.HandleNextDocument(handler));
}
+9 -9
View File
@@ -1,6 +1,6 @@
#include "gtest/gtest.h"
#include "regex_yaml.h" #include "regex_yaml.h"
#include "stream.h" #include "stream.h"
#include "gtest/gtest.h"
using YAML::RegEx; using YAML::RegEx;
using YAML::Stream; using YAML::Stream;
@@ -106,8 +106,8 @@ TEST(RegExTest, OperatorOr) {
for (int j = i + 1; j < 128; ++j) { for (int j = i + 1; j < 128; ++j) {
auto iStr = std::string(1, char(i)); auto iStr = std::string(1, char(i));
auto jStr = std::string(1, char(j)); auto jStr = std::string(1, char(j));
RegEx ex1 = RegEx(iStr) || RegEx(jStr); RegEx ex1 = RegEx(iStr) | RegEx(jStr);
RegEx ex2 = RegEx(jStr) || RegEx(iStr); RegEx ex2 = RegEx(jStr) | RegEx(iStr);
for (int k = MIN_CHAR; k < 128; ++k) { for (int k = MIN_CHAR; k < 128; ++k) {
auto str = std::string(1, char(k)); auto str = std::string(1, char(k));
@@ -128,8 +128,8 @@ TEST(RegExTest, OperatorOr) {
} }
TEST(RegExTest, OperatorOrShortCircuits) { TEST(RegExTest, OperatorOrShortCircuits) {
RegEx ex1 = RegEx(std::string("aaaa")) || RegEx(std::string("aa")); RegEx ex1 = RegEx(std::string("aaaa")) | RegEx(std::string("aa"));
RegEx ex2 = RegEx(std::string("aa")) || RegEx(std::string("aaaa")); RegEx ex2 = RegEx(std::string("aa")) | RegEx(std::string("aaaa"));
EXPECT_TRUE(ex1.Matches(std::string("aaaaa"))); EXPECT_TRUE(ex1.Matches(std::string("aaaaa")));
EXPECT_EQ(4, ex1.Match(std::string("aaaaa"))); EXPECT_EQ(4, ex1.Match(std::string("aaaaa")));
@@ -139,13 +139,13 @@ TEST(RegExTest, OperatorOrShortCircuits) {
} }
TEST(RegExTest, OperatorAnd) { TEST(RegExTest, OperatorAnd) {
RegEx emptySet = RegEx('a') && RegEx(); RegEx emptySet = RegEx('a') & RegEx();
EXPECT_FALSE(emptySet.Matches(std::string("a"))); EXPECT_FALSE(emptySet.Matches(std::string("a")));
} }
TEST(RegExTest, OperatorAndShortCircuits) { TEST(RegExTest, OperatorAndShortCircuits) {
RegEx ex1 = RegEx(std::string("aaaa")) && RegEx(std::string("aa")); RegEx ex1 = RegEx(std::string("aaaa")) & RegEx(std::string("aa"));
RegEx ex2 = RegEx(std::string("aa")) && RegEx(std::string("aaaa")); RegEx ex2 = RegEx(std::string("aa")) & RegEx(std::string("aaaa"));
EXPECT_TRUE(ex1.Matches(std::string("aaaaa"))); EXPECT_TRUE(ex1.Matches(std::string("aaaaa")));
EXPECT_EQ(4, ex1.Match(std::string("aaaaa"))); EXPECT_EQ(4, ex1.Match(std::string("aaaaa")));
@@ -174,4 +174,4 @@ TEST(RegExTest, StringOr) {
EXPECT_EQ(1, ex.Match(str)); EXPECT_EQ(1, ex.Match(str));
} }
} } // namespace
+30 -12
View File
@@ -1,14 +1,32 @@
add_sources(parse.cpp) add_executable(yaml-cpp-sandbox sandbox.cpp)
add_executable(parse parse.cpp) add_executable(yaml-cpp-parse parse.cpp)
target_link_libraries(parse yaml-cpp) add_executable(yaml-cpp-read read.cpp)
set_target_properties(parse PROPERTIES COMPILE_FLAGS "-std=c++11")
add_sources(sandbox.cpp) target_link_libraries(yaml-cpp-sandbox PRIVATE yaml-cpp)
add_executable(sandbox sandbox.cpp) target_link_libraries(yaml-cpp-parse PRIVATE yaml-cpp)
target_link_libraries(sandbox yaml-cpp) target_link_libraries(yaml-cpp-read PRIVATE yaml-cpp)
set_target_properties(sandbox PROPERTIES COMPILE_FLAGS "-std=c++11")
add_sources(read.cpp) set_property(TARGET yaml-cpp-sandbox PROPERTY OUTPUT_NAME sandbox)
add_executable(read read.cpp) set_property(TARGET yaml-cpp-parse PROPERTY OUTPUT_NAME parse)
target_link_libraries(read yaml-cpp) set_property(TARGET yaml-cpp-read PROPERTY OUTPUT_NAME read)
set_target_properties(read PROPERTIES COMPILE_FLAGS "-std=c++11")
set_target_properties(yaml-cpp-sandbox
PROPERTIES
CXX_STANDARD_REQUIRED ON
OUTPUT_NAME sandbox)
set_target_properties(yaml-cpp-parse
PROPERTIES
CXX_STANDARD_REQUIRED ON
OUTPUT_NAME parse)
set_target_properties(yaml-cpp-read
PROPERTIES
CXX_STANDARD_REQUIRED ON
OUTPUT_NAME read)
if (NOT DEFINED CMAKE_CXX_STANDARD)
set_target_properties(yaml-cpp-sandbox yaml-cpp-parse yaml-cpp-read
PROPERTIES
CXX_STANDARD 11)
endif()
-11
View File
@@ -1,11 +0,0 @@
set(PACKAGE_VERSION "@YAML_CPP_VERSION@")
# Check whether the requested PACKAGE_FIND_VERSION is compatible
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()
+2 -2
View File
@@ -1,7 +1,7 @@
prefix=@CMAKE_INSTALL_PREFIX@ prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix} exec_prefix=${prefix}
includedir=${prefix}/@INCLUDE_INSTALL_ROOT_DIR@ includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
libdir=${exec_prefix}/@LIB_INSTALL_DIR@ libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
Name: Yaml-cpp Name: Yaml-cpp
Description: A YAML parser and emitter for C++ Description: A YAML parser and emitter for C++