aboutsummaryrefslogtreecommitdiff
path: root/xsde/cxx/hybrid/elements.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'xsde/cxx/hybrid/elements.cxx')
-rw-r--r--xsde/cxx/hybrid/elements.cxx493
1 files changed, 493 insertions, 0 deletions
diff --git a/xsde/cxx/hybrid/elements.cxx b/xsde/cxx/hybrid/elements.cxx
new file mode 100644
index 0000000..454d0c3
--- /dev/null
+++ b/xsde/cxx/hybrid/elements.cxx
@@ -0,0 +1,493 @@
+// file : xsde/cxx/hybrid/elements.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/hybrid/elements.hxx>
+
+namespace CXX
+{
+ namespace Hybrid
+ {
+ Context::
+ Context (std::wostream& o,
+ SemanticGraph::Schema& root,
+ CLI::Options const& ops,
+ Regex const* fe,
+ Regex const* he,
+ Regex const* ie)
+ : CXX::Context (o,
+ root,
+ "name",
+ "char",
+ ops.value<CLI::include_with_brackets> (),
+ ops.value<CLI::include_prefix> (),
+ "", // export symbol
+ ops.value<CLI::namespace_map> (),
+ ops.value<CLI::namespace_regex> (),
+ ops.value<CLI::namespace_regex_trace> (),
+ ops.value<CLI::include_regex> (),
+ ops.value<CLI::include_regex_trace> (),
+ ops.value<CLI::generate_inline> (),
+ ops.value<CLI::reserved_name> ()),
+ options (ops),
+ exceptions (!ops.value<CLI::no_exceptions> ()),
+ stl (!ops.value<CLI::no_stl> ()),
+ poly_code (false),
+ poly_runtime (false),
+ reset (!ops.value<CLI::suppress_reset> ()),
+ mixin (ops.value<CLI::reuse_style_mixin> ()),
+ tiein (!mixin),
+ fwd_expr (fe),
+ hxx_expr (he),
+ ixx_expr (ie),
+ ns_stack (ns_stack_)
+ {
+ String xs_ns (xs_ns_name ());
+
+ string_type = L"::xsde::cxx::ro_string";
+ }
+
+ // Parser
+ //
+ String const& Context::
+ pret_type (SemanticGraph::Type& t)
+ {
+ return t.context ().get<String> ("p:ret-type");
+ }
+
+ String const& Context::
+ parg_type (SemanticGraph::Type& t)
+ {
+ return t.context ().get<String> ("p:arg-type");
+ }
+
+ String const& Context::
+ post_name (SemanticGraph::Type& t)
+ {
+ return t.context ().get<String> ("p:post");
+ }
+
+ static String pre_impl ("pre_impl");
+
+ String const& Context::
+ pre_impl_name (SemanticGraph::Type&)
+ {
+ // @@ Currently not assigned because we don't assign names to
+ // types in included/imported schemas which makes assigning
+ // this name correctly impossible.
+ //
+ return pre_impl;
+ // return t.context ().get<String> ("ppre-impl");
+ }
+
+ String const& Context::
+ epname (SemanticGraph::Particle& p)
+ {
+ return p.context ().get<String> ("p:name");
+ }
+
+ String const& Context::
+ epname (SemanticGraph::Attribute& a)
+ {
+ return a.context ().get<String> ("p:name");
+ }
+
+ String const& Context::
+ epimpl (SemanticGraph::Type& t)
+ {
+ // Use p:impl instead of pimpl because C++/Parser assigns impl
+ // names to the built-in types.
+ //
+ return t.context ().get<String> ("p:impl");
+ }
+
+ String const& Context::
+ epimpl_custom (SemanticGraph::Type& t)
+ {
+ SemanticGraph::Context& c (t.context ());
+
+ if (!c.count ("p:impl-base"))
+ return c.get<String> ("p:impl");
+ else
+ return c.get<String> ("p:impl-base");
+ }
+
+ String const& Context::
+ epstate (SemanticGraph::Type& t)
+ {
+ return t.context ().get<String> ("pstate");
+ }
+
+ String const& Context::
+ epstate_type (SemanticGraph::Type& t)
+ {
+ return t.context ().get<String> ("pstate-type");
+ }
+
+ String const& Context::
+ epstate_member (SemanticGraph::Type& t)
+ {
+ return t.context ().get<String> ("pstate-member");
+ }
+
+ String const& Context::
+ epstate_base (SemanticGraph::Type& t)
+ {
+ return t.context ().get<String> ("pstate-base");
+ }
+
+ String const& Context::
+ epstate_member (SemanticGraph::Compositor& c)
+ {
+ return c.context ().get<String> ("pstate-member");
+ }
+
+ String const& Context::
+ epskel (SemanticGraph::Type& t)
+ {
+ return t.context ().get<String> ("p:name");
+ }
+
+ String const& Context::
+ eppresent (SemanticGraph::Compositor& c)
+ {
+ return c.context ().get<String> ("p:present");
+ }
+
+ String const& Context::
+ epnext (SemanticGraph::Compositor& c)
+ {
+ return c.context ().get<String> ("p:next");
+ }
+
+ String const& Context::
+ eptag (SemanticGraph::Particle& p)
+ {
+ return p.context ().get<String> ("p:tag");
+ }
+
+ String const& Context::
+ eparm (SemanticGraph::Choice& c)
+ {
+ return c.context ().get<String> ("p:arm");
+ }
+
+ String const& Context::
+ eparm_tag (SemanticGraph::Choice& c)
+ {
+ return c.context ().get<String> ("p:arm-tag");
+ }
+
+ // Serializer
+ //
+ String const& Context::
+ sret_type (SemanticGraph::Type& t)
+ {
+ return t.context ().get<String> ("s:ret-type");
+ }
+
+ String const& Context::
+ sarg_type (SemanticGraph::Type& t)
+ {
+ return t.context ().get<String> ("s:arg-type");
+ }
+
+ String const& Context::
+ esname (SemanticGraph::Particle& p)
+ {
+ return p.context ().get<String> ("s:name");
+ }
+
+ String const& Context::
+ esname (SemanticGraph::Attribute& a)
+ {
+ return a.context ().get<String> ("s:name");
+ }
+
+ String const& Context::
+ esimpl (SemanticGraph::Type& t)
+ {
+ // Use s:impl instead of simpl because C++/Serializer assigns impl
+ // names to the built-in types.
+ //
+ return t.context ().get<String> ("s:impl");
+ }
+
+ String const& Context::
+ esimpl_custom (SemanticGraph::Type& t)
+ {
+ SemanticGraph::Context& c (t.context ());
+
+ if (!c.count ("s:impl-base"))
+ return c.get<String> ("s:impl");
+ else
+ return c.get<String> ("s:impl-base");
+ }
+
+ String const& Context::
+ esstate (SemanticGraph::Type& t)
+ {
+ return t.context ().get<String> ("sstate");
+ }
+
+ String const& Context::
+ esstate_type (SemanticGraph::Type& t)
+ {
+ return t.context ().get<String> ("sstate-type");
+ }
+
+ String const& Context::
+ esstate_member (SemanticGraph::Type& t)
+ {
+ return t.context ().get<String> ("sstate-member");
+ }
+
+ String const& Context::
+ esstate_member (SemanticGraph::Particle& p)
+ {
+ return p.context ().get<String> ("sstate-member");
+ }
+
+ String const& Context::
+ esstate_member_end (SemanticGraph::Particle& p)
+ {
+ return p.context ().get<String> ("sstate-member-end");
+ }
+
+ String const& Context::
+ esskel (SemanticGraph::Type& t)
+ {
+ return t.context ().get<String> ("s:name");
+ }
+
+ String const& Context::
+ espresent (SemanticGraph::Particle& p)
+ {
+ return p.context ().get<String> ("s:present");
+ }
+
+ String const& Context::
+ espresent (SemanticGraph::Attribute& a)
+ {
+ return a.context ().get<String> ("s:present");
+ }
+
+ String const& Context::
+ esnext (SemanticGraph::Particle& p)
+ {
+ return p.context ().get<String> ("s:next");
+ }
+
+ String const& Context::
+ estag (SemanticGraph::Particle& p)
+ {
+ return p.context ().get<String> ("s:tag");
+ }
+
+ String const& Context::
+ esarm (SemanticGraph::Choice& c)
+ {
+ return c.context ().get<String> ("s:arm");
+ }
+
+ String const& Context::
+ esarm_tag (SemanticGraph::Choice& c)
+ {
+ return c.context ().get<String> ("s:arm-tag");
+ }
+
+ //
+ //
+ String Context::
+ scope (SemanticGraph::Compositor& c, Boolean fq) const
+ {
+ using namespace SemanticGraph;
+
+ String r;
+
+ Compositor* p (&c);
+
+ while (!p->contained_compositor_p ())
+ {
+ p = &p->contained_particle ().compositor ();
+
+ if (!p->context ().count ("type"))
+ continue; // See-through compositor.
+
+ if (!r)
+ r = etype (*p);
+ else
+ {
+ String tmp;
+ tmp.swap (r);
+ r = etype (*p);
+ r += L"::";
+ r += tmp;
+ }
+ }
+
+ Complex& t (
+ dynamic_cast<Complex&> (
+ p->contained_compositor ().container ()));
+
+ if (!r)
+ r = fq ? fq_name (t) : ename (t);
+ else
+ {
+ String tmp;
+ tmp.swap (r);
+ r = fq ? fq_name (t) : ename (t);
+ r += L"::";
+ r += tmp;
+ }
+
+ return r;
+ }
+
+ String Context::
+ scope (SemanticGraph::Element& e, Boolean fq) const
+ {
+ SemanticGraph::Compositor& c (e.contained_particle ().compositor ());
+
+ if (!c.context ().count ("type"))
+ return scope (c, fq);
+ else
+ return scope (c, fq) + L"::" + etype (c);
+ }
+
+ String Context::
+ scope (SemanticGraph::Attribute& a, Boolean fq) const
+ {
+ using SemanticGraph::Complex;
+
+ Complex& t (dynamic_cast<Complex&> (a.scope ()));
+ return fq ? fq_name (t) : ename (t);
+ }
+
+ Void Context::
+ close_ns ()
+ {
+ for (Size i (0), n (ns_stack.size () - 1); i < n; ++i)
+ os << "}";
+ }
+
+ Void Context::
+ open_ns ()
+ {
+ for (NamespaceStack::Iterator i (ns_stack.begin () + 1);
+ i != ns_stack.end ();
+ ++i)
+ {
+ os << "namespace " << *i
+ << "{";
+ }
+ }
+
+ // Namespace
+ //
+ Namespace::
+ Namespace (Context& c, Boolean track_scope)
+ : CXX::Namespace (c, track_scope ? this : 0), ctx_ (c)
+ {
+ }
+
+ Void Namespace::
+ enter (String const& name)
+ {
+ ctx_.ns_stack.push_back (name);
+ }
+
+ Void Namespace::
+ leave ()
+ {
+ ctx_.ns_stack.pop_back ();
+ }
+
+ // Includes
+ //
+ Void TypeForward::
+ traverse (SemanticGraph::Type& t)
+ {
+ os << "class " << ename (t) << ";";
+ }
+
+ Void Includes::
+ traverse_ (SemanticGraph::Uses& u)
+ {
+ // Support for weak (forward) inclusion used in the file-per-type
+ // compilation model.
+ //
+ Type t (type_);
+ Boolean weak (u.context ().count ("weak"));
+
+ if (weak && (t == header || t == impl_header))
+ {
+ // Generate forward declarations. We don't really need them
+ // in the impl files.
+ //
+ if (t == impl_header)
+ return;
+
+ if (forward_)
+ t = forward;
+ else
+ {
+ schema_.dispatch (u.schema ());
+ return;
+ }
+ }
+
+ if (t == source && !weak)
+ return;
+
+ SemanticGraph::Path path (u.path ());
+
+ // 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.string ();
+ }
+ catch (SemanticGraph::InvalidPath const&)
+ {
+ path_str = path.native_file_string ();
+ }
+
+ String inc_path;
+
+ switch (t)
+ {
+ case forward:
+ {
+ inc_path = ctx_.fwd_expr->merge (path_str);
+ break;
+ }
+ case header:
+ case impl_header:
+ case source:
+ {
+ inc_path = ctx_.hxx_expr->merge (path_str);
+ break;
+ }
+ case inline_:
+ {
+ if (weak)
+ {
+ inc_path = ctx_.hxx_expr->merge (path_str);
+ ctx_.os << "#include " << ctx_.process_include_path (inc_path)
+ << endl;
+ }
+
+ inc_path = ctx_.ixx_expr->merge (path_str);
+ break;
+ }
+ }
+
+ ctx_.os << "#include " << ctx_.process_include_path (inc_path) << endl
+ << endl;
+ }
+ }
+}