// file : xsde/cxx/parser/elements.cxx // copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include namespace CXX { namespace Parser { Context:: Context (std::wostream& o, SemanticGraph::Schema& root, SemanticGraph::Path const& path, options_type const& ops, Regex const* he, Regex const* ie, Regex const* hie) : CXX::Context (o, root, path, ops, "p:name", "char"), options (ops), xml_parser (xml_parser_), simple_base (simple_base_), complex_base (complex_base_), list_base (list_base_), parser_map (parser_map_), validation (!ops.suppress_validation ()), exceptions (!ops.no_exceptions ()), poly_code (ops.generate_polymorphic ()), poly_runtime (poly_code || ops.runtime_polymorphic ()), reset (!ops.suppress_reset ()), mixin (ops.reuse_style_mixin ()), tiein (!mixin && !ops.reuse_style_none ()), hxx_expr (he), ixx_expr (ie), hxx_impl_expr (hie), xml_parser_ ("expat") { string_type = L"::xsde::cxx::ro_string"; simple_base_ = L"::xsde::cxx::parser::"; simple_base_ += (validation ? L"validating" : L"non_validating"); simple_base_ += L"::simple_content"; complex_base_ = L"::xsde::cxx::parser::"; complex_base_ += (validation ? L"validating" : L"non_validating"); complex_base_ += L"::complex_content"; list_base_ = L"::xsde::cxx::parser::"; list_base_ += (validation ? L"validating" : L"non_validating"); list_base_ += L"::list_base"; if (poly_code) parser_map_ = xs_ns_name () + L"::parser_map"; } String Context:: real_fq_name (SemanticGraph::Nameable& n) { SemanticGraph::Context& c (n.context ()); if (c.count ("p:real-name")) return c.get ("p:real-name"); else return fq_name (n); } Content::Value Context:: content (SemanticGraph::Complex& c) { using namespace SemanticGraph; if (c.mixed_p ()) return Content::mixed; if (c.inherits_p ()) { Type& base (c.inherits ().base ()); if (Complex* cb = dynamic_cast (&base)) return content (*cb); if (base.is_a ()) return Content::complex; // Everyhting else (built-in type and AnySimpleType) is simple // content. // return Content::simple; } else return Content::complex; } String const& Context:: ret_type (SemanticGraph::Type& t) { return t.context ().get ("p:ret-type"); } String const& Context:: arg_type (SemanticGraph::Type& t) { return t.context ().get ("p:arg-type"); } String const& Context:: post_name (SemanticGraph::Type& t) { return t.context ().get ("p:post"); } String const& Context:: epresent (SemanticGraph::Compositor& c) { return c.context ().get ("p:present"); } String const& Context:: enext (SemanticGraph::Sequence& s) { return s.context ().get ("p:next"); } String const& Context:: etag (SemanticGraph::Particle& p) { return p.context ().get ("p:tag"); } String const& Context:: earm (SemanticGraph::Choice& c) { return c.context ().get ("p:arm"); } String const& Context:: earm_tag (SemanticGraph::Choice& c) { return c.context ().get ("p:arm-tag"); } String const& Context:: eparser (SemanticGraph::Member& m) { return m.context ().get ("p:parser"); } String const& Context:: emember (SemanticGraph::Member& m) { return m.context ().get ("p:member"); } String const& Context:: emember_map (SemanticGraph::Member& m) { return m.context ().get ("p:member-map"); } String const& Context:: etiein (SemanticGraph::Type& t) { return t.context ().get ("p:tiein"); } String const& Context:: eimpl (SemanticGraph::Type& t) { return t.context ().get ("p:impl"); } bool Context:: has_facets (SemanticGraph::Complex& c) { if (restriction_p (c)) { using SemanticGraph::Restricts; Restricts& r (dynamic_cast (c.inherits ())); if (r.facet_empty ()) return false; SemanticGraph::Type& ub (ultimate_base (c)); Restricts::FacetIterator end (r.facet_end ()); if (ub.is_a () || ub.is_a ()) { if (r.facet_find (L"whiteSpace") != end) return true; if (validation) { if (r.facet_find (L"length") != end || r.facet_find (L"minLength") != end || r.facet_find (L"maxLength") != end || r.facet_find (L"pattern") != end) return true; } } if (ub.is_a () || ub.is_a () || ub.is_a () || ub.is_a () || ub.is_a () || ub.is_a () || ub.is_a () || ub.is_a () || ub.is_a () || ub.is_a () || ub.is_a () || ub.is_a () || ub.is_a () || ub.is_a () || ub.is_a () || ub.is_a ()) { if (validation) { if (r.facet_find (L"minInclusive") != end || r.facet_find (L"minExclusive") != end || r.facet_find (L"maxInclusive") != end || r.facet_find (L"maxExclusive") != end) return true; } } } return false; } // Includes // void TypeForward:: traverse (SemanticGraph::Type& t) { os << "class " << t.context ().get (name_key_) << ";"; } void Includes:: traverse_ (SemanticGraph::Uses& u) { // Support for weak (forward) inclusion used in the file-per-type // compilation model. // SemanticGraph::Schema& s (u.schema ()); bool weak (u.context ().count ("weak")); if (weak && (type_ == header || type_ == impl_header)) { // Generate forward declarations. We don't really need them // in the impl files. // if (type_ == header) schema_.dispatch (s); return; } if (type_ == source && !weak) return; SemanticGraph::Path path ( s.context ().count ("renamed") ? s.context ().get ("renamed") : u.path ()); path.normalize (); // Try to use the portable representation of the path. If that // fails, fall back to the native representation. // NarrowString path_str; try { path_str = path.posix_string (); } catch (SemanticGraph::InvalidPath const&) { path_str = path.string (); } String inc_path; switch (type_) { case header: case source: { inc_path = ctx_.hxx_expr->replace (path_str); break; } case impl_header: { inc_path = ctx_.hxx_impl_expr->replace (path_str); break; } } ctx_.os << "#include " << ctx_.process_include_path (inc_path) << endl << endl; } } }