diff options
author | arseny.kapoulkine <arseny.kapoulkine@99668b35-9821-0410-8761-19e4c4f06640> | 2010-05-31 16:53:13 +0000 |
---|---|---|
committer | arseny.kapoulkine <arseny.kapoulkine@99668b35-9821-0410-8761-19e4c4f06640> | 2010-05-31 16:53:13 +0000 |
commit | 4c0e67ae92f288be74748af9de7891b7b641943e (patch) | |
tree | 4cdde5be09f005e4f13b0aeaf1fa987d6966780b | |
parent | 18848ef589e6a476fb0082a2fa02b54429c90734 (diff) |
XPath: Replaced backtracking with lookahead in absolute path parsing
git-svn-id: http://pugixml.googlecode.com/svn/trunk@485 99668b35-9821-0410-8761-19e4c4f06640
-rw-r--r-- | src/pugixpath.cpp | 32 | ||||
-rw-r--r-- | tests/test_xpath_parse.cpp | 15 |
2 files changed, 24 insertions, 23 deletions
diff --git a/src/pugixpath.cpp b/src/pugixpath.cpp index 6262ff3..78127dc 100644 --- a/src/pugixpath.cpp +++ b/src/pugixpath.cpp @@ -881,12 +881,6 @@ namespace pugi return m_cur;
}
- void reset(const char_t* state)
- {
- m_cur = state;
- next();
- }
-
void next()
{
contents_clear();
@@ -3079,25 +3073,17 @@ namespace pugi {
if (m_lexer.current() == lex_slash)
{
- // Save state for next lexeme - that is, whatever follows '/'
- const char_t* state = 0; // gcc3 "variable might be used uninitialized in this function" bug workaround
- state = m_lexer.state();
-
m_lexer.next();
- xpath_ast_node* n = 0; // gcc3 "variable might be used uninitialized in this function" bug workaround
- n = new (m_alloc.node()) xpath_ast_node(ast_step_root, xpath_type_node_set);
-
- try
- {
- n = parse_relative_location_path(n);
- }
- catch (const xpath_exception&)
- {
- m_lexer.reset(state);
- }
-
- return n;
+ xpath_ast_node* n = new (m_alloc.node()) xpath_ast_node(ast_step_root, xpath_type_node_set);
+
+ // relative location path can start from axis_attribute, dot, double_dot, multiply and string lexemes; any other lexeme means standalone root path
+ lexeme_t l = m_lexer.current();
+
+ if (l == lex_string || l == lex_axis_attribute || l == lex_dot || l == lex_double_dot || l == lex_multiply)
+ return parse_relative_location_path(n);
+ else
+ return n;
}
else if (m_lexer.current() == lex_double_slash)
{
diff --git a/tests/test_xpath_parse.cpp b/tests/test_xpath_parse.cpp index b977ce5..caebb9b 100644 --- a/tests/test_xpath_parse.cpp +++ b/tests/test_xpath_parse.cpp @@ -254,4 +254,19 @@ TEST(xpath_parse_jaxen_invalid) }
}
+TEST_XML(xpath_parse_absolute, "<div><s/></div>")
+{
+ CHECK_XPATH_NODESET(doc, STR("/")) % 1;
+
+ CHECK_XPATH_NODESET(doc, STR("/div/s")) % 3;
+ CHECK_XPATH_NODESET(doc, STR("/ div /s")) % 3;
+ CHECK_XPATH_FAIL(STR("/ div 5"));
+
+ CHECK_XPATH_NODESET(doc, STR("/*/s")) % 3;
+ CHECK_XPATH_NODESET(doc, STR("/ * /s")) % 3;
+ CHECK_XPATH_FAIL(STR("/ * 5"));
+
+ CHECK_XPATH_NODESET(doc, STR("/*[/]")) % 2;
+}
+
#endif
|