Salome HOME
Copyright update: 2016
[tools/yacsgen.git] / module_generator / fcompo.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 from gener import Component
21 from cppcompo import CPPComponent
22
23 import platform
24 archi = platform.architecture()[0]
25
26 if archi == "64bit":
27   f77Types = {"double":"double *", "long":"int *", "string":"const char *"}
28 else:
29   f77Types = {"double":"double *", "long":"long *", "string":"const char *"}
30
31 class F77Component(CPPComponent):
32   """
33    A :class:`F77Component` instance represents a Fortran SALOME component with services given as a list of :class:`Service`
34    instances with the parameter *services*.
35
36    :param name: gives the name of the component.
37    :type name: str
38    :param services: the list of services (:class:`Service`) of the component.
39    :param kind: If it is given and has the value "exe", the component will be built as a standalone
40       component (executable or shell script). The default is to build the component as a dynamic library.
41    :param libs: list of the additional libraries. see *Library* class.
42       If you want to add "libmylib.so", installed in "/path/to/lib" you should use:
43          libs=[Library(name="mylib", path="/path/to/lib")]
44       For more advanced features, see the documentation of cmake / FIND_LIBRARY
45    :param rlibs: space-separated list specifying the rpath to use in installed targets
46    :param sources: gives all the external source files to add in the compilation step (list of paths).
47    :param exe_path: is only used when kind is "exe" and gives the path to the standalone component.
48
49    For example, the following call defines a Fortran component named "mycompo" with one service s1 (it must have been defined before).
50    This component is implemented as a dynamic library linked with a user's library "mylib"::
51
52       >>> c1 = module_generator.F77Component('mycompo', services=[s1,],
53                                                        libs=[[Library(name="mylib", path=mydir)])
54
55   """
56   def __init__(self, name, services=None, libs=[], rlibs="", 
57                      kind="lib", exe_path=None, sources=None):
58     CPPComponent.__init__(self, name, services, libs=libs, rlibs=rlibs, 
59                                 kind=kind, exe_path=exe_path, sources=sources)
60     self.impl = "F77"
61
62   def makebody(self):
63     """generate definitions (defs attribute of services) et bodys (body attribute of services)"""
64     for serv in self.services:
65       #defs generation
66       params=[]
67       if serv.instream or serv.outstream:
68         params = ["void *compo"]
69       strparams = []
70       for name, typ in serv.inport:
71         if typ == "file":continue #files are not passed through service interface
72         if typ == "string":
73           params.append("const STR_PSTR(%s)"%name)
74           strparams.append("STR_PLEN(%s)"%name)
75         else:
76           params.append("%s %s" % (f77Types[typ], name))
77       for name, typ in serv.outport:
78         if typ == "file":continue #files are not passed through service interface
79         if typ == "string":
80           params.append("const STR_PSTR(%s)"%name)
81           strparams.append("STR_PLEN(%s)"%name)
82         else:
83           params.append("%s %s" % (f77Types[typ], name))
84       args = ','.join(params)+" " + " ".join(strparams)
85       serv.defs = serv.defs+'\nextern "C" void F_FUNC(%s,%s)(%s);' % (serv.name.lower(), serv.name.upper(), args)
86
87       #body generation
88       params=[]
89       if serv.instream or serv.outstream:
90         params = ["&component"]
91       strparams = []
92       strallocs = []
93       #length allocated for out string
94       lstr = 20
95       for name, typ in serv.inport:
96         if typ == "file":continue #files are not passed through service interface
97         if typ == "string":
98           params.append("STR_CPTR(%s)" % name)
99           strparams.append("STR_CLEN(%s)"%name)
100         else:
101           params.append("&%s" % name)
102       for name, typ in serv.outport:
103         if typ == "file":continue #files are not passed through service interface
104         if typ == "string":
105           params.append("STR_CPTR(%s.ptr())" % name)
106           strparams.append("STR_CLEN(%s.ptr())"%name)
107           strallocs.append('%s=CORBA::string_dup("%s");' %(name, " "*lstr))
108         else:
109           params.append("&%s" % name)
110       serv.body = '\n'.join(strallocs)+'\n'+serv.body
111       args = ','.join(params)+" " + " ".join(strparams)
112       serv.body = serv.body+"\n   F_CALL(%s,%s)(%s);" % (serv.name.lower(), serv.name.upper(), args)
113
114   def makeCompo(self, gen):
115     """build a dictionary that defines component files
116        dictionary key = file name
117        dictionary value = file content or dictionary defining subdirectory content
118     """
119     self.makebody()
120     return CPPComponent.makeCompo(self, gen)