Compare commits

...
Author SHA1 Message Date
Oliver Hamlet a66cf123c7 Add support for merge keys
Merge keys are specified here[1] for YAML 1.1. While not part of
the YAML 1.2 specification, they're very useful and are supported
in other implementations[2][3][4] that target 1.2.

Support for merge keys is optional and disabled by default. It can
be enabled by defining YAML_CPP_SUPPORT_MERGE_KEYS, either directly
or by setting the CMake option YAML_CPP_SUPPORT_MERGE_KEYS=ON.

[1]: http://yaml.org/type/merge.html
[2]: https://github.com/go-yaml/yaml
[3]: https://github.com/ruby/psych
[4]: https://bitbucket.org/ruamel/yaml
2018-08-23 19:40:12 +01:00
Jesse Beder 562aefc114 Bump CMake version to 0.6.2.
It was incorrectly left at 0.6.0 when 0.6.1 was released, so this needs to be done to make it consistent between the tagged version and the CMake version.
2018-03-05 22:56:23 -06:00
4 changed files with 82 additions and 3 deletions
+4 -1
View File
@@ -5,6 +5,9 @@ os:
compiler:
- clang
- gcc
env:
- YAML_CPP_SUPPORT_MERGE_KEYS=ON
- YAML_CPP_SUPPORT_MERGE_KEYS=OFF
before_install:
- |
if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
@@ -17,7 +20,7 @@ before_install:
before_script:
- mkdir build
- cd build
- cmake ..
- cmake .. -DYAML_CPP_SUPPORT_MERGE_KEYS=$YAML_CPP_SUPPORT_MERGE_KEYS
script:
- make
- test/run-tests
+6 -1
View File
@@ -28,7 +28,7 @@ project(YAML_CPP)
set(YAML_CPP_VERSION_MAJOR "0")
set(YAML_CPP_VERSION_MINOR "6")
set(YAML_CPP_VERSION_PATCH "0")
set(YAML_CPP_VERSION_PATCH "2")
set(YAML_CPP_VERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}.${YAML_CPP_VERSION_PATCH}")
enable_testing()
@@ -41,6 +41,7 @@ enable_testing()
option(YAML_CPP_BUILD_TESTS "Enable testing" ON)
option(YAML_CPP_BUILD_TOOLS "Enable parse tools" ON)
option(YAML_CPP_BUILD_CONTRIB "Enable contrib stuff in library" ON)
option(YAML_CPP_SUPPORT_MERGE_KEYS "Support YAML merge keys ('<<') in yaml-cpp's executable targets. Use '#define YAML_CPP_SUPPORT_MERGE_KEYS' instead when linking from another project." OFF)
## Build options
# --> General
@@ -97,6 +98,10 @@ else()
add_definitions(-DYAML_CPP_NO_CONTRIB)
endif()
if (YAML_CPP_SUPPORT_MERGE_KEYS)
add_definitions(-DYAML_CPP_SUPPORT_MERGE_KEYS)
endif()
set(library_sources
${sources}
${public_headers}
+39 -1
View File
@@ -122,12 +122,23 @@ class node {
// 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
// key).
return static_cast<const node_ref&>(*m_pRef).get(key, pMemory);
node* value = static_cast<const node_ref&>(*m_pRef).get(key, pMemory);
#ifdef YAML_CPP_SUPPORT_MERGE_KEYS
if (!value || value->type() == NodeType::Undefined) {
return get_value_from_merge_key(key, value, pMemory);
}
#endif
return value;
}
template <typename Key>
node& get(const Key& key, shared_memory_holder pMemory) {
node& value = m_pRef->get(key, pMemory);
value.add_dependency(*this);
#ifdef YAML_CPP_SUPPORT_MERGE_KEYS
if (value.type() == NodeType::Undefined) {
return *get_value_from_merge_key(key, &value, pMemory);
}
#endif
return value;
}
template <typename Key>
@@ -159,6 +170,33 @@ class node {
}
private:
#ifdef YAML_CPP_SUPPORT_MERGE_KEYS
template <typename Key>
inline node* get_value_from_merge_key(const Key& key, node* currentValue,
shared_memory_holder pMemory) const {
node* mergeValue =
static_cast<const node_ref&>(*m_pRef).get(std::string("<<"), pMemory);
if (!mergeValue) {
return currentValue;
}
if (mergeValue->type() == NodeType::Map) {
return &mergeValue->get(key, pMemory);
}
if (mergeValue->type() == NodeType::Sequence) {
for (const_node_iterator it = mergeValue->begin();
it != mergeValue->end(); ++it) {
if (it->pNode && it->pNode->type() == NodeType::Map) {
node* value = it->pNode->get(key, pMemory);
if (value && value->type() != NodeType::Undefined) {
return value;
}
}
}
}
return currentValue;
}
#endif
shared_node_ref m_pRef;
typedef std::set<node*> nodes;
nodes m_dependencies;
+33
View File
@@ -185,6 +185,39 @@ TEST(LoadNodeTest, DereferenceIteratorError) {
EXPECT_THROW(node.begin()->begin()->Type(), InvalidNode);
}
#ifdef YAML_CPP_SUPPORT_MERGE_KEYS
TEST(NodeTest, MergeKeyScalarSupport) {
Node node = Load("{<<: {a: 1}}");
ASSERT_FALSE(!node["a"]);
EXPECT_EQ(1, node["a"].as<int>());
}
TEST(NodeTest, MergeKeyExistingKey) {
Node node = Load("{a: 1, <<: {a: 2}}");
ASSERT_FALSE(!node["a"]);
EXPECT_EQ(1, node["a"].as<int>());
}
TEST(NodeTest, MergeKeySequenceSupport) {
Node node = Load("<<: [{a: 1}, {a: 2, b: 3}]");
ASSERT_FALSE(!node["a"]);
ASSERT_FALSE(!node["b"]);
EXPECT_EQ(1, node["a"].as<int>());
EXPECT_EQ(3, node["b"].as<int>());
}
TEST(NodeTest, NestedMergeKeys) {
Node node = Load("{<<: {<<: {a: 1}}}");
ASSERT_FALSE(!node["a"]);
EXPECT_EQ(1, node["a"].as<int>());
}
#else
TEST(NodeTest, MergeKeySupport) {
Node node = Load("{<<: {a: 1}}");
ASSERT_FALSE(node["a"]);
}
#endif
TEST(NodeTest, EmitEmptyNode) {
Node node;
Emitter emitter;