]> SALOME platform Git repositories - tools/yacsgen.git/commitdiff
Salome HOME
Parallel component generation with yacsgen/hxx2salome
authorcrouzet <crouzet>
Tue, 18 Oct 2011 12:06:16 +0000 (12:06 +0000)
committercrouzet <crouzet>
Tue, 18 Oct 2011 12:06:16 +0000 (12:06 +0000)
15 files changed:
Examples/hxx1/component.py
Examples/hxx1/cpp_component.tgz
Examples/hxx1/test_compohxx.py
module_generator/__init__.py
module_generator/gener.py
module_generator/gui_tmpl.py
module_generator/hxx_awk.py
module_generator/hxx_para_tmpl.py [new file with mode: 0644]
module_generator/hxx_tmpl.py
module_generator/hxx_tmpl_gui.py [new file with mode: 0644]
module_generator/hxxcompo.py
module_generator/hxxparacompo.py [new file with mode: 0644]
module_generator/salomemodules.py
module_generator/yacstypes.py
setup.py

index 9210fd02771e51dccb89b75383b38df06e810b64..9677d73b06d636d7744c459d7cae6a53ea9ba54f 100644 (file)
 import os
 from module_generator import Generator,Module,Service
 from module_generator import CPPComponent,PYComponent,HXX2SALOMEComponent
+class Invalid(Exception):
+    pass
 
 kernel_root_dir=os.environ["KERNEL_ROOT_DIR"]
 gui_root_dir=os.environ["GUI_ROOT_DIR"]
 yacs_root_dir=os.environ["YACS_ROOT_DIR"]
 med_root_dir=os.environ["MED_ROOT_DIR"]
 geom_root_dir=os.environ["GEOM_ROOT_DIR"]
+prereq_file=os.path.join(kernel_root_dir,"..","env_products.sh")
+if not os.path.exists(prereq_file):
+    prereq_file=os.path.join(kernel_root_dir,"..","..","env_products.sh")
+if not os.path.exists(prereq_file):
+    raise Invalid("prerequisite file env_products.sh not found. please replace it manually in component.py")
 
 #import context from ..
-execfile("../context.py")
+context={'update':1,
+         "makeflags":"",
+         "prerequisites":prereq_file,
+         "kernel":kernel_root_dir,
+         "gui":gui_root_dir,
+         "geom":geom_root_dir,
+         "med":med_root_dir,
+         "yacs":yacs_root_dir,
+        }
 
 cwd=os.getcwd()
 cpppath=os.path.join(cwd,"COMPONENTCPP_INSTALL")
index 87432a041a678c7cc9db603c48871399290508ea..2298007af5f985649a04b0c7211d85b74d596ee4 100644 (file)
Binary files a/Examples/hxx1/cpp_component.tgz and b/Examples/hxx1/cpp_component.tgz differ
index c5f932fff2603daeb07c0ed3a947e3e740e68e1e..5403e6e2baaace19b100f8c7c465b542f57c0087 100644 (file)
@@ -46,15 +46,15 @@ assert  banner == "Hello" , 'erreur dans la fonction getBanner() : mauvaise vale
 print "Creation et tests des supports :"
 supportName=myTestMed.getSupportName(myTestMed.getSupport())
 print "Support name : ",supportName
-assert supportName == "XsupportX"
+assert supportName == "SupportOnAll_MED_MAILLE"
 #
 from libMEDClient import FIELDDOUBLEClient
 f_loc=FIELDDOUBLEClient(myTestMed.getVolume(myTestMed.getSupport()))
 assert f_loc.getNumberOfValues() == 16 , 'created field has incorrect size'
 from math import fabs
 assert fabs(f_loc.norm2()-6.39444)<1.0e-5  , 'created field has incorrect norm 2'
-#
-myTestMed.affiche_fieldT(myTestMed.getVolume(myTestMed.getSupport()))
+##
+# CNC bug Medclient  myTestMed.affiche_fieldT(myTestMed.getVolume(myTestMed.getSupport()))
 myTestMed.printSupportEntity(myTestMed.getSupport())
 myMedCalc.printSupport(myTestMed.getSupport())
 myMedCalc.printSupport(myTestMed.getPartialSupport())
@@ -70,14 +70,14 @@ assert  banner == "Hello" , 'erreur dans la fonction getBanner() : mauvaise vale
 theMesh= myTestMed.getMesh()
 theField = myTestMed.getField()
 (theField1,theField2) = myTestMed.create2DoubleField()
-myTestMed.affiche_fieldT(theField1)
+#CNC  bug Medclient  myTestMed.affiche_fieldT(theField1)
 mynorm=myTestMed.getNormMax(theField)
 from math import fabs
 assert fabs(mynorm-3.0)<1.0e-10  , 'created field has incorrect norm 1'
 print "Norm of the Field : " , mynorm
 
 field1 = myTestMed.getConstFieldDouble( 3.0 , "field1" )
-myTestMed.affiche_fieldT(field1)
+# CNC bug Medclient myTestMed.affiche_fieldT(field1)
 print "Creation tableau :"
 size=12
 myTab = myTestMed.createDoubleTab(size)
index f551078b6d27b5c0b6bb47742fb5a7b340114f4b..99824a20a1038979c4f3877f3840651fb37f9283 100644 (file)
@@ -29,5 +29,6 @@ from pacocompo import PACOComponent
 from pycompo import PYComponent
 from astcompo import ASTERComponent
 from hxxcompo import HXX2SALOMEComponent
+from hxxparacompo import HXX2SALOMEParaComponent
 from yacstypes import add_type
 from salomemodules import add_module
index 9d425f29193a4fa844791b0710bb96f6c58f10fd..d1c224179f1aaefc9cd2704db7ef959954b6eef0 100644 (file)
@@ -647,6 +647,8 @@ echo "  Qt ..................... : $qt_ok"
             sources.append(os.path.basename(src)[:-2]+"_moc.cxx")
           elif src[-3:]==".ui":
             ui_files.append("ui_"+os.path.basename(src)[:-3]+".h")
+          elif src[-3:]==".ts":
+            other.append(os.path.basename(src)[:-3]+".qm")
           else:
             other.append(os.path.basename(src))
 
@@ -727,6 +729,7 @@ echo "  Qt ..................... : $qt_ok"
     """generate module IDL file source (CORBA interface)"""
     from pacocompo import PACOComponent
     interfaces = []
+    idldefs=""
     for compo in self.module.components:
       if isinstance(compo, PACOComponent):
         services = []
@@ -767,11 +770,18 @@ echo "  Qt ..................... : $qt_ok"
           services.append(service)
 
         from hxxcompo import HXX2SALOMEComponent
-        if isinstance(compo,HXX2SALOMEComponent):
+        from hxxparacompo import HXX2SALOMEParaComponent
+        if isinstance(compo,HXX2SALOMEComponent) or isinstance(compo,HXX2SALOMEParaComponent):
           from hxx_tmpl import interfaceidlhxx
           Inherited=""
-          if compo.use_medmem==True:
-              Inherited=", SALOME_MED::MED_Gen_Driver"
+          if isinstance(compo,HXX2SALOMEParaComponent):
+              Inherited="SALOME_MED::ParaMEDMEMComponent"
+              idldefs="""#include "ParaMEDMEMComponent.idl"\n"""
+          else:
+              if compo.use_medmem==True:
+                  Inherited="Engines::EngineComponent,SALOME::MultiCommClass,SALOME_MED::MED_Gen_Driver"
+              else:
+                  Inherited="Engines::EngineComponent"
           interfaces.append(interfaceidlhxx.substitute(component=compo.name,inherited=Inherited, services="\n".join(services)))
         else:
           inheritedinterface=""
@@ -780,7 +790,6 @@ echo "  Qt ..................... : $qt_ok"
           interfaces.append(interface.substitute(component=compo.name, services="\n".join(services),inheritedinterface=inheritedinterface))
 
     #build idl includes for SALOME modules
-    idldefs=""
     for mod in self.used_modules:
       idldefs = idldefs + salome_modules[mod]["idldefs"]
 
index 646ae3f930c072d54bc8490a50e16be6577203fa..cd3c552a5316f5b8d80adebb23f7baf3ac1ad73c 100644 (file)
@@ -67,6 +67,9 @@ salomeres_DATA =SalomeApp.xml ${other_sources}
 ui_%.h: %.ui
        $$(UIC) -o $$@ $$<
 
+# translation (*.qm) files generation (lrelease)
+%.qm: %.ts
+       $$(LRELEASE) $$< -qm $$@
 """
 cppguimakefile=Template(cppguimakefile)
 
index d79a89e4634b6ae586b2a405d9895687ffd6954c..54a8865db1ce492715237dc89fd504d3e42e6232 100644 (file)
@@ -52,6 +52,8 @@ cpp2idl_mapping["MEDMEM::FIELD<int>*&"]="out SALOME_MED::FIELDINT"
 cpp2idl_mapping["const std::vector<int>&"]="in %(module)s::intvec"
 cpp2idl_mapping["std::vector<int>*&"]="out %(module)s::intvec"
 cpp2idl_mapping["const ParaMEDMEM::MEDCouplingFieldDouble*"]="in SALOME_MED::MEDCouplingFieldDoubleCorbaInterface"
+cpp2idl_mapping["const ParaMEDMEM::MEDCouplingFieldDouble&"]="in SALOME_MED::MEDCouplingFieldDoubleCorbaInterface"
+cpp2idl_mapping["ParaMEDMEM::MEDCouplingFieldDouble*&"]="out SALOME_MED::MEDCouplingFieldDoubleCorbaInterface"
 
 # ['stringvec', 'string', 'double', 'long', 'dblevec', 'file', 'intvec', 'dataref', 'GEOM_Object', 'SMESH_Mesh', 'SMESH_Hypothesis', 'SALOME_MED/MED', 'SALOME_MED/MESH', 'SALOME_MED/SUPPORT', 'SALOME_MED/FIELD', 'SALOME_MED/FIELDDOUBLE', 'SALOME_MED/FIELDINT']
 cpp2yacs_mapping={}
@@ -367,6 +369,8 @@ BEGIN {
   idl_arg_type["const std::vector<int>&"]="in SALOME::vectorOfLong"
   idl_arg_type["std::vector<int>*&"]="out SALOME::vectorOfLong"
   idl_arg_type["const ParaMEDMEM::MEDCouplingFieldDouble*"]="in SALOME_MED::MEDCouplingFieldDoubleCorbaInterface"
+  idl_arg_type["const ParaMEDMEM::MEDCouplingFieldDouble&"]="in SALOME_MED::MEDCouplingFieldDoubleCorbaInterface"
+  idl_arg_type["ParaMEDMEM::MEDCouplingFieldDouble*&"]="out SALOME_MED::MEDCouplingFieldDoubleCorbaInterface"
 #
 #
 # mapping for returned types
diff --git a/module_generator/hxx_para_tmpl.py b/module_generator/hxx_para_tmpl.py
new file mode 100644 (file)
index 0000000..7df0ed7
--- /dev/null
@@ -0,0 +1,206 @@
+#  Copyright (C) 2009-2011  EDF R&D
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+try:
+  from string import Template
+except:
+  from compat import Template,set
+
+cxxCompo="""
+// this cxx file was generated by yacsgen
+#include "${component}_i.hxx"
+#include "${cxx_include_file}"
+using namespace std;
+#include <string>
+#include <vector>
+#include <pthread.h>
+#include "SenderFactory.hxx"
+#include "MultiCommException.hxx"
+#include "ReceiverFactory.hxx"
+#include "SALOME_Matrix_i.hxx"
+#include "MatrixClient.hxx"
+#include "Utils_CorbaException.hxx"
+#include "MEDCouplingFieldDouble.hxx"
+
+typedef struct
+{
+  bool exception;
+  string msg;
+} except_st;
+
+
+//DEFS
+${servicesdef}
+//ENDDEF
+
+//=============================================================================
+/*!
+ *  standard constructor
+ */
+//=============================================================================
+${component}_i::${component}_i(CORBA::ORB_ptr orb,
+       PortableServer::POA_ptr poa,
+       PortableServer::ObjectId * contId, 
+       const char *instanceName, 
+        const char *interfaceName,
+       bool regist) :
+  ParaMEDMEMComponent_i(orb,poa,contId,instanceName,interfaceName,regist),${inheritedconstructor}cppCompo_(new ${component})
+{
+  MESSAGE("activate object");
+  _thisObj = this ;
+  _id = _poa->activate_object(_thisObj);
+}
+
+${component}_i::~${component}_i()
+{
+}
+
+${servicesimpl}
+
+${thread_impl}
+
+extern "C"
+{
+  PortableServer::ObjectId * ${component}Engine_factory(
+                              CORBA::ORB_ptr orb,
+                              PortableServer::POA_ptr poa, 
+                              PortableServer::ObjectId * contId,
+                              const char *instanceName, 
+                              const char *interfaceName)
+  {
+
+   bool regist;
+   int numproc;
+
+   MPI_Comm_rank( MPI_COMM_WORLD, &numproc );
+   if( numproc == 0 )
+      regist = true;
+   else
+      regist = false;
+   ${component}_i * my${component} = new ${component}_i(orb, poa, contId, instanceName, interfaceName, regist);
+   return my${component}->getId();
+  }
+}
+"""
+cxxCompo=Template(cxxCompo)
+
+hxxCompo="""
+//this file was generated by yacsgen
+#ifndef __${component}_hxx2salome__
+#define __${component}_hxx2salome__
+
+#include <SALOMEconfig.h>
+#include "Utils_CorbaException.hxx"
+#include CORBA_SERVER_HEADER(${module})
+#include "Utils_CorbaException.hxx"
+#include <memory>  // for std::auto_ptr
+
+${compodefs}
+
+// thread functions declaration
+${thread_func_decl}
+
+// thread structures declaration
+${thread_str_decl}
+
+class ${component};  // forward declaration
+
+class ${component}_i: ${inheritedclass}
+  public POA_${module}_ORB::${component}_Gen,
+  public ParaMEDMEM::ParaMEDMEMComponent_i
+{
+
+public:
+    ${component}_i(CORBA::ORB_ptr orb,
+           PortableServer::POA_ptr poa,
+           PortableServer::ObjectId * contId, 
+           const char *instanceName, 
+           const char *interfaceName,
+           bool regist);
+    virtual ~${component}_i();
+
+${servicesdef}
+
+// (re)defined methods of Driver
+
+private:
+    std::auto_ptr<${component}> cppCompo_;
+
+};
+
+
+extern "C"
+    PortableServer::ObjectId * ${component}Engine_factory(
+           CORBA::ORB_ptr orb,
+           PortableServer::POA_ptr poa,
+           PortableServer::ObjectId * contId,
+           const char *instanceName,
+           const char *interfaceName);
+
+
+#endif
+"""
+hxxCompo=Template(hxxCompo)
+
+cxxService="""
+${ret} ${component}_i::${service}(${parameters}) throw (SALOME::SALOME_Exception)
+{
+    beginService("${component}_i::${service}");
+    BEGIN_OF("${component}_i::${service}");
+    except_st *est;
+    void *ret_th;
+    pthread_t *th;
+    try
+    {
+${body}
+       endService("${component}_i::${service}");
+       END_OF("${component}_i::${service}");
+
+    }
+    catch (std::exception& ex)
+    {
+        THROW_SALOME_CORBA_EXCEPTION( ex.what(), SALOME::INTERNAL_ERROR );
+    }
+}
+"""
+cxxService=Template(cxxService)
+
+
+compoMakefile="""
+
+dist_lib${component}Engine_la_SOURCES = \
+       ${component}_i.cxx
+
+lib${component}Engine_la_CXXFLAGS = -I$$(top_builddir)/idl  $$(SALOME_INCLUDES) $$(MPI_INCLUDES) ${includes}
+lib${component}Engine_la_LIBADD   = ${libs} -L$$(top_builddir)/idl -lSalomeIDL${module} $${SALOME_LIBS} -lSalomeMPIContainer -lparamedmemcompo $$(FLIBS)
+
+
+"""
+
+#, SALOME_MED::MED_Gen_Driver, SALOME::MultiCommClass
+interfaceidlhxx="""
+  interface ${component}_Gen: ${inherited}
+  {
+${services}
+  };
+"""
+interfaceidlhxx=Template(interfaceidlhxx)
+
+
+compoMakefile=Template(compoMakefile)
index 172af897c26f6559663514e859e9ad2d727535c9..77c5900dc3c447deaeb69363c5982d198b68bf05 100644 (file)
@@ -110,8 +110,7 @@ class ${component};  // forward declaration
 
 class ${component}_i: ${inheritedclass}
   public POA_${module}_ORB::${component}_Gen,
-  public Engines_Component_i,
-  public SALOMEMultiComm
+  public Engines_Component_i
 {
 
 public:
@@ -178,7 +177,7 @@ lib${component}Engine_la_LIBADD   = ${libs} -L$$(top_builddir)/idl -lSalomeIDL${
 
 #, SALOME_MED::MED_Gen_Driver, SALOME::MultiCommClass
 interfaceidlhxx="""
-  interface ${component}_Gen:Engines::EngineComponent,SALOME::MultiCommClass ${inherited}
+  interface ${component}_Gen: ${inherited}
   {
 ${services}
   };
diff --git a/module_generator/hxx_tmpl_gui.py b/module_generator/hxx_tmpl_gui.py
new file mode 100644 (file)
index 0000000..62d594e
--- /dev/null
@@ -0,0 +1,602 @@
+#  Copyright (C) 2009-2011  EDF R&D
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+try:
+  from string import Template
+except:
+  from compat import Template,set
+
+hxxgui_cxx="""
+#include "${component_name}GUI.h"
+
+#include <SUIT_MessageBox.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Desktop.h>
+#include <SUIT_Session.h>
+#include <SalomeApp_Application.h>
+#include <LightApp_Preferences.h>
+
+#include <SALOME_LifeCycleCORBA.hxx>
+
+#define COMPONENT_NAME "${component_name}"
+
+using namespace std;
+
+// Constructor
+${component_name}GUI::${component_name}GUI() :
+  SalomeApp_Module( COMPONENT_NAME ), // Module name
+  LightApp_Module( COMPONENT_NAME )  
+{
+  // Initializations
+  default_bool = false;
+  default_int = 0;
+  default_spinInt = 0;
+  default_spinDbl = 0.;
+  default_selection = QString("");
+  
+  // List for the selector
+  selector_strings.clear();
+  selector_strings.append( tr( "PREF_LIST_TEXT_0" ) );
+  selector_strings.append( tr( "PREF_LIST_TEXT_1" ) );
+  selector_strings.append( tr( "PREF_LIST_TEXT_2" ) );
+}
+
+// Gets a reference to the module's engine
+${component_name}_ORB::${component_name}_Gen_ptr ${component_name}GUI::Init${component_name}Gen( SalomeApp_Application* app )
+{
+  Engines::EngineComponent_var comp = app->lcc()->FindOrLoad_Component( "FactoryServer",COMPONENT_NAME );
+  ${component_name}_ORB::${component_name}_Gen_ptr clr = ${component_name}_ORB::${component_name}_Gen::_narrow(comp);
+  ASSERT(!CORBA::is_nil(clr));
+  return clr;
+}
+
+// Module's initialization
+void ${component_name}GUI::initialize( CAM_Application* app )
+{
+  // Get handle to Application, Desktop and Resource Manager
+  SalomeApp_Module::initialize( app );
+
+  Init${component_name}Gen( dynamic_cast<SalomeApp_Application*>( app ) );
+
+  QWidget* aParent = app->desktop();
+  
+  SUIT_ResourceMgr* aResourceMgr = application()->resourceMgr();
+  
+  // GUI items
+  // --> Create actions: 190 is linked to item in "File" menu 
+  //     and 901 is linked to both specific menu and toolbar
+  createAction( 190, tr( "TLT_MY_NEW_ITEM" ), QIcon(), tr( "MEN_MY_NEW_ITEM" ), tr( "STS_MY_NEW_ITEM" ), 0, aParent, false,
+               this, SLOT( OnMyNewItem() ) );
+
+  QPixmap aPixmap = aResourceMgr->loadPixmap( COMPONENT_NAME,tr( "ICON_${component_name}" ) );
+  createAction( 901, tr( "TLT_${component_name}_ACTION" ), QIcon( aPixmap ), tr( "MEN_${component_name}_ACTION" ), tr( "STS_${component_name}_ACTION" ), 0, aParent, false,
+               this, SLOT( OnCallAction() ) );
+
+  // --> Create item in "File" menu
+  int aMenuId;
+  aMenuId = createMenu( tr( "MEN_FILE" ), -1, -1 );
+  createMenu( separator(), aMenuId, -1, 10 );
+  aMenuId = createMenu( tr( "MEN_FILE_${component_name}" ), aMenuId, -1, 10 );
+  createMenu( 190, aMenuId );
+
+  // --> Create specific menu
+  aMenuId = createMenu( tr( "MEN_${component_name}" ), -1, -1, 30 );
+  createMenu( 901, aMenuId, 10 );
+
+  // --> Create toolbar item
+  int aToolId = createTool ( tr( "TOOL_${component_name}" ) );
+  createTool( 901, aToolId );
+}
+
+// Module's engine IOR
+QString ${component_name}GUI::engineIOR() const
+{
+  CORBA::String_var anIOR = getApp()->orb()->object_to_string( Init${component_name}Gen( getApp() ) );
+  return QString( anIOR.in() );
+}
+
+// Module's activation
+bool ${component_name}GUI::activateModule( SUIT_Study* theStudy )
+{
+  bool bOk = SalomeApp_Module::activateModule( theStudy );
+
+  setMenuShown( true );
+  setToolShown( true );
+
+  return bOk;
+}
+
+// Module's deactivation
+bool ${component_name}GUI::deactivateModule( SUIT_Study* theStudy )
+{
+  setMenuShown( false );
+  setToolShown( false );
+
+  return SalomeApp_Module::deactivateModule( theStudy );
+}
+
+// Default windows
+void ${component_name}GUI::windows( QMap<int, int>& theMap ) const
+{
+  theMap.clear();
+  theMap.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
+  theMap.insert( SalomeApp_Application::WT_PyConsole,     Qt::BottomDockWidgetArea );
+}
+
+// Action slot: Launched with action 190
+void ${component_name}GUI::OnMyNewItem()
+{
+  SUIT_MessageBox::warning( getApp()->desktop(),tr( "INF_${component_name}_TITLE" ), tr( "INF_${component_name}_TEXT" ), tr( "BUT_OK" ) );
+}
+
+// Action slot: Launched with action 901
+void ${component_name}GUI::OnCallAction()
+{
+  // Create a ${component_name} component
+  ${component_name}_ORB::${component_name}_Gen_ptr ${component_name}gen = ${component_name}GUI::Init${component_name}Gen( getApp() );
+  
+  // Do the job...
+  //
+  // ${component_name}gen->method( arg1, arg2, ... );
+  
+  // Open a dialog showing Preferences values (just to display something)
+  
+  // ****** Direct access to preferences: implementation at 12/12/05 ******
+  // Comment out this section when "preferencesChanged" called back
+  SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();
+  
+  default_bool = mgr->booleanValue(COMPONENT_NAME, "default_bool", false);
+
+  default_int = mgr->integerValue(COMPONENT_NAME, "default_integer", 3);
+
+  default_spinInt = mgr->integerValue(COMPONENT_NAME, "default_spinint", 4);
+
+  default_spinDbl = mgr->doubleValue(COMPONENT_NAME, "default_spindbl", 4.5);
+
+  int selectorIndex = mgr->integerValue(COMPONENT_NAME, "default_selector");
+  default_selection = (0<=selectorIndex && selectorIndex<=selector_strings.count() ? selector_strings[selectorIndex]: QString("None"));
+  // ****** End of section to be commented out ******
+  
+  QString SUC = ( default_bool ? QString( tr ("INF_${component_name}_CHECK") ) : QString( tr("INF_${component_name}_UNCHECK") ) ) ;
+    
+  QString textResult = QString( tr( "RES_${component_name}_TEXT" ) ).arg(SUC).arg(default_int).arg(default_spinInt).arg(default_spinDbl).arg(default_selection);
+  SUIT_MessageBox::information( getApp()->desktop(), tr( "RES_${component_name}_TITLE" ), textResult, tr( "BUT_OK" ) );
+}
+
+void ${component_name}GUI::createPreferences()
+{
+  // A sample preference dialog
+  
+  // One only tab
+  int genTab = addPreference( tr( "PREF_TAB_GENERAL" ) );
+
+  // One only group
+  int defaultsGroup = addPreference( tr( "PREF_GROUP_DEFAULTS" ), genTab );
+  
+  // A checkbox
+  addPreference( tr( "PREF_DEFAULT_BOOL" ), defaultsGroup, LightApp_Preferences::Bool, COMPONENT_NAME, "default_bool" );
+  
+  // An entry for integer
+  addPreference( tr( "PREF_DEFAULT_INTEGER" ), defaultsGroup, LightApp_Preferences::Integer, COMPONENT_NAME, "default_integer" );
+
+  // An integer changed by spinbox
+  int spinInt = addPreference( tr( "PREF_DEFAULT_SPININT" ), defaultsGroup, LightApp_Preferences::IntSpin, COMPONENT_NAME, "default_spinint" );
+  setPreferenceProperty( spinInt, "min", 0 );
+  setPreferenceProperty( spinInt, "max", 20 );
+  setPreferenceProperty( spinInt, "step", 2 );
+
+  // A Double changed by spinbox
+  int spinDbl = addPreference( tr( "PREF_DEFAULT_SPINDBL" ), defaultsGroup, LightApp_Preferences::DblSpin, COMPONENT_NAME, "default_spindbl" );
+  setPreferenceProperty( spinDbl, "min", 1 );
+  setPreferenceProperty( spinDbl, "max", 10 );
+  setPreferenceProperty( spinDbl, "step", 0.1 );
+
+  // A choice in a list
+  int options = addPreference( tr( "PREF_DEFAULT_SELECTOR" ), defaultsGroup, LightApp_Preferences::Selector, COMPONENT_NAME, "default_selector" );
+  QList<QVariant> indices;
+  indices.append( 0 );
+  indices.append( 1 );
+  indices.append( 2 );
+  setPreferenceProperty( options, "strings", selector_strings );
+  setPreferenceProperty( options, "indexes", indices );
+}
+
+void ${component_name}GUI::preferencesChanged( const QString& sect, const QString& name )
+{
+// ****** This is normal way: Not yet called back at 12/12/05 ******
+  SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();
+  if( sect==COMPONENT_NAME )
+  {
+    if( name=="default_bool" )
+       default_bool = mgr->booleanValue(COMPONENT_NAME, "default_bool", false);
+    if( name=="default_integer" )
+       default_int = mgr->integerValue(COMPONENT_NAME, "default_integer", 3);
+    if( name=="default_spinint" )
+       default_spinInt = mgr->integerValue(COMPONENT_NAME, "default_spinint", 4);
+    if( name=="default_spindbl" )
+       default_spinDbl = mgr->doubleValue(COMPONENT_NAME, "default_spindbl", 4.5);
+    if( name=="default_selector" )
+    {
+       int selectorIndex = mgr->integerValue(COMPONENT_NAME, "default_selector");
+       default_selection = (0<=selectorIndex && selectorIndex<=selector_strings.count() ? selector_strings[selectorIndex]: QString("None"));
+    }
+  }
+}
+
+// Export the module
+extern "C" {
+  CAM_Module* createModule()
+  {
+    return new ${component_name}GUI();
+  }
+}
+"""
+hxxgui_cxx=Template(hxxgui_cxx)
+
+hxxgui_h="""
+#ifndef _${component_name}GUI_H_
+#define _${component_name}GUI_H_
+
+#include <SalomeApp_Module.h>
+
+#include <SALOMEconfig.h>
+#include CORBA_CLIENT_HEADER(${component_name})
+
+class SalomeApp_Application;
+class ${component_name}GUI: public SalomeApp_Module
+{
+  Q_OBJECT
+
+public:
+  ${component_name}GUI();
+
+  void    initialize( CAM_Application* );
+  QString engineIOR() const;
+  void    windows( QMap<int, int>& ) const;
+
+  static ${component_name}_ORB::${component_name}_Gen_ptr Init${component_name}Gen( SalomeApp_Application* );
+
+  virtual void                createPreferences();
+  virtual void                preferencesChanged( const QString&, const QString& );
+
+public slots:
+  bool    deactivateModule( SUIT_Study* );
+  bool    activateModule( SUIT_Study* );
+
+protected slots:
+  void            OnMyNewItem();
+  void            OnCallAction();
+
+private:
+  bool default_bool;
+  int default_int;
+  int default_spinInt;
+  double default_spinDbl;
+  QString default_selection;
+  
+  QStringList selector_strings;
+  
+};
+
+#endif
+"""
+hxxgui_h=Template(hxxgui_h)
+hxxgui_icon_ts="""
+<!DOCTYPE TS>
+<TS version="1.1" >
+    <context>
+        <name>@default</name>
+        <message>
+            <source>ICON_${component_name}</source>
+            <translation>Exec${component_name}.png</translation>
+        </message>
+    </context>
+</TS>
+"""
+hxxgui_icon_ts=Template(hxxgui_icon_ts)
+hxxgui_message_en="""
+<!DOCTYPE TS>
+<TS version="1.1" >
+    <context>
+        <name>@default</name>
+        <message>
+            <source>TLT_MY_NEW_ITEM</source>
+            <translation>A ${component_name} owned menu item</translation>
+        </message>
+        <message>
+            <source>MEN_MY_NEW_ITEM</source>
+            <translation>My menu</translation>
+        </message>
+        <message>
+            <source>STS_MY_NEW_ITEM</source>
+            <translation>Display a simple dialog</translation>
+        </message>
+        <message>
+            <source>TLT_${component_name}_ACTION</source>
+            <translation>Open ${component_name} dialog</translation>
+        </message>
+        <message>
+            <source>MEN_FILE</source>
+            <translation>File</translation>
+        </message>
+        <message>
+            <source>MEN_FILE_${component_name}</source>
+            <translation>${component_name} menu</translation>
+        </message>
+        <message>
+            <source>MEN_${component_name}</source>
+            <translation>${component_name}</translation>
+        </message>
+        <message>
+            <source>TOOL_${component_name}</source>
+            <translation>${component_name}</translation>
+        </message>
+    </context>
+    <context>
+        <name>${component_name}GUI</name>
+        <message>
+            <source>BUT_OK</source>
+            <translation>OK</translation>
+        </message>
+        <message>
+            <source>BUT_CANCEL</source>
+            <translation>Cancel</translation>
+        </message>
+        <message>
+            <source>INF_${component_name}_TITLE</source>
+            <translation>${component_name} Information</translation>
+        </message>
+        <message>
+            <source>INF_${component_name}_TEXT</source>
+            <translation>This is just a test</translation>
+        </message>
+        <message>
+            <source>INF_${component_name}_CHECK</source>
+            <translation>checked</translation>
+        </message>
+        <message>
+            <source>INF_${component_name}_UNCHECK</source>
+            <translation>Unchecked</translation>
+        </message>
+        <message>
+            <source>RES_${component_name}_TITLE</source>
+            <translation>Sample ${component_name} dialog</translation>
+        </message>
+        <message>
+            <source>RES_${component_name}_TEXT</source>
+            <translation>Preferences are: \n\tCheckbox: %1\n\tInteger: %2\n\tInteger2: %3\n\tDouble: %4\n\tText: %5</translation>
+        </message>
+        <message>
+            <source>PREF_TAB_GENERAL</source>
+            <translation>General</translation>
+        </message>
+        <message>
+            <source>PREF_GROUP_DEFAULTS</source>
+            <translation>Default Values</translation>
+        </message>
+        <message>
+            <source>PREF_DEFAULT_BOOL</source>
+            <translation>Check me</translation>
+        </message>
+        <message>
+            <source>PREF_DEFAULT_INTEGER</source>
+            <translation>Enter an integer :</translation>
+        </message>
+        <message>
+            <source>PREF_DEFAULT_SPININT</source>
+            <translation>Click arrows (integer) :</translation>
+        </message>
+        <message>
+            <source>PREF_DEFAULT_SPINDBL</source>
+            <translation>Click arrows (double)</translation>
+        </message>
+        <message>
+            <source>PREF_DEFAULT_SELECTOR</source>
+            <translation>Select an option</translation>
+        </message>
+        <message>
+            <source>PREF_LIST_TEXT_0</source>
+            <translation>first option</translation>
+        </message>
+        <message>
+            <source>PREF_LIST_TEXT_1</source>
+            <translation>second option</translation>
+        </message>
+        <message>
+            <source>PREF_LIST_TEXT_2</source>
+            <translation>third option</translation>
+        </message>
+    </context>
+</TS>
+"""
+hxxgui_message_en=Template(hxxgui_message_en)
+hxxgui_message_fr="""
+<!DOCTYPE TS>
+<TS version="1.1" >
+    <context>
+        <name>@default</name>
+        <message>
+            <source>TLT_MY_NEW_ITEM</source>
+            <translation>Un article de menu propre a ${component_name}</translation>
+        </message>
+        <message>
+            <source>MEN_MY_NEW_ITEM</source>
+            <translation>Mon menu</translation>
+        </message>
+        <message>
+            <source>STS_MY_NEW_ITEM</source>
+            <translation>Affiche une boite de dialogue simple</translation>
+        </message>
+        <message>
+            <source>TLT_${component_name}_ACTION</source>
+            <translation>Ouvre la boite de dialogue de ${component_name}</translation>
+        </message>
+        <message>
+            <source>MEN_FILE</source>
+            <translation>File</translation>
+        </message>
+        <message>
+            <source>MEN_FILE_${component_name}</source>
+            <translation>Menu de ${component_name}</translation>
+        </message>
+        <message>
+            <source>MEN_${component_name}</source>
+            <translation>${component_name}</translation>
+        </message>
+        <message>
+            <source>TOOL_${component_name}</source>
+            <translation>${component_name}</translation>
+        </message>
+    </context>
+    <context>
+        <name>${component_name}GUI</name>
+        <message>
+            <source>BUT_OK</source>
+            <translation>OK</translation>
+        </message>
+        <message>
+            <source>BUT_CANCEL</source>
+            <translation>Annuler</translation>
+        </message>
+        <message>
+            <source>INF_${component_name}_TITLE</source>
+            <translation>Information ${component_name}</translation>
+        </message>
+        <message>
+            <source>INF_${component_name}_TEXT</source>
+            <translation>Ceci est un simple test</translation>
+        </message>
+        <message>
+            <source>INF_${component_name}_CHECK</source>
+            <translation>coche</translation>
+        </message>
+        <message>
+            <source>INF_${component_name}_UNCHECK</source>
+            <translation>decoche</translation>
+        </message>
+        <message>
+            <source>RES_${component_name}_TITLE</source>
+            <translation>Dialogue example de ${component_name}</translation>
+        </message>
+        <message>
+            <source>RES_${component_name}_TEXT</source>
+            <translation>Les preferences sont : \n\tCase a cocher : %1\n\tEntier : %2\n\tEntier2 : %3\n\tDouble : %4\n\tTexte : %5</translation>
+        </message>
+        <message>
+            <source>PREF_TAB_GENERAL</source>
+            <translation>General</translation>
+        </message>
+        <message>
+            <source>PREF_GROUP_DEFAULTS</source>
+            <translation>valeur par defaut</translation>
+        </message>
+        <message>
+            <source>PREF_DEFAULT_BOOL</source>
+            <translation>Cochez-moi</translation>
+        </message>
+        <message>
+            <source>PREF_DEFAULT_INTEGER</source>
+            <translation>Entrez un entier :</translation>
+        </message>
+        <message>
+            <source>PREF_DEFAULT_SPININT</source>
+            <translation>cliquez sur les fleches (entier)</translation>
+        </message>
+        <message>
+            <source>PREF_DEFAULT_SPINDBL</source>
+            <translation>cliquez sur les fleches (double)</translation>
+        </message>
+        <message>
+            <source>PREF_DEFAULT_SELECTOR</source>
+            <translation>Choisissez une option</translation>
+        </message>
+        <message>
+            <source>PREF_LIST_TEXT_0</source>
+            <translation>premiere option</translation>
+        </message>
+        <message>
+            <source>PREF_LIST_TEXT_1</source>
+            <translation>deuxieme option</translation>
+        </message>
+        <message>
+            <source>PREF_LIST_TEXT_2</source>
+            <translation>troisieme option</translation>
+        </message>
+    </context>
+</TS>
+"""
+hxxgui_message_fr=Template(hxxgui_message_fr)
+hxxgui_config="""
+language=en
+"""
+hxxgui_config=Template(hxxgui_config)
+hxxgui_xml_en="""
+<?xml version='1.0' encoding='us-ascii'?>
+<!DOCTYPE application PUBLIC "" "desktop.dtd">
+<application title="${component_name} component" date="9/12/2001" author="C Caremoli" appId="${component_name}" >
+<desktop>
+<!-- ### MENUBAR ###  -->
+<menubar>
+
+ <menu-item label-id="File" item-id="1" pos-id="">
+  <submenu label-id="Hello" item-id="19" pos-id="9">
+   <popup-item item-id="190" pos-id="" label-id="MyNewItem" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+  </submenu>
+  <endsubmenu />
+ </menu-item>
+
+ <menu-item label-id="${component_name}" item-id="90" pos-id="3">
+  <popup-item item-id="901" label-id="Get banner" icon-id="" tooltip-id="Get ${component_name} banner" accel-id="" toggle-id="" execute-action=""/>
+
+ </menu-item>
+</menubar>
+<!-- ### TOOLBAR ###  -->
+<toolbar label-id="${component_name}">
+ <toolbutton-item item-id="901" label-id="Get banner" icon-id="Exec${component_name}.png" tooltip-id="Get ${component_name} banner" accel-id="" toggle-id="" execute-action=""/>
+</toolbar>
+</desktop>
+</application>
+"""
+hxxgui_xml_en=Template(hxxgui_xml_en)
+hxxgui_xml_fr="""
+<?xml version='1.0' encoding='us-ascii'?>
+<!DOCTYPE application PUBLIC "" "desktop.dtd">
+<application title="${component_name} component" date="9/12/2001" author="C Caremoli" appId="${component_name}" >
+<desktop>
+<!-- ### MENUBAR ###  -->
+<menubar>
+ <menu-item label-id="File" item-id="1" pos-id="">
+  <submenu label-id="Hello" item-id="19" pos-id="9">
+   <popup-item item-id="190" pos-id="" label-id="MyNewItem" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+  </submenu>
+  <endsubmenu />
+ </menu-item>
+ <menu-item label-id="${component_name}" item-id="90" pos-id="3">
+  <popup-item item-id="941" label-id="Lancer IHM" icon-id="" tooltip-id="Lancer IHM ${component_name}" accel-id="" toggle-id="" execute-action=""/>
+ </menu-item>
+</menubar>
+<!-- ### TOOLBAR ###  -->
+<toolbar label-id="${component_name}">
+ <toolbutton-item item-id="941" label-id="Lancer IHM" icon-id="Exec${component_name}.png" tooltip-id="Lancer IHM ${component_name}" accel-id="" toggle-id="" execute-action=""/>
+</toolbar>
+</desktop>
+</application>
+"""
+hxxgui_xml_fr=Template(hxxgui_xml_fr)
+
index 06cff79f77a972a2ffd1ff80885344195f107b14..04a44e3047d16c1adb8a70790256f0f5b4ba2b13 100644 (file)
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 """
-  Module that generates SALOME c++ Component from a non SALOME c++ component (its header and its shares library)
+  Module that generates SALOME c++ Component from a non SALOME c++ component 
+  (its header and its shares library)
 """
 
 debug=1
 import os
+import string
+import fnmatch
+from tempfile import mkstemp
 from gener import Component, Invalid
 from hxx_tmpl import cxxService, hxxCompo, cxxCompo, compoMakefile
 from module_generator import Service
-import string
-from tempfile import mkstemp
 from yacstypes import corba_rtn_type,moduleTypes
+from hxx_awk import parse01,parse1,parse2,parse3
+from hxx_awk import cpp2idl_mapping
+# these tables contain the part of code which depends upon c++ types
+from hxx_awk import cpp_impl_a,cpp_impl_b,cpp_impl_c  
+from hxx_awk import cpp2yacs_mapping
+from tempfile import mkdtemp
+from hxx_tmpl_gui import hxxgui_cxx, hxxgui_h, hxxgui_icon_ts
+from hxx_tmpl_gui import hxxgui_message_en, hxxgui_message_fr
+from hxx_tmpl_gui import hxxgui_config, hxxgui_xml_fr, hxxgui_xml_en
+
+# ------------------------------------------------------------------------------
 
 class HXX2SALOMEComponent(Component):
   def __init__(self, hxxfile , cpplib , cpp_path ):
     # search a file within a directory tree
-    import fnmatch
     def search_file(pattern, root):
         matches = []
         for path, dirs, files in os.walk(os.path.abspath(root)):
@@ -40,23 +52,24 @@ class HXX2SALOMEComponent(Component):
                  matches.append(os.path.join(path, filename))
         return matches
 
-    hxxfileful=search_file(hxxfile,cpp_path)
-    cpplibful=search_file(cpplib,cpp_path)
-    assert len(hxxfileful) > 0  ,'Error in HXX2SALOMEComponent : file ' + hxxfile + ' not found in ' + cpp_path
-    assert len(cpplibful) > 0   ,'Error in HXX2SALOMEComponent : file ' + cpplib + ' not found in ' + cpp_path
-    hxxfile=hxxfileful[0]
-    cpplib=cpplibful[0]
+    hxxfileful = search_file(hxxfile,cpp_path)
+    cpplibful = search_file(cpplib,cpp_path)
+    format_error = 'Error in HXX2SALOMEComponent : file %s ot found in %s'
+    assert len(hxxfileful) > 0, format_error %  (hxxfile, cpp_path)
+    assert len(cpplibful) > 0, format_error % (cpplib, cpp_path)
+    hxxfile = hxxfileful[0]
+    cpplib = cpplibful[0]
 
     # grab name of c++ component
-    from hxx_awk import parse01,parse1,parse2,parse3
-    cmd1="""awk '$1 == "class" && $0 !~ /;/ {print $2}' """ + hxxfile + """|awk -F: '{printf "%s",$1}' """
+    cmd1="""awk '$1 == "class" && $0 !~ /;/ {print $2}' """ + hxxfile +\
+         """|awk -F: '{printf "%s",$1}' """
     f=os.popen(cmd1)
     class_name=f.readlines()[0]
     name=class_name
     print "classname=",class_name
     f.close()
 
-    # create temporary awk files
+    # create temporary awk files for the parsing
     (fd01,p01n)=mkstemp()
     f01=os.fdopen(fd01,"w")
     f01.write(parse01)
@@ -77,154 +90,207 @@ class HXX2SALOMEComponent(Component):
     f3.write(parse3)
     f3.close()
 
-    # awk parsing of hxx files - result written in file parse_type_result
-    cmd2="cat " + hxxfile + " | awk -f " + p01n + """ | sed 's/virtual //g' | sed 's/MEDMEM_EXPORT//g' | sed 's/throw.*;/;/g' | awk -f """ + p1n + " | awk -f " + p2n + " | awk -v class_name=" + class_name + " -f " + p3n
+    # awk parsing of hxx files - 
+    # result written in file parse_type_result
+    cmd2 = [
+        "cat %s" % hxxfile,
+        "awk -f %s" % p01n,
+        "sed 's/virtual //g'",
+        "sed 's/MEDMEM_EXPORT//g'",
+        "sed 's/throw.*;/;/g'",
+        "awk -f %s" % p1n,
+        "awk -f %s" % p2n,
+        "awk -v class_name=%s -f %s" % (class_name, p3n) ]
+    cmd2 = ' | '.join(cmd2)
+
     os.system(cmd2)
     os.remove(p01n)
     os.remove(p1n)
     os.remove(p2n)
     os.remove(p3n)
 
-    # Retrieve the information which was generated in the file parse_type_result.
+    # Retrieve the information which was generated in 
+    # the file parse_type_result.
     # The structure of the file is :
     #
     #   Function  return_type   function_name
     #   [arg1_type  arg1_name]
     #   [arg2_type  arg2_name]
     #   ...
-    # The information is stored in a list of dictionnaries (service_definition)
-    from hxx_awk import cpp2idl_mapping
+    # The service names are stored in list_of_services
+    # The information relative to a service (called service_name) is stored in
+    # the dictionnary service_definition[service_name]
     list_of_services=[]
     service_definition={}
     result_parsing=open("parse_type_result","r")
     for line in result_parsing.readlines():
-       line=line[0:-1] # get rid of trailing \n
+        line=line[0:-1] # get rid of trailing \n
         words = string.split(line,';')
 
         if len(words) >=3 and words[0] == "Function": # detect a new service
-           function_name=words[2]
-            list_of_services.append(function_name)
-            service_definition[function_name]={}
+            function_name=words[2]
+            # store the name of new service
+            list_of_services.append(function_name) 
+            # create a dict to store informations relative to this service
+            service_definition[function_name]={} 
             service_definition[function_name]["ret"]=words[1]  # return type
             service_definition[function_name]["inports"]=[]
             service_definition[function_name]["outports"]=[]
             service_definition[function_name]["ports"]=[]
             service_definition[function_name]["impl"]=[]
 
-        if len(words) == 2:  # an argument type and argument name of a previous service
+        # an argument type and argument name of the current service
+        if len(words) == 2:  
+            current_service=list_of_services[-1]
+            current_service_dict=service_definition[current_service]
             typename=words[0]
             argname=words[1]
-            service_definition[list_of_services[-1]]["ports"].append( (argname,typename) ) # store in c++ order the arg names
+            # store in c++ order the arg names
+            current_service_dict["ports"].append( (argname,typename) ) 
 
             # separate in from out parameters
             inout=cpp2idl_mapping[typename][0:2]
             assert inout=="in" or inout=="ou",'Error in table cpp2idl_mapping'
             if inout == "in":
-                service_definition[list_of_services[-1]]["inports"].append( (argname,typename) )
+                current_service_dict["inports"].append((argname, typename) )
             else:
-                service_definition[list_of_services[-1]]["outports"].append( (argname,typename) )
-
-    # generate implementation of c++ servant
-    from hxx_awk import cpp_impl_a,cpp_impl_b,cpp_impl_c  # these tables contain the part of code which depends upon c++ types
+                current_service_dict["outports"].append((argname, typename) )
+    #
+    # For each service : 
+    #  - generate implementation of c++ servant
+    #  - store it in service_definition[serv]["impl"]
     for serv in list_of_services:
-       if debug:
-           print "service : ",serv
-           print "  inports  -> ",service_definition[serv]["inports"]
-           print "  outports -> ",service_definition[serv]["outports"]
-           print "  return   -> ",service_definition[serv]["ret"]
-
-
-       # Part 1 : Argument pre-processing
-       s_argument_processing="//\tArguments processing\n"
-       for (argname,argtype) in service_definition[serv]["inports"] + service_definition[serv]["outports"]:
-           format=cpp_impl_a[argtype]
-           s_argument_processing += format % {"arg" : argname }
-       if s_argument_processing=="//\tArguments processing\n": # if there was no args
-           s_argument_processing=""
-
-
-       # Part 2 : Call to the underlying c++ function
-       s_call_cpp_function="//\tCall cpp component\n\t"
-       rtn_type=service_definition[serv]["ret"]
-       if rtn_type == "void" : # if return type is void, the call syntax is different
-           s_call_cpp_function += "cppCompo_->%s(" % serv
-       else:
-           s_call_cpp_function += "%s _rtn_cpp = cppCompo_->%s(" % (rtn_type ,serv )
-
-       for (argname,argtype) in service_definition[serv]["ports"]:
-             # special treatment for some arguments
-             post=""
-             pre=""
-             if string.find(cpp_impl_a[argtype],"auto_ptr" ) != -1 :
-                 post=".get()" # for auto_ptr argument, retrieve the raw pointer behind
-             if  argtype == "const MEDMEM::MESH&"  or  argtype == "const MEDMEM::SUPPORT&" : 
-                  pre="*"  # we cannot create MESHClient on the stack (private constructor), so we create it on the heap and dereference it
-             post+="," # separator between arguments
-             s_call_cpp_function += " %s_%s%s" % ( pre,argname,post)
-       if s_call_cpp_function[-1]==',':
-           s_call_cpp_function=s_call_cpp_function[0:-1] # get rid of trailing comma
-       s_call_cpp_function=s_call_cpp_function+');\n'
-
-       # Part 3.a : Out Argument Post-processing
-       s_argument_postprocessing="//\tPost-processing & return\n"
-       for (argname,argtype) in service_definition[serv]["outports"]:
-           format=cpp_impl_c[argtype]
-           s_argument_postprocessing += format % {"arg" : argname, "module" : "%(module)s" } # the treatment of %(module) is postponed in makecxx() 
-                                                                                             # because we don't know here the module name
-       # Part 3.b : In Argument Post-processing
-       for (argname,argtype) in service_definition[serv]["inports"]:
-           if cpp_impl_c.has_key(argtype): # not all in types require a treatment
-               format=cpp_impl_c[argtype]
-               s_argument_postprocessing += format % {"arg" : argname, "module" : "%(module)s" } # id : treatment of %(module) is postponed in makecxx
-
-       # Part 3.c : return processing
-       s_rtn_processing=cpp_impl_b[rtn_type]
-       s_rtn_processing += "\tendService(\"%(class_name)s_i::%(serv_name)s\");\n\tEND_OF(\"%(class_name)s_i::%(serv_name)s\");\n" % { "serv_name" : serv, "class_name" : class_name }
-       if  rtn_type != "void":
-           s_rtn_processing += "\treturn _rtn_ior;"
-
-        service_definition[serv]["impl"] = s_argument_processing + s_call_cpp_function + s_argument_postprocessing + s_rtn_processing
-       if debug:
+        if debug:
+            print "service : ",serv
+            print "  inports  -> ",service_definition[serv]["inports"]
+            print "  outports -> ",service_definition[serv]["outports"]
+            print "  return   -> ",service_definition[serv]["ret"]
+
+
+        # Part 1 : Argument pre-processing
+        s_argument_processing="//\tArguments processing\n"
+        for (argname,argtype) in service_definition[serv]["inports"] + \
+                                 service_definition[serv]["outports"]:
+            format=cpp_impl_a[argtype]
+            s_argument_processing += format % {"arg" : argname }
+
+        # if there was no args
+        if s_argument_processing=="//\tArguments processing\n": 
+            s_argument_processing=""
+
+
+        # Part 2 : Call to the underlying c++ function
+        s_call_cpp_function="//\tCall cpp component\n\t"
+        rtn_type=service_definition[serv]["ret"]
+
+        # if return type is void, the call syntax is different
+        if rtn_type == "void" : 
+            s_call_cpp_function += "cppCompo_->%s(" % serv
+        else:
+            s_call_cpp_function +=\
+                "%s _rtn_cpp = cppCompo_->%s(" % (rtn_type ,serv )
+
+        for (argname,argtype) in service_definition[serv]["ports"]:
+              # special treatment for some arguments
+              post=""
+              pre=""
+
+              if string.find(cpp_impl_a[argtype],"auto_ptr" ) != -1 :
+                  # for auto_ptr argument, retrieve the raw pointer behind
+                  post=".get()" 
+              if  argtype == "const MEDMEM::MESH&"  or  \
+                  argtype == "const MEDMEM::SUPPORT&" : 
+                  # we cannot create MESHClient on the stack 
+                  # (private constructor!), 
+                  # so we create it on the heap and dereference it
+                  pre="*"  
+
+              post+="," # separator between arguments
+              s_call_cpp_function += " %s_%s%s" % ( pre,argname,post)
+        if s_call_cpp_function[-1]==',':
+            # get rid of trailing comma
+            s_call_cpp_function=s_call_cpp_function[0:-1] 
+
+        s_call_cpp_function=s_call_cpp_function+');\n'
+
+        # Part 3.a : Out Argument Post-processing
+        s_argument_postprocessing="//\tPost-processing & return\n"
+        for (argname,argtype) in service_definition[serv]["outports"]:
+            format=cpp_impl_c[argtype]
+            # the treatment of %(module) is postponed in makecxx() 
+            # because we don't know here the module name
+            s_argument_postprocessing += \
+                format % {"arg" : argname, "module" : "%(module)s" } 
+
+        # Part 3.b : In Argument Post-processing
+        for (argname,argtype) in service_definition[serv]["inports"]:
+            # not all in types require a treatment
+            if cpp_impl_c.has_key(argtype): 
+                format=cpp_impl_c[argtype]
+                # id : treatment of %(module) is postponed in makecxx
+                s_argument_postprocessing += \
+                        format % {"arg" : argname, "module" : "%(module)s" } 
+
+        # Part 3.c : return processing
+        s_rtn_processing=cpp_impl_b[rtn_type]
+
+        format_end_serv = "\tendService(\"%(class_name)s_i::%(serv_name)s\");"
+        format_end_serv += "\n\tEND_OF(\"%(class_name)s_i::%(serv_name)s\");\n"
+        s_rtn_processing += format_end_serv %\
+                { "serv_name" : serv, "class_name" : class_name }
+
+        if  rtn_type != "void":
+            s_rtn_processing += "\treturn _rtn_ior;"
+
+        service_definition[serv]["impl"] = s_argument_processing + \
+                                           s_call_cpp_function + \
+                                           s_argument_postprocessing + \
+                                           s_rtn_processing
+        if debug:
             print "implementation :\n",service_definition[serv]["impl"]
 
     #
-    # Create a list of services, and give it to Component constructor
+    # Create a list of Service objects (called services), 
+    # and give it to Component constructor
+    #
     services=[]
-    from hxx_awk import cpp2yacs_mapping
     self.use_medmem=False
     self.use_medcoupling=False
     for serv in list_of_services:
-       # for inports and outports, Service class expects a list of tuples, each tuple containing the name and the yacs type of the port
-       # thus we need to convert c++ types to yacs types  (we use for that the cpp2yacs_mapping table
+        # for inports and outports, Service class expects a list of tuples, 
+        # each tuple containing the name and the yacs type of the port
+        # thus we need to convert c++ types to yacs types  
+        # (we use for that the cpp2yacs_mapping table)
         inports=[]
-        for i in range( len(service_definition[serv]["inports"]) ):
-           inports.append( [service_definition[serv]["inports"][i][0], cpp2yacs_mapping[service_definition[serv]["inports"][i][1]] ] )
-        outports=[]
-        for i in range( len(service_definition[serv]["outports"]) ):
-           outports.append( [service_definition[serv]["outports"][i][0], cpp2yacs_mapping[service_definition[serv]["outports"][i][1]] ] )
-
-       Return="void"
-       if service_definition[serv]["ret"] != "void":
+        for op in service_definition[serv]["inports"]:
+            inports.append([op[0], cpp2yacs_mapping[op[1]] ] )
+
+        outports = []
+        for op in service_definition[serv]["outports"]:
+            outports.append([op[0], cpp2yacs_mapping[op[1]] ] )
+
+        Return="void"
+        if service_definition[serv]["ret"] != "void":
             Return=cpp2yacs_mapping[service_definition[serv]["ret"]]
 
-       # find out if component uses medmem types and/or medcoupling types
-       for (argname,argtype) in inports + outports + [("return",Return)]:
-           if moduleTypes[argtype]=="MED":
-               if argtype.count("Coupling")>0:
-                   self.use_medcoupling=True
-               else:
-                   self.use_medmem=True
-               break
+        # find out if component uses medmem types and/or medcoupling types
+        for (argname,argtype) in inports + outports + [("return",Return)]:
+            if moduleTypes[argtype]=="MED":
+                if argtype.count("Coupling")>0:
+                    self.use_medcoupling=True
+                else:
+                    self.use_medmem=True
+                break
 
         code=service_definition[serv]["impl"]
-       if debug:
-           print "service : ",serv
-           print "  inports  -> ",service_definition[serv]["inports"]
-           print "  converted inports  -> ",inports
-           print "  outports -> ",service_definition[serv]["outports"]
-           print "  converted outports  -> ",outports
-           print "  Return  -> ",service_definition[serv]["ret"]
-           print "  converted Return  -> ",Return
+        if debug:
+            print "service : ",serv
+            print "  inports  -> ",service_definition[serv]["inports"]
+            print "  converted inports  -> ",inports
+            print "  outports -> ",service_definition[serv]["outports"]
+            print "  converted outports  -> ",outports
+            print "  Return  -> ",service_definition[serv]["ret"]
+            print "  converted Return  -> ",Return
 
         services.append(Service(serv, 
            inport=inports, 
@@ -240,7 +306,7 @@ class HXX2SALOMEComponent(Component):
     Inheritedclass=""
     self.inheritedconstructor=""
     if self.use_medmem:
-       Compodefs="""
+        Compodefs="""
 #include CORBA_CLIENT_HEADER(MED)
 #include CORBA_CLIENT_HEADER(MED_Gen)
 #include "FIELDClient.hxx"
@@ -250,11 +316,11 @@ class HXX2SALOMEComponent(Component):
 #include "MEDMEM_FieldTemplate_i.hxx"
 #include "Med_Gen_Driver_i.hxx"
 """
-        Inheritedclass="Med_Gen_Driver_i"
-       self.inheritedconstructor="Med_Gen_Driver_i(orb),"
+        Inheritedclass="Med_Gen_Driver_i, public SALOMEMultiComm"
+        self.inheritedconstructor="Med_Gen_Driver_i(orb),"
 
     if self.use_medcoupling:
-       Compodefs+="""
+        Compodefs+="""
 #include CORBA_CLIENT_HEADER(MEDCouplingCorbaServant)
 #include CORBA_CLIENT_HEADER(MED_Gen)
 #include "MEDCouplingFieldDoubleServant.hxx"
@@ -271,10 +337,11 @@ class HXX2SALOMEComponent(Component):
                              sources=None,inheritedclass=Inheritedclass,
                              compodefs=Compodefs)
 
+# ------------------------------------------------------------------------------
   def makeCompo(self, gen):
     """generate files for C++ component
-
-       return a dict where key is the file name and value is the content of the file
+       return a dict where key is the file name and 
+       value is the content of the file
     """
     cxxfile = "%s_i.cxx" % self.name
     hxxfile = "%s_i.hxx" % self.name
@@ -283,6 +350,7 @@ class HXX2SALOMEComponent(Component):
             hxxfile:self.makehxx(gen)
            }
 
+# ------------------------------------------------------------------------------
   def getMakefileItems(self,gen):
       makefileItems={"header":"""
 include $(top_srcdir)/adm_local/make_common_starter.am
@@ -296,12 +364,14 @@ include $(top_srcdir)/adm_local/make_common_starter.am
                                                      includes=self.includes)
       return makefileItems
 
+# ------------------------------------------------------------------------------
   def makehxx(self, gen):
     """return a string that is the content of .hxx file
     """
     services = []
     for serv in self.services:
-      service = "    %s %s(" % (corba_rtn_type(serv.ret,gen.module.name),serv.name)
+      service = "    %s %s(" % (corba_rtn_type(serv.ret,gen.module.name),
+                                serv.name)
       service = service+gen.makeArgs(serv)+") throw (SALOME::SALOME_Exception);"
       services.append(service)
     servicesdef = "\n".join(services)
@@ -310,10 +380,13 @@ include $(top_srcdir)/adm_local/make_common_starter.am
     if self.inheritedclass:
       inheritedclass= " public virtual " + self.inheritedclass + ","
 
-    return hxxCompo.substitute(component=self.name, module=gen.module.name,
-                               servicesdef=servicesdef, inheritedclass=inheritedclass,
-                              compodefs=self.compodefs)
+    return hxxCompo.substitute(component=self.name, 
+                               module=gen.module.name,
+                               servicesdef=servicesdef, 
+                               inheritedclass=inheritedclass,
+                               compodefs=self.compodefs)
 
+# ------------------------------------------------------------------------------
   def makecxx(self, gen, exe=0):
     """return a string that is the content of .cxx file
     """
@@ -322,12 +395,85 @@ include $(top_srcdir)/adm_local/make_common_starter.am
     defs = []
     for serv in self.services:
       defs.append(serv.defs)
-      service = cxxService.substitute(component=self.name, service=serv.name,ret=corba_rtn_type(serv.ret,gen.module.name),
-                                      parameters=gen.makeArgs(serv),
-                                     body=serv.body % {"module":gen.module.name+"_ORB"} )
+      print "CNC bug : ",serv.body
+      service = cxxService.substitute(
+                           component=self.name, 
+                           service=serv.name,
+                           ret=corba_rtn_type(serv.ret,gen.module.name),
+                           parameters=gen.makeArgs(serv),
+                           body=serv.body % {"module":gen.module.name+"_ORB"} )
       services.append(service)
     return cxxCompo.substitute(component=self.name, 
-                              inheritedconstructor=self.inheritedconstructor,
+                               inheritedconstructor=self.inheritedconstructor,
                                servicesdef="\n".join(defs),
                                servicesimpl="\n".join(services))
 
+# ------------------------------------------------------------------------------
+  def getGUIfilesTemplate(self):
+      """generate in a temporary directory files for a generic GUI, 
+         and return a list with file names.
+         it is the responsability of the user to get rid 
+         of the temporary directory when finished
+      """
+      gui_cxx=hxxgui_cxx.substitute(component_name=self.name)
+      gui_h=hxxgui_h.substitute(component_name=self.name)
+      gui_icon_ts=hxxgui_icon_ts.substitute(component_name=self.name)
+      gui_message_en=hxxgui_message_en.substitute(component_name=self.name)
+      gui_message_fr=hxxgui_message_fr.substitute(component_name=self.name)
+      gui_config=hxxgui_config.substitute(component_name=self.name)
+      gui_xml_fr=hxxgui_xml_fr.substitute(component_name=self.name)
+      gui_xml_en=hxxgui_xml_en.substitute(component_name=self.name)
+      temp_dir=mkdtemp()
+      gui_cxx_file_name=os.path.join(temp_dir,self.name+"GUI.cxx")
+      gui_h_file_name=os.path.join(temp_dir,self.name+"GUI.h")
+      gui_icon_ts_file_name=os.path.join(temp_dir,self.name+"_icons.ts")
+      gui_message_en_file_name=os.path.join(temp_dir,self.name+"_msg_en.ts")
+      gui_message_fr_file_name=os.path.join(temp_dir,self.name+"_msg_fr.ts")
+      gui_config_file_name=os.path.join(temp_dir,"config")
+      gui_xml_fr_file_name=os.path.join(temp_dir,self.name+"_en.xml")
+      gui_xml_en_file_name=os.path.join(temp_dir,self.name+"_fr.xml")
+
+      list_of_gui_names=[]
+
+      gui_cxx_file=open(gui_cxx_file_name,"w")
+      gui_cxx_file.write(gui_cxx)
+      gui_cxx_file.close()
+      list_of_gui_names.append(gui_cxx_file_name)
+
+      gui_h_file=open(gui_h_file_name,"w")
+      gui_h_file.write(gui_h)
+      gui_h_file.close()
+      list_of_gui_names.append(gui_h_file_name)
+
+      gui_icon_ts_file=open(gui_icon_ts_file_name,"w")
+      gui_icon_ts_file.write(gui_icon_ts)
+      gui_icon_ts_file.close()
+      list_of_gui_names.append(gui_icon_ts_file_name)
+
+      gui_message_en_file=open(gui_message_en_file_name,"w")
+      gui_message_en_file.write(gui_message_en)
+      gui_message_en_file.close()
+      list_of_gui_names.append(gui_message_en_file_name)
+
+      gui_message_fr_file=open(gui_message_fr_file_name,"w")
+      gui_message_fr_file.write(gui_message_fr)
+      gui_message_fr_file.close()
+      list_of_gui_names.append(gui_message_fr_file_name)
+
+      gui_config_file=open(gui_config_file_name,"w")
+      gui_config_file.write(gui_config)
+      gui_config_file.close()
+      list_of_gui_names.append(gui_config_file_name)
+
+      gui_xml_fr_file=open(gui_xml_fr_file_name,"w")
+      gui_xml_fr_file.write(gui_xml_fr)
+      gui_xml_fr_file.close()
+      list_of_gui_names.append(gui_xml_fr_file_name)
+
+      gui_xml_en_file=open(gui_xml_en_file_name,"w")
+      gui_xml_en_file.write(gui_xml_en)
+      gui_xml_en_file.close()
+      list_of_gui_names.append(gui_xml_en_file_name)
+
+
+      return list_of_gui_names
diff --git a/module_generator/hxxparacompo.py b/module_generator/hxxparacompo.py
new file mode 100644 (file)
index 0000000..89f5d80
--- /dev/null
@@ -0,0 +1,446 @@
+#  Copyright (C) 2009-2011  CEA DEN
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+"""
+  Module that generates SALOME c++ Component from a non SALOME c++ component (its header and its shares library)
+"""
+
+debug=1
+import os
+from gener import Component, Invalid
+from hxx_para_tmpl import cxxService, hxxCompo, cxxCompo, compoMakefile
+from module_generator import Service
+import string
+from tempfile import mkstemp
+from yacstypes import corba_rtn_type,moduleTypes
+
+class HXX2SALOMEParaComponent(Component):
+  def __init__(self, hxxfile , cpplib , cpp_path ):
+    # search a file within a directory tree
+    import fnmatch
+    def search_file(pattern, root):
+        matches = []
+        for path, dirs, files in os.walk(os.path.abspath(root)):
+            for filename in fnmatch.filter(files, pattern):
+                 matches.append(os.path.join(path, filename))
+        return matches
+
+    hxxfileful=search_file(hxxfile,cpp_path)
+    cpplibful=search_file(cpplib,cpp_path)
+    assert len(hxxfileful) > 0  ,'Error in HXX2SALOMEComponent : file ' + hxxfile + ' not found in ' + cpp_path
+    assert len(cpplibful) > 0   ,'Error in HXX2SALOMEComponent : file ' + cpplib + ' not found in ' + cpp_path
+
+    self.hxxfile=hxxfile  # to include it in servant implementation
+
+    # grab name of c++ component
+    from hxx_awk import parse01,parse1,parse2,parse3
+    cmd1="""awk '$1 == "class" && $0 !~ /;/ {print $2}' """ + hxxfileful[0] + """|awk -F: '{printf "%s",$1}' """
+    f=os.popen(cmd1)
+    class_name=f.readlines()[0]
+    name=class_name
+    print "classname=",class_name
+
+    if cpplib[:3]=="lib" and cpplib[-3:]==".so":
+        cpplibname=cpplib[3:-3]  # get rid of lib and .so, to use within makefile.am
+    else:
+        cpplibname=class_name+"CXX"  # the default name
+
+    f.close()
+
+    # create temporary awk files
+    (fd01,p01n)=mkstemp()
+    f01=os.fdopen(fd01,"w")
+    f01.write(parse01)
+    f01.close()
+
+    (fd1,p1n)=mkstemp()
+    f1=os.fdopen(fd1,"w")
+    f1.write(parse1)
+    f1.close()
+
+    (fd2,p2n)=mkstemp()
+    f2=os.fdopen(fd2,"w")
+    f2.write(parse2)
+    f2.close()
+
+    (fd3,p3n)=mkstemp()
+    f3=os.fdopen(fd3,"w")
+    f3.write(parse3)
+    f3.close()
+
+    # awk parsing of hxx files - result written in file parse_type_result
+    cmd2="cat " + hxxfileful[0] + " | awk -f " + p01n + """ | sed 's/virtual //g' | sed 's/MEDMEM_EXPORT//g' | sed 's/throw.*;/;/g' | awk -f """ + p1n + " | awk -f " + p2n + " | awk -v class_name=" + class_name + " -f " + p3n
+    os.system(cmd2)
+    os.remove(p01n)
+    os.remove(p1n)
+    os.remove(p2n)
+    os.remove(p3n)
+
+    # Retrieve the information which was generated in the file parse_type_result.
+    # The structure of the file is :
+    #
+    #   Function  return_type   function_name
+    #   [arg1_type  arg1_name]
+    #   [arg2_type  arg2_name]
+    #   ...
+    # The service names are stored in list_of_services
+    # The information relative to a service (called service_name) is stored in the dictionnary service_definition[service_name]
+    from hxx_awk import cpp2idl_mapping
+    from hxx_awk import cpp2yacs_mapping
+    cpp2yacs_mapping["const ParaMEDMEM::MEDCouplingFieldDouble*"]="SALOME_MED/MPIMEDCouplingFieldDoubleCorbaInterface"
+    cpp2yacs_mapping["const ParaMEDMEM::MEDCouplingFieldDouble&"]="SALOME_MED/MPIMEDCouplingFieldDoubleCorbaInterface"
+    cpp2yacs_mapping["ParaMEDMEM::MEDCouplingFieldDouble*&"]="SALOME_MED/MPIMEDCouplingFieldDoubleCorbaInterface"
+    cpp2yacs_mapping["ParaMEDMEM::MEDCouplingFieldDouble*"]="SALOME_MED/MPIMEDCouplingFieldDoubleCorbaInterface"
+    list_of_services=[]
+    list_of_services_with_in_fields=[]
+    service_definition={}
+    result_parsing=open("parse_type_result","r")
+    for line in result_parsing.readlines():
+        line=line[0:-1] # get rid of trailing \n
+        words = string.split(line,';')
+
+        if len(words) >=3 and words[0] == "Function": # detect a new service
+            function_name=words[2]
+            if function_name != "getInputFieldTemplate":
+                list_of_services.append(function_name)
+            service_definition[function_name]={}
+            service_definition[function_name]["ret"]=words[1]  # return type
+            service_definition[function_name]["inports"]=[]
+            service_definition[function_name]["outports"]=[]
+            service_definition[function_name]["ports"]=[]
+            service_definition[function_name]["impl"]=[]
+            service_definition[function_name]["thread_func_decl"]=[]
+            service_definition[function_name]["thread_str_decl"]=[]
+
+        if len(words) == 2 and function_name != "getInputFieldTemplate":  # an argument type and argument name of a previous service
+            typename=words[0]
+            argname=words[1]
+            service_definition[list_of_services[-1]]["ports"].append( (argname,typename) ) # store in c++ order the arg names
+
+            # separate in from out parameters
+            inout=cpp2idl_mapping[typename][0:2]
+            assert inout=="in" or inout=="ou",'Error in table cpp2idl_mapping'
+            if inout == "in":
+                service_definition[list_of_services[-1]]["inports"].append( (argname,typename) )
+                if typename=="const ParaMEDMEM::MEDCouplingFieldDouble*":
+                    list_of_services_with_in_fields.append(list_of_services[-1])
+            else:
+                service_definition[list_of_services[-1]]["outports"].append( (argname,typename) )
+    for servNane in list_of_services_with_in_fields:
+        service_definition[servNane]["inports"].append(("coupling","const char*"))
+        service_definition[servNane]["ports"].append(("coupling","const char*"))
+
+    if service_definition.has_key('getInputFieldTemplate'):
+        del service_definition['getInputFieldTemplate']
+    #
+    # generate implementation of c++ servant
+    # store it in service_definition[serv]["impl"]
+    #
+    from hxx_awk import cpp_impl_a,cpp_impl_b,cpp_impl_c  # these tables contain the part of code which depends upon c++ types
+    cpp_impl_b["ParaMEDMEM::MEDCouplingFieldDouble*"]="""\tParaMEDMEM::MPIMEDCouplingFieldDoubleServant * _rtn_field_i = new ParaMEDMEM::MPIMEDCouplingFieldDoubleServant(_orb,this,_rtn_cpp);
+\t_rtn_cpp->decrRef();
+\tSALOME_MED::MPIMEDCouplingFieldDoubleCorbaInterface_ptr _rtn_ior = _rtn_field_i->_this();\n"""
+    cpp_impl_a["const ParaMEDMEM::MEDCouplingFieldDouble*"]="\tParaMEDMEM::MEDCouplingFieldDouble* _%(arg)s=cppCompo_->getInputFieldTemplate();\n\t_setInputField(coupling,%(arg)s,_%(arg)s);\n"
+
+    from yacstypes import corbaTypes,corbaOutTypes
+    format_thread_signature="void * th_%s(void * st);" # this thread declaration will be included in servant's header
+    format_thread_struct="typedef struct {\n  int ip;\n  Engines::IORTab* tior;\n%(arg_decl)s} thread_%(serv_name)s_str;" # this thread declaration will be included in servant's header
+    format_thread_create="""
+//      create threads to forward to other processes the service invocation
+        if(_numproc == 0)
+        {
+            th = new pthread_t[_nbproc];
+            for(int ip=1;ip<_nbproc;ip++)
+            {
+                %(init_thread_str)s
+                pthread_create(&(th[ip]),NULL,th_%(serv_name)s,(void*)st);
+            }
+        }
+"""
+    s_thread_join="""
+//      waiting for all threads to complete
+        if(_numproc == 0)
+        {
+            for(int ip=1;ip<_nbproc;ip++)
+            {
+                pthread_join(th[ip],&ret_th);
+                est = (except_st*)ret_th;
+                if(est->exception)
+                {
+                    ostringstream msg;
+                    msg << "[" << ip << "] " << est->msg;
+                    THROW_SALOME_CORBA_EXCEPTION(msg.str().c_str(),SALOME::INTERNAL_ERROR);
+                }
+                delete est;
+            }
+          delete[] th;
+        }
+"""
+    format_thread_impl="""
+void *th_%(serv_name)s(void *s)
+{
+  ostringstream msg;
+  thread_%(serv_name)s_str *st = (thread_%(serv_name)s_str*)s;
+  except_st *est = new except_st;
+  est->exception = false;
+
+  try
+    {
+      %(module)s_ORB::%(component_name)s_Gen_var compo = %(module)s_ORB::%(component_name)s_Gen::_narrow((*(st->tior))[st->ip]);
+      compo->%(serv_name)s(%(arg_thread_invocation)s);
+    }
+  catch(const SALOME::SALOME_Exception &ex)
+    {
+      est->exception = true;
+      est->msg = ex.details.text;
+    }
+  catch(const CORBA::Exception &ex)
+    {
+      est->exception = true;
+      msg << "CORBA::Exception: " << ex;
+      est->msg = msg.str();
+    }
+  delete st;
+  return((void*)est);
+}
+
+"""
+
+    self.thread_impl=""  # the implementation of the thread functions used to invoque services on slave processors 
+    for serv in list_of_services:
+        if debug:
+            print "service : ",serv
+            print "  inports  -> ",service_definition[serv]["inports"]
+            print "  outports -> ",service_definition[serv]["outports"]
+            print "  return   -> ",service_definition[serv]["ret"]
+
+        # Part 0 : specific treatments for parallel components (call threads to forward the invocation to the service to all processes)
+        service_definition[serv]["thread_func_decl"]=format_thread_signature % serv
+        arg_declaration=""
+        arg_thread_invocation=""
+        init_thread_str="thread_%s_str *st = new thread_%s_str;" % (serv,serv) 
+        init_thread_str+="\n                st->ip = ip;"
+        init_thread_str+="\n                st->tior = _tior;"
+        for (argname,argtype) in service_definition[serv]["inports"]:
+            arg_declaration+="  "+corbaTypes[cpp2yacs_mapping[argtype]]+" "+argname+";\n"
+            init_thread_str+="\n                st->"+argname+" = "+argname+";"
+        for (argname,argtype) in service_definition[serv]["outports"]:
+            arg_declaration+="  "+corbaOutTypes[cpp2yacs_mapping[argtype]]+" "+argname+";\n"
+            init_thread_str+="\n                st->"+argname+" = "+argname+";"
+        for (argname,argtype) in service_definition[serv]["ports"]:
+            arg_thread_invocation+="st->"+argname+", "
+        if len(arg_thread_invocation)>0:
+            arg_thread_invocation=arg_thread_invocation[0:-2] # get rid of trailing comma
+        service_definition[serv]["thread_str_decl"]=format_thread_struct % { "serv_name" : serv, "arg_decl" : arg_declaration }
+        s_thread_call=format_thread_create % { "serv_name" : serv , "init_thread_str" : init_thread_str}
+        # within format_thread_impl the treatment of %(module) is postponed in makecxx() because we don't know here the module name
+        self.thread_impl+=format_thread_impl % {"serv_name" : serv , "arg_thread_invocation" : arg_thread_invocation , "component_name" : name, "module" : "%(module)s" } 
+
+        # Part 1 : Argument pre-processing
+        s_argument_processing="//\tArguments processing\n"
+        for (argname,argtype) in service_definition[serv]["inports"] + service_definition[serv]["outports"]:
+            format=cpp_impl_a[argtype]
+            s_argument_processing += format % {"arg" : argname }
+        if s_argument_processing=="//\tArguments processing\n": # if there was no args
+            s_argument_processing=""
+
+        # if an argument called name is of type const char*, this argument is transmitted to getInputFieldTemplate()
+        # => we insert "name" between the bracket of getInputFieldTemplate()
+        indice_getInputFieldTemplate=s_argument_processing.find ("cppCompo_->getInputFieldTemplate();")
+        if s_argument_processing.find ("const std::string _name") != -1  and  indice_getInputFieldTemplate != -1:
+            ind_insertion=indice_getInputFieldTemplate+33
+            s_argument_processing=s_argument_processing[:ind_insertion]+"name"+s_argument_processing[ind_insertion:-1]
+
+        # Part 2 : Call to the underlying c++ function
+        s_call_cpp_function="//\tCall cpp component\n\t"
+        rtn_type=service_definition[serv]["ret"]
+        if rtn_type == "void" : # if return type is void, the call syntax is different
+            s_call_cpp_function += "cppCompo_->%s(" % serv
+        else:
+            s_call_cpp_function += "%s _rtn_cpp = cppCompo_->%s(" % (rtn_type ,serv )
+
+        for (argname,argtype) in service_definition[serv]["ports"]:
+              # special treatment for some arguments
+              post=""
+              pre=""
+              if string.find(cpp_impl_a[argtype],"auto_ptr" ) != -1 :
+                  post=".get()" # for auto_ptr argument, retrieve the raw pointer behind
+              if  argtype == "const MEDMEM::MESH&"  or  argtype == "const MEDMEM::SUPPORT&" : 
+                  pre="*"  # we cannot create MESHClient on the stack (private constructor), so we create it on the heap and dereference it
+              post+="," # separator between arguments
+              if(argname!="coupling"):  # coupling is a special argument added for input fields - it should not be transferred to the underlying c++ component
+                  s_call_cpp_function += " %s_%s%s" % ( pre,argname,post)
+        if s_call_cpp_function[-1]==',':
+            s_call_cpp_function=s_call_cpp_function[0:-1] # get rid of trailing comma
+        s_call_cpp_function=s_call_cpp_function+');\n'
+
+        # Part 3.a : Out Argument Post-processing
+        s_argument_postprocessing="//\tPost-processing & return\n"
+        for (argname,argtype) in service_definition[serv]["outports"]:
+            format=cpp_impl_c[argtype]
+            s_argument_postprocessing += format % {"arg" : argname, "module" : "%(module)s" } # the treatment of %(module) is postponed in makecxx() 
+                                                                                              # because we don't know here the module name
+        # Part 3.b : In Argument Post-processing
+        for (argname,argtype) in service_definition[serv]["inports"]:
+            if cpp_impl_c.has_key(argtype): # not all in types require a treatment
+                format=cpp_impl_c[argtype]
+                s_argument_postprocessing += format % {"arg" : argname, "module" : "%(module)s" } # id : treatment of %(module) is postponed in makecxx
+
+        # Part 3.c : return processing
+        s_rtn_processing=cpp_impl_b[rtn_type]
+        if  rtn_type != "void":
+            s_rtn_processing += "\treturn _rtn_ior;"
+
+        service_definition[serv]["impl"] = s_thread_call + s_argument_processing + s_call_cpp_function + s_thread_join  + s_argument_postprocessing + s_rtn_processing
+        if debug:
+            print "implementation :\n",service_definition[serv]["impl"]
+
+    #
+    # Create a list of Service objects (called services), and give it to Component constructor
+    #
+    services=[]
+    self.use_medmem=False
+    self.use_medcoupling=False
+    self.thread_func_decl=[]
+    self.thread_str_decl=[]
+    for serv in list_of_services:
+        # for inports and outports, Service class expects a list of tuples, each tuple containing the name and the yacs type of the port
+        # thus we need to convert c++ types to yacs types  (we use for that the cpp2yacs_mapping table
+        inports=[]
+        for i in range( len(service_definition[serv]["inports"]) ):
+            inports.append( [service_definition[serv]["inports"][i][0], cpp2yacs_mapping[service_definition[serv]["inports"][i][1]] ] )
+        outports=[]
+        for i in range( len(service_definition[serv]["outports"]) ):
+            outports.append( [service_definition[serv]["outports"][i][0], cpp2yacs_mapping[service_definition[serv]["outports"][i][1]] ] )
+
+        Return="void"
+        if service_definition[serv]["ret"] != "void":
+            Return=cpp2yacs_mapping[service_definition[serv]["ret"]]
+
+        # find out if component uses medmem types and/or medcoupling types
+        for (argname,argtype) in inports + outports + [("return",Return)]:
+            if moduleTypes[argtype]=="MED":
+                if argtype.count("Coupling")>0:
+                    self.use_medcoupling=True
+                else:
+                    self.use_medmem=True
+                break
+
+        code=service_definition[serv]["impl"]
+        if debug:
+            print "service : ",serv
+            print "  inports  -> ",service_definition[serv]["inports"]
+            print "  converted inports  -> ",inports
+            print "  outports -> ",service_definition[serv]["outports"]
+            print "  converted outports  -> ",outports
+            print "  Return  -> ",service_definition[serv]["ret"]
+            print "  converted Return  -> ",Return
+
+        services.append(Service(serv, 
+           inport=inports, 
+           outport=outports,
+           ret=Return, 
+           defs="", 
+           body=code,
+           ) )
+        self.thread_func_decl.append(service_definition[serv]["thread_func_decl"])
+        self.thread_str_decl.append(service_definition[serv]["thread_str_decl"])
+    Includes="-I${"+name+"CPP_ROOT_DIR}/include"
+    Libs="-L${"+name+"CPP_ROOT_DIR}/lib -l"+cpplibname
+    Compodefs=""
+    Inheritedclass=""
+    self.inheritedconstructor=""
+    Compodefs="""
+#include CORBA_SERVER_HEADER(MEDCouplingCorbaServantTest)
+#include "MPIMEDCouplingFieldDoubleServant.hxx"
+"""
+
+    Component.__init__(self, name, services, impl="CPP", libs=Libs,
+                             rlibs="", includes=Includes, kind="lib",
+                             sources=None,inheritedclass=Inheritedclass,
+                             compodefs=Compodefs)
+
+  def makeCompo(self, gen):
+    """generate files for C++ component
+
+       return a dict where key is the file name and value is the content of the file
+    """
+    cxxfile = "%s_i.cxx" % self.name
+    hxxfile = "%s_i.hxx" % self.name
+    return {"Makefile.am":gen.makeMakefile(self.getMakefileItems(gen)),
+            cxxfile:self.makecxx(gen),
+            hxxfile:self.makehxx(gen)
+           }
+
+  def getMakefileItems(self,gen):
+      makefileItems={"header":"""
+include $(top_srcdir)/adm_local/make_common_starter.am
+
+"""}
+      makefileItems["lib_LTLIBRARIES"]=["lib"+self.name+"Engine.la"]
+      makefileItems["salomeinclude_HEADERS"]=["%s_i.hxx" % self.name]
+      makefileItems["body"]=compoMakefile.substitute(module=gen.module.name,
+                                                     component=self.name,
+                                                     libs=self.libs,
+                                                     includes=self.includes)
+      return makefileItems
+
+  def makehxx(self, gen):
+    """return a string that is the content of .hxx file
+    """
+    services = []
+    for serv in self.services:
+      service = "    %s %s(" % (corba_rtn_type(serv.ret,gen.module.name),serv.name)
+      service = service+gen.makeArgs(serv)+") throw (SALOME::SALOME_Exception);"
+      services.append(service)
+    servicesdef = "\n".join(services)
+
+    inheritedclass=self.inheritedclass
+    thread_func_decl="\n".join(self.thread_func_decl)
+    thread_str_decl="\n".join(self.thread_str_decl)
+    if debug:
+        print "thread_func_decl : "
+        print thread_func_decl
+        print "thread_str_decl : "
+        print thread_str_decl
+
+    if self.inheritedclass:
+      inheritedclass= " public virtual " + self.inheritedclass + ","
+
+    return hxxCompo.substitute(component=self.name, module=gen.module.name, thread_func_decl=thread_func_decl,
+                               thread_str_decl=thread_str_decl, servicesdef=servicesdef, inheritedclass=inheritedclass,
+                               compodefs=self.compodefs)
+
+  def makecxx(self, gen, exe=0):
+    """return a string that is the content of .cxx file
+    """
+    services = []
+    inits = []
+    defs = []
+    for serv in self.services:
+      defs.append(serv.defs)
+      service = cxxService.substitute(component=self.name, service=serv.name,ret=corba_rtn_type(serv.ret,gen.module.name),
+                                      parameters=gen.makeArgs(serv),
+                                      body=serv.body % {"module":gen.module.name+"_ORB"} )
+      services.append(service)
+    return cxxCompo.substitute(component=self.name, cxx_include_file=self.hxxfile,
+                               inheritedconstructor=self.inheritedconstructor,
+                               servicesdef="\n".join(defs),
+                               servicesimpl="\n".join(services),
+                               thread_impl=self.thread_impl % {"module":gen.module.name} )
+
index c877ab971d1add2dcf7d6e24fde5123e1e450c61..9fccfc92003eea1bd8d1834baf4b70a040f9d1af 100644 (file)
@@ -69,7 +69,7 @@ idldefs="""
 makefiledefs="""
 #module MED
 MED_IDL_INCLUDES = -I$(MED_ROOT_DIR)/idl/salome
-MED_INCLUDES= -I${MED2HOME}/include -I${MED_ROOT_DIR}/include/salome -I${HDF5HOME}/include
+MED_INCLUDES= -I${MED2HOME}/include -I${MED_ROOT_DIR}/include/salome -DH5_USE_16_API -I${HDF5HOME}/include
 MED_IDL_LIBS= -L$(MED_ROOT_DIR)/lib/salome -lSalomeIDLMED
 MED_LIBS= -L${MED2HOME}/lib -lmed -L${HDF5HOME}/lib -lhdf5 -L${MED_ROOT_DIR}/lib/salome -lSalomeIDLMED -lMEDClientcmodule -lmedcouplingcorba -lmedcouplingclient 
 SALOME_LIBS += ${MED_LIBS}
index fb9bf08bc626a01e40a07a4bc8443bfbf2f99663..cd7c5daab3a1277ea089a7ad92f46105886de866 100644 (file)
@@ -132,6 +132,7 @@ add_type("SALOME_MED/SUPPORT", "SALOME_MED::SUPPORT_ptr", "SALOME_MED::SUPPORT_o
 add_type("SALOME_MED/FIELD", "SALOME_MED::FIELD_ptr", "SALOME_MED::FIELD_out", "MED", "SALOME_MED::FIELD", "SALOME_MED::FIELD_ptr")
 add_type("SALOME_MED/FIELDDOUBLE", "SALOME_MED::FIELDDOUBLE_ptr", "SALOME_MED::FIELDDOUBLE_out", "MED", "SALOME_MED::FIELDDOUBLE", "SALOME_MED::FIELDDOUBLE_ptr")
 add_type("SALOME_MED/FIELDINT", "SALOME_MED::FIELDINT_ptr", "SALOME_MED::FIELDINT_out", "MED", "SALOME_MED::FIELDINT", "SALOME_MED::FIELDINT_ptr")
-add_type("SALOME/Matrix", "SALOME::Matrix_ptr", "SALOME::Matrix_out", "", "SALOME::Matrix", "SALOME::Matrix_ptr")
+add_type("SALOME/Matrix", "SALOME::Matrix_ptr", "SALOME::Matrix_out", "MED", "SALOME::Matrix", "SALOME::Matrix_ptr")
 add_type("SALOME_MED/MEDCouplingFieldDoubleCorbaInterface", "SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr", "SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_out", "MED", "SALOME_MED::MEDCouplingFieldDoubleCorbaInterface", "SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr")
+add_type("SALOME_MED/MPIMEDCouplingFieldDoubleCorbaInterface", "SALOME_MED::MPIMEDCouplingFieldDoubleCorbaInterface_ptr", "SALOME_MED::MPIMEDCouplingFieldDoubleCorbaInterface_out", "MED", "SALOME_MED::MPIMEDCouplingFieldDoubleCorbaInterface", "SALOME_MED::MPIMEDCouplingFieldDoubleCorbaInterface_ptr")
 add_type("SALOME_MED/MEDCouplingUMeshCorbaInterface", "SALOME_MED::MEDCouplingUMeshCorbaInterface_ptr", "SALOME_MED::MEDCouplingUMeshCorbaInterface_out", "MED", "SALOME_MED::MEDCouplingUMeshCorbaInterface", "SALOME_MED::MEDCouplingUMeshCorbaInterface_ptr")
index 8fa5a25d512c14fb22def35103cb9a4e1ed83b59..74d962233db9c16b6aa96903bca1b348d7894f7d 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -22,4 +22,5 @@ setup(name='YACSGEN',
       version='6.3.1',
       author='C. Caremoli',
       packages=['module_generator'],
+      scripts=['script/hxx2salome.py',]
      )