diff options
Diffstat (limited to 'modules/CIAO/tools/IDL3_to_XMI')
19 files changed, 6395 insertions, 0 deletions
diff --git a/modules/CIAO/tools/IDL3_to_XMI/CIAO_IDL3_TO_XMI_Export.h b/modules/CIAO/tools/IDL3_to_XMI/CIAO_IDL3_TO_XMI_Export.h new file mode 100644 index 00000000000..d34de5bdfd3 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_XMI/CIAO_IDL3_TO_XMI_Export.h @@ -0,0 +1,58 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl CIAO_IDL3_TO_XMI +// ------------------------------ +#ifndef CIAO_IDL3_TO_XMI_EXPORT_H +#define CIAO_IDL3_TO_XMI_EXPORT_H + +#include "ace/config-all.h" + +#if defined (ACE_AS_STATIC_LIBS) && !defined (CIAO_IDL3_TO_XMI_HAS_DLL) +# define CIAO_IDL3_TO_XMI_HAS_DLL 0 +#endif /* ACE_AS_STATIC_LIBS && CIAO_IDL3_TO_XMI_HAS_DLL */ + +#if !defined (CIAO_IDL3_TO_XMI_HAS_DLL) +# define CIAO_IDL3_TO_XMI_HAS_DLL 1 +#endif /* ! CIAO_IDL3_TO_XMI_HAS_DLL */ + +#if defined (CIAO_IDL3_TO_XMI_HAS_DLL) && (CIAO_IDL3_TO_XMI_HAS_DLL == 1) +# if defined (CIAO_IDL3_TO_XMI_BUILD_DLL) +# define CIAO_IDL3_TO_XMI_Export ACE_Proper_Export_Flag +# define CIAO_IDL3_TO_XMI_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define CIAO_IDL3_TO_XMI_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* CIAO_IDL3_TO_XMI_BUILD_DLL */ +# define CIAO_IDL3_TO_XMI_Export ACE_Proper_Import_Flag +# define CIAO_IDL3_TO_XMI_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define CIAO_IDL3_TO_XMI_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* CIAO_IDL3_TO_XMI_BUILD_DLL */ +#else /* CIAO_IDL3_TO_XMI_HAS_DLL == 1 */ +# define CIAO_IDL3_TO_XMI_Export +# define CIAO_IDL3_TO_XMI_SINGLETON_DECLARATION(T) +# define CIAO_IDL3_TO_XMI_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* CIAO_IDL3_TO_XMI_HAS_DLL == 1 */ + +// Set CIAO_IDL3_TO_XMI_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (CIAO_IDL3_TO_XMI_NTRACE) +# if (ACE_NTRACE == 1) +# define CIAO_IDL3_TO_XMI_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define CIAO_IDL3_TO_XMI_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !CIAO_IDL3_TO_XMI_NTRACE */ + +#if (CIAO_IDL3_TO_XMI_NTRACE == 1) +# define CIAO_IDL3_TO_XMI_TRACE(X) +#else /* (CIAO_IDL3_TO_XMI_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define CIAO_IDL3_TO_XMI_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (CIAO_IDL3_TO_XMI_NTRACE == 1) */ + +#endif /* CIAO_IDL3_TO_XMI_EXPORT_H */ + +// End of auto generated file. diff --git a/modules/CIAO/tools/IDL3_to_XMI/IDL3_TO_XMI.mpc b/modules/CIAO/tools/IDL3_to_XMI/IDL3_TO_XMI.mpc new file mode 100644 index 00000000000..57db9772560 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_XMI/IDL3_TO_XMI.mpc @@ -0,0 +1,65 @@ +// -*- MPC -*- +// $Id$ + +project(CIAO_IDL3_TO_XMI_BE) : acelib, install, ciao_output, ciao_xml_utils, tao_idl_fe { + sharedname = CIAO_IDL3_TO_XMI_BE + dynamicflags = CIAO_IDL3_TO_XMI_BUILD_DLL + + // This is necessary for MPC to pull in rules.ciao.GNU + includes += $(CIAO_ROOT) + + Source_Files { + be_global.cpp + be_helper.cpp + be_init.cpp + be_produce.cpp + be_sunsoft.cpp + IDL3_to_XMI_visitor.cpp + IR_Simulator_visitor.cpp + Literals.cpp + identifier_helper.cpp + } + + Header_Files { + be_extern.h + be_global.h + be_helper.h + be_sunsoft.h + IDL3_to_XMI_visitor.h + CIAO_IDL3_TO_XMI_Export.h + } +} + +project(CIAO_IDL3_TO_XMI_EXE) : aceexe, install, ciao_output, ciao_xml_utils, tao_idl_mcpp, xerces, tao_idl_fe { + after += CIAO_IDL3_TO_XMI_BE + exename = tao_idl3_to_xmi + libs += CIAO_IDL3_TO_XMI_BE + includes += $(TAO_ROOT) . + exeout = $(CIAO_ROOT)/bin + + // Adding a strict ordering dependency with TAO_IDL_EXE. It appears on some systems, there + // can be a race between these two projects for tao_idl.cpp, causing some errors. + after += TAO_IDL_EXE + + // This is necessary for MPC to pull in rules.ciao.GNU + includes += $(CIAO_ROOT) + + verbatim(gnuace, local) { + ifeq ($(TAO_IDL_PREPROCESSOR),) + CPPFLAGS += -DTAO_IDL_PREPROCESSOR=\\\"$(strip $(CXX))\\\" + else + CPPFLAGS += -DTAO_IDL_PREPROCESSOR=\\\"$(subst \\,\\,$(TAO_IDL_PREPROCESSOR))\\\" + endif + + VPATH = $(TAO_ROOT)/TAO_IDL $(TAO_ROOT)/TAO_IDL/driver + } + + Source_Files { + $(TAO_ROOT)/TAO_IDL/driver/drv_args.cpp + $(TAO_ROOT)/TAO_IDL/tao_idl.cpp + } + + Header_Files { + $(TAO_ROOT)/TAO_IDL/include/drv_extern.h + } +} diff --git a/modules/CIAO/tools/IDL3_to_XMI/IDL3_to_XMI_visitor.cpp b/modules/CIAO/tools/IDL3_to_XMI/IDL3_to_XMI_visitor.cpp new file mode 100644 index 00000000000..0005b5e0f28 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_XMI/IDL3_to_XMI_visitor.cpp @@ -0,0 +1,2692 @@ +// $Id$ + +#include "IDL3_to_XMI_visitor.h" +#include "identifier_helper.h" + +#include "be_sunsoft.h" +#include "be_extern.h" + +#include "ast_argument.h" +#include "ast_array.h" +#include "ast_attribute.h" +#include "ast_component_fwd.h" +#include "ast_provides.h" +#include "ast_uses.h" +#include "ast_publishes.h" +#include "ast_emits.h" +#include "ast_consumes.h" +#include "ast_enum.h" +#include "ast_enum_val.h" +#include "ast_eventtype.h" +#include "ast_eventtype_fwd.h" +#include "ast_exception.h" +#include "ast_factory.h" +#include "ast_field.h" +#include "ast_home.h" +#include "ast_operation.h" +#include "ast_root.h" +#include "ast_sequence.h" +#include "ast_string.h" +#include "ast_structure_fwd.h" +#include "ast_template_module.h" +#include "ast_template_module_inst.h" +#include "ast_template_module_ref.h" +#include "ast_typedef.h" +#include "ast_union.h" +#include "ast_union_branch.h" +#include "ast_union_fwd.h" +#include "ast_union_label.h" +#include "ast_valuebox.h" +#include "ast_valuetype_fwd.h" +#include "ast_native.h" +#include "utl_exceptlist.h" +#include "utl_identifier.h" +#include "utl_idlist.h" +#include "utl_string.h" +#include "global_extern.h" +#include "nr_extern.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_sys_time.h" +#include "ace/ACE.h" + +#include "Literals.h" +#include "XML/XercesString.h" + +#include <iostream> +#include <limits> +#include <sstream> + +#include "xercesc/dom/DOM.hpp" +#include "xercesc/util/XMLChar.hpp" + +#include "XML/XML_Helper.h" + +using XERCES_CPP_NAMESPACE::DOMDocument; +using XERCES_CPP_NAMESPACE::DOMAttr; +using XERCES_CPP_NAMESPACE::DOMElement; +using XERCES_CPP_NAMESPACE::DOMText; +using XERCES_CPP_NAMESPACE::DOMDocumentType; +using XERCES_CPP_NAMESPACE::XMLChar1_1; +using CIAO::XML::XStr; + +#if 0 +struct Foo { + std::string foo_; + Foo (const char *foo) : foo_ (foo) + { + std::cout << "Entering " << foo_ << std::endl; + } + ~Foo () + { + std::cout << "Leaving " << foo_ << std::endl; + } +}; + +#define XMI_TRACE(X) Foo _foobarbaz (X); +#else +#define XMI_TRACE(X) +#endif + +namespace CIAO +{ + namespace XMI + { + size_t idl3_to_xmi_visitor::current_id_ = 0; + + template <typename T> + ACE_TCHAR * + idl3_to_xmi_visitor::number_to_string (T val) + { + std::stringstream str; + + str << val; + + return ACE::strnew (ACE_TEXT_CHAR_TO_TCHAR (str.str ().c_str ())); + } + + template <> + ACE_TCHAR * + idl3_to_xmi_visitor::number_to_string (bool val) + { + if (val) + return ACE::strnew (LITERALS[CAPS_TRUE]); + else + return ACE::strnew (LITERALS[CAPS_FALSE]); + } + + template <> + ACE_TCHAR * + idl3_to_xmi_visitor::number_to_string (char val) + { + // There is no way to convert any char to xml encoding nicely + // so we convert it to a decimal integer. This will preserve at + // least a correct char value instead of some non-printable xml. + std::stringstream str; + + str << static_cast<unsigned int>(static_cast<unsigned char> (val)); + + return ACE::strnew (ACE_TEXT_CHAR_TO_TCHAR (str.str ().c_str ())); + } + + template <> + ACE_TCHAR * + idl3_to_xmi_visitor::number_to_string (wchar_t val) + { + // There is no way to convert any char to xml encoding nicely + // so we convert it to a decimal integer. This will preserve at + // least a correct char value instead of some non-printable xml. + std::stringstream str; + + str << static_cast<unsigned long>(static_cast<wchar_t> (val)); + + return ACE::strnew (ACE_TEXT_CHAR_TO_TCHAR (str.str ().c_str ())); + } + + idl3_to_xmi_visitor::idl3_to_xmi_visitor (bool skip_imported) + : dom_ (0), + root_ (0), + generalizations_ (0), + associations_ (0), + base_id_ (idl3_to_xmi_visitor::gen_xmi_id ()), + skip_imported_ (skip_imported), + visiting_enum_ (false), + union_disc_ (0) + { + } + + idl3_to_xmi_visitor::~idl3_to_xmi_visitor (void) + { + } + + int + idl3_to_xmi_visitor::visit_decl (AST_Decl *) + { + XMI_TRACE ("got a decl"); + return 0; + } + + char * + copy_scoped_name (UTL_ScopedName *name) + { + ACE_CString fullname; + for (UTL_ScopedNameActiveIterator si (name); + !si.is_done (); + si.next ()) + { + Identifier *item = si.item (); + fullname += item->get_string (); + } + + return fullname.rep (); + } + + int + idl3_to_xmi_visitor::visit_scope (UTL_Scope *node) + { + XMI_TRACE ("got a scope"); + + this->order_ = 0; + + for (UTL_ScopeActiveIterator si (node, UTL_Scope::IK_decls); + !si.is_done (); + si.next ()) + { + AST_Decl *d = si.item (); + d->ast_accept (this); + ++this->order_; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_type (AST_Type *) + { + XMI_TRACE ("got a type"); + return 0; + } + + int + idl3_to_xmi_visitor::visit_predefined_type (AST_PredefinedType *node) + { + XMI_TRACE ("predef type"); + + char const *local_name = 0; + switch (node->pt ()) + { + case AST_PredefinedType::PT_pseudo: + // Only a limited number of predefined pseudo types + // needs our attention. + local_name = node->original_local_name ()->get_string (); + if (ACE_OS::strcmp (local_name, "TypeCode") == 0) + { + ES_Guard class_guard (LITERALS[CLASS_TAG], this); + this->gen_common_elements (node, LITERALS[ST_TC]); + } + default: + break; + } + return 0; + } + + int + idl3_to_xmi_visitor::visit_module (AST_Module *node) + { + XMI_TRACE ("module"); + + try + { + ElementContext ec; + if (this->repo_id_map_.find (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec) == 0) + { + // If the module is reopened then put it on the stack. + NS_Guard ns_guard (ec.ns_.c_str (), this); + ES_Guard owned_guard (ec.elem_, this); + this->visit_scope (node); + // And don't do anything more. + return 0; + } + + ES_Guard package_guard (LITERALS[PACKAGE_TAG], this); + this->gen_common_elements (node, LITERALS[ST_MODULE]); + + { + NS_Guard ns_guard (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), this); + ES_Guard owned_guard (LITERALS[OWNEDELEMENT_TAG], this); + + // Save ownedElement to add to it later if the module + // will be reopened. + this->stack_.top (ec.elem_); + // Same save namespace string. + this->namespace_.top (ec.ns_); + this->repo_id_map_.bind (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec); + + this->visit_scope (node); + } + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_template_module (AST_Template_Module *) + { + return 0; + } + + int + idl3_to_xmi_visitor::visit_template_module_inst ( + AST_Template_Module_Inst *) + { + return 0; + } + + int + idl3_to_xmi_visitor::visit_template_module_ref (AST_Template_Module_Ref *) + { + return 0; + } + + int + idl3_to_xmi_visitor::visit_param_holder (AST_Param_Holder *) + { + return 0; + } + + int + idl3_to_xmi_visitor::visit_finder (AST_Finder *) + { + return 0; + } + + int + idl3_to_xmi_visitor::visit_interface (AST_Interface *node) + { + XMI_TRACE ("interface"); + + if (this->skip_imported_ && node->imported ()) + { + this->visit_scope (node); + return 0; + } + + try + { + ElementContext ec; + if (this->repo_id_map_.find (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec) != 0) + { + ES_Guard class_guard (LITERALS[CLASS_TAG], this); + this->gen_common_elements (node, LITERALS[ST_INTF]); + NS_Guard ns_guard (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), this); + + // Save in order not to generate same element later. + this->stack_.top (ec.elem_); + this->namespace_.top (ec.ns_); + this->repo_id_map_.bind (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec); + } + + ES_Guard class_guard (ec.elem_, this); + NS_Guard ns_guard (ec.ns_.c_str (), this); + + { // Operations. + ES_Guard owned_guard (LITERALS[OWNEDELEMENT_TAG], this); + this->cached_type_ = node; + this->visit_scope (node); + this->cached_type_ = 0; + } + + // Inheritance + for (long i = 0; i < node->n_inherits (); ++i) + { + XStr xid (this->add_generalization ( + ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), + ACE_TEXT_CHAR_TO_TCHAR (node->inherits ()[i]->repoID ()))); + } + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_interface_fwd (AST_InterfaceFwd *node) + { + XMI_TRACE ("interface_fwd"); + + try + { + ElementContext ec; + if (this->repo_id_map_.find (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec) != 0) + { + ES_Guard class_guard (LITERALS[CLASS_TAG], this); + this->gen_common_elements (node, LITERALS[ST_INTF]); + NS_Guard ns_guard (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), this); + + // Save in order not to generate same element later. + this->stack_.top (ec.elem_); + this->namespace_.top (ec.ns_); + this->repo_id_map_.bind (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec); + } + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_valuebox (AST_ValueBox *node) + { + XMI_TRACE ("valuebox"); + + if (this->skip_imported_ && node->imported ()) + { + return 0; + } + + try + { + ES_Guard class_guard (LITERALS[CLASS_TAG], this); + this->gen_common_elements (node, LITERALS[ST_BOXVALUE]); + + // add a generalization for the value we box + XStr xid (this->add_generalization ( + ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), + ACE_TEXT_CHAR_TO_TCHAR (node->boxed_type ()->repoID ()))); + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + void + idl3_to_xmi_visitor::visit_valuetype_impl (AST_ValueType *node) + { + try + { + // isAbstract + if (node->is_abstract ()) + { + this->set_attribute (LITERALS[ABSTRACT], LITERALS[_TRUE]); + } + else + { + this->set_attribute (LITERALS[ABSTRACT], LITERALS[_FALSE]); + } + + if (node->inherits_concrete () != 0) + { + XStr xid (this->add_generalization ( + ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), + ACE_TEXT_CHAR_TO_TCHAR (node->inherits_concrete ()->repoID ()))); + } + + for (long i = 0; i < node->n_supports (); ++i) + { + XStr xid (this->add_generalization ( + ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), + ACE_TEXT_CHAR_TO_TCHAR (node->supports ()[i]->repoID ()))); + } + + ES_Guard oe_guard (LITERALS[OWNEDELEMENT_TAG], this); + + this->cached_type_ = node; + this->visit_scope (node); + this->cached_type_ = 0; + } + catch (Error &err) + { + err.node (node); + throw; + } + } + + int + idl3_to_xmi_visitor::visit_valuetype (AST_ValueType *node) + { + XMI_TRACE ("valuetype"); + + if (this->skip_imported_ && node->imported ()) + { + this->visit_scope (node); + return 0; + } + + try + { + ElementContext ec; + if (this->repo_id_map_.find (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec) != 0) + { + ES_Guard class_guard (LITERALS[CLASS_TAG], this); + this->gen_common_elements (node, LITERALS[ST_VALUE]); + NS_Guard ns_guard (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), this); + + // Save in order not to generate same element later. + this->stack_.top (ec.elem_); + this->namespace_.top (ec.ns_); + this->repo_id_map_.bind (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec); + } + + ES_Guard class_guard (ec.elem_, this); + NS_Guard ns_guard (ec.ns_.c_str (), this); + + this->visit_valuetype_impl (node); + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_valuetype_fwd (AST_ValueTypeFwd *node) + { + XMI_TRACE ("valuetype_fwd"); + + try + { + ElementContext ec; + if (this->repo_id_map_.find (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec) != 0) + { + ES_Guard class_guard (LITERALS[CLASS_TAG], this); + this->gen_common_elements (node, LITERALS[ST_VALUE]); + NS_Guard ns_guard (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), this); + + // Save in order not to generate same element later. + this->stack_.top (ec.elem_); + this->namespace_.top (ec.ns_); + this->repo_id_map_.bind (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec); + } + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_eventtype (AST_EventType *node) + { + XMI_TRACE ("eventtype"); + + if (this->skip_imported_ && node->imported ()) + { + this->visit_scope (node); + return 0; + } + + try + { + ElementContext ec; + if (this->repo_id_map_.find (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec) != 0) + { + ES_Guard class_guard (LITERALS[CLASS_TAG], this); + this->gen_common_elements (node, LITERALS[ST_EVENT]); + NS_Guard ns_guard (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), this); + + // Save in order not to generate same element later. + this->stack_.top (ec.elem_); + this->namespace_.top (ec.ns_); + this->repo_id_map_.bind (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec); + } + + ES_Guard class_guard (ec.elem_, this); + NS_Guard ns_guard (ec.ns_.c_str (), this); + + this->visit_valuetype_impl (node); + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_eventtype_fwd (AST_EventTypeFwd *node) + { + XMI_TRACE ("eventtype_fwd"); + + try + { + ElementContext ec; + if (this->repo_id_map_.find (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec) != 0) + { + ES_Guard class_guard (LITERALS[CLASS_TAG], this); + this->gen_common_elements (node, LITERALS[ST_EVENT]); + NS_Guard ns_guard (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), this); + + // Save in order not to generate same element later. + this->stack_.top (ec.elem_); + this->namespace_.top (ec.ns_); + this->repo_id_map_.bind (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec); + } + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_component (AST_Component *node) + { + XMI_TRACE ("component"); + + if (this->skip_imported_ && node->imported ()) + { + this->visit_scope (node); + return 0; + } + + try + { + ElementContext ec; + if (this->repo_id_map_.find (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec) != 0) + { + ES_Guard class_guard (LITERALS[CLASS_TAG], this); + this->gen_common_elements (node, LITERALS[ST_COMP]); + NS_Guard ns_guard (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), this); + + // Save in order not to generate same element later. + this->stack_.top (ec.elem_); + this->namespace_.top (ec.ns_); + this->repo_id_map_.bind (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec); + } + + ES_Guard class_guard (ec.elem_, this); + NS_Guard ns_guard (ec.ns_.c_str (), this); + + for (long i = 0; i < node->n_supports (); ++i) + { + XStr xid (this->add_generalization ( + ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), + ACE_TEXT_CHAR_TO_TCHAR (node->supports ()[i]->repoID ()))); + + } + + if (node->base_component () != 0) + { + XStr xid (this->add_generalization ( + ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), + ACE_TEXT_CHAR_TO_TCHAR (node->base_component ()->repoID ()))); + } + + ES_Guard oe_guard (LITERALS[OWNEDELEMENT_TAG], this); + + this->cached_type_ = node; + this->visit_scope (node); + this->cached_type_ = 0; + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_component_fwd (AST_ComponentFwd *node) + { + XMI_TRACE ("component_fwd"); + + try + { + ElementContext ec; + if (this->repo_id_map_.find (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec) != 0) + { + ES_Guard class_guard (LITERALS[CLASS_TAG], this); + this->gen_common_elements (node, LITERALS[ST_COMP]); + NS_Guard ns_guard (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), this); + + // Save in order not to generate same element later. + this->stack_.top (ec.elem_); + this->namespace_.top (ec.ns_); + this->repo_id_map_.bind (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec); + } + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_provides (AST_Provides *node) + { + this->add_port (LITERALS[ST_PROVIDES], node); + return 0; + } + + int + idl3_to_xmi_visitor::visit_uses (AST_Uses *node) + { + this->add_port (LITERALS[ST_USES], node); + return 0; + } + + int + idl3_to_xmi_visitor::visit_publishes (AST_Publishes *node) + { + this->add_port (LITERALS[ST_PUBLISH], node); + return 0; + } + + int + idl3_to_xmi_visitor::visit_emits (AST_Emits *node) + { + this->add_port (LITERALS[ST_EMITS], node); + return 0; + } + + int + idl3_to_xmi_visitor::visit_consumes (AST_Consumes *node) + { + this->add_port (LITERALS[ST_CONSUMES], node); + return 0; + } + + int + idl3_to_xmi_visitor::visit_porttype (AST_PortType *) + { + return 0; + } + + int + idl3_to_xmi_visitor::visit_extended_port (AST_Extended_Port *) + { + return 0; + } + + int + idl3_to_xmi_visitor::visit_mirror_port (AST_Mirror_Port *) + { + return 0; + } + + int + idl3_to_xmi_visitor::visit_connector (AST_Connector *) + { + return 0; + } + + int + idl3_to_xmi_visitor::visit_home (AST_Home *node) + { + XMI_TRACE ("home"); + + if (this->skip_imported_ && node->imported ()) + { + this->visit_scope (node); + return 0; + } + + try + { + ES_Guard es_guard (LITERALS[CLASS_TAG], this); + this->gen_common_elements (node, LITERALS[ST_HOME]); + NS_Guard ns_guard (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), this); + + for (long i = 0; i < node->n_supports (); ++i) + { + XStr xid (this->add_generalization ( + ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), + ACE_TEXT_CHAR_TO_TCHAR (node->supports ()[i]->repoID ()))); + } + + if (node->base_home () != 0) + { + XStr xid (this->add_generalization ( + ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), + ACE_TEXT_CHAR_TO_TCHAR (node->base_home ()->repoID ()))); + } +/* + * @@@ (JP) This code will be moved to the appropriate visit_* methods + * + if (node->factories ().size () != 0) + { + ES_Guard noe_guard (LITERALS[OWNEDELEMENT_TAG], this); + + for (size_t i = 0; i < node->factories ().size (); ++i) + { + AST_Operation **op = 0; + node->factories ().get (op, i); + this->visit_operation_impl (*op, LITERALS[ST_HFACT]); + } + } + + if (node->finders () .size () != 0) + { + throw Error ("home finders not supported", node); + } +*/ + this->add_managed_component ( + ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), + ACE_TEXT_CHAR_TO_TCHAR (node->managed_component ()->repoID ())); + + ES_Guard noe_guard (LITERALS[OWNEDELEMENT_TAG], this); + + // attributes in scope. + this->cached_type_ = node; + this->visit_scope (node); + this->cached_type_ = 0; + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_factory (AST_Factory *node) + { + XMI_TRACE ("factory"); + + if (this->skip_imported_ && node->imported ()) + { + return 0; + } + + throw Error ("Factories not supported", node); + + return 0; + } + + void + idl3_to_xmi_visitor::visit_struct_impl (AST_Structure *node) + { + try + { + ES_Guard ns_oe_guard (LITERALS[OWNEDELEMENT_TAG], this); + this->visit_scope (node); + } + catch (Error &err) + { + err.node (node); + throw; + } + } + + int + idl3_to_xmi_visitor::visit_structure (AST_Structure *node) + { + XMI_TRACE ("structure"); + + if (this->skip_imported_ && node->imported ()) + { + this->visit_scope (node); + return 0; + } + + try + { + ElementContext ec; + if (this->repo_id_map_.find (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec) != 0) + { + ES_Guard class_guard (LITERALS[CLASS_TAG], this); + this->gen_common_elements (node, LITERALS[ST_STRUCT]); + NS_Guard ns_guard (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), this); + + // Save in order not to generate same element later. + this->stack_.top (ec.elem_); + this->namespace_.top (ec.ns_); + this->repo_id_map_.bind (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec); + } + + ES_Guard class_guard (ec.elem_, this); + NS_Guard ns_guard (ec.ns_.c_str (), this); + + this->visit_struct_impl (node); + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_structure_fwd (AST_StructureFwd *node) + { + XMI_TRACE ("structure_fwd"); + + try + { + ElementContext ec; + if (this->repo_id_map_.find (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec) != 0) + { + ES_Guard class_guard (LITERALS[CLASS_TAG], this); + this->gen_common_elements (node, LITERALS[ST_STRUCT]); + NS_Guard ns_guard (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), this); + + // Save in order not to generate same element later. + this->stack_.top (ec.elem_); + this->namespace_.top (ec.ns_); + this->repo_id_map_.bind (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec); + } + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_exception (AST_Exception *node) + { + XMI_TRACE ("exception"); + + if (this->skip_imported_ && node->imported ()) + { + this->visit_scope (node); + return 0; + } + + try + { + ElementContext ec; + if (this->repo_id_map_.find (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec) != 0) + { + ES_Guard class_guard (LITERALS[EXCEPTION_TAG], this); + this->gen_common_elements (node, LITERALS[ST_EX]); + NS_Guard ns_guard (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), this); + + // Save in order not to generate same element later. + this->stack_.top (ec.elem_); + this->namespace_.top (ec.ns_); + this->repo_id_map_.bind (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec); + } + + ES_Guard class_guard (ec.elem_, this); + NS_Guard ns_guard (ec.ns_.c_str (), this); + + this->visit_struct_impl (node); + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_expression (AST_Expression *) + { + XMI_TRACE ("expression"); + + // we don't particularly care about expressions. + + return 0; + } + + int + idl3_to_xmi_visitor::visit_enum (AST_Enum *node) + { + XMI_TRACE ("enum"); + + if (this->skip_imported_ && node->imported ()) + { + this->visit_scope (node); + return 0; + } + + try + { + ES_Guard es_guard (LITERALS[CLASS_TAG], this); + this->gen_common_elements (node, LITERALS[ST_ENUM]); + + NS_Guard ns_guard (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), this); + ES_Guard oe_guard (LITERALS[OWNEDELEMENT_TAG], this); + + this->visiting_enum_ = true; + this->visit_scope (node); + this->visiting_enum_ = false; + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + void + idl3_to_xmi_visitor::visit_operation_impl (AST_Operation *op, + const ACE_TCHAR *stereotype) + { + XMI_TRACE ("operation"); + + if (this->skip_imported_ && op->imported ()) + { + this->visit_scope (op); + return; + } + + // This is a mess because the operation has so many special cases.... + try + { + ES_Guard op_guard (LITERALS[OP_TAG], this); + + // name and visiblity + this->set_attribute ( + LITERALS[NAME], + ACE_TEXT_CHAR_TO_TCHAR (op->original_local_name ()->get_string ())); + + this->set_attribute (LITERALS[VISIBIL], LITERALS[PUBLIC]); + + this->set_containing_element (LITERALS[OWNER]); + + // If we have a stereotype, set it + if (stereotype != 0) + { + this->find_and_set_xid_as_attr (LITERALS[STEREO_ATTR], + stereotype); + } + + // XMI ID + this->create_and_store_xmi_id (op); + + // while not strictly a namespace, the repo id goes on the + // namespace stack as the owner of contained elements. + NS_Guard ns_guard (ACE_TEXT_CHAR_TO_TCHAR (op->repoID ()), this); + + { // we need to generate the tagged value in a custom way here + ES_Guard me_guard (LITERALS[ME_TV_TAG], this); + + { + ES_Guard tv_guard (LITERALS[TV_TAG], this); + this->set_attribute (LITERALS[TAG], LITERALS[TYPEID]); + this->set_attribute (LITERALS[VALUE], + ACE_TEXT_CHAR_TO_TCHAR (op->repoID ())); + } + + UTL_ExceptList *exceptions = op->exceptions (); + + if (exceptions != 0 && exceptions->length () > 0) + { + for (UTL_ExceptlistActiveIterator ei (exceptions); + !ei.is_done (); + ei.next ()) + { + ES_Guard tv_guard (LITERALS[TV_TAG], this); + this->set_attribute (LITERALS[TAG], LITERALS[RAISES]); + this->set_attribute ( + LITERALS[VALUE], + ACE_TEXT_CHAR_TO_TCHAR (ei.item ()->full_name ())); + } + } + } + + ES_Guard bfp_guard (LITERALS[BFP_TAG], this); + + // return value + { + ES_Guard param_guard (LITERALS[PARAM_TAG], this); + + // I don't think anything else can refer to the parameter by + // xid, so I won't store it. + XStr xid = this->gen_xmi_id (op); + + this->set_attribute (LITERALS[XMI_ID], xid); + + this->set_attribute (LITERALS[KIND], LITERALS[RETURN]); + + this->set_containing_element (LITERALS[BFEATURE]); + + xid = this->lookup_type_xid (op->return_type ()); + this->set_attribute (LITERALS[TYPE], + xid); + } + + if (op->argument_count () != 0) + { + // Visit arguments + for (UTL_ScopeActiveIterator si (op, UTL_Scope::IK_decls); + !si.is_done ();) + { + si.item ()->ast_accept (this); + si.next (); + } + } + } + catch (Error &err) + { + err.node (op); + throw; + } + } + + int + idl3_to_xmi_visitor::visit_operation (AST_Operation *op) + { + XMI_TRACE ("operation"); + + this->visit_operation_impl (op, 0); + + return 0; + } + + int + idl3_to_xmi_visitor::visit_field (AST_Field *node) + { + XMI_TRACE ("field"); + + if (this->skip_imported_ && node->imported ()) + { + return 0; + } + + try + { + ES_Guard attr_guard (LITERALS[ATTR_TAG], this); + + if (node->field_type ()->node_type () == AST_Decl::NT_sequence) + { + AST_Sequence* sequence = + AST_Sequence::narrow_from_decl (node->field_type ()); + sequence->ast_accept (this); + // There is no need to proceed any further. + return 0; + } + else if (node->field_type ()->node_type () == AST_Decl::NT_array) + { + AST_Array* array = + AST_Array::narrow_from_decl (node->field_type ()); + array->ast_accept (this); + // There is no need to proceed any further. + return 0; + } + + // I don't think anything else can refer to the parameter by + // xid, so I won't store it. + XStr xid = this->gen_xmi_id (node); + this->set_attribute (LITERALS[XMI_ID], xid); + + this->set_attribute ( + LITERALS[NAME], + ACE_TEXT_CHAR_TO_TCHAR (node->original_local_name ()->get_string ())); + + switch (node->visibility ()) + { + case AST_Field::vis_NA: + case AST_Field::vis_PUBLIC: + this->set_attribute (LITERALS[VISIBIL], LITERALS[PUBLIC]); + break; + case AST_Field::vis_PRIVATE: + this->set_attribute (LITERALS[VISIBIL], LITERALS[_PRIVATE]); + break; + default: + throw Error ("unknown visibility type detected.", node); + } + + // I think this is fixed. + this->set_attribute (LITERALS[MULT], LITERALS[MULT_OTO]); + + this->set_containing_element (LITERALS[OWNER]); + + xid = this->lookup_type_xid (node->field_type ()); + this->set_attribute (LITERALS[TYPE], + xid); + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_argument (AST_Argument *node) + { + XMI_TRACE ("argument"); + + if (this->skip_imported_ && node->imported ()) + { + return 0; + } + + try + { + ES_Guard param_guard (LITERALS[PARAM_TAG], this); + + this->set_attribute ( + LITERALS[NAME], + ACE_TEXT_CHAR_TO_TCHAR (node->original_local_name ()->get_string ())); + + // I don't think anything else can refer to the parameter by + // xid, so I won't store it. + XStr xid = this->gen_xmi_id (node); + this->set_attribute (LITERALS[XMI_ID], xid); + + // kind + switch (node->direction ()) + { + case AST_Argument::dir_IN: + this->set_attribute (LITERALS[KIND], LITERALS[_IN]); + break; + + case AST_Argument::dir_INOUT: + this->set_attribute (LITERALS[KIND], LITERALS[INOUT]); + break; + + case AST_Argument::dir_OUT: + this->set_attribute (LITERALS[KIND], LITERALS[_OUT]); + break; + + default: + throw Error ("Unknown argument direction", node); + } + + this->set_containing_element (LITERALS[BFEATURE]); + + xid = this->lookup_type_xid (node->field_type ()); + this->set_attribute (LITERALS[TYPE], + xid); + + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_attribute (AST_Attribute *node) + { + XMI_TRACE ("attribute"); + + if (this->skip_imported_ && node->imported ()) + { + return 0; + } + + if (this->cached_type_ == 0) + { + ACE_ERROR ((LM_ERROR, "Zounds! %d\n", + this->cached_type_)); + throw Error ("Internal error - attribute expected " + "to have a cached type, but didn't"); + } + + try + { + // *** + NS_Guard global_ns (ACE_TEXT ("::"), this); + ES_Guard assoc_group (this->associations_, this); + ES_Guard assoc_g (LITERALS[ASSOC_TAG], this); + + // I don't think anything else can refer to the attribute by + // xid, so I won't store it. + XStr xid = this->gen_xmi_id (node); + this->set_attribute (LITERALS[XMI_ID], xid); + this->set_attribute (LITERALS[VISIBIL], LITERALS[PUBLIC]); + this->set_containing_element (LITERALS[NS]); + + if (node->readonly ()) + { + this->find_and_set_xid_as_attr (LITERALS[STEREO_ATTR], + LITERALS[ST_RO]); + } + + ES_Guard assoc_conn (LITERALS[ASSOC_CONN_TAG], this); + + { // Containing type + ES_Guard assoc_end (LITERALS[ASSOC_END_TAG], this); + this->set_attribute (LITERALS[MULT], ACE_TEXT ("1")); + this->find_and_set_xid_as_attr ( + LITERALS[TYPE], + ACE_TEXT_CHAR_TO_TCHAR (this->cached_type_->repoID ())); + } + + { + ES_Guard assoc_end (LITERALS[ASSOC_END_TAG], this); + this->set_attribute ( + LITERALS[NAME], + ACE_TEXT_CHAR_TO_TCHAR (node->original_local_name ()->get_string ())); + this->set_attribute (LITERALS[MULT], ACE_TEXT ("1")); + xid = this->lookup_type_xid (node->field_type ()); + this->set_attribute (LITERALS[TYPE], xid); + } + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_union (AST_Union *node) + { + XMI_TRACE ("union"); + + if (this->skip_imported_ && node->imported ()) + { + return 0; + } + + try + { + ElementContext ec; + if (this->repo_id_map_.find (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec) != 0) + { + ES_Guard class_guard (LITERALS[CLASS_TAG], this); + this->gen_common_elements (node, LITERALS[ST_UNION]); + NS_Guard ns_guard (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), this); + + // Save in order not to generate same element later. + this->stack_.top (ec.elem_); + this->namespace_.top (ec.ns_); + this->repo_id_map_.bind (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec); + } + + ES_Guard class_guard (ec.elem_, this); + NS_Guard ns_guard (ec.ns_.c_str (), this); + ES_Guard oe_guard (LITERALS[OWNEDELEMENT_TAG], this); + + // Set discriminator type + this->union_disc_ = node->disc_type (); + this->visit_scope (node); + this->union_disc_ = 0; + } + catch (Error &err) + { + this->union_disc_ = 0; + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_union_fwd (AST_UnionFwd *node) + { + XMI_TRACE ("union_fwd"); + + try + { + ElementContext ec; + if (this->repo_id_map_.find (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec) != 0) + { + ES_Guard class_guard (LITERALS[CLASS_TAG], this); + this->gen_common_elements (node, LITERALS[ST_UNION]); + NS_Guard ns_guard (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), this); + + // Save in order not to generate same element later. + this->stack_.top (ec.elem_); + this->namespace_.top (ec.ns_); + this->repo_id_map_.bind (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), ec); + } + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_union_branch (AST_UnionBranch *node) + { + XMI_TRACE ("union_branch"); + + try + { + ES_Guard attr_guard (LITERALS[ATTR_TAG], this); + + // I don't think anything else can refer to the parameter by + // xid, so I won't store it. + XStr xid = this->gen_xmi_id (node); + this->set_attribute (LITERALS[XMI_ID], xid); + + // name + this->set_attribute ( + LITERALS[NAME], + ACE_TEXT_CHAR_TO_TCHAR (node->original_local_name ()->get_string ())); + + // visiblity + this->set_attribute (LITERALS[VISIBIL], LITERALS[PUBLIC]); + + this->set_containing_element (LITERALS[OWNER]); + + // I think this is fixed. + this->set_attribute (LITERALS[MULT], LITERALS[MULT_ZTO]); + + xid = this->lookup_type_xid (node->field_type ()); + this->set_attribute (LITERALS[TYPE], + xid); + + { + ES_Guard me_tv_guard (LITERALS[ME_TV_TAG], this); + + { + ES_Guard tv_guard (LITERALS[TV_TAG], this); + this->set_attribute (LITERALS[TAG], LITERALS[IDLORDER]); + + // convert the order value to a string + // need a buffer, with a little safety padding + ACE_Auto_Basic_Array_Ptr<ACE_TCHAR> buffer + (this->number_to_string (this->order_)); + + this->set_attribute (LITERALS[VALUE], buffer.get ()); + } + + for (unsigned long i = 0; i < node->label_list_length (); ++i) + { + this->visit_union_label (node->label (i)); + } + + } + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + ACE_TCHAR * + idl3_to_xmi_visitor::union_label_value (AST_Expression *exp) + { + ACE_Auto_Basic_Array_Ptr<ACE_TCHAR> buffer; + + // @@TODO: Yuck, there has got to be a better way.... + AST_Expression::AST_ExprValue *ev = exp->ev (); + + if (exp->ec () != AST_Expression::EC_symbol || + this->union_disc_->node_type () == AST_Decl::NT_typedef || + this->union_disc_->node_type () == AST_Decl::NT_pre_defined) + { + /*AST_Expression::ExprType type; + + if (this->union_disc_->node_type () == AST_Decl::NT_typedef) + { + AST_Typedef *td (AST_Typedef::narrow_from_decl (this->union_disc_)); + type = td->base_type ()->node_type (); + } + else type = ev->et;*/ + + // Decode the type + switch (ev->et) + { + case AST_Expression::EV_long: + buffer.reset (this->number_to_string (ev->u.lval)); + break; + case AST_Expression::EV_ulong: + buffer.reset (this->number_to_string (ev->u.ulval)); + break; + case AST_Expression::EV_short: + buffer.reset (this->number_to_string (ev->u.sval)); + break; + case AST_Expression::EV_ushort: + buffer.reset (this->number_to_string (ev->u.usval)); + break; + case AST_Expression::EV_bool: + buffer.reset (this->number_to_string (ev->u.bval)); + break; + case AST_Expression::EV_char: + buffer.reset (this->number_to_string (ev->u.cval)); + break; + default: + throw Error ("Unknown union union label type"); + } + } + else + { + AST_Enum *desc (0); + + if ((desc = AST_Enum::narrow_from_decl (this->union_disc_)) == 0) + { + throw Error ("Descriminator type is not an enum"); + } + + AST_Decl *ev_decl = + desc->lookup_by_name (exp->n (), 1); + + if (ev_decl == 0) + { + throw Error ("Couldn't look up enum name"); + } + + AST_EnumVal *ev = AST_EnumVal::narrow_from_decl (ev_decl); + + if (ev == 0) + { + throw Error ("Couldn't look up enum name"); + } + + buffer.reset (ACE::strnew (ACE_TEXT_CHAR_TO_TCHAR (ev->full_name ()))); + //const char *name = desc->lookup_by_value (exp)->full_name (); + // const char *name = exp->n (); + //buffer.reset (copy_scoped_name (exp->n ())); + } + + if (buffer.get () == 0) + { + throw Error ("Unable to parse union label"); + } + + return buffer.release (); + } + + int + idl3_to_xmi_visitor::visit_union_label (AST_UnionLabel *node) + { + XMI_TRACE ("union_label"); + + ES_Guard tv_guard (LITERALS[TV_TAG], this); + this->set_attribute (LITERALS[TAG], LITERALS[CASE]); + + if (node->label_kind () == AST_UnionLabel::UL_default) + { + this->set_attribute (LITERALS[VALUE], + LITERALS[DEFAULT_UNION]); + } + else + { + ACE_Auto_Basic_Array_Ptr<ACE_TCHAR> buffer ( + this->union_label_value (node->label_val ())); + + this->set_attribute (LITERALS[VALUE], buffer.get ()); + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_constant (AST_Constant *node) + { + XMI_TRACE ("constant"); + + if (this->skip_imported_ && node->imported ()) + { + return 0; + } + + try + { + ES_Guard attr_guard (LITERALS[ATTR_TAG], this); + + this->set_attribute (LITERALS[OWNER_SCOPE], LITERALS[CLASSIFIER]); + this->set_attribute (LITERALS[CHANGEABLE], LITERALS[FROZEN]); + this->gen_common_elements (node, LITERALS[ST_CONST]); + + // Constant type + const ACE_TCHAR *exprtype (0); + AST_Expression::AST_ExprValue *val + (node->constant_value ()->ev ()); + + ACE_Auto_Basic_Array_Ptr<ACE_TCHAR> str_value; + + switch (node->et ()) + { + case AST_Expression::EV_short: + exprtype = LITERALS[ST_SHORT]; + str_value.reset (this->number_to_string (val->u.sval)); + break; + case AST_Expression::EV_ushort: + exprtype = LITERALS[ST_US]; + str_value.reset (this->number_to_string (val->u.usval)); + break; + case AST_Expression::EV_long: + exprtype = LITERALS[ST_LONG]; + str_value.reset (this->number_to_string (val->u.lval)); + break; + case AST_Expression::EV_ulong: + exprtype = LITERALS[ST_UL]; + str_value.reset (this->number_to_string (val->u.ulval)); + break; + case AST_Expression::EV_longlong: + exprtype = LITERALS[ST_LL]; + str_value.reset (this->number_to_string (val->u.llval)); + case AST_Expression::EV_ulonglong: + exprtype = LITERALS[ST_ULL]; + str_value.reset (this->number_to_string (val->u.ullval)); + break; + case AST_Expression::EV_float: + exprtype = LITERALS[ST_FLOAT]; + str_value.reset (this->number_to_string (val->u.fval)); + break; + case AST_Expression::EV_double: + exprtype = LITERALS[ST_DOUBLE]; + str_value.reset (this->number_to_string (val->u.dval)); + break; + case AST_Expression::EV_longdouble: + exprtype = LITERALS[ST_LD]; + str_value.reset (this->number_to_string (val->u.dval)); + break; + case AST_Expression::EV_char: + exprtype = LITERALS[ST_CHAR]; + str_value.reset (this->number_to_string (val->u.cval)); + break; + case AST_Expression::EV_wchar: + exprtype = LITERALS[ST_WCHAR]; + str_value.reset (this->number_to_string (val->u.wcval)); + break; + case AST_Expression::EV_octet: + exprtype = LITERALS[ST_OCTET]; + str_value.reset (this->number_to_string (val->u.dval)); + break; + case AST_Expression::EV_bool: + exprtype = LITERALS[ST_BOOL]; + str_value.reset (this->number_to_string (val->u.bval)); + break; + case AST_Expression::EV_string: + exprtype = LITERALS[ST_STR]; + str_value.reset (ACE::strnew ( + ACE_TEXT_CHAR_TO_TCHAR (val->u.strval->get_string ()))); + break; + case AST_Expression::EV_wstring: + exprtype = LITERALS[ST_WSTR]; + str_value.reset (ACE::strnew ( + ACE_TEXT_CHAR_TO_TCHAR (val->u.wstrval))); + break; + case AST_Expression::EV_enum: + { + UTL_Scope *s = node->defined_in (); + AST_Decl *d = + s->lookup_by_name (node->constant_value ()->n (), 1); + exprtype = ACE_TEXT_CHAR_TO_TCHAR ( + ScopeAsDecl (d->defined_in ())->repoID ()); + str_value.reset (ACE::strnew ( + ACE_TEXT_CHAR_TO_TCHAR (d->full_name ()))); + } + break; + + default: + throw Error ("Unsupported constant type", node); + } + + // type attribute + XStr xid (this->lookup_xid (exprtype)); + this->set_attribute (LITERALS[TYPE], + xid); + + { + ES_Guard me_tv (LITERALS[ME_TV_TAG], this); + { + ES_Guard tv (LITERALS[TV_TAG], this); + this->set_attribute (LITERALS[TAG], LITERALS[INIT_VAL]); + this->set_attribute (LITERALS[VALUE], str_value.get ()); + } + } + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_enum_val (AST_EnumVal *node) + { + XMI_TRACE ("enum val"); + + if (this->skip_imported_ && node->imported ()) + { + return 0; + } + + if (!this->visiting_enum_) + { + // It makes sence only to process enumvals in enum "scope". + return 0; + } + + try + { + ES_Guard att_guard (LITERALS[ATTR_TAG], this); + + this->create_and_store_xmi_id ( + ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), + node); + this->set_attribute ( + LITERALS[NAME], + ACE_TEXT_CHAR_TO_TCHAR (node->original_local_name ()->get_string ())); + + // I think this is fixed. + this->set_attribute (LITERALS[MULT], LITERALS[MULT_OTO]); + this->set_containing_element (LITERALS[OWNER]); + + ES_Guard me_guard (LITERALS[ME_TV_TAG], this); + ES_Guard tv_guard (LITERALS[TV_TAG], this); + + this->set_attribute (LITERALS[TAG], LITERALS[IDLORDER]); + + // convert the enum value to a string + // need a buffer, with a little safety padding + + ACE_Auto_Basic_Array_Ptr<ACE_TCHAR> buffer + (this->number_to_string (node->constant_value ()->ev ()->u.eval)); + + this->set_attribute (LITERALS[VALUE], buffer.get ()); + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_array (AST_Array *node) + { + XMI_TRACE ("array val"); + + if (this->skip_imported_ && node->imported ()) + { + return 0; + } + + try + { + this->gen_common_elements (node, + LITERALS[ST_ARR]); + + this->gen_array_associations (node, node); + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + void + idl3_to_xmi_visitor::gen_array_associations (AST_Decl *node, + AST_Array *array) + { + // <UML:Namespace.ownedElement> + NS_Guard global_ns (ACE_TEXT ("::"), this); + + // <UML:Association xmi.id="xmi.1210085542354" + // visibility="public" namespace="xmi.1210085542350"> + ES_Guard assoc_group (this->associations_, this); + ES_Guard assoc_g (LITERALS[ASSOC_TAG], this); + + XStr xid = this->gen_xmi_id (node); + this->set_attribute (LITERALS[XMI_ID], xid); + this->set_attribute (LITERALS[VISIBIL], LITERALS[PUBLIC]); + this->set_containing_element (LITERALS[NS]); + + // <UML:Association.connection> + ES_Guard assoc_conn (LITERALS[ASSOC_CONN_TAG], this); + + { + // <UML:AssociationEnd multiplicity="0..1" type="xmi.1210085542353"> + ES_Guard assocend (LITERALS[ASSOC_END_TAG], this); + + this->set_attribute (LITERALS[MULT], LITERALS[MULT_ZTO]); + + xid = this->lookup_xid (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ())); + this->set_attribute (LITERALS[TYPE], xid); + + // <UML:AssociationEnd.qualifier> + ES_Guard assoc_qual (LITERALS[ASSOC_END_QUAL_TAG], this); + + for (unsigned long i = 0; + array != 0 && i < array->n_dims (); + ++i) + { + // <UML:Attribute xmi.id="xmi.1210085542355" + // name="index0" type='xmi.1210085542329'> + // N.B. that type is long. + ES_Guard attr (LITERALS[ATTR_TAG], this); + + xid = this->gen_xmi_id (node); + this->set_attribute (LITERALS[XMI_ID], xid); + + std::stringstream str; + str << LITERALS[INDEX]; + str << i; + + this->set_attribute ( + LITERALS[NAME], + ACE_TEXT_CHAR_TO_TCHAR (str.str ().c_str ())); + xid = this->lookup_xid (LITERALS[ST_LONG]); + this->set_attribute (LITERALS[TYPE], xid); + + // <UML:ModelElement.constraint> + ES_Guard me_c (LITERALS[ME_CONS_TAG], this); + + // <UML:Constraint xmi.id="xmi.1210085542356"> + ES_Guard cons (LITERALS[CONSTRAINT], this); + + xid = this->gen_xmi_id (node); + this->set_attribute (LITERALS[XMI_ID], xid); + + // <UML:ModelElement.taggedValue> + ES_Guard me_tv (LITERALS[ME_TV_TAG], this); + + // <UML:TaggedValue tag="constraintUpperValue" value="4"/> + ES_Guard tv (LITERALS[TV_TAG], this); + + this->set_attribute (LITERALS[TAG], LITERALS[CONST_UPPER]); + + ACE_Auto_Basic_Array_Ptr<ACE_TCHAR> buffer ( + this->number_to_string (array->dims ()[i]->ev ()->u.ulval)); + + this->set_attribute (LITERALS[VALUE], buffer.get ()); + } + } + + // <UML:AssociationEnd multiplicity="1..1" + // type="xmi.1210085542346"/> - type is Char for this IDL + ES_Guard assoc_end (LITERALS[ASSOC_END_TAG], this); + this->set_attribute (LITERALS[MULT], LITERALS[MULT_OTO]); + + XStr arr_type = this->lookup_type_xid (array->base_type ()); + this->set_attribute (LITERALS[TYPE], arr_type); + } + + int + idl3_to_xmi_visitor::visit_sequence (AST_Sequence *node) + { + XMI_TRACE ("sequence val"); + + if (this->skip_imported_ && node->imported ()) + { + return 0; + } + + try + { + this->gen_common_elements (node, + LITERALS[ST_SEQ]); + + // Generate the bounds and type on the sequence, which is an + // association in the association tree. + this->gen_sequence_associations (node, node); + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + void + idl3_to_xmi_visitor::gen_sequence_associations (AST_Decl *node, + AST_Sequence *sequence) + { + // <UML:Namespace.ownedElement> + NS_Guard global_ns (ACE_TEXT ("::"), this); + + // <UML:Association xmi.id="xmi.1210085542354" + // visibility="public" namespace="xmi.1210085542350"> + ES_Guard assoc_group (this->associations_, this); + ES_Guard assoc_g (LITERALS[ASSOC_TAG], this); + + XStr xid = this->gen_xmi_id (node); + this->set_attribute (LITERALS[XMI_ID], xid); + this->set_attribute (LITERALS[VISIBIL], LITERALS[PUBLIC]); + this->set_containing_element (LITERALS[NS]); + + // <UML:Association.connection> + ES_Guard assoc_conn (LITERALS[ASSOC_CONN_TAG], this); + + { + // <UML:AssociationEnd multiplicity="0..1" type="xmi.1210085542353"> + ES_Guard assocend (LITERALS[ASSOC_END_TAG], this); + + this->set_attribute (LITERALS[MULT], LITERALS[MULT_ZTO]); + + xid = this->lookup_xid (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ())); + this->set_attribute (LITERALS[TYPE], xid); + + // <UML:AssociationEnd.qualifier> + ES_Guard assoc_qual (LITERALS[ASSOC_END_QUAL_TAG], this); + + ES_Guard attr (LITERALS[ATTR_TAG], this); + + xid = this->gen_xmi_id (node); + this->set_attribute (LITERALS[XMI_ID], xid); + this->set_attribute (LITERALS[NAME], LITERALS[INDEX]); + xid = this->lookup_xid (LITERALS[ST_LONG]); + this->set_attribute (LITERALS[TYPE], xid); + + ES_Guard me_c (LITERALS[ME_CONS_TAG], this); + ES_Guard cons (LITERALS[CONSTRAINT], this); + ES_Guard me_tv (LITERALS[ME_TV_TAG], this); + ES_Guard tv (LITERALS[TV_TAG], this); + + this->set_attribute (LITERALS[TAG], LITERALS[CONST_UPPER]); + + // @@TODO: need to extract bound from node. + if (sequence->unbounded ()) + { + this->set_attribute (LITERALS[VALUE], + LITERALS[UNBOUNDED_SEQ]); + } + else + { // bounded sequence + // convert the array bound to a string + // need a buffer, with a little safety padding + ACE_Auto_Basic_Array_Ptr<ACE_TCHAR> buffer ( + this->number_to_string (sequence->max_size ()->ev ()->u.ulval)); + + this->set_attribute (LITERALS[VALUE], buffer.get ()); + } + } + + // <UML:AssociationEnd multiplicity="1..1" + // type="xmi.1210085542346"/> - type is Char for this IDL + ES_Guard assoc_end (LITERALS[ASSOC_END_TAG], this); + this->set_attribute (LITERALS[MULT], LITERALS[MULT_OTO]); + + XStr seq_type = this->lookup_type_xid (sequence->base_type ()); + this->set_attribute (LITERALS[TYPE], seq_type); + } + + int + idl3_to_xmi_visitor::visit_string (AST_String *) + { + XMI_TRACE ("string"); + return 0; + } + + int + idl3_to_xmi_visitor::visit_typedef (AST_Typedef *node) + { + XMI_TRACE ("typedef"); + + if (this->skip_imported_ && node->imported ()) + { + return 0; + } + + try + { + ES_Guard class_guard (LITERALS[CLASS_TAG], this); + + // Anonymous Sequences and arrays appear to be a special case + AST_Decl *base (node->base_type ()); + if (base->node_type () == AST_Decl::NT_sequence) + { + this->gen_common_elements (node, LITERALS[ST_SEQ]); + + AST_Sequence* sequence = + AST_Sequence::narrow_from_decl (base); + this->gen_sequence_associations (node, sequence); + } + else if (base->node_type () == AST_Decl::NT_array) + { + this->gen_common_elements (node, LITERALS[ST_ARR]); + + AST_Array* array = + AST_Array::narrow_from_decl (base); + this->gen_array_associations (node, array); + } + else + { + this->gen_common_elements (node, + LITERALS[ST_TYPEDEF]); + + // Generalization. Assignment required for memory management. + XStr xid = this->add_generalization (node, + node->base_type ()); + ACE_UNUSED_ARG (xid); + } + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + idl3_to_xmi_visitor::visit_root (AST_Root *node) + { + XMI_TRACE ("root"); + try + { + ACE_CString fn; + + if ((fn = be_global->filename ()) == "") + { + fn = idl_global->stripped_filename ()->get_string (); + fn = fn.substr (0, fn.rfind ('.')); + fn += ".xmi"; + } + + const char *path = be_global->output_dir (); + ACE_CString target_name; + + if (path != 0) + { + target_name = path; + target_name += "/"; + } + + target_name += fn; + + CIAO::XML::NoOp_Resolver res_func; + CIAO::XML::XML_Schema_Resolver<> resolver (res_func); + CIAO::XML::XML_Error_Handler handler; + CIAO::XML::XML_Helper<> helper (resolver, handler); + + // Create XML document + std::auto_ptr<DOMDocumentType> doctype ( + helper.create_doctype (ACE_TEXT("XMI"), + 0, + ACE_TEXT_CHAR_TO_TCHAR (be_global->dtd ()))); + + if ((this->dom_ = helper.create_dom (ACE_TEXT("XMI"), + ACE_TEXT(""), + doctype.get ())) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "Unable to create XML document."), -1); + + this->root_ = this->dom_->getDocumentElement (); + + this->stack_.push (this->root_); + + this->set_attribute (LITERALS[VERSION_TAG], + LITERALS[VERSION_VALUE]); + + this->set_attribute (LITERALS[NS_TAG], + LITERALS[NS_VALUE]); + + DOMElement *tmp = 0; + + // Pregenerate stereotypes to cache xmi.ids. + DOMElement *stereotypes = this->generate_stereotypes (); + + // Create XMI header + { + ES_Guard ht_g (LITERALS[HEADER_TAG], this); + ES_Guard d_t (LITERALS[DOC_TAG], this); + ES_Guard e_t (LITERALS[EXPORTER_TAG], this); + this->add_text (LITERALS[EXPORTER_VALUE]); + } + + this->stack_.push (this->create_element (LITERALS[CONTENT_TAG])); + this->stack_.push (this->create_element (LITERALS[MODEL_TAG])); + + // Store the base model xid + this->set_attribute (LITERALS[XMI_ID], this->base_id_); + this->id_map_.bind (ACE_TEXT ("::"), this->base_id_); + + + // Global namespace + this->stack_.push (this->create_element (LITERALS[OWNEDELEMENT_TAG])); + this->namespace_.push (ACE_TEXT ("::")); + + // Create generalizations and associations elements, but don't join + // them to the tree yet + this->associations_ = + this->dom_->createElement (XStr (LITERALS[OWNEDELEMENT_TAG])); + this->generalizations_ = + this->dom_->createElement (XStr (LITERALS[OWNEDELEMENT_TAG])); + + if (this->visit_scope (node) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "idl3_to_idl2_visitor::visit_root - " + "codegen for scope failed\n"), + -1); + } + + this->stack_.pop (tmp); + + this->stack_.top (tmp); + + tmp->appendChild (this->generalizations_); + tmp->appendChild (this->associations_); + tmp->appendChild (stereotypes); + + helper.write_DOM (this->dom_, + ACE_TEXT_CHAR_TO_TCHAR (target_name.c_str ())); + } + catch (const Error &ex) + { + if (ex.node_ != 0) + ACE_ERROR ((LM_ERROR, "%s:%d:error: %s\n", + ex.node_->file_name ().c_str (), + ex.node_->line (), + ex.diag_.c_str ())); + else + ACE_ERROR ((LM_ERROR, "::error:%s\n", + ex.diag_.c_str ())); + + return -1; + } + return 0; + } + + int + idl3_to_xmi_visitor::visit_native (AST_Native *node) + { + XMI_TRACE ("native"); + + if (this->skip_imported_ && node->imported ()) + { + return 0; + } + + try + { + ES_Guard class_guard (LITERALS[CLASS_TAG], this); + + this->gen_common_elements (node, LITERALS[ST_NATIVE]); + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + void + idl3_to_xmi_visitor::set_attribute (const ACE_TCHAR *name, + const ACE_TCHAR *value) + { + DOMElement *ele = 0; + this->stack_.top (ele); + + ele->setAttribute (XStr (name), XStr (value)); + } + + + void + idl3_to_xmi_visitor::set_attribute (const ACE_TCHAR *name, + const XMLCh *value) + { + DOMElement *ele = 0; + this->stack_.top (ele); + + ele->setAttribute (XStr (name), value); + } + + void + idl3_to_xmi_visitor::add_text (const ACE_TCHAR *text) + { + DOMElement *ele = 0; + this->stack_.top (ele); + + DOMText *node = this->dom_->createTextNode (XStr (text)); + ele->appendChild (node); + } + + DOMElement * + idl3_to_xmi_visitor::create_element (const ACE_TCHAR *name) + { + DOMElement *ele = 0; + this->stack_.top (ele); + + DOMElement *node = this->dom_->createElement (XStr (name)); + + ele->appendChild (node); + + return node; + } + + DOMElement * + idl3_to_xmi_visitor::generate_stereotypes (void) + { + DOMElement *retval = + this->dom_->createElement (XStr (LITERALS[OWNEDELEMENT_TAG])); + + // put it on the stack to subsequent create_element calls refer to it. + this->stack_.push (retval); + + this->add_stereotype (ST_CONSUMES, ASSOC); + this->add_stereotype (ST_ANON_SEQ, CLASS); + this->add_stereotype (ST_PRINC, DATATYPE); + this->add_stereotype (ST_UNION, CLASS); + this->add_stereotype (ST_USES, ASSOC); + this->add_stereotype (ST_SEQ, CLASS); + this->add_stereotype (ST_ROE, __NULL); + this->add_stereotype (ST_RO, __NULL); + this->add_stereotype (ST_OBJ, DATATYPE); + this->add_stereotype (ST_STR, DATATYPE); + this->add_stereotype (ST_LD, DATATYPE); + this->add_stereotype (ST_ANON_ARR, CLASS); + this->add_stereotype (ST_ALIAS, CLASS); + this->add_stereotype (ST_NULL, DATATYPE); + this->add_stereotype (ST_VALUE, CLASS); + this->add_stereotype (ST_VOID, DATATYPE); + this->add_stereotype (ST_EX, CLASS); + this->add_stereotype (ST_OCTET, DATATYPE); + this->add_stereotype (ST_MANAGES, ASSOC); + this->add_stereotype (ST_WSTR, DATATYPE); + this->add_stereotype (ST_FLOAT, DATATYPE); + this->add_stereotype (ST_ENUM, CLASS); + this->add_stereotype (ST_VAL_SUP, CLASS); + this->add_stereotype (ST_MODULE, PACKAGE); + this->add_stereotype (ST_HFINDER, CLASS); + this->add_stereotype (ST_DOUBLE, DATATYPE); + this->add_stereotype (ST_LL, DATATYPE); + this->add_stereotype (ST_HFACT, CLASS); + this->add_stereotype (ST_ARR, CLASS); + this->add_stereotype (ST_COMP, CLASS); + this->add_stereotype (ST_SHORT, DATATYPE); + this->add_stereotype (ST_TYPEDEF, CLASS); + this->add_stereotype (ST_ULL, DATATYPE); + this->add_stereotype (ST_LONG, DATATYPE); + this->add_stereotype (ST_TC, DATATYPE); + this->add_stereotype (ST_HOME, CLASS); + this->add_stereotype (ST_STRUCT, CLASS); + this->add_stereotype (ST_FIXED, DATATYPE); + this->add_stereotype (ST_US, DATATYPE); + this->add_stereotype (ST_EMITS, ASSOC); + this->add_stereotype (ST_BOXVALUE, CLASS); + this->add_stereotype (ST_BOOL, DATATYPE); + this->add_stereotype (ST_CONST, ATTR); + this->add_stereotype (ST_PUBLISH, ASSOC); + this->add_stereotype (ST_CONSTANTS, CLASS); + this->add_stereotype (ST_PROVIDES, ASSOC); + this->add_stereotype (ST_WCHAR, DATATYPE); + this->add_stereotype (ST_UL, DATATYPE); + this->add_stereotype (ST_VAL_FACT, CLASS); + this->add_stereotype (ST_EVENT, CLASS); + this->add_stereotype (ST_CHAR, DATATYPE); + this->add_stereotype (ST_INTF, CLASS); + this->add_stereotype (ST_PRI_KEY, CLASS); + this->add_stereotype (ST_ANY, DATATYPE); + this->add_stereotype (ST_NATIVE, CLASS); + + this->stack_.pop (retval); + + return retval; + } + + void + idl3_to_xmi_visitor::add_stereotype (const LITERAL_T name, + const LITERAL_T bc) + { + // Generate our xmi.id + XStr xid (this->gen_xmi_id ()); + + // Bind the id in the map + this->id_map_.bind (LITERALS[name], xid); + + DOMElement *ele = this->create_element (LITERALS[STEREOTYPE_TAG]); + ele->setAttribute (XStr (LITERALS[XMI_ID]), xid); + ele->setAttribute (XStr (LITERALS[NAME]), XStr (LITERALS[name])); + ele->setAttribute (XStr (LITERALS[BASEC]), XStr (LITERALS[bc])); + + return; + } + + XMLCh * + idl3_to_xmi_visitor::gen_xmi_id (const ACE_TCHAR *name, long line) + { + if (current_id_ == 0) + { + ACE_OS::srand (ACE_OS::gettimeofday ().msec ()); + current_id_ = rand (); + } + std::stringstream str; + // Skip all characters that cannot be a first name char in xmi.id. + while (name && *name && !XMLChar1_1::isFirstNameChar(*name)) ++name; + // Since we use a file path as name then let's change all non-name + // chars for '_'. + while (name && *name) + { + if (XMLChar1_1::isNameChar (*name)) + { + str << *name; + } + else + { + str << '_'; + } + ++name; + } + str << ':' << line << '.' << current_id_++; + + XStr retval (ACE_TEXT_CHAR_TO_TCHAR (str.str ().c_str ())); + return retval.release (); + } + + XMLCh * + idl3_to_xmi_visitor::gen_xmi_id (AST_Decl *node) + { + if (current_id_ == 0) + { + ACE_OS::srand (ACE_OS::gettimeofday ().msec ()); + current_id_ = rand (); + } + + // we want these IDs to be unique, but the CDMW + // code generator sometimes depends + // on the order these things were declared in IDL, + // so for cases like that, + // we generate an ID that will sort to the order it + // was declared in IDL, + // no matter which order we visit the nodes. + if (node != 0) + { + return + gen_xmi_id ( + ACE_TEXT_CHAR_TO_TCHAR (node->file_name ().c_str ()), + node->line ()); + } + + std::stringstream str; + + str << "xmi." << current_id_++; + XStr retval (ACE_TEXT_CHAR_TO_TCHAR (str.str ().c_str ())); + return retval.release (); + } + + void + idl3_to_xmi_visitor::set_containing_element ( + const ACE_TCHAR *cont_name) + { + ACE_TString tmp; + XStr xid; + + this->namespace_.top (tmp); + this->id_map_.find (tmp, xid); + this->set_attribute (cont_name, xid); + } + + void + idl3_to_xmi_visitor::create_and_store_xmi_id (AST_Decl *node) + { + try + { + this->create_and_store_xmi_id ( + ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), node); + } + catch (Error &ex) + { + ex.node (node); + throw; + } + } + + void + idl3_to_xmi_visitor::create_and_store_xmi_id ( + const ACE_TCHAR *name, AST_Decl *node) + { + XStr xid = this->gen_xmi_id (node); + + // store xmi_id + if (this->id_map_.trybind (name, xid) == -1) + throw Error ("error binding in the XMI ID map"); + + this->set_attribute (LITERALS[XMI_ID], xid); + } + + XMLCh * + idl3_to_xmi_visitor::lookup_xid (const ACE_TCHAR *name) + { + XStr tmp; + if (this->id_map_.find (name, tmp) == -1) + { + ACE_CString err ("unknown XMI ID requested for "); + err += ACE_TEXT_ALWAYS_CHAR (name); + throw Error (err.c_str ()); + } + + return tmp.release (); + } + + XMLCh * + idl3_to_xmi_visitor::lookup_type_xid (AST_Type *node) + { + AST_PredefinedType *pdt = 0; + + switch (node->node_type ()) + { + case AST_Decl::NT_string: + return this->lookup_xid (LITERALS[ST_STR]); + case AST_Decl::NT_wstring: + return this->lookup_xid (LITERALS[ST_WSTR]); + + case AST_Decl::NT_pre_defined: + pdt = AST_PredefinedType::narrow_from_decl (node); + + switch (pdt->pt ()) + { + case AST_PredefinedType::PT_pseudo: + return this->lookup_xid (ACE_TEXT_CHAR_TO_TCHAR (pdt->repoID ())); + case AST_PredefinedType::PT_object: + return this->lookup_xid (LITERALS[ST_OBJ]); + case AST_PredefinedType::PT_any: + return this->lookup_xid (LITERALS[ST_ANY]); + case AST_PredefinedType::PT_long: + return this->lookup_xid (LITERALS[ST_LONG]); + case AST_PredefinedType::PT_ulong: + return this->lookup_xid (LITERALS[ST_UL]); + case AST_PredefinedType::PT_longlong: + return this->lookup_xid (LITERALS[ST_LL]); + case AST_PredefinedType::PT_ulonglong: + return this->lookup_xid (LITERALS[ST_ULL]); + case AST_PredefinedType::PT_short: + return this->lookup_xid (LITERALS[ST_SHORT]); + case AST_PredefinedType::PT_ushort: + return this->lookup_xid (LITERALS[ST_US]); + case AST_PredefinedType::PT_float: + return this->lookup_xid (LITERALS[ST_FLOAT]); + case AST_PredefinedType::PT_double: + return this->lookup_xid (LITERALS[ST_DOUBLE]); + case AST_PredefinedType::PT_longdouble: + return this->lookup_xid (LITERALS[ST_LD]); + case AST_PredefinedType::PT_char: + return this->lookup_xid (LITERALS[ST_CHAR]); + case AST_PredefinedType::PT_wchar: + return this->lookup_xid (LITERALS[ST_WCHAR]); + case AST_PredefinedType::PT_boolean: + return this->lookup_xid (LITERALS[ST_BOOL]); + case AST_PredefinedType::PT_octet: + return this->lookup_xid (LITERALS[ST_OCTET]); + case AST_PredefinedType::PT_void: + return this->lookup_xid (LITERALS[ST_VOID]); + default: + throw Error ("Unknown or unsupported predefined type", + pdt); + } + default: + return this->lookup_xid (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ())); + } + } + + void + idl3_to_xmi_visitor::find_and_set_xid_as_attr (const ACE_TCHAR *attr_name, + const ACE_TCHAR *xid_name) + { + XStr tmp; + + if (this->id_map_.find (xid_name, tmp) == -1) + { + ACE_CString err ("unknown XMI ID when looking up "); + err += ACE_TEXT_ALWAYS_CHAR (xid_name); + throw Error (err.c_str ()); + } + + this->set_attribute (attr_name, tmp); + } + + void + idl3_to_xmi_visitor::gen_tagged_value (AST_Decl *node) + { + ES_Guard me_guard (LITERALS[ME_TV_TAG], this); + ES_Guard tv_guard (LITERALS[TV_TAG], this); + + this->set_attribute (LITERALS[TAG], LITERALS[TYPEID]); + this->set_attribute (LITERALS[VALUE], + ACE_TEXT_CHAR_TO_TCHAR (node->repoID ())); + } + + XMLCh * + idl3_to_xmi_visitor::add_generalization (const ACE_TCHAR *sub, + const ACE_TCHAR *super) + { + return this->add_generalization (XStr (this->lookup_xid (sub)), + XStr (this->lookup_xid (super))); + } + + XMLCh * + idl3_to_xmi_visitor::add_generalization (AST_Type *sub, AST_Type *super) + { + return this->add_generalization (XStr (this->lookup_type_xid (sub)), + XStr (this->lookup_type_xid (super))); + } + + XMLCh * + idl3_to_xmi_visitor::add_generalization (const XMLCh *sub, + const XMLCh *super) + { + // Generate XMI ID + XStr xid (this->gen_xmi_id ()); + + { // add generalization to the 'generalizations' set + ES_Guard es_guard (this->generalizations_, this); + NS_Guard ns_guard (ACE_TEXT ("::"), this); + + ES_Guard gen_guard (LITERALS[GEN_TAG], this); + + this->set_attribute (LITERALS[XMI_ID], xid); + + this->set_containing_element (LITERALS[NS]); + + { // subtype + ES_Guard st_guard (LITERALS[GEN_SUB_TAG], this); + ES_Guard element_guard (LITERALS[GEN_ELEMENT_TAG], this); + + this->set_attribute (LITERALS[IDREF], sub); + } + + { // subtype + ES_Guard st_guard (LITERALS[GEN_SUPER_TAG], this); + ES_Guard element_guard (LITERALS[GEN_ELEMENT_TAG], this); + + this->set_attribute (LITERALS[IDREF], super); + } + } + + { // Reference generalization in the calling element. + ES_Guard et_g (LITERALS[GEN_ELEMENT_GEN_TAG], this); + ES_Guard g_g (LITERALS[GEN_TAG], this); + this->set_attribute (LITERALS[IDREF], xid); + } + + return xid.release (); + } + + void + idl3_to_xmi_visitor::add_port (const ACE_TCHAR *port_kind, + AST_Field *port_node) + { + if (port_node->node_type () == AST_Decl::NT_uses) + { + AST_Uses *u = AST_Uses::narrow_from_decl (port_node); + + if (u->is_multiple ()) + { + throw Error ("uses multiple not yet supported."); + } + } + + ES_Guard es_guard (this->associations_, this); + NS_Guard ns_guard (ACE_TEXT ("::"), this); + + ES_Guard assoc_guard (LITERALS[ASSOC_TAG], this); + + // Generate XMI ID + XStr xid (this->gen_xmi_id (port_node)); + this->set_attribute (LITERALS[XMI_ID], xid); + this->set_attribute (LITERALS[VISIBIL], LITERALS[PUBLIC]); + this->find_and_set_xid_as_attr (LITERALS[STEREO_ATTR], port_kind); + this->set_containing_element (LITERALS[NS]); + + ES_Guard conn_guard (LITERALS[ASSOC_CONN_TAG], this); + + { // component end + ES_Guard end_guard (LITERALS[ASSOC_END_TAG], this); + this->set_attribute (LITERALS[MULT], ACE_TEXT ("1")); + this->find_and_set_xid_as_attr ( + LITERALS[TYPE], + ACE_TEXT_CHAR_TO_TCHAR (this->cached_type_->repoID ())); + } + + { // component end + ES_Guard end_guard (LITERALS[ASSOC_END_TAG], this); + + Identifier *id = + IdentifierHelper::original_local_name ( + port_node->local_name ()); + + this->set_attribute (LITERALS[NAME], ACE_TEXT_CHAR_TO_TCHAR (id->get_string ())); + this->set_attribute (LITERALS[MULT], ACE_TEXT ("1")); + + this->find_and_set_xid_as_attr ( + LITERALS[TYPE], + ACE_TEXT_CHAR_TO_TCHAR (port_node->field_type ()->repoID ())); + + id->destroy (); + delete id; + id = 0; + } + } + + void + idl3_to_xmi_visitor::add_managed_component (const ACE_TCHAR *home, + const ACE_TCHAR *component) + { + ES_Guard es_guard (this->associations_, this); + NS_Guard ns_guard (ACE_TEXT ("::"), this); + + ES_Guard assoc_guard (LITERALS[ASSOC_TAG], this); + + // Generate XMI ID + XStr xid (this->gen_xmi_id ()); + this->set_attribute (LITERALS[XMI_ID], xid); + this->set_attribute (LITERALS[VISIBIL], LITERALS[PUBLIC]); + this->find_and_set_xid_as_attr (LITERALS[STEREO_ATTR], + LITERALS[ST_MANAGES]); + this->set_containing_element (LITERALS[NS]); + + ES_Guard conn_guard (LITERALS[ASSOC_CONN_TAG], this); + + { // home end + ES_Guard end_guard (LITERALS[ASSOC_END_TAG], this); + this->find_and_set_xid_as_attr (LITERALS[STEREO_ATTR], + LITERALS[ST_HOME]); + this->find_and_set_xid_as_attr (LITERALS[TYPE], home); + } + + { // component end + ES_Guard end_guard (LITERALS[ASSOC_END_TAG], this); + this->find_and_set_xid_as_attr (LITERALS[STEREO_ATTR], + LITERALS[ST_COMP]); + this->find_and_set_xid_as_attr (LITERALS[TYPE], component); + } + } + + void + idl3_to_xmi_visitor::gen_common_elements (AST_Decl *node, + const ACE_TCHAR *stereotype) + { + this->create_and_store_xmi_id (node); + this->set_attribute ( + LITERALS[NAME], + ACE_TEXT_CHAR_TO_TCHAR (node->original_local_name ()->get_string ())); + this->set_attribute (LITERALS[VISIBIL], LITERALS[PUBLIC]); + this->set_containing_element (LITERALS[NS]); + this->find_and_set_xid_as_attr (LITERALS[STEREO_ATTR], + stereotype); + + NS_Guard ns_guard (ACE_TEXT_CHAR_TO_TCHAR (node->repoID ()), this); + this->gen_tagged_value (node); + } + + idl3_to_xmi_visitor::ES_Guard::ES_Guard (const ACE_TCHAR *name, + idl3_to_xmi_visitor *vis) + : vis_ (*vis) + { + if (vis_.stack_.push (vis_.create_element (name))) + throw Error ("element stack error"); + } + + idl3_to_xmi_visitor::ES_Guard::ES_Guard (DOMElement *ele, + idl3_to_xmi_visitor *vis) + : vis_ (*vis) + { + if (vis_.stack_.push (ele) != 0) + throw Error ("element stack error"); + } + + idl3_to_xmi_visitor::ES_Guard::~ES_Guard (void) + { + DOMElement *tmp; + if (vis_.stack_.pop (tmp) != 0) + { + vis_.output_dirty_ = true; + ACE_ERROR ((LM_ERROR, "error: element stack underflow.")); + } + } + + idl3_to_xmi_visitor::NS_Guard::NS_Guard (const ACE_TCHAR *name, + idl3_to_xmi_visitor *vis) + : vis_ (*vis) + { + int res = vis_.namespace_.push (name); + + if (res == 0) return; + throw Error ("stack error"); + } + + idl3_to_xmi_visitor::NS_Guard::~NS_Guard (void) + { + ACE_TString tmp; + if (vis_.namespace_.pop (tmp) != 0) + { + vis_.output_dirty_ = true; + ACE_ERROR ((LM_ERROR, "error:namespace stack underflow")); + } + } + } +} diff --git a/modules/CIAO/tools/IDL3_to_XMI/IDL3_to_XMI_visitor.h b/modules/CIAO/tools/IDL3_to_XMI/IDL3_to_XMI_visitor.h new file mode 100644 index 00000000000..d376f8ace89 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_XMI/IDL3_to_XMI_visitor.h @@ -0,0 +1,324 @@ +/** + * @file IDL3_to_XMI_visitor.h + * @author William R. Otte <wotte@dre.vanderbilt.edu> + * $Id$ + * Implements a visitor that generates XMI for the CARDAMOM + * code generation facility. + * + * This IDL->XMI mapping appears to be based on a IDL->UML->XMI + * mapping, and should be valid XMI version 1.1 + */ + +#ifndef CIAO_XMI_VISITOR_H +#define CIAO_XMI_VISITOR_H + +#include "ace/Containers.h" +#include "ace/Hash_Map_Manager.h" +#include "ace/Null_Mutex.h" +#include "ace/SString.h" + +#include "xercesc/util/XercesDefs.hpp" + +#include "ast_visitor.h" +#include "ast_component.h" +#include "ast_concrete_type.h" + +#include "utl_scoped_name.h" +#include "Literals.h" +#include "XML/XercesString.h" +#include "CIAO_IDL3_TO_XMI_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class TAO_OutStream; +class UTL_ExceptList; + +namespace XERCES_CPP_NAMESPACE +{ + class DOMDocument; + class DOMElement; +} + +namespace CIAO +{ + namespace XMI + { + + /** + * @class idl3_to_xmi_visitor + * @brief Visitor that generates XMI for the CARDAMOM code + * generation facilities. + */ + class CIAO_IDL3_TO_XMI_Export idl3_to_xmi_visitor : public ast_visitor + { + public: + idl3_to_xmi_visitor (bool skip_imported); + virtual ~idl3_to_xmi_visitor (void); + + virtual int visit_decl (AST_Decl *d); + virtual int visit_scope (UTL_Scope *node); + virtual int visit_type (AST_Type *node); + virtual int visit_predefined_type (AST_PredefinedType *node); + virtual int visit_module (AST_Module *node); + virtual int visit_template_module (AST_Template_Module *node); + virtual int visit_template_module_inst (AST_Template_Module_Inst *node); + virtual int visit_template_module_ref (AST_Template_Module_Ref *node); + virtual int visit_param_holder(AST_Param_Holder *node); + virtual int visit_interface (AST_Interface *node); + virtual int visit_interface_fwd (AST_InterfaceFwd *node); + virtual int visit_valuebox (AST_ValueBox *node); + virtual int visit_valuetype (AST_ValueType *node); + virtual int visit_valuetype_fwd (AST_ValueTypeFwd *node); + virtual int visit_eventtype (AST_EventType *node); + virtual int visit_eventtype_fwd (AST_EventTypeFwd *node); + virtual int visit_component (AST_Component *node); + virtual int visit_component_fwd (AST_ComponentFwd *node); + virtual int visit_provides (AST_Provides *node); + virtual int visit_uses (AST_Uses *node); + virtual int visit_publishes (AST_Publishes *node); + virtual int visit_emits (AST_Emits *node); + virtual int visit_consumes (AST_Consumes *node); + virtual int visit_porttype (AST_PortType *node); + virtual int visit_extended_port (AST_Extended_Port *node); + virtual int visit_mirror_port (AST_Mirror_Port *node); + virtual int visit_connector (AST_Connector *node); + virtual int visit_home (AST_Home *node); + virtual int visit_factory (AST_Factory *node); + virtual int visit_structure (AST_Structure *node); + virtual int visit_structure_fwd (AST_StructureFwd *node); + virtual int visit_exception (AST_Exception *node); + virtual int visit_expression (AST_Expression *node); + virtual int visit_enum (AST_Enum *node); + virtual int visit_operation (AST_Operation *node); + virtual int visit_field (AST_Field *node); + virtual int visit_argument (AST_Argument *node); + virtual int visit_attribute (AST_Attribute *node); + virtual int visit_union (AST_Union *node); + virtual int visit_union_fwd (AST_UnionFwd *node); + virtual int visit_union_branch (AST_UnionBranch *node); + virtual int visit_union_label (AST_UnionLabel *node); + virtual int visit_constant (AST_Constant *node); + virtual int visit_enum_val (AST_EnumVal *node); + virtual int visit_array (AST_Array *node); + virtual int visit_sequence (AST_Sequence *node); + virtual int visit_string (AST_String *node); + virtual int visit_typedef (AST_Typedef *node); + virtual int visit_root (AST_Root *node); + virtual int visit_native (AST_Native *node); + virtual int visit_finder (AST_Finder *node); + + struct Error + { + Error (const ACE_CString &diag, AST_Decl *node = 0) + : diag_ (diag), + node_ (node) + {} + + void node (AST_Decl *node) { if (node_ == 0) node_ = node; } + + const ACE_CString diag_; + AST_Decl *node_; + }; + + private: + /// Generates several elements common to most XMI elements. + /// Generates the following attributes: xmi.id, name, visibility, namespace, stereotype + /// and the tagged value grouping. + /// @param stereotype The stereotype this element should be associated with. + void gen_common_elements (AST_Decl *node, const ACE_TCHAR *stereotype); + + /// Converts a number into a string representation. + /// Caller responsible for memory. + template <typename T> + ACE_TCHAR * number_to_string (T val); + + /// Common elements of operation XMI generation + void visit_operation_impl (AST_Operation *node, const ACE_TCHAR *stereotype); + + /// implementation for elements common to both eventtypes + /// and valuetypes + void visit_valuetype_impl (AST_ValueType *node); + + /// implementation of elements common to exceptions and structures. + void visit_struct_impl (AST_Structure *node); + + /// Generation of common associations of anonymous and typedefed arrays. + void gen_array_associations (AST_Decl *node, AST_Array *array); + + /// Generation of common associations of anonymous and typedefed sequences. + void gen_sequence_associations (AST_Decl *node, AST_Sequence *sequence); + + /// sets an attribute on the element at the top of the stack. + void set_attribute (const ACE_TCHAR *name, + const ACE_TCHAR *value); + + + /// sets an attribute on the element at the top of the stack + void set_attribute (const ACE_TCHAR *name, + const XMLCh *value); + + /// Adds a text child to the element at the top of the stack + void add_text (const ACE_TCHAR *text); + + /// Greates a new element as a child of the current stack element + XERCES_CPP_NAMESPACE::DOMElement * create_element (const ACE_TCHAR *name); + + /// Generate stereotypes for XMI document + XERCES_CPP_NAMESPACE::DOMElement * generate_stereotypes (void); + + /// Helper method which creates new stereotype elements + void add_stereotype (const LITERAL_T name, + const LITERAL_T bc); + + /// Generates an XMI ID. + /// @param node If passed, the file name and line number will be + /// generated as part of the ID. + static XMLCh * gen_xmi_id (AST_Decl * node = 0); + + /// Generates an XMI ID with file_name and line as part of the id. + static XMLCh * gen_xmi_id (const ACE_TCHAR *file_name, long line); + + /// Used to store the next ID for generation + static size_t current_id_; + + /// Generates the tagged value grouping common to most XMI elements + void gen_tagged_value (AST_Decl *); + + /// Sets an attribute with name containment_name whose value is the + /// ID of the top of the namespace stack. + void set_containing_element (const ACE_TCHAR *containment_name); + + /// Looks up the xmi:id assoviated with xid_name and sets it as an + /// attribute + void find_and_set_xid_as_attr (const ACE_TCHAR *attr_name, const ACE_TCHAR *xid_name); + + /// Creates a XMI ID based on node, and sets its value to + /// the xmi.id attribute of the current top of element stack. + void create_and_store_xmi_id (AST_Decl *node); + + /// Creates a XMI ID based on node, and sets its value to + /// the name attribute of the current top of element stack. + void create_and_store_xmi_id (const ACE_TCHAR *name, AST_Decl *node = 0); + + /// Finds and returns the xmi.id associated with name. + XMLCh * lookup_xid (const ACE_TCHAR *name); + + /// Finds and returns the xmi.id associated with the provided type. + XMLCh * lookup_type_xid (AST_Type *); + + /// Used to add generalizations - most commonly used for supports + /// relationships. in component foo supports bar, foo is the sub, + /// bar is the super. + XMLCh * add_generalization (const ACE_TCHAR *sub, const ACE_TCHAR *super); + XMLCh * add_generalization (AST_Type *sub, AST_Type *super); + + XMLCh * add_generalization (const XMLCh *sub, const XMLCh *super); + + /// @param component Repository ID of component + /// @param port_kind text of port stereotype from LITERALS + /// @param port_type Repository ID of port type (ie, interface type for facet) + /// @param name The name of the port + /// @param is_multiple The multiplicity of the port (ie, uses multiple.) + void add_port (const ACE_TCHAR *port_kind, + AST_Field *port_node); + + void add_managed_component (const ACE_TCHAR *home, const ACE_TCHAR *component); + + + ACE_TCHAR * union_label_value (AST_Expression *exp); + + typedef ACE_Hash_Map_Manager_Ex< ACE_TString, + CIAO::XML::XStr, + ACE_Hash <ACE_TString>, + ACE_Equal_To <ACE_TString>, + ACE_Null_Mutex > XMI_ID_MAP; + + /// Stores xmi.ids for elements, indexed by repoId. + XMI_ID_MAP id_map_; + + typedef ACE_Unbounded_Stack<XERCES_CPP_NAMESPACE::DOMElement *> ELEMENT_STACK; + + /// Stores elements we are currently generating XMI. Top of stack is the current + /// element. + ELEMENT_STACK stack_; + + struct ElementContext { + ACE_TString ns_; + XERCES_CPP_NAMESPACE::DOMElement *elem_; + }; + + typedef ACE_Hash_Map_Manager_Ex< ACE_TString, + ElementContext, + ACE_Hash <ACE_TString>, + ACE_Equal_To <ACE_TString>, + ACE_Null_Mutex > REPO_ID_MAP; + + /// Stores elements that were forward declared. Also stores modules that can + /// be reopened. + REPO_ID_MAP repo_id_map_; + + /// Provides a "protected" push that is popped when the current scope + /// is exited. + struct ES_Guard + { + ES_Guard (const ACE_TCHAR *name, idl3_to_xmi_visitor *); + ES_Guard (XERCES_CPP_NAMESPACE::DOMElement *ele, + idl3_to_xmi_visitor *); + ~ES_Guard (void); + + idl3_to_xmi_visitor &vis_; + }; + + friend struct ES_Guard; + + typedef ACE_Unbounded_Stack< ACE_TString > STRING_STACK; + + /// Stores namespaces associated with our current scope. + STRING_STACK namespace_; + + /// Provides a protected push for the namespace stack that + /// pops when the current scope is exited. + struct NS_Guard + { + NS_Guard (const ACE_TCHAR *name, idl3_to_xmi_visitor *); + ~NS_Guard (void); + + idl3_to_xmi_visitor &vis_; + }; + + friend struct NS_Guard; + + XERCES_CPP_NAMESPACE::DOMDocument *dom_; + + XERCES_CPP_NAMESPACE::DOMElement *root_; + + XERCES_CPP_NAMESPACE::DOMElement *generalizations_; + + XERCES_CPP_NAMESPACE::DOMElement *associations_; + + const CIAO::XML::XStr base_id_; + + /// true if for some reason the generated output is bad + /// and shouldn't be written. + bool output_dirty_; + + bool skip_imported_; + + /// true if we are in enum "scope". + bool visiting_enum_; + + /// Used to determine IDL ordering of union labels. + size_t order_; + + /// USed to cache the type of union descriminators + AST_ConcreteType *union_disc_; + + /// Used to cache the type whose scope we are currently in. + AST_Decl *cached_type_; + }; + } +} + +#endif diff --git a/modules/CIAO/tools/IDL3_to_XMI/IR_Simulator_visitor.cpp b/modules/CIAO/tools/IDL3_to_XMI/IR_Simulator_visitor.cpp new file mode 100644 index 00000000000..3d977ddc73b --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_XMI/IR_Simulator_visitor.cpp @@ -0,0 +1,1193 @@ +// $Id$ + +#include "IR_Simulator_visitor.h" + +#include "be_sunsoft.h" +#include "be_extern.h" + +#include "ast_argument.h" +#include "ast_array.h" +#include "ast_attribute.h" +#include "ast_component_fwd.h" +#include "ast_provides.h" +#include "ast_uses.h" +#include "ast_publishes.h" +#include "ast_emits.h" +#include "ast_consumes.h" +#include "ast_enum.h" +#include "ast_enum_val.h" +#include "ast_eventtype.h" +#include "ast_eventtype_fwd.h" +#include "ast_exception.h" +#include "ast_finder.h" +#include "ast_field.h" +#include "ast_home.h" +#include "ast_operation.h" +#include "ast_root.h" +#include "ast_sequence.h" +#include "ast_string.h" +#include "ast_structure_fwd.h" +#include "ast_template_module.h" +#include "ast_template_module_inst.h" +#include "ast_template_module_ref.h" +#include "ast_param_holder.h" +#include "ast_typedef.h" +#include "ast_union.h" +#include "ast_union_branch.h" +#include "ast_union_fwd.h" +#include "ast_union_label.h" +#include "ast_valuebox.h" +#include "ast_valuetype_fwd.h" +#include "ast_native.h" +#include "utl_exceptlist.h" +#include "utl_identifier.h" +#include "utl_idlist.h" +#include "utl_string.h" +#include "global_extern.h" +#include "nr_extern.h" +#include "ace/OS_NS_stdio.h" + + +#include <iostream> +#include <limits> + +#if 0 +#define XMI_TRACE(X) std::cout << X << std::endl +#else +#define XMI_TRACE(X) +#endif + +namespace CIAO +{ + namespace XMI + { + struct Incr_Guard + { + public: + Incr_Guard (size_t &subject, bool arm = false) + : subject_ (subject), + armed_ (arm) + { + } + + ~Incr_Guard (void) + { + if (this->armed_) + --subject_; + } + void arm (void) + { + this->armed_ = true; + ++subject_; + } + + private: + size_t &subject_; + bool armed_; + }; + + ir_simulator_visitor::ir_simulator_visitor (void) + : associating_ (false) + { + } + + ir_simulator_visitor::~ir_simulator_visitor (void) + { + } + + int + ir_simulator_visitor::visit_decl (AST_Decl *) + { + XMI_TRACE ("got a decl"); + return 0; + } + + int + ir_simulator_visitor::visit_scope (UTL_Scope *node) + { + XMI_TRACE ("got a scope"); + + for (UTL_ScopeActiveIterator si (node, UTL_Scope::IK_decls); + !si.is_done (); + si.next ()) + { + AST_Decl *d = si.item (); + + if (d->ast_accept (this) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "ir_simulator_visitor::visit_scope - " + "codegen for scope failed\n"), + -1); + } + } + return 0; + } + + int + ir_simulator_visitor::visit_type (AST_Type *) + { + XMI_TRACE ("got a type"); + return 0; + } + + int + ir_simulator_visitor::visit_predefined_type (AST_PredefinedType *) + { + XMI_TRACE ("predef type"); + return 0; + } + + int + ir_simulator_visitor::visit_module (AST_Module *node) + { + XMI_TRACE ("module"); + + if (!this->do_i_care (node)) + { + return 0; + } + + Incr_Guard guard (this->associating_); + + if (!this->associating_) + { + // not associating, imported, not my concern + if (node->imported ()) + { + return 0; + } + // not imported, but not associating, need to set the guard + else + { + guard.arm (); + } + } + // associating, import + else + { + node->set_imported (false); + } + + try + { + if (this->visit_scope (node) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "idl3_to_idl2_visitor::visit_module - " + "codegen for scope failed\n"), + -1); + } + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + ir_simulator_visitor::visit_template_module (AST_Template_Module *node) + { + XMI_TRACE ("template module"); + + throw Error ("Template modules not supported", node); + + return 0; + } + + int + ir_simulator_visitor::visit_template_module_inst ( + AST_Template_Module_Inst *node) + { + XMI_TRACE ("template module instance"); + + throw Error ("Template modules not supported", node); + + return 0; + } + + int + ir_simulator_visitor::visit_template_module_ref ( + AST_Template_Module_Ref *node) + { + XMI_TRACE ("template module reference"); + + throw Error ("Template modules not supported", node); + + return 0; + } + + int + ir_simulator_visitor::visit_param_holder (AST_Param_Holder *node) + { + XMI_TRACE ("param holder"); + + throw Error ("Param holders not supported", node); + + return 0; + } + + int + ir_simulator_visitor::visit_finder (AST_Finder *node) + { + XMI_TRACE ("finder"); + + throw Error ("Finders not supported", node); + + return 0; + } + + int + ir_simulator_visitor::visit_interface (AST_Interface *node) + { + XMI_TRACE ("interface"); + + if (!this->do_i_care (node)) + { + return 0; + } + + Incr_Guard guard (this->associating_); + + if (!this->associating_) + { + // not associating, imported, not my concern + if (node->imported ()) + { + return 0; + } + // not imported, but not associating, need to set the guard + else + { + guard.arm (); + } + } + // associating, import + else + { + node->set_imported (false); + } + + try + { + // Inheritance + for (long i = 0; i < node->n_inherits (); ++i) + { + node->inherits ()[i]->ast_accept (this); + } + + if (this->visit_scope (node) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "idl3_to_idl2_visitor::visit_interface - " + "codegen for scope failed\n"), + -1); + } + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + ir_simulator_visitor::visit_interface_fwd (AST_InterfaceFwd *node) + { + XMI_TRACE ("interface_fwd"); + + // won't hurt to import the fwd interface + node->set_imported (false); + + return 0; + } + + int + ir_simulator_visitor::visit_valuebox (AST_ValueBox *node) + { + XMI_TRACE ("valuebox"); + + if (!this->do_i_care (node)) + { + return 0; + } + + Incr_Guard guard (this->associating_); + + if (!this->associating_) + { + // not associating, imported, not my concern + if (node->imported ()) return 0; + // not imported, but not associating, need to set the guard + else guard.arm (); + } + // associating, import + else + { + node->set_imported (false); + } + + try + { + // **** need to visit type we are boxing? + node->boxed_type ()->ast_accept (this); + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + ir_simulator_visitor::visit_valuetype (AST_ValueType *node) + { + XMI_TRACE ("valuetype"); + + try + { + this->visit_valuetype_impl (node); + } + catch (Error &err) + { + err.node (node); + } + + return 0; + } + + void + ir_simulator_visitor::visit_valuetype_impl (AST_ValueType *node) + { + Incr_Guard guard (this->associating_); + + if (!this->do_i_care (node)) + { + return; + } + + if (!this->associating_) + { + // not associating, imported, not my concern + if (node->imported ()) + { + return; + } + // not imported, but not associating, need to set the guard + else + { + guard.arm (); + } + } + // associating, import + else + { + node->set_imported (false); + } + + try + { + AST_Type *t = node->inherits_concrete (); + AST_ValueType *v = + AST_ValueType::narrow_from_decl (t); + + if (v != 0) + { + this->visit_valuetype_impl (v); + } + + long lim = node->n_supports (); + AST_Type **sppts = node->supports (); + + for (long i = 0; i < lim; ++i) + { + sppts[i]->ast_accept (this); + } + + this->visit_scope (node); + } + catch (Error &err) + { + err.node (node); + throw; + } + } + + int + ir_simulator_visitor::visit_valuetype_fwd (AST_ValueTypeFwd *node) + { + XMI_TRACE ("valuetype_fwd"); + + try + { + // no harm from importing a fwd interface + // node->is_imported (false); + } + catch (Error &err) + { + err.node (node); + } + + return 0; + } + + int + ir_simulator_visitor::visit_component (AST_Component *node) + { + XMI_TRACE ("component"); + + if (!this->do_i_care (node)) + { + return 0; + } + + Incr_Guard guard (this->associating_); + + if (!this->associating_) + { + // not associating, imported, not my concern + if (node->imported ()) + { + return 0; + } + // not imported, but not associating, need to set the guard + else + { + guard.arm (); + } + } + // associating, import + else + { + node->set_imported (false); + } + + try + { + if (node->base_component () != 0) + { + node->base_component ()->ast_accept (this); + } + + long len = node->n_supports (); + AST_Type **sppts = node->supports (); + + for (long i = 0; i < len; ++i) + { + sppts[i]->ast_accept (this); + } + + this->visit_scope (node); + } + catch (Error &err) + { + err.node (node); + } + + return 0; + } + + int + ir_simulator_visitor::visit_component_fwd (AST_ComponentFwd *node) + { + XMI_TRACE ("component_fwd"); + + try + { + // no harm from importing a fwd interface + // node->is_imported (false); + } + catch (Error &err) + { + err.node (node); + } + + return 0; + } + + int + ir_simulator_visitor::visit_provides (AST_Provides *node) + { + return node->provides_type ()->ast_accept (this); + } + + int + ir_simulator_visitor::visit_uses (AST_Uses *node) + { + return node->uses_type ()->ast_accept (this); + } + + int + ir_simulator_visitor::visit_publishes (AST_Publishes *node) + { + return node->publishes_type ()->ast_accept (this); + } + + int + ir_simulator_visitor::visit_emits (AST_Emits *node) + { + return node->emits_type ()->ast_accept (this); + } + + int + ir_simulator_visitor::visit_consumes (AST_Consumes *node) + { + return node->consumes_type ()->ast_accept (this); + } + + int + ir_simulator_visitor::visit_porttype (AST_PortType *) + { + return 0; + } + + int + ir_simulator_visitor::visit_extended_port (AST_Extended_Port *) + { + return 0; + } + + int + ir_simulator_visitor::visit_mirror_port (AST_Mirror_Port *) + { + return 0; + } + + int + ir_simulator_visitor::visit_connector (AST_Connector *) + { + return 0; + } + + int + ir_simulator_visitor::visit_eventtype (AST_EventType *node) + { + XMI_TRACE ("eventtype"); + + try + { + this->visit_valuetype_impl (node); + } + catch (Error &err) + { + err.node (node); + } + + return 0; + } + + int + ir_simulator_visitor::visit_eventtype_fwd (AST_EventTypeFwd *node) + { + XMI_TRACE ("eventtype_fwd"); + + this->visit_valuetype_fwd (node); + + return 0; + } + + int + ir_simulator_visitor::visit_home (AST_Home *node) + { + XMI_TRACE ("home"); + + if (!this->do_i_care (node)) + { + return 0; + } + + Incr_Guard guard (this->associating_); + + if (!this->associating_) + { + // not associating, imported, not my concern + if (node->imported ()) + { + return 0; + } + // not imported, but not associating, need to set the guard + else + { + guard.arm (); + } + } + // associating, import + else + { + node->set_imported (false); + } + + try + { + // **** supported interfaces + long len = node->n_supports (); + AST_Type **sppts = node->supports (); + + for (long i = 0; i < len; ++i) + { + sppts[i]->ast_accept (this); + } + + if (node->base_home ()) + { + node->base_home ()->ast_accept (this); + } + + if (node->managed_component ()) + { + node->managed_component ()->ast_accept (this); + } + + if (node->primary_key ()) + { + node->primary_key ()->ast_accept (this); + } + + this->visit_scope (node); + } + catch (Error &err) + { + err.node (node); + } + + return 0; + } + + int + ir_simulator_visitor::visit_factory (AST_Factory *node) + { + XMI_TRACE ("factory"); + + throw Error ("Factories not supported", node); + + return 0; + } + + int + ir_simulator_visitor::visit_structure (AST_Structure *node) + { + XMI_TRACE ("structure"); + + try + { + this->visit_struct_impl (node); + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + void + ir_simulator_visitor::visit_struct_impl (AST_Structure *node) + { + if (!this->do_i_care (node)) + { + return; + } + + Incr_Guard guard (this->associating_); + + if (!this->associating_) + { + // not associating, imported, not my concern + if (node->imported ()) + { + return; + } + // not imported, but not associating, need to set the guard + else + { + guard.arm (); + } + } + // associating, import + else + { + node->set_imported (false); + } + + try + { + this->visit_scope (node); + } + catch (Error &err) + { + err.node (node); + throw; + } + } + + int + ir_simulator_visitor::visit_structure_fwd (AST_StructureFwd *node) + { + XMI_TRACE ("structure_fwd"); + + try + { + node->set_imported (false); + } + catch (Error &err) + { + err.node (node); + } + + return 0; + } + + int + ir_simulator_visitor::visit_exception (AST_Exception *node) + { + XMI_TRACE ("exception"); + + + try + { + this->visit_struct_impl (node); + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + ir_simulator_visitor::visit_expression (AST_Expression *) + { + XMI_TRACE ("expression"); + + /* Incr_Guard guard (this->associating_); + + if (!this->associating_) + { + // not associating, imported, not my concern + if (node->imported ()) return; + // not imported, but not associating, need to set the guard + else guard.arm (); + } + // associating, import + else node->set_imported (false); + */ + return 0; + } + + int + ir_simulator_visitor::visit_enum (AST_Enum *node) + { + XMI_TRACE ("enum"); + + if (!this->do_i_care (node)) + { + return 0; + } + + Incr_Guard guard (this->associating_); + + if (!this->associating_) + { + // not associating, imported, not my concern + if (node->imported ()) + { + return 0; + } + // not imported, but not associating, need to set the guard + else + { + guard.arm (); + } + } + // associating, import + else + { + node->set_imported (false); + } + + try + { + this->visit_scope (node); + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + ir_simulator_visitor::visit_operation (AST_Operation *node) + { + XMI_TRACE ("operation"); + + Incr_Guard guard (this->associating_); + + if (!this->associating_) + { + // not associating, imported, not my concern + if (node->imported ()) + { + return 0; + } + // not imported, but not associating, need to set the guard + else + { + guard.arm (); + } + } + // associating, import + else + { + node->set_imported (false); + } + + try + { + // ACE_DEBUG ((LM_DEBUG, "foo")); + + if (node->return_type ()) + { + // ACE_DEBUG ((LM_DEBUG, "bar")); + node->return_type ()->ast_accept (this); + } + + // **** arguments + // **** exceptions + UTL_ExceptList *exceptions = node->exceptions (); + + if (exceptions != 0 && exceptions->length () > 0) + { + for (UTL_ExceptlistActiveIterator ei (exceptions); + !ei.is_done (); + ei.next ()) + { + ei.item ()->ast_accept (this); + } + } + + this->visit_scope (node); + } + catch (Error &err) + { + err.node (node); + } + + return 0; + } + + int + ir_simulator_visitor::visit_field (AST_Field *node) + { + XMI_TRACE ("field"); + + if (node == 0) + { + ACE_DEBUG ((LM_DEBUG, "null field?\n")); + return 0; + } + + Incr_Guard guard (this->associating_); + + if (!this->associating_) + { + // not associating, imported, not my concern + if (node->imported ()) + { + return 0; + } + // not imported, but not associating, need to set the guard + else + { + guard.arm (); + } + } + // associating, import + else + { + node->set_imported (false); + } + + try + { + if (node->field_type ()) + { + node->field_type ()->ast_accept (this); + } + } + catch (Error &err) + { + err.node (node); + } + + return 0; + } + + int + ir_simulator_visitor::visit_argument (AST_Argument *node) + { + XMI_TRACE ("argument"); + + this->visit_field (node); + + return 0; + } + + int + ir_simulator_visitor::visit_attribute (AST_Attribute *node) + { + XMI_TRACE ("attribute"); + + return this->visit_field (node); + } + + int + ir_simulator_visitor::visit_union (AST_Union *node) + { + XMI_TRACE ("union"); + + if (!this->do_i_care (node)) + { + return 0; + } + + Incr_Guard guard (this->associating_); + + if (!this->associating_) + { + // not associating, imported, not my concern + if (node->imported ()) + { + return 0; + } + // not imported, but not associating, need to set the guard + else + { + guard.arm (); + } + } + // associating, import + else + { + node->set_imported (false); + } + + if (node->disc_type ()) + { + this->visit_type (node->disc_type ()); + } + + return this->visit_scope (node); + } + + int + ir_simulator_visitor::visit_union_fwd (AST_UnionFwd *node) + { + XMI_TRACE ("union_fwd"); + node->set_imported (false); + return 0; + } + + int + ir_simulator_visitor::visit_union_branch (AST_UnionBranch *node) + { + XMI_TRACE ("union_branch"); + this->visit_field (node); + return 0; + } + + int + ir_simulator_visitor::visit_union_label (AST_UnionLabel *node) + { + XMI_TRACE ("union_label"); + + if (node->label_val ()) + { + node->label_val ()->ast_accept (this); + } + + return 0; + } + + int + ir_simulator_visitor::visit_constant (AST_Constant *) + { + XMI_TRACE ("constant"); + + return 0; + } + + int + ir_simulator_visitor::visit_enum_val (AST_EnumVal *) + { + XMI_TRACE ("enum val"); + return 0; + } + + int + ir_simulator_visitor::visit_array (AST_Array *node) + { + XMI_TRACE ("array val"); + + if (!this->do_i_care (node)) + { + return 0; + } + + Incr_Guard guard (this->associating_); + + if (!this->associating_) + { + // not associating, imported, not my concern + if (node->imported ()) + { + return 0; + } + // not imported, but not associating, need to set the guard + else + { + guard.arm (); + } + } + // associating, import + else + { + node->set_imported (false); + } + + return node->base_type ()->ast_accept (this); + } + + int + ir_simulator_visitor::visit_sequence (AST_Sequence *node) + { + XMI_TRACE ("sequence val"); + + try + { + Incr_Guard guard (this->associating_); + + if (!this->associating_) + { + // not associating, imported, not my concern + if (node->imported ()) + { + return 0; + } + // not imported, but not associating, need to set the guard + else + { + guard.arm (); + } + } + // associating, import + else + { + node->set_imported (false); + } + + node->base_type ()->ast_accept (this); + } + catch (Error &err) + { + err.node (node); + throw; + } + + return 0; + } + + int + ir_simulator_visitor::visit_string (AST_String *) + { + XMI_TRACE ("string"); + return 0; + } + + int + ir_simulator_visitor::visit_typedef (AST_Typedef *node) + { + XMI_TRACE ("typedef"); + + Incr_Guard guard (this->associating_); + + if (!this->associating_) + { + // not associating, imported, not my concern + if (node->imported ()) + { + return 0; + } + // not imported, but not associating, need to set the guard + else + { + guard.arm (); + } + } + // associating, import + else + { + node->set_imported (false); + } + + return node->base_type ()->ast_accept (this); + } + + int + ir_simulator_visitor::visit_root (AST_Root *node) + { + XMI_TRACE ("root"); + + try + { + this->visit_scope (node); + } + catch (const Error &ex) + { + if (ex.node_ != 0) + { + ACE_ERROR ((LM_ERROR, "%s:%d:error: %s\n", + ex.node_->file_name ().c_str (), + ex.node_->line (), + ex.diag_.c_str ())); + } + else + { + ACE_ERROR ((LM_ERROR, "::error:%s\n", + ex.diag_.c_str ())); + } + + return -1; + } + + return 0; + } + + int + ir_simulator_visitor::visit_native (AST_Native *) + { + XMI_TRACE ("native"); + return 0; + } + + bool + ir_simulator_visitor::do_i_care (AST_Decl *node) + { + std::string name (node->repoID ()); + + return this->seen_types_.insert (name).second; + } + } +} diff --git a/modules/CIAO/tools/IDL3_to_XMI/IR_Simulator_visitor.h b/modules/CIAO/tools/IDL3_to_XMI/IR_Simulator_visitor.h new file mode 100644 index 00000000000..8a35bd8d71f --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_XMI/IR_Simulator_visitor.h @@ -0,0 +1,131 @@ +/** + * @file IR_Simulator_visitor.h + * @author William R. Otte <wotte@dre.vanderbilt.edu> + * $Id$ + * Implements a visitor that generates XMI for the CARDAMOM + * code generation facility. + * + * This IDL->XMI mapping appears to be based on a IDL->UML->XMI + * mapping, and should be valid XMI version 1.1 + */ + +#ifndef CIAO_IR_SIMULATOR_VISITOR_H +#define CIAO_IR_SIMULATOR_VISITOR_H + +#include "ace/Containers.h" +#include "ace/Hash_Map_Manager.h" +#include "ace/Null_Mutex.h" +#include "ace/SString.h" + +#include "xercesc/util/XercesDefs.hpp" + +#include "ast_visitor.h" +#include "ast_component.h" +#include "utl_scoped_name.h" +#include "Literals.h" +#include "XML/XercesString.h" +#include "CIAO_IDL3_TO_XMI_Export.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class TAO_OutStream; +class UTL_ExceptList; + +#include <set> +#include <string> + +namespace CIAO +{ + namespace XMI + { + + /** + * @class ir_simulator_visitor + * @brief Visitor that generates XMI for the CARDAMOM code + * generation facilities. + */ + class CIAO_IDL3_TO_XMI_Export ir_simulator_visitor + : public ast_visitor + { + public: + ir_simulator_visitor (void); + virtual ~ir_simulator_visitor (void); + + virtual int visit_decl (AST_Decl *d); + virtual int visit_scope (UTL_Scope *node); + virtual int visit_type (AST_Type *node); + virtual int visit_predefined_type (AST_PredefinedType *node); + virtual int visit_module (AST_Module *node); + virtual int visit_template_module (AST_Template_Module *node); + virtual int visit_template_module_inst (AST_Template_Module_Inst *node); + virtual int visit_template_module_ref (AST_Template_Module_Ref *node); + virtual int visit_param_holder (AST_Param_Holder *node); + virtual int visit_finder (AST_Finder *node); + virtual int visit_interface (AST_Interface *node); + virtual int visit_interface_fwd (AST_InterfaceFwd *node); + virtual int visit_valuebox (AST_ValueBox *node); + virtual int visit_valuetype (AST_ValueType *node); + void visit_valuetype_impl (AST_ValueType *); + virtual int visit_valuetype_fwd (AST_ValueTypeFwd *node); + virtual int visit_component (AST_Component *node); + virtual int visit_component_fwd (AST_ComponentFwd *node); + virtual int visit_provides (AST_Provides *node); + virtual int visit_uses (AST_Uses *node); + virtual int visit_publishes (AST_Publishes *node); + virtual int visit_emits (AST_Emits *node); + virtual int visit_consumes (AST_Consumes *node); + virtual int visit_porttype (AST_PortType *node); + virtual int visit_extended_port (AST_Extended_Port *node); + virtual int visit_mirror_port (AST_Mirror_Port *node); + virtual int visit_connector (AST_Connector *node); + virtual int visit_eventtype (AST_EventType *node); + virtual int visit_eventtype_fwd (AST_EventTypeFwd *node); + virtual int visit_home (AST_Home *node); + virtual int visit_factory (AST_Factory *node); + virtual int visit_structure (AST_Structure *node); + void visit_struct_impl (AST_Structure *node); + virtual int visit_structure_fwd (AST_StructureFwd *node); + virtual int visit_exception (AST_Exception *node); + virtual int visit_expression (AST_Expression *node); + virtual int visit_enum (AST_Enum *node); + virtual int visit_operation (AST_Operation *node); + virtual int visit_field (AST_Field *node); + virtual int visit_argument (AST_Argument *node); + virtual int visit_attribute (AST_Attribute *node); + virtual int visit_union (AST_Union *node); + virtual int visit_union_fwd (AST_UnionFwd *node); + virtual int visit_union_branch (AST_UnionBranch *node); + virtual int visit_union_label (AST_UnionLabel *node); + virtual int visit_constant (AST_Constant *node); + virtual int visit_enum_val (AST_EnumVal *node); + virtual int visit_array (AST_Array *node); + virtual int visit_sequence (AST_Sequence *node); + virtual int visit_string (AST_String *node); + virtual int visit_typedef (AST_Typedef *node); + virtual int visit_root (AST_Root *node); + virtual int visit_native (AST_Native *node); + + struct Error + { + Error (const ACE_CString &diag, AST_Decl *node = 0) + : diag_ (diag), + node_ (node) + {} + + void node (AST_Decl *node) { if (node_ == 0) node_ = node; } + + const ACE_CString diag_; + AST_Decl *node_; + }; + + private: + bool do_i_care (AST_Decl *node); + size_t associating_; + std::set <std::string> seen_types_; + }; + } +} +#endif diff --git a/modules/CIAO/tools/IDL3_to_XMI/Literals.cpp b/modules/CIAO/tools/IDL3_to_XMI/Literals.cpp new file mode 100644 index 00000000000..2172bbeb075 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_XMI/Literals.cpp @@ -0,0 +1,156 @@ +// $Id$ + +#include "Literals.h" + +namespace CIAO +{ + namespace XMI + { + + const ACE_TCHAR* const LITERALS[MAX_LITERAL] = + { + ACE_TEXT("xmi.version"), // VERSION_TAG + ACE_TEXT("1.1"), // VERSION_VALUE + ACE_TEXT("xmlns:UML"), // NS_TAG + ACE_TEXT("org.omg/UML1.3"), // NS_VALUE + ACE_TEXT("XMI.header"), // HEADER_TAG + ACE_TEXT("XMI.documentation"), // DOC_TAG + ACE_TEXT("XMI.exporter"), // EXPORTER_TAG + ACE_TEXT("DOC Group IDL to XMI converter"), // EXPORTER_VALUE + ACE_TEXT("XMI.content"), // CONTENT_TAG + ACE_TEXT("UML:Model"), // MODEL_TAG + ACE_TEXT("xmi.id"), // XMI_ID + ACE_TEXT("UML:Namespace.ownedElement"), // OWNEDELEMENT_TAG + ACE_TEXT("UML:Package"), // PACKAGE_TAG + ACE_TEXT("UML:ModelElement"), // MODELELEMENT_TAG + ACE_TEXT("UML:ModelElement.taggedValue"), // ME_TV_TAG + ACE_TEXT("UML:ModelElement.constraint"), // ME_CONS_TAG + ACE_TEXT("UML:Constraint"), // CONSTRAINT + ACE_TEXT("UML:TaggedValue"), // TV_TAG + ACE_TEXT("UML:Stereotype"), // STEREOTYPE_TAG + ACE_TEXT("UML:Class"), // CLASS_TAG + ACE_TEXT("UML:Operation"), // OP_TAG + ACE_TEXT("UML:BehavioralFeature.parameter"), // BFP_TAG + ACE_TEXT("UML:Parameter"), // PARAM_TAG + ACE_TEXT("UML:BehavioralFeature.raisedException"), // BF_RE_TAG + ACE_TEXT("UML:Exception"), // EXCEPT_TAG + ACE_TEXT("UML:Attribute"), // ATTR_TAG + ACE_TEXT("UML:Association"), // ASSOC_TAG + ACE_TEXT("UML:Association.connection"), // ASSOC_CONN_TAG + ACE_TEXT("UML:AssociationEnd"), // ASSOC_END_TAG + ACE_TEXT("UML:AssociationEnd.qualifier"), // ASSOC_END_QUAL_TAG + ACE_TEXT("UML:Generalization"), // GEN_TAG + ACE_TEXT("UML:Generalization.subtype"), // GEN_SUB_TAG + ACE_TEXT("UML:Generalization.supertype"), // GEN_SUPER_TAG + ACE_TEXT("UML:GeneralizableElement"), // GEN_ELEMENT_TAG + ACE_TEXT("UML:GeneralizableElement.generalization"),// GEN_ELEMENT_GEN_TAG + ACE_TEXT("UML:Exception"), // EXCEPTION_TAG + + // ******* Attributes + ACE_TEXT("tag"), // TAG + ACE_TEXT("value"), // VALUE + ACE_TEXT("name"), // NAME + ACE_TEXT("baseClass"), // BASEC + ACE_TEXT("visibility"), // VISIBIL + ACE_TEXT("stereotype"), // STEREO_ATTR + ACE_TEXT("namespace"), // NS + ACE_TEXT("owner"), // OWNER + ACE_TEXT("kind"), // KIND + ACE_TEXT("behavioralFeature"), // BFEATURE + ACE_TEXT("type"), // TYPE + ACE_TEXT("isAbstract"), // ABSTRACT + ACE_TEXT("multiplicity"), // MULT + ACE_TEXT("xmi.idref"), // IDREF + ACE_TEXT("ownerScope"), // OWNER_SCOPE + ACE_TEXT("changeable"), // CHANGEABLE + + // ******* Attribute values + ACE_TEXT("Association"), // ASSOC + ACE_TEXT("Class"), // CLASS + ACE_TEXT("DataType"), // DATATYPE + ACE_TEXT("Package"), // PACKAGE + ACE_TEXT("null"), // NULL + ACE_TEXT("Attribute"), // ATTR + ACE_TEXT("public"), // PUBLIC + ACE_TEXT("private"), // _PRIVATE + ACE_TEXT("typeid"), // TYPEID + ACE_TEXT("raises"), // RAISES + ACE_TEXT("return"), // RETURN + ACE_TEXT("in"), // _IN + ACE_TEXT("inout"), // INOUT + ACE_TEXT("out"), // _OUT + ACE_TEXT("true"), // _TRUE + ACE_TEXT("false"), // _FALSE + ACE_TEXT("TRUE"), // CAPS_TRUE + ACE_TEXT("FALSE"), // CAPS_FALSE + ACE_TEXT("1..1"), // MULT_OTO + ACE_TEXT("0..1"), // MULT_ZTO + ACE_TEXT("IDLOrder"), // IDLORDER + ACE_TEXT("index"), // INDEX + ACE_TEXT("constraintUpperValue"), // CONST_UPPER + ACE_TEXT("*"), // UNBOUNDED_SEQ + ACE_TEXT("Case"), // CASE + ACE_TEXT("default"), // DEFAULT_UNION + ACE_TEXT("classifier"), // CLASSIFIER + ACE_TEXT("frozen"), // FROZEN + ACE_TEXT("initialValue"), // INIT_VAL + + //******** Stereotypes + ACE_TEXT("CCMConsumes"), // ST_CONSUMES + ACE_TEXT("CORBAAnonymousSequence"), // ST_ANON_SEQ + ACE_TEXT("CORBAPrincipal"), // ST_PRINC + ACE_TEXT("CORBAUnion"), // ST_UNION + ACE_TEXT("CCMUses"), // ST_USES + ACE_TEXT("CORBASequence"), // ST_SEQ + ACE_TEXT("readonlyEnd"), // ST_ROE + ACE_TEXT("readonly"), // ST_RO + ACE_TEXT("CORBAObject"), // ST_OBJ + ACE_TEXT("CORBAstring"), // ST_STR + ACE_TEXT("CORBAlongdouble"), // ST_LD + ACE_TEXT("CORBAAnonymousArray"), // ST_ANON_ARR + ACE_TEXT("CORBAAlias"), // ST_ALIAS + ACE_TEXT("null"), // ST_NULL + ACE_TEXT("CORBAValue"), // ST_VALUE + ACE_TEXT("void"), // ST_VOID + ACE_TEXT("CORBAException"), // ST_EX + ACE_TEXT("CORBAoctet"), // ST_OCTET + ACE_TEXT("CCMManages"), // ST_MANAGES + ACE_TEXT("CORBAwstring"), // ST_WSTR + ACE_TEXT("CORBAfloat"), // ST_FLOAT + ACE_TEXT("CORBAEnum"), // ST_ENUM + ACE_TEXT("CORBAValueSupports"), // ST_VAL_SUP + ACE_TEXT("CORBAModule"), // ST_MODULE + ACE_TEXT("CCMHomeFinder"), // ST_HFINDER + ACE_TEXT("CORBAdouble"), // ST_DOUBLE + ACE_TEXT("CORBAlonglong"), // ST_LL + ACE_TEXT("CCMHomeFactory"), // ST_HFACT + ACE_TEXT("CORBAArray"), // ST_ARR + ACE_TEXT("CCMComponent"), // ST_COMP + ACE_TEXT("CORBAshort"), // ST_SHORT + ACE_TEXT("CORBATypedef"), // ST_TYPEDEF + ACE_TEXT("CORBAunsignedlonglong"), // ST_ULL + ACE_TEXT("CORBAlong"), // ST_LONG + ACE_TEXT("CORBATypeCode"), // ST_TC + ACE_TEXT("CCMHome"), // ST_HOME + ACE_TEXT("CORBAStruct"), // ST_STRUCT + ACE_TEXT("CORBAFixed"), // ST_FIXED + ACE_TEXT("CORBAunsignedshort"), // ST_US + ACE_TEXT("CCMEmits"), // ST_EMITS + ACE_TEXT("CORBABoxedValue"), // ST_BOXVALUE + ACE_TEXT("CORBAboolean"), // ST_BOOL + ACE_TEXT("CORBAConstant"), // ST_CONST + ACE_TEXT("CCMPublishes"), // ST_PUBLISH + ACE_TEXT("CORBAConstants"), // ST_CONSTANTS + ACE_TEXT("CCMProvides"), // ST_PROVIDES + ACE_TEXT("CORBAwchar"), // ST_WCHAR + ACE_TEXT("CORBAunsignedlong"), // ST_UL + ACE_TEXT("CORBAValueFactory"), // ST_VAL_FACT + ACE_TEXT("CCMEvent"), // ST_EVENT + ACE_TEXT("CORBAchar"), // ST_CHAR + ACE_TEXT("CORBAInterface"), // ST_INTF + ACE_TEXT("CCMPrimaryKey"), // ST_PRI_KEY + ACE_TEXT("CORBAany"), // ST_ANY + ACE_TEXT("CORBAnative") // ST_NATIVE + }; + } +} diff --git a/modules/CIAO/tools/IDL3_to_XMI/Literals.h b/modules/CIAO/tools/IDL3_to_XMI/Literals.h new file mode 100644 index 00000000000..e8c36180b30 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_XMI/Literals.h @@ -0,0 +1,170 @@ +/** + * @file Literals.h + * @author William R. Otte <wotte@dre.vanderbilt.edu> + * + * $Id$ + * + */ + +#ifndef XMI_LITERALS_H +#define XMI_LITERALS_H + +#include "ace/config-lite.h" + +namespace CIAO +{ + namespace XMI + { + enum LITERAL_T + { + VERSION_TAG, + VERSION_VALUE, + NS_TAG, + NS_VALUE, + HEADER_TAG, + DOC_TAG, + EXPORTER_TAG, + EXPORTER_VALUE, + CONTENT_TAG, + MODEL_TAG, + XMI_ID, + OWNEDELEMENT_TAG, + PACKAGE_TAG, + MODELELEMENT_TAG, + ME_TV_TAG, + ME_CONS_TAG, + CONSTRAINT, + TV_TAG, + STEREOTYPE_TAG, + CLASS_TAG, + OP_TAG, + BFP_TAG, + PARAM_TAG, + BF_RE_TAG, + EXCEPT_TAG, + ATTR_TAG, + ASSOC_TAG, + ASSOC_CONN_TAG, + ASSOC_END_TAG, + ASSOC_END_QUAL_TAG, + GEN_TAG, + GEN_SUB_TAG, + GEN_SUPER_TAG, + GEN_ELEMENT_TAG, + GEN_ELEMENT_GEN_TAG, + EXCEPTION_TAG, + + // Attributes + TAG, + VALUE, + NAME, + BASEC, + VISIBIL, + STEREO_ATTR, + NS, + OWNER, + KIND, + BFEATURE, + TYPE, + ABSTRACT, + MULT, + IDREF, + OWNER_SCOPE, + CHANGEABLE, + + // attribute values + ASSOC, + CLASS, + DATATYPE, + PACKAGE, + __NULL, + ATTR, + PUBLIC, + _PRIVATE, + TYPEID, + RAISES, + RETURN, + _IN, + INOUT, + _OUT, + _TRUE, + _FALSE, + CAPS_TRUE, + CAPS_FALSE, + MULT_OTO, + MULT_ZTO, + IDLORDER, + INDEX, + CONST_UPPER, + UNBOUNDED_SEQ, + CASE, + DEFAULT_UNION, + CLASSIFIER, + FROZEN, + INIT_VAL, + + // Stereotypes + ST_CONSUMES, + ST_ANON_SEQ, + ST_PRINC, + ST_UNION, + ST_USES, + ST_SEQ, + ST_ROE, + ST_RO, + ST_OBJ, + ST_STR, + ST_LD, + ST_ANON_ARR, + ST_ALIAS, + ST_NULL, + ST_VALUE, + ST_VOID, + ST_EX, + ST_OCTET, + ST_MANAGES, + ST_WSTR, + ST_FLOAT, + ST_ENUM, + ST_VAL_SUP, + ST_MODULE, + ST_HFINDER, + ST_DOUBLE, + ST_LL, + ST_HFACT, + ST_ARR, + ST_COMP, + ST_SHORT, + ST_TYPEDEF, + ST_ULL, + ST_LONG, + ST_TC, + ST_HOME, + ST_STRUCT, + ST_FIXED, + ST_US, + ST_EMITS, + ST_BOXVALUE, + ST_BOOL, + ST_CONST, + ST_PUBLISH, + ST_CONSTANTS, + ST_PROVIDES, + ST_WCHAR, + ST_UL, + ST_VAL_FACT, + ST_EVENT, + ST_CHAR, + ST_INTF, + ST_PRI_KEY, + ST_ANY, + ST_NATIVE, + + MAX_LITERAL + }; + + extern const ACE_TCHAR* const LITERALS[MAX_LITERAL]; + } +} + +#endif /* XMI_LITERALS_H */ diff --git a/modules/CIAO/tools/IDL3_to_XMI/be_extern.h b/modules/CIAO/tools/IDL3_to_XMI/be_extern.h new file mode 100644 index 00000000000..532b5ebe64e --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_XMI/be_extern.h @@ -0,0 +1,86 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ +/* + +COPYRIGHT + +Copyright 1992, 1993, 1994 Sun Microsystems, Inc. Printed in the United +States of America. All Rights Reserved. + +This product is protected by copyright and distributed under the following +license restricting its use. + +The Interface Definition Language Compiler Front End (CFE) is made +available for your use provided that you include this license and copyright +notice on all media and documentation and the software program in which +this product is incorporated in whole or part. You may copy and extend +functionality (but may not remove functionality) of the Interface +Definition Language CFE without charge, but you are not authorized to +license or distribute it to anyone else except as part of a product or +program developed by you or with the express written consent of Sun +Microsystems, Inc. ("Sun"). + +The names of Sun Microsystems, Inc. and any of its subsidiaries or +affiliates may not be used in advertising or publicity pertaining to +distribution of Interface Definition Language CFE as permitted herein. + +This license is effective until terminated by Sun for failure to comply +with this license. Upon termination, you shall destroy or return all code +and documentation for the Interface Definition Language CFE. + +INTERFACE DEFINITION LANGUAGE CFE IS PROVIDED AS IS WITH NO WARRANTIES OF +ANY KIND INCLUDING THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS +FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR ARISING FROM A COURSE OF +DEALING, USAGE OR TRADE PRACTICE. + +INTERFACE DEFINITION LANGUAGE CFE IS PROVIDED WITH NO SUPPORT AND WITHOUT +ANY OBLIGATION ON THE PART OF Sun OR ANY OF ITS SUBSIDIARIES OR AFFILIATES +TO ASSIST IN ITS USE, CORRECTION, MODIFICATION OR ENHANCEMENT. + +SUN OR ANY OF ITS SUBSIDIARIES OR AFFILIATES SHALL HAVE NO LIABILITY WITH +RESPECT TO THE INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY +INTERFACE DEFINITION LANGUAGE CFE OR ANY PART THEREOF. + +IN NO EVENT WILL SUN OR ANY OF ITS SUBSIDIARIES OR AFFILIATES BE LIABLE FOR +ANY LOST REVENUE OR PROFITS OR OTHER SPECIAL, INDIRECT AND CONSEQUENTIAL +DAMAGES, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +Use, duplication, or disclosure by the government is subject to +restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in +Technical Data and Computer Software clause at DFARS 252.227-7013 and FAR +52.227-19. + +Sun, Sun Microsystems and the Sun logo are trademarks or registered +trademarks of Sun Microsystems, Inc. + +SunSoft, Inc. +2550 Garcia Avenue +Mountain View, California 94043 + +NOTE: + +SunOS, SunSoft, Sun, Solaris, Sun Microsystems or the Sun logo are +trademarks or registered trademarks of Sun Microsystems, Inc. + +*/ + +#ifndef TAO_IFR_BE_EXTERN_H +#define TAO_IFR_BE_EXTERN_H + +#include "CIAO_IDL3_TO_XMI_Export.h" +#include "be_global.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +extern CIAO_IDL3_TO_XMI_Export BE_GlobalData *be_global; + +extern CIAO_IDL3_TO_XMI_Export int BE_init (int &, ACE_TCHAR*[]); +extern CIAO_IDL3_TO_XMI_Export void BE_post_init (char *[], long); +extern CIAO_IDL3_TO_XMI_Export void BE_version (void); +extern CIAO_IDL3_TO_XMI_Export void BE_produce (void); +extern CIAO_IDL3_TO_XMI_Export void BE_cleanup (void); +extern CIAO_IDL3_TO_XMI_Export void BE_abort (void); + +#endif /* TAO_IFR_BE_EXTERN_H */ diff --git a/modules/CIAO/tools/IDL3_to_XMI/be_global.cpp b/modules/CIAO/tools/IDL3_to_XMI/be_global.cpp new file mode 100644 index 00000000000..ceeb3f56ed6 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_XMI/be_global.cpp @@ -0,0 +1,222 @@ +// $Id$ + +// ============================================================================ +// +// +// = LIBRARY +// TAO_IDL3_TO_IDL2L_BE_DLL +// +// = FILENAME +// be_global.cpp +// +// = DESCRIPTION +// Stores global data specific to the compiler back end. +// +// = AUTHOR +// Jeff Parsons <j.parsons@vanderbilt.edu> +// +// ============================================================================ + +#include "be_global.h" +#include "ast_generator.h" +#include "global_extern.h" +#include "idl_defines.h" +#include "ace/OS_NS_stdio.h" + +CIAO_IDL3_TO_XMI_Export BE_GlobalData *be_global = 0; + +BE_GlobalData::BE_GlobalData (void) + : ir_filter_ (false), + filename_ (0), + output_dir_ (0), + dtd_ ("XMI.dtd"), + local_only_(true) +{ +} + +BE_GlobalData::~BE_GlobalData (void) +{ +} + +bool +BE_GlobalData::ir_filter (void) const +{ + return this->ir_filter_; +} + +void +BE_GlobalData::ir_filter (bool flag) +{ + this->ir_filter_ = flag; +} + +const char * +BE_GlobalData::filename (void) const +{ + return this->filename_; +} + +void +BE_GlobalData::filename (char *fname) +{ + this->filename_ = fname; +} + +const char* +BE_GlobalData::output_dir (void) const +{ + return this->output_dir_; +} + +void +BE_GlobalData::output_dir (const char* s) +{ + delete [] this->output_dir_; + this->output_dir_ = ACE::strnew (s); +} + +const char* +BE_GlobalData::dtd (void) const +{ + return this->dtd_.c_str (); +} + +void +BE_GlobalData::dtd (const char* s) +{ + this->dtd_ = s; +} + +bool +BE_GlobalData::local_only (void) const +{ + return this->local_only_; +} + +void +BE_GlobalData::local_only (bool flag) +{ + this->local_only_ = flag; +} + +void +BE_GlobalData::parse_args (long &i, char **av) +{ + switch (av[i][1]) + { + // Directory where the generated file is to + // be kept. Default is the current directory from which + // <tao_idl3_to_idl2> is called. + case 'f': + be_global->ir_filter (true); + break; + + case 'o': + switch (av[i][2]) + { + case 'd': + if (av[i][3] == '\0') + { + be_global->output_dir (av [i + 1]); + i++; + } + else + { + be_global->output_dir (av[i] + 3); + } + break; + + case 'f': + if (av[i][3] == '\0') + { + be_global->filename (av [i + 1]); + i++; + } + else + { + be_global->filename (av[i] + 3); + } + break; + default: + idl_global->set_compile_flags (idl_global->compile_flags () + | IDL_CF_ONLY_USAGE); + } + break; + + case 'x': + if (av[i][3] == '\0') + { + be_global->dtd (av [i + 1]); + ++i; + } + else + { + be_global->dtd (av[i] + 3); + } + break; + + case 'n': + be_global->local_only (false); + break; + + default: + ACE_ERROR (( + LM_ERROR, + ACE_TEXT ("IDL: I don't understand the '%s' option\n"), + av[i])); + + idl_global->set_compile_flags (idl_global->compile_flags () + | IDL_CF_ONLY_USAGE); + break; + } +} + +// Prepare an argument for a BE +void +BE_GlobalData::prep_be_arg (char *) +{ +} + +void +BE_GlobalData::arg_post_proc (void) +{ +} + +void +BE_GlobalData::usage (void) const +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT (" -f\t\t\tsimulates IFR type filtering on included types\n") + )); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT (" -od <dir>\t\toutput directory for the generated file ") + ACE_TEXT ("(default is current directory)\n") + )); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT (" -of <dir>\t\toutput file for the generated XMI ") + ACE_TEXT ("(default for example.idl is example.xmi)\n") + )); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT (" -xd <dtd_file>\t\tfull path to XMI dtd file to include in generated file ") + ACE_TEXT ("(default is XMI.dtd)\n") + )); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT (" -n\t\t\texports XMI for non-local entities\n") + )); +} + +AST_Generator * +BE_GlobalData::generator_init (void) +{ + AST_Generator *gen = 0; + ACE_NEW_RETURN (gen, + AST_Generator, + 0); + return gen; +} + + +void +BE_GlobalData::destroy (void) +{ +} diff --git a/modules/CIAO/tools/IDL3_to_XMI/be_global.h b/modules/CIAO/tools/IDL3_to_XMI/be_global.h new file mode 100644 index 00000000000..2092587d94a --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_XMI/be_global.h @@ -0,0 +1,103 @@ +/* -*- c++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO_IFR_BE_DLL +// +// = FILENAME +// be_global.h +// +// = DESCRIPTION +// Header file for class containing compiler back end global data. +// +// = AUTHOR +// Jeff Parsons <parsons@cs.wustl.edu> +// +// ============================================================================ + +#ifndef TAO_IFR_BE_GLOBAL_H +#define TAO_IFR_BE_GLOBAL_H + +#include "CIAO_IDL3_TO_XMI_Export.h" +#include "idl_defines.h" + +#include "ace/SString.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class AST_Generator; + +// Defines a class containing all back end global data. + +class CIAO_IDL3_TO_XMI_Export BE_GlobalData +{ +public: + // = TITLE + // BE_GlobalData + // + // = DESCRIPTION + // Storage of global data specific to the compiler back end + // + BE_GlobalData (void); + // Constructor. + + virtual ~BE_GlobalData (void); + // Destructor. + + // Data accessors. + bool ir_filter (void) const; + void ir_filter (bool flag); + + const char *filename (void) const; + void filename (char *fname); + + const char* output_dir (void) const; + void output_dir (const char* s); + + const char * dtd (void) const; + void dtd (const char *s); + + bool local_only (void) const; + void local_only (bool); + + void parse_args (long &i, char **av); + // Parse args that affect the backend. + + void prep_be_arg (char *s); + // Special BE arg call factored out of DRV_args. + + void arg_post_proc (void); + // Checks made after parsing args. + + void usage (void) const; + // Usage message for backend options. + + AST_Generator *generator_init (void); + // Create an AST node generator. + + void destroy (void); + // Cleanup. + +private: + bool ir_filter_; + + char *filename_; + // Name of the IDL file we are processing. + + char *output_dir_; + // Directory where the generated file is to be + // kept. Default value is 0 for this string which means the current + // directory from which the <tao_picml> is called. + + /// full path to dtd to be used. + ACE_CString dtd_; + + /// generate xmi for local entities only + bool local_only_; +}; + +#endif /* TAO_IFR_BE_GLOBAL_H */ diff --git a/modules/CIAO/tools/IDL3_to_XMI/be_helper.cpp b/modules/CIAO/tools/IDL3_to_XMI/be_helper.cpp new file mode 100644 index 00000000000..4a7b28096c6 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_XMI/be_helper.cpp @@ -0,0 +1,438 @@ +// $Id$ + +// ============================================================================ +// +// +// = LIBRARY +// TAO IDL +// +// = FILENAME +// be_helper.cpp +// +// = DESCRIPTION +// Provides helper classes to print generated code to the output +// +// = AUTHOR +// Aniruddha Gokhale +// +// Improvements by Carlos O'Ryan +// +// ============================================================================ + +#include "be_helper.h" +#include "idl_defines.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "ace/os_include/os_ctype.h" + +ACE_RCSID (be, + be_helper, + "$Id$") + +static const char copyright[] = +" <--\n" +" -*- XML -*-\n" +"\n" +" $I" "d$\n\n" +" **** Code generated by the The ACE ORB (TAO) IDL Compiler ****\n" +" TAO and the TAO IDL Compiler have been developed by:\n" +" Center for Distributed Object Computing\n" +" Washington University\n" +" St. Louis, MO\n" +" USA\n" +" http:www.cs.wustl.edu/~schmidt/doc-center.html\n" +" and\n" +" Distributed Object Computing Laboratory\n" +" University of California at Irvine\n" +" Irvine, CA\n" +" USA\n" +" http:doc.ece.uci.edu/\n" +" and\n" +" Institute for Software Integrated Systems\n" +" Vanderbilt University\n" +" Nashville, TN\n" +" USA\n" +" http:www.isis.vanderbilt.edu/\n" +"\n" +" Information about TAO is available at:\n" +" http:www.cs.wustl.edu/~schmidt/TAO.html\n" +"-->"; + +TAO_NL::TAO_NL (void) +{ +} + +TAO_INDENT::TAO_INDENT (int do_now) + : do_now_ (do_now) +{ +} + +TAO_UNINDENT::TAO_UNINDENT (int do_now) + : do_now_ (do_now) +{ +} + +const TAO_NL be_nl; +const TAO_INDENT be_idt; +const TAO_INDENT be_idt_nl (1); +const TAO_UNINDENT be_uidt; +const TAO_UNINDENT be_uidt_nl (1); + +// Methods of the TAO_OutStream class. + +TAO_OutStream::TAO_OutStream (void) + : fp_ (0), + indent_level_ (0) +{ +} + +TAO_OutStream::~TAO_OutStream (void) +{ + // Close the underlying I/O handle only if it exists. + if (this->fp_ != 0) + { + ACE_OS::fclose (this->fp_); + this->fp_ = 0; + } + + indent_level_ = 0; +} + +int +TAO_OutStream::open (const char *fname) +{ + if (fname != 0) + { + // File name exists, open an I/O file handle. + this->fp_ = ACE_OS::fopen (fname, "w"); + + if (this->fp_ != 0) + { + // Put the copyright notice. + ACE_OS::fprintf (this->fp_, + "%s\n", + copyright); + + ACE_OS::fflush (this->fp_); + + return 0; + } + else + { + return -1; + } + } + else + { + return -1; + } +} + +// Return the underlying lowlevel file pointer. +// indentation. +FILE * +TAO_OutStream::file (void) +{ + return this->fp_; +} + +int +TAO_OutStream::incr_indent (unsigned short flag) +{ + indent_level_++; + + if (flag != 0) + { + return this->indent (); + } + else + { + // Do not indent output. + return 0; + } +} + +// Indentation +int +TAO_OutStream::decr_indent (unsigned short flag) +{ + this->indent_level_--; + // Just in case somebody gets "unindent happy". + if (this->indent_level_ < 0) + { + // ACE_DEBUG ((LM_DEBUG, "negative indentation?\n")); + this->indent_level_ = 0; + } + if (flag != 0) + { + return this->indent (); + } + else + { + // Do not indent output. + return 0; + } +} + +int +TAO_OutStream::reset (void) +{ + this->indent_level_ = 0; + return 0; +} + +// Indented print. +int +TAO_OutStream::indent (void) +{ + // Based on the current indentation level, leave appropriate number of blank + // spaces in the output. + if (this->indent_level_ > 0) + { + for (int i = 0; i < this->indent_level_; i++) + { + ACE_OS::fprintf (this->fp_, " "); + ACE_OS::fflush (this->fp_); + } + } + + return 0; +} + +int +TAO_OutStream::nl (void) +{ + ACE_OS::fprintf (this->fp_, "\n"); + this->indent (); + return 0; +} + +// Printf style variable argument print. +int +TAO_OutStream::print (const char *format, ...) +{ + int result = 0; + va_list ap; + va_start (ap, format); + ACE_OSCALL (::vfprintf (this->fp_, + format, + ap), + int, + -1, + result); + + ACE_OS::fflush (this->fp_); + va_end (ap); + + return result; +} + +void +TAO_OutStream::gen_ifndef_string (const char *fname, + const char *prefix, + const char *suffix) +{ + static char macro_name [NAMEBUFSIZE]; + + ACE_OS::memset (macro_name, + '\0', + NAMEBUFSIZE); + + const char *extension = ACE_OS::strrchr (fname, '.'); + + if (extension == 0) + { + // File seems to have no extension, so let us take the name + // as it is. + extension = fname; + } + + ACE_OS::sprintf (macro_name, prefix); + + size_t offset = ACE_OS::strlen (prefix); + + // Convert letters in fname to upper case. + for (int i = 0; i < (extension - fname); i++) + { + if (isalpha (fname [i])) + { + macro_name[i + offset] = (char) toupper (fname [i]); + } + else if (isdigit (fname [i])) + { + macro_name[i + offset] = fname[i]; + } + else + { + macro_name[i + offset] = '_'; + } + } + + ACE_OS::strcat (macro_name, suffix); + + // Generate the #ifndef ... #define statements. + this->print ("#ifndef %s\n", + macro_name); + this->print ("#define %s", + macro_name); +} + +TAO_OutStream & +TAO_OutStream::operator<< (const char *str) +{ + ACE_OS::fprintf (this->fp_, "%s", str); + ACE_OS::fflush (this->fp_); + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const ACE_CDR::UShort num) +{ + ACE_OS::fprintf (this->fp_, + "%hu", + num); + + ACE_OS::fflush (this->fp_); + + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const ACE_CDR::Short num) +{ + ACE_OS::fprintf (this->fp_, + "%hd", + num); + + ACE_OS::fflush (this->fp_); + + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const ACE_CDR::ULong num) +{ + ACE_OS::fprintf (this->fp_, + "%lu", + (unsigned long) num); + + ACE_OS::fflush (this->fp_); + + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const ACE_CDR::Long num) +{ + ACE_OS::fprintf (this->fp_, + "%ld", + (long) num); + + ACE_OS::fflush (this->fp_); + + return *this; +} + +#if defined (ACE_WIN64) +TAO_OutStream & +TAO_OutStream::operator<< (const ACE_CDR::ULongLong num) +{ + ACE_OS::fprintf (this->fp_, + ACE_UINT64_FORMAT_SPECIFIER, + num); + + ACE_OS::fflush (this->fp_); + + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const ACE_CDR::LongLong num) +{ + ACE_OS::fprintf (this->fp_, + ACE_INT64_FORMAT_SPECIFIER, + num); + + ACE_OS::fflush (this->fp_); + + return *this; +} +#endif /* ACE_WIN64 */ + +TAO_OutStream & +TAO_OutStream::operator<< (const unsigned long num) +{ + ACE_OS::fprintf (this->fp_, + "%lu", + num); + + ACE_OS::fflush (this->fp_); + + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const long num) +{ + ACE_OS::fprintf (this->fp_, + "%ld", + num); + + ACE_OS::fflush (this->fp_); + + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const TAO_NL&) +{ + ACE_OS::fprintf (this->fp_ , + "\n"); + this->indent (); + + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const TAO_INDENT& i) +{ + this->incr_indent (0); + + if (i.do_now_) + { + this->nl (); + } + + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const TAO_UNINDENT& i) +{ + this->decr_indent (0); + + if (i.do_now_) + { + this->nl (); + } + + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (Identifier *id) +{ + return this->print (id); +} + +TAO_OutStream & +TAO_OutStream::operator<< (UTL_IdList *id) +{ + return this->print (id); +} + +TAO_OutStream & +TAO_OutStream::operator<< (AST_Expression *expr) +{ + return this->print (expr); +} diff --git a/modules/CIAO/tools/IDL3_to_XMI/be_helper.h b/modules/CIAO/tools/IDL3_to_XMI/be_helper.h new file mode 100644 index 00000000000..d8bbb3b1766 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_XMI/be_helper.h @@ -0,0 +1,176 @@ +/* -*- c++ -*- */ +// $Id$ + +/** + * @file be_helper.h + * @author Aniruddha Gokhale + * @author Carlos O'Ryan + * + * Defines the abstract class for outputting the C++ mapping. This is a + * helper class to the singleton TAO_CodeGen class + */ + +#ifndef TAO_BE_OUTSTRM_H +#define TAO_BE_OUTSTRM_H + +#include "ace/CDR_Base.h" + +class Identifier; +class UTL_IdList; +class AST_Expression; + +// a dummy structure to inform TAO_OutStream's << operator to put a newline +// and use the current indentation for the succeeding line +struct TAO_NL +{ +public: + TAO_NL (void); +}; + +struct TAO_INDENT +{ + // = TITLE + // Operates like a manipulator, increasing the indentation level. + // + // = DESCRIPTION + // Increase the indentation level, if the "do_now" parameter is + // not zero then the <indent> method is called on the stream. + // + TAO_INDENT (int do_now = 0); + + const int do_now_; +}; + +struct TAO_UNINDENT +{ + // = TITLE + // Operates like a manipulator, decreasing the indentation level. + // + // = DESCRIPTION + // Decrease the indentation level, if the "do_now" parameter is + // not zero then the <indent> method is called on the stream. + // + TAO_UNINDENT (int do_now = 0); + + const int do_now_; +}; + +extern const TAO_NL be_nl; +extern const TAO_INDENT be_idt; +extern const TAO_INDENT be_idt_nl; +extern const TAO_UNINDENT be_uidt; +extern const TAO_UNINDENT be_uidt_nl; + +class TAO_OutStream +{ + // =TITLE + // TAO_OutStream + // + // =DESCRIPTION + // Defines an interface by which the backend code generator can + // print its output to the underlying I/O handle. This is a + // helper class that will be used by the TAO_CodeGen + // class. However, this is an abstract class and classes that + // understand specific front ends must derive from this class. +public: + TAO_OutStream (void); + // constructor. + + virtual ~TAO_OutStream (void); + // destructor. + + int open (const char *fname); + // open the underlying low-level handle for output. + + + FILE *file (void); + // Return the underlying lowlevel file pointer. + + int incr_indent (unsigned short flag = 1); + // increment the indentation level and by default actually indent the output + // accordingly + + int decr_indent (unsigned short flag = 1); + // decrease the indentation level and by default actually indent the output + // accordingly + + int reset (void); + // reset indentation level to 0 + + int indent (void); + // indent starting next line + + int nl (void); + // put a newline and indent on the next line + + int print (const char *format, ...); + // "printf" style variable argument print + + void gen_ifndef_string (const char *fname, + const char *prefix, + const char *suffix); + + // =overloaded operators + + TAO_OutStream &operator<< (const char *str); + // output the char string and return a reference to ourselves + + TAO_OutStream &operator<< (const ACE_CDR::UShort num); + // output the integer and return a reference to ourselves + + TAO_OutStream &operator<< (const ACE_CDR::Short num); + // output the integer and return a reference to ourselves + + TAO_OutStream &operator<< (const ACE_CDR::ULong num); + // output the integer and return a reference to ourselves + + TAO_OutStream &operator<< (const ACE_CDR::Long num); + // output the integer and return a reference to ourselves + +#if defined (ACE_WIN64) + TAO_OutStream &operator<< (const ACE_CDR::ULongLong num); + // output the integer and return a reference to ourselves + + TAO_OutStream &operator<< (const ACE_CDR::LongLong num); + // output the integer and return a reference to ourselves +#endif /* ACE_WIN64 */ + + TAO_OutStream &operator<< (const unsigned long num); + // output the integer and return a reference to ourselves + + TAO_OutStream &operator<< (const long num); + // output the integer and return a reference to ourselves + + // = MANIPULATORS + + TAO_OutStream &operator<< (const TAO_NL& nl); + TAO_OutStream &operator<< (const TAO_INDENT& i); + TAO_OutStream &operator<< (const TAO_UNINDENT& i); + + // The following will be provided by specialized classes + + TAO_OutStream &operator<< (Identifier *id); + // output an Identifier node + + TAO_OutStream &operator<< (UTL_IdList *idl); + // output a scoped name + + TAO_OutStream &operator<< (AST_Expression *expr); + // output an AST_Expression node + + // provided by specialized classes + virtual TAO_OutStream &print (Identifier *id) = 0; + + virtual TAO_OutStream &print (UTL_IdList *idl) = 0; + + virtual TAO_OutStream &print (AST_Expression *idl) = 0; + +protected: + FILE *fp_; + // the underlying low-level I/O handle + + int indent_level_; + // indentation level +}; + +#endif // if !defined diff --git a/modules/CIAO/tools/IDL3_to_XMI/be_init.cpp b/modules/CIAO/tools/IDL3_to_XMI/be_init.cpp new file mode 100644 index 00000000000..7863fcae9d8 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_XMI/be_init.cpp @@ -0,0 +1,31 @@ +// $Id$ + +#include "global_extern.h" +#include "be_extern.h" +#include "../../ciao/Version.h" + +CIAO_IDL3_TO_XMI_Export void +BE_version (void) +{ + ACE_DEBUG ((LM_DEBUG, + "%s %s\n", + ACE_TEXT ("TAO_ID3_TO_IDL2_BE, version"), + ACE_TEXT (CIAO_VERSION))); +} + +CIAO_IDL3_TO_XMI_Export int +BE_init (int & /* argc */, ACE_TCHAR * /* argv */ []) +{ + // Initialize BE global data object. + ACE_NEW_RETURN (be_global, + BE_GlobalData, + -1); + + idl_global->pass_orb_idl (true); + return 0; +} + +CIAO_IDL3_TO_XMI_Export void +BE_post_init (char * /* files */ [], long /* nfiles */) +{ +} diff --git a/modules/CIAO/tools/IDL3_to_XMI/be_produce.cpp b/modules/CIAO/tools/IDL3_to_XMI/be_produce.cpp new file mode 100644 index 00000000000..7a66096bd32 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_XMI/be_produce.cpp @@ -0,0 +1,139 @@ +// $Id$ + +/* + +COPYRIGHT + +Copyright 1992, 1993, 1994 Sun Microsystems, Inc. Printed in the United +States of America. All Rights Reserved. + +This product is protected by copyright and distributed under the following +license restricting its use. + +The Interface Definition Language Compiler Front End (CFE) is made +available for your use provided that you include this license and copyright +notice on all media and documentation and the software program in which +this product is incorporated in whole or part. You may copy and extend +functionality (but may not remove functionality) of the Interface +Definition Language CFE without charge, but you are not authorized to +license or distribute it to anyone else except as part of a product or +program developed by you or with the express written consent of Sun +Microsystems, Inc. ("Sun"). + +The names of Sun Microsystems, Inc. and any of its subsidiaries or +affiliates may not be used in advertising or publicity pertaining to +distribution of Interface Definition Language CFE as permitted herein. + +This license is effective until terminated by Sun for failure to comply +with this license. Upon termination, you shall destroy or return all code +and documentation for the Interface Definition Language CFE. + +INTERFACE DEFINITION LANGUAGE CFE IS PROVIDED AS IS WITH NO WARRANTIES OF +ANY KIND INCLUDING THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS +FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR ARISING FROM A COURSE OF +DEALING, USAGE OR TRADE PRACTICE. + +INTERFACE DEFINITION LANGUAGE CFE IS PROVIDED WITH NO SUPPORT AND WITHOUT +ANY OBLIGATION ON THE PART OF Sun OR ANY OF ITS SUBSIDIARIES OR AFFILIATES +TO ASSIST IN ITS USE, CORRECTION, MODIFICATION OR ENHANCEMENT. + +SUN OR ANY OF ITS SUBSIDIARIES OR AFFILIATES SHALL HAVE NO LIABILITY WITH +RESPECT TO THE INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY +INTERFACE DEFINITION LANGUAGE CFE OR ANY PART THEREOF. + +IN NO EVENT WILL SUN OR ANY OF ITS SUBSIDIARIES OR AFFILIATES BE LIABLE FOR +ANY LOST REVENUE OR PROFITS OR OTHER SPECIAL, INDIRECT AND CONSEQUENTIAL +DAMAGES, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +Use, duplication, or disclosure by the government is subject to +restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in +Technical Data and Computer Software clause at DFARS 252.227-7013 and FAR +52.227-19. + +Sun, Sun Microsystems and the Sun logo are trademarks or registered +trademarks of Sun Microsystems, Inc. + +SunSoft, Inc. +2550 Garcia Avenue +Mountain View, California 94043 + +NOTE: + +SunOS, SunSoft, Sun, Solaris, Sun Microsystems or the Sun logo are +trademarks or registered trademarks of Sun Microsystems, Inc. + + */ + +#include "CIAO_IDL3_TO_XMI_Export.h" +#include "global_extern.h" +#include "be_extern.h" +#include "fe_extern.h" +#include "ast_root.h" +#include "IDL3_to_XMI_visitor.h" +#include "IR_Simulator_visitor.h" +#include <xercesc/util/PlatformUtils.hpp> + +// Clean up before exit, whether successful or not. +CIAO_IDL3_TO_XMI_Export void +BE_cleanup (void) +{ + idl_global->destroy (); +} + +// Abort this run of the BE. +CIAO_IDL3_TO_XMI_Export void +BE_abort (void) +{ + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Fatal Error - Aborting\n"))); + + // BE_cleanup will be called after the exception is caught. + BE_cleanup (); +} + +// Do the work of this BE. This is the starting point for code generation. +CIAO_IDL3_TO_XMI_Export void +BE_produce (void) +{ + // Get the root node. + AST_Decl *d = idl_global->root (); + AST_Root *ast_root = AST_Root::narrow_from_decl (d); + + if (ast_root == 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%N:%l) BE_produce - ") + ACE_TEXT ("No Root\n"))); + BE_abort (); + } + + xercesc::XMLPlatformUtils::Initialize (); + + if (be_global->ir_filter ()) + { + CIAO::XMI::ir_simulator_visitor visitor; + + if (visitor.visit_root (ast_root) == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("error: an error occured in the ir_simulator visitor."))); + xercesc::XMLPlatformUtils::Terminate (); + BE_cleanup (); + return; + } + } + + CIAO::XMI::idl3_to_xmi_visitor visitor (be_global->ir_filter ()); + + if (visitor.visit_root (ast_root) == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%N:%l) BE_produce -") + ACE_TEXT (" failed to accept visitor\n"))); + } + + xercesc::XMLPlatformUtils::Terminate (); + + // Clean up. + BE_cleanup (); +} diff --git a/modules/CIAO/tools/IDL3_to_XMI/be_sunsoft.cpp b/modules/CIAO/tools/IDL3_to_XMI/be_sunsoft.cpp new file mode 100644 index 00000000000..30126f74451 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_XMI/be_sunsoft.cpp @@ -0,0 +1,193 @@ +// $Id$ + +#include "be_sunsoft.h" +#include "ast_expression.h" +#include "utl_identifier.h" +#include "utl_idlist.h" +#include "utl_string.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_ctype.h" + +ACE_RCSID (be, + be_sunsoft, + "$Id$") + +TAO_SunSoft_OutStream::TAO_SunSoft_OutStream (void) + : TAO_OutStream () +{ +} + +TAO_SunSoft_OutStream::~TAO_SunSoft_OutStream (void) +{ +} + +TAO_OutStream & +TAO_SunSoft_OutStream::print (Identifier *id) +{ + ACE_OS::fprintf (this->fp_, + id->get_string ()); + + return *this; +} + +TAO_OutStream & +TAO_SunSoft_OutStream::print (UTL_IdList *idl) +{ + long first = true; + long second = false; + Identifier *id = 0; + + for (UTL_IdListActiveIterator i (idl); !i.is_done (); i.next ()) + { + if (!first) + { + *this << "::"; + } + else if (second) + { + first = second = false; + } + + // Print the identifier. + id = i.item (); + *this << id; + + if (first) + { + if (ACE_OS::strcmp (id->get_string (), "") != 0) + { + // Does not start with a "". + first = false; + } + else + { + second = true; + } + } + } + + return *this; +} + +TAO_OutStream& +TAO_SunSoft_OutStream::print (AST_Expression *expr) +{ + AST_Expression::AST_ExprValue *ev = expr->ev (); + + if (ev) + { + switch (ev->et) + { + case AST_Expression::EV_short: + this->TAO_OutStream::print (ACE_INT32_FORMAT_SPECIFIER_ASCII, ev->u.sval); + break; + case AST_Expression::EV_ushort: + this->TAO_OutStream::print (ACE_INT32_FORMAT_SPECIFIER_ASCII "%c", ev->u.usval, 'U'); + break; + case AST_Expression::EV_long: + this->TAO_OutStream::print (ACE_INT32_FORMAT_SPECIFIER_ASCII, ev->u.lval); + break; + case AST_Expression::EV_ulong: + this->TAO_OutStream::print (ACE_UINT32_FORMAT_SPECIFIER_ASCII "%c", ev->u.ulval, 'U'); + break; + // The ACE_LACKS_LONGLONG_T guards have been removed around + // the next 2 cases since the macros now used should work + // whether native 64-bit integers are defined or not. + case AST_Expression::EV_longlong: + this->TAO_OutStream::print ("ACE_INT64_LITERAL ("); + this->TAO_OutStream::print (ACE_INT64_FORMAT_SPECIFIER_ASCII, + ev->u.llval); + this->TAO_OutStream::print (")"); + break; + case AST_Expression::EV_ulonglong: + this->TAO_OutStream::print ("ACE_UINT64_LITERAL ("); + this->TAO_OutStream::print (ACE_UINT64_FORMAT_SPECIFIER_ASCII, + ev->u.ullval); + this->TAO_OutStream::print (")"); + break; + case AST_Expression::EV_float: + this->TAO_OutStream::print ("%f%c", ev->u.fval, 'F'); + break; + case AST_Expression::EV_double: + this->TAO_OutStream::print ("%24.16G", ev->u.dval); + break; + case AST_Expression::EV_longdouble: + break; + case AST_Expression::EV_char: + // isprint() sees \ and ' as printable characters + // so we have to test for them first. + if (ev->u.cval == '\\') + this->TAO_OutStream::print ("'\\\\'"); + else if (ev->u.cval == '\'') + this->TAO_OutStream::print ("'\\''"); + + // This handles hex and octal escape sequences + // that would print out either as weird characters + // or as an unsigned number too large for a char. + else if ((unsigned char) ev->u.cval > ACE_CHAR_MAX) + this->TAO_OutStream::print ("%hd", ev->u.cval); + else if (ACE_OS::ace_isprint (ev->u.cval)) + this->TAO_OutStream::print ("'%c'", ev->u.cval); + else if (ACE_OS::ace_iscntrl (ev->u.cval)) + switch (ev->u.cval) + { + case '\n': + this->TAO_OutStream::print ("'\\n'"); + break; + case '\t': + this->TAO_OutStream::print ("'\\t'"); + break; + case '\r': + this->TAO_OutStream::print ("'\\r'"); + break; + case '\v': + this->TAO_OutStream::print ("'\\v'"); + break; + case '\f': + this->TAO_OutStream::print ("'\\f'"); + break; + case '\b': + this->TAO_OutStream::print ("'\\b'"); + break; + case '\a': + this->TAO_OutStream::print ("'\\a'"); + break; + case '\?': + this->TAO_OutStream::print ("'?'"); + break; + default: + this->TAO_OutStream::print ("'\\x%x'", ev->u.cval); + } + else + this->TAO_OutStream::print ("'\\x%x'", ev->u.cval); + break; + case AST_Expression::EV_wchar: + this->TAO_OutStream::print ("L'%lc'", ev->u.wcval); + break; + case AST_Expression::EV_octet: + this->TAO_OutStream::print ("%d", ev->u.oval); + break; + case AST_Expression::EV_bool: + this->TAO_OutStream::print ("%s", ev->u.bval ? "true" : "false"); + break; + case AST_Expression::EV_string: + this->TAO_OutStream::print ("\"%s\"", ev->u.strval->get_string ()); + break; + case AST_Expression::EV_wstring: + this->TAO_OutStream::print ("L\"%s\"", ev->u.wstrval); + break; + case AST_Expression::EV_enum: + this->print (expr->n ()); + break; + default: + break; + } + } + else + { + // XXXASG: need to add code here + } + + return *this; +} diff --git a/modules/CIAO/tools/IDL3_to_XMI/be_sunsoft.h b/modules/CIAO/tools/IDL3_to_XMI/be_sunsoft.h new file mode 100644 index 00000000000..5aef8a66d4d --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_XMI/be_sunsoft.h @@ -0,0 +1,39 @@ +/* -*- c++ -*- */ +// $Id$ + +/** + * @file be_sunsoft.h + * + * Sunsoft backend output generation. + */ + +#ifndef TAO_BE_HELPER_H +#define TAO_BE_HELPER_H + +#include "be_helper.h" + +class TAO_SunSoft_OutStream : public TAO_OutStream +{ + // =TITLE + // TAO_SunSoft_OutStream + // =DESCRIPTION + // Backend specific to SunSoft AST nodes +public: + TAO_SunSoft_OutStream (void); + // constructor + + ~TAO_SunSoft_OutStream (void); + // destuctor + + virtual TAO_OutStream &print (Identifier *id); + // output the SunSoft IDL Identifier Node + + virtual TAO_OutStream &print (UTL_IdList *idl); + // output the SunSoft IDL UTL_IdList Node which is usually used to maintain a + // scoped name + + virtual TAO_OutStream &print (AST_Expression *expr); + // output the contents of the AST_Expression node +}; + +#endif // if !defined diff --git a/modules/CIAO/tools/IDL3_to_XMI/identifier_helper.cpp b/modules/CIAO/tools/IDL3_to_XMI/identifier_helper.cpp new file mode 100644 index 00000000000..dc540554f18 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_XMI/identifier_helper.cpp @@ -0,0 +1,115 @@ +/* -*- c++ -*- */ +// $Id$ + +#include "identifier_helper.h" +#include "utl_identifier.h" +#include "utl_string.h" +#include "global_extern.h" + +Identifier * +IdentifierHelper::original_local_name (Identifier * local_name) +{ + Identifier * id = 0; + + // Remove _cxx_ if it is present. + if (ACE_OS::strstr (local_name->get_string (), + "_cxx_") + == local_name->get_string ()) + { + // CString class is good to do this stuff. + ACE_CString name_str (local_name->get_string ()); + + // Remove _cxx_. + name_str = name_str.substr (ACE_OS::strlen ("_cxx_")); + + // Assign to the Identifier variable. + ACE_NEW_RETURN (id, + Identifier (name_str.c_str ()), + 0); + } + else + { + id = local_name->copy (); + } + + return id; +} + + +ACE_CString +IdentifierHelper::orig_sn (UTL_IdList * sn, bool appended_to) +{ + ACE_CString retval; + bool first = true; + bool second = false; + Identifier *id = 0; + + for (UTL_IdListActiveIterator i (sn); !i.is_done ();) + { + if (!first) + { + retval += "::"; + } + else if (second) + { + first = second = false; + } + + id = IdentifierHelper::original_local_name (i.item ()); + i.next (); + + // Append the identifier. + retval += + appended_to && i.is_done () + ? id->get_string () + : IdentifierHelper::try_escape (id).c_str (); + + if (first) + { + if (ACE_OS::strcmp (id->get_string (), "") != 0) + { + // Does not start with a "". + first = false; + } + else + { + second = true; + } + } + + id->destroy (); + delete id; + id = 0; + } + + return retval; +} + +bool +IdentifierHelper::is_idl_keyword (Identifier * local_name) +{ + UTL_String utl_tmp (local_name->get_string ()); + ACE_CString ext_id (utl_tmp.get_canonical_rep (), + 0, + false); + + int status = idl_global->idl_keywords ().find (ext_id); + utl_tmp.destroy (); + + return status == 0; +} + +ACE_CString +IdentifierHelper::try_escape (Identifier * local_name) +{ + ACE_CString s_local_name (local_name->get_string ()); + + if (IdentifierHelper::is_idl_keyword (local_name)) + { + return "_" + s_local_name; + } + else + { + return s_local_name; + } +} diff --git a/modules/CIAO/tools/IDL3_to_XMI/identifier_helper.h b/modules/CIAO/tools/IDL3_to_XMI/identifier_helper.h new file mode 100644 index 00000000000..a414b8fadd5 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_XMI/identifier_helper.h @@ -0,0 +1,64 @@ +// $Id$ + +/* -*- c++ -*- */ +// ============================================================================ +// +// = LIBRARY +// TAO_IDL3_TO_IDL2_BE_DLL +// +// = FILENAME +// identifier_helper.h +// +// = DESCRIPTION +// Utilities associated with UTL_Identifier. +// +// = AUTHOR +// Jeff Parsons <j.parsons@vanderbilt.edu> +// +// ============================================================================ + +#ifndef IDENTIFIER_HELPER_H +#define IDENTIFIER_HELPER_H + +#include "utl_scoped_name.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/SString.h" + +class Identifier; + +struct IdentifierHelper +{ + // + // = TITLE + // IdentifierHelper. + // + // = DESCRIPTION + // 1) keeps escape (leading underscore character in generated + // identifier in IDL + // 2) removes the '_' escape character when the identifier is + // part of another identifier such as in provides_XXX + // 3) removes any '_cxx_' in generated IDL + + static Identifier * + original_local_name (Identifier * local_name); + + // Removes '_cxx_ from segments of a scoped name, and optionally + // de-escape the last segment, if it's to be appended to. + static ACE_CString + orig_sn (UTL_ScopedName * scoped_name, bool appended_to = false); + + // Detects case-insensitive match with IDL keyword. + static bool + is_idl_keyword (Identifier * local_name); + + // Preserves the 'escape' (leading underscore) in a + // generated identifier if necessary. + static ACE_CString + try_escape (Identifier * local_name); +}; + +#endif /* IDENTIFIER_HELPER_H */ |