diff options
Diffstat (limited to 'modules/CIAO/CIDLC/DescriptorGenerator.cpp')
-rw-r--r-- | modules/CIAO/CIDLC/DescriptorGenerator.cpp | 582 |
1 files changed, 582 insertions, 0 deletions
diff --git a/modules/CIAO/CIDLC/DescriptorGenerator.cpp b/modules/CIAO/CIDLC/DescriptorGenerator.cpp new file mode 100644 index 00000000000..76a5a810774 --- /dev/null +++ b/modules/CIAO/CIDLC/DescriptorGenerator.cpp @@ -0,0 +1,582 @@ +// $Id$ + +#include "DescriptorGenerator.hpp" +#include "UnescapedNamePrinter.hpp" +#include "Literals.hpp" + +#include <ostream> + +#include "CCF/CIDL/SemanticGraph.hpp" +#include "CCF/CIDL/Traversal.hpp" + +#include "CCF/CodeGenerationKit/Regex.hpp" +#include "CCF/CodeGenerationKit/IndentationXML.hpp" +#include "CCF/CodeGenerationKit/IndentationImplanter.hpp" + +using std::cout; +using std::endl; +using std::string; + +using namespace StringLiterals; +using namespace CCF::CIDL; +using namespace CCF::CIDL::SemanticGraph; + +namespace +{ + class EmitterBase + { + public: + EmitterBase (fs::ofstream& ofs) + : os (ofs) + {} + + protected: + fs::ofstream& os; + }; + + class CompositionEmitter : public EmitterBase, + public Traversal::Composition + { + // Nested classes for emitters created and dispatched inside + // ComponsitionEmitter::traverse(). + private: + struct ComponentIdEmitter : Traversal::Component, EmitterBase + { + ComponentIdEmitter (fs::ofstream& ofs) + : EmitterBase (ofs) + {} + + virtual void + traverse (Type& c) + { + os << "<componentrepid repid=\"" + << c.context ().get<string> (STRS[REPO_ID]) + << "\"/>" + << endl; + } + }; + + struct HomeIdEmitter : Traversal::Home, EmitterBase + { + HomeIdEmitter (fs::ofstream& ofs) + : EmitterBase (ofs) + {} + + virtual void + traverse (Type& h) + { + os << "<homerepid repid=\"" + << h.context ().get<string> (STRS[REPO_ID]) + << "\"/>" + << endl; + } + }; + + struct HomeFeaturesEmitter : Traversal::Home, EmitterBase + { + HomeFeaturesEmitter (fs::ofstream& ofs) + : EmitterBase (ofs) + {} + + virtual void + traverse (Type& h) + { + os << "<homefeatures" << endl + << "name=\"" << h.name () << "\"" << endl + << "repid=\"" + << h.context ().get<string> (STRS[REPO_ID]) + << "\">" << endl; + + Traversal::Inherits home_inherits; + HomeInheritanceEmitter emitter (os); + home_inherits.node_traverser (emitter); + + inherits (h, home_inherits); + + os << "</homefeatures>" << endl << endl; + + // Go after inherited homes. + // + Traversal::Home::traverse (h); + } + + struct HomeInheritanceEmitter : Traversal::Home, EmitterBase + { + HomeInheritanceEmitter (fs::ofstream& ofs) + : EmitterBase (ofs) + {} + + virtual void + traverse (Type& h) + { + os << "<inheritshome repid=\"" + << h.context ().get<string> (STRS[REPO_ID]) + << "\"/>" + << endl; + } + }; + }; + + struct ComponentFeaturesEmitter : Traversal::Component, EmitterBase + { + ComponentFeaturesEmitter (fs::ofstream& ofs) + : EmitterBase (ofs) + {} + + virtual void + traverse (Type& c) + { + os << "<componentfeatures" << endl + << "name=\"" << c.name () << "\"" << endl + << "repid=\"" + << c.context ().get<string> (STRS[REPO_ID]) + << "\">" << endl; + + Traversal::Inherits component_inherits; + Traversal::Supports component_supports; + ComponentInheritanceEmitter i_emitter (os); + ComponentSupportsEmitter s_emitter (os); + component_inherits.node_traverser (i_emitter); + component_supports.node_traverser (s_emitter); + + inherits (c, component_inherits); + supports (c, component_supports); + + os << "<ports>" << endl; + + Traversal::Defines defines; + PortsEmitter ports_emitter (os); + defines.node_traverser (ports_emitter); + + names (c, defines); + + os << "</ports>" << endl; + + os << "</componentfeatures>" << endl << endl; + + // Go after inherited components. + // + Traversal::Component::traverse (c); + } + + struct ComponentInheritanceEmitter : Traversal::Component, EmitterBase + { + ComponentInheritanceEmitter (fs::ofstream& ofs) + : EmitterBase (ofs) + {} + + virtual void + traverse (Type& c) + { + os << "<inheritscomponent repid=\"" + << c.context ().get<string> (STRS[REPO_ID]) + << "\"/>" + << endl; + } + }; + + struct ComponentSupportsEmitter : Traversal::Interface, EmitterBase + { + ComponentSupportsEmitter (fs::ofstream& ofs) + : EmitterBase (ofs) + {} + + virtual void + traverse (Type& i) + { + os << "<supportsinterface repid=\"" + << i.context ().get<string> (STRS[REPO_ID]) + << "\"/>" + << endl; + } + }; + + struct PortsEmitter : Traversal::EmitterData, + Traversal::UserData, + Traversal::ProviderData, + Traversal::ConsumerData, + Traversal::PublisherData, + EmitterBase + { + PortsEmitter (fs::ofstream& ofs) + : EmitterBase (ofs), + type_name_emitter_ (ofs), + facettag_ (1U) + { + belongs_.node_traverser (type_name_emitter_); + } + + virtual void + traverse (SemanticGraph::Emitter& e) + { + os << "<emits" << endl + << "emitsname=\"" << e.name () << "\"" << endl + << "eventtype="; + + Traversal::EmitterData::belongs (e, belongs_); + + os << ">" << endl + << "<eventpolicy policy=\"normal\"/>" << endl + << "</emits>" << endl; + } + + virtual void + traverse (SemanticGraph::User& u) + { + os << "<uses" << endl + << "usesname=\"" << u.name () << "\"" << endl + << "repid="; + + Traversal::UserData::belongs (u, belongs_); + + os << ">" << endl + << "</uses>" << endl; + } + + virtual void + traverse (SemanticGraph::Provider& p) + { + os << "<provides" << endl + << "providesname=\"" << p.name () << "\"" << endl + << "repid="; + + Traversal::ProviderData::belongs (p, belongs_); + + os << endl + << "facettag=\"" << facettag_ << "\">" << endl + << "</provides>" << endl; + + ++facettag_; + } + + virtual void + traverse (SemanticGraph::Consumer& c) + { + os << "<consumes" << endl + << "consumesname=\"" << c.name () << "\"" << endl + << "eventtype="; + + Traversal::ConsumerData::belongs (c, belongs_); + + os << ">" << endl + << "<eventpolicy policy=\"normal\"/>" << endl + << "</consumes>" << endl; + } + + virtual void + traverse (SemanticGraph::Publisher& p) + { + os << "<publishes" << endl + << "publishesname=\"" << p.name () + << "\"" << endl + << "eventtype="; + + Traversal::PublisherData::belongs (p, belongs_); + + os << ">" << endl + << "<eventpolicy policy=\"normal\"/>" << endl + << "</publishes>" << endl; + } + + struct FullTypeNameEmitter : Traversal::Type, EmitterBase + { + FullTypeNameEmitter (fs::ofstream& ofs) + : EmitterBase (ofs) + {} + + virtual void + traverse (SemanticGraph::Type& t) + { + os << '\"' + << t.context ().get<string> (STRS[REPO_ID]) + << '\"'; + } + }; + + private: + FullTypeNameEmitter type_name_emitter_; + unsigned long facettag_; + Traversal::Belongs belongs_; + }; + }; + + struct InterfaceEmitter : Traversal::UnconstrainedInterface, + EmitterBase + { + InterfaceEmitter (fs::ofstream& ofs) + : EmitterBase (ofs) + {} + + bool + add (UnconstrainedInterface& i) + { + return interfaces_.insert (&i).second; + } + + virtual void + traverse (UnconstrainedInterface& i) + { + if (add (i)) + { + os << "<interface" << endl + << "name=\"" << i.name () + << "\"" << endl + << "repid=\"" + << i.context ().get<string> (STRS[REPO_ID]) + << "\">" << endl; + + Traversal::Inherits interface_inherits; + InterfaceInheritanceEmitter i_emitter (os); + interface_inherits.node_traverser (i_emitter); + + inherits (i, interface_inherits); + + os << "</interface>" << endl << endl; + + // Go after inherited interfaces. + Traversal::UnconstrainedInterface::traverse (i); + } + } + + struct InterfaceInheritanceEmitter : Traversal::Interface, EmitterBase + { + InterfaceInheritanceEmitter (fs::ofstream& ofs) + : EmitterBase (ofs) + {} + + virtual void + traverse (Type& i) + { + os << "<inheritsinterface repid=\"" + << i.context ().get<string> (STRS[REPO_ID]) + << "\"/>" << endl; + } + }; + + private: + std::set<UnconstrainedInterface*> interfaces_; + }; + + public: + CompositionEmitter (fs::ofstream& ofs, + CommandLine const& cl) + : EmitterBase (ofs), + cl_ (cl) + {} + + virtual void + traverse (Composition& c) + { + ScopedName scoped (c.scoped_name ()); + Name stripped (scoped.begin () + 1, scoped.end ()); + string name (stripped.unescaped_str ()); + configure_stream (name); + + os << "<?xml version=\"1.0\"?>" << endl + << "<!DOCTYPE corbacomponent SYSTEM \"corbacomponent.dtd\">" + << endl << endl; + + os << "<corbacomponent>" << endl + << "<corbaversion>3.0</corbaversion>" << endl; + + { + ComponentIdEmitter component_id_emitter (os); + HomeIdEmitter home_id_emitter (os); + Traversal::Defines defines; + Traversal::ComponentExecutor component_executor; + Traversal::HomeExecutor home_executor; + defines.node_traverser (component_executor); + defines.node_traverser (home_executor); + Traversal::Implements implements; + component_executor.edge_traverser (implements); + home_executor.edge_traverser (implements); + implements.node_traverser (component_id_emitter); + implements.node_traverser (home_id_emitter); + + names (c, defines); + } + + os << "<componentkind>" << endl + << "<session>" << endl + << "<servant lifetime=\"container\"/>" << endl + << "</session>" << endl + << "</componentkind>" << endl + << "<threading policy=\"multithread\"/>" << endl + << "<configurationcomplete set=\"true\"/>" << endl << endl; + + { + HomeFeaturesEmitter home_features_emitter (os); + Traversal::Defines defines; + Traversal::HomeExecutor home_executor; + defines.node_traverser (home_executor); + Traversal::Implements implements; + home_executor.edge_traverser (implements); + implements.node_traverser (home_features_emitter); + + Traversal::Inherits inherits; + home_features_emitter.edge_traverser (inherits); + inherits.node_traverser (home_features_emitter); + + names (c, defines); + } + + { + ComponentFeaturesEmitter component_features_emitter (os); + Traversal::Defines defines; + Traversal::ComponentExecutor component_executor; + defines.node_traverser (component_executor); + Traversal::Implements implements; + component_executor.edge_traverser (implements); + implements.node_traverser (component_features_emitter); + + Traversal::Inherits inherits; + component_features_emitter.edge_traverser (inherits); + inherits.node_traverser (component_features_emitter); + + names (c, defines); + } + + { + Traversal::Component component; + Traversal::Home home; + Traversal::Defines defines; + Traversal::ComponentExecutor component_executor; + Traversal::HomeExecutor home_executor; + defines.node_traverser (component_executor); + defines.node_traverser (home_executor); + Traversal::Implements implements; + component_executor.edge_traverser (implements); + home_executor.edge_traverser (implements); + implements.node_traverser (component); + implements.node_traverser (home); + + Traversal::Supports supports; + InterfaceEmitter interface_emitter (os); + supports.node_traverser (interface_emitter); + component.edge_traverser (supports); + home.edge_traverser (supports); + + Traversal::Defines component_defines; + component.edge_traverser (component_defines); + Traversal::Provider provider; + Traversal::User user; + component_defines.node_traverser (provider); + component_defines.node_traverser (user); + Traversal::Belongs belongs; + belongs.node_traverser (interface_emitter); + provider.edge_traverser (belongs); + user.edge_traverser (belongs); + + Traversal::Inherits inherits; + inherits.node_traverser (interface_emitter); + interface_emitter.edge_traverser (inherits); + + names (c, defines); + } + + os << "</corbacomponent>" << endl; + } + + private: + void configure_stream (string const& scoped_name) + { + string file_suffix = cl_.get_value ("desc-file-suffix", + ".ccd"); + + string desc_file_name = regex::perl_s (scoped_name, "/::/_/"); + + desc_file_name += file_suffix; + + fs::path desc_file_path (desc_file_name); + + if (os.is_open ()) + { + os.close (); + } + + os.open (desc_file_path, std::ios_base::out); + + if (!os.is_open ()) + { + cerr << desc_file_name + << ": error: unable to open file in write mode" + << endl; + } + } + + private: + CommandLine const& cl_; + }; +} + +// ========================================================== + +void +DescriptorGenerator::options (CL::Description& d) +{ + d.add_option (CL::OptionDescription ( + "desc-file-suffix", + "suffix", + "Use provided suffix instead of default \'.ccd\' " + "when constructing name of descriptor file.", + CL::OptionType::value)); + + d.add_option (CL::OptionDescription ( + "desc-file-regex", + "regex", + "Use provided regular expression when constructing " + "name of descriptor file.", + CL::OptionType::value)); +} + +void +DescriptorGenerator::generate (CommandLine const& cl, + TranslationUnit& u) +{ + // Set auto-indentation for os. + // + Indentation::Implanter<Indentation::XML> guard (ofs_); + + // Set unescaped name printer for os. + // + UnescapedNamePrinter name_printer; + ofs_.pword (name_printer_index) = &name_printer; + + // + Traversal::TranslationUnit unit; + + // Layer 1 + // + Traversal::ContainsPrincipal contains_principal; + unit.edge_traverser (contains_principal); + + //-- + Traversal::TranslationRegion region; + contains_principal.node_traverser (region); + + // Layer 2 + // + Traversal::ContainsRoot contains_root; + Traversal::Includes includes; + + region.edge_traverser (includes); + region.edge_traverser (contains_root); + + //-- + Traversal::Root root; + includes.node_traverser (region); + contains_root.node_traverser (root); + + // Layer 3 + // + Traversal::Defines defines; + root.edge_traverser (defines); + + //-- + Traversal::Module module; + CompositionEmitter composition (ofs_, cl); + defines.node_traverser (module); + defines.node_traverser (composition); + + unit.traverse (u); +} |