aboutsummaryrefslogtreecommitdiff
path: root/libxsde
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-02-11 17:18:30 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-02-11 17:18:30 +0200
commit49d8e39f9a42ff1963c5df0f6e9ed903d66f2eb0 (patch)
tree17cb3577baa07e30720788e059399f7c07c22a37 /libxsde
parentbcf2ac66e6c21d75f4e76b8e0bc2e3c6d64886b8 (diff)
Fix recursive polymorphic parsing in C++/Parser
New test: cxx/parser/polyrecur.
Diffstat (limited to 'libxsde')
-rw-r--r--libxsde/xsde/cxx/parser/context.hxx18
-rw-r--r--libxsde/xsde/cxx/parser/expat/document.cxx26
2 files changed, 40 insertions, 4 deletions
diff --git a/libxsde/xsde/cxx/parser/context.hxx b/libxsde/xsde/cxx/parser/context.hxx
index cd68631..f3e49e0 100644
--- a/libxsde/xsde/cxx/parser/context.hxx
+++ b/libxsde/xsde/cxx/parser/context.hxx
@@ -142,6 +142,18 @@ namespace xsde
void
start_wildcard_content ();
+ parser_base*
+ nested_parser () const
+ {
+ return nested_parser_;
+ }
+
+ void
+ nested_parser (parser_base* p)
+ {
+ nested_parser_ = p;
+ }
+
void
reset (XML_Parser);
@@ -154,6 +166,12 @@ namespace xsde
public:
parser_state current_;
+ private:
+ // Nested parser when transitioning from outer to inner or from
+ // inner to outer parsers.
+ //
+ parser_base* nested_parser_;
+
protected:
XML_Parser xml_parser_;
diff --git a/libxsde/xsde/cxx/parser/expat/document.cxx b/libxsde/xsde/cxx/parser/expat/document.cxx
index 2ebde82..3afca7b 100644
--- a/libxsde/xsde/cxx/parser/expat/document.cxx
+++ b/libxsde/xsde/cxx/parser/expat/document.cxx
@@ -875,14 +875,30 @@ namespace xsde
else if (cur.parser_)
{
// The "normal" case: call _start_element which will
- // call pre() and _pre_impl() (which will push the
- // new parser).
+ // call pre() and set the nested parser. We then call
+ // _pre_impl on that (which will push the new parser).
//
+
+ context_.nested_parser (0);
+
#ifdef XSDE_POLYMORPHIC
cur.parser_->_start_element (ns, name, type);
#else
cur.parser_->_start_element (ns, name);
#endif
+
+#if defined(XSDE_PARSER_VALIDATION) || !defined(XSDE_EXCEPTIONS)
+ if (context_.error_type ())
+ {
+ XML_StopParser (xml_parser_, false);
+ return;
+ }
+#endif
+ if (parser_base* p = context_.nested_parser ())
+ p->_pre_impl (context_);
+ else
+ if (!cur.any_)
+ cur.depth_++; // Ignoring.
}
else
{
@@ -1073,7 +1089,7 @@ namespace xsde
// The "normal" case: call _post to pop the parser and then
// call _end_element on the "outer" parser which calls post().
//
- parser_base* p = cur.parser_;
+ context_.nested_parser (cur.parser_);
cur.parser_->_post_impl ();
#if defined(XSDE_PARSER_VALIDATION) || !defined(XSDE_EXCEPTIONS)
@@ -1091,7 +1107,7 @@ namespace xsde
{
// End of the root element. post() is called by the user.
//
- end_root_element (ns, name, p);
+ end_root_element (ns, name, context_.nested_parser ());
}
}
else
@@ -1113,6 +1129,8 @@ namespace xsde
}
else
{
+ context_.nested_parser (0);
+
if (cur.any_)
{
// Handling content matched by a wildcard.