Fix a bug with path parsing
It is now required that the whole path is parsed (that is, there is a
space after the path, or a EOI), when not completing, so that all path
types are tried. Before this, the parser could stop before trying
different path types.
Change-Id: I1964f892418508e6356c4a8811ab00ce1acfa24d
diff --git a/src/ast_handlers.hpp b/src/ast_handlers.hpp
index f0bbf4c..943af19 100644
--- a/src/ast_handlers.hpp
+++ b/src/ast_handlers.hpp
@@ -558,3 +558,14 @@
});
}
};
+
+struct completing_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);
+
+ if (!parserContext.m_completing)
+ _pass(context) = false;
+ }
+};
diff --git a/src/grammars.hpp b/src/grammars.hpp
index cfd5203..f3dd6f9 100644
--- a/src/grammars.hpp
+++ b/src/grammars.hpp
@@ -58,6 +58,7 @@
x3::rule<createKeySuggestions_class, x3::unused_type> const createKeySuggestions = "createKeySuggestions";
x3::rule<suggestKeysEnd_class, x3::unused_type> const suggestKeysEnd = "suggestKeysEnd";
x3::rule<createCommandSuggestions_class, x3::unused_type> const createCommandSuggestions = "createCommandSuggestions";
+x3::rule<completing_class, x3::unused_type> const completing = "completing";
#if __clang__
#pragma GCC diagnostic push
@@ -142,10 +143,14 @@
auto const space_separator =
x3::omit[x3::no_skip[space]];
+// This is a pseudo-parser, that fails if we're not completing a command
+auto const completing_def =
+ x3::eps;
+
// I have to insert an empty vector to the first alternative, otherwise they won't have the same attribute
auto const dataPath_def =
initializePath >> absoluteStart >> createPathSuggestions >> x3::attr(decltype(dataPath_::m_nodes)()) >> x3::attr(TrailingSlash::NonPresent) >> x3::eoi |
- initializePath >> -(absoluteStart >> createPathSuggestions) >> dataNode % '/' >> (trailingSlash >> createPathSuggestions | (&space_separator | x3::eoi));
+ initializePath >> -(absoluteStart >> createPathSuggestions) >> dataNode % '/' >> (trailingSlash >> createPathSuggestions >> (completing | x3::eoi) | (&space_separator | x3::eoi));
auto const dataNodeList_def =
-(module) >> createPathSuggestions >> list;
@@ -160,11 +165,11 @@
auto const dataPathListEnd_def =
initializePath >> absoluteStart >> createPathSuggestions >> x3::attr(decltype(dataPath_::m_nodes)()) >> x3::attr(TrailingSlash::NonPresent) >> x3::eoi |
- initializePath >> -(absoluteStart >> createPathSuggestions) >> dataNodesListEnd >> (trailingSlash >> createPathSuggestions | (&space_separator | x3::eoi));
+ initializePath >> -(absoluteStart >> createPathSuggestions) >> dataNodesListEnd >> (trailingSlash >> createPathSuggestions >> (completing | x3::eoi) | (&space_separator | x3::eoi));
auto const schemaPath_def =
initializePath >> absoluteStart >> createPathSuggestions >> x3::attr(decltype(schemaPath_::m_nodes)()) >> x3::attr(TrailingSlash::NonPresent) >> x3::eoi |
- initializePath >> -(absoluteStart >> createPathSuggestions) >> schemaNode % '/' >> (trailingSlash >> createPathSuggestions | (&space_separator | x3::eoi));
+ initializePath >> -(absoluteStart >> createPathSuggestions) >> schemaNode % '/' >> (trailingSlash >> createPathSuggestions >> (completing | x3::eoi) | (&space_separator | x3::eoi));
auto const leafPath_def =
dataPath;
@@ -290,3 +295,4 @@
BOOST_SPIRIT_DEFINE(createKeySuggestions)
BOOST_SPIRIT_DEFINE(suggestKeysEnd)
BOOST_SPIRIT_DEFINE(createCommandSuggestions)
+BOOST_SPIRIT_DEFINE(completing)
diff --git a/src/parser.cpp b/src/parser.cpp
index ba6690d..cf433e2 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -44,6 +44,7 @@
std::set<std::string> completions;
command_ parsedCommand;
ParserContext ctx(*m_schema, dataPathToSchemaPath(m_curDir));
+ ctx.m_completing = true;
auto it = line.begin();
boost::spirit::x3::error_handler<std::string::const_iterator> errorHandler(it, line.end(), errorStream);
diff --git a/src/parser_context.hpp b/src/parser_context.hpp
index 5d0fe38..3871192 100644
--- a/src/parser_context.hpp
+++ b/src/parser_context.hpp
@@ -18,6 +18,7 @@
bool m_topLevelModulePresent = false;
std::set<std::string> m_tmpListKeys;
bool m_errorHandled = false;
+ bool m_completing = false;
std::set<std::string> m_suggestions;
// Iterator pointing to where suggestions were created
std::string::const_iterator m_completionIterator;