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/tree-inline.cxx | 1025 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1025 insertions(+) create mode 100644 xsd/cxx/tree/tree-inline.cxx (limited to 'xsd/cxx/tree/tree-inline.cxx') diff --git a/xsd/cxx/tree/tree-inline.cxx b/xsd/cxx/tree/tree-inline.cxx new file mode 100644 index 0000000..5bec713 --- /dev/null +++ b/xsd/cxx/tree/tree-inline.cxx @@ -0,0 +1,1025 @@ +// file : xsd/cxx/tree/tree-inline.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 List : Traversal::List, protected virtual Context + { + List (Context& c) + : Context (c) + { + } + + virtual Void + traverse (Type& l) + { + String name (ename (l)); + + // If renamed name is empty then we do not need to generate + // anything for this type. + // + if (renamed_type (l, name) && !name) + return; + + SemanticGraph::Type& item_type (l.argumented ().type ()); + String item_name (item_type_name (item_type)); + String base_type (L"::xsd::cxx::tree::list< " + item_name + + L", " + char_type); + + if (item_type.is_a ()) + base_type += L", ::xsd::cxx::tree::schema_type::double_"; + else if (item_type.is_a ()) + base_type += L", ::xsd::cxx::tree::schema_type::decimal"; + + base_type += L" >"; + + os << "// " << name << endl + << "//" << endl + << endl; + + // c-tor () + // + os << inl + << name << "::" << endl + << name << " ()" + << "{" + << "}"; + + // c-tor (size_type, const X& x) + // + String size_type (name != L"size_type" + ? String (L"size_type") + : base_type + L"::size_type"); + + os << inl + << name << "::" << endl + << name << " (" << size_type << " n, const " << item_name << + "& x)" << endl + << ": " << base_type << " (n, x)" + << "{" + << "}"; + + // copy c-tor () + // + os << inl + << name << "::" << endl + << name << " (const " << name << "& o," << endl + << flags_type << " f," << endl + << container << "* c)" << endl + << ": " << any_simple_type << " (o, f, c)," << endl + << " " << base_type << " (o, f, c)" + << "{" + << "}"; + } + + private: + String + item_type_name (SemanticGraph::Type& t) + { + std::wostringstream o; + + MemberTypeName type (*this, o); + type.dispatch (t); + + return o.str (); + } + }; + + + struct Union : Traversal::Union, protected virtual Context + { + Union (Context& c) + : Context (c) + { + } + + virtual Void + traverse (Type& u) + { + String name (ename (u)); + + // If renamed name is empty then we do not need to generate + // anything for this type. + // + if (renamed_type (u, name) && !name) + return; + + String const& base (xs_string_type); + + os << "// " << name << endl + << "//" << endl + << endl; + + if (options.value ()) + { + // c-tor () + // + os << inl + << name << "::" << endl + << name << " ()" << endl + << ": " << base << " ()" + << "{" + << "}"; + } + + // c-tor (const char*) + // + os << inl + << name << "::" << endl + << name << " (const " << char_type << "* s)" << endl + << ": " << base << " (s)" + << "{" + << "}"; + + // c-tor (string const&) + // + os << inl + << name << "::" << endl + << name << " (const " << string_type << "& s)" << endl + << ": " << base << " (s)" + << "{" + << "}"; + + // copy c-tor () + // + os << inl + << name << "::" << endl + << name << " (const " << name << "& o," << endl + << flags_type << " f," << endl + << container << "* c)" << endl + << ": " << base << " (o, f, c)" + << "{" + << "}"; + } + }; + + // Enumeration + // + + // Generate a sequence of explicit c-tor calls until we reach + // one of the fundamental string types that can be constructed + // from char literals. + // + struct CtorCallSequence: Traversal::Complex, + Traversal::Fundamental::Type, + protected virtual Context + { + CtorCallSequence (Context& c, String const& arg) + : Context (c), arg_ (arg), base_type_name_ (c) + { + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + // This type should be ultimately string based. + // + assert (c.inherits_p ()); + + os << ename (c) << " (" << endl; + + dispatch (c.inherits ().base ()); + + os << ")"; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Type& t) + { + base_type_name_.dispatch (t); + + os << " (" << arg_ << ")"; + } + + private: + String arg_; + BaseTypeName base_type_name_; + }; + + struct Enumeration : Traversal::Enumeration, + protected virtual Context + { + Enumeration (Context& c) + : Context (c), member_ (c) + { + inherits_member_ >> member_; + } + + virtual Void + traverse (Type& e) + { + String name (ename (e)); + + // If renamed name is empty then we do not need to generate + // anything for this type. + // + if (renamed_type (e, name) && !name) + return; + + Boolean string_based (false); + { + IsStringBasedType t (string_based); + t.dispatch (e); + } + + Boolean enum_based (false); + if (string_based) + { + SemanticGraph::Enumeration* be (0); + IsEnumBasedType t (be); + t.dispatch (e); + + enum_based = (be != 0); + } + + String value; + if (string_based) + value = evalue (e); + + // Get to the ultimate base and see if is a fundamental type. + // + Boolean fund_based (false); + SemanticGraph::Type& ult_base (ultimate_base (e)); + { + IsFundamentalType t (fund_based); + t.dispatch (ult_base); + } + + // + // + String base; // base type name + { + std::wostringstream o; + + BaseTypeName base_type (*this, o); + Traversal::Inherits inherits_type (base_type); + + inherits (e, inherits_type); + base = o.str (); + } + + os << "// " << name << endl + << "// " << endl + << endl; + + // default c-tor + // + if (options.value ()) + { + os << inl + << name << "::" << endl + << name << " ()" << endl + << ": " << base << " ()" + << "{" + << "}"; + } + + // c-tor (value) + // + if (string_based) + { + os << inl + << name << "::" << endl + << name << " (" << value << " v)" << endl + << ": "; + + // If we are enum-based then we can just use the corresponding + // base c-tor directly. Otherwise we will use the from-string + // c-tor. + // + if (enum_based) + os << base << " (v)"; + else + { + CtorCallSequence t (*this, L"_xsd_" + name + L"_literals_[v]"); + t.dispatch (e.inherits ().base ()); + } + + os << "{" + << "}"; + } + + // c-tor (const char*) + // + if (string_based) + { + os << inl + << name << "::" << endl + << name << " (const " << char_type << "* v)" << endl + << ": " << base << " (v)" + << "{" + << "}"; + } + + // c-tor (const std::string&) + // + if (string_based) + { + os << inl + << name << "::" << endl + << name << " (const " << string_type << "& v)" << endl + << ": " << base << " (v)" + << "{" + << "}"; + } + + // c-tor (fundamental) + // + if (fund_based) + { + os << inl + << name << "::" << endl + << name << " ("; + + member_.dispatch (ult_base); + + os << " v)" + << ": " << base << " (v)" + << "{" + << "}"; + } + + // c-tor (base) + // + // If the ultimate is also our immediate base and it is a + // fundamental type then this c-tor clashes with c-tor + // (fundamental) above. + // + if (!fund_based || &ult_base != &e.inherits ().base ()) + { + os << inl + << name << "::" << endl + << name << " (const "; + + inherits (e, inherits_member_); + + os << "& v)" << endl + << ": " << base << " (v)" + << "{" + << "}"; + } + + // copy c-tor + // + os << inl + << name << "::" << endl + << name << " (const " << name << "& v," << endl + << flags_type << " f," << endl + << container << "* c)" << endl + << ": " << base << " (v, f, c)" + << "{" + << "}"; + + // operato= (value) + // + if (string_based) + { + os << inl + << name << "& " << name << "::" << endl + << "operator= (" << value << " v)" + << "{" + << "static_cast< " << base << "& > (*this) = "; + + // If we are enum-based then we can just use the corresponding + // base assignment directly. Otherwise we will use the from- + // base assignment and a from-string base c-tor. + // + if (enum_based) + os << "v"; + else + { + os << endl; + + CtorCallSequence t (*this, L"_xsd_" + name + L"_literals_[v]"); + t.dispatch (e.inherits ().base ()); + } + + os << ";" + << endl + << "return *this;" + << "}"; + } + + os << endl; + } + + private: + Traversal::Inherits inherits_member_; + MemberTypeName member_; + }; + + struct Member: Traversal::Member, protected virtual Context + { + Member (Context& c, String const& scope) + : Context (c), scope_ (scope) + { + } + + virtual Void + traverse (Type& m) + { + if (skip (m)) + return; + + String const& aname (eaname (m)); + String const& mname (emname (m)); + String const& member (emember (m)); + + Boolean fund (false); + { + IsFundamentalType t (fund); + t.dispatch (m.type ()); + } + + Boolean def_attr (m.default_ () && + m.is_a () && + !is_qname (m.type ())); + + if (max (m) != 1) + { + // sequence + // + String container (econtainer (m)); + String q_container (scope_ + L"::" + container); + + // container const& + // name () const; + // + os << inl + << "const " << q_container << "& " << scope_ << "::" << endl + << aname << " () const" + << "{" + << "return this->" << member << ";" + << "}"; + + // container& + // name (); + // + os << inl + << q_container << "& " << scope_ << "::" << endl + << aname << " ()" + << "{" + << "return this->" << member << ";" + << "}"; + + // void + // name (container const&); + // + os << inl + << "void " << scope_ << "::" << endl + << mname << " (const " << container << "& s)" + << "{" + << "this->" << member << " = s;" + << "}"; + } + else if (min (m) == 0 && !def_attr) + { + // optional + // + String type (etype (m)); + String container (econtainer (m)); + String q_container (scope_ + L"::" + container); + + // container const& + // name () const; + // + os << inl + << "const " << q_container << "& " << scope_ << "::" << endl + << aname << " () const" + << "{" + << "return this->" << member << ";" + << "}"; + + // container& + // name (); + // + os << inl + << q_container << "& " << scope_ << "::" << endl + << aname << " ()" + << "{" + << "return this->" << member << ";" + << "}"; + + // void + // name (type const&); + // + os << inl + << "void " << scope_ << "::" << endl + << mname << " (const " << type << "& x)" + << "{" + << "this->" << member << ".set (x);" + << "}"; + + // void + // name (container const&); + // + os << inl + << "void " << scope_ << "::" << endl + << mname << " (const " << container << "& x)" + << "{" + << "this->" << member << " = x;" + << "}"; + + // void + // name (auto_ptr); + // + if (!fund) + os << inl + << "void " << scope_ << "::" << endl + << mname << " (::std::auto_ptr< " << type << " > x)" + << "{" + << "this->" << member << ".set (x);" + << "}"; + } + else + { + // one + // + String type (etype (m)); + String q_type (scope_ + L"::" + type); + + // type const& + // name () const; + // + os << inl + << "const " << q_type << "& " << scope_ << "::" << endl + << aname << " () const" + << "{" + << "return this->" << member << ".get ();" + << "}"; + + // Do not generate modifiers for fixed attributes. + // + if (!(def_attr && m.fixed ())) + { + // type& + // name (); + // + os << inl + << q_type << "& " << scope_ << "::" << endl + << aname << " ()" + << "{" + << "return this->" << member << ".get ();" + << "}"; + + // void + // name (type const&); + // + os << inl + << "void " << scope_ << "::" << endl + << mname << " (const " << type << "& x)" + << "{" + << "this->" << member << ".set (x);" + << "}"; + + // void + // name (auto_ptr); + // + if (!fund) + os << inl + << "void " << scope_ << "::" << endl + << mname << " (::std::auto_ptr< " << type << " > x)" + << "{" + << "this->" << member << ".set (x);" + << "}"; + } + } + + + // default_value + // + if (m.default_ () && !is_qname (m.type ())) + { + Boolean simple (true); + + if (m.is_a ()) + { + IsSimpleType test (simple); + test.dispatch (m.type ()); + } + + if (simple) + { + os << inl + << "const " << scope_ << "::" << etype (m) << "& " << + scope_ << "::" << endl + << edefault_value (m) << " ()" + << "{" + << "return " << edefault_value_member (m) << ";" + << "}"; + } + } + } + + private: + String scope_; + }; + + struct Any: Traversal::Any, + Traversal::AnyAttribute, + protected virtual Context + { + Any (Context& c, String const& scope) + : Context (c), scope_ (scope) + { + } + + virtual Void + traverse (SemanticGraph::Any& a) + { + String const& aname (eaname (a)); + String const& mname (emname (a)); + + String const& member (emember (a)); + + if (max (a) != 1) + { + // sequence + // + String container (econtainer (a)); + String q_container (scope_ + L"::" + container); + + // container const& + // name () const; + // + os << inl + << "const " << q_container << "& " << scope_ << "::" << endl + << aname << " () const" + << "{" + << "return this->" << member << ";" + << "}"; + + // container& + // name (); + // + os << inl + << q_container << "& " << scope_ << "::" << endl + << aname << " ()" + << "{" + << "return this->" << member << ";" + << "}"; + + // void + // name (container const&); + // + os << inl + << "void " << scope_ << "::" << endl + << mname << " (const " << container << "& s)" + << "{" + << "this->" << member << " = s;" + << "}"; + } + else if (min (a) == 0) + { + // optional + // + String container (econtainer (a)); + String q_container (scope_ + L"::" + container); + + // container const& + // name () const; + // + os << inl + << "const " << q_container << "& " << scope_ << "::" << endl + << aname << " () const" + << "{" + << "return this->" << member << ";" + << "}"; + + // container& + // name (); + // + os << inl + << q_container << "& " << scope_ << "::" << endl + << aname << " ()" + << "{" + << "return this->" << member << ";" + << "}"; + + // void + // name (type const&); + // + os << inl + << "void " << scope_ << "::" << endl + << mname << " (const " << xerces_ns << "::DOMElement& e)" + << "{" + << "this->" << member << ".set (e);" + << "}"; + + // void + // name (type*); + // + os << inl + << "void " << scope_ << "::" << endl + << mname << " (" << xerces_ns << "::DOMElement* e)" + << "{" + << "this->" << member << ".set (e);" + << "}"; + + // void + // name (container const&); + // + os << inl + << "void " << scope_ << "::" << endl + << mname << " (const " << container << "& x)" + << "{" + << "this->" << member << " = x;" + << "}"; + } + else + { + // one + // + + // type const& + // name () const; + // + os << inl + << "const " << xerces_ns << "::DOMElement& " << + scope_ << "::" << endl + << aname << " () const" + << "{" + << "return this->" << member << ".get ();" + << "}"; + + // type& + // name (); + // + os << inl + << xerces_ns << "::DOMElement& " << scope_ << "::" << endl + << aname << " ()" + << "{" + << "return this->" << member << ".get ();" + << "}"; + + // void + // name (type const&); + // + os << inl + << "void " << scope_ << "::" << endl + << mname << " (const " << xerces_ns << "::DOMElement& e)" + << "{" + << "this->" << member << ".set (e);" + << "}"; + + // void + // name (type*); + // + os << inl + << "void " << scope_ << "::" << endl + << mname << " (" << xerces_ns << "::DOMElement* e)" + << "{" + << "this->" << member << ".set (e);" + << "}"; + } + } + + virtual Void + traverse (SemanticGraph::AnyAttribute& a) + { + String const& aname (eaname (a)); + String const& mname (emname (a)); + + String const& member (emember (a)); + String container (econtainer (a)); + String q_container (scope_ + L"::" + container); + + // container const& + // name () const; + // + os << inl + << "const " << q_container << "& " << scope_ << "::" << endl + << aname << " () const" + << "{" + << "return this->" << member << ";" + << "}"; + + // container& + // name (); + // + os << inl + << q_container << "& " << scope_ << "::" << endl + << aname << " ()" + << "{" + << "return this->" << member << ";" + << "}"; + + // void + // name (container const&); + // + os << inl + << "void " << scope_ << "::" << endl + << mname << " (const " << container << "& s)" + << "{" + << "this->" << member << " = s;" + << "}"; + } + + private: + String scope_; + }; + + struct Complex : Traversal::Complex, protected virtual Context + { + Complex (Context& c) + : Context (c) + { + } + + virtual Void + traverse (Type& c) + { + String name (ename (c)); + + // If renamed name is empty then we do not need to generate + // anything for this type. + // + if (renamed_type (c, name) && !name) + return; + + os << "// " << name << endl + << "// " << endl + << endl; + + // Generate accessors and modifiers. + // + Any any (*this, name); + Member member (*this, name); + Traversal::Names names; + + if (options.value ()) + names >> any; + + names >> member; + + Complex::names (c, names); + + // dom_document accessors. + // + if (edom_document_member_p (c)) + { + os << inl + << "const " << xerces_ns << "::DOMDocument& " << + name << "::" << endl + << edom_document (c) << " () const" + << "{" + << "return *" << edom_document_member (c) << ";" + << "}"; + + os << inl + << xerces_ns << "::DOMDocument& " << name << "::" << endl + << edom_document (c) << " ()" + << "{" + << "return *" << edom_document_member (c) << ";" + << "}"; + } + + os << endl; + } + }; + + + struct GlobalElement : Traversal::Element, + GlobalElementBase, + protected virtual Context + { + GlobalElement (Context& c) + : Context (c), GlobalElementBase (c) + { + } + + virtual Void + traverse (Type& e) + { + if (!doc_root_p (e)) + return; + + Boolean fund (false); + { + IsFundamentalType test (fund); + test.dispatch (e.type ()); + } + + String const& name (ename (e)); + + os << "// " << name << endl + << "// " << endl + << endl; + + // Accessors/modifiers. + // + String const& type (etype (e)); + String const& aname (eaname (e)); + String const& mname (emname (e)); + String const& member (emember (e)); + + // type const& + // name () const; + // + os << inl + << "const " << name << "::" << type << "& " << name << "::" << endl + << aname << " () const" + << "{" + << "return this->" << member << ".get ();" + << "}"; + + // type& + // name (); + // + os << inl + << name << "::" << type << "& " << name << "::" << endl + << aname << " ()" + << "{" + << "return this->" << member << ".get ();" + << "}"; + + // void + // name (type const&); + // + os << inl + << "void " << name << "::" << endl + << mname << " (const " << type << "& x)" + << "{" + << "return this->" << member << ".set (x);" + << "}"; + + // void + // name (auto_ptr); + // + if (!fund) + { + os << inl + << "void " << name << "::" << endl + << mname << " (::std::auto_ptr< " << type << " > p)" + << "{" + << "return this->" << member << ".set (p);" + << "}"; + } + } + }; + } + + Void + generate_tree_inline (Context& ctx, UnsignedLong first, UnsignedLong last) + { + // Generate includes. + // + if (ctx.options.value ()) + { + Traversal::Schema schema; + Includes includes (ctx, Includes::inline_); + + schema >> includes; + + schema.dispatch (ctx.schema_root); + } + else + { + // Emit "weak" header includes that are used in the file-per-type + // compilation model. + // + Traversal::Schema schema; + Includes includes (ctx, Includes::source); + + schema >> includes; + + schema.dispatch (ctx.schema_root); + } + + Traversal::Schema schema; + Traversal::Sources sources; + Traversal::Names names_ns, names; + Namespace ns (ctx, first, last); + + List list (ctx); + Union union_ (ctx); + Complex complex (ctx); + Enumeration enumeration (ctx); + GlobalElement element (ctx); + + schema >> sources >> schema; + schema >> names_ns >> ns >> names; + + names >> list; + names >> union_; + names >> complex; + names >> enumeration; + + if (ctx.options.value ()) + names >> element; + + schema.dispatch (ctx.schema_root); + } + } +} -- cgit v1.1