Salome HOME
Merge from V6_main 01/04/2013
[tools/yacsgen.git] / module_generator / cpp_tmpl.py
1 # Copyright (C) 2009-2013  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.
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 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 typedef void (*sighandler_t)(int);
40 sighandler_t setsig(int sig, sighandler_t handler)
41 {
42   struct sigaction context, ocontext;
43   context.sa_handler = handler;
44   sigemptyset(&context.sa_mask);
45   context.sa_flags = 0;
46   if (sigaction(sig, &context, &ocontext) == -1)
47     return SIG_ERR;
48   return ocontext.sa_handler;
49 }
50
51 static void AttachDebugger()
52 {
53   void *array[20];
54   size_t size=20;
55   char **strings;
56   size_t i;
57   std::string _what;
58   size = backtrace (array, size);
59   strings = backtrace_symbols (array, size);
60   for (i = 0; i < size; i++)
61      _what=_what+strings[i]+ '\\n';
62   free (strings);
63
64   std::cerr << pthread_self() << std::endl;
65   std::cerr << _what << std::endl;
66
67   if(getenv ("DEBUGGER"))
68     {
69       std::stringstream exec;
70 #if ${exe}
71       exec << "$$DEBUGGER " << "${exe_path} " << getpid() << "&";
72 #else
73       exec << "$$DEBUGGER SALOME_Container " << getpid() << "&";
74 #endif
75       std::cerr << exec.str() << std::endl;
76       system(exec.str().c_str());
77       while(1);
78     }
79 }
80
81 static void THandler(int theSigId)
82 {
83   std::cerr << "SIGSEGV: "  << std::endl;
84   AttachDebugger();
85   //to exit or not to exit
86   _exit(1);
87 }
88
89 static void terminateHandler(void)
90 {
91   std::cerr << "Terminate: not managed exception !"  << std::endl;
92   AttachDebugger();
93   throw SALOME_Exception("Terminate: not managed exception !");
94 }
95
96 static void unexpectedHandler(void)
97 {
98   std::cerr << "Unexpected: unexpected exception !"  << std::endl;
99   AttachDebugger();
100   throw SALOME_Exception("Unexpected: unexpected exception !");
101 }
102
103
104 #define  _(A,B)   A##B
105 #ifdef _WIN32
106 #define F_FUNC(lname,uname) __stdcall uname
107 #define F_CALL(lname,uname) uname
108 #define STR_PSTR(str)       char *str, int _(Len,str)
109 #define STR_PLEN(str)
110 #define STR_PTR(str)        str
111 #define STR_LEN(str)        _(Len,str)
112 #define STR_CPTR(str)        str,strlen(str)
113 #define STR_CLEN(str)
114 #else
115 #define F_FUNC(lname,uname) _(lname,_)        /* Fortran function name */
116 #define F_CALL(lname,uname) _(lname,_)        /* Fortran function call */
117 #define STR_PSTR(str)       char *str         /* fortran string arg pointer */
118 #define STR_PLEN(str)       , int _(Len,str)  /* fortran string arg length */
119 #define STR_PTR(str)        str               /* fortran string pointer */
120 #define STR_LEN(str)        _(Len,str)        /* fortran string length */
121 #define STR_CPTR(str)        str              /* fortran string calling arg pointer */
122 #define STR_CLEN(str)       , strlen(str)     /* fortran string calling arg length */
123 #endif
124
125 //DEFS
126 ${servicesdef}
127 //ENDDEF
128
129 #include <calcium.h>
130
131 extern "C" void cp_exit(int err);
132
133 extern "C" void F_FUNC(cpexit,CPEXIT)(int *err)
134 {
135   if(*err==-1)
136     _exit(-1);
137   else
138     cp_exit(*err);
139 }
140
141 using namespace std;
142
143 //! Constructor for component "${component}" instance
144 /*!
145  *
146  */
147 ${component}_i::${component}_i(CORBA::ORB_ptr orb,
148                      PortableServer::POA_ptr poa,
149                      PortableServer::ObjectId * contId,
150                      const char *instanceName,
151                      const char *interfaceName)
152           : Superv_Component_i(orb, poa, contId, instanceName, interfaceName)
153 {
154 #if ${exe}
155   setsig(SIGSEGV,&THandler);
156   set_terminate(&terminateHandler);
157   set_unexpected(&unexpectedHandler);
158 #endif
159   _thisObj = this ;
160   _id = _poa->activate_object(_thisObj);
161 }
162
163 ${component}_i::${component}_i(CORBA::ORB_ptr orb,
164                      PortableServer::POA_ptr poa,
165                      Engines::Container_ptr container,
166                      const char *instanceName,
167                      const char *interfaceName)
168           : Superv_Component_i(orb, poa, container, instanceName, interfaceName)
169 {
170 #if ${exe}
171   setsig(SIGSEGV,&THandler);
172   set_terminate(&terminateHandler);
173   set_unexpected(&unexpectedHandler);
174 #endif
175   _thisObj = this ;
176   _id = _poa->activate_object(_thisObj);
177 }
178
179 //! Destructor for component "${component}" instance
180 ${component}_i::~${component}_i()
181 {
182 }
183
184 void ${component}_i::destroy()
185 {
186 #if ${exe}
187   _remove_ref();
188   if(!CORBA::is_nil(_orb))
189     _orb->shutdown(0);
190 #else
191   Engines_Component_i::destroy();
192 #endif
193 }
194
195 //! Register datastream ports for a component service given its name
196 /*!
197  *  \param service_name : service name
198  *  \\return true if port registering succeeded, false if not
199  */
200 CORBA::Boolean
201 ${component}_i::init_service(const char * service_name) {
202   CORBA::Boolean rtn = false;
203   string s_name(service_name);
204 ${initservice}
205   return rtn;
206 }
207
208 ${servicesimpl}
209
210 extern "C"
211 {
212   PortableServer::ObjectId * ${component}Engine_factory( CORBA::ORB_ptr orb,
213                                                     PortableServer::POA_ptr poa,
214                                                     PortableServer::ObjectId * contId,
215                                                     const char *instanceName,
216                                                     const char *interfaceName)
217   {
218     MESSAGE("PortableServer::ObjectId * ${component}Engine_factory()");
219     ${component}_i * myEngine = new ${component}_i(orb, poa, contId, instanceName, interfaceName);
220     return myEngine->getId() ;
221   }
222   void yacsinit()
223   {
224     int argc=0;
225     char *argv=0;
226     CORBA::ORB_var orb = CORBA::ORB_init( argc , &argv ) ;
227     PortableServer::POAManager_var pman;
228     CORBA::Object_var obj;
229     try
230       {
231         SALOME_NamingService * salomens = new SALOME_NamingService(orb);
232         obj = orb->resolve_initial_references("RootPOA");
233         PortableServer::POA_var  poa = PortableServer::POA::_narrow(obj);
234         PortableServer::POAManager_var pman = poa->the_POAManager();
235         std::string containerName(getenv("SALOME_CONTAINERNAME"));
236         std::string instanceName(getenv("SALOME_INSTANCE"));
237         obj=orb->string_to_object(getenv("SALOME_CONTAINER"));
238         Engines::Container_var container = Engines::Container::_narrow(obj);
239         ${component}_i * myEngine = new ${component}_i(orb, poa, container, instanceName.c_str(), "${component}");
240         pman->activate();
241         obj=myEngine->POA_${module}_ORB::${component}::_this();
242         Engines::EngineComponent_var component = Engines::EngineComponent::_narrow(obj);
243         string component_registerName = containerName + "/" + instanceName;
244         salomens->Register(component,component_registerName.c_str());
245         orb->run();
246         orb->destroy();
247       }
248     catch(CORBA::Exception&)
249       {
250         std::cerr << "Caught CORBA::Exception."<< std::endl;
251       }
252     catch(std::exception& exc)
253       {
254         std::cerr << "Caught std::exception - "<<exc.what() << std::endl;
255       }
256     catch(...)
257       {
258         std::cerr << "Caught unknown exception." << std::endl;
259       }
260   }
261
262   void F_FUNC(yacsinit,YACSINIT)()
263   {
264     yacsinit();
265   }
266 }
267 """
268 cxxCompo=Template(cxxCompo)
269
270 hxxCompo="""
271 #ifndef _${component}_HXX_
272 #define _${component}_HXX_
273
274 #include <SALOME_Component.hh>
275 #include "Superv_Component_i.hxx"
276 #include "${module}.hh"
277
278 //COMPODEFS
279 ${compodefs}
280 //ENDDEF
281
282 class ${component}_i: public virtual POA_${module}_ORB::${component},
283                       ${inheritedclass} public virtual Superv_Component_i
284 {
285   public:
286     ${component}_i(CORBA::ORB_ptr orb, PortableServer::POA_ptr poa,
287               PortableServer::ObjectId * contId,
288               const char *instanceName, const char *interfaceName);
289     ${component}_i(CORBA::ORB_ptr orb, PortableServer::POA_ptr poa,
290               Engines::Container_ptr container,
291               const char *instanceName, const char *interfaceName);
292     virtual ~${component}_i();
293     void destroy();
294     CORBA::Boolean init_service(const char * service_name);
295 ${servicesdef}
296 };
297
298 extern "C"
299 {
300     PortableServer::ObjectId * ${component}Engine_factory( CORBA::ORB_ptr orb,
301                                                       PortableServer::POA_ptr poa,
302                                                       PortableServer::ObjectId * contId,
303                                                       const char *instanceName,
304                                                       const char *interfaceName);
305     void yacsinit();
306 }
307 #endif
308
309 """
310 hxxCompo=Template(hxxCompo)
311
312 cxxService="""
313 void ${component}_i::${service}(${parameters})
314 {
315   beginService("${component}_i::${service}");
316   Superv_Component_i * component = dynamic_cast<Superv_Component_i*>(this);
317   //char       nom_instance[INSTANCE_LEN];
318   //int info = cp_cd(component,nom_instance);
319   try
320     {
321 //BODY
322 ${body}
323 //ENDBODY
324       //cp_fin(component,CP_ARRET);
325     }
326   catch ( const CalciumException & ex)
327     {
328       std::cerr << ex.what() << std::endl;
329       //cp_fin(component,CP_ARRET);
330       SALOME::ExceptionStruct es;
331       es.text=CORBA::string_dup(ex.what());
332       es.type=SALOME::INTERNAL_ERROR;
333       throw SALOME::SALOME_Exception(es);
334     }
335   catch ( const SALOME_Exception & ex)
336     {
337       //cp_fin(component,CP_ARRET);
338       SALOME::ExceptionStruct es;
339       es.text=CORBA::string_dup(ex.what());
340       es.type=SALOME::INTERNAL_ERROR;
341       throw SALOME::SALOME_Exception(es);
342     }
343   catch ( const SALOME::SALOME_Exception & ex)
344     {
345       //cp_fin(component,CP_ARRET);
346       throw;
347     }
348   catch ( const std::exception& ex)
349     {
350       //std::cerr << typeid(ex).name() << std::endl;
351       SALOME::ExceptionStruct es;
352       es.text=CORBA::string_dup(ex.what());
353       es.type=SALOME::INTERNAL_ERROR;
354       throw SALOME::SALOME_Exception(es);
355     }
356   catch (...)
357     {
358       std::cerr << "unknown exception" << std::endl;
359 #if ${exe}
360       _exit(-1);
361 #endif
362       //cp_fin(component,CP_ARRET);
363       SALOME::ExceptionStruct es;
364       es.text=CORBA::string_dup(" unknown exception");
365       es.type=SALOME::INTERNAL_ERROR;
366       throw SALOME::SALOME_Exception(es);
367     }
368   endService("${component}_i::${service}");
369 }
370
371 """
372 cxxService=Template(cxxService)
373
374 initService="""
375   if (s_name == "${service}")
376     {
377       try
378         {
379           //initialization CALCIUM ports IN
380 ${instream}
381           //initialization CALCIUM ports OUT
382 ${outstream}
383         }
384       catch(const PortAlreadyDefined& ex)
385         {
386           std::cerr << "${component}: " << ex.what() << std::endl;
387           //Ports already created : we use them
388         }
389       catch ( ... )
390         {
391           std::cerr << "${component}: unknown exception" << std::endl;
392         }
393       rtn = true;
394     }
395 """
396 initService=Template(initService)
397
398 exeCPP="""#!/bin/sh
399
400 export SALOME_CONTAINER=$$1
401 export SALOME_CONTAINERNAME=$$2
402 export SALOME_INSTANCE=$$3
403
404 ${compoexe}
405 """
406 exeCPP=Template(exeCPP)
407
408 # Makefile
409
410 compoMakefile="""
411 lib${component}Engine_la_SOURCES      = ${component}.cxx ${sources}
412 nodist_lib${component}Engine_la_SOURCES =
413 lib${component}Engine_la_CXXFLAGS = -I$$(top_builddir)/idl  $$(SALOME_INCLUDES) ${includes}
414 lib${component}Engine_la_FFLAGS = $$(SALOME_INCLUDES) -fexceptions ${includes}
415 lib${component}Engine_la_LIBADD   = ${libs} -L$$(top_builddir)/idl -lSalomeIDL${module} $${SALOME_LIBS} $$(FLIBS)
416 lib${component}Engine_la_LDFLAGS = ${rlibs}
417 """
418 compoMakefile=Template(compoMakefile)
419
420 compoEXEMakefile="""
421 lib${component}Exelib_la_SOURCES      = ${component}.cxx
422 nodist_lib${component}Exelib_la_SOURCES =
423 lib${component}Exelib_la_CXXFLAGS = -I$$(top_builddir)/idl  $$(SALOME_INCLUDES) ${includes}
424 lib${component}Exelib_la_FFLAGS = $$(SALOME_INCLUDES) -fexceptions ${includes}
425 lib${component}Exelib_la_LIBADD   = ${libs} -L$$(top_builddir)/idl -lSalomeIDL${module} $${SALOME_LIBS} $$(FLIBS)
426 lib${component}Exelib_la_LDFLAGS = ${rlibs}
427 """
428 compoEXEMakefile=Template(compoEXEMakefile)