-import re, os
+"""
+ This module defines the ASTERComponent class for ASTER component generation
+ An ASTER component comes in 3 flavors :
+ - implemented as a dynamic library (kind='lib')
+ - implemented as a standalone component (kind='exe')
+ - implemented as a specific container (kind='cexe')
+"""
+import re, os, sys
from gener import Component, Invalid, makedirs
def __init__(self, name, services=None, libs="", rlibs="", aster_dir="",
python_path=None, argv=None, kind="lib", exe_path=None,
asrun=None, export_extras=""):
+ """initialise component attributes"""
self.aster_dir = aster_dir
self.python_path = python_path or []
self.argv = argv or []
rlibs=rlibs, kind=kind)
def validate(self):
+ """validate the component definition"""
Component.validate(self)
if not self.aster_dir:
raise Invalid("aster_dir must be defined for component %s" % self.name)
kinds = ("lib", "cexe", "exe")
if self.kind not in kinds:
- raise Invalid("kind must be one of %s" % kinds)
+ raise Invalid("kind must be one of %s for component %s" % (kinds,self.name))
if self.kind == "lib" and not self.python_path:
raise Invalid("python_path must be defined for component %s" % self.name)
if self.kind == "cexe" :
if not self.exe_path:
raise Invalid("exe_path must be defined for component %s" % self.name)
- if not self.asrun:
- raise Invalid("asrun must be defined for component %s" % self.name)
- if not os.path.exists(self.asrun):
- raise Invalid("asrun does not exist for component %s" % self.name)
if self.kind == "exe" :
if not self.exe_path:
raise Invalid("exe_path must be defined for component %s" % self.name)
- if not self.asrun:
- raise Invalid("asrun must be defined for component %s" % self.name)
- if not os.path.exists(self.asrun):
- raise Invalid("asrun does not exist for component %s" % self.name)
+ #Si un port de nom jdc n'est pas defini dans la liste des inports du service,
+ #on en ajoute un de type string en premiere position
for serv in self.services:
- #on ajoute un inport string de nom jdc en premier dans la liste des ports de chaque service
- serv.inport.insert(0, ("jdc", "string"))
+ found=False
+ for port_name,port_type in serv.inport:
+ if port_name == "jdc":
+ found=True
+ break
+ if not found:
+ serv.inport.insert(0, ("jdc", "string"))
def makeCompo(self, gen):
+ """drive the generation of SALOME module files and code files
+ depending on the choosen component kind
+ """
filename = "%s.py" % self.name
#on suppose que les composants ASTER sont homogenes (utilisent meme install)
gen.aster = self.aster_dir
if self.kind == "lib":
- return {"Makefile.am":astercompoMakefile.substitute(module=gen.module.name,
+ return {"Makefile.am":astercompoMakefile.substitute(module=gen.module.name,
component=self.name),
filename:self.makeaster(gen)}
elif self.kind == "cexe":
#creation de l'installation aster dans exe_path
- self.makecexepath(gen)
- return {"Makefile.am":astercexeMakefile.substitute(module=gen.module.name,
- component=self.name),
- filename:self.makecexeaster(gen)}
+ fdict=self.makecexepath(gen)
+ d= {"Makefile.am":astercexeMakefile.substitute(module=gen.module.name,
+ component=self.name),
+ self.name+".exe":cexe.substitute(compoexe=self.exe_path),
+ filename:self.makecexeaster(gen)
+ }
+ d.update(fdict)
+ return d
elif self.kind == "exe":
#creation de l'installation aster dans exe_path
- self.makeexepath(gen)
- return {"Makefile.am":asterexeMakefile.substitute(module=gen.module.name,
+ fdict=self.makeexepath(gen)
+ d= {"Makefile.am":asterexeMakefile.substitute(module=gen.module.name,
component=self.name),
- self.name+".exe":exeaster.substitute(export=os.path.join(self.exe_path, "make_etude.export"), asrun=self.asrun),
- self.name+"_module.py":self.makeexeaster(gen)}
+ self.name+".exe":exeaster.substitute(compoexe=self.exe_path),
+ self.name+"_module.py":self.makeexeaster(gen)
+ }
+ d.update(fdict)
+ return d
def makeexepath(self, gen):
- makedirs(self.exe_path)
+ """standalone component: generate files for calculation code"""
#patch to E_SUPERV.py
fil = open(os.path.join(self.aster_dir, "bibpyt", "Execution", "E_SUPERV.py"))
esuperv = fil.read()
- esuperv = re.sub("j=self.JdC", "self.jdc=j=self.JdC", esuperv)
fil.close()
- #utilisation d'un programme principal python different
+ esuperv = re.sub("def Execute\(self\)", "def Execute(self, params)", esuperv)
+ esuperv = re.sub("j=self.JdC", "self.jdc=j=self.JdC", esuperv)
+ esuperv = re.sub("\*\*args", "context_ini=params, **args", esuperv)
+ esuperv = re.sub("def main\(self\)", "def main(self,params={})", esuperv)
+ esuperv = re.sub("return self.Execute\(\)", "return self.Execute(params)", esuperv)
+ #use a specific main program (modification of config.txt file)
fil = open(os.path.join(self.aster_dir, "config.txt"))
config = fil.read()
- config = re.sub("Execution\/E_SUPERV.py", os.path.join(self.exe_path, "aster_component.py"), config)
fil.close()
+ config = re.sub("profile.sh", os.path.join(self.aster_dir, "profile.sh"), config)
- gen.makeFiles({
- "aster_component.py":component.substitute(component=self.name),
- "make_etude.export":make_etude.substitute(config=os.path.join(self.exe_path, "config.txt"),
- comm=os.path.join(self.exe_path, self.name+".comm"),
- extras=self.export_extras),
- self.name+".comm":comm,
- "config.txt":config,
- "profile.sh":os.path.join(self.aster_dir, "profile.sh"),
- "E_SUPERV.py":esuperv,
- }, self.exe_path)
+ path=os.path.join(os.path.abspath(gen.module.prefix),'lib',
+ 'python%s.%s' % (sys.version_info[0], sys.version_info[1]),
+ 'site-packages','salome','%s_component.py'%self.name)
+ config = re.sub("Execution\/E_SUPERV.py", path, config)
+
+ fdict= {
+ "%s_component.py"%self.name:component.substitute(component=self.name),
+ "%s_config.txt" % self.name:config,
+ "E_SUPERV.py":esuperv,
+ }
+ return fdict
def makecexepath(self, gen):
- makedirs(self.exe_path)
+ """specific container: generate files"""
#patch to E_SUPERV.py
fil = open(os.path.join(self.aster_dir, "bibpyt", "Execution", "E_SUPERV.py"))
esuperv = fil.read()
- esuperv = re.sub("j=self.JdC", "self.jdc=j=self.JdC", esuperv)
fil.close()
- #utilisation d'un programme principal python different
+ esuperv = re.sub("def Execute\(self\)", "def Execute(self, params)", esuperv)
+ esuperv = re.sub("j=self.JdC", "self.jdc=j=self.JdC", esuperv)
+ esuperv = re.sub("\*\*args", "context_ini=params, **args", esuperv)
+ esuperv = re.sub("def main\(self\)", "def main(self,params={})", esuperv)
+ esuperv = re.sub("return self.Execute\(\)", "return self.Execute(params)", esuperv)
+
+ #use a specific main program
fil = open(os.path.join(self.aster_dir, "config.txt"))
config = fil.read()
- config = re.sub("Execution\/E_SUPERV.py", os.path.join(self.exe_path, "aster_container.py"), config)
fil.close()
- gen.makeFiles({self.name+".exe":cexe.substitute(export=os.path.join(self.exe_path, "make_etude.export"),
- asrun=self.asrun),
- "aster_container.py":container,
- "make_etude.export":make_etude.substitute(config=os.path.join(self.exe_path, "config.txt"),
- comm=os.path.join(self.exe_path, self.name+".comm"),
- extras=self.export_extras),
- self.name+".comm":comm,
- "config.txt":config,
- "profile.sh":os.path.join(self.aster_dir, "profile.sh"),
- "E_SUPERV.py":esuperv,
- }, self.exe_path)
- #make exe executable
- os.chmod(os.path.join(self.exe_path, self.name+".exe"), 0777)
+ config = re.sub("profile.sh", os.path.join(self.aster_dir, "profile.sh"), config)
+ path=os.path.join(os.path.abspath(gen.module.prefix),'lib',
+ 'python%s.%s' % (sys.version_info[0], sys.version_info[1]),
+ 'site-packages','salome','%s_container.py' % self.name)
+ config = re.sub("Execution\/E_SUPERV.py", path, config)
+
+ fdict= {
+ "%s_container.py" % self.name:container,
+ "%s_config.txt" % self.name:config,
+ "E_SUPERV.py":esuperv,
+ }
+ return fdict
def makeexeaster(self, gen):
+ """standalone component: generate SALOME component source"""
services = []
inits = []
defs = []
params = []
datas = []
for name, typ in serv.inport:
+ if typ=="file":continue #files are not passed through service interface
params.append(name)
if typ == "pyobj":
datas.append('"%s":cPickle.loads(%s)' % (name, name))
params = []
datas = []
for name, typ in serv.outport:
+ if typ=="file":continue #files are not passed through service interface
params.append(name)
if typ == "pyobj":
datas.append('cPickle.dumps(j.g_context["%s"],-1)'%name)
aster_dir=self.aster_dir)
def makecexeaster(self, gen):
+ """specific container: generate SALOME component source"""
services = []
inits = []
defs = []
params = []
datas = []
for name, typ in serv.inport:
+ if typ=="file":continue #files are not passed through service interface
params.append(name)
if typ == "pyobj":
datas.append('"%s":cPickle.loads(%s)' % (name, name))
aster_dir=self.aster_dir)
def getImpl(self):
if self.kind == "cexe":
- return "CEXE", os.path.join(self.exe_path, self.name+".exe")
+ return "CEXE", self.name+".exe"
else:
return "SO", ""
def makeaster(self, gen):
+ """library component: generate SALOME component source"""
services = []
inits = []
defs = []
params = []
datas = []
for name, typ in serv.inport:
+ if typ=="file":continue #files are not passed through service interface
params.append(name)
if typ == "pyobj":
datas.append('"%s":cPickle.loads(%s)' % (name, name))
"""
astercompoMakefile=Template(astercompoMakefile)
-astercexeMakefile=astercompoMakefile
+
+astercexeMakefile="""include $$(top_srcdir)/adm_local/make_common_starter.am
+salomepython_PYTHON = ${component}.py ${component}_container.py E_SUPERV.py
+# These files are executable scripts
+dist_salomescript_SCRIPTS= ${component}.exe
+salomeres_DATA = ${component}_config.txt
+"""
+astercexeMakefile=Template(astercexeMakefile)
asterexeMakefile="""include $$(top_srcdir)/adm_local/make_common_starter.am
-salomepython_PYTHON = ${component}_module.py
+salomepython_PYTHON = ${component}_module.py ${component}_component.py E_SUPERV.py
# These files are executable scripts
dist_salomescript_SCRIPTS= ${component}.exe
+salomeres_DATA = ${component}_config.txt
"""
asterexeMakefile=Template(asterexeMakefile)
${servicesdef}
#ENDDEF
+class ExecutionError(Exception):
+ '''General exception during execution'''
+
class ${component}(${module}__POA.${component},dsccalcium.PyDSCComponent,SUPERV):
'''
To be identified as a SALOME component this Python class
${initservice}
return False
+ def interpstring(self,text,args):
+ try:
+ self.jdc.g_context.update(args)
+ CONTEXT.set_current_step(self.jdc)
+ linecache.cache['<string>']=0,None,string.split(text,'\\n'),'<string>'
+ exec text in self.jdc.const_context,self.jdc.g_context
+ CONTEXT.unset_current_step()
+ except EOFError:
+ CONTEXT.unset_current_step()
+ except:
+ CONTEXT.unset_current_step()
+ raise
+
${servicesimpl}
"""
asterCEXEService="""
def ${service}(self,${inparams}):
self.beginService("${component}.${service}")
- if not self.init:
- self.init=1
- ier=self.main()
- j=self.jdc
- self.jdc.g_context.update(${dvars})
try:
- CONTEXT.set_current_step(self.jdc)
- linecache.cache['<string>']=0,0,string.split(jdc,'\\n'),'<string>'
- exec jdc in self.jdc.g_context
- CONTEXT.unset_current_step()
- self.endService("${component}.${service}")
- except EOFError:
+ args=${dvars}
+ if not args.has_key("jdc"):
+ fcomm=open("jdc",'r')
+ jdc=fcomm.read()
+ fcomm.close()
+ #args["jdc"]=jdc
+ if not self.init:
+ self.init=1
+ fcomm=open("fort.1",'w')
+ fcomm.write(jdc)
+ fcomm.close()
+ ier=self.main(args)
+ if ier != 0:
+ raise ExecutionError("Error in initial execution")
+ else:
+ self.interpstring(jdc,args)
+
self.endService("${component}.${service}")
+ j=self.jdc
+ return ${rvars}
except:
- sys.stdout.flush()
exc_typ,exc_val,exc_fr=sys.exc_info()
l=traceback.format_exception(exc_typ,exc_val,exc_fr)
self.endService("${component}.${service}")
- CONTEXT.unset_current_step()
+ sys.stdout.flush()
+ sys.stderr.flush()
raise SALOME.SALOME_Exception(SALOME.ExceptionStruct(SALOME.BAD_PARAM,"".join(l),"${component}.py",0))
- return ${rvars}
"""
asterCEXEService=Template(asterCEXEService)
asterEXEService=asterCEXEService
export SALOME_CONTAINERNAME=$$1
-cp ${export} temp.export
-cat >> temp.export << END
-F mess $$PWD/messages R 6
-F resu $$PWD/resu R 8
-F erre $$PWD/erre R 9
-END
-
-${asrun} temp.export
+${compoexe}
"""
cexe=Template(cexe)
export SALOME_CONTAINERNAME=$$2
export SALOME_INSTANCE=$$3
-cp ${export} temp.export
-cat >> temp.export << END
-F mess $$PWD/messages R 6
-F resu $$PWD/resu R 8
-F erre $$PWD/erre R 9
-END
-
-${asrun} temp.export
+${compoexe}
"""
exeaster=Template(exeaster)
Component.validate(self)
kinds = ("lib", "exe")
if self.kind not in kinds:
- raise Invalid("kind must be one of %s" % kinds)
+ raise Invalid("kind must be one of %s for component %s" % (kinds,self.name))
if self.kind == "exe" :
if not self.exe_path:
self.impl = "F77"
def makebody(self):
+ """generate definitions (defs attribute of services) et bodys (body attribute of services)"""
for serv in self.services:
#defs generation
params = ["void *compo"]
strparams = []
for name, typ in serv.inport:
+ if typ == "file":continue #files are not passed through service interface
if typ == "string":
params.append("const STR_PSTR(%s)"%name)
strparams.append("STR_PLEN(%s)"%name)
else:
params.append("%s %s" % (f77Types[typ], name))
for name, typ in serv.outport:
+ if typ == "file":continue #files are not passed through service interface
if typ == "string":
params.append("const STR_PSTR(%s)"%name)
strparams.append("STR_PLEN(%s)"%name)
#length allocated for out string
lstr = 20
for name, typ in serv.inport:
+ if typ == "file":continue #files are not passed through service interface
if typ == "string":
params.append("STR_CPTR(%s)" % name)
strparams.append("STR_CLEN(%s)"%name)
else:
params.append("&%s" % name)
for name, typ in serv.outport:
+ if typ == "file":continue #files are not passed through service interface
if typ == "string":
params.append("STR_CPTR(%s.ptr())" % name)
strparams.append("STR_CLEN(%s.ptr())"%name)
serv.body = serv.body+"\n F_CALL(%s,%s)(%s);" % (serv.name.lower(), serv.name.upper(), args)
def makeCompo(self, gen):
+ """build a dictionary that defines component files
+ dictionary key = file name
+ dictionary value = file content or dictionary defining subdirectory content
+ """
self.makebody()
return CPPComponent.makeCompo(self, gen)
import os, shutil, glob, socket
+import traceback
try:
from string import Template
class Invalid(Exception):
pass
+debug=0
+
from mod_tmpl import resMakefile, makecommon, configure, paco_configure
from mod_tmpl import mainMakefile, autogen, application
from cata_tmpl import catalog, interface, idl, idlMakefile, parallel_interface
corbaTypes = {"double":"CORBA::Double", "long":"CORBA::Long",
"string":"const char*", "dblevec":"const %s::dblevec&",
"stringvec":"const %s::stringvec&", "intvec":"const %s::intvec&",
- "dataref":"const Engines::dataref&",
+ "dataref":"const Engines::dataref&","file":None
}
corbaOutTypes = {"double":"CORBA::Double&", "long":"CORBA::Long&",
"string":"CORBA::String_out", "dblevec":"%s::dblevec_out",
"stringvec":"%s::stringvec_out", "intvec":"%s::intvec_out",
- "dataref":"Engines::dataref_out",
+ "dataref":"Engines::dataref_out","file":None
}
def corba_in_type(typ, module):
self.name = name
self.components = components or []
self.prefix = prefix or "%s_INSTALL" % name
- self.validate()
+ try:
+ self.validate()
+ except Invalid,e:
+ if debug:
+ traceback.print_exc()
+ print "Error in module %s: %s" % (name,e)
+ raise SystemExit
def validate(self):
lcompo = set()
self.aster = ""
def generate(self):
+ """generate SALOME module as described by module attribute"""
module = self.module
namedir = module.name+"_SRC"
force = self.context.get("force")
return
def makeArgs(self, service):
+ """generate source service for arguments"""
params = []
for name, typ in service.inport:
+ if typ=="file":continue #files are not passed through service interface
params.append("%s %s" % (corba_in_type(typ, self.module.name), name))
for name, typ in service.outport:
+ if typ=="file":continue #files are not passed through service interface
params.append("%s %s" % (corba_out_type(typ, self.module.name), name))
return ",".join(params)
def makeCatalog(self):
+ """generate SALOME components catalog source"""
components = []
for compo in self.module.components:
services = []
return catalog.substitute(components='\n'.join(components))
def makeidl(self):
+ """generate module IDL file source (CORBA interface)"""
from pacocompo import PACOComponent
interfaces = []
for compo in self.module.components:
for serv in compo.services:
params = []
for name, typ in serv.inport:
+ if typ == "file":continue #files are not passed through IDL interface
params.append("in %s %s" % (typ, name))
for name, typ in serv.outport:
+ if typ == "file":continue #files are not passed through IDL interface
params.append("out %s %s" % (typ, name))
service = " void %s(" % serv.name
service = service+",".join(params)+");"
services.append(service)
interfaces.append(parallel_interface.substitute(component=compo.name, services="\n".join(services)))
- else:
+ else:
services = []
for serv in compo.services:
params = []
for name, typ in serv.inport:
+ if typ == "file":continue #files are not passed through IDL interface
if compo.impl in ("PY", "ASTER") and typ == "pyobj":
typ = "Engines::fileBlock"
params.append("in %s %s" % (typ, name))
for name, typ in serv.outport:
+ if typ == "file":continue #files are not passed through IDL interface
if compo.impl in ("PY", "ASTER") and typ == "pyobj":
typ = "Engines::fileBlock"
params.append("out %s %s" % (typ, name))
return xml.substitute(module=self.module.name, interfaces='\n'.join(interfaces))
def makeFiles(self, dic, basedir):
+ """create files and directories defined in dictionary dic in basedir directory
+ dic key = file name to create
+ dic value = file content or dictionary defining the content of a sub directory
+ """
for name, content in dic.items():
filename = os.path.join(basedir, name)
if isinstance(content, str):
self.makeFiles(content, filename)
def bootstrap(self):
+ """execute module autogen.sh script: execution of libtool, autoconf, automake"""
ier = os.system("cd %s_SRC;sh autogen.sh" % self.module.name)
if ier != 0:
raise Invalid("bootstrap has ended in error")
def configure(self):
+ """execute module configure script with installation prefix (prefix attribute of module)"""
prefix = self.module.prefix
paco = self.context.get("paco")
mpi = self.context.get("mpi")
raise Invalid("configure has ended in error")
def make(self):
+ """execute module Makefile : make"""
make_command = "make "
if self.makeflags:
make_command += self.makeflags
raise Invalid("make has ended in error")
def install(self):
+ """install module: make install """
ier = os.system("cd %s_SRC;make install" % self.module.name)
if ier != 0:
raise Invalid("install has ended in error")
def make_appli(self, appliname, restrict=None, altmodules=None):
+ """generate SALOME application"""
makedirs(appliname)
rootdir, kerdir = os.path.split(self.kernel)
Component.validate(self)
kinds = ("lib")
if self.kind not in kinds:
- raise Invalid("kind must be one of %s" % kinds)
+ raise Invalid("kind must be one of %s for component %s" % (kinds,self.name))
parallel_libs = ("dummy", "mpi")
if self.parallel_lib not in parallel_libs:
raise Invalid("parallel_lib must be one of %s" % parallel_libs)
from gener import Component, Invalid
from pyth_tmpl import pyinitService, pyService, pyCompoEXE, pyCompo
from pyth_tmpl import pycompoEXEMakefile, pycompoMakefile
+import textwrap
+from string import split,rstrip,join
+
+def indent(text, prefix=' '):
+ """Indent text by prepending a given prefix to each line."""
+ if not text: return ''
+ lines = split(text, '\n')
+ lines = map(lambda line, prefix=prefix: prefix + line, lines)
+ if lines: lines[-1] = rstrip(lines[-1])
+ return join(lines, '\n')
class PYComponent(Component):
def __init__(self, name, services=None, python_path=None, kind="lib",
sources=None):
+ """initialise component attributes"""
self.python_path = python_path or []
Component.__init__(self, name, services, impl="PY", kind=kind,
sources=sources)
def validate(self):
+ """validate component attributes"""
Component.validate(self)
kinds = ("lib","exe")
if self.kind not in kinds:
- raise Invalid("kind must be one of %s" % kinds)
+ raise Invalid("kind must be one of %s for component %s" % (kinds,self.name))
def makeCompo(self, gen):
+ """generate component sources as a dictionary containing
+ file names (key) and file content (values)
+ """
pyfile = "%s.py" % self.name
sources = " ".join(map(os.path.basename,self.sources))
if self.kind == "lib":
}
def makepy(self, gen):
+ """generate standard SALOME component source (python module)"""
services = []
inits = []
defs = []
params = []
pyparams = []
for name, typ in serv.inport:
+ if typ=="file":continue #files are not passed through service interface
params.append(name)
if typ == "pyobj":
pyparams.append(" %s=cPickle.loads(%s)" %(name, name))
params = []
pyparams = []
for name, typ in serv.outport:
+ if typ=="file":continue #files are not passed through service interface
params.append(name)
if typ == "pyobj":
pyparams.append(" %s=cPickle.dumps(%s,-1)" %(name, name))
outparams = ",".join(params)
convertoutparams = '\n'.join(pyparams)
+ #dedent and indent the body
+ body=textwrap.dedent(serv.body)
+ body=indent(body,' '*6)
+
service = pyService.substitute(component=self.name, service=serv.name, inparams=inparams,
- outparams=outparams, body=serv.body,
+ outparams=outparams, body= body,
convertinparams=convertinparams,
convertoutparams=convertoutparams)
streams = []
python_path=python_path)
def makepyexe(self, gen):
+ """generate standalone component source (python executable)"""
services = []
inits = []
defs = []
params = []
pyparams = []
for name, typ in serv.inport:
+ if typ=="file":continue #files are not passed through service interface
params.append(name)
if typ == "pyobj":
pyparams.append(" %s=cPickle.loads(%s)" %(name, name))
params = []
pyparams = []
for name, typ in serv.outport:
+ if typ=="file":continue #files are not passed through service interface
params.append(name)
if typ == "pyobj":
pyparams.append(" %s=cPickle.dumps(%s,-1)" %(name, name))
outparams = ",".join(params)
convertoutparams = '\n'.join(pyparams)
- service = pyService.substitute(component=self.name, service=serv.name,
- inparams=inparams, outparams=outparams,
- body=serv.body,
+ #dedent and indent the body
+ body=textwrap.dedent(serv.body)
+ body=indent(body,' '*6)
+ service = pyService.substitute(component=self.name, service=serv.name,
+ inparams=inparams, outparams=outparams,
+ body=body,
convertinparams=convertinparams,
convertoutparams=convertoutparams,
)