Salome HOME
Python3 porting for Examples.
[tools/yacsgen.git] / module_generator / cpp_tmpl.py
1 # Copyright (C) 2009-2016  EDF R&D
2 #
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
7 #
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 # Lesser General Public License for more details.
12 #
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 #
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 #
19
20 try:
21   from string import Template
22 except:
23   from module_generator.compat import Template,set
24
25 cxxCompo="""
26 #include "${component}.hxx"
27 #include <string>
28 #include <unistd.h>
29
30 #include <Calcium.hxx>
31 #include <CalciumException.hxx>
32 ${CalciumInterface}
33 #include <signal.h>
34 #include <SALOME_NamingService.hxx>
35 #include <Utils_SALOME_Exception.hxx>
36 #include <pthread.h>
37 #include <execinfo.h>
38
39 #define BUILD_EXE ${exe}
40
41 typedef void (*sighandler_t)(int);
42 sighandler_t setsig(int sig, sighandler_t handler)
43 {
44   struct sigaction context, ocontext;
45   context.sa_handler = handler;
46   sigemptyset(&context.sa_mask);
47   context.sa_flags = 0;
48   if (sigaction(sig, &context, &ocontext) == -1)
49     return SIG_ERR;
50   return ocontext.sa_handler;
51 }
52
53 static void AttachDebugger()
54 {
55   void *array[20];
56   size_t size=20;
57   char **strings;
58   size_t i;
59   std::string _what;
60   size = backtrace (array, size);
61   strings = backtrace_symbols (array, size);
62   for (i = 0; i < size; i++)
63      _what=_what+strings[i]+ '\\n';
64   free (strings);
65
66   std::cerr << pthread_self() << std::endl;
67   std::cerr << _what << std::endl;
68
69   if(getenv ("DEBUGGER"))
70     {
71       std::stringstream exec;
72 #if BUILD_EXE
73       exec << "$$DEBUGGER " << "${exe_path} " << getpid() << "&";
74 #else
75       exec << "$$DEBUGGER SALOME_Container " << getpid() << "&";
76 #endif
77       std::cerr << exec.str() << std::endl;
78       system(exec.str().c_str());
79       while(1);
80     }
81 }
82
83 static void THandler(int theSigId)
84 {
85   std::cerr << "SIGSEGV: "  << std::endl;
86   AttachDebugger();
87   //to exit or not to exit
88   _exit(1);
89 }
90
91 static void terminateHandler(void)
92 {
93   std::cerr << "Terminate: not managed exception !"  << std::endl;
94   AttachDebugger();
95   throw SALOME_Exception("Terminate: not managed exception !");
96 }
97
98 static void unexpectedHandler(void)
99 {
100   std::cerr << "Unexpected: unexpected exception !"  << std::endl;
101   AttachDebugger();
102   throw SALOME_Exception("Unexpected: unexpected exception !");
103 }
104
105
106 #define  _(A,B)   A##B
107 #ifdef _WIN32
108 #define F_FUNC(lname,uname) __stdcall uname
109 #define F_CALL(lname,uname) uname
110 #define STR_PSTR(str)       char *str, int _(Len,str)
111 #define STR_PLEN(str)
112 #define STR_PTR(str)        str
113 #define STR_LEN(str)        _(Len,str)
114 #define STR_CPTR(str)        str,strlen(str)
115 #define STR_CLEN(str)
116 #else
117 #define F_FUNC(lname,uname) _(lname,_)        /* Fortran function name */
118 #define F_CALL(lname,uname) _(lname,_)        /* Fortran function call */
119 #define STR_PSTR(str)       char *str         /* fortran string arg pointer */
120 #define STR_PLEN(str)       , int _(Len,str)  /* fortran string arg length */
121 #define STR_PTR(str)        str               /* fortran string pointer */
122 #define STR_LEN(str)        _(Len,str)        /* fortran string length */
123 #define STR_CPTR(str)        str              /* fortran string calling arg pointer */
124 #define STR_CLEN(str)       , strlen(str)     /* fortran string calling arg length */
125 #endif
126
127 //DEFS
128 ${servicesdef}
129 //ENDDEF
130
131 #include <calcium.h>
132
133 extern "C" void cp_exit(int err);
134
135 extern "C" void F_FUNC(cpexit,CPEXIT)(int *err)
136 {
137   if(*err==-1)
138     _exit(-1);
139   else
140     cp_exit(*err);
141 }
142
143 using namespace std;
144
145 //! Constructor for component "${component}" instance
146 /*!
147  *
148  */
149 ${component}_i::${component}_i(CORBA::ORB_ptr orb,
150                      PortableServer::POA_ptr poa,
151                      PortableServer::ObjectId * contId,
152                      const char *instanceName,
153                      const char *interfaceName)
154           : Superv_Component_i(orb, poa, contId, instanceName, interfaceName)
155 {
156 #if BUILD_EXE
157   setsig(SIGSEGV,&THandler);
158   set_terminate(&terminateHandler);
159   set_unexpected(&unexpectedHandler);
160 #endif
161   _thisObj = this ;
162   _id = _poa->activate_object(_thisObj);
163 }
164
165 ${component}_i::${component}_i(CORBA::ORB_ptr orb,
166                      PortableServer::POA_ptr poa,
167                      Engines::Container_ptr container,
168                      const char *instanceName,
169                      const char *interfaceName)
170           : Superv_Component_i(orb, poa, container, instanceName, interfaceName)
171 {
172 #if BUILD_EXE
173   setsig(SIGSEGV,&THandler);
174   set_terminate(&terminateHandler);
175   set_unexpected(&unexpectedHandler);
176 #endif
177   _thisObj = this ;
178   _id = _poa->activate_object(_thisObj);
179 }
180
181 //! Destructor for component "${component}" instance
182 ${component}_i::~${component}_i()
183 {
184 }
185
186 void ${component}_i::destroy()
187 {
188 #if BUILD_EXE
189   _remove_ref();
190   if(!CORBA::is_nil(_orb))
191     _orb->shutdown(0);
192 #else
193   Engines_Component_i::destroy();
194 #endif
195 }
196
197 //! Register datastream ports for a component service given its name
198 /*!
199  *  \param service_name : service name
200  *  \\return true if port registering succeeded, false if not
201  */
202 CORBA::Boolean
203 ${component}_i::init_service(const char * service_name) {
204   CORBA::Boolean rtn = false;
205   string s_name(service_name);
206 ${initservice}
207   return rtn;
208 }
209
210 ${servicesimpl}
211
212 extern "C"
213 {
214   PortableServer::ObjectId * ${component}Engine_factory( CORBA::ORB_ptr orb,
215                                                     PortableServer::POA_ptr poa,
216                                                     PortableServer::ObjectId * contId,
217                                                     const char *instanceName,
218                                                     const char *interfaceName)
219   {
220     MESSAGE("PortableServer::ObjectId * ${component}Engine_factory()");
221     ${component}_i * myEngine = new ${component}_i(orb, poa, contId, instanceName, interfaceName);
222     return myEngine->getId() ;
223   }
224   void yacsinit()
225   {
226     int argc=0;
227     char *argv=0;
228     CORBA::ORB_var orb = CORBA::ORB_init( argc , &argv ) ;
229     PortableServer::POAManager_var pman;
230     CORBA::Object_var obj;
231     try
232       {
233         SALOME_NamingService * salomens = new SALOME_NamingService(orb);
234         obj = orb->resolve_initial_references("RootPOA");
235         PortableServer::POA_var  poa = PortableServer::POA::_narrow(obj);
236         PortableServer::POAManager_var pman = poa->the_POAManager();
237         std::string containerName(getenv("SALOME_CONTAINERNAME"));
238         std::string instanceName(getenv("SALOME_INSTANCE"));
239         obj=orb->string_to_object(getenv("SALOME_CONTAINER"));
240         Engines::Container_var container = Engines::Container::_narrow(obj);
241         ${component}_i * myEngine = new ${component}_i(orb, poa, container, instanceName.c_str(), "${component}");
242         pman->activate();
243         obj=myEngine->POA_${module}_ORB::${component}::_this();
244         Engines::EngineComponent_var component = Engines::EngineComponent::_narrow(obj);
245         string component_registerName = containerName + "/" + instanceName;
246         salomens->Register(component,component_registerName.c_str());
247         orb->run();
248         orb->destroy();
249       }
250     catch(CORBA::Exception&)
251       {
252         std::cerr << "Caught CORBA::Exception."<< std::endl;
253       }
254     catch(std::exception& exc)
255       {
256         std::cerr << "Caught std::exception - "<<exc.what() << std::endl;
257       }
258     catch(...)
259       {
260         std::cerr << "Caught unknown exception." << std::endl;
261       }
262   }
263
264   void F_FUNC(yacsinit,YACSINIT)()
265   {
266     yacsinit();
267   }
268 }
269 """
270 cxxCompo=Template(cxxCompo)
271
272 hxxCompo="""
273 #ifndef _${component}_HXX_
274 #define _${component}_HXX_
275
276 #include <SALOME_Component.hh>
277 #include "Superv_Component_i.hxx"
278 #include "${module}.hh"
279
280 //COMPODEFS
281 ${compodefs}
282 //ENDDEF
283
284 class ${component}_i: public virtual POA_${module}_ORB::${component},
285                       ${inheritedclass} public virtual Superv_Component_i
286 {
287   public:
288     ${component}_i(CORBA::ORB_ptr orb, PortableServer::POA_ptr poa,
289               PortableServer::ObjectId * contId,
290               const char *instanceName, const char *interfaceName);
291     ${component}_i(CORBA::ORB_ptr orb, PortableServer::POA_ptr poa,
292               Engines::Container_ptr container,
293               const char *instanceName, const char *interfaceName);
294     virtual ~${component}_i();
295     void destroy();
296     CORBA::Boolean init_service(const char * service_name);
297 ${servicesdef}
298 };
299
300 extern "C"
301 {
302     PortableServer::ObjectId * ${component}Engine_factory( CORBA::ORB_ptr orb,
303                                                       PortableServer::POA_ptr poa,
304                                                       PortableServer::ObjectId * contId,
305                                                       const char *instanceName,
306                                                       const char *interfaceName);
307     void yacsinit();
308 }
309 #endif
310
311 """
312 hxxCompo=Template(hxxCompo)
313
314 cxxService="""
315 void ${component}_i::${service}(${parameters})
316 {
317   beginService("${component}_i::${service}");
318   Superv_Component_i * component = dynamic_cast<Superv_Component_i*>(this);
319   //char       nom_instance[INSTANCE_LEN];
320   //int info = cp_cd(component,nom_instance);
321   try
322     {
323 //BODY
324 ${body}
325 //ENDBODY
326       //cp_fin(component,CP_ARRET);
327     }
328   catch ( const CalciumException & ex)
329     {
330       std::cerr << ex.what() << std::endl;
331       //cp_fin(component,CP_ARRET);
332       SALOME::ExceptionStruct es;
333       es.text=CORBA::string_dup(ex.what());
334       es.type=SALOME::INTERNAL_ERROR;
335       throw SALOME::SALOME_Exception(es);
336     }
337   catch ( const SALOME_Exception & ex)
338     {
339       //cp_fin(component,CP_ARRET);
340       SALOME::ExceptionStruct es;
341       es.text=CORBA::string_dup(ex.what());
342       es.type=SALOME::INTERNAL_ERROR;
343       throw SALOME::SALOME_Exception(es);
344     }
345   catch ( const SALOME::SALOME_Exception & ex)
346     {
347       //cp_fin(component,CP_ARRET);
348       throw;
349     }
350   catch ( const std::exception& ex)
351     {
352       //std::cerr << typeid(ex).name() << std::endl;
353       SALOME::ExceptionStruct es;
354       es.text=CORBA::string_dup(ex.what());
355       es.type=SALOME::INTERNAL_ERROR;
356       throw SALOME::SALOME_Exception(es);
357     }
358   catch (...)
359     {
360       std::cerr << "unknown exception" << std::endl;
361 #if BUILD_EXE
362       _exit(-1);
363 #endif
364       //cp_fin(component,CP_ARRET);
365       SALOME::ExceptionStruct es;
366       es.text=CORBA::string_dup(" unknown exception");
367       es.type=SALOME::INTERNAL_ERROR;
368       throw SALOME::SALOME_Exception(es);
369     }
370   endService("${component}_i::${service}");
371 }
372
373 """
374 cxxService=Template(cxxService)
375
376 initService="""
377   if (s_name == "${service}")
378     {
379       try
380         {
381           //initialization CALCIUM ports IN
382 ${instream}
383           //initialization CALCIUM ports OUT
384 ${outstream}
385         }
386       catch(const PortAlreadyDefined& ex)
387         {
388           std::cerr << "${component}: " << ex.what() << std::endl;
389           //Ports already created : we use them
390         }
391       catch ( ... )
392         {
393           std::cerr << "${component}: unknown exception" << std::endl;
394         }
395       rtn = true;
396     }
397 """
398 initService=Template(initService)
399
400 exeCPP="""#!/bin/sh
401
402 export SALOME_CONTAINER=$$1
403 export SALOME_CONTAINERNAME=$$2
404 export SALOME_INSTANCE=$$3
405
406 ${compoexe}
407 """
408 exeCPP=Template(exeCPP)
409
410 # Makefile
411
412 # CMakeLists.txt in src/<component>
413 # template parameters:
414 #   module : module name
415 #   component : component name
416 #   componentlib : name of the target library
417 #   includes : additional headers, separated by spaces or \n. can be empty
418 #   sources : additional sources, separated by spaces or \n. can be empty
419 #   libs : additional libraries
420 #   find_libs : find_library commands
421 #   target_properties : set_target_properties commands
422 cmake_src_compo_cpp = """
423 # --- options ---
424 # additional include directories
425 INCLUDE_DIRECTORIES(
426   $${KERNEL_INCLUDE_DIRS}
427   $${OMNIORB_INCLUDE_DIR}
428   $${PROJECT_BINARY_DIR}
429   $${PROJECT_BINARY_DIR}/idl
430   ${includes}
431 )
432
433 # --- definitions ---
434 ADD_DEFINITIONS(
435   $${OMNIORB_DEFINITIONS}
436 )
437
438 # find additional libraries
439 ${find_libs}
440
441 # libraries to link to
442 SET(_link_LIBRARIES
443   $${OMNIORB_LIBRARIES}
444   $${KERNEL_SalomeIDLKernel}
445   $${KERNEL_OpUtil}
446   $${KERNEL_SalomeContainer}
447   SalomeIDL${module}
448   ${libs}
449 )
450
451 # --- headers ---
452
453 # header files / no moc processing
454
455 SET(${module}_HEADERS
456   ${component}.hxx
457 )
458
459 # --- sources ---
460
461 # sources / static
462 SET(${module}_SOURCES
463   ${component}.cxx
464   ${sources}
465 )
466
467 # --- rules ---
468
469 ADD_LIBRARY(${componentlib} $${${module}_SOURCES})
470 TARGET_LINK_LIBRARIES(${componentlib} $${_link_LIBRARIES} )
471 ${target_properties}
472 INSTALL(TARGETS ${componentlib} EXPORT $${PROJECT_NAME}TargetGroup DESTINATION $${SALOME_INSTALL_LIBS})
473
474 INSTALL(FILES $${${module}_HEADERS} DESTINATION $${SALOME_INSTALL_HEADERS})
475 """
476 cmake_src_compo_cpp = Template(cmake_src_compo_cpp)