summaryrefslogtreecommitdiff
path: root/xsd/xsd/cxx/parser/parser-header.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'xsd/xsd/cxx/parser/parser-header.cxx')
-rw-r--r--xsd/xsd/cxx/parser/parser-header.cxx1440
1 files changed, 1440 insertions, 0 deletions
diff --git a/xsd/xsd/cxx/parser/parser-header.cxx b/xsd/xsd/cxx/parser/parser-header.cxx
new file mode 100644
index 0000000..327bb07
--- /dev/null
+++ b/xsd/xsd/cxx/parser/parser-header.cxx
@@ -0,0 +1,1440 @@
+// file : xsd/cxx/parser/parser-header.cxx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <set>
+
+#include <xsd/cxx/parser/parser-header.hxx>
+
+#include <libxsd-frontend/semantic-graph.hxx>
+#include <libxsd-frontend/traversal.hxx>
+
+using namespace std;
+
+namespace CXX
+{
+ namespace Parser
+ {
+ namespace
+ {
+ struct Enumeration: Traversal::Enumeration, Context
+ {
+ Enumeration (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual void
+ traverse (Type& e)
+ {
+ String const& name (ename (e));
+ SemanticGraph::Type& base (e.inherits ().base ());
+
+ os << "class " << type_exp << name << ": public virtual " <<
+ fq_name (base)
+ << "{"
+ << "public:" << endl
+ << "// Parser callbacks. Override them in your " <<
+ "implementation." << endl
+ << "//" << endl;
+
+ os << "// virtual void" << endl
+ << "// pre ();" << endl
+ << endl;
+
+ String const& ret (ret_type (e));
+
+ bool same (ret == ret_type (base));
+
+ os << "virtual " << ret << endl
+ << post_name (e) << " ()" <<
+ (same || ret == L"void" ? ";" : " = 0;");
+
+ if (polymorphic)
+ {
+ os << endl
+ << "public:" << endl
+ << "static const " << char_type << "*" << endl
+ << "_static_type ();"
+ << endl
+ << "virtual const " << char_type << "*" << endl
+ << "_dynamic_type () const;";
+ }
+
+ os << "};";
+ }
+ };
+
+ //
+ //
+ struct List: Traversal::List, Context
+ {
+ List (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual void
+ traverse (Type& l)
+ {
+ String const& name (ename (l));
+ SemanticGraph::Type& t (l.argumented ().type ());
+
+ String item (unclash (name, "item"));
+
+ os << "class " << type_exp << name << ": public " << list_base
+ << "{"
+ << "public:" << endl
+ << "// Parser callbacks. Override them in your " <<
+ "implementation." << endl
+ << "//" << endl;
+
+ // pre
+ //
+ os << "// virtual void" << endl
+ << "// pre ();" << endl
+ << endl;
+
+ // item
+ //
+ String const& arg (arg_type (t));
+
+ os << "virtual void" << endl
+ << item;
+
+ if (arg == L"void")
+ os << " ();";
+ else
+ os << " (" << arg << ");";
+
+ os << endl;
+
+ // post
+ //
+ String const& ret (ret_type (l));
+
+ os << "virtual " << ret << endl
+ << post_name (l) << " ()" << (ret == L"void" ? ";" : " = 0;")
+ << endl;
+
+ //
+ //
+ os << "// Parser construction API." << endl
+ << "//" << endl;
+
+ // item_parser
+ //
+ os << "void" << endl
+ << unclash (name, "item_parser") << " (" << fq_name (t) << "&);"
+ << endl;
+
+ // parsers
+ //
+ os << "void" << endl
+ << "parsers (" << fq_name (t) << "& /* item */);"
+ << endl;
+
+ // c-tor
+ //
+ os << "// Constructor." << endl
+ << "//" << endl
+ << name << " ();"
+ << endl;
+
+
+ if (polymorphic)
+ {
+ os << "public:" << endl
+ << "static const " << char_type << "*" << endl
+ << "_static_type ();"
+ << endl
+ << "virtual const " << char_type << "*" << endl
+ << "_dynamic_type () const;"
+ << endl;
+ }
+
+ //
+ //
+ os << "// Implementation." << endl
+ << "//" << endl
+ << "protected:" << endl;
+
+ os << "virtual void" << endl
+ << "_xsd_parse_item (const " << string_type << "&);"
+ << endl;
+
+ os << "protected:" << endl
+ << fq_name (t) << "* _xsd_" << item << "_;"
+ << "};";
+ }
+ };
+
+ struct Union: Traversal::Union, Context
+ {
+ Union (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual void
+ traverse (Type& u)
+ {
+ String const& name (ename (u));
+
+ os << "class " << type_exp << name << ": public " << simple_base
+ << "{"
+ << "public:" << endl
+ << "// Parser callbacks. Override them in your " <<
+ "implementation." << endl
+ << "//" << endl;
+
+ os << "// virtual void" << endl
+ << "// pre ();" << endl
+ << "//" << endl
+ << "// virtual void" << endl
+ << "// _characters (const " << string_type << "&);" << endl
+ << endl;
+
+ String const& ret (ret_type (u));
+
+ os << "virtual " << ret << endl
+ << post_name (u) << " ()" << (ret == L"void" ? ";" : " = 0;");
+
+ if (polymorphic)
+ {
+ os << endl
+ << "public:" << endl
+ << "static const " << char_type << "*" << endl
+ << "_static_type ();"
+ << endl
+ << "virtual const " << char_type << "*" << endl
+ << "_dynamic_type () const;";
+ }
+
+ os << "};";
+ }
+ };
+
+
+ //
+ //
+ struct ParserCallback: Traversal::Member, Context
+ {
+ ParserCallback (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual void
+ traverse (Type& m)
+ {
+ if (skip (m)) return;
+
+ String const& arg (arg_type (m.type ()));
+
+ os << "virtual void" << endl
+ << ename (m);
+
+ if (arg == L"void")
+ os << " ();";
+ else
+ os << " (" << arg << ");";
+
+ os << endl;
+ }
+ };
+
+
+ //
+ //
+ struct ParserModifier: Traversal::Member, Context
+ {
+ ParserModifier (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual void
+ traverse (Type& m)
+ {
+ if (skip (m))
+ return;
+
+ os << "void" << endl
+ << eparser (m) << " (" << fq_name (m.type ()) << "&);"
+ << endl;
+
+ if (polymorphic &&
+ m.is_a<SemanticGraph::Element> () &&
+ !anonymous (m.type ()))
+ {
+ os << "void" << endl
+ << eparser (m) << " (const " << parser_map << "&);"
+ << endl;
+ }
+ }
+ };
+
+ //
+ //
+ struct ParserMember: Traversal::Member, Context
+ {
+ ParserMember (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual void
+ traverse (Type& m)
+ {
+ if (skip (m))
+ return;
+
+ String type (fq_name (m.type ()));
+
+ os << type << "* " << emember (m) << ";";
+
+ if (polymorphic &&
+ m.is_a<SemanticGraph::Element> () &&
+ !anonymous (m.type ()))
+ {
+ os << "const " << parser_map << "* " << emember_map (m) << ";"
+ << endl;
+ }
+ }
+ };
+
+ //
+ //
+ struct Particle: Traversal::All,
+ Traversal::Choice,
+ Traversal::Sequence,
+ Context
+ {
+ Particle (Context& c)
+ : Context (c)
+ {
+ *this >> contains_particle_ >> *this;
+ }
+
+
+ virtual void
+ traverse (SemanticGraph::All& a)
+ {
+ if (!a.context().count ("comp-number"))
+ return;
+
+ size_t state_count (a.context().get<size_t> ("state-count"));
+
+ os << "void" << endl
+ << "all_0 (unsigned long& state," << endl
+ << "unsigned char* count," << endl
+ << "const " << string_type << "& ns," << endl
+ << "const " << string_type << "& n," << endl
+ << "const " << string_type << "* t," << endl
+ << "bool start);"
+ << endl
+ << "unsigned char v_all_first_[" << state_count << "UL];"
+ << "::xsd::cxx::parser::validating::all_stack v_all_count_;"
+ << endl;
+ }
+
+ virtual void
+ traverse (SemanticGraph::Choice& c)
+ {
+ if (!c.context().count ("comp-number"))
+ return;
+
+ size_t n (c.context ().get<size_t> ("comp-number"));
+
+ os << "void" << endl
+ << "choice_" << n << " (unsigned long& state," << endl
+ << "unsigned long& count," << endl
+ << "const " << string_type << "& ns," << endl
+ << "const " << string_type << "& n," << endl
+ << "const " << string_type << "* t," << endl
+ << "bool start);"
+ << endl;
+
+ Traversal::Choice::traverse (c);
+ }
+
+ virtual void
+ traverse (SemanticGraph::Sequence& s)
+ {
+ if (!s.context().count ("comp-number"))
+ return;
+
+ size_t n (s.context ().get<size_t> ("comp-number"));
+
+ os << "void" << endl
+ << "sequence_" << n << " (unsigned long& state," << endl
+ << "unsigned long& count," << endl
+ << "const " << string_type << "& ns," << endl
+ << "const " << string_type << "& n," << endl
+ << "const " << string_type << "* t," << endl
+ << "bool start);"
+ << endl;
+
+ Traversal::Sequence::traverse (s);
+ }
+
+ private:
+ Traversal::ContainsParticle contains_particle_;
+ };
+
+
+ //
+ //
+ struct AttributeValidationState: Traversal::Attribute, Context
+ {
+ AttributeValidationState (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual void
+ traverse (Type& a)
+ {
+ if (!a.optional_p ())
+ {
+ os << "bool " << ename (a) << ";";
+ }
+ }
+ };
+
+ //
+ //
+ struct Complex: Traversal::Complex, Context
+ {
+ Complex (Context& c)
+ : Context (c),
+ parser_callback_ (c),
+ parser_member_ (c),
+ parser_modifier_ (c),
+ attribute_validation_state_ (c)
+ {
+ names_parser_callback_ >> parser_callback_;
+ names_parser_member_ >> parser_member_;
+ names_parser_modifier_ >> parser_modifier_;
+ names_attribute_validation_state_ >> attribute_validation_state_;
+ }
+
+ virtual void
+ traverse (Type& c)
+ {
+ String const& name (ename (c));
+
+ // In case of an inheritance-by-restriction, we don't need to
+ // generate parser callbacks, etc. since they are the same as in
+ // the base. We only need the parsing/validation code.
+ //
+ bool restriction (restriction_p (c));
+
+ bool he (has<Traversal::Element> (c));
+ bool ha (has<Traversal::Attribute> (c));
+
+ bool hae (has_particle<Traversal::Any> (c));
+ bool haa (has<Traversal::AnyAttribute> (c));
+
+ bool hra (false); // Has required attribute.
+ if (ha)
+ {
+ RequiredAttributeTest test (hra);
+ Traversal::Names names_test (test);
+ names (c, names_test);
+ }
+
+
+ //
+ //
+ os << "class " << type_exp << name << ": public ";
+
+ if (c.inherits_p ())
+ os << "virtual " << fq_name (c.inherits ().base ());
+ else
+ os << complex_base;
+
+ os << "{"
+ << "public:" << endl
+ << "// Parser callbacks. Override them in your " <<
+ "implementation." << endl
+ << "//" << endl;
+
+ os << "// virtual void" << endl
+ << "// pre ();" << endl
+ << endl;
+
+
+ if (!restriction && (ha || he))
+ {
+ names (c, names_parser_callback_);
+ }
+
+ String const& ret (ret_type (c));
+
+ bool same (c.inherits_p () &&
+ ret == ret_type (c.inherits ().base ()));
+
+ os << "virtual " << ret << endl
+ << post_name (c) << " ()" <<
+ (same || ret == L"void" ? ";" : " = 0;")
+ << endl;
+
+ //
+ //
+ if (!restriction && (he || ha))
+ {
+ os << "// Parser construction API." << endl
+ << "//" << endl;
+
+ names (c, names_parser_modifier_);
+
+ os << "void" << endl
+ << "parsers (";
+
+ {
+ ParserParamDecl decl (*this, false);
+ decl.traverse (c);
+ }
+
+ os << ");"
+ << endl;
+ }
+
+ // Default c-tor.
+ //
+ if ((!restriction && (he || ha)) ||
+ (validation && (he || hae || hra)))
+ {
+ os << "// Constructor." << endl
+ << "//" << endl
+ << name << " ();"
+ << endl;
+ }
+
+ if (polymorphic)
+ {
+ os << "public:" << endl
+ << "static const " << char_type << "*" << endl
+ << "_static_type ();"
+ << endl
+ << "virtual const " << char_type << "*" << endl
+ << "_dynamic_type () const;"
+ << endl;
+ }
+
+ // Implementation.
+ //
+ if (he || ha || (validation && (hae || haa)))
+ {
+ os << "// Implementation." << endl
+ << "//" << endl
+ << "protected:" << endl;
+ }
+
+ // element
+ //
+ if (he || (validation && hae))
+ {
+ // _start_element_impl
+ //
+ os << "virtual bool" << endl
+ << "_start_element_impl (const " << string_type << "&," << endl
+ << "const " << string_type << "&," << endl
+ << "const " << string_type << "*);"
+ << endl;
+
+ // end_element
+ //
+ os << "virtual bool" << endl
+ << "_end_element_impl (const " << string_type << "&," << endl
+ << "const " << string_type << "&);"
+ << endl;
+ }
+
+ // attribute
+ //
+ if (validation)
+ {
+ if (ha)
+ {
+ os << "virtual bool" << endl
+ << "_attribute_impl_phase_one (const " << string_type <<
+ "&," << endl
+ << "const " << string_type << "&," << endl
+ << "const " << string_type << "&);" << endl
+ << endl;
+ }
+
+ if (haa)
+ {
+ os << "virtual bool" << endl
+ << "_attribute_impl_phase_two (const " << string_type <<
+ "&," << endl
+ << "const " << string_type << "&," << endl
+ << "const " << string_type << "&);"
+ << endl;
+ }
+ }
+ else
+ {
+ if (ha)
+ {
+ os << "virtual bool" << endl
+ << "_attribute_impl (const " << string_type << "&," << endl
+ << "const " << string_type << "&," << endl
+ << "const " << string_type << "&);"
+ << endl;
+ }
+ }
+
+ // characters
+ //
+ if (validation && c.mixed_p ())
+ {
+ os << "virtual bool" << endl
+ << "_characters_impl (const " << string_type << "&);"
+ << endl;
+ }
+
+ if (!restriction && (he || ha))
+ {
+ os << "protected:" << endl;
+ names (c, names_parser_member_);
+ os << endl;
+ }
+
+ if (validation && (he || hae))
+ {
+ size_t depth (c.context ().get<size_t> ("depth"));
+
+ os << "protected:" << endl;
+
+ os << "struct v_state_descr_"
+ << "{"
+ << "void (" << fq_name (c) << "::*func) (" << endl
+ << "unsigned long&," << endl
+ << "unsigned long&," << endl
+ << "const " << string_type << "&," << endl
+ << "const " << string_type << "&," << endl
+ << "const " << string_type << "*," << endl
+ << "bool);"
+ << "unsigned long state;"
+ << "unsigned long count;"
+ << "};";
+
+ // Allocate one extra slot for the special state.
+ //
+ os << "struct v_state_"
+ << "{"
+ << "v_state_descr_ data[" << depth + 1 << "UL];"
+ << "unsigned long size;"
+ << "};";
+
+ os << "v_state_ v_state_first_;"
+ << "::xsd::cxx::parser::pod_stack v_state_stack_;"
+ << endl;
+
+ os << "virtual void" << endl
+ << "_pre_e_validate ();"
+ << endl;
+
+ os << "virtual void" << endl
+ << "_post_e_validate ();"
+ << endl;
+
+ Particle t (*this);
+ t.dispatch (c.contains_compositor ().compositor ());
+ }
+
+ if (validation && hra)
+ {
+ os << "protected:" << endl;
+
+ os << "struct v_state_attr_"
+ << "{";
+
+ names (c, names_attribute_validation_state_);
+
+ os << "};";
+
+ os << "v_state_attr_ v_state_attr_first_;"
+ << "::xsd::cxx::parser::pod_stack v_state_attr_stack_;"
+ << endl;
+
+ os << "virtual void" << endl
+ << "_pre_a_validate ();"
+ << endl;
+
+ os << "virtual void" << endl
+ << "_post_a_validate ();"
+ << endl;
+ }
+
+ os << "};";
+ }
+
+ private:
+ //
+ //
+ ParserCallback parser_callback_;
+ Traversal::Names names_parser_callback_;
+
+ //
+ //
+ ParserMember parser_member_;
+ Traversal::Names names_parser_member_;
+
+ //
+ //
+ ParserModifier parser_modifier_;
+ Traversal::Names names_parser_modifier_;
+
+ //
+ //
+ AttributeValidationState attribute_validation_state_;
+ Traversal::Names names_attribute_validation_state_;
+ };
+
+ struct FundType : Context,
+
+ 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
+ {
+ FundType (Context& c)
+ : Context (c), xs_ns_ (xs_ns_name ())
+ {
+ impl_ns_ = "::xsd::cxx::parser::";
+ impl_ns_ += (validation ? L"validating" : L"non_validating");
+
+ if (char_type == L"char")
+ string_type_ = L"::std::string";
+ else if (char_type == L"wchar_t")
+ string_type_ = L"::std::wstring";
+ else
+ string_type_ = L"::std::basic_string< " + char_type + L" >";
+ }
+
+ // anyType & anySimpleType.
+ //
+ virtual void
+ traverse (SemanticGraph::AnyType& t)
+ {
+ gen_typedef (t, "void", "any_type_pskel", "any_type_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::AnySimpleType& t)
+ {
+ gen_typedef (t, "void",
+ "any_simple_type_pskel", "any_simple_type_pimpl");
+ }
+
+ // Boolean.
+ //
+ virtual void
+ traverse (SemanticGraph::Fundamental::Boolean& t)
+ {
+ gen_typedef (t, "bool", "boolean_pskel", "boolean_pimpl");
+ }
+
+ // Integral types.
+ //
+ virtual void
+ traverse (SemanticGraph::Fundamental::Byte& t)
+ {
+ gen_typedef (t, "signed char", "byte_pskel", "byte_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::UnsignedByte& t)
+ {
+ gen_typedef (t, "unsigned char",
+ "unsigned_byte_pskel", "unsigned_byte_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::Short& t)
+ {
+ gen_typedef (t, "short", "short_pskel", "short_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::UnsignedShort& t)
+ {
+ gen_typedef (t, "unsigned short",
+ "unsigned_short_pskel", "unsigned_short_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::Int& t)
+ {
+ gen_typedef (t, "int", "int_pskel", "int_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::UnsignedInt& t)
+ {
+ gen_typedef (t, "unsigned int",
+ "unsigned_int_pskel", "unsigned_int_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::Long& t)
+ {
+ gen_typedef (t, "long long", "long_pskel", "long_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::UnsignedLong& t)
+ {
+ gen_typedef (t, "unsigned long long",
+ "unsigned_long_pskel", "unsigned_long_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::Integer& t)
+ {
+ gen_typedef (t, "long long", "integer_pskel", "integer_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::NegativeInteger& t)
+ {
+ gen_typedef (t, "long long",
+ "negative_integer_pskel", "negative_integer_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::NonPositiveInteger& t)
+ {
+ gen_typedef (t, "long long",
+ "non_positive_integer_pskel",
+ "non_positive_integer_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::PositiveInteger& t)
+ {
+ gen_typedef (t, "unsigned long long",
+ "positive_integer_pskel", "positive_integer_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::NonNegativeInteger& t)
+ {
+ gen_typedef (t, "unsigned long long",
+ "non_negative_integer_pskel",
+ "non_negative_integer_pimpl");
+ }
+
+ // Floats.
+ //
+ virtual void
+ traverse (SemanticGraph::Fundamental::Float& t)
+ {
+ gen_typedef (t, "float", "float_pskel", "float_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::Double& t)
+ {
+ gen_typedef (t, "double", "double_pskel", "double_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::Decimal& t)
+ {
+ gen_typedef (t, "double", "decimal_pskel", "decimal_pimpl");
+ }
+
+ // Strings.
+ //
+ virtual void
+ traverse (SemanticGraph::Fundamental::String& t)
+ {
+ gen_typedef (t, string_type_, "string_pskel", "string_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::NormalizedString& t)
+ {
+ gen_typedef (t, string_type_,
+ "normalized_string_pskel", "normalized_string_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::Token& t)
+ {
+ gen_typedef (t, string_type_, "token_pskel", "token_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::NameToken& t)
+ {
+ nmtoken_ = gen_typedef (t, string_type_,
+ "nmtoken_pskel", "nmtoken_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::NameTokens& t)
+ {
+ // NMTOKENS uses NMTOKEN implementation to parse individual items.
+ // As a result, we don't generate NMTOKENS if we didn't generate
+ // NMTOKEN. Here we assume NMTOKEN is handled before NMTOKENS.
+ //
+ if(nmtoken_)
+ gen_typedef (t, xs_ns_ + L"::string_sequence",
+ "nmtokens_pskel", "nmtokens_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::Name& t)
+ {
+ gen_typedef (t, string_type_, "name_pskel", "name_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::NCName& t)
+ {
+ gen_typedef (t, string_type_, "ncname_pskel", "ncname_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::Language& t)
+ {
+ gen_typedef (t, string_type_, "language_pskel", "language_pimpl");
+ }
+
+ // Qualified name.
+ //
+ virtual void
+ traverse (SemanticGraph::Fundamental::QName& t)
+ {
+ gen_typedef (t, xs_ns_ + L"::qname", "qname_pskel", "qname_pimpl");
+ }
+
+ // ID/IDREF.
+ //
+ virtual void
+ traverse (SemanticGraph::Fundamental::Id& t)
+ {
+ gen_typedef (t, string_type_, "id_pskel", "id_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::IdRef& t)
+ {
+ idref_ = gen_typedef (t, string_type_, "idref_pskel", "idref_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::IdRefs& t)
+ {
+ // IDREFS uses IDREF implementation to parse individual items.
+ // As a result, we don't generate IDREFS if we didn't generate
+ // IDREF. Here we assume IDREF is handled before IDREFS.
+ //
+ if (idref_)
+ gen_typedef (t, xs_ns_ + L"::string_sequence",
+ "idrefs_pskel", "idrefs_pimpl");
+ }
+
+ // URI.
+ //
+ virtual void
+ traverse (SemanticGraph::Fundamental::AnyURI& t)
+ {
+ gen_typedef (t, string_type_, "uri_pskel", "uri_pimpl");
+ }
+
+ // Binary.
+ //
+ virtual void
+ traverse (SemanticGraph::Fundamental::Base64Binary& t)
+ {
+ String buffer (auto_ptr + L"< " + xs_ns_ + L"::buffer >");
+ gen_typedef (t, buffer,
+ "base64_binary_pskel", "base64_binary_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::HexBinary& t)
+ {
+ String buffer (auto_ptr + L"< " + xs_ns_ + L"::buffer >");
+ gen_typedef (t, buffer, "hex_binary_pskel", "hex_binary_pimpl");
+ }
+
+
+ // Date/time.
+ //
+ virtual void
+ traverse (SemanticGraph::Fundamental::Date& t)
+ {
+ gen_typedef (t, xs_ns_ + L"::date", "date_pskel", "date_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::DateTime& t)
+ {
+ gen_typedef (t, xs_ns_ + L"::date_time",
+ "date_time_pskel", "date_time_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::Duration& t)
+ {
+ gen_typedef (t, xs_ns_ + L"::duration",
+ "duration_pskel", "duration_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::Day& t)
+ {
+ gen_typedef (t, xs_ns_ + L"::gday", "gday_pskel", "gday_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::Month& t)
+ {
+ gen_typedef (t, xs_ns_ + L"::gmonth",
+ "gmonth_pskel", "gmonth_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::MonthDay& t)
+ {
+ gen_typedef (t, xs_ns_ + L"::gmonth_day",
+ "gmonth_day_pskel", "gmonth_day_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::Year& t)
+ {
+ gen_typedef (t, xs_ns_ + L"::gyear", "gyear_pskel", "gyear_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::YearMonth& t)
+ {
+ gen_typedef (t, xs_ns_ + L"::gyear_month",
+ "gyear_month_pskel", "gyear_month_pimpl");
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::Time& t)
+ {
+ gen_typedef (t, xs_ns_ + L"::time", "time_pskel", "time_pimpl");
+ }
+
+ // Entity.
+ //
+ virtual void
+ traverse (SemanticGraph::Fundamental::Entity&)
+ {
+ }
+
+ virtual void
+ traverse (SemanticGraph::Fundamental::Entities&)
+ {
+ }
+
+ private:
+ bool
+ gen_typedef (SemanticGraph::Type& t,
+ String const& type,
+ String const& pskel,
+ String const& pimpl)
+ {
+ if (ret_type (t) == type)
+ {
+ os << "typedef " << impl_ns_ << "::" << pskel << "< " <<
+ char_type << " > " << ename (t) << ";";
+
+ String const& pimpl_name (t.context ().get<String> ("impl"));
+
+ os << "typedef " << impl_ns_ << "::" << pimpl << "< " <<
+ char_type << " > " << pimpl_name << ";"
+ << endl;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ String xs_ns_;
+ String impl_ns_;
+ String string_type_;
+
+ bool idref_;
+ bool nmtoken_;
+ };
+
+ struct FundNamespace: Namespace, Context
+ {
+ FundNamespace (Context& c)
+ : Namespace (c), Context (c)
+ {
+ }
+
+ void
+ traverse (Type& ns)
+ {
+ pre (ns);
+
+ String impl ("::xsd::cxx::parser::");
+ impl += (validation ? L"validating" : L"non_validating");
+
+ String const c (char_type);
+
+ os << "// Built-in XML Schema types mapping." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::parser::string_sequence< " << c <<
+ " > string_sequence;"
+ << "typedef ::xsd::cxx::parser::qname< " << c << " > qname;"
+ << "typedef ::xsd::cxx::parser::buffer buffer;"
+ << "typedef ::xsd::cxx::parser::time_zone time_zone;"
+ << "typedef ::xsd::cxx::parser::gday gday;"
+ << "typedef ::xsd::cxx::parser::gmonth gmonth;"
+ << "typedef ::xsd::cxx::parser::gyear gyear;"
+ << "typedef ::xsd::cxx::parser::gmonth_day gmonth_day;"
+ << "typedef ::xsd::cxx::parser::gyear_month gyear_month;"
+ << "typedef ::xsd::cxx::parser::date date;"
+ << "typedef ::xsd::cxx::parser::time time;"
+ << "typedef ::xsd::cxx::parser::date_time date_time;"
+ << "typedef ::xsd::cxx::parser::duration duration;"
+ << endl;
+
+ os << "// Base parser skeletons." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::parser::parser_base< " << c <<
+ " > parser_base;"
+ << "typedef " << impl << "::empty_content< " << c <<
+ " > empty_content;"
+ << "typedef " << impl << "::simple_content< " << c <<
+ " > simple_content;"
+ << "typedef " << impl << "::complex_content< " << c <<
+ " > complex_content;"
+ << "typedef " << impl << "::list_base< " << c << " > list_base;"
+ << endl;
+
+ if (polymorphic)
+ {
+ os << "// Parser map interface and default implementation." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::parser::parser_map< " << c <<
+ " > parser_map;"
+ << "typedef ::xsd::cxx::parser::parser_map_impl< " << c <<
+ " > parser_map_impl;"
+ << endl;
+ }
+
+ os << "// Parser skeletons and implementations for the XML Schema" << endl
+ << "// built-in types." << endl
+ << "//" << endl;
+
+ names (ns);
+
+ os << "// Exceptions. See xsd/cxx/parser/exceptions.hxx " <<
+ "for details." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::parser::exception< " <<
+ char_type << " > exception;"
+ << endl
+ << "// Parsing diagnostics." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::parser::severity severity;"
+ << "typedef ::xsd::cxx::parser::error< " << c << " > error;"
+ << "typedef ::xsd::cxx::parser::diagnostics< " << c <<
+ " > diagnostics;"
+ << "typedef ::xsd::cxx::parser::parsing< " << c << " > parsing;"
+ << endl;
+
+ os << "// Error handler. See " <<
+ "xsd/cxx/xml/error-handler.hxx for details." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::xml::error_handler< " << c <<
+ " > error_handler;"
+ << endl;
+
+ os << "// Read-only string." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::ro_string< " << c << " > ro_string;"
+ << endl;
+
+ if (xml_parser == L"xerces")
+ {
+ os << "// Parsing flags. See " <<
+ "xsd/cxx/parser/xerces/elements.hxx" << endl
+ << "// for details." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::parser::xerces::flags flags;"
+ << endl;
+
+ os << "// Parsing properties. See " <<
+ "xsd/cxx/parser/xerces/elements.hxx" << endl
+ << "// for details." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::parser::xerces::properties< " << c <<
+ " > properties;"
+ << endl;
+
+ os << "// Document type. See " <<
+ "xsd/cxx/parser/xerces/elements.hxx" << endl
+ << "// for details." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::parser::xerces::document< " << c <<
+ " > document;"
+ << endl;
+
+ }
+ else if (xml_parser == L"expat")
+ {
+ os << "// Document type. See " <<
+ "xsd/cxx/parser/expat/elements.hxx" << endl
+ << "// for details." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::parser::expat::document< " << c <<
+ " > document;"
+ << endl;
+ }
+
+ post (ns);
+ }
+ };
+ }
+
+ void
+ generate_parser_header (Context& ctx, bool generate_xml_schema)
+ {
+ String c (ctx.char_type);
+
+ //
+ //
+ if (c == L"char")
+ {
+ ctx.os << "#ifndef XSD_USE_CHAR" << endl
+ << "#define XSD_USE_CHAR" << endl
+ << "#endif" << endl
+ << endl;
+
+ ctx.os << "#ifndef XSD_CXX_PARSER_USE_CHAR" << endl
+ << "#define XSD_CXX_PARSER_USE_CHAR" << endl
+ << "#endif" << endl
+ << endl;
+ }
+ else if (c == L"wchar_t")
+ {
+ ctx.os << "#ifndef XSD_USE_WCHAR" << endl
+ << "#define XSD_USE_WCHAR" << endl
+ << "#endif" << endl
+ << endl;
+
+ ctx.os << "#ifndef XSD_CXX_PARSER_USE_WCHAR" << endl
+ << "#define XSD_CXX_PARSER_USE_WCHAR" << endl
+ << "#endif" << endl
+ << endl;
+ }
+
+ //
+ //
+ NarrowString extern_xml_schema;
+
+ if (!generate_xml_schema)
+ extern_xml_schema = ctx.options.extern_xml_schema ();
+
+ if (extern_xml_schema)
+ {
+ String name (ctx.hxx_expr->replace (extern_xml_schema));
+
+ ctx.os << "#include " << ctx.process_include_path (name) << endl
+ << endl;
+
+ // Generate includes that came from the type map.
+ //
+ if (ctx.schema_root.context ().count ("includes"))
+ {
+ typedef set<String> Includes;
+
+ Includes const& is (
+ ctx.schema_root.context ().get<Includes> ("includes"));
+
+ for (Includes::const_reverse_iterator i (is.rbegin ());
+ i != is.rend (); ++i)
+ {
+ ctx.os << "#include " << *i << endl;
+ }
+
+ ctx.os << endl;
+ }
+ }
+ else
+ {
+ if (ctx.char_type == L"char" &&
+ ctx.xml_parser == L"xerces" &&
+ ctx.char_encoding != L"custom")
+ {
+ ctx.os << "#include <xsd/cxx/xml/char-" << ctx.char_encoding << ".hxx>" << endl;
+ }
+
+ ctx.os << "#include <xsd/cxx/xml/error-handler.hxx>" << endl
+ << "#include <xsd/cxx/parser/exceptions.hxx>" << endl
+ << "#include <xsd/cxx/parser/elements.hxx>" << endl
+ << "#include <xsd/cxx/parser/xml-schema.hxx>" << endl;
+
+ if (ctx.polymorphic)
+ ctx.os << "#include <xsd/cxx/parser/map.hxx>" << endl;
+
+ if (ctx.validation)
+ ctx.os << "#include <xsd/cxx/parser/validating/parser.hxx>" << endl
+ << "#include <xsd/cxx/parser/validating/exceptions.hxx>" << endl
+ << "#include <xsd/cxx/parser/validating/xml-schema-pskel.hxx>" << endl
+ << "#include <xsd/cxx/parser/validating/xml-schema-pimpl.hxx>" << endl;
+ else
+ ctx.os << "#include <xsd/cxx/parser/non-validating/parser.hxx>" << endl
+ << "#include <xsd/cxx/parser/non-validating/xml-schema-pskel.hxx>" << endl
+ << "#include <xsd/cxx/parser/non-validating/xml-schema-pimpl.hxx>" << endl;
+
+ ctx.os << "#include <xsd/cxx/parser/" << ctx.xml_parser <<
+ "/elements.hxx>" << endl
+ << endl;
+
+ // Generate includes that came from the type map.
+ //
+ if (ctx.schema_root.context ().count ("includes"))
+ {
+ typedef set<String> Includes;
+
+ Includes const& is (
+ ctx.schema_root.context ().get<Includes> ("includes"));
+
+ for (Includes::const_reverse_iterator i (is.rbegin ());
+ i != is.rend (); ++i)
+ {
+ ctx.os << "#include " << *i << endl;
+ }
+
+ ctx.os << endl;
+ }
+
+ // Generate fundamental types.
+ //
+ if (generate_xml_schema)
+ {
+ Traversal::Schema schema;
+ Traversal::Names names;
+ FundNamespace ns (ctx);
+
+ schema >> names >> ns;
+
+ Traversal::Names ns_names;
+ FundType type (ctx);
+
+ ns >> ns_names >> type;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ else
+ {
+ Traversal::Schema schema, xsd;
+ Traversal::Implies implies;
+ Traversal::Names names;
+ FundNamespace ns (ctx);
+
+ schema >> implies >> xsd >> names >> ns;
+
+ Traversal::Names ns_names;
+ FundType type (ctx);
+
+ ns >> ns_names >> type;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+
+ // Generate user type mapping.
+ //
+ if (!generate_xml_schema)
+ {
+ Traversal::Schema schema;
+
+ Sources sources;
+ Includes includes (ctx, Includes::header);
+ Traversal::Names schema_names;
+
+ Namespace ns (ctx);
+ Traversal::Names names;
+
+ schema >> includes;
+ schema >> sources >> schema;
+ schema >> schema_names >> ns >> names;
+
+ List list (ctx);
+ Union union_ (ctx);
+ Complex complex (ctx);
+ Enumeration enumeration (ctx);
+
+ names >> list;
+ names >> union_;
+ names >> complex;
+ names >> enumeration;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+ }
+}