// file : xsd/cxx/hybrid/tree-header.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 Hybrid { namespace { struct List : Traversal::List, Context { List (Context& c) : Context (c), base_name_ (c, TypeName::seq) { } virtual Void traverse (Type& l) { String name (ename (l)); os << "// " << comment (l.name ()) << " (variable-length)" << endl << "//" << endl; os << "class " << name << ": public "; base_name_.dispatch (l.argumented ().type ()); os << "{" << "private:" << endl << name << " (const " << name << "&);" << name << "& operator= (const " << name << "&);" << endl; // c-tor // os << "public:" << endl << name << " ();"; // Custom data. // if (l.context ().count ("cd-name")) { String const& name (ecd_name (l)); String const& sequence (ecd_sequence (l)); String const& iterator (ecd_iterator (l)); String const& const_iterator (ecd_const_iterator (l)); os << endl << "// Custom data." << endl << "//" << endl; // sequence & iterators // os << "typedef ::xsde::cxx::hybrid::data_seq " << sequence << ";" << "typedef " << sequence << "::iterator " << iterator << ";" << "typedef " << sequence << "::const_iterator " << const_iterator << ";" << endl; // const seq& // name () const // os << "const " << sequence << "&" << endl << name << " () const;" << endl; // seq& // name () // os << sequence << "&" << endl << name << " ();" << endl; os << "private:" << endl << sequence << " " << ecd_member (l) << ";"; } os << "};"; } private: TypeName base_name_; }; struct Union : Traversal::Union, Context { Union (Context& c) : Context (c) { } virtual Void traverse (Type& u) { SemanticGraph::Context& uc (u.context ()); String name (ename (u)); Boolean cd (uc.count ("cd-name")); os << "// " << comment (u.name ()) << " (variable-length)" << endl << "//" << endl; os << "class " << name << "{"; if (!fixed_length (u)) os << "private:" << endl << name << " (const " << name << "&);" << name << "& operator= (const " << name << "&);" << endl; os << "public:" << endl; // c-tor // os << name << " ();"; String const& value (uc.get ("value")); String const& member (uc.get ("value-member")); if (stl) { os << endl; // const std::string& // name () const // os << "const ::std::string&" << endl << value << " () const;" << endl; // std::string& // name () // os << "::std::string&" << endl << value << " ();" << endl; // void // name (const std::string&) // os << "void" << endl << value << " (const ::std::string&);" << endl; } else { // d-tor // os << "~" << name << " ();" << endl; // const char* // name () const // os << "const char*" << endl << value << " () const;" << endl; // char* // name () // os << "char*" << endl << value << " ();" << endl; // void // name (char*) // os << "void" << endl << value << " (char*);" << endl; } // Custom data. // if (cd) { String const& name (ecd_name (u)); String const& sequence (ecd_sequence (u)); String const& iterator (ecd_iterator (u)); String const& const_iterator (ecd_const_iterator (u)); os << "// Custom data." << endl << "//" << endl; // sequence & iterators // os << "typedef ::xsde::cxx::hybrid::data_seq " << sequence << ";" << "typedef " << sequence << "::iterator " << iterator << ";" << "typedef " << sequence << "::const_iterator " << const_iterator << ";" << endl; // const seq& // name () const // os << "const " << sequence << "&" << endl << name << " () const;" << endl; // seq& // name () // os << sequence << "&" << endl << name << " ();" << endl; } if (stl) { os << "private:" << endl << "::std::string " << member << ";"; } else { os << "private:" << endl << "char* " << member << ";"; } // Custom data. // if (cd) os << ecd_sequence (u) << " " << ecd_member (u) << ";"; os << "};"; } }; // // Data. // struct AlignType: Traversal::Compositor, 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::NCName, Traversal::Fundamental::Language, Traversal::Fundamental::QName, Traversal::Fundamental::Id, Traversal::Fundamental::IdRef, Traversal::Fundamental::AnyURI, 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, Context { AlignType (Context& c) : Context (c), nested_ (false) { *this >> inherits_ >> *this; *this >> attribute_names_ >> attribute_; *this >> contains_particle_; contains_particle_ >> particle_; contains_particle_ >> *this; contains_compositor_ >> *this; attribute_ >> belongs_; particle_ >> belongs_; belongs_ >> *this; } virtual Void dispatch (SemanticGraph::Node& n) { found_ = false; NodeBase::dispatch (n); } virtual Void traverse (SemanticGraph::Compositor& c) { Boolean top (false); if (!nested_) { nested_ = true; top = true; } Traversal::Compositor::traverse (c); if (top) { nested_ = false; if (!found_) os << "char"; // Empty compositor. } } virtual Void traverse (SemanticGraph::List&) { align_type ("size_t"); } virtual Void traverse (SemanticGraph::Union&) { align_type ("size_t"); // std::string } virtual Void traverse (SemanticGraph::Complex& c) { // Keep track of the nested calls for base types. // Boolean top (false); if (!nested_) { nested_ = true; top = true; } Complex::inherits (c, inherits_); if (!found_) { Complex::names (c, attribute_names_); if (!found_ && c.contains_compositor_p ()) Complex::contains_compositor (c, contains_compositor_); } if (top) { nested_ = false; if (!found_) os << "char"; // Empty class. } } // anyType & anySimpleType. // virtual Void traverse (SemanticGraph::AnyType&) { align_type ("char"); } virtual Void traverse (SemanticGraph::AnySimpleType&) { align_type ("char"); } // Boolean. // virtual Void traverse (SemanticGraph::Fundamental::Boolean&) { align_type ("bool"); } // Integral types. // virtual Void traverse (SemanticGraph::Fundamental::Byte&) { align_type ("signed char"); } virtual Void traverse (SemanticGraph::Fundamental::UnsignedByte&) { align_type ("unsigned char"); } virtual Void traverse (SemanticGraph::Fundamental::Short&) { align_type ("short"); } virtual Void traverse (SemanticGraph::Fundamental::UnsignedShort&) { align_type ("unsigned short"); } virtual Void traverse (SemanticGraph::Fundamental::Int&) { align_type ("int"); } virtual Void traverse (SemanticGraph::Fundamental::UnsignedInt&) { align_type ("unsigned int"); } virtual Void traverse (SemanticGraph::Fundamental::Long&) { align_type (options.value () ? "long" : "long long"); } virtual Void traverse (SemanticGraph::Fundamental::UnsignedLong&) { align_type (options.value () ? "unsigned long" : "unsigned long long"); } virtual Void traverse (SemanticGraph::Fundamental::Integer&) { align_type ("long"); } virtual Void traverse (SemanticGraph::Fundamental::NonPositiveInteger&) { align_type ("long"); } virtual Void traverse (SemanticGraph::Fundamental::NonNegativeInteger&) { align_type ("unsigned long"); } virtual Void traverse (SemanticGraph::Fundamental::PositiveInteger&) { align_type ("unsigned long"); } virtual Void traverse (SemanticGraph::Fundamental::NegativeInteger&) { align_type ("long"); } // Floats. // virtual Void traverse (SemanticGraph::Fundamental::Float&) { align_type ("float"); } virtual Void traverse (SemanticGraph::Fundamental::Double&) { align_type ("double"); } virtual Void traverse (SemanticGraph::Fundamental::Decimal&) { align_type ("double"); } // Strings. // virtual Void traverse (SemanticGraph::Fundamental::String&) { align_type ("size_t"); // std::string } virtual Void traverse (SemanticGraph::Fundamental::NormalizedString&) { align_type ("size_t"); // std::string } virtual Void traverse (SemanticGraph::Fundamental::Token&) { align_type ("size_t"); // std::string } virtual Void traverse (SemanticGraph::Fundamental::NameToken&) { align_type ("size_t"); // std::string } virtual Void traverse (SemanticGraph::Fundamental::Name&) { align_type ("size_t"); // std::string } virtual Void traverse (SemanticGraph::Fundamental::NCName&) { align_type ("size_t"); // std::string } virtual Void traverse (SemanticGraph::Fundamental::Language&) { align_type ("size_t"); // std::string } // Qualified name. // virtual Void traverse (SemanticGraph::Fundamental::QName&) { align_type ("size_t"); // std::string } // ID/IDREF. // virtual Void traverse (SemanticGraph::Fundamental::Id&) { align_type ("size_t"); // std::string } virtual Void traverse (SemanticGraph::Fundamental::IdRef&) { align_type ("size_t"); // std::string } // URI. // virtual Void traverse (SemanticGraph::Fundamental::AnyURI&) { align_type ("size_t"); // std::string } // Date/time. // virtual Void traverse (SemanticGraph::Fundamental::Date&) { align_type ("bool"); } virtual Void traverse (SemanticGraph::Fundamental::DateTime&) { align_type ("bool"); } virtual Void traverse (SemanticGraph::Fundamental::Duration&) { align_type ("bool"); } virtual Void traverse (SemanticGraph::Fundamental::Day&) { align_type ("bool"); } virtual Void traverse (SemanticGraph::Fundamental::Month&) { align_type ("bool"); } virtual Void traverse (SemanticGraph::Fundamental::MonthDay&) { align_type ("bool"); } virtual Void traverse (SemanticGraph::Fundamental::Year&) { align_type ("bool"); } virtual Void traverse (SemanticGraph::Fundamental::YearMonth&) { align_type ("bool"); } virtual Void traverse (SemanticGraph::Fundamental::Time&) { align_type ("bool"); } // Entity. // virtual Void traverse (SemanticGraph::Fundamental::Entity&) { align_type ("size_t"); // std::string } private: Void align_type (Char const* t) { if (!found_) { os << t; found_ = true; } } private: Boolean found_; Boolean nested_; private: Traversal::Inherits inherits_; Traversal::Attribute attribute_; Traversal::Names attribute_names_; Traversal::Element particle_; Traversal::ContainsParticle contains_particle_; Traversal::ContainsCompositor contains_compositor_; Traversal::Belongs belongs_; }; struct AttributeData: Traversal::Attribute, Context { AttributeData (Context& c) : Context (c), var_ (c, TypeName::var) { } virtual Void traverse (SemanticGraph::Attribute& a) { SemanticGraph::Type& t (a.type ()); var_.dispatch (t); os << " " << emember (a) << ";"; if (a.optional () && fixed_length (t)) os << "bool " << epresent_member (a) << ";"; } private: TypeName var_; }; struct ElementData: Traversal::Element, Context { ElementData (Context& c) : Context (c), var_ (c, TypeName::var) { } virtual Void traverse (SemanticGraph::Element& e) { if (e.max () != 1) { os << esequence (e) << " " << emember (e) << ";"; } else { SemanticGraph::Type& t (e.type ()); var_.dispatch (t); os << " " << emember (e) << ";"; if (e.min () == 0 && fixed_length (t)) os << "bool " << epresent_member (e) << ";"; } } private: TypeName var_; }; struct ElementInChoiceData: Traversal::Element, Context { ElementInChoiceData (Context& c) : Context (c), var_ (c, TypeName::var), align_type_ (c) { } virtual Void traverse (SemanticGraph::Element& e) { if (e.max () != 1) { os << "union" << "{" << "size_t align_;" << "char data_[sizeof (" << esequence (e) << ")];" << "} " << emember (e) << ";"; } else { SemanticGraph::Type& t (e.type ()); if (fixed_length (t)) { os << "union" << "{"; align_type_.dispatch (t); os << " align_;" << "char data_[sizeof ("; var_.dispatch (t); os << ")"; // Reserve an extra byte for the present flag. // if (e.min () == 0) os << " + 1"; os << "];" << "} " << emember (e) << ";"; } else { var_.dispatch (t); os << " " << emember (e) << ";"; } } } private: TypeName var_; AlignType align_type_; }; struct AllData: Traversal::All, Context { AllData (Context& c) : Context (c) { } virtual Void traverse (SemanticGraph::All& a) { // For the all compositor, maxOccurs=1 and minOccurs={0,1} // and it can only contain particles. // if (a.min () == 0) { String const& type (etype (a)); String const& member (emember(a)); if (fixed_length (a)) { os << type << " " << member << ";" << "bool " << epresent_member (a) << ";"; } else os << type << "* " << member << ";"; } else All::contains (a); } }; struct ChoiceInSequenceData: Traversal::Choice, Context { ChoiceInSequenceData (Context& c) : Context (c) { } virtual Void traverse (SemanticGraph::Choice& c) { if (c.max () != 1) { os << esequence (c) << " " << emember (c) << ";"; } else if (c.min () == 0) { String const& type (etype (c)); String const& member (emember (c)); if (fixed_length (c)) os << type << " " << member << ";" << "bool " << epresent_member (c) << ";"; else os << type << "* " << member << ";"; } else { os << "union" << "{"; Choice::contains (c); os << "} " << emember (c) << ";" << earm_tag (c) << " " << earm_member (c) << ";"; } } }; struct ChoiceInChoiceData: Traversal::Choice, Context { ChoiceInChoiceData (Context& c) : Context (c), align_type_ (c) { } virtual Void traverse (SemanticGraph::Choice& c) { // For choice in choice we always have a nested class. // if (c.max () != 1) { os << "union" << "{" << "size_t align_;" << "char data_[sizeof (" << esequence (c) << ")];" << "} " << emember (c) << ";"; } else { if (fixed_length (c)) { os << "union" << "{"; align_type_.dispatch (c); os << " align_;" << "char data_[sizeof (" << etype (c) << ")"; // Reserve an extra byte for the present flag. // if (c.min () == 0) os << " + 1"; os << "];" << "} " << emember (c) << ";"; } else os << etype (c) << "* " << emember (c) << ";"; } } private: AlignType align_type_; }; struct SequenceInSequenceData: Traversal::Sequence, Context { SequenceInSequenceData (Context& c) : Context (c) { } virtual Void traverse (SemanticGraph::Sequence& s) { if (s.max () != 1) { os << esequence (s) << " " << emember (s) << ";"; } else if (s.min () == 0) { String const& type (etype (s)); String const& member (emember (s)); if (fixed_length (s)) os << type << " " << member << ";" << "bool " << epresent_member (s) << ";"; else os << type << "* " << member << ";"; } else Sequence::contains (s); } }; struct SequenceInChoiceData: Traversal::Sequence, Context { SequenceInChoiceData (Context& c) : Context (c), align_type_ (c) { } virtual Void traverse (SemanticGraph::Sequence& s) { // For sequence in choice we always have a nested class. // if (s.max () != 1) { os << "union" << "{" << "size_t align_;" << "char data_[sizeof (" << esequence (s) << ")];" << "} " << emember (s) << ";"; } else { if (fixed_length (s)) { os << "union" << "{"; align_type_.dispatch (s); os << " align_;" << "char data_[sizeof (" << etype (s) << ")"; // Reserve an extra byte for the present flag. // if (s.min () == 0) os << " + 1"; os << "];" << "} " << emember (s) << ";"; } else os << etype (s) << "* " << emember (s) << ";"; } } private: AlignType align_type_; }; // // Accessors/modifiers. // struct Attribute: Traversal::Attribute, Context { Attribute (Context& c) : Context (c), ro_ret_ (c, TypeName::ro_ret), ret_ (c, TypeName::ret), arg_ (c, TypeName::arg) { } virtual Void traverse (SemanticGraph::Attribute& a) { os << "// " << comment (a.name ()) << endl << "// " << endl; String const& name (ename (a)); SemanticGraph::Type& t (a.type ()); if (a.optional ()) { String const& present (epresent (a)); os << "bool" << endl << present << " () const;" << endl; os << "void" << endl << present << " (bool);" << endl; } // const type& // name () const // ro_ret_.dispatch (t); os << endl << name << " () const;" << endl; // type& // name () // ret_.dispatch (t); os << endl << name << " ();" << endl; // void // name (const type& | type*) // os << "void" << endl << name << " ("; arg_.dispatch (t); os << ");" << endl; } private: TypeName ro_ret_; TypeName ret_; TypeName arg_; }; struct Element: Traversal::Element, virtual Context { Element (Context& c) : Context (c), seq_ (c, TypeName::seq), ro_ret_ (c, TypeName::ro_ret), ret_ (c, TypeName::ret), arg_ (c, TypeName::arg) { } virtual Void traverse (SemanticGraph::Element& e) { os << "// " << comment (e.name ()) << endl << "// " << endl; String const& name (ename (e)); SemanticGraph::Type& t (e.type ()); if (e.max () != 1) { String const& sequence (esequence (e)); String const& iterator (eiterator (e)); String const& const_iterator (econst_iterator (e)); // sequence & iterators // os << "typedef "; seq_.dispatch (t); os << " " << sequence << ";" << "typedef " << sequence << "::iterator " << iterator << ";" << "typedef " << sequence << "::const_iterator " << const_iterator << ";" << endl; // const seq& // name () const // os << "const " << sequence << "&" << endl << name << " () const;" << endl; // seq& // name () // os << sequence << "&" << endl << name << " ();" << endl; } else { if (e.min () == 0) { // optional // String const& present (epresent (e)); os << "bool" << endl << present << " () const;" << endl; os << "void" << endl << present << " (bool);" << endl; } // const type& // name () const // ro_ret_.dispatch (t); os << endl << name << " () const;" << endl; // type& // name () // ret_.dispatch (t); os << endl << name << " ();" << endl; // void // name (const type& | type*) // os << "void" << endl << name << " ("; arg_.dispatch (t); os << ");" << endl; } } private: TypeName seq_; TypeName ro_ret_; TypeName ret_; TypeName arg_; }; struct All: Traversal::All, Context { All (Context& c, Traversal::ContainsParticle& contains_data) : Context (c), contains_data_ (contains_data) { } virtual Void traverse (SemanticGraph::All& a) { // For the all compositor, maxOccurs=1 and minOccurs={0,1} // and it can only contain particles. // if (a.min () == 0) { Boolean fl (fixed_length (a)); Boolean cd (a.context ().count ("cd-name")); String const& name (ename (a)); String const& type (etype (a)); String const& present (epresent (a)); os << "// " << comment (name) << " (" << (fl ? "fixed-length" : "variable-length") << ")" << endl << "// " << endl; os << "class " << type << "{"; // c-tor & d-tor // os << "public:" << endl << type << " ();" << "~" << type << " ();"; // copy c-tor & operator= // if (!fl) os << endl << "private:" << endl; os << type << " (const " << type << "&);" << type << "& operator= (const " << type << "&);" << endl; if (!fl) os << "public:" << endl; All::contains (a); // Custom data. // if (cd) { String const& name (ecd_name (a)); String const& sequence (ecd_sequence (a)); String const& iterator (ecd_iterator (a)); String const& const_iterator (ecd_const_iterator (a)); os << "// Custom data." << endl << "//" << endl; // sequence & iterators // os << "typedef ::xsde::cxx::hybrid::data_seq " << sequence << ";" << "typedef " << sequence << "::iterator " << iterator << ";" << "typedef " << sequence << "::const_iterator " << const_iterator << ";" << endl; // const seq& // name () const // os << "const " << sequence << "&" << endl << name << " () const;" << endl; // seq& // name () // os << sequence << "&" << endl << name << " ();" << endl; } os << "private:" << endl; All::contains (a, contains_data_); // Custom data. // if (cd) os << ecd_sequence (a) << " " << ecd_member (a) << ";"; os << "};"; // name_present // os << "bool" << endl << present << " () const;" << endl; os << "void" << endl << present << " (bool);" << endl; // const type& // name () const // os << "const " << type << "&" << endl << name << " () const;" << endl; // type& // name () // os << type << "&" << endl << name << " ();" << endl; // void // name (const type& | type*) // os << "void" << endl << name << " ("; if (fl) os << "const " << type << "&"; else os << type << "*"; os << ");" << endl; } else All::contains (a); } private: Traversal::ContainsParticle& contains_data_; }; struct ParticleTag: Traversal::Element, Traversal::Any, Traversal::Choice, Traversal::Sequence, Context { ParticleTag (Context& c) : Context (c), first_ (true) { } virtual Void traverse (SemanticGraph::Element& e) { emit_tag (etag (e)); } virtual Void traverse (SemanticGraph::Any& a) { emit_tag (etag (a)); } virtual Void traverse (SemanticGraph::Choice& c) { emit_tag (etag (c)); } virtual Void traverse (SemanticGraph::Sequence& s) { emit_tag (etag (s)); } virtual Void emit_tag (String const& tag) { if (first_) first_ = false; else os << "," << endl; os << tag; } private: Boolean first_; }; struct ChoiceInSequence: Traversal::Choice, Context { ChoiceInSequence (Context& c, Traversal::ContainsParticle& contains_data) : Context (c), contains_data_ (contains_data) { } virtual Void traverse (SemanticGraph::Choice& c) { UnsignedLong min (c.min ()), max (c.max ()); String const& name (ename (c)); Boolean fl; String type; if (max != 1 || min == 0) { type = etype (c); fl = fixed_length (c); os << "// " << comment (name) << " (" << (fl ? "fixed-length" : "variable-length") << ")" << endl << "// " << endl; os << "class " << type << "{"; // c-tor & d-tor // os << "public:" << endl << type << " ();" << "~" << type << " ();"; // copy c-tor & operator= // if (!fl) os << endl << "private:" << endl; os << type << " (const " << type << "&);" << type << "& operator= (const " << type << "&);" << endl; if (!fl) os << "public:" << endl; } else { os << "// " << comment (name) << endl << "// " << endl; } String const& arm_tag (earm_tag (c)); String const& arm (earm (c)); os << "enum " << arm_tag << "{"; { ParticleTag particle (*this); Traversal::ContainsParticle contains_particle (particle); Traversal::Choice::contains (c, contains_particle); } os << "};"; // arm_tag // arm () const; // os << arm_tag << endl << arm << " () const;" << endl; // void // arm (arm_tag); // os << "void" << endl << arm << " (" << arm_tag << ");" << endl; Choice::contains (c); if (max != 1 || min == 0) { Boolean cd (c.context ().count ("cd-name")); // Custom data. // if (cd) { String const& name (ecd_name (c)); String const& sequence (ecd_sequence (c)); String const& iterator (ecd_iterator (c)); String const& const_iterator (ecd_const_iterator (c)); os << "// Custom data." << endl << "//" << endl; // sequence & iterators // os << "typedef ::xsde::cxx::hybrid::data_seq " << sequence << ";" << "typedef " << sequence << "::iterator " << iterator << ";" << "typedef " << sequence << "::const_iterator " << const_iterator << ";" << endl; // const seq& // name () const // os << "const " << sequence << "&" << endl << name << " () const;" << endl; // seq& // name () // os << sequence << "&" << endl << name << " ();" << endl; } os << "private:" << endl << "union" << "{"; Choice::contains (c, contains_data_); os << "} " << emember (c) << ";" << arm_tag << " " << earm_member (c) << ";"; // Custom data. // if (cd) os << ecd_sequence (c) << " " << ecd_member (c) << ";"; os << "};"; } if (max != 1) { String const& sequence (esequence (c)); String const& iterator (eiterator (c)); String const& const_iterator (econst_iterator (c)); // sequence & iterators // os << "typedef ::xsde::cxx::hybrid::"; if (fl) os << "fix_seq"; else os << "var_seq"; os << "< " << type << " > " << sequence << ";" << "typedef " << sequence << "::iterator " << iterator << ";" << "typedef " << sequence << "::const_iterator " << const_iterator << ";" << endl; // const seq& // name () const // os << "const " << sequence << "&" << endl << name << " () const;" << endl; // seq& // name () // os << sequence << "&" << endl << name << " ();" << endl; } else if (min == 0) { String const& present (epresent (c)); // name_present // os << "bool" << endl << present << " () const;" << endl; os << "void" << endl << present << " (bool);" << endl; // const type& // name () const // os << "const " << type << "&" << endl << name << " () const;" << endl; // type& // name () // os << type << "&" << endl << name << " ();" << endl; // void // name (const type& | type*) // os << "void" << endl << name << " ("; if (fl) os << "const " << type << "&"; else os << type << "*"; os << ");" << endl; } } private: Traversal::ContainsParticle& contains_data_; }; struct ChoiceInChoice: Traversal::Choice, Context { ChoiceInChoice (Context& c, Traversal::ContainsParticle& contains_data) : Context (c), contains_data_ (contains_data) { } virtual Void traverse (SemanticGraph::Choice& c) { // When shoice is in choice we generate nested class even // for min == max == 1. // UnsignedLong min (c.min ()), max (c.max ()); Boolean fl (fixed_length (c)); Boolean cd (c.context ().count ("cd-name")); String const& name (ename (c)); String const& type (etype (c)); os << "// " << comment (name) << " (" << (fl ? "fixed-length" : "variable-length") << ")" << endl << "// " << endl; os << "class " << type << "{"; // c-tor & d-tor // os << "public:" << endl << type << " ();" << "~" << type << " ();"; // copy c-tor & operator= // if (!fl) os << endl << "private:" << endl; os << type << " (const " << type << "&);" << type << "& operator= (const " << type << "&);" << endl; if (!fl) os << "public:" << endl; String const& arm_tag (earm_tag (c)); String const& arm (earm (c)); os << "enum " << arm_tag << "{"; { ParticleTag particle (*this); Traversal::ContainsParticle contains_particle (particle); Traversal::Choice::contains (c, contains_particle); } os << "};"; // arm_tag // arm () const; // os << arm_tag << endl << arm << " () const;" << endl; // void // arm (arm_tag); // os << "void" << endl << arm << " (" << arm_tag << ");" << endl; Choice::contains (c); // Custom data. // if (cd) { String const& name (ecd_name (c)); String const& sequence (ecd_sequence (c)); String const& iterator (ecd_iterator (c)); String const& const_iterator (ecd_const_iterator (c)); os << "// Custom data." << endl << "//" << endl; // sequence & iterators // os << "typedef ::xsde::cxx::hybrid::data_seq " << sequence << ";" << "typedef " << sequence << "::iterator " << iterator << ";" << "typedef " << sequence << "::const_iterator " << const_iterator << ";" << endl; // const seq& // name () const // os << "const " << sequence << "&" << endl << name << " () const;" << endl; // seq& // name () // os << sequence << "&" << endl << name << " ();" << endl; } os << "private:" << endl << "union" << "{"; Choice::contains (c, contains_data_); os << "} " << emember (c) << ";" << arm_tag << " " << earm_member (c) << ";"; // Custom data. // if (cd) os << ecd_sequence (c) << " " << ecd_member (c) << ";"; os << "};"; if (max != 1) { String const& sequence (esequence (c)); String const& iterator (eiterator (c)); String const& const_iterator (econst_iterator (c)); // sequence & iterators // os << "typedef ::xsde::cxx::hybrid::"; if (fl) os << "fix_seq"; else os << "var_seq"; os << "< " << type << " > " << sequence << ";" << "typedef " << sequence << "::iterator " << iterator << ";" << "typedef " << sequence << "::const_iterator " << const_iterator << ";" << endl; // const seq& // name () const // os << "const " << sequence << "&" << endl << name << " () const;" << endl; // seq& // name () // os << sequence << "&" << endl << name << " ();" << endl; } else { if (min == 0) { String const& present (epresent (c)); // name_present // os << "bool" << endl << present << " () const;" << endl; os << "void" << endl << present << " (bool);" << endl; } // const type& // name () const // os << "const " << type << "&" << endl << name << " () const;" << endl; // type& // name () // os << type << "&" << endl << name << " ();" << endl; // void // name (const type& | type*) // os << "void" << endl << name << " ("; if (fl) os << "const " << type << "&"; else os << type << "*"; os << ");" << endl; } } private: Traversal::ContainsParticle& contains_data_; }; struct SequenceInSequence: Traversal::Sequence, Context { SequenceInSequence (Context& c, Traversal::ContainsParticle& contains_data) : Context (c), contains_data_ (contains_data) { } virtual Void traverse (SemanticGraph::Sequence& s) { UnsignedLong min (s.min ()), max (s.max ()); if (max == 1 && min == 1) { Sequence::contains (s); return; } Boolean fl (fixed_length (s)); Boolean cd (s.context ().count ("cd-name")); String const& name (ename (s)); String const& type (etype (s)); os << "// " << comment (name) << " (" << (fl ? "fixed-length" : "variable-length") << ")" << endl << "// " << endl; os << "class " << type << "{"; // c-tor & d-tor // os << "public:" << endl << type << " ();" << "~" << type << " ();"; // copy c-tor & operator= // if (!fl) os << endl << "private:" << endl; os << type << " (const " << type << "&);" << type << "& operator= (const " << type << "&);" << endl; if (!fl) os << "public:" << endl; Sequence::contains (s); // Custom data. // if (cd) { String const& name (ecd_name (s)); String const& sequence (ecd_sequence (s)); String const& iterator (ecd_iterator (s)); String const& const_iterator (ecd_const_iterator (s)); os << "// Custom data." << endl << "//" << endl; // sequence & iterators // os << "typedef ::xsde::cxx::hybrid::data_seq " << sequence << ";" << "typedef " << sequence << "::iterator " << iterator << ";" << "typedef " << sequence << "::const_iterator " << const_iterator << ";" << endl; // const seq& // name () const // os << "const " << sequence << "&" << endl << name << " () const;" << endl; // seq& // name () // os << sequence << "&" << endl << name << " ();" << endl; } os << "private:" << endl; Sequence::contains (s, contains_data_); // Custom data. // if (cd) os << ecd_sequence (s) << " " << ecd_member (s) << ";"; os << "};"; if (max != 1) { String const& sequence (esequence (s)); String const& iterator (eiterator (s)); String const& const_iterator (econst_iterator (s)); // sequence & iterators // os << "typedef ::xsde::cxx::hybrid::"; if (fl) os << "fix_seq"; else os << "var_seq"; os << "< " << type << " > " << sequence << ";" << "typedef " << sequence << "::iterator " << iterator << ";" << "typedef " << sequence << "::const_iterator " << const_iterator << ";" << endl; // const seq& // name () const // os << "const " << sequence << "&" << endl << name << " () const;" << endl; // seq& // name () // os << sequence << "&" << endl << name << " ();" << endl; } else if (min == 0) { String const& present (epresent (s)); // name_present // os << "bool" << endl << present << " () const;" << endl; os << "void" << endl << present << " (bool);" << endl; // const type& // name () const // os << "const " << type << "&" << endl << name << " () const;" << endl; // type& // name () // os << type << "&" << endl << name << " ();" << endl; // void // name (const type& | type*) // os << "void" << endl << name << " ("; if (fl) os << "const " << type << "&"; else os << type << "*"; os << ");" << endl; } } private: Traversal::ContainsParticle& contains_data_; }; struct SequenceInChoice: Traversal::Sequence, Context { SequenceInChoice (Context& c, Traversal::ContainsParticle& contains_data) : Context (c), contains_data_ (contains_data) { } virtual Void traverse (SemanticGraph::Sequence& s) { // When sequence is in choice we generate nested class even // for min == max == 1. // Boolean fl (fixed_length (s)); Boolean cd (s.context ().count ("cd-name")); String const& name (ename (s)); String const& type (etype (s)); os << "// " << comment (name) << " (" << (fl ? "fixed-length" : "variable-length") << ")" << endl << "// " << endl; os << "class " << type << "{"; // c-tor & d-tor // os << "public:" << endl << type << " ();" << "~" << type << " ();"; // copy c-tor & operator= // if (!fl) os << endl << "private:" << endl; os << type << " (const " << type << "&);" << type << "& operator= (const " << type << "&);" << endl; if (!fl) os << "public:" << endl; Sequence::contains (s); if (cd) { String const& name (ecd_name (s)); String const& sequence (ecd_sequence (s)); String const& iterator (ecd_iterator (s)); String const& const_iterator (ecd_const_iterator (s)); os << "// Custom data." << endl << "//" << endl; // sequence & iterators // os << "typedef ::xsde::cxx::hybrid::data_seq " << sequence << ";" << "typedef " << sequence << "::iterator " << iterator << ";" << "typedef " << sequence << "::const_iterator " << const_iterator << ";" << endl; // const seq& // name () const // os << "const " << sequence << "&" << endl << name << " () const;" << endl; // seq& // name () // os << sequence << "&" << endl << name << " ();" << endl; } os << "private:" << endl; Sequence::contains (s, contains_data_); // Custom data. // if (cd) os << ecd_sequence (s) << " " << ecd_member (s) << ";"; os << "};"; if (s.max () != 1) { String const& sequence (esequence (s)); String const& iterator (eiterator (s)); String const& const_iterator (econst_iterator (s)); // sequence & iterators // os << "typedef ::xsde::cxx::hybrid::"; if (fl) os << "fix_seq"; else os << "var_seq"; os << "< " << type << " > " << sequence << ";" << "typedef " << sequence << "::iterator " << iterator << ";" << "typedef " << sequence << "::const_iterator " << const_iterator << ";" << endl; // const seq& // name () const // os << "const " << sequence << "&" << endl << name << " () const;" << endl; // seq& // name () // os << sequence << "&" << endl << name << " ();" << endl; } else { if (s.min () == 0) { String const& present (epresent (s)); // name_present // os << "bool" << endl << present << " () const;" << endl; os << "void" << endl << present << " (bool);" << endl; } // const type& // name () const // os << "const " << type << "&" << endl << name << " () const;" << endl; // type& // name () // os << type << "&" << endl << name << " ();" << endl; // void // name (const type& | type*) // os << "void" << endl << name << " ("; if (fl) os << "const " << type << "&"; else os << type << "*"; os << ");" << endl; } } private: Traversal::ContainsParticle& contains_data_; }; struct Complex : Traversal::Complex, Context { Complex (Context& c) : Context (c), base_name_ (c, TypeName::base), // Data. // attribute_data_ (c), element_data_ (c), element_in_choice_data_ (c), all_data_ (c), choice_in_choice_data_ (c), choice_in_sequence_data_ (c), sequence_in_choice_data_ (c), sequence_in_sequence_data_ (c), // Functions and nested classes. // attribute_ (c), element_ (c), all_ (c, all_contains_data_), choice_in_choice_ (c, choice_contains_data_), choice_in_sequence_ (c, choice_contains_data_), sequence_in_choice_ (c, sequence_contains_data_), sequence_in_sequence_ (c, sequence_contains_data_) { // Data // attribute_names_data_ >> attribute_data_; all_data_ >> all_contains_data_ >> element_data_; sequence_in_choice_data_ >> sequence_contains_data_; sequence_in_sequence_data_ >> sequence_contains_data_; sequence_contains_data_ >> element_data_; sequence_contains_data_ >> choice_in_sequence_data_; sequence_contains_data_ >> sequence_in_sequence_data_; choice_in_choice_data_ >> choice_contains_data_; choice_in_sequence_data_ >> choice_contains_data_; choice_contains_data_ >> element_in_choice_data_; choice_contains_data_ >> choice_in_choice_data_; choice_contains_data_ >> sequence_in_choice_data_; contains_compositor_data_ >> all_data_; contains_compositor_data_ >> choice_in_sequence_data_; contains_compositor_data_ >> sequence_in_sequence_data_; // Functions and nested classes. // attribute_names_ >> attribute_; all_ >> all_contains_ >> element_; choice_in_choice_ >> choice_contains_; choice_in_sequence_ >> choice_contains_; choice_contains_ >> element_; choice_contains_ >> choice_in_choice_; choice_contains_ >> sequence_in_choice_; sequence_in_choice_ >> sequence_contains_; sequence_in_sequence_ >> sequence_contains_; sequence_contains_ >> element_; sequence_contains_ >> choice_in_sequence_; sequence_contains_ >> sequence_in_sequence_; contains_compositor_ >> all_; contains_compositor_ >> choice_in_sequence_; contains_compositor_ >> sequence_in_sequence_; } virtual Void traverse (Type& c) { String name (ename (c)); Boolean fl (fixed_length (c)); Boolean restriction (restriction_p (c)); Boolean cd (c.context ().count ("cd-name")); os << "// " << comment (c.name ()) << " (" << (fl ? "fixed-length" : "variable-length") << ")" << endl << "//" << endl; os << "class " << name; if (c.inherits_p ()) { os << ": public "; base_name_.dispatch (c.inherits ().base ()); } os << "{"; // c-tor // os << "public:" << endl << name << " ();"; // d-tor // if (!restriction) os << "~" << name << " ();"; // copy c-tor & operator= // if (!fl) os << endl << "private:" << endl; if (!fl || !restriction) os << name << " (const " << name << "&);" << name << "& operator= (const " << name << "&);" << endl; if ((!restriction && !fl) || cd) os << "public:" << endl; if (!restriction) { Complex::names (c, attribute_names_); if (c.contains_compositor_p ()) Complex::contains_compositor (c, contains_compositor_); } // Custom data. // if (cd) { String const& name (ecd_name (c)); String const& sequence (ecd_sequence (c)); String const& iterator (ecd_iterator (c)); String const& const_iterator (ecd_const_iterator (c)); os << "// Custom data." << endl << "//" << endl; // sequence & iterators // os << "typedef ::xsde::cxx::hybrid::data_seq " << sequence << ";" << "typedef " << sequence << "::iterator " << iterator << ";" << "typedef " << sequence << "::const_iterator " << const_iterator << ";" << endl; // const seq& // name () const // os << "const " << sequence << "&" << endl << name << " () const;" << endl; // seq& // name () // os << sequence << "&" << endl << name << " ();" << endl; } if (!restriction || cd) os << "private:" << endl; if (!restriction) { Complex::names (c, attribute_names_data_); if (c.contains_compositor_p ()) Complex::contains_compositor (c, contains_compositor_data_); } // Custom data. // if (cd) os << ecd_sequence (c) << " " << ecd_member (c) << ";"; os << "};"; } private: TypeName base_name_; // Data. // AttributeData attribute_data_; Traversal::Names attribute_names_data_; ElementData element_data_; ElementInChoiceData element_in_choice_data_; AllData all_data_; ChoiceInChoiceData choice_in_choice_data_; ChoiceInSequenceData choice_in_sequence_data_; SequenceInChoiceData sequence_in_choice_data_; SequenceInSequenceData sequence_in_sequence_data_; Traversal::ContainsParticle all_contains_data_; Traversal::ContainsParticle choice_contains_data_; Traversal::ContainsParticle sequence_contains_data_; Traversal::ContainsCompositor contains_compositor_data_; // Functions and nested classes. // Attribute attribute_; Traversal::Names attribute_names_; Element element_; All all_; ChoiceInChoice choice_in_choice_; ChoiceInSequence choice_in_sequence_; SequenceInChoice sequence_in_choice_; SequenceInSequence sequence_in_sequence_; Traversal::ContainsParticle all_contains_; Traversal::ContainsParticle choice_contains_; Traversal::ContainsParticle sequence_contains_; Traversal::ContainsCompositor contains_compositor_; }; } Void generate_tree_header (Context& ctx) { ctx.os << "#include " << endl << endl; Boolean inline_ (ctx.options.value ()); // Emit header includes. // { if (inline_) { ctx.os << "#ifndef XSDE_DONT_INCLUDE_INLINE" << endl << "#define XSDE_DONT_INCLUDE_INLINE" << endl << endl; } Traversal::Schema schema; Includes includes (ctx, Includes::header); schema >> includes; schema.dispatch (ctx.schema_root); if (inline_) { ctx.os << "#undef XSDE_DONT_INCLUDE_INLINE" << endl << "#else" << endl << endl; schema.dispatch (ctx.schema_root); ctx.os << "#endif // XSDE_DONT_INCLUDE_INLINE" << endl << endl; } } { Traversal::Schema schema; Traversal::Sources sources; Traversal::Names names_ns, names; Namespace ns (ctx); List list (ctx); Union union_ (ctx); Complex complex (ctx); //Enumeration enumeration (ctx); schema >> sources >> schema; schema >> names_ns >> ns >> names; names >> list; names >> union_; names >> complex; //names >> enumeration; schema.dispatch (ctx.schema_root); } // Emit inline includes. // if (inline_) { ctx.os << "#ifndef XSDE_DONT_INCLUDE_INLINE" << endl << endl; Traversal::Schema schema; Includes ixx_includes (ctx, Includes::inline_); schema >> ixx_includes; schema.dispatch (ctx.schema_root); ctx.os << "#endif // XSDE_DONT_INCLUDE_INLINE" << endl << endl; } } } }