From f0510d2f90467de8e8f260b47d79a9baaf9bef17 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 17 Sep 2009 07:15:29 +0200 Subject: Start tracking XSD with git --- xsd/cxx/tree/parser-source.cxx | 544 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 544 insertions(+) create mode 100644 xsd/cxx/tree/parser-source.cxx (limited to 'xsd/cxx/tree/parser-source.cxx') diff --git a/xsd/cxx/tree/parser-source.cxx b/xsd/cxx/tree/parser-source.cxx new file mode 100644 index 0000000..5c121f2 --- /dev/null +++ b/xsd/cxx/tree/parser-source.cxx @@ -0,0 +1,544 @@ +// file : xsd/cxx/tree/parser-source.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +#include +#include + +namespace CXX +{ + namespace Tree + { + namespace + { + struct ElementFunction: Traversal::Element, + GlobalElementBase, + protected virtual Context + { + ElementFunction (Context& c) + : Context (c), GlobalElementBase (c) + { + } + + virtual Void + traverse (Type& e) + { + if (!doc_root_p (e)) + return; + + String const& name (eparser (e)); + SemanticGraph::Type& t (e.type ()); + String type (type_name (e)); + String const& error_handler (error_handler_type); + + // Note that I am using fq-name in function calls because g++ gets + // confused if the name is 'type'. (see tests/schema/anonymous) + // + + // URI. + // + os << "::std::auto_ptr< " << type << " >" << endl + << name << " (const " << string_type << "& u," << endl + << flags_type << " f," << endl + << "const " << properties_type << "& p)" + << "{" + << "::xsd::cxx::xml::auto_initializer i (" << endl + << "(f & " << flags_type << "::dont_initialize) == 0," << endl + << "(f & " << flags_type << "::keep_dom) == 0);" + << endl + << "::xsd::cxx::tree::error_handler< " << char_type << " > h;" + << endl + << dom_auto_ptr << "< " << xerces_ns << + "::DOMDocument > d (" << endl + << "::xsd::cxx::xml::dom::parse< " << char_type << " > (" << endl + << "u, h, p, f"; + + if (options.value ()) + os << " | ::xsd::cxx::xml::dom::no_muliple_imports"; + + os << "));" + << endl + << "h.throw_if_failed< ::xsd::cxx::tree::parsing< " << + char_type << " > > ();" + << endl + << "::std::auto_ptr< " << type << " > r (" << endl + << fq_name (e, "parser") << " (" << endl + << "d, f | " << flags_type << "::own_dom, p));" + << endl + << "return r;" + << "}"; + + os << "::std::auto_ptr< " << type << " >" << endl + << name << " (const " << string_type << "& u," << endl + << error_handler << "& h," << endl + << flags_type << " f," << endl + << "const " << properties_type << "& p)" + << "{" + << "::xsd::cxx::xml::auto_initializer i (" << endl + << "(f & " << flags_type << "::dont_initialize) == 0," << endl + << "(f & " << flags_type << "::keep_dom) == 0);" + << endl + << dom_auto_ptr << "< " << xerces_ns << + "::DOMDocument > d (" << endl + << "::xsd::cxx::xml::dom::parse< " << char_type << " > (" << endl + << "u, h, p, f"; + + if (options.value ()) + os << " | ::xsd::cxx::xml::dom::no_muliple_imports"; + + os << "));" + << endl + << "if (!d.get ())" << endl + << "throw ::xsd::cxx::tree::parsing< " << char_type << " > ();" + << endl + << "::std::auto_ptr< " << type << " > r (" << endl + << fq_name (e, "parser") << " (" << endl + << "d, f | " << flags_type << "::own_dom, p));" + << endl + << "return r;" + << "}"; + + os << "::std::auto_ptr< " << type << " >" << endl + << name << " (const " << string_type << "& u," << endl + << xerces_ns << "::DOMErrorHandler& h," << endl + << flags_type << " f," << endl + << "const " << properties_type << "& p)" + << "{" + << dom_auto_ptr << "< " << xerces_ns << + "::DOMDocument > d (" << endl + << "::xsd::cxx::xml::dom::parse< " << char_type << " > (" << endl + << "u, h, p, f"; + + if (options.value ()) + os << " | ::xsd::cxx::xml::dom::no_muliple_imports"; + + os << "));" + << endl + << "if (!d.get ())" << endl + << "throw ::xsd::cxx::tree::parsing< " << char_type << " > ();" + << endl + << "::std::auto_ptr< " << type << " > r (" << endl + << fq_name (e, "parser") << " (" << endl + << "d, f | " << flags_type << "::own_dom, p));" + << endl + << "return r;" + << "}"; + + + // istream + // + os << "::std::auto_ptr< " << type << " >" << endl + << name << " (::std::istream& is," << endl + << flags_type << " f," << endl + << "const " << properties_type << "& p)" + << "{" + << "::xsd::cxx::xml::auto_initializer i (" << endl + << "(f & " << flags_type << "::dont_initialize) == 0," << endl + << "(f & " << flags_type << "::keep_dom) == 0);" + << endl + << "::xsd::cxx::xml::sax::std_input_source isrc (is);" + << "return " << fq_name (e, "parser") << " (isrc, f, p);" + << "}"; + + os << "::std::auto_ptr< " << type << " >" << endl + << name << " (::std::istream& is," << endl + << error_handler << "& h," << endl + << flags_type << " f," << endl + << "const " << properties_type << "& p)" + << "{" + << "::xsd::cxx::xml::auto_initializer i (" << endl + << "(f & " << flags_type << "::dont_initialize) == 0," << endl + << "(f & " << flags_type << "::keep_dom) == 0);" + << endl + << "::xsd::cxx::xml::sax::std_input_source isrc (is);" + << "return " << fq_name (e, "parser") << " (isrc, h, f, p);" + << "}"; + + os << "::std::auto_ptr< " << type << " >" << endl + << name << " (::std::istream& is," << endl + << xerces_ns << "::DOMErrorHandler& h," << endl + << flags_type << " f," << endl + << "const " << properties_type << "& p)" + << "{" + << "::xsd::cxx::xml::sax::std_input_source isrc (is);" + << "return " << fq_name (e, "parser") << " (isrc, h, f, p);" + << "}"; + + os << "::std::auto_ptr< " << type << " >" << endl + << name << " (::std::istream& is," << endl + << "const " << string_type << "& sid," << endl + << flags_type << " f," << endl + << "const " << properties_type << "& p)" + << "{" + << "::xsd::cxx::xml::auto_initializer i (" << endl + << "(f & " << flags_type << "::dont_initialize) == 0," << endl + << "(f & " << flags_type << "::keep_dom) == 0);" + << endl + << "::xsd::cxx::xml::sax::std_input_source isrc (is, sid);" + << "return " << fq_name (e, "parser") << " (isrc, f, p);" + << "}"; + + os << "::std::auto_ptr< " << type << " >" << endl + << name << " (::std::istream& is," << endl + << "const " << string_type << "& sid," << endl + << error_handler << "& h," << endl + << flags_type << " f," << endl + << "const " << properties_type << "& p)" + << "{" + << "::xsd::cxx::xml::auto_initializer i (" << endl + << "(f & " << flags_type << "::dont_initialize) == 0," << endl + << "(f & " << flags_type << "::keep_dom) == 0);" + << endl + << "::xsd::cxx::xml::sax::std_input_source isrc (is, sid);" + << "return " << fq_name (e, "parser") << " (isrc, h, f, p);" + << "}"; + + os << "::std::auto_ptr< " << type << " >" << endl + << name << " (::std::istream& is," << endl + << "const " << string_type << "& sid," << endl + << xerces_ns << "::DOMErrorHandler& h," << endl + << flags_type << " f," << endl + << "const " << properties_type << "& p)" + << "{" + << "::xsd::cxx::xml::sax::std_input_source isrc (is, sid);" + << "return " << fq_name (e, "parser") << " (isrc, h, f, p);" + << "}"; + + + // InputSource. + // + os << "::std::auto_ptr< " << type << " >" << endl + << name << " (" << xerces_ns << "::InputSource& i," << endl + << flags_type << " f," << endl + << "const " << properties_type << "& p)" + << "{" + << "::xsd::cxx::tree::error_handler< " << char_type << " > h;" + << endl + << dom_auto_ptr << "< " << xerces_ns << + "::DOMDocument > d (" << endl + << "::xsd::cxx::xml::dom::parse< " << char_type << " > (" << endl + << "i, h, p, f"; + + if (options.value ()) + os << " | ::xsd::cxx::xml::dom::no_muliple_imports"; + + os << "));" + << endl + << "h.throw_if_failed< ::xsd::cxx::tree::parsing< " << + char_type << " > > ();" + << endl + << "::std::auto_ptr< " << type << " > r (" << endl + << fq_name (e, "parser") << " (" << endl + << "d, f | " << flags_type << "::own_dom, p));" + << endl + << "return r;" + << "}"; + + os << "::std::auto_ptr< " << type << " >" << endl + << name << " (" << xerces_ns << "::InputSource& i," << endl + << error_handler << "& h," << endl + << flags_type << " f," << endl + << "const " << properties_type << "& p)" + << "{" + << dom_auto_ptr << "< " << xerces_ns << + "::DOMDocument > d (" << endl + << "::xsd::cxx::xml::dom::parse< " << char_type << " > (" << endl + << "i, h, p, f"; + + if (options.value ()) + os << " | ::xsd::cxx::xml::dom::no_muliple_imports"; + + os << "));" + << endl + << "if (!d.get ())" << endl + << "throw ::xsd::cxx::tree::parsing< " << char_type << " > ();" + << endl + << "::std::auto_ptr< " << type << " > r (" << endl + << fq_name (e, "parser") << " (" << endl + << "d, f | " << flags_type << "::own_dom, p));" + << endl + << "return r;" + << "}"; + + + os << "::std::auto_ptr< " << type << " >" << endl + << name << " (" << xerces_ns << "::InputSource& i," << endl + << xerces_ns << "::DOMErrorHandler& h," << endl + << flags_type << " f," << endl + << "const " << properties_type << "& p)" + << "{" + << dom_auto_ptr << "< " << xerces_ns << + "::DOMDocument > d (" << endl + << "::xsd::cxx::xml::dom::parse< " << char_type << " > (" << endl + << "i, h, p, f"; + + if (options.value ()) + os << " | ::xsd::cxx::xml::dom::no_muliple_imports"; + + os << "));" + << endl + << "if (!d.get ())" << endl + << "throw ::xsd::cxx::tree::parsing< " << char_type << " > ();" + << endl + << "::std::auto_ptr< " << type << " > r (" << endl + << fq_name (e, "parser") << " (" << endl + << "d, f | " << flags_type << "::own_dom, p));" + << endl + << "return r;" + << "}"; + + + // DOM. + // + + Boolean fund (false); + + { + IsFundamentalType test (fund); + test.dispatch (t); + } + + // Check if we need to handle xsi:type and substitution groups. + // If this element's type is anonymous or mapped to a fundamental + // C++ type then we don't need to do anything. + // + Boolean poly (!fund && polymorphic && + !t.context ().count ("anonymous")); + + // const DOMDocument& + // + os << "::std::auto_ptr< " << type << " >" << endl + << name << " (const " << xerces_ns << "::DOMDocument& d," << endl + << flags_type << " f," << endl + << "const " << properties_type << "& p)" + << "{" + << "if (f & " << flags_type << "::keep_dom)" + << "{" + << dom_auto_ptr << "< " << xerces_ns << + "::DOMDocument > c (" << endl + << "static_cast< " << xerces_ns << + "::DOMDocument* > (d.cloneNode (true)));" + << endl + << "::std::auto_ptr< " << type << " > r (" << endl + << fq_name (e, "parser") << " (" << endl + << "c, f | " << flags_type << "::own_dom, p));" + << endl + << "return r;" + << "}" + << "const " << xerces_ns << "::DOMElement& e (*d.getDocumentElement ());" + << "const " << qname_type << " n (" << endl + << "::xsd::cxx::xml::dom::name< " << char_type << " > (e));" + << endl; + + if (poly) + { + // aCC cannot handle an inline call to type_factory_map_instance. + // + os << "::xsd::cxx::tree::type_factory_map< " << char_type << + " >& tfm (" << endl + << "::xsd::cxx::tree::type_factory_map_instance< 0, " << + char_type << " > ());" + << endl + << "::std::auto_ptr< ::xsd::cxx::tree::type > tmp (" << endl + << "tfm.create (" << endl + << L << strlit (e.name ()) << "," << endl + << L << strlit (e.namespace_().name ()) << "," << endl + << "&::xsd::cxx::tree::factory_impl< " << type << " >," << endl + << "true, true, e, n, f, 0));" + << endl + << "if (tmp.get () != 0)" + << "{" + << "::std::auto_ptr< " << type << " > r (" << endl + << "dynamic_cast< " << type << "* > (tmp.get ()));" + << endl + << "if (r.get ())" << endl + << "tmp.release ();" + << "else" << endl + << "throw ::xsd::cxx::tree::not_derived< " << char_type << + " > ();" + << endl; + } + else + { + os << "if (n.name () == " << L << strlit (e.name ()) << " &&" << endl + << "n.namespace_ () == " << L << strlit (e.namespace_().name ()) << ")" + << "{"; + + if (fund) + { + os << "::std::auto_ptr< " << type << " > r (" << endl + << "new " << type << " (" << endl + << "::xsd::cxx::tree::traits< " << type << ", " << + char_type; + + if (t.is_a ()) + os << ", ::xsd::cxx::tree::schema_type::double_"; + else if (t.is_a ()) + os << ", ::xsd::cxx::tree::schema_type::decimal"; + + os << " >::create (" << endl + << "e, f, 0)));"; + } + else + { + os << "::std::auto_ptr< " << type << " > r (" << endl + << "::xsd::cxx::tree::traits< " << type << ", " << + char_type << " >::create (" << endl + << "e, f, 0));"; + } + } + + os << "return r;" + << "}" + << "throw ::xsd::cxx::tree::unexpected_element < " << + char_type << " > (" << endl + << "n.name ()," << endl + << "n.namespace_ ()," << endl + << L << strlit (e.name ()) << "," << endl + << L << strlit (e.namespace_().name ()) << ");" + << "}"; + + + // dom::auto_ptr + // + os << "::std::auto_ptr< " << type << " >" << endl + << name << " (" << dom_auto_ptr << "< " << xerces_ns << + "::DOMDocument >& d," << endl + << flags_type << " f," << endl + << "const " << properties_type << "&)" + << "{" + << dom_auto_ptr << "< " << xerces_ns << + "::DOMDocument > c (" << endl + << "((f & " << flags_type << "::keep_dom) &&" << endl + << "!(f & " << flags_type << "::own_dom))" << endl + << "? static_cast< " << xerces_ns << "::DOMDocument* > (" << + "d->cloneNode (true))" << endl + << ": 0);" + << endl + << xerces_ns << "::DOMDocument& doc (c.get () ? *c : *d);" + << "const " << xerces_ns << "::DOMElement& e (" << + "*doc.getDocumentElement ());" + << endl + << "const " << qname_type << " n (" << endl + << "::xsd::cxx::xml::dom::name< " << char_type << " > (e));" + << endl + << "if (f & " << flags_type << "::keep_dom)" << endl + << "doc.setUserData (" << dom_node_key << "," << endl + << "(c.get () ? &c : &d)," << endl + << "0);" + << endl; + + if (poly) + { + // aCC cannot handle an inline call to type_factory_map_instance. + // + os << "::xsd::cxx::tree::type_factory_map< " << char_type << + " >& tfm (" << endl + << "::xsd::cxx::tree::type_factory_map_instance< 0, " << + char_type << " > ());" + << endl + << "::std::auto_ptr< ::xsd::cxx::tree::type > tmp (" << endl + << "tfm.create (" << endl + << L << strlit (e.name ()) << "," << endl + << L << strlit (e.namespace_().name ()) << "," << endl + << "&::xsd::cxx::tree::factory_impl< " << type << " >," << endl + << "true, true, e, n, f, 0));" + << endl + << "if (tmp.get () != 0)" + << "{"; + } + else + { + os << "if (n.name () == " << L << strlit (e.name ()) << " &&" << endl + << "n.namespace_ () == " << L << strlit (e.namespace_().name ()) << ")" + << "{"; + + if (fund) + { + os << "::std::auto_ptr< " << type << " > r (" << endl + << "new " << type << " (" << endl + << "::xsd::cxx::tree::traits< " << type << ", " << + char_type; + + if (t.is_a ()) + os << ", ::xsd::cxx::tree::schema_type::double_"; + else if (t.is_a ()) + os << ", ::xsd::cxx::tree::schema_type::decimal"; + + os << " >::create (" << endl + << "e, f, 0)));"; + } + else + { + os << "::std::auto_ptr< " << type << " > r (" << endl + << "::xsd::cxx::tree::traits< " << type << ", " << + char_type << " >::create (" << endl + << "e, f, 0));"; + } + } + + if (poly) + { + os << endl + << "::std::auto_ptr< " << type << " > r (" << endl + << "dynamic_cast< " << type << "* > (tmp.get ()));" + << endl + << "if (r.get ())" << endl + << "tmp.release ();" + << "else" << endl + << "throw ::xsd::cxx::tree::not_derived< " << char_type << + " > ();" + << endl; + } + + os << "return r;" + << "}" + << "throw ::xsd::cxx::tree::unexpected_element < " << + char_type << " > (" << endl + << "n.name ()," << endl + << "n.namespace_ ()," << endl + << L << strlit (e.name ()) << "," << endl + << L << strlit (e.namespace_().name ()) << ");" + << "}"; + } + + private: + String + type_name (Type& e) + { + std::wostringstream o; + + MemberTypeName type (*this, o); + type.dispatch (e.type ()); + + return o.str (); + } + }; + } + + Void + generate_parser_source (Context& ctx, + UnsignedLong first, + UnsignedLong last) + { + ctx.os << "#include " << endl + << "#include " << endl + << "#include " << endl + << endl; + + Traversal::Schema schema; + Traversal::Sources sources; + Traversal::Names names_ns, names; + Namespace ns (ctx, first, last); + ElementFunction element (ctx); + + schema >> sources >> schema; + schema >> names_ns >> ns >> names >> element; + + schema.dispatch (ctx.schema_root); + } + } +} -- cgit v1.1