Add get command
Change-Id: Id06539070fb8d815786149e1479e93d75d4b70f1
diff --git a/src/ast_commands.hpp b/src/ast_commands.hpp
index 3a92e10..969515e 100644
--- a/src/ast_commands.hpp
+++ b/src/ast_commands.hpp
@@ -59,8 +59,12 @@
bool operator==(const set_& b) const;
};
+struct get_ : x3::position_tagged {
+ bool operator==(const get_& b) const;
+ boost::optional<path_> m_path;
+};
-using command_ = boost::variant<ls_, cd_, create_, delete_, set_, commit_>;
+using command_ = boost::variant<ls_, cd_, create_, delete_, set_, commit_, get_>;
BOOST_FUSION_ADAPT_STRUCT(ls_, m_path)
BOOST_FUSION_ADAPT_STRUCT(cd_, m_path)
@@ -69,3 +73,4 @@
BOOST_FUSION_ADAPT_STRUCT(enum_, m_value)
BOOST_FUSION_ADAPT_STRUCT(set_, m_path, m_data)
BOOST_FUSION_ADAPT_STRUCT(commit_)
+BOOST_FUSION_ADAPT_STRUCT(get_, m_path)
diff --git a/src/ast_handlers.hpp b/src/ast_handlers.hpp
index bddc83e..686ae30 100644
--- a/src/ast_handlers.hpp
+++ b/src/ast_handlers.hpp
@@ -394,6 +394,8 @@
struct commit_class;
+struct get_class;
+
struct command_class {
template <typename Iterator, typename Exception, typename Context>
x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const& x, Context const& context)
diff --git a/src/ast_path.cpp b/src/ast_path.cpp
index 2621792..e943d0e 100644
--- a/src/ast_path.cpp
+++ b/src/ast_path.cpp
@@ -91,7 +91,7 @@
res << node.m_name + "[";
std::transform(node.m_keys.begin(), node.m_keys.end(),
std::experimental::make_ostream_joiner(res, ' '),
- [] (const auto& it) { return it.first + "=" + it.second; });
+ [] (const auto& it) { return it.first + "=" + '\'' + it.second + '\''; });
res << "]";
return res.str();
}
diff --git a/src/ast_path.hpp b/src/ast_path.hpp
index 8827a38..dab06ea 100644
--- a/src/ast_path.hpp
+++ b/src/ast_path.hpp
@@ -68,8 +68,7 @@
bool operator==(const node_& b) const;
};
-enum class Scope
-{
+enum class Scope {
Absolute,
Relative
};
diff --git a/src/ast_values.hpp b/src/ast_values.hpp
index 121e760..369a73e 100644
--- a/src/ast_values.hpp
+++ b/src/ast_values.hpp
@@ -22,4 +22,3 @@
int32_t,
uint32_t,
std::string>;
-
diff --git a/src/grammars.hpp b/src/grammars.hpp
index 6ad9b1b..5a3db0f 100644
--- a/src/grammars.hpp
+++ b/src/grammars.hpp
@@ -38,6 +38,7 @@
x3::rule<ls_class, ls_> const ls = "ls";
x3::rule<cd_class, cd_> const cd = "cd";
x3::rule<set_class, set_> const set = "set";
+x3::rule<get_class, get_> const get = "get";
x3::rule<create_class, create_> const create = "create";
x3::rule<delete_class, delete_> const delete_rule = "delete_rule";
x3::rule<commit_class, commit_> const commit = "commit";
@@ -145,6 +146,9 @@
auto const delete_rule_def =
lit("delete") >> space_separator > path;
+auto const get_def =
+ lit("get") >> -path;
+
auto const set_def =
lit("set") >> space_separator > leafPath > leaf_data;
@@ -152,7 +156,7 @@
lit("commit") >> x3::attr(commit_());
auto const command_def =
- x3::expect[cd | create | delete_rule | set | commit | ls] >> x3::eoi;
+ x3::expect[cd | create | delete_rule | set | commit | get | ls] >> x3::eoi;
#if __clang__
#pragma GCC diagnostic pop
@@ -181,6 +185,7 @@
BOOST_SPIRIT_DEFINE(leaf_data_string)
BOOST_SPIRIT_DEFINE(set)
BOOST_SPIRIT_DEFINE(commit)
+BOOST_SPIRIT_DEFINE(get)
BOOST_SPIRIT_DEFINE(ls)
BOOST_SPIRIT_DEFINE(cd)
BOOST_SPIRIT_DEFINE(create)
diff --git a/src/interpreter.cpp b/src/interpreter.cpp
index b919786..4e5d665 100644
--- a/src/interpreter.cpp
+++ b/src/interpreter.cpp
@@ -34,6 +34,14 @@
m_datastore.setLeaf(absolutePathFromCommand(set), set.m_data);
}
+void Interpreter::operator()(const get_& get) const
+{
+ auto items = m_datastore.getItems(absolutePathFromCommand(get));
+ for (auto it : items) {
+ std::cout << it.first << " = " << boost::apply_visitor(leafDataToString(), it.second) << std::endl;
+ }
+}
+
void Interpreter::operator()(const cd_& cd) const
{
m_parser.changeNode(cd.m_path);
@@ -66,6 +74,17 @@
return joinPaths(m_parser.currentNode(), pathToDataString(command.m_path));
}
+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);
+ } else {
+ return joinPaths(m_parser.currentNode(), pathToDataString(*get.m_path));
+ }
+}
+
Interpreter::Interpreter(Parser& parser, DatastoreAccess& datastore)
: m_parser(parser)
, m_datastore(datastore)
diff --git a/src/interpreter.hpp b/src/interpreter.hpp
index fd14ffe..262b037 100644
--- a/src/interpreter.hpp
+++ b/src/interpreter.hpp
@@ -17,6 +17,7 @@
void operator()(const commit_&) const;
void operator()(const set_&) const;
+ void operator()(const get_&) const;
void operator()(const cd_&) const;
void operator()(const create_&) const;
void operator()(const delete_&) const;
@@ -25,6 +26,7 @@
private:
template <typename T>
std::string absolutePathFromCommand(const T& command) const;
+ std::string absolutePathFromCommand(const get_& command) const;
Parser& m_parser;
DatastoreAccess& m_datastore;
diff --git a/src/sysrepo_access.cpp b/src/sysrepo_access.cpp
index 54fa1fd..af553d9 100644
--- a/src/sysrepo_access.cpp
+++ b/src/sysrepo_access.cpp
@@ -11,21 +11,28 @@
leaf_data_ leafValueFromVal(const S_Val& value)
{
+ using namespace std::string_literals;
switch (value->type()) {
- case SR_INT32_T:
- return value->data()->get_int32();
- case SR_UINT32_T:
- return value->data()->get_uint32();
- case SR_BOOL_T:
- return value->data()->get_bool();
- case SR_STRING_T:
- return std::string(value->data()->get_string());
- case SR_ENUM_T:
- return std::string(value->data()->get_enum());
- case SR_DECIMAL64_T:
- return value->data()->get_decimal64();
- default: // TODO: implement all types
- throw std::runtime_error("This type is not yet implemented");
+ case SR_INT32_T:
+ return value->data()->get_int32();
+ case SR_UINT32_T:
+ return value->data()->get_uint32();
+ case SR_BOOL_T:
+ return value->data()->get_bool();
+ case SR_STRING_T:
+ return std::string(value->data()->get_string());
+ case SR_ENUM_T:
+ return std::string(value->data()->get_enum());
+ case SR_DECIMAL64_T:
+ return value->data()->get_decimal64();
+ case SR_CONTAINER_T:
+ return "(container)"s;
+ case SR_CONTAINER_PRESENCE_T:
+ return "(presence container)"s;
+ case SR_LIST_T:
+ return "(list)"s;
+ default: // TODO: implement all types
+ return value->val_to_string();
}
}
@@ -71,14 +78,25 @@
std::map<std::string, leaf_data_> SysrepoAccess::getItems(const std::string& path)
{
+ using namespace std::string_literals;
std::map<std::string, leaf_data_> res;
- auto iterator = m_session->get_items_iter(path.c_str());
- if (!iterator)
- return res;
+ auto fillMap = [&res](auto items) {
+ if (!items)
+ return;
+ for (unsigned int i = 0; i < items->val_cnt(); i++) {
+ res.emplace(items->val(i)->xpath(), leafValueFromVal(items->val(i)));
+ }
+ };
- while (auto value = m_session->get_item_next(iterator)) {
- res.emplace(value->xpath(), leafValueFromVal(value));
+ if (path == "/") {
+ // Sysrepo doesn't have a root node ("/"), so we take all top-level nodes from all schemas
+ auto schemas = m_session->list_schemas();
+ for (unsigned int i = 0; i < schemas->schema_cnt(); i++) {
+ fillMap(m_session->get_items(("/"s + schemas->schema(i)->module_name() + ":*//.").c_str()));
+ }
+ } else {
+ fillMap(m_session->get_items((path + "//.").c_str()));
}
return res;