Make set report the expected type in case of error
Change-Id: Id46251b4859739e3c8f77d3bf2513ec22b048cf1
diff --git a/src/ast_handlers.hpp b/src/ast_handlers.hpp
index 848ce21..65d8405 100644
--- a/src/ast_handlers.hpp
+++ b/src/ast_handlers.hpp
@@ -228,7 +228,34 @@
struct delete_class : public presenceContainerPathHandler {
};
+struct leaf_path_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);
+ try {
+ auto leaf = boost::get<leaf_>(ast.m_nodes.back());
+ } catch (boost::bad_get&) {
+ parserContext.m_errorMsg = "This is not a path to leaf.";
+ _pass(context) = false;
+ }
+ }
+};
+
struct leaf_data_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);
+ auto& schema = parserContext.m_schema;
+ if (parserContext.m_errorMsg.empty()) {
+ leaf_ leaf = boost::get<leaf_>(parserContext.m_curPath.m_nodes.back());
+ path_ location = pathWithoutLastNode(parserContext.m_curPath);
+ parserContext.m_errorMsg = "Expected " + leafDataTypeToString(schema.leafType(location, leaf.m_name)) + " here:";
+ return x3::error_handler_result::fail;
+ }
+ return x3::error_handler_result::rethrow;
+ }
};
struct leaf_data_base_class {
@@ -312,18 +339,6 @@
};
struct set_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);
- try {
- auto leaf = boost::get<leaf_>(ast.m_path.m_nodes.back());
- } catch (boost::bad_get&) {
- parserContext.m_errorMsg = "This is not a leaf.";
- _pass(context) = false;
- }
- }
-
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/grammars.hpp b/src/grammars.hpp
index 443b28d..5386417 100644
--- a/src/grammars.hpp
+++ b/src/grammars.hpp
@@ -21,6 +21,7 @@
x3::rule<container_class, container_> const container = "container";
x3::rule<leaf_class, leaf_> const leaf = "leaf";
x3::rule<path_class, path_> const path = "path";
+x3::rule<leaf_path_class, path_> 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";
@@ -72,6 +73,9 @@
auto const path_def =
(x3::expect[container | listElement | nodeup | leaf]) % '/';
+auto const leafPath_def =
+ path;
+
auto const leaf_data_enum_def =
+char_;
auto const leaf_data_decimal_def =
@@ -96,12 +100,13 @@
*char_;
auto const leaf_data_def =
+x3::expect[
leaf_data_enum |
leaf_data_decimal |
leaf_data_bool |
leaf_data_int |
leaf_data_uint |
- leaf_data_string;
+ leaf_data_string];
auto const space_separator =
x3::omit[x3::no_skip[space]];
@@ -116,7 +121,7 @@
lit("delete") >> space_separator > path;
auto const set_def =
- lit("set") >> space_separator > path > leaf_data;
+ lit("set") >> space_separator > leafPath > leaf_data;
auto const command_def =
x3::expect[cd | create | delete_rule | set] >> x3::eoi;
@@ -133,6 +138,7 @@
BOOST_SPIRIT_DEFINE(nodeup)
BOOST_SPIRIT_DEFINE(container)
BOOST_SPIRIT_DEFINE(leaf)
+BOOST_SPIRIT_DEFINE(leafPath)
BOOST_SPIRIT_DEFINE(path)
BOOST_SPIRIT_DEFINE(leaf_data)
BOOST_SPIRIT_DEFINE(leaf_data_enum)
diff --git a/src/utils.cpp b/src/utils.cpp
index a7fea46..b4f60ab 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -30,3 +30,23 @@
{
return path_{decltype(path_::m_nodes)(path.m_nodes.begin(), path.m_nodes.end() - 1)};
}
+
+std::string leafDataTypeToString(yang::LeafDataTypes type)
+{
+ switch (type) {
+ case yang::LeafDataTypes::String:
+ return "a string";
+ case yang::LeafDataTypes::Decimal:
+ return "a decimal";
+ case yang::LeafDataTypes::Bool:
+ return "a boolean";
+ case yang::LeafDataTypes::Int:
+ return "an integer";
+ case yang::LeafDataTypes::Uint:
+ return "an unsigned integer";
+ case yang::LeafDataTypes::Enum:
+ return "an enum";
+ default:
+ return "";
+ }
+}
diff --git a/src/utils.hpp b/src/utils.hpp
index 2c550d7..9583ebe 100644
--- a/src/utils.hpp
+++ b/src/utils.hpp
@@ -7,7 +7,9 @@
*/
#include <string>
#include "ast_path.hpp"
+#include "schema.hpp"
std::string joinPaths(const std::string& prefix, const std::string& suffix);
std::string stripLastNodeFromPath(const std::string& path);
path_ pathWithoutLastNode(const path_& path);
+std::string leafDataTypeToString(yang::LeafDataTypes type);