Merge "Update the NETCONF stack"
diff --git a/src/ast_commands.hpp b/src/ast_commands.hpp
index a1c377b..787fb94 100644
--- a/src/ast_commands.hpp
+++ b/src/ast_commands.hpp
@@ -40,27 +40,27 @@
struct ls_ : x3::position_tagged {
bool operator==(const ls_& b) const;
std::vector<LsOption> m_options;
- boost::optional<path_> m_path;
+ boost::optional<boost::variant<dataPath_, schemaPath_>> m_path;
};
struct cd_ : x3::position_tagged {
bool operator==(const cd_& b) const;
- path_ m_path;
+ dataPath_ m_path;
};
struct create_ : x3::position_tagged {
bool operator==(const create_& b) const;
- path_ m_path;
+ dataPath_ m_path;
};
struct delete_ : x3::position_tagged {
bool operator==(const delete_& b) const;
- path_ m_path;
+ dataPath_ m_path;
};
struct set_ : x3::position_tagged {
bool operator==(const set_& b) const;
- path_ m_path;
+ dataPath_ m_path;
leaf_data_ m_data;
};
@@ -70,7 +70,7 @@
struct get_ : x3::position_tagged {
bool operator==(const get_& b) const;
- boost::optional<path_> m_path;
+ boost::optional<boost::variant<dataPath_, schemaPath_>> m_path;
};
using command_ = boost::variant<discard_, ls_, cd_, create_, delete_, set_, commit_, get_>;
diff --git a/src/ast_handlers.hpp b/src/ast_handlers.hpp
index b19ece0..0cb64f1 100644
--- a/src/ast_handlers.hpp
+++ b/src/ast_handlers.hpp
@@ -121,7 +121,18 @@
}
}
};
+struct list_class {
+ template <typename T, typename Iterator, typename Context>
+ void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
+ {
+ auto& parserContext = x3::get<parser_context_tag>(context);
+ const Schema& schema = parserContext.m_schema;
+ if (!schema.isList(parserContext.m_curPath, {parserContext.m_curModule, ast.m_name})) {
+ _pass(context) = false;
+ }
+ }
+};
struct nodeup_class {
template <typename T, typename Iterator, typename Context>
void on_success(Iterator const&, Iterator const&, T&, Context const& context)
@@ -157,7 +168,6 @@
}
};
-
struct module_class {
template <typename T, typename Iterator, typename Context>
void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
@@ -175,7 +185,7 @@
}
};
-struct node_class {
+struct schemaNode_class {
template <typename T, typename Iterator, typename Context>
void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
{
@@ -191,6 +201,24 @@
}
};
+struct dataNodeList_class;
+
+struct dataNode_class {
+ template <typename T, typename Iterator, typename Context>
+ void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
+ {
+ auto& parserContext = x3::get<parser_context_tag>(context);
+ if (ast.m_suffix.type() == typeid(nodeup_)) {
+ parserContext.m_curPath.m_nodes.pop_back();
+ if (parserContext.m_curPath.m_nodes.empty())
+ parserContext.m_topLevelModulePresent = false;
+ } else {
+ parserContext.m_curPath.m_nodes.push_back(dataNodeToSchemaNode(ast));
+ parserContext.m_curModule = boost::none;
+ }
+ }
+};
+
struct absoluteStart_class {
template <typename T, typename Iterator, typename Context>
void on_success(Iterator const&, Iterator const&, T&, Context const& context)
@@ -200,7 +228,25 @@
}
};
-struct path_class {
+struct dataNodesListEnd_class;
+
+struct dataPathListEnd_class;
+
+struct dataPath_class {
+ template <typename Iterator, typename Exception, typename Context>
+ x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const&, Context const& context)
+ {
+ auto& parserContext = x3::get<parser_context_tag>(context);
+ if (parserContext.m_errorMsg.empty()) {
+ parserContext.m_errorMsg = "Expected path.";
+ return x3::error_handler_result::fail;
+ } else {
+ return x3::error_handler_result::rethrow;
+ }
+ }
+};
+
+struct schemaPath_class {
template <typename Iterator, typename Exception, typename Context>
x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const&, Context const& context)
{
@@ -240,7 +286,7 @@
if (ast.m_path.m_nodes.back().m_prefix)
module = ast.m_path.m_nodes.back().m_prefix.value().m_name;
container_ cont = boost::get<container_>(ast.m_path.m_nodes.back().m_suffix);
- path_ location = pathWithoutLastNode(parserContext.m_curPath);
+ schemaPath_ location = pathWithoutLastNode(parserContext.m_curPath);
if (!schema.isPresenceContainer(location, {module, cont.m_name})) {
parserContext.m_errorMsg = "This container is not a presence container.";
@@ -290,7 +336,10 @@
auto& schema = parserContext.m_schema;
if (parserContext.m_errorMsg.empty()) {
leaf_ leaf = boost::get<leaf_>(parserContext.m_curPath.m_nodes.back().m_suffix);
- path_ location = pathWithoutLastNode(parserContext.m_curPath);
+ schemaPath_ location = pathWithoutLastNode(parserContext.m_curPath);
+ if (location.m_nodes.empty()) {
+ parserContext.m_curModule = parserContext.m_curPath.m_nodes.back().m_prefix->m_name;
+ }
parserContext.m_errorMsg = "Expected " + leafDataTypeToString(schema.leafType(location, {parserContext.m_curModule, leaf.m_name})) + " here:";
return x3::error_handler_result::fail;
}
@@ -316,7 +365,7 @@
module = parserContext.m_curPath.m_nodes.back().m_prefix.value().m_name;
leaf_ leaf = boost::get<leaf_>(parserContext.m_curPath.m_nodes.back().m_suffix);
- path_ location = pathWithoutLastNode(parserContext.m_curPath);
+ schemaPath_ location = pathWithoutLastNode(parserContext.m_curPath);
if (schema.leafType(location, {module, leaf.m_name}) != m_type) {
_pass(context) = false;
@@ -341,7 +390,7 @@
module = parserContext.m_curPath.m_nodes.back().m_prefix.value().m_name;
leaf_ leaf = boost::get<leaf_>(parserContext.m_curPath.m_nodes.back().m_suffix);
- path_ location = pathWithoutLastNode(parserContext.m_curPath);
+ schemaPath_ location = pathWithoutLastNode(parserContext.m_curPath);
if (!schema.leafEnumHasValue(location, {module, leaf.m_name}, ast.m_value)) {
_pass(context) = false;
@@ -412,3 +461,18 @@
return x3::error_handler_result::fail;
}
};
+
+struct initializeContext_class {
+ template <typename T, typename Iterator, typename Context>
+ void on_success(Iterator const&, Iterator const&, T&, Context const& context)
+ {
+ auto& parserContext = x3::get<parser_context_tag>(context);
+ parserContext.m_curPath = parserContext.m_curPathOrig;
+ parserContext.m_tmpListKeys.clear();
+ parserContext.m_tmpListName.clear();
+ if (!parserContext.m_curPath.m_nodes.empty() && parserContext.m_curPath.m_nodes.at(0).m_prefix)
+ parserContext.m_topLevelModulePresent = true;
+ else
+ parserContext.m_topLevelModulePresent = false;
+ }
+};
diff --git a/src/ast_path.cpp b/src/ast_path.cpp
index bb14425..1f01a72 100644
--- a/src/ast_path.cpp
+++ b/src/ast_path.cpp
@@ -30,21 +30,38 @@
return this->m_name == b.m_name;
}
-node_::node_() = default;
+dataNode_::dataNode_() = default;
-node_::node_(decltype(m_suffix) node)
+dataNode_::dataNode_(decltype(m_suffix) node)
: m_suffix(node)
{
}
-node_::node_(module_ module, decltype(m_suffix) node)
+dataNode_::dataNode_(module_ module, decltype(m_suffix) node)
: m_prefix(module)
, m_suffix(node)
{
}
+schemaNode_::schemaNode_(decltype(m_suffix) node)
+ : m_suffix(node)
+{
+}
-bool node_::operator==(const node_& b) const
+schemaNode_::schemaNode_(module_ module, decltype(m_suffix) node)
+ : m_prefix(module)
+ , m_suffix(node)
+{
+}
+
+schemaNode_::schemaNode_() = default;
+
+bool schemaNode_::operator==(const schemaNode_& b) const
+{
+ return this->m_suffix == b.m_suffix && this->m_prefix == b.m_prefix;
+}
+
+bool dataNode_::operator==(const dataNode_& b) const
{
return this->m_suffix == b.m_suffix && this->m_prefix == b.m_prefix;
}
@@ -65,7 +82,24 @@
return (this->m_name == b.m_name && this->m_keys == b.m_keys);
}
-bool path_::operator==(const path_& b) const
+bool list_::operator==(const list_& b) const
+{
+ return (this->m_name == b.m_name);
+}
+
+list_::list_(const std::string& listName)
+ : m_name(listName)
+{
+}
+
+bool schemaPath_::operator==(const schemaPath_& b) const
+{
+ if (this->m_nodes.size() != b.m_nodes.size())
+ return false;
+ return this->m_nodes == b.m_nodes;
+}
+
+bool dataPath_::operator==(const dataPath_& b) const
{
if (this->m_nodes.size() != b.m_nodes.size())
return false;
@@ -118,12 +152,12 @@
}
};
-std::string nodeToSchemaString(decltype(path_::m_nodes)::value_type node)
+std::string nodeToSchemaString(decltype(dataPath_::m_nodes)::value_type node)
{
return boost::apply_visitor(nodeToSchemaStringVisitor(), node.m_suffix);
}
-std::string pathToDataString(const path_& path)
+std::string pathToDataString(const dataPath_& path)
{
std::string res;
for (const auto it : path.m_nodes)
@@ -135,7 +169,12 @@
return res;
}
-std::string pathToAbsoluteSchemaString(const path_& path)
+std::string pathToAbsoluteSchemaString(const dataPath_& path)
+{
+ return pathToAbsoluteSchemaString(dataPathToSchemaPath(path));
+}
+
+std::string pathToAbsoluteSchemaString(const schemaPath_& path)
{
std::string res;
if (path.m_nodes.empty()) {
@@ -152,7 +191,7 @@
return res;
}
-std::string pathToSchemaString(const path_& path)
+std::string pathToSchemaString(const schemaPath_& path)
{
std::string res;
for (const auto it : path.m_nodes) {
@@ -163,3 +202,40 @@
}
return res;
}
+
+std::string pathToSchemaString(const dataPath_& path)
+{
+ return pathToSchemaString(dataPathToSchemaPath(path));
+}
+
+struct dataSuffixToSchemaSuffix : boost::static_visitor<decltype(schemaNode_::m_suffix)> {
+ auto operator()(const listElement_& listElement) const
+ {
+ return list_{listElement.m_name};
+ }
+
+ template <typename T>
+ auto operator()(const T& suffix) const
+ {
+ return suffix;
+ }
+};
+
+schemaNode_ dataNodeToSchemaNode(const dataNode_& node)
+{
+ schemaNode_ res;
+ res.m_prefix = node.m_prefix;
+ res.m_suffix = boost::apply_visitor(dataSuffixToSchemaSuffix(), node.m_suffix);
+ return res;
+}
+
+schemaPath_ dataPathToSchemaPath(const dataPath_& path)
+{
+ schemaPath_ res{path.m_scope, {}};
+
+ std::transform(path.m_nodes.begin(), path.m_nodes.end(),
+ std::back_inserter(res.m_nodes),
+ [](const dataNode_& node) { return dataNodeToSchemaNode(node); });
+
+ return res;
+}
diff --git a/src/ast_path.hpp b/src/ast_path.hpp
index dab06ea..2711a30 100644
--- a/src/ast_path.hpp
+++ b/src/ast_path.hpp
@@ -53,19 +53,38 @@
std::map<std::string, std::string> m_keys;
};
+struct list_ {
+ list_() {}
+ list_(const std::string& listName);
+
+ bool operator==(const list_& b) const;
+
+ std::string m_name;
+};
+
struct module_ {
bool operator==(const module_& b) const;
std::string m_name;
};
-struct node_ {
+struct schemaNode_ {
boost::optional<module_> m_prefix;
- boost::variant<container_, listElement_, nodeup_, leaf_> m_suffix;
+ boost::variant<container_, list_, nodeup_, leaf_> m_suffix;
- node_();
- node_(decltype(m_suffix) node);
- node_(module_ module, decltype(m_suffix) node);
- bool operator==(const node_& b) const;
+ schemaNode_();
+ schemaNode_(decltype(m_suffix) node);
+ schemaNode_(module_ module, decltype(m_suffix) node);
+ bool operator==(const schemaNode_& b) const;
+};
+
+struct dataNode_ {
+ boost::optional<module_> m_prefix;
+ boost::variant<container_, listElement_, nodeup_, leaf_, list_> m_suffix;
+
+ dataNode_();
+ dataNode_(decltype(m_suffix) node);
+ dataNode_(module_ module, decltype(m_suffix) node);
+ bool operator==(const dataNode_& b) const;
};
enum class Scope {
@@ -73,20 +92,31 @@
Relative
};
-struct path_ {
- bool operator==(const path_& b) const;
+struct schemaPath_ {
+ bool operator==(const schemaPath_& b) const;
Scope m_scope = Scope::Relative;
- std::vector<node_> m_nodes;
+ std::vector<schemaNode_> m_nodes;
};
-std::string nodeToSchemaString(decltype(path_::m_nodes)::value_type node);
+struct dataPath_ {
+ bool operator==(const dataPath_& b) const;
+ Scope m_scope = Scope::Relative;
+ std::vector<dataNode_> m_nodes;
+};
-std::string pathToAbsoluteSchemaString(const path_& path);
-std::string pathToDataString(const path_& path);
-std::string pathToSchemaString(const path_& path);
+std::string nodeToSchemaString(decltype(dataPath_::m_nodes)::value_type node);
+
+std::string pathToAbsoluteSchemaString(const dataPath_& path);
+std::string pathToAbsoluteSchemaString(const schemaPath_& path);
+std::string pathToDataString(const dataPath_& path);
+std::string pathToSchemaString(const schemaPath_& path);
+schemaNode_ dataNodeToSchemaNode(const dataNode_& node);
+schemaPath_ dataPathToSchemaPath(const dataPath_& path);
BOOST_FUSION_ADAPT_STRUCT(container_, m_name)
BOOST_FUSION_ADAPT_STRUCT(listElement_, m_name, m_keys)
BOOST_FUSION_ADAPT_STRUCT(module_, m_name)
-BOOST_FUSION_ADAPT_STRUCT(node_, m_prefix, m_suffix)
-BOOST_FUSION_ADAPT_STRUCT(path_, m_scope, m_nodes)
+BOOST_FUSION_ADAPT_STRUCT(dataNode_, m_prefix, m_suffix)
+BOOST_FUSION_ADAPT_STRUCT(schemaNode_, m_prefix, m_suffix)
+BOOST_FUSION_ADAPT_STRUCT(dataPath_, m_scope, m_nodes)
+BOOST_FUSION_ADAPT_STRUCT(schemaPath_, m_scope, m_nodes)
diff --git a/src/grammars.hpp b/src/grammars.hpp
index 03753e8..7caa45c 100644
--- a/src/grammars.hpp
+++ b/src/grammars.hpp
@@ -19,14 +19,20 @@
x3::rule<listPrefix_class, std::string> const listPrefix = "listPrefix";
x3::rule<listSuffix_class, std::vector<keyValue_>> const listSuffix = "listSuffix";
x3::rule<listElement_class, listElement_> const listElement = "listElement";
+x3::rule<list_class, list_> const list = "list";
x3::rule<nodeup_class, nodeup_> const nodeup = "nodeup";
x3::rule<container_class, container_> const container = "container";
x3::rule<leaf_class, leaf_> const leaf = "leaf";
x3::rule<module_class, module_> const module = "module";
-x3::rule<node_class, node_> const node = "node";
+x3::rule<dataNode_class, dataNode_> const dataNode = "dataNode";
+x3::rule<schemaNode_class, schemaNode_> const schemaNode = "schemaNode";
x3::rule<absoluteStart_class, Scope> const absoluteStart = "absoluteStart";
-x3::rule<path_class, path_> const path = "path";
-x3::rule<leaf_path_class, path_> const leafPath = "leafPath";
+x3::rule<schemaPath_class, schemaPath_> const schemaPath = "schemaPath";
+x3::rule<dataNodeList_class, decltype(dataPath_::m_nodes)::value_type> const dataNodeList = "dataNodeList";
+x3::rule<dataNodesListEnd_class, decltype(dataPath_::m_nodes)> const dataNodesListEnd = "dataNodesListEnd";
+x3::rule<dataPathListEnd_class, dataPath_> const dataPathListEnd = "dataPathListEnd";
+x3::rule<dataPath_class, dataPath_> const dataPath = "dataPath";
+x3::rule<leaf_path_class, dataPath_> const leafPath = "leafPath";
x3::rule<leaf_data_class, leaf_data_> const leaf_data = "leaf_data";
x3::rule<leaf_data_enum_class, enum_> const leaf_data_enum = "leaf_data_enum";
@@ -46,6 +52,8 @@
x3::rule<commit_class, commit_> const commit = "commit";
x3::rule<command_class, command_> const command = "command";
+x3::rule<initializeContext_class, x3::unused_type> const initializeContext = "initializeContext";
+
#if __clang__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Woverloaded-shift-op-parentheses"
@@ -86,6 +94,9 @@
auto const listElement_def =
listPrefix > listSuffix;
+auto const list_def =
+ node_identifier >> !char_('[');
+
auto const nodeup_def =
lit("..") > x3::attr(nodeup_());
@@ -99,19 +110,41 @@
node_identifier;
// leaf cannot be in the middle of a path, however, I need the grammar's attribute to be a vector of variants
-auto const node_def =
- -(module) >> x3::expect[container | listElement | nodeup | leaf];
+auto const schemaNode_def =
+ -(module) >> x3::expect[container | list | nodeup | leaf];
+
+auto const dataNode_def =
+ -(module) >> (container | listElement | nodeup | leaf);
auto const absoluteStart_def =
x3::omit['/'] >> x3::attr(Scope::Absolute);
// I have to insert an empty vector to the first alternative, otherwise they won't have the same attribute
-auto const path_def =
- absoluteStart >> x3::attr(decltype(path_::m_nodes)()) >> x3::eoi |
- -(absoluteStart) >> node % '/';
+auto const dataPath_def =
+ absoluteStart >> x3::attr(decltype(dataPath_::m_nodes)()) >> x3::eoi |
+ -(absoluteStart) >> dataNode % '/';
+
+auto const dataNodeList_def =
+ -(module) >> list;
+
+// This intermediate rule is mandatory, because we need the first alternative
+// to be collapsed to a vector. If we didn't use the intermediate rule,
+// Spirit wouldn't know we want it to collapse.
+// https://github.com/boostorg/spirit/issues/408
+auto const dataNodesListEnd_def =
+ dataNode % '/' >> '/' >> dataNodeList |
+ initializeContext >> x3::attr(decltype(dataPath_::m_nodes)()) >> dataNodeList;
+
+auto const dataPathListEnd_def =
+ absoluteStart >> x3::attr(decltype(dataPath_::m_nodes)()) >> x3::eoi |
+ -(absoluteStart) >> dataNodesListEnd;
+
+auto const schemaPath_def =
+ absoluteStart >> x3::attr(decltype(schemaPath_::m_nodes)()) >> x3::eoi |
+ -(absoluteStart) >> schemaNode % '/';
auto const leafPath_def =
- path;
+ dataPath;
auto const leaf_data_enum_def =
+char_;
@@ -156,20 +189,24 @@
}
} const ls_options;
+// A "nothing" parser, which is used to reset the context (when trying to parse different types of paths)
+auto const initializeContext_def =
+ x3::eps;
+
auto const ls_def =
- lit("ls") >> *(space_separator >> ls_options) >> -(space_separator >> path);
+ lit("ls") >> *(space_separator >> ls_options) >> -(space_separator >> (dataPathListEnd | initializeContext >> dataPath));
auto const cd_def =
- lit("cd") >> space_separator > path;
+ lit("cd") >> space_separator > dataPath;
auto const create_def =
- lit("create") >> space_separator > path;
+ lit("create") >> space_separator > dataPath;
auto const delete_rule_def =
- lit("delete") >> space_separator > path;
+ lit("delete") >> space_separator > dataPath;
auto const get_def =
- lit("get") >> -path;
+ lit("get") >> -(space_separator >> (dataPathListEnd | initializeContext >> dataPath));
auto const set_def =
lit("set") >> space_separator > leafPath > leaf_data;
@@ -194,13 +231,19 @@
BOOST_SPIRIT_DEFINE(listPrefix)
BOOST_SPIRIT_DEFINE(listSuffix)
BOOST_SPIRIT_DEFINE(listElement)
+BOOST_SPIRIT_DEFINE(list)
BOOST_SPIRIT_DEFINE(nodeup)
+BOOST_SPIRIT_DEFINE(schemaNode)
+BOOST_SPIRIT_DEFINE(dataNode)
BOOST_SPIRIT_DEFINE(container)
BOOST_SPIRIT_DEFINE(leaf)
BOOST_SPIRIT_DEFINE(leafPath)
-BOOST_SPIRIT_DEFINE(node)
+BOOST_SPIRIT_DEFINE(schemaPath)
+BOOST_SPIRIT_DEFINE(dataPath)
+BOOST_SPIRIT_DEFINE(dataNodeList)
+BOOST_SPIRIT_DEFINE(dataNodesListEnd)
+BOOST_SPIRIT_DEFINE(dataPathListEnd)
BOOST_SPIRIT_DEFINE(absoluteStart)
-BOOST_SPIRIT_DEFINE(path)
BOOST_SPIRIT_DEFINE(module)
BOOST_SPIRIT_DEFINE(leaf_data)
BOOST_SPIRIT_DEFINE(leaf_data_enum)
@@ -209,6 +252,7 @@
BOOST_SPIRIT_DEFINE(leaf_data_int)
BOOST_SPIRIT_DEFINE(leaf_data_uint)
BOOST_SPIRIT_DEFINE(leaf_data_string)
+BOOST_SPIRIT_DEFINE(initializeContext)
BOOST_SPIRIT_DEFINE(set)
BOOST_SPIRIT_DEFINE(commit)
BOOST_SPIRIT_DEFINE(get)
diff --git a/src/interpreter.cpp b/src/interpreter.cpp
index 452bc74..80e6195 100644
--- a/src/interpreter.cpp
+++ b/src/interpreter.cpp
@@ -84,14 +84,39 @@
return joinPaths(m_parser.currentNode(), pathToDataString(command.m_path));
}
+struct pathToStringVisitor : boost::static_visitor<std::string> {
+ std::string operator()(const schemaPath_& path) const
+ {
+ return pathToSchemaString(path);
+ }
+ std::string operator()(const dataPath_& path) const
+ {
+ return pathToDataString(path);
+ }
+};
+
+struct getPathScopeVisitor : boost::static_visitor<Scope> {
+ template <typename T>
+ Scope operator()(const T& path) const
+ {
+ return path.m_scope;
+ }
+};
+
std::string Interpreter::absolutePathFromCommand(const get_& get) const
{
if (!get.m_path) {
return m_parser.currentNode();
- } else if (get.m_path->m_scope == Scope::Absolute) {
- return "/" + pathToDataString(*get.m_path);
+ }
+
+ const auto path = *get.m_path;
+ std::string pathString = boost::apply_visitor(pathToStringVisitor(), path);
+ auto pathScope{boost::apply_visitor(getPathScopeVisitor(), path)};
+
+ if (pathScope == Scope::Absolute) {
+ return "/" + pathString;
} else {
- return joinPaths(m_parser.currentNode(), pathToDataString(*get.m_path));
+ return joinPaths(m_parser.currentNode(), pathString);
}
}
diff --git a/src/parser.cpp b/src/parser.cpp
index f25f1a3..ee0233e 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -21,7 +21,7 @@
command_ Parser::parseCommand(const std::string& line, std::ostream& errorStream)
{
command_ parsedCommand;
- ParserContext ctx(*m_schema, m_curDir);
+ ParserContext ctx(*m_schema, dataPathToSchemaPath(m_curDir));
auto it = line.begin();
boost::spirit::x3::error_handler<std::string::const_iterator> errorHandler(it, line.end(), errorStream);
@@ -39,7 +39,7 @@
return parsedCommand;
}
-void Parser::changeNode(const path_& name)
+void Parser::changeNode(const dataPath_& name)
{
if (name.m_scope == Scope::Absolute) {
m_curDir = name;
@@ -58,10 +58,25 @@
return "/" + pathToDataString(m_curDir);
}
-std::set<std::string> Parser::availableNodes(const boost::optional<path_>& path, const Recursion& option) const
+struct getSchemaPathVisitor : boost::static_visitor<schemaPath_> {
+ schemaPath_ operator()(const dataPath_& path) const
+ {
+ return dataPathToSchemaPath(path);
+ }
+
+ schemaPath_ operator()(const schemaPath_& path) const
+ {
+ return path;
+ }
+};
+
+
+std::set<std::string> Parser::availableNodes(const boost::optional<boost::variant<dataPath_, schemaPath_>>& path, const Recursion& option) const
{
- auto pathArg = m_curDir;
- if (path)
- pathArg.m_nodes.insert(pathArg.m_nodes.end(), path->m_nodes.begin(), path->m_nodes.end());
+ auto pathArg = dataPathToSchemaPath(m_curDir);
+ if (path) {
+ auto schemaPath = boost::apply_visitor(getSchemaPathVisitor(), *path);
+ pathArg.m_nodes.insert(pathArg.m_nodes.end(), schemaPath.m_nodes.begin(), schemaPath.m_nodes.end());
+ }
return m_schema->childNodes(pathArg, option);
}
diff --git a/src/parser.hpp b/src/parser.hpp
index 0318733..343a1e5 100644
--- a/src/parser.hpp
+++ b/src/parser.hpp
@@ -27,11 +27,11 @@
public:
Parser(const std::shared_ptr<const Schema> schema);
command_ parseCommand(const std::string& line, std::ostream& errorStream);
- void changeNode(const path_& name);
+ void changeNode(const dataPath_& name);
std::string currentNode() const;
- std::set<std::string> availableNodes(const boost::optional<path_>& path, const Recursion& option) const;
+ std::set<std::string> availableNodes(const boost::optional<boost::variant<dataPath_, schemaPath_>>& path, const Recursion& option) const;
private:
const std::shared_ptr<const Schema> m_schema;
- path_ m_curDir;
+ dataPath_ m_curDir;
};
diff --git a/src/parser_context.cpp b/src/parser_context.cpp
index fa64344..c240984 100644
--- a/src/parser_context.cpp
+++ b/src/parser_context.cpp
@@ -7,11 +7,11 @@
*/
#include "parser_context.hpp"
-ParserContext::ParserContext(const Schema& schema, const path_ curDir)
+ParserContext::ParserContext(const Schema& schema, const schemaPath_& curDir)
: m_schema(schema)
+ , m_curPath(curDir)
+ , m_curPathOrig(curDir)
{
- m_curPath = curDir;
-
if (!m_curPath.m_nodes.empty() && m_curPath.m_nodes.at(0).m_prefix)
m_topLevelModulePresent = true;
}
diff --git a/src/parser_context.hpp b/src/parser_context.hpp
index 28c5eb1..a0b8e30 100644
--- a/src/parser_context.hpp
+++ b/src/parser_context.hpp
@@ -8,9 +8,10 @@
#include "schema.hpp"
struct ParserContext {
- ParserContext(const Schema& schema, const path_ curDir);
+ ParserContext(const Schema& schema, const schemaPath_& curDir);
const Schema& m_schema;
- path_ m_curPath;
+ schemaPath_ m_curPath;
+ const schemaPath_ m_curPathOrig;
boost::optional<std::string> m_curModule;
std::string m_errorMsg;
std::string m_tmpListName;
diff --git a/src/schema.hpp b/src/schema.hpp
index e5827de..e1f019f 100644
--- a/src/schema.hpp
+++ b/src/schema.hpp
@@ -69,17 +69,17 @@
public:
virtual ~Schema();
- virtual bool isContainer(const path_& location, const ModuleNodePair& node) const = 0;
- virtual bool isLeaf(const path_& location, const ModuleNodePair& node) const = 0;
- virtual bool isModule(const path_& location, const std::string& name) const = 0;
- virtual bool isList(const path_& location, const ModuleNodePair& node) const = 0;
- virtual bool isPresenceContainer(const path_& location, const ModuleNodePair& node) const = 0;
- virtual bool leafEnumHasValue(const path_& location, const ModuleNodePair& node, const std::string& value) const = 0;
- virtual bool listHasKey(const path_& location, const ModuleNodePair& node, const std::string& key) const = 0;
+ virtual bool isContainer(const schemaPath_& location, const ModuleNodePair& node) const = 0;
+ virtual bool isLeaf(const schemaPath_& location, const ModuleNodePair& node) const = 0;
+ virtual bool isModule(const schemaPath_& location, const std::string& name) const = 0;
+ virtual bool isList(const schemaPath_& location, const ModuleNodePair& node) const = 0;
+ virtual bool isPresenceContainer(const schemaPath_& location, const ModuleNodePair& node) const = 0;
+ virtual bool leafEnumHasValue(const schemaPath_& location, const ModuleNodePair& node, const std::string& value) const = 0;
+ virtual bool listHasKey(const schemaPath_& location, const ModuleNodePair& node, const std::string& key) const = 0;
virtual bool nodeExists(const std::string& location, const std::string& node) const = 0;
- virtual const std::set<std::string> listKeys(const path_& location, const ModuleNodePair& node) const = 0;
- virtual yang::LeafDataTypes leafType(const path_& location, const ModuleNodePair& node) const = 0;
- virtual std::set<std::string> childNodes(const path_& path, const Recursion recursion) const = 0;
+ virtual const std::set<std::string> listKeys(const schemaPath_& location, const ModuleNodePair& node) const = 0;
+ virtual yang::LeafDataTypes leafType(const schemaPath_& location, const ModuleNodePair& node) const = 0;
+ virtual std::set<std::string> childNodes(const schemaPath_& path, const Recursion recursion) const = 0;
private:
const std::unordered_map<std::string, NodeType>& children(const std::string& name) const;
diff --git a/src/static_schema.cpp b/src/static_schema.cpp
index ce94218..9be7751 100644
--- a/src/static_schema.cpp
+++ b/src/static_schema.cpp
@@ -31,12 +31,12 @@
return childrenRef.find(node) != childrenRef.end();
}
-bool StaticSchema::isModule(const path_&, const std::string& name) const
+bool StaticSchema::isModule(const schemaPath_&, const std::string& name) const
{
return m_modules.find(name) != m_modules.end();
}
-bool StaticSchema::isContainer(const path_& location, const ModuleNodePair& node) const
+bool StaticSchema::isContainer(const schemaPath_& location, const ModuleNodePair& node) const
{
std::string locationString = pathToAbsoluteSchemaString(location);
auto fullName = fullNodeName(location, node);
@@ -55,7 +55,7 @@
m_nodes.emplace(key, std::unordered_map<std::string, NodeType>());
}
-bool StaticSchema::listHasKey(const path_& location, const ModuleNodePair& node, const std::string& key) const
+bool StaticSchema::listHasKey(const schemaPath_& location, const ModuleNodePair& node, const std::string& key) const
{
std::string locationString = pathToAbsoluteSchemaString(location);
assert(isList(location, node));
@@ -65,7 +65,7 @@
return list.m_keys.find(key) != list.m_keys.end();
}
-const std::set<std::string> StaticSchema::listKeys(const path_& location, const ModuleNodePair& node) const
+const std::set<std::string> StaticSchema::listKeys(const schemaPath_& location, const ModuleNodePair& node) const
{
std::string locationString = pathToAbsoluteSchemaString(location);
assert(isList(location, node));
@@ -75,7 +75,7 @@
return list.m_keys;
}
-bool StaticSchema::isList(const path_& location, const ModuleNodePair& node) const
+bool StaticSchema::isList(const schemaPath_& location, const ModuleNodePair& node) const
{
std::string locationString = pathToAbsoluteSchemaString(location);
auto fullName = fullNodeName(location, node);
@@ -95,7 +95,7 @@
m_nodes.emplace(name, std::unordered_map<std::string, NodeType>());
}
-bool StaticSchema::isPresenceContainer(const path_& location, const ModuleNodePair& node) const
+bool StaticSchema::isPresenceContainer(const schemaPath_& location, const ModuleNodePair& node) const
{
if (!isContainer(location, node))
return false;
@@ -119,7 +119,7 @@
}
-bool StaticSchema::leafEnumHasValue(const path_& location, const ModuleNodePair& node, const std::string& value) const
+bool StaticSchema::leafEnumHasValue(const schemaPath_& location, const ModuleNodePair& node, const std::string& value) const
{
std::string locationString = pathToAbsoluteSchemaString(location);
assert(isLeaf(location, node));
@@ -129,7 +129,7 @@
return list.m_enumValues.find(value) != list.m_enumValues.end();
}
-bool StaticSchema::isLeaf(const path_& location, const ModuleNodePair& node) const
+bool StaticSchema::isLeaf(const schemaPath_& location, const ModuleNodePair& node) const
{
std::string locationString = pathToAbsoluteSchemaString(location);
auto fullName = fullNodeName(location, node);
@@ -139,7 +139,7 @@
return children(locationString).at(fullName).type() == typeid(yang::leaf);
}
-yang::LeafDataTypes StaticSchema::leafType(const path_& location, const ModuleNodePair& node) const
+yang::LeafDataTypes StaticSchema::leafType(const schemaPath_& location, const ModuleNodePair& node) const
{
std::string locationString = pathToAbsoluteSchemaString(location);
return boost::get<yang::leaf>(children(locationString).at(fullNodeName(location, node))).m_type;
@@ -147,7 +147,7 @@
// We do not test StaticSchema, so we don't need to implement recursive childNodes
// for this class.
-std::set<std::string> StaticSchema::childNodes(const path_& path, const Recursion) const
+std::set<std::string> StaticSchema::childNodes(const schemaPath_& path, const Recursion) const
{
std::string locationString = pathToAbsoluteSchemaString(path);
std::set<std::string> res;
diff --git a/src/static_schema.hpp b/src/static_schema.hpp
index 68f1401..7326120 100644
--- a/src/static_schema.hpp
+++ b/src/static_schema.hpp
@@ -23,17 +23,17 @@
public:
StaticSchema();
- bool isContainer(const path_& location, const ModuleNodePair& node) const override;
- bool isModule(const path_& location, const std::string& name) const override;
- bool isLeaf(const path_& location, const ModuleNodePair& node) const override;
- bool isList(const path_& location, const ModuleNodePair& node) const override;
- bool isPresenceContainer(const path_& location, const ModuleNodePair& node) const override;
- bool leafEnumHasValue(const path_& location, const ModuleNodePair& node, const std::string& value) const override;
- bool listHasKey(const path_& location, const ModuleNodePair& node, const std::string& key) const override;
+ bool isContainer(const schemaPath_& location, const ModuleNodePair& node) const override;
+ bool isModule(const schemaPath_& location, const std::string& name) const override;
+ bool isLeaf(const schemaPath_& location, const ModuleNodePair& node) const override;
+ bool isList(const schemaPath_& location, const ModuleNodePair& node) const override;
+ bool isPresenceContainer(const schemaPath_& location, const ModuleNodePair& node) const override;
+ bool leafEnumHasValue(const schemaPath_& location, const ModuleNodePair& node, const std::string& value) const override;
+ bool listHasKey(const schemaPath_& location, const ModuleNodePair& node, const std::string& key) const override;
bool nodeExists(const std::string& location, const std::string& node) const override;
- const std::set<std::string> listKeys(const path_& location, const ModuleNodePair& node) const override;
- yang::LeafDataTypes leafType(const path_& location, const ModuleNodePair& node) const override;
- std::set<std::string> childNodes(const path_& path, const Recursion) const override;
+ const std::set<std::string> listKeys(const schemaPath_& location, const ModuleNodePair& node) const override;
+ yang::LeafDataTypes leafType(const schemaPath_& location, const ModuleNodePair& node) const override;
+ std::set<std::string> childNodes(const schemaPath_& path, const Recursion) const override;
void addContainer(const std::string& location, const std::string& name, yang::ContainerTraits isPresence = yang::ContainerTraits::None);
void addLeaf(const std::string& location, const std::string& name, const yang::LeafDataTypes& type);
diff --git a/src/utils.cpp b/src/utils.cpp
index eb48349..f9eae06 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -26,9 +26,9 @@
return res;
}
-path_ pathWithoutLastNode(const path_& path)
+schemaPath_ pathWithoutLastNode(const schemaPath_& path)
{
- return path_{path.m_scope, decltype(path_::m_nodes)(path.m_nodes.begin(), path.m_nodes.end() - 1)};
+ return schemaPath_{path.m_scope, decltype(schemaPath_::m_nodes)(path.m_nodes.begin(), path.m_nodes.end() - 1)};
}
std::string leafDataTypeToString(yang::LeafDataTypes type)
@@ -51,7 +51,7 @@
}
}
-std::string fullNodeName(const path_& location, const ModuleNodePair& pair)
+std::string fullNodeName(const schemaPath_& location, const ModuleNodePair& pair)
{
if (!pair.first) {
return location.m_nodes.at(0).m_prefix.value().m_name + ":" + pair.second;
@@ -59,3 +59,8 @@
return pair.first.value() + ":" + pair.second;
}
}
+
+std::string fullNodeName(const dataPath_& location, const ModuleNodePair& pair)
+{
+ return fullNodeName(dataPathToSchemaPath(location), pair);
+}
diff --git a/src/utils.hpp b/src/utils.hpp
index 49b5b29..f009ccd 100644
--- a/src/utils.hpp
+++ b/src/utils.hpp
@@ -11,6 +11,8 @@
std::string joinPaths(const std::string& prefix, const std::string& suffix);
std::string stripLastNodeFromPath(const std::string& path);
-path_ pathWithoutLastNode(const path_& path);
+schemaPath_ pathWithoutLastNode(const schemaPath_& path);
+dataPath_ pathWithoutLastNode(const dataPath_& path);
std::string leafDataTypeToString(yang::LeafDataTypes type);
-std::string fullNodeName(const path_& location, const ModuleNodePair& pair);
+std::string fullNodeName(const schemaPath_& location, const ModuleNodePair& pair);
+std::string fullNodeName(const dataPath_& location, const ModuleNodePair& pair);
diff --git a/src/yang_schema.cpp b/src/yang_schema.cpp
index 7127082..522e58a 100644
--- a/src/yang_schema.cpp
+++ b/src/yang_schema.cpp
@@ -30,7 +30,8 @@
~InvalidSchemaQueryException() override = default;
};
-std::string pathToYangAbsSchemPath(const path_& path)
+template <typename T>
+std::string pathToYangAbsSchemPath(const T& path)
{
std::string res = "/";
std::string currentModule;
@@ -78,38 +79,38 @@
}
}
-bool YangSchema::isModule(const path_&, const std::string& name) const
+bool YangSchema::isModule(const schemaPath_&, const std::string& name) const
{
const auto set = modules();
return set.find(name) != set.end();
}
-bool YangSchema::isContainer(const path_& location, const ModuleNodePair& node) const
+bool YangSchema::isContainer(const schemaPath_& location, const ModuleNodePair& node) const
{
const auto schemaNode = getSchemaNode(location, node);
return schemaNode && schemaNode->nodetype() == LYS_CONTAINER;
}
-bool YangSchema::isLeaf(const path_& location, const ModuleNodePair& node) const
+bool YangSchema::isLeaf(const schemaPath_& location, const ModuleNodePair& node) const
{
const auto schemaNode = getSchemaNode(location, node);
return schemaNode && schemaNode->nodetype() == LYS_LEAF;
}
-bool YangSchema::isList(const path_& location, const ModuleNodePair& node) const
+bool YangSchema::isList(const schemaPath_& location, const ModuleNodePair& node) const
{
const auto schemaNode = getSchemaNode(location, node);
return schemaNode && schemaNode->nodetype() == LYS_LIST;
}
-bool YangSchema::isPresenceContainer(const path_& location, const ModuleNodePair& node) const
+bool YangSchema::isPresenceContainer(const schemaPath_& location, const ModuleNodePair& node) const
{
if (!isContainer(location, node))
return false;
return libyang::Schema_Node_Container(getSchemaNode(location, node)).presence();
}
-bool YangSchema::leafEnumHasValue(const path_& location, const ModuleNodePair& node, const std::string& value) const
+bool YangSchema::leafEnumHasValue(const schemaPath_& location, const ModuleNodePair& node, const std::string& value) const
{
if (!isLeaf(location, node) || leafType(location, node) != yang::LeafDataTypes::Enum)
return false;
@@ -128,7 +129,7 @@
return std::any_of(enm.begin(), enm.end(), [=](const auto& x) { return x->name() == value; });
}
-bool YangSchema::listHasKey(const path_& location, const ModuleNodePair& node, const std::string& key) const
+bool YangSchema::listHasKey(const schemaPath_& location, const ModuleNodePair& node, const std::string& key) const
{
if (!isList(location, node))
return false;
@@ -143,14 +144,14 @@
return set->number() == 1;
}
-libyang::S_Set YangSchema::getNodeSet(const path_& location, const ModuleNodePair& node) const
+libyang::S_Set YangSchema::getNodeSet(const schemaPath_& location, const ModuleNodePair& node) const
{
std::string absPath = location.m_nodes.empty() ? "" : "/";
absPath += pathToAbsoluteSchemaString(location) + "/" + fullNodeName(location, node);
return m_context->find_path(absPath.c_str());
}
-libyang::S_Schema_Node YangSchema::getSchemaNode(const path_& location, const ModuleNodePair& node) const
+libyang::S_Schema_Node YangSchema::getSchemaNode(const schemaPath_& location, const ModuleNodePair& node) const
{
const auto set = getNodeSet(location, node);
if (!set)
@@ -161,7 +162,7 @@
return *schemaSet.begin();
}
-const std::set<std::string> YangSchema::listKeys(const path_& location, const ModuleNodePair& node) const
+const std::set<std::string> YangSchema::listKeys(const schemaPath_& location, const ModuleNodePair& node) const
{
std::set<std::string> keys;
if (!isList(location, node))
@@ -174,7 +175,7 @@
return keys;
}
-yang::LeafDataTypes YangSchema::leafType(const path_& location, const ModuleNodePair& node) const
+yang::LeafDataTypes YangSchema::leafType(const schemaPath_& location, const ModuleNodePair& node) const
{
using namespace std::string_literals;
if (!isLeaf(location, node))
@@ -210,7 +211,7 @@
return res;
}
-std::set<std::string> YangSchema::childNodes(const path_& path, const Recursion recursion) const
+std::set<std::string> YangSchema::childNodes(const schemaPath_& path, const Recursion recursion) const
{
using namespace std::string_view_literals;
std::set<std::string> res;
diff --git a/src/yang_schema.hpp b/src/yang_schema.hpp
index c61232f..e4d6d5d 100644
--- a/src/yang_schema.hpp
+++ b/src/yang_schema.hpp
@@ -29,17 +29,17 @@
YangSchema();
~YangSchema() override;
- bool isContainer(const path_& location, const ModuleNodePair& node) const override;
- bool isLeaf(const path_& location, const ModuleNodePair& node) const override;
- bool isModule(const path_& location, const std::string& name) const override;
- bool isList(const path_& location, const ModuleNodePair& node) const override;
- bool isPresenceContainer(const path_& location, const ModuleNodePair& node) const override;
- bool leafEnumHasValue(const path_& location, const ModuleNodePair& node, const std::string& value) const override;
- bool listHasKey(const path_& location, const ModuleNodePair& node, const std::string& key) const override;
+ bool isContainer(const schemaPath_& location, const ModuleNodePair& node) const override;
+ bool isLeaf(const schemaPath_& location, const ModuleNodePair& node) const override;
+ bool isModule(const schemaPath_& location, const std::string& name) const override;
+ bool isList(const schemaPath_& location, const ModuleNodePair& node) const override;
+ bool isPresenceContainer(const schemaPath_& location, const ModuleNodePair& node) const override;
+ bool leafEnumHasValue(const schemaPath_& location, const ModuleNodePair& node, const std::string& value) const override;
+ bool listHasKey(const schemaPath_& location, const ModuleNodePair& node, const std::string& key) const override;
bool nodeExists(const std::string& location, const std::string& node) const override;
- const std::set<std::string> listKeys(const path_& location, const ModuleNodePair& node) const override;
- yang::LeafDataTypes leafType(const path_& location, const ModuleNodePair& node) const override;
- std::set<std::string> childNodes(const path_& path, const Recursion recursion) const override;
+ const std::set<std::string> listKeys(const schemaPath_& location, const ModuleNodePair& node) const override;
+ yang::LeafDataTypes leafType(const schemaPath_& location, const ModuleNodePair& node) const override;
+ std::set<std::string> childNodes(const schemaPath_& path, const Recursion recursion) const override;
void registerModuleCallback(const std::function<std::string(const char*, const char*, const char*)>& clb);
@@ -57,12 +57,12 @@
private:
std::set<std::string> modules() const;
- bool nodeExists(const path_& location, const ModuleNodePair& node) const;
+ bool nodeExists(const schemaPath_& location, const ModuleNodePair& node) const;
/** @short Returns a set of nodes, that match the location and name criteria. */
- std::shared_ptr<libyang::Set> getNodeSet(const path_& location, const ModuleNodePair& node) const;
+ std::shared_ptr<libyang::Set> getNodeSet(const schemaPath_& location, const ModuleNodePair& node) const;
/** @short Returns a single Schema_Node if the criteria matches only one, otherwise nullptr. */
- std::shared_ptr<libyang::Schema_Node> getSchemaNode(const path_& location, const ModuleNodePair& node) const;
+ std::shared_ptr<libyang::Schema_Node> getSchemaNode(const schemaPath_& location, const ModuleNodePair& node) const;
std::shared_ptr<libyang::Context> m_context;
};
diff --git a/tests/cd.cpp b/tests/cd.cpp
index ffa4bbf..85ea794 100644
--- a/tests/cd.cpp
+++ b/tests/cd.cpp
@@ -40,40 +40,40 @@
SECTION("example:a")
{
input = "cd example:a";
- expected.m_path.m_nodes.push_back(node_(module_{"example"}, container_("a")));
+ expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
}
SECTION("second:a")
{
input = "cd second:a";
- expected.m_path.m_nodes.push_back(node_(module_{"second"}, container_("a")));
+ expected.m_path.m_nodes.push_back(dataNode_(module_{"second"}, container_("a")));
}
SECTION("example:b")
{
input = "cd example:b";
- expected.m_path.m_nodes.push_back(node_(module_{"example"}, container_("b")));
+ expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("b")));
}
SECTION("example:a/a2")
{
input = "cd example:a/a2";
- expected.m_path.m_nodes.push_back(node_(module_{"example"}, container_("a")));
- expected.m_path.m_nodes.push_back(node_(container_("a2")));
+ expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
+ expected.m_path.m_nodes.push_back(dataNode_(container_("a2")));
}
SECTION("example:a/example:a2")
{
input = "cd example:a/example:a2";
- expected.m_path.m_nodes.push_back(node_(module_{"example"}, container_("a")));
- expected.m_path.m_nodes.push_back(node_(module_{"example"}, container_("a2")));
+ expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
+ expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a2")));
}
SECTION("example:b/b2")
{
input = "cd example:b/b2";
- expected.m_path.m_nodes.push_back(node_(module_{"example"}, container_("b")));
- expected.m_path.m_nodes.push_back(node_(container_("b2")));
+ expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("b")));
+ expected.m_path.m_nodes.push_back(dataNode_(container_("b2")));
}
}
@@ -84,7 +84,7 @@
input = "cd example:list[number=1]";
auto keys = std::map<std::string, std::string>{
{"number", "1"}};
- expected.m_path.m_nodes.push_back(node_(module_{"example"}, listElement_("list", keys)));
+ expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, listElement_("list", keys)));
}
SECTION("example:list[number=1]/contInList")
@@ -92,8 +92,8 @@
input = "cd example:list[number=1]/contInList";
auto keys = std::map<std::string, std::string>{
{"number", "1"}};
- expected.m_path.m_nodes.push_back(node_(module_{"example"}, listElement_("list", keys)));
- expected.m_path.m_nodes.push_back(node_(container_("contInList")));
+ expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, listElement_("list", keys)));
+ expected.m_path.m_nodes.push_back(dataNode_(container_("contInList")));
}
SECTION("example:twoKeyList[number=4][name='abcd']")
@@ -102,7 +102,7 @@
auto keys = std::map<std::string, std::string>{
{"number", "4"},
{"name", "abcd"}};
- expected.m_path.m_nodes.push_back(node_(module_{"example"}, listElement_("twoKeyList", keys)));
+ expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, listElement_("twoKeyList", keys)));
}
}
@@ -111,7 +111,7 @@
SECTION(" cd example:a ")
{
input = " cd example:a ";
- expected.m_path.m_nodes.push_back(node_(module_{"example"}, container_("a")));
+ expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
}
}
@@ -120,25 +120,25 @@
SECTION("example:a/..")
{
input = "cd example:a/..";
- expected.m_path.m_nodes.push_back(node_(module_{"example"}, container_("a")));
- expected.m_path.m_nodes.push_back(node_(nodeup_()));
+ expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
+ expected.m_path.m_nodes.push_back(dataNode_(nodeup_()));
}
SECTION("example:a/../example:a")
{
input = "cd example:a/../example:a";
- expected.m_path.m_nodes.push_back(node_(module_{"example"}, container_("a")));
- expected.m_path.m_nodes.push_back(node_(nodeup_()));
- expected.m_path.m_nodes.push_back(node_(module_{"example"}, container_("a")));
+ expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
+ expected.m_path.m_nodes.push_back(dataNode_(nodeup_()));
+ expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
}
SECTION("example:a/../example:a/a2")
{
input = "cd example:a/../example:a/a2";
- expected.m_path.m_nodes.push_back(node_(module_{"example"}, container_("a")));
- expected.m_path.m_nodes.push_back(node_(nodeup_()));
- expected.m_path.m_nodes.push_back(node_(module_{"example"}, container_("a")));
- expected.m_path.m_nodes.push_back(node_(container_("a2")));
+ expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
+ expected.m_path.m_nodes.push_back(dataNode_(nodeup_()));
+ expected.m_path.m_nodes.push_back(dataNode_(module_{"example"}, container_("a")));
+ expected.m_path.m_nodes.push_back(dataNode_(container_("a2")));
}
}
diff --git a/tests/leaf_editing.cpp b/tests/leaf_editing.cpp
index a0eeed3..757a617 100644
--- a/tests/leaf_editing.cpp
+++ b/tests/leaf_editing.cpp
@@ -36,15 +36,15 @@
SECTION("set leafString some_data")
{
input = "set mod:leafString some_data";
- expected.m_path.m_nodes.push_back(node_{module_{"mod"}, leaf_("leafString")});
+ expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafString")});
expected.m_data = std::string("some_data");
}
SECTION("set mod:contA/leafInCont more_data")
{
input = "set mod:contA/leafInCont more_data";
- expected.m_path.m_nodes.push_back(node_{module_{"mod"}, container_("contA")});
- expected.m_path.m_nodes.push_back(node_{leaf_("leafInCont")});
+ expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, container_("contA")});
+ expected.m_path.m_nodes.push_back(dataNode_{leaf_("leafInCont")});
expected.m_data = std::string("more_data");
}
@@ -53,8 +53,8 @@
input = "set mod:list[number=1]/leafInList another_data";
auto keys = std::map<std::string, std::string>{
{"number", "1"}};
- expected.m_path.m_nodes.push_back(node_{module_{"mod"}, listElement_("list", keys)});
- expected.m_path.m_nodes.push_back(node_{leaf_("leafInList")});
+ expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, listElement_("list", keys)});
+ expected.m_path.m_nodes.push_back(dataNode_{leaf_("leafInList")});
expected.m_data = std::string("another_data");
}
@@ -63,35 +63,35 @@
SECTION("string")
{
input = "set mod:leafString somedata";
- expected.m_path.m_nodes.push_back(node_{module_{"mod"}, leaf_("leafString")});
+ expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafString")});
expected.m_data = std::string("somedata");
}
SECTION("int")
{
input = "set mod:leafInt 2";
- expected.m_path.m_nodes.push_back(node_{module_{"mod"}, leaf_("leafInt")});
+ expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafInt")});
expected.m_data = 2;
}
SECTION("decimal")
{
input = "set mod:leafDecimal 3.14159";
- expected.m_path.m_nodes.push_back(node_{module_{"mod"}, leaf_("leafDecimal")});
+ expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafDecimal")});
expected.m_data = 3.14159;
}
SECTION("enum")
{
input = "set mod:leafEnum coze";
- expected.m_path.m_nodes.push_back(node_{module_{"mod"}, leaf_("leafEnum")});
+ expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafEnum")});
expected.m_data = enum_("coze");
}
SECTION("bool")
{
input = "set mod:leafBool true";
- expected.m_path.m_nodes.push_back(node_{module_{"mod"}, leaf_("leafBool")});
+ expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafBool")});
expected.m_data = true;
}
}
diff --git a/tests/ls.cpp b/tests/ls.cpp
index 47d28ed..e42152d 100644
--- a/tests/ls.cpp
+++ b/tests/ls.cpp
@@ -17,6 +17,7 @@
schema->addModule("example");
schema->addModule("second");
schema->addContainer("", "example:a");
+ schema->addList("example:a", "example:listInCont", {"number"});
schema->addContainer("", "second:a");
schema->addContainer("", "example:b");
schema->addContainer("example:a", "example:a2");
@@ -51,81 +52,103 @@
SECTION("ls example:a")
{
input = "ls example:a";
- expected.m_path = path_{Scope::Relative, {node_(module_{"example"}, container_{"a"})}};
+ expected.m_path = dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"})}};
}
SECTION("ls /example:a")
{
SECTION("cwd: /") {}
- SECTION("cwd: /example:a") {parser.changeNode(path_{Scope::Relative, {node_(module_{"example"}, container_{"a"})}});}
+ SECTION("cwd: /example:a") {parser.changeNode(dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"})}});}
input = "ls /example:a";
- expected.m_path = path_{Scope::Absolute, {node_(module_{"example"}, container_{"a"})}};
+ expected.m_path = dataPath_{Scope::Absolute, {dataNode_(module_{"example"}, container_{"a"})}};
}
SECTION("ls /")
{
SECTION("cwd: /") {}
- SECTION("cwd: /example:a") {parser.changeNode(path_{Scope::Relative, {node_(module_{"example"}, container_{"a"})}});}
+ SECTION("cwd: /example:a") {parser.changeNode(dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"})}});}
input = "ls /";
- expected.m_path = path_{Scope::Absolute, {}};
+ expected.m_path = dataPath_{Scope::Absolute, {}};
}
SECTION("ls example:a/a2")
{
input = "ls example:a/a2";
- expected.m_path = path_{Scope::Relative, {node_(module_{"example"}, container_{"a"}),
- node_(container_{"a2"})}};
+ expected.m_path = dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"}),
+ dataNode_(container_{"a2"})}};
}
SECTION("ls a2")
{
- parser.changeNode(path_{Scope::Relative, {node_(module_{"example"}, container_{"a"})}});
+ parser.changeNode(dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"})}});
input = "ls a2";
- expected.m_path = path_{Scope::Relative, {node_(container_{"a2"})}};
+ expected.m_path = dataPath_{Scope::Relative, {dataNode_(container_{"a2"})}};
}
SECTION("ls /example:a/a2")
{
SECTION("cwd: /") {}
- SECTION("cwd: /example:a") {parser.changeNode(path_{Scope::Relative, {node_(module_{"example"}, container_{"a"})}});}
+ SECTION("cwd: /example:a") {parser.changeNode(dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"})}});}
input = "ls /example:a/a2";
- expected.m_path = path_{Scope::Absolute, {node_(module_{"example"}, container_{"a"}),
- node_(container_{"a2"})}};
+ expected.m_path = dataPath_{Scope::Absolute, {dataNode_(module_{"example"}, container_{"a"}),
+ dataNode_(container_{"a2"})}};
}
SECTION("ls example:a/example:a2")
{
input = "ls example:a/example:a2";
- expected.m_path = path_{Scope::Relative, {node_(module_{"example"}, container_{"a"}),
- node_(module_{"example"}, container_{"a2"})}};
+ expected.m_path = dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"}),
+ dataNode_(module_{"example"}, container_{"a2"})}};
}
SECTION("ls example:a2")
{
- parser.changeNode(path_{Scope::Relative, {node_(module_{"example"}, container_{"a"})}});
+ parser.changeNode(dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"})}});
input = "ls example:a2";
- expected.m_path = path_{Scope::Relative, {node_(module_{"example"}, container_{"a2"})}};
+ expected.m_path = dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a2"})}};
}
SECTION("ls /example:a/example:a2")
{
SECTION("cwd: /") {}
- SECTION("cwd: /example:a") {parser.changeNode(path_{Scope::Relative, {node_(module_{"example"}, container_{"a"})}});}
+ SECTION("cwd: /example:a") {parser.changeNode(dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"})}});}
input = "ls /example:a/example:a2";
- expected.m_path = path_{Scope::Absolute, {node_(module_{"example"}, container_{"a"}),
- node_(module_{"example"}, container_{"a2"})}};
+ expected.m_path = dataPath_{Scope::Absolute, {dataNode_(module_{"example"}, container_{"a"}),
+ dataNode_(module_{"example"}, container_{"a2"})}};
}
SECTION("ls --recursive /example:a")
{
SECTION("cwd: /") {}
- SECTION("cwd: /example:a") {parser.changeNode(path_{Scope::Relative, {node_(module_{"example"}, container_{"a"})}});}
+ SECTION("cwd: /example:a") {parser.changeNode(dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"})}});}
input = "ls --recursive /example:a";
expected.m_options.push_back(LsOption::Recursive);
- expected.m_path = path_{Scope::Absolute, {node_(module_{"example"}, container_{"a"})}};
+ expected.m_path = dataPath_{Scope::Absolute, {dataNode_(module_{"example"}, container_{"a"})}};
+ }
+
+ SECTION("ls example:list")
+ {
+ input = "ls example:list";
+ expected.m_path = dataPath_{Scope::Relative, {dataNode_(module_{"example"}, list_{"list"})}};
+ }
+
+ SECTION("ls example:a/example:listInCont")
+ {
+ input = "ls example:a/example:listInCont";
+ expected.m_path = dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"}),
+ dataNode_(module_{"example"}, list_{"listInCont"})}};
+ }
+
+ SECTION("ls example:list[number=342]/contInList")
+ {
+ input = "ls example:list[number=342]/contInList";
+ auto keys = std::map<std::string, std::string>{
+ {"number", "342"}};
+ expected.m_path = dataPath_{Scope::Relative, {dataNode_(module_{"example"}, listElement_{"list", keys}),
+ dataNode_(container_{"contInList"})}};
}
}
diff --git a/tests/presence_containers.cpp b/tests/presence_containers.cpp
index 5a43ce9..6872d1b 100644
--- a/tests/presence_containers.cpp
+++ b/tests/presence_containers.cpp
@@ -29,7 +29,7 @@
SECTION("valid input")
{
- path_ expectedPath;
+ dataPath_ expectedPath;
SECTION("mod:a")
{
diff --git a/tests/yang.cpp b/tests/yang.cpp
index dc2286d..76b3c15 100644
--- a/tests/yang.cpp
+++ b/tests/yang.cpp
@@ -124,7 +124,7 @@
{
YangSchema ys;
ys.addSchemaString(schema);
- path_ path;
+ schemaPath_ path;
ModuleNodePair node;
SECTION("positive")
@@ -139,7 +139,7 @@
SECTION("example-schema:a/a2")
{
- path.m_nodes.push_back(node_(module_{"example-schema"}, container_("a")));
+ path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
node.second = "a2";
}
@@ -155,7 +155,7 @@
SECTION("example-schema:a/leafa")
{
- path.m_nodes.push_back(node_(module_{"example-schema"}, container_("a")));
+ path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
node.first = "example-schema";
node.second = "leafa";
}
@@ -186,8 +186,8 @@
{
SECTION("example-schema:a/a2/a3")
{
- path.m_nodes.push_back(node_(module_{"example-schema"}, container_("a")));
- path.m_nodes.push_back(node_(module_{"example-schema"}, container_("a2")));
+ path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
+ path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a2")));
node.second = "a3";
}
@@ -359,7 +359,7 @@
SECTION("a")
{
- path.m_nodes.push_back(node_(module_{"example-schema"}, container_("a")));
+ path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
set = {"example-schema:a2", "example-schema:leafa"};
}
@@ -379,13 +379,13 @@
SECTION("example-schema:a/nevim")
{
- path.m_nodes.push_back(node_(module_{"example-schema"}, container_("a")));
+ path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
node.second = "nevim";
}
SECTION("modul:a/nevim")
{
- path.m_nodes.push_back(node_(module_{"modul"}, container_("a")));
+ path.m_nodes.push_back(schemaNode_(module_{"modul"}, container_("a")));
node.second = "nevim";
}
@@ -405,7 +405,7 @@
SECTION("example-schema:a/a2")
{
- path.m_nodes.push_back(node_(module_{"example-schema"}, container_("a")));
+ path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
node.second = "a2";
}
@@ -416,7 +416,7 @@
SECTION("nodetype-specific methods called with different nodetypes")
{
- path.m_nodes.push_back(node_(module_{"example-schema"}, container_("a")));
+ path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
node.second = "a2";
REQUIRE(!ys.leafEnumHasValue(path, node, "haha"));