aboutsummaryrefslogtreecommitdiff
path: root/xsde/cxx/serializer/elements.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'xsde/cxx/serializer/elements.hxx')
-rw-r--r--xsde/cxx/serializer/elements.hxx443
1 files changed, 443 insertions, 0 deletions
diff --git a/xsde/cxx/serializer/elements.hxx b/xsde/cxx/serializer/elements.hxx
new file mode 100644
index 0000000..c80ab5b
--- /dev/null
+++ b/xsde/cxx/serializer/elements.hxx
@@ -0,0 +1,443 @@
+// file : xsde/cxx/serializer/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_SERIALIZER_ELEMENTS_HXX
+#define CXX_SERIALIZER_ELEMENTS_HXX
+
+#include <sstream>
+
+#include <backend-elements/regex.hxx>
+
+#include <cxx/elements.hxx>
+
+#include <cxx/serializer/cli.hxx>
+
+namespace CXX
+{
+ namespace Serializer
+ {
+ struct Content
+ {
+ enum Value
+ {
+ simple,
+ complex,
+ mixed
+ };
+ };
+
+ //
+ //
+ class Context: public CXX::Context
+ {
+ public:
+ typedef BackendElements::Regex::Expression<Char> Regex;
+
+ public:
+ Context (std::wostream&,
+ SemanticGraph::Schema&,
+ CLI::Options const&,
+ Regex const* hxx_expr,
+ Regex const* ixx_expr,
+ Regex const* hxx_impl_expr);
+
+ protected:
+ Context (Context& c)
+ : CXX::Context (c),
+ options (c.options),
+ xml_serializer (c.xml_serializer),
+ serializer_base (c.serializer_base),
+ simple_base (c.simple_base),
+ complex_base (c.complex_base),
+ serializer_map (c.serializer_map),
+ validation (c.validation),
+ exceptions (c.exceptions),
+ stl (c.stl),
+ poly_code (c.poly_code),
+ poly_runtime (c.poly_runtime),
+ reset (c.reset),
+ mixin (c.mixin),
+ tiein (c.tiein),
+ hxx_expr (c.hxx_expr),
+ ixx_expr (c.ixx_expr),
+ hxx_impl_expr (c.hxx_impl_expr)
+ {
+ }
+
+ Context (Context& c, std::wostream& o)
+ : CXX::Context (c, o),
+ options (c.options),
+ xml_serializer (c.xml_serializer),
+ serializer_base (c.serializer_base),
+ simple_base (c.simple_base),
+ complex_base (c.complex_base),
+ serializer_map (c.serializer_map),
+ validation (c.validation),
+ exceptions (c.exceptions),
+ stl (c.stl),
+ poly_code (c.poly_code),
+ poly_runtime (c.poly_runtime),
+ reset (c.reset),
+ mixin (c.mixin),
+ tiein (c.tiein),
+ hxx_expr (c.hxx_expr),
+ ixx_expr (c.ixx_expr),
+ hxx_impl_expr (c.hxx_impl_expr)
+ {
+ }
+
+ public:
+ Boolean
+ restriction_p (SemanticGraph::Complex& c) const
+ {
+ if (c.inherits_p () &&
+ c.inherits ().is_a<SemanticGraph::Restricts> ())
+ {
+ // Restriction of anyType is a special case.
+ //
+ return !c.inherits ().base ().is_a<SemanticGraph::AnyType> ();
+ }
+
+ return false;
+ }
+
+ // Real (e.g., non-typedef) fq-name.
+ //
+ String
+ real_fq_name (SemanticGraph::Nameable& n);
+
+ public:
+ static Content::Value
+ content (SemanticGraph::Complex&);
+
+ public:
+ static String const&
+ ret_type (SemanticGraph::Type&);
+
+ static String const&
+ arg_type (SemanticGraph::Type&);
+
+ public:
+ // Optional.
+ //
+ static String const&
+ epresent (SemanticGraph::Particle&);
+
+ static String const&
+ epresent (SemanticGraph::Attribute&);
+
+ // Sequence.
+ //
+ static String const&
+ enext (SemanticGraph::Particle&);
+
+ static String const&
+ enext (SemanticGraph::AnyAttribute&);
+
+ // Choice.
+ //
+ static String const&
+ etag (SemanticGraph::Particle&);
+
+ static String const&
+ earm (SemanticGraph::Choice&);
+
+ static String const&
+ earm_tag (SemanticGraph::Choice&);
+
+ public:
+ static String const&
+ eserializer (SemanticGraph::Member&);
+
+ static String const&
+ emember (SemanticGraph::Member&);
+
+ static String const&
+ emember_map (SemanticGraph::Member&);
+
+ static String const&
+ etiein (SemanticGraph::Type&);
+
+ // serialize_*
+ //
+ public:
+ static String const&
+ eserialize (SemanticGraph::Any&);
+
+ static String const&
+ eserialize (SemanticGraph::AnyAttribute&);
+
+ public:
+ static String const&
+ eimpl (SemanticGraph::Type&);
+
+ public:
+ CLI::Options const& options;
+ String& xml_serializer;
+ String& serializer_base;
+ String& simple_base;
+ String& complex_base;
+ String& serializer_map;
+
+ Boolean validation;
+ Boolean exceptions;
+ Boolean stl;
+ Boolean poly_code;
+ Boolean poly_runtime;
+ Boolean reset;
+ Boolean mixin;
+ Boolean tiein;
+
+ Regex const* hxx_expr;
+ Regex const* ixx_expr;
+ Regex const* hxx_impl_expr;
+
+ private:
+ String xml_serializer_;
+ String serializer_base_;
+ String simple_base_;
+ String complex_base_;
+ String serializer_map_;
+ };
+
+ //
+ //
+ struct RequiredAttributeTest: Traversal::Attribute
+ {
+ RequiredAttributeTest (Boolean& result)
+ : result_ (result)
+ {
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ if (!result_ && !a.optional ())
+ result_ = true;
+ }
+
+ private:
+ Boolean& result_;
+ };
+
+
+ //
+ //
+ struct ParticleParamDecl: Traversal::Element, Context
+ {
+ ParticleParamDecl (Context& c, Boolean& first, Boolean name_arg)
+ : Context (c), first_ (first), name_arg_ (name_arg)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ if (!first_)
+ os << "," << endl;
+ else
+ first_ = false;
+
+ os << fq_name (e.type ()) << "&";
+
+ if (name_arg_)
+ os << " " << ename (e);
+ else
+ os << " /* " << comment (e.name ()) << " */";
+ }
+
+ private:
+ Boolean& first_;
+ Boolean name_arg_;
+ };
+
+ struct AttributeParamDecl: Traversal::Attribute, Context
+ {
+ AttributeParamDecl (Context& c, Boolean& first, Boolean name_arg)
+ : Context (c), first_ (first), name_arg_ (name_arg)
+ {
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ if (!first_)
+ os << "," << endl;
+ else
+ first_ = false;
+
+ os << fq_name (a.type ()) << "&";
+
+ if (name_arg_)
+ os << " " << ename (a);
+ else
+ os << " /* " << comment (a.name ()) << " */";
+ }
+
+ private:
+ Boolean& first_;
+ Boolean name_arg_;
+ };
+
+ struct SerializerParamDecl : Traversal::Complex,
+ Traversal::List,
+ Context
+ {
+ SerializerParamDecl (Context& c, Boolean name_arg)
+ : Context (c),
+ particle_ (c, first_, name_arg),
+ attribute_ (c, first_, name_arg),
+ first_ (true),
+ name_arg_ (name_arg)
+ {
+ inherits_ >> *this;
+
+ contains_compositor_ >> compositor_ >> contains_particle_;
+ contains_particle_ >> particle_;
+ contains_particle_ >> compositor_;
+
+ names_ >> attribute_;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ inherits (c, inherits_);
+
+ if (!restriction_p (c))
+ {
+ names (c, names_);
+ contains_compositor (c, contains_compositor_);
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::List& l)
+ {
+ if (!first_)
+ os << "," << endl;
+ else
+ first_ = false;
+
+ os << fq_name (l.argumented ().type ()) << "&";
+
+ if (name_arg_)
+ os << " " << ename (l) << "_item";
+ else
+ os << " /* " << comment (l.name ()) << " item */";
+ }
+
+ private:
+ Traversal::Inherits inherits_;
+
+ Traversal::Compositor compositor_;
+ ParticleParamDecl particle_;
+ Traversal::ContainsCompositor contains_compositor_;
+ Traversal::ContainsParticle contains_particle_;
+
+ AttributeParamDecl attribute_;
+ Traversal::Names names_;
+
+ Boolean first_;
+ Boolean name_arg_;
+ };
+
+ //
+ //
+ struct TypeForward: Traversal::Type, Context
+ {
+ TypeForward (Context& c, Char const* name_key)
+ : Context (c), name_key_ (name_key)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Type& t);
+
+ private:
+ Char const* name_key_;
+ };
+
+ struct Includes : Traversal::Imports,
+ Traversal::Includes
+ {
+ enum Type
+ {
+ header,
+ source,
+ impl_header
+ };
+
+ Includes (Context& c, Type t)
+ : ctx_ (c),
+ type_ (t),
+ namespace_ (c),
+ type_forward_ (c, t == header ? "s:name" : "s:impl")
+ {
+ 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_;
+
+ Traversal::Schema schema_;
+ Traversal::Names schema_names_;
+ Namespace namespace_;
+ Traversal::Names names_;
+ TypeForward type_forward_;
+ };
+
+ // Find root element for the test driver.
+ //
+ struct RootElement: Traversal::Element
+ {
+ RootElement (CLI::Options const& options,
+ SemanticGraph::Element*& element)
+ : options_ (options), element_ (element)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (options_.value<CLI::root_element_first> ())
+ {
+ if (element_ == 0)
+ element_ = &e;
+ }
+ else if (String name = options_.value<CLI::root_element> ())
+ {
+ if (e.name () == name)
+ element_ = &e;
+ }
+ else
+ element_ = &e; // Cover root-element-last and no option.
+ }
+
+ private:
+ CLI::Options const& options_;
+ SemanticGraph::Element*& element_;
+ };
+ }
+}
+
+#endif // CXX_SERIALIZER_ELEMENTS_HXX