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/elements.hxx | 2030 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2030 insertions(+) create mode 100644 xsd/cxx/tree/elements.hxx (limited to 'xsd/cxx/tree/elements.hxx') diff --git a/xsd/cxx/tree/elements.hxx b/xsd/cxx/tree/elements.hxx new file mode 100644 index 0000000..3d70aab --- /dev/null +++ b/xsd/cxx/tree/elements.hxx @@ -0,0 +1,2030 @@ +// file : xsd/cxx/tree/elements.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CXX_TREE_ELEMENTS_HXX +#define CXX_TREE_ELEMENTS_HXX + +#include + +#include +#include +#include + +#include + +#include + +#include + + +namespace CXX +{ + namespace Tree + { + struct Counts + { + Counts () + : global_types (0), + global_elements (0), + generated_global_elements (0), + complexity_total (0) + { + } + + UnsignedLong global_types; + UnsignedLong global_elements; + UnsignedLong generated_global_elements; + + // Complexity value for each global type and generated global + // element, in order. + // + Cult::Containers::Vector complexity; + UnsignedLong complexity_total; + }; + + struct InvalidCustomTypeMapping + { + InvalidCustomTypeMapping (String const& mapping, + String const& reason) + : mapping_ (mapping), reason_ (reason) + { + } + + String const& + mapping () const + { + return mapping_; + } + + String const& + reason () const + { + return reason_; + } + + private: + String mapping_; + String reason_; + }; + + // + // + class Context: public CXX::Context + { + public: + typedef BackendElements::Regex::Expression Regex; + typedef BackendElements::Regex::Pattern WideRegexPat; + + struct DirectCustomTypeMapInfo + { + DirectCustomTypeMapInfo (String const& t = L"", + String const& b = L"") + : type (t), base (b) + { + } + + String type; + String base; + }; + + struct RegexCustomTypeMapInfo + { + RegexCustomTypeMapInfo (WideRegexPat const& p, + String const& t, + String const& b) + : pat (p), type_sub (t), base_sub (b) + { + } + + WideRegexPat pat; + String type_sub; + String base_sub; + }; + + typedef + Cult::Containers::Vector + RegexCustomTypeMap; + + typedef + Cult::Containers::Map + DirectCustomTypeMap; + + public: + Context (std::wostream& o, + SemanticGraph::Schema& root, + CLI::Options const& ops, + Counts const& counts_, + Boolean generate_xml_schema, + Regex const* fwd_expr, + Regex const* hxx_expr, + Regex const* ixx_expr); + + protected: + Context (Context& c); + Context (Context& c, std::wostream& o); + + // Custom type mapping. + // + public: + // Returns empty string if custom mapping is not required. + // + String + custom_type (SemanticGraph::Type const&) const; + + // Returns true if custom mapping is required. name is + // populated with the custom type name or empty if the + // original name should be used. + // + Boolean + custom_type (SemanticGraph::Type const&, String& name) const; + + // Returns true if this type has been renamed as part of the + // customization process. If the function returns true, the + // name string is populated with the new name or empty if + // the type should not be generated at all. + // + Boolean + renamed_type (SemanticGraph::Type const&, String& name) const; + + public: + // Return true if this type is-a QName. + // + Boolean + is_qname (SemanticGraph::Type&); + + public: + // Performs a number of processing steps, including forcing a new + // line after 80 characters as well as "commentizing" the text by + // adding '* ' after each newline. + // + Void + write_annotation (SemanticGraph::Annotation&); + + // Escaped names. + // + public: + // Accessor name. + // + static String const& + eaname (SemanticGraph::Member const& m) + { + return m.context ().get ("aname"); + } + + static String const& + eaname (SemanticGraph::Any const& a) + { + return a.context ().get ("aname"); + } + + static String const& + eaname (SemanticGraph::AnyAttribute const& a) + { + return a.context ().get ("aname"); + } + + // Modifier name. + // + static String const& + emname (SemanticGraph::Member const& m) + { + return m.context ().get ("mname"); + } + + static String const& + emname (SemanticGraph::Any const& a) + { + return a.context ().get ("mname"); + } + + static String const& + emname (SemanticGraph::AnyAttribute const& a) + { + return a.context ().get ("mname"); + } + + // + // + static String const& + etype (SemanticGraph::Member const& m) + { + return m.context ().get ("type"); + } + + static String const& + etraits (SemanticGraph::Member const& m) + { + return m.context ().get ("traits"); + } + + static String const& + econtainer (SemanticGraph::Member const& m) + { + return m.context ().get ("container"); + } + + static String const& + econtainer (SemanticGraph::Any const& a) + { + return a.context ().get ("container"); + } + + static String const& + econtainer (SemanticGraph::AnyAttribute const& a) + { + return a.context ().get ("container"); + } + + static String const& + eiterator (SemanticGraph::Member const& m) + { + return m.context ().get ("iterator"); + } + + static String const& + eiterator (SemanticGraph::Any const& a) + { + return a.context ().get ("iterator"); + } + + static String const& + eiterator (SemanticGraph::AnyAttribute const& a) + { + return a.context ().get ("iterator"); + } + + static String const& + econst_iterator (SemanticGraph::Member const& m) + { + return m.context ().get ("const-iterator"); + } + + static String const& + econst_iterator (SemanticGraph::Any const& a) + { + return a.context ().get ("const-iterator"); + } + + static String const& + econst_iterator (SemanticGraph::AnyAttribute const& a) + { + return a.context ().get ("const-iterator"); + } + + static String const& + emember (SemanticGraph::Member const& m) + { + return m.context ().get ("member"); + } + + static String const& + emember (SemanticGraph::Any const& a) + { + return a.context ().get ("member"); + } + + static String const& + emember (SemanticGraph::AnyAttribute const& a) + { + return a.context ().get ("member"); + } + + static String const& + edefault_value (SemanticGraph::Member const& m) + { + return m.context ().get ("default-value"); + } + + static String const& + edefault_value_member (SemanticGraph::Member const& m) + { + return m.context ().get ("default-value-member"); + } + + // Underlying enum value type. + // + static String const& + evalue (SemanticGraph::Enumeration const& e) + { + return e.context ().get ("value"); + } + + // dom_document + // + static Boolean + edom_document_p (SemanticGraph::Complex const& c) + { + return c.context ().count ("dom-document"); + } + + static String const& + edom_document (SemanticGraph::Complex const& c) + { + return c.context ().get ("dom-document"); + } + + static Boolean + edom_document_member_p (SemanticGraph::Complex const& c) + { + return c.context ().count ("dom-document-member"); + } + + static String const& + edom_document_member (SemanticGraph::Complex const& c) + { + return c.context ().get ("dom-document-member"); + } + + // Parsing and serialization function names. + // + static String const& + eparser (SemanticGraph::Element const& e) + { + return e.context ().get ("parser"); + } + + static String const& + eserializer (SemanticGraph::Element const& e) + { + return e.context ().get ("serializer"); + } + + public: + Void + enter_ns_scope (String const& name) + { + ns_scope_stack.push_back (name); + update_ns_scope (); + } + + Void + leave_ns_scope () + { + ns_scope_stack.pop_back (); + update_ns_scope (); + } + + private: + Void + update_ns_scope (); + + private: + // Write text that may contain characters that we will have + // to escape (indicated by the rogue flag). + // + Void + write_rogue_text (WideChar const* s, Size size, Boolean rogue); + + public: + CLI::Options const& options; + Counts const& counts; + String& any_type; + String& any_simple_type; + String& element_type; + String& container; + String& flags_type; + String& qname_type; + String& xs_string_type; + String& properties_type; + String& error_handler_type; + String& list_stream_type; + String& namespace_infomap_type; + String& parser_type; + String& std_ostream_type; + String& ostream_type; + String& istream_type; + String& xerces_ns; + String& dom_auto_ptr; + String& dom_node_key; + String& as_double_type; + String& as_decimal_type; + + Boolean& generate_xml_schema; + Boolean& doxygen; + Boolean polymorphic; + + Regex const* fwd_expr; + Regex const* hxx_expr; + Regex const* ixx_expr; + + String& ns_scope; + + RegexCustomTypeMap& regex_custom_type_map; + DirectCustomTypeMap& direct_custom_type_map; + + private: + String any_type_; + String any_simple_type_; + String element_type_; + String container_; + String flags_type_; + String qname_type_; + String xs_string_type_; + String properties_type_; + String error_handler_type_; + String list_stream_type_; + String namespace_infomap_type_; + String parser_type_; + String std_ostream_type_; + String ostream_type_; + String istream_type_; + String xerces_ns_; + String dom_auto_ptr_; + String dom_node_key_; + String as_double_type_; + String as_decimal_type_; + + Boolean generate_xml_schema_; + Boolean doxygen_; + + typedef + Cult::Containers::Deque + NamespaceStack; + + typedef + Cult::Containers::Deque + ScopeStack; + + String ns_scope_; + + NamespaceStack& ns_scope_stack; + NamespaceStack ns_scope_stack_; + + RegexCustomTypeMap regex_custom_type_map_; + DirectCustomTypeMap direct_custom_type_map_; + + private: + WideRegexPat const cxx_uq_id_expr_; + WideRegexPat const& cxx_uq_id_expr; + }; + + // Check whether this Schema type maps to a fundamental C++ type. + // + struct IsFundamentalType : Traversal::Fundamental::Byte, + Traversal::Fundamental::UnsignedByte, + Traversal::Fundamental::Short, + Traversal::Fundamental::UnsignedShort, + Traversal::Fundamental::Int, + Traversal::Fundamental::UnsignedInt, + Traversal::Fundamental::Long, + Traversal::Fundamental::UnsignedLong, + Traversal::Fundamental::Integer, + Traversal::Fundamental::NonPositiveInteger, + Traversal::Fundamental::NonNegativeInteger, + Traversal::Fundamental::PositiveInteger, + Traversal::Fundamental::NegativeInteger, + + Traversal::Fundamental::Boolean, + + Traversal::Fundamental::Float, + Traversal::Fundamental::Double, + Traversal::Fundamental::Decimal + + { + IsFundamentalType (Boolean& r) + : r_ (r) + { + } + + // Integral types. + // + virtual Void + traverse (SemanticGraph::Fundamental::Byte&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedByte&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Short&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedShort&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Int&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedInt&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Long&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedLong&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Integer&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NonPositiveInteger&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NonNegativeInteger&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::PositiveInteger&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NegativeInteger&) + { + r_ = true; + } + + // Boolean. + // + virtual Void + traverse (SemanticGraph::Fundamental::Boolean&) + { + r_ = true; + } + + // Floats. + // + virtual Void + traverse (SemanticGraph::Fundamental::Float&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Double&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Decimal&) + { + r_ = true; + } + + private: + Boolean& r_; + }; + + // Check whether this is a string-based type. + // + struct IsStringBasedType : Traversal::Complex, + Traversal::Union, + Traversal::Fundamental::String, + Traversal::Fundamental::NormalizedString, + Traversal::Fundamental::Token, + Traversal::Fundamental::Name, + Traversal::Fundamental::NameToken, + Traversal::Fundamental::NCName, + Traversal::Fundamental::Language + { + IsStringBasedType (Boolean& r) + : r_ (r) + { + *this >> inherits_ >> *this; + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + inherits (c, inherits_); + } + + virtual Void + traverse (SemanticGraph::Union&) + { + // Current mapping of union is string-based. + // + r_ = true; + } + + // Strings. + // + virtual Void + traverse (SemanticGraph::Fundamental::String&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NormalizedString&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Token&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NameToken&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Name&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NCName&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Language&) + { + r_ = true; + } + + private: + Boolean& r_; + Traversal::Inherits inherits_; + }; + + + // Check whether this is a enumeration-based type. + // + struct IsEnumBasedType : Traversal::Complex + { + IsEnumBasedType (SemanticGraph::Enumeration*& e) + : enum_ (e) + { + *this >> inherits_; + + inherits_ >> *this; + inherits_ >> enum_; + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + inherits (c, inherits_); + } + + private: + struct Enumeration: Traversal::Enumeration + { + Enumeration (SemanticGraph::Enumeration*& e) + : e_ (e) + { + } + + virtual Void + traverse (Type& e) + { + if (e_ == 0) + e_ = &e; + } + + private: + SemanticGraph::Enumeration*& e_; + }; + + + private: + Enumeration enum_; + Traversal::Inherits inherits_; + }; + + + // + // + struct MemberTypeName : protected Context, + Traversal::Type, + Traversal::List, + Traversal::Union, + Traversal::Complex, + + Traversal::AnyType, + Traversal::AnySimpleType, + + Traversal::Fundamental::Byte, + Traversal::Fundamental::UnsignedByte, + Traversal::Fundamental::Short, + Traversal::Fundamental::UnsignedShort, + Traversal::Fundamental::Int, + Traversal::Fundamental::UnsignedInt, + Traversal::Fundamental::Long, + Traversal::Fundamental::UnsignedLong, + Traversal::Fundamental::Integer, + Traversal::Fundamental::NonPositiveInteger, + Traversal::Fundamental::NonNegativeInteger, + Traversal::Fundamental::PositiveInteger, + Traversal::Fundamental::NegativeInteger, + + Traversal::Fundamental::Boolean, + + Traversal::Fundamental::Float, + Traversal::Fundamental::Double, + Traversal::Fundamental::Decimal, + + Traversal::Fundamental::String, + Traversal::Fundamental::NormalizedString, + Traversal::Fundamental::Token, + Traversal::Fundamental::Name, + Traversal::Fundamental::NameToken, + Traversal::Fundamental::NameTokens, + Traversal::Fundamental::NCName, + Traversal::Fundamental::Language, + + Traversal::Fundamental::QName, + + Traversal::Fundamental::Id, + Traversal::Fundamental::IdRef, + Traversal::Fundamental::IdRefs, + + Traversal::Fundamental::AnyURI, + + Traversal::Fundamental::Base64Binary, + Traversal::Fundamental::HexBinary, + + Traversal::Fundamental::Date, + Traversal::Fundamental::DateTime, + Traversal::Fundamental::Duration, + Traversal::Fundamental::Day, + Traversal::Fundamental::Month, + Traversal::Fundamental::MonthDay, + Traversal::Fundamental::Year, + Traversal::Fundamental::YearMonth, + Traversal::Fundamental::Time, + + Traversal::Fundamental::Entity, + Traversal::Fundamental::Entities + + { + MemberTypeName (Context& c) + : Context (c) + { + } + + MemberTypeName (Context& c, std::wostream& o) + : Context (c, o) + { + } + + virtual Void + traverse (SemanticGraph::Type&) + { + abort (); + } + + virtual Void + traverse (SemanticGraph::List& l) + { + os << fq_name (l); + } + + virtual Void + traverse (SemanticGraph::Union& u) + { + os << fq_name (u); + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + os << fq_name (c); + } + + // anyType & anySimpleType. + // + virtual Void + traverse (SemanticGraph::AnyType& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::AnySimpleType& t) + { + os << fq_name (t); + } + + // Integral types. + // + virtual Void + traverse (SemanticGraph::Fundamental::Byte& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedByte& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Short& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedShort& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Int& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedInt& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Long& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedLong& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Integer& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NonPositiveInteger& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NonNegativeInteger& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::PositiveInteger& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NegativeInteger& t) + { + os << fq_name (t); + } + + // Boolean. + // + virtual Void + traverse (SemanticGraph::Fundamental::Boolean& t) + { + os << fq_name (t); + } + + // Floats. + // + virtual Void + traverse (SemanticGraph::Fundamental::Float& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Double& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Decimal& t) + { + os << fq_name (t); + } + + // Strings. + // + virtual Void + traverse (SemanticGraph::Fundamental::String& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NormalizedString& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Token& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NameToken& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NameTokens& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Name& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NCName& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Language& t) + { + os << fq_name (t); + } + + + // Qualified name. + // + virtual Void + traverse (SemanticGraph::Fundamental::QName& t) + { + os << fq_name (t); + } + + + // ID/IDREF. + // + virtual Void + traverse (SemanticGraph::Fundamental::Id& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::IdRef& t) + { + if (t.named ()) + { + // IDREF + // + os << fq_name (t); + } + else + { + SemanticGraph::Nameable& ncname ( + xs_ns ().find ("NCName").first->named ()); + + os << "::xsd::cxx::tree::idref< " << + type_name (t.argumented ().type ()) << ", " << + char_type << ", " << fq_name (ncname) << " >"; + } + } + + virtual Void + traverse (SemanticGraph::Fundamental::IdRefs& t) + { + if (t.named ()) + { + // IDREFS + // + os << fq_name (t); + } + else + { + SemanticGraph::Nameable& ncname ( + xs_ns ().find ("NCName").first->named ()); + + os << "::xsd::cxx::tree::idrefs< " << char_type << ", " << + any_simple_type << ", ::xsd::cxx::tree::idref< " << + type_name (t.argumented ().type ()) << ", " << char_type << + ", " << fq_name (ncname) << " > >"; + } + } + + // URI. + // + virtual Void + traverse (SemanticGraph::Fundamental::AnyURI& t) + { + os << fq_name (t); + } + + // Binary. + // + virtual Void + traverse (SemanticGraph::Fundamental::Base64Binary& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::HexBinary& t) + { + os << fq_name (t); + } + + + // Date/time. + // + virtual Void + traverse (SemanticGraph::Fundamental::Date& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::DateTime& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Duration& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Day& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Month& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::MonthDay& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Year& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::YearMonth& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Time& t) + { + os << fq_name (t); + } + + // Entity. + // + virtual Void + traverse (SemanticGraph::Fundamental::Entity& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Entities& t) + { + os << fq_name (t); + } + + private: + // For idref/idrefs + // + String + type_name (SemanticGraph::Type& t) + { + // This type is always named. + // + std::wostringstream o; + + MemberTypeName type (*this, o); + type.dispatch (t); + + return o.str (); + } + }; + + + // + // + struct BaseTypeName : MemberTypeName + { + BaseTypeName (Context& c) + : MemberTypeName (c) + { + } + + BaseTypeName (Context& c, std::wostream& o) + : MemberTypeName (c, o) + { + } + + virtual Void + fundamental_base (SemanticGraph::Type& t) + { + os << "::xsd::cxx::tree::fundamental_base< " << + fq_name (t) << ", " << char_type << ", " << + any_simple_type << " >"; + } + + // Integrals. + // + virtual Void + traverse (SemanticGraph::Fundamental::Byte& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedByte& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Short& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedShort& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Int& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedInt& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Long& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedLong& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Integer& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NonPositiveInteger& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NonNegativeInteger& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::PositiveInteger& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NegativeInteger& t) + { + fundamental_base (t); + } + + // Boolean. + // + virtual Void + traverse (SemanticGraph::Fundamental::Boolean& t) + { + fundamental_base (t); + } + + // Floats. + // + virtual Void + traverse (SemanticGraph::Fundamental::Float& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Double& t) + { + os << "::xsd::cxx::tree::fundamental_base< " << + fq_name (t) << ", " << char_type << ", " << + any_simple_type << ", " << + "::xsd::cxx::tree::schema_type::double_ >"; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Decimal& t) + { + os << "::xsd::cxx::tree::fundamental_base< " << + fq_name (t) << ", " << char_type << ", " << + any_simple_type << ", " << + "::xsd::cxx::tree::schema_type::decimal >"; + } + }; + + // Initial value should be true. + // + struct IsSimpleType : Traversal::Complex, + Traversal::Member, + Traversal::Any, + Traversal::AnyAttribute + { + IsSimpleType (Boolean& v) + : v_ (v) + { + *this >> names_ >> *this; + *this >> inherits_ >> *this; + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + names (c, names_); + + if (v_) + inherits (c, inherits_); + } + + virtual Void + traverse (SemanticGraph::Member&) + { + v_ = false; + } + + virtual Void + traverse (SemanticGraph::Any&) + { + v_ = false; + } + + virtual Void + traverse (SemanticGraph::AnyAttribute&) + { + v_ = false; + } + + private: + Boolean& v_; + Traversal::Names names_; + Traversal::Inherits inherits_; + }; + + // Test whether we need to generate default c-tor. Note that we are not + // interested in anyAttribute since it is always mapped to a sequence. + // + struct GenerateDefaultCtor: Traversal::Complex, + Traversal::Enumeration, + Traversal::Type, + Traversal::Element, + Traversal::Attribute, + Traversal::Any, + protected virtual Context + { + // generate should initially be false. + // + GenerateDefaultCtor (Context&, Boolean& generate, Boolean no_base); + + virtual Void + traverse (SemanticGraph::Complex&); + + virtual Void + traverse (SemanticGraph::Type&); + + virtual Void + traverse (SemanticGraph::Enumeration&); + + virtual Void + traverse (SemanticGraph::Element&); + + virtual Void + traverse (SemanticGraph::Attribute&); + + virtual Void + traverse (SemanticGraph::Any&); + + private: + Boolean& generate_; + Boolean no_base_; + + private: + Traversal::Inherits inherits_; + Traversal::Names names_; + }; + + // Test whether we need to generate from-base c-tor. + // + struct GenerateFromBaseCtor: Traversal::Complex + { + // generate should initially be false. + // + GenerateFromBaseCtor (Context& c, Boolean& generate); + + virtual Void + traverse (SemanticGraph::Complex& c); + + private: + // Note that we are not interested in anyAttribute since it is always + // mapped to a sequence. + // + struct Traverser: Traversal::Complex, + Traversal::Element, + Traversal::Attribute, + Traversal::Any, + protected virtual Context + { + Traverser (Context& c, Boolean& generate); + + virtual Void + traverse (SemanticGraph::Complex&); + + virtual Void + traverse (SemanticGraph::Attribute&); + + virtual Void + traverse (SemanticGraph::Element&); + + virtual Void + traverse (SemanticGraph::Any&); + + private: + Boolean& generate_; + + private: + Traversal::Inherits inherits_; + Traversal::Names names_; + } traverser_; + + Traversal::Inherits inherits_; + }; + + // Test whether the type has any non-optional element of complex + // (has attributes/elements) and non-fundamental types. + // + struct HasComplexNonFundNonOptArgs: Traversal::Complex, + Traversal::Element, + protected virtual Context + { + // complex and non_fund should initially be false. clash + // should initially be true. + // + HasComplexNonFundNonOptArgs (Context& c, + Boolean including_base, + Boolean& complex, + Boolean& non_fund, + Boolean& clash); + + virtual Void + traverse (SemanticGraph::Complex&); + + virtual Void + traverse (SemanticGraph::Element&); + + private: + Boolean& complex_; + Boolean& non_fund_; + Boolean& clash_; + + Traversal::Inherits inherits_; + Traversal::Names names_; + }; + + // Immediate non-optional member. Note that AnyAttribute is always + // mapped to a sequence. + // + struct FromBaseCtorArg : Traversal::Any, + Traversal::Element, + Traversal::Attribute, + protected virtual Context + { + enum ArgType + { + arg_type, + arg_complex_auto_ptr, + arg_non_fund_auto_ptr + }; + + FromBaseCtorArg (Context& c, ArgType, Boolean arg); + + virtual Void + traverse (SemanticGraph::Any&); + + virtual Void + traverse (SemanticGraph::Attribute&); + + virtual Void + traverse (SemanticGraph::Element&); + + private: + ArgType arg_type_; + Boolean arg_; + }; + + // List of all non-optional members and a simple base. Note that + // AnyAttribute is always mapped to a sequence. + // + struct CtorArgs : Traversal::Complex, + Traversal::Enumeration, + Traversal::Type, + Traversal::Any, + Traversal::Element, + Traversal::Attribute, + protected virtual Context + { + enum ArgType + { + arg_type, + arg_complex_auto_ptr, + arg_non_fund_auto_ptr + }; + + // The second version outputs the argument name and stores + // in in the base_arg string. + // + CtorArgs (Context&, ArgType); + CtorArgs (Context&, ArgType, String& base_arg); + + virtual Void + traverse (SemanticGraph::Type&); + + virtual Void + traverse (SemanticGraph::Enumeration&); + + virtual Void + traverse (SemanticGraph::Any&); + + virtual Void + traverse (SemanticGraph::Attribute&); + + virtual Void + traverse (SemanticGraph::Element&); + + private: + String + comma (); + + private: + ArgType arg_type_; + String base_; + String* base_arg_; + Boolean first_; + + private: + Traversal::Inherits inherits_; + Traversal::Names names_; + + MemberTypeName member_name_; + }; + + + // Check whether we need to generate c-tor without the base argument. + // + struct GenerateWithoutBaseCtor: Traversal::List, + Traversal::Union, + Traversal::Complex, + Traversal::Enumeration, + + Traversal::AnyType, + Traversal::AnySimpleType, + + Traversal::Fundamental::String, + Traversal::Fundamental::NormalizedString, + Traversal::Fundamental::Token, + + Traversal::Fundamental::NameTokens, + Traversal::Fundamental::IdRefs, + + Traversal::Fundamental::Base64Binary, + Traversal::Fundamental::HexBinary + { + // generate should initially be false. + // + GenerateWithoutBaseCtor (Boolean& generate) + : generate_ (generate) + { + *this >> inherits_ >> *this; + } + + virtual Void + traverse (SemanticGraph::List&) + { + generate_ = true; + } + + virtual Void + traverse (SemanticGraph::Union&) + { + // No default initialization. + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + Complex::inherits (c); + } + + virtual Void + traverse (SemanticGraph::Enumeration&) + { + // No default initialization. + } + + virtual Void + traverse (SemanticGraph::AnyType&) + { + generate_ = true; + } + + virtual Void + traverse (SemanticGraph::AnySimpleType&) + { + generate_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::String&) + { + generate_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NormalizedString&) + { + generate_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Token&) + { + generate_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NameTokens&) + { + generate_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::IdRefs&) + { + generate_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Base64Binary&) + { + generate_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::HexBinary&) + { + generate_ = true; + } + + private: + Boolean& generate_; + Traversal::Inherits inherits_; + }; + + + // List of all non-optional members sans simple base. Note that + // AnyAttribute is always mapped to a sequence. + // + struct CtorArgsWithoutBase: Traversal::Complex, + Traversal::Any, + Traversal::Element, + Traversal::Attribute, + protected virtual Context + { + enum ArgType + { + arg_type, + arg_complex_auto_ptr, + arg_non_fund_auto_ptr + }; + + CtorArgsWithoutBase (Context& c, ArgType, Boolean arg, Boolean first); + + virtual Void + traverse (SemanticGraph::Any&); + + virtual Void + traverse (SemanticGraph::Element&); + + virtual Void + traverse (SemanticGraph::Attribute&); + + private: + String + comma (); + + private: + ArgType arg_type_; + Boolean arg_; + Boolean first_; + + private: + Traversal::Inherits inherits_; + Traversal::Names names_; + }; + + // + // + struct GlobalElementBase + { + GlobalElementBase (Context& c) + : ctx_ (c) + { + } + + Boolean + generate_p (SemanticGraph::Element&); + + Boolean + doc_root_p (SemanticGraph::Element&); + + private: + Context& ctx_; + }; + + + // + // + struct Namespace: CXX::Namespace, + GlobalElementBase, + CXX::Namespace::ScopeTracker + { + Namespace (Context&, + UnsignedLong first = 1, + UnsignedLong last = 0); + + virtual Void + traverse (Type&); + + protected: + virtual Void + enter (Type&, String const& name, Boolean last); + + virtual Void + leave (); + + protected: + Context& ctx_; + + private: + UnsignedLong first_; + UnsignedLong last_; + UnsignedLong count_; + }; + + // + // + struct DocumentedNamespace: Namespace + { + DocumentedNamespace (Context& c) + : Namespace (c) + { + } + + virtual Void + enter (Type& ns, String const& name, Boolean last) + { + Namespace::enter (ns, name, last); + + // Only add documentation to the innermost namespace. + // + if (ctx_.doxygen && name && last) + { + ctx_.os << "/**" << endl + << " * @brief C++ namespace for the %" << + ctx_.comment (ns.name ()) << endl + << " * schema namespace." << endl + << " */" << endl; + } + } + }; + + // + // + struct TypeForward: Traversal::Type, Context + { + TypeForward (Context& c) + : Context (c) + { + } + + virtual Void + traverse (SemanticGraph::Type& t); + }; + + struct Includes : Traversal::Imports, + Traversal::Includes + { + enum Type + { + forward, + header, + inline_, + source + }; + + Includes (Context& c, Type type) + : ctx_ (c), + type_ (type), + forward_ (c.options.value ()), + namespace_ (c), + type_forward_ (c) + { + schema_ >> schema_names_ >> namespace_ >> names_ >> type_forward_; + } + + virtual Void + traverse (SemanticGraph::Imports& i) + { + traverse_ (i); + } + + virtual Void + traverse (SemanticGraph::Includes& i) + { + traverse_ (i); + } + + private: + Void + traverse_ (SemanticGraph::Uses&); + + private: + Context& ctx_; + Type type_; + Boolean forward_; + + Traversal::Schema schema_; + Traversal::Names schema_names_; + Namespace namespace_; + Traversal::Names names_; + TypeForward type_forward_; + }; + + // + // + struct FundIncludes : Traversal::Fundamental::Byte, + Traversal::Fundamental::UnsignedByte, + Traversal::Fundamental::Short, + Traversal::Fundamental::UnsignedShort, + Traversal::Fundamental::Int, + Traversal::Fundamental::UnsignedInt, + Traversal::Fundamental::Long, + Traversal::Fundamental::UnsignedLong, + Traversal::Fundamental::Integer, + Traversal::Fundamental::NonPositiveInteger, + Traversal::Fundamental::NonNegativeInteger, + Traversal::Fundamental::PositiveInteger, + Traversal::Fundamental::NegativeInteger, + + Traversal::Fundamental::Boolean, + + Traversal::Fundamental::Float, + Traversal::Fundamental::Double, + Traversal::Fundamental::Decimal, + Context + + { + FundIncludes (Context& c, String const& prefix) + : Context (c), prefix_ (prefix), + long_ (false), unsigned_long_ (false) + { + } + + // Integral types. + // + virtual Void + traverse (SemanticGraph::Fundamental::Byte& t) + { + gen_include (t, "byte.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedByte& t) + { + gen_include (t, "unsigned-byte.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Short& t) + { + gen_include (t, "short.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedShort& t) + { + gen_include (t, "unsigned-short.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Int& t) + { + gen_include (t, "int.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedInt& t) + { + gen_include (t, "unsigned-int.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Long& t) + { + if (!long_) + long_ = gen_include (t, "long.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedLong& t) + { + if (!unsigned_long_) + unsigned_long_ = gen_include (t, "unsigned-long.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Integer& t) + { + if (!long_) + long_ = gen_include (t, "long.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NonPositiveInteger& t) + { + if (!long_) + long_ = gen_include (t, "long.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NonNegativeInteger& t) + { + if (!unsigned_long_) + unsigned_long_ = gen_include (t, "unsigned-long.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::PositiveInteger& t) + { + if (!unsigned_long_) + unsigned_long_ = gen_include (t, "unsigned-long.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NegativeInteger& t) + { + if (!long_) + long_ = gen_include (t, "long.hxx"); + } + + // Boolean. + // + virtual Void + traverse (SemanticGraph::Fundamental::Boolean& t) + { + gen_include (t, "boolean.hxx"); + } + + // Floats. + // + virtual Void + traverse (SemanticGraph::Fundamental::Float& t) + { + gen_include (t, "float.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Double& t) + { + gen_include (t, "double.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Decimal& t) + { + gen_include (t, "decimal.hxx"); + } + + private: + Boolean + gen_include (SemanticGraph::Type& t, String const& file) + { + String custom; + + // XML Schema built-in type customization is only possible when + // we are generating separate header. + // + if (generate_xml_schema && custom_type (t, custom)) + { + String new_name; + renamed_type (t, new_name); + + if (!new_name) + return false; + } + + os << "#include " + << endl; + + return true; + } + + private: + String prefix_; + Boolean long_; + Boolean unsigned_long_; + }; + } +} + +#endif // CXX_TREE_ELEMENTS_HXX -- cgit v1.1