Fix YangSchema::childNodes with paths with choice
YangSchema::childNodes, if called with a path with a choice segfaulted,
because it was using libyang in a different way, than the rest of the
class. childNodes now uses libyang consistenly with the rest of the
class.
Change-Id: I81f19114a3088994c552c1bb2fd9b4e3bc326196
diff --git a/src/yang_schema.cpp b/src/yang_schema.cpp
index 2619943..1ac7a79 100644
--- a/src/yang_schema.cpp
+++ b/src/yang_schema.cpp
@@ -188,11 +188,8 @@
return keys.find(key) != keys.end();
}
-libyang::S_Schema_Node YangSchema::getSchemaNode(const schemaPath_& location, const ModuleNodePair& node) const
+libyang::S_Schema_Node YangSchema::impl_getSchemaNode(const std::string& node) const
{
- std::string absPath = location.m_nodes.empty() ? "" : "/";
- absPath += pathToAbsoluteSchemaString(location) + "/" + fullNodeName(location, node);
-
// If no node is found find_path prints an error message, so we have to
// disable logging
// https://github.com/CESNET/libyang/issues/753
@@ -205,10 +202,24 @@
[&oldOptions]() {
libyang::set_log_options(oldOptions);
});
- return m_context->get_node(nullptr, absPath.c_str());
+ return m_context->get_node(nullptr, node.c_str());
}
}
+
+libyang::S_Schema_Node YangSchema::getSchemaNode(const std::string& node) const
+{
+ return impl_getSchemaNode(node);
+}
+
+libyang::S_Schema_Node YangSchema::getSchemaNode(const schemaPath_& location, const ModuleNodePair& node) const
+{
+ std::string absPath = location.m_nodes.empty() ? "" : "/";
+ absPath += pathToAbsoluteSchemaString(location) + "/" + fullNodeName(location, node);
+
+ return impl_getSchemaNode(absPath);
+}
+
const std::set<std::string> YangSchema::listKeys(const schemaPath_& location, const ModuleNodePair& node) const
{
std::set<std::string> keys;
@@ -309,9 +320,8 @@
nodes = m_context->data_instantiables(0);
} else {
const auto absolutePath = "/" + pathToAbsoluteSchemaString(path);
- const auto set = m_context->find_path(absolutePath.c_str());
- const auto schemaSet = set->schema();
- nodes = (*schemaSet.begin())->child_instantiables(0);
+ const auto node = getSchemaNode(absolutePath);
+ nodes = node->child_instantiables(0);
}
for (const auto node : nodes) {
diff --git a/src/yang_schema.hpp b/src/yang_schema.hpp
index 12a250c..aa5faa4 100644
--- a/src/yang_schema.hpp
+++ b/src/yang_schema.hpp
@@ -69,6 +69,11 @@
/** @short Returns a set of nodes, that match the location and name criteria. */
/** @short Returns a single Schema_Node if the criteria matches only one, otherwise nullptr. */
+ std::shared_ptr<libyang::Schema_Node> getSchemaNode(const std::string& node) const;
+
+ /** @short Returns a single Schema_Node if the criteria matches only one, otherwise nullptr. */
std::shared_ptr<libyang::Schema_Node> getSchemaNode(const schemaPath_& location, const ModuleNodePair& node) const;
std::shared_ptr<libyang::Context> m_context;
+
+ std::shared_ptr<libyang::Schema_Node> impl_getSchemaNode(const std::string& node) const;
};
diff --git a/tests/yang.cpp b/tests/yang.cpp
index 156d94b..d9c2a89 100644
--- a/tests/yang.cpp
+++ b/tests/yang.cpp
@@ -6,6 +6,7 @@
*
*/
+#include <experimental/iterator>
#include "trompeloeil_doctest.h"
#include "yang_schema.hpp"
@@ -251,6 +252,16 @@
})";
+namespace std {
+std::ostream& operator<<(std::ostream& s, const std::set<std::string> set)
+{
+ s << std::endl << "{";
+ std::copy(set.begin(), set.end(), std::experimental::make_ostream_joiner(s, ", "));
+ s << "}" << std::endl;
+ return s;
+}
+}
+
TEST_CASE("yangschema")
{
using namespace std::string_view_literals;
@@ -696,6 +707,12 @@
set = {"bla2"};
}
+ SECTION("example-schema:ethernet")
+ {
+ path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("ethernet")));
+ set = {"ip"};
+ }
+
REQUIRE(ys.childNodes(path, Recursion::NonRecursive) == set);
}
}