summaryrefslogtreecommitdiff
path: root/xsd/cxx/elements.hxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2009-09-17 07:15:29 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2009-09-17 07:15:29 +0200
commitf0510d2f90467de8e8f260b47d79a9baaf9bef17 (patch)
tree0b9929946f06a9cbe9b9e8f2a7600dae4e048f79 /xsd/cxx/elements.hxx
Start tracking XSD with git
Diffstat (limited to 'xsd/cxx/elements.hxx')
-rw-r--r--xsd/cxx/elements.hxx577
1 files changed, 577 insertions, 0 deletions
diff --git a/xsd/cxx/elements.hxx b/xsd/cxx/elements.hxx
new file mode 100644
index 0000000..dba9665
--- /dev/null
+++ b/xsd/cxx/elements.hxx
@@ -0,0 +1,577 @@
+// file : xsd/cxx/elements.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_ELEMENTS_HXX
+#define CXX_ELEMENTS_HXX
+
+#include <cult/types.hxx>
+#include <cult/containers/map.hxx>
+#include <cult/containers/vector.hxx>
+
+#include <backend-elements/regex.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <elements.hxx>
+
+#include <ostream>
+
+namespace CXX
+{
+ using std::endl;
+ typedef WideString String;
+
+
+ // On some platforms std::toupper can be something other than a
+ // function with C++ linkage.
+ //
+ wchar_t
+ upcase (wchar_t c);
+
+
+ // Exceptions.
+ //
+
+ struct NoNamespaceMapping
+ {
+ NoNamespaceMapping (SemanticGraph::Path const& file,
+ UnsignedLong line,
+ UnsignedLong column,
+ String const& ns)
+ : file_ (file),
+ line_ (line),
+ column_ (column),
+ ns_ (ns)
+ {
+ }
+
+
+ SemanticGraph::Path const&
+ file () const
+ {
+ return file_;
+ }
+
+ UnsignedLong
+ line () const
+ {
+ return line_;
+ }
+
+ UnsignedLong
+ column () const
+ {
+ return column_;
+ }
+
+ String const&
+ ns () const
+ {
+ return ns_;
+ }
+
+ private:
+ SemanticGraph::Path file_;
+ UnsignedLong line_;
+ UnsignedLong column_;
+ String ns_;
+ };
+
+ struct InvalidNamespaceMapping
+ {
+ InvalidNamespaceMapping (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:
+ typedef BackendElements::Regex::Pattern<WideChar> RegexPat;
+ typedef BackendElements::Regex::Expression<WideChar> Regex;
+ typedef Cult::Containers::Vector<Regex> RegexMapping;
+ typedef Cult::Containers::Map<String, String> MapMapping;
+ typedef Cult::Containers::Map<String, String> MappingCache;
+
+ typedef Cult::Containers::Map<String, String> ReservedNameMap;
+
+ public:
+ Context (std::wostream& o,
+ SemanticGraph::Schema& root,
+ NarrowString const& char_type__,
+ Boolean include_with_brackets__,
+ NarrowString const& include_prefix__,
+ NarrowString const& esymbol,
+ Containers::Vector<NarrowString> const& nsm,
+ Containers::Vector<NarrowString> const& nsr,
+ Boolean trace_namespace_regex_,
+ Containers::Vector<NarrowString> const& include_regex,
+ Boolean trace_include_regex_,
+ Boolean inline_,
+ Containers::Vector<NarrowString> const& reserved_name);
+
+ protected:
+ Context (Context& c)
+ : os (c.os),
+ schema_root (c.schema_root),
+ char_type (c.char_type),
+ L (c.L),
+ string_type (c.string_type),
+ include_with_brackets (c.include_with_brackets),
+ include_prefix (c.include_prefix),
+ type_exp (c.type_exp),
+ inst_exp (c.inst_exp),
+ inl (c.inl),
+ ns_mapping_cache (c.ns_mapping_cache),
+ xs_ns_ (c.xs_ns_),
+ cxx_id_expr (c.cxx_id_expr),
+ trace_namespace_regex (c.trace_namespace_regex),
+ nsr_mapping (c.nsr_mapping),
+ nsm_mapping (c.nsm_mapping),
+ include_mapping (c.include_mapping),
+ trace_include_regex (c.trace_include_regex),
+ reserved_name_map (c.reserved_name_map)
+ {
+ }
+
+ Context (Context& c, std::wostream& o)
+ : os (o),
+ schema_root (c.schema_root),
+ char_type (c.char_type),
+ L (c.L),
+ string_type (c.string_type),
+ include_with_brackets (c.include_with_brackets),
+ include_prefix (c.include_prefix),
+ type_exp (c.type_exp),
+ inst_exp (c.inst_exp),
+ inl (c.inl),
+ ns_mapping_cache (c.ns_mapping_cache),
+ xs_ns_ (c.xs_ns_),
+ cxx_id_expr (c.cxx_id_expr),
+ trace_namespace_regex (c.trace_namespace_regex),
+ nsr_mapping (c.nsr_mapping),
+ nsm_mapping (c.nsm_mapping),
+ include_mapping (c.include_mapping),
+ trace_include_regex (c.trace_include_regex),
+ reserved_name_map (c.reserved_name_map)
+ {
+ }
+
+ public:
+ static String
+ unclash (String const& name, String const& new_name)
+ {
+ return name == new_name ? (new_name + L'_') : new_name;
+ }
+
+ public:
+ // Return UTF-32 character starting at this position. Position is
+ // advanced by 1 if this Unicode character takes more than one
+ // underlying character.
+ //
+ static UnsignedLong
+ unicode_char (String const& str, Size& pos);
+
+ static UnsignedLong
+ unicode_char (WideChar const*& p);
+
+ // Escape C++ keywords and illegal characters.
+ //
+ String
+ escape (String const&);
+
+ // Create a string literal so that it can be used in C++ source
+ // code. It includes "".
+ //
+ String
+ strlit (String const&);
+
+ // Escape the string so that it can be used in C++ comment.
+ //
+ String
+ comment (String const&);
+
+ // Translate XML namespace name to a C++ identifier.
+ //
+ String
+ ns_name (SemanticGraph::Namespace&);
+
+ // XML Schema namespace.
+ //
+ SemanticGraph::Namespace&
+ xs_ns ();
+
+ // C++ namespace for XML Schema.
+ //
+ String
+ xs_ns_name ();
+
+ //
+ //
+ SemanticGraph::Namespace&
+ namespace_ (SemanticGraph::Nameable& n);
+
+ // Original XML namespace name.
+ //
+ String
+ xml_ns_name (SemanticGraph::Nameable& ns);
+
+
+ // Fully-qualified C++ name.
+ //
+ String
+ fq_name (SemanticGraph::Nameable& n, Char const* name_key = "name");
+
+ public:
+ static SemanticGraph::Type&
+ ultimate_base (SemanticGraph::Complex&);
+
+ public:
+ String
+ process_include_path (String const&) const;
+
+ public:
+ static Boolean
+ skip (SemanticGraph::Member& m)
+ {
+ // "Subsequent" local element.
+ //
+ return !m.scope ().is_a<SemanticGraph::Namespace> () &&
+ m.context ().count ("min") == 0;
+ }
+
+ static UnsignedLong
+ min (SemanticGraph::Member const& m)
+ {
+ return m.context ().get<UnsignedLong> ("min");
+ }
+
+ static UnsignedLong
+ min (SemanticGraph::Any const& a)
+ {
+ return a.context ().get<UnsignedLong> ("min");
+ }
+
+ static UnsignedLong
+ max (SemanticGraph::Member const& m)
+ {
+ return m.context ().get<UnsignedLong> ("max");
+ }
+
+ static UnsignedLong
+ max (SemanticGraph::Any const& a)
+ {
+ return a.context ().get<UnsignedLong> ("max");
+ }
+
+ public:
+ // Get escaped name.
+ //
+ static String const&
+ ename (SemanticGraph::Nameable const& n)
+ {
+ return n.context ().get<String> ("name");
+ }
+
+ public:
+ std::wostream& os;
+
+ SemanticGraph::Schema& schema_root;
+
+ String& char_type;
+ String& L; // string literal prefix
+ String& string_type;
+
+ Boolean& include_with_brackets;
+ String& include_prefix;
+
+ String& type_exp;
+ String& inst_exp;
+ String& inl;
+
+ public:
+ MappingCache& ns_mapping_cache;
+
+ private:
+ SemanticGraph::Namespace* xs_ns_;
+
+ String char_type_;
+ String L_;
+ String string_type_;
+
+ Boolean include_with_brackets_;
+ String include_prefix_;
+
+ String type_exp_;
+ String inst_exp_;
+ String inl_;
+
+ private:
+ RegexPat const cxx_id_expr_;
+ RegexPat const& cxx_id_expr;
+ Boolean trace_namespace_regex;
+ RegexMapping nsr_mapping_;
+ MapMapping nsm_mapping_;
+ RegexMapping const& nsr_mapping;
+ MapMapping const& nsm_mapping;
+ MappingCache ns_mapping_cache_;
+
+ RegexMapping include_mapping_;
+ RegexMapping const& include_mapping;
+ Boolean trace_include_regex;
+
+ ReservedNameMap const& reserved_name_map;
+ ReservedNameMap reserved_name_map_;
+ };
+
+ inline UnsignedLong Context::
+ unicode_char (String const& str, Size& pos)
+ {
+ if (sizeof (WideChar) == 4)
+ {
+ return str[pos];
+ }
+ else if (sizeof (WideChar) == 2)
+ {
+ WideChar x (str[pos]);
+
+ if (x < 0xD800 || x > 0xDBFF)
+ return x;
+ else
+ return ((x - 0xD800) << 10) + (str[++pos] - 0xDC00) + 0x10000;
+ }
+ else
+ return 0;
+ }
+
+ inline UnsignedLong Context::
+ unicode_char (WideChar const*& p)
+ {
+ if (sizeof (WideChar) == 4)
+ {
+ return *p;
+ }
+ else if (sizeof (WideChar) == 2)
+ {
+ WideChar x (*p);
+
+ if (x < 0xD800 || x > 0xDBFF)
+ return x;
+ else
+ return ((x - 0xD800) << 10) + (*(++p) - 0xDC00) + 0x10000;
+ }
+ else
+ return 0;
+ }
+
+ // Usual namespace mapping.
+ //
+ struct Namespace : Traversal::Namespace
+ {
+ struct ScopeTracker
+ {
+ // First scope name if always empty (global scope). The last flag
+ // signals the last scope.
+ //
+ virtual Void
+ enter (Type&, String const& name, Boolean last) = 0;
+
+ virtual Void
+ leave () = 0;
+ };
+
+
+ Namespace (Context& c)
+ : ctx_ (c), st_ (0)
+ {
+ }
+
+ Namespace (Context& c, ScopeTracker& st)
+ : ctx_ (c), st_ (&st)
+ {
+ }
+
+ virtual Void
+ pre (Type&);
+
+ virtual Void
+ post (Type&);
+
+ private:
+ Context& ctx_;
+ ScopeTracker* st_;
+ };
+
+
+ //
+ //
+ template <typename X>
+ struct Has : X
+ {
+ Has (Boolean& result)
+ : result_ (result)
+ {
+ }
+
+ virtual Void
+ traverse (typename X::Type&)
+ {
+ result_ = true;
+ }
+
+ private:
+ Boolean& result_;
+ };
+
+ // Checks if scope 'Y' names any of 'X'
+ //
+ template <typename X, typename Y>
+ Boolean
+ has (Y& y)
+ {
+ using SemanticGraph::Scope;
+
+ Boolean result (false);
+ Has<X> t (result);
+
+ for (Scope::NamesIterator i (y.names_begin ()), e (y.names_end ());
+ !result && i != e; ++i)
+ t.dispatch (i->named ());
+
+ return result;
+ }
+
+ // Checks if the compositor has any particle of 'X'
+ //
+ template <typename X>
+ Boolean
+ has_particle (SemanticGraph::Compositor& y)
+ {
+ using SemanticGraph::Compositor;
+
+ Boolean result (false);
+ Has<X> t (result);
+
+ for (Compositor::ContainsIterator i (y.contains_begin ()),
+ e (y.contains_end ()); !result && i != e; ++i)
+ {
+ SemanticGraph::Particle& p (i->particle ());
+
+ t.dispatch (p);
+
+ if (!result && p.is_a<Compositor> ())
+ result = has_particle<X> (dynamic_cast<Compositor&> (p));
+ }
+
+ return result;
+ }
+
+ // Specialization for Complex
+ //
+ template <typename X>
+ Boolean
+ has_particle (SemanticGraph::Complex& c)
+ {
+ return c.contains_compositor_p () &&
+ has_particle<X> (c.contains_compositor ().compositor ());
+ }
+
+ // Fundamental type mapping helper.
+ //
+ struct Fundamental : Traversal::Fundamental::Type,
+ Traversal::Fundamental::String,
+ Traversal::Fundamental::NormalizedString,
+ Traversal::Fundamental::Token,
+ Traversal::Fundamental::Name,
+ Traversal::Fundamental::NameToken,
+ Traversal::Fundamental::NCName,
+ Traversal::Fundamental::Id,
+ Traversal::Fundamental::IdRef
+ {
+ virtual Void
+ fundamental_type (SemanticGraph::Fundamental::Type& t) = 0;
+
+ virtual Void
+ fundamental_template (SemanticGraph::Fundamental::Type& t) = 0;
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Type& t)
+ {
+ fundamental_type (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::String& t)
+ {
+ fundamental_template (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NormalizedString& t)
+ {
+ fundamental_template (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Token& t)
+ {
+ fundamental_template (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Name& t)
+ {
+ fundamental_template (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameToken& t)
+ {
+ fundamental_template (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NCName& t)
+ {
+ fundamental_template (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Id& t)
+ {
+ fundamental_template (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRef& t)
+ {
+ fundamental_template (t);
+ }
+ };
+}
+
+#endif // CXX_TREE_ELEMENTS_HXX