summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarseny.kapoulkine <arseny.kapoulkine@99668b35-9821-0410-8761-19e4c4f06640>2010-05-31 16:53:13 +0000
committerarseny.kapoulkine <arseny.kapoulkine@99668b35-9821-0410-8761-19e4c4f06640>2010-05-31 16:53:13 +0000
commit4c0e67ae92f288be74748af9de7891b7b641943e (patch)
tree4cdde5be09f005e4f13b0aeaf1fa987d6966780b
parent18848ef589e6a476fb0082a2fa02b54429c90734 (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.cpp32
-rw-r--r--tests/test_xpath_parse.cpp15
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