X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModuleGenerator%2FIDLparser.py;h=0f2ab825d22cc68f57ff36b8c9cad02ea9bb32ca;hb=1119e0f3b0ead5c13e8f458fc9a75b7797420dd8;hp=96ccd6c3747a940df078d26250075b7c93efbe45;hpb=e6bfea36374791cd31c274a2f97df90dc60ddaf3;p=modules%2Fkernel.git diff --git a/src/ModuleGenerator/IDLparser.py b/src/ModuleGenerator/IDLparser.py index 96ccd6c37..0f2ab825d 100644 --- a/src/ModuleGenerator/IDLparser.py +++ b/src/ModuleGenerator/IDLparser.py @@ -1,24 +1,26 @@ -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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 +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # +# 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, or (at your option) any later version. # +# 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 +# + # File : IDLparser.py # Module : SALOME @@ -28,6 +30,7 @@ import pdb from xml.sax.handler import * from omniidl import idlast, idltype, idlvisitor, idlutil, output +from salome_utils import getUserName # parameters not found in IDL file, user's specified in optional parameters common_data={"AUTHOR" : "", @@ -58,7 +61,7 @@ def getParamValue( param_name, default_value, args ): res = opt[s.end():] break #found - return res + return res #-------------------------------------------------- @@ -72,7 +75,7 @@ def error (message): # base class implementing tree #-------------------------------------------------- class Tree: - + def __init__(self, name = '', content = '', key = None): self.name = name self.content = content @@ -80,9 +83,10 @@ class Tree: self.parent = None self.childs = [] self.comments = [] - + self.attrs={} + def addChild(self, tree): - if tree is not None: + if tree is not None: self.childs.append(tree) tree.parent = self return tree @@ -101,12 +105,12 @@ class Tree: pos += 1 return self.addChild(tree) - + def insertFirstChild(self, tree): if tree is not None: self.childs.insert(0, tree) return tree - + def insertFirstNamedChild(self, name, content = ''): return self.insertFirstChild(Tree(name, content)) @@ -114,7 +118,10 @@ class Tree: d = depth if self.name != '': s = string.ljust('', 4*depth) - s += '<' + self.name + '>' + s += '<' + self.name + for k,v in self.attrs.items(): + s += ' ' + k + '="' + v + '"' + s += '>' if self.content != '': s += self.content else: @@ -122,10 +129,10 @@ class Tree: s += '\n' f.write(s) d += 1 - + for i in self.childs: i.output_xml(f, d) - + if self.name != '': s = '\n' if len(self.childs) > 0 : @@ -134,9 +141,9 @@ class Tree: def Dump(self, levels=-1, depth=0): #Dumps the tree contents - + if levels == 0: return - + s = string.ljust('', 4*depth) print s, self, self.content for i in self.childs: @@ -151,7 +158,7 @@ class Tree: l.append(p.name) p = p.parent return l - + def getChild(self, name, content=None): # return child node with a given name # if content == None, don't compare contents @@ -167,12 +174,12 @@ class Tree: if (self.name == name): if (content is None) | (self.content == content): return self - + if (depth != 0): for i in self.childs: n = i.getNode(name, content, depth-1) - if n: return n - + if n: return n + return None def __repr__(self): @@ -192,44 +199,46 @@ class Tree: L_int = self.getChild(list) L_merge = Tree(list) - + for i_ext in L_ext.childs: k_ext = i_ext.key if k_ext is None: continue present = 0 - + for i_int in L_int.childs: k_int = i_int.key if k_int is None: continue - + if (k_int == k_ext): present = 1 break; - + if present : i_int.merge(i_ext) L_merge.addChild(i_int) else: L_merge.addChild(i_ext) - + self.replaceChild(L_merge) - - + def setAttrib(self, name,value): + self.attrs[name]=value + + #-------------------------------------------------- # implements parameter tree #-------------------------------------------------- class parameter(Tree): - + def __init__(self, name=None, mode = 'in', type='', comment='unknown'): Tree.__init__(self, mode + 'Parameter', key=name) self.mode = mode if name is None: return - + self.addNamedChild(mode + 'Parameter-name', name) self.addNamedChild(mode + 'Parameter-type', type) self.addNamedChild(mode + 'Parameter-comment', comment) - + def merge(self, P): self.mode = P.mode @@ -238,19 +247,19 @@ class parameter(Tree): C = P.getChild(P.mode + 'Parameter-comment') if C.content != 'unkonwn': self.replaceChild(C) - + #-------------------------------------------------- # implements dataStreamParameter tree #-------------------------------------------------- class dataStreamParameter(parameter): - + def __init__(self, name=None, mode='in', type='', dependency='', comment='unknown'): parameter.__init__(self, name, mode, type, comment) if name is None: return - + self.addNamedChild(mode + 'Parameter-dependency', dependency) self.mode = mode - + def merge(self, P): parameter.merge(self, P) @@ -261,11 +270,11 @@ def parseComment(comment): spaces = '[\t\n ]*' word = spaces + '([a-zA-Z][a-zA-Z0-9_]*)' + spaces - + result = [] type = None key = None - + ## match : // followed by a 'DataStreamPorts' string, ## the service name, and a list of ports pattern = '// *DataStreamPorts{,1}' + word @@ -276,7 +285,7 @@ def parseComment(comment): ## service type = 'DataStreamPorts' key = m.group(1) - + sPorts = comment[m.end():] pattern = word + '\('+word+','+word +','+word+'\)' \ + spaces + ',{,1}' + spaces @@ -291,19 +300,19 @@ def parseComment(comment): 'format error in DataStreamPort definition : '+sPorts sPorts = sPorts[m.end():] result.append(m.groups()) - + return type, key, result; #-------------------------------------------------- # implements service tree #-------------------------------------------------- class Service(Tree): - + def __init__(self, name=None, comment = 'unknown'): - + Tree.__init__(self, 'component-service', key=name) if name is None: return - + self.addNamedChild('service-name', name) self.addNamedChild('service-author',common_data["AUTHOR"]) self.addNamedChild('service-version',common_data["VERSION"]) @@ -312,13 +321,13 @@ class Service(Tree): self.addNamedChild('inParameter-list') self.addNamedChild('outParameter-list') self.addNamedChild('DataStream-list') - + def createInParameter(self, name, type): L = self.getChild('inParameter-list') p = parameter(name, 'in', type) L.replaceChild(p) return p - + def createOutParameter(self, name, type): L = self.getChild('outParameter-list') p = parameter(name, 'out', type) @@ -330,7 +339,7 @@ class Service(Tree): p = dataStreamParameter(p[0], p[2], p[1], p[3]) L.replaceChild(p) return p - + def merge(self, S): self.replaceChild(S.getChild('service-author')) @@ -339,27 +348,26 @@ class Service(Tree): C = S.getChild('service-comment') if C.content != 'unkonwn': self.replaceChild(C) - + for L in ['inParameter-list', 'outParameter-list', 'DataStream-list']: self.mergeChilds(S, L) - #-------------------------------------------------- # implements interface tree #-------------------------------------------------- class Interface(Tree): - + def __init__(self, name=None, comment='unknown'): - + Tree.__init__(self, key=name) if name is None: return - + self.addNamedChild('component-interface-name', name) self.addNamedChild('component-interface-comment', comment); self.addNamedChild('component-service-list') - + def createService(self, name): L = self.getChild('component-service-list') @@ -377,7 +385,7 @@ class Interface(Tree): if S.key == key: return S return None - + def merge(self, I): C = S.getChild('component-interface-comment') @@ -385,7 +393,7 @@ class Interface(Tree): self.replaceChild(C) self.mergeChilds(I, 'component-service-list') - + def processDataStreams(self): for sComment in self.comments: @@ -409,12 +417,12 @@ class Component(Tree): def __init__(self, name=None): Tree.__init__(self, 'component', key=name) if name is None: return - + # ASV : fix for bug PAL8922 (Component name indicated by user in GUI is not taken into account - if common_data["COMP_NAME"] != '': - self.addNamedChild('component-name', common_data["COMP_NAME"]) - else: - self.addNamedChild('component-name', name) + if common_data["COMP_NAME"] != '': + self.addNamedChild('component-name', common_data["COMP_NAME"]) + else: + self.addNamedChild('component-name', name) # ASV : if user name is NOT set, then use component-name instead. Else - default. if common_data["COMP_UNAME"] != '': @@ -424,16 +432,17 @@ class Component(Tree): self.addNamedChild('component-username', common_data["COMP_NAME"] ) else: self.addNamedChild('component-username', name) - + self.addNamedChild('component-type', common_data["COMP_TYPE"]) self.addNamedChild('component-author', common_data["AUTHOR"]) self.addNamedChild('component-version', common_data["VERSION"]) self.addNamedChild('component-comment', 'unknown') self.addNamedChild('component-multistudy', common_data["COMP_MULT"]) + self.addNamedChild('component-impltype', common_data["COMP_IMPL"]) self.addNamedChild('component-icone', common_data["ICON"]) self.addNamedChild('constraint') self.addNamedChild('component-interface-list') - + def createInterface(self, name): L = self.getChild('component-interface-list') if L is None: @@ -447,20 +456,20 @@ class Component(Tree): for i in ['component-username', 'component-author', 'component-type', 'component-icone', 'component-version', - 'component-multistudy', 'constraint']: + 'component-multistudy', 'component-impltype', 'constraint']: ext = C.getChild(i) int = self.getChild(i) if int is None: int = ext elif ext is not None and len(ext.content): int.content = ext.content - + Cc = C.getChild('component-comment') if Cc.content != 'unkonwn': self.replaceChild(Cc) - + self.mergeChilds(C, 'component-interface-list') - + #-------------------------------------------------- # implements document tree #-------------------------------------------------- @@ -475,6 +484,7 @@ class Catalog(ContentHandler, Tree): parser.parse(filename) else: t = self.addNamedChild('begin-catalog') + t.addNamedChild('type-list') t.addNamedChild('component-list') n = self.getChild('begin-catalog') @@ -483,9 +493,12 @@ class Catalog(ContentHandler, Tree): return if n.getChild('path-prefix-list') is None: n.insertFirstNamedChild('path-prefix-list') + if n.getChild('type-list') is None: + p=n.childs.index(n.getChild('path-prefix-list')) + n.childs.insert(p+1,Tree('type-list')) if n.getChild('component-list') is None: n.addNamedChild('component-list') - + def removeComponent(self, name): complist = self.getNode('component-list') idx = 0 @@ -498,11 +511,11 @@ class Catalog(ContentHandler, Tree): if cname.content == name: complist.childs.pop(idx) print "Component " + name + " is removed" - idx += 1 - + idx += 1 + def startDocument(self): self.list.append(self) - + def startElement(self, name, attrs): p = self.list[len(self.list)-1] if name == 'component': @@ -515,11 +528,21 @@ class Catalog(ContentHandler, Tree): e = p.addChild(parameter(mode='in')) elif name == 'outParameter': e = p.addChild(parameter(mode='out')) + elif name == 'sequence': + e = p.addChild(SeqType(attrs["name"],attrs["content"])) + elif name == 'objref': + e = p.addChild(ObjType(attrs["name"])) + elif name == 'struct': + e = p.addChild(StructType(attrs["name"])) + elif name == 'type': + e = p.addChild(Type(attrs["name"],attrs["kind"])) + elif name == 'member': + e = p.addChild(Member(attrs["name"],attrs["type"])) else: e = p.addNamedChild(name) self.list.append(e) self.buffer = '' - + def endElement(self, name): self.buffer = string.join(string.split(self.buffer), ' ') p = self.list[len(self.list)-1] @@ -528,17 +551,17 @@ class Catalog(ContentHandler, Tree): p.key = p.getChild('component-name').content self.buffer = '' e = self.list.pop() - + def characters(self, ch): self.buffer += ch def mergeComponent(self, comp): - + L_int = self.getNode('component-list') if L_int is None: error("Catalog.mergeComponent : 'component-list' is not found") return - + i_ext = comp present = 0 n_ext = i_ext.key @@ -546,16 +569,74 @@ class Catalog(ContentHandler, Tree): if (i_int.key == n_ext): present = 1 break; - + if present == 0: print ' add component', i_ext.getChild('component-name').content L_int.addChild(i_ext) else: print ' replace component', i_ext.getChild('component-name').content i_int.merge(i_ext) - - + def mergeType(self, type): + L_int = self.getNode('type-list') + if L_int is None: + error("Catalog.mergeType : 'type-list' is not found") + return + for t in L_int.childs: + if t.attrs["name"] == type.attrs["name"]: + t.merge(type) + return + + L_int.addChild(type) + +class Member(Tree): + def __init__(self, name,type): + Tree.__init__(self, 'member') + self.setAttrib("name",name) + self.setAttrib("type",type) + +class Type(Tree): + def __init__(self, name,kind): + Tree.__init__(self, 'type') + self.setAttrib("name",name) + self.setAttrib("kind",kind) + + def merge(self,t): + self.setAttrib("kind",t.attrs["kind"]) + +class SeqType(Tree): + def __init__(self, name,content): + Tree.__init__(self, 'sequence') + self.setAttrib("name",name) + self.setAttrib("content",content) + + def merge(self,t): + self.setAttrib("content",t.attrs["content"]) + +class StructType(Tree): + def __init__(self, name): + Tree.__init__(self, 'struct') + self.setAttrib("name",name) + + def merge(self,t): + #remove childs and replace by t childs + self.childs=[] + for c in t.childs: + self.childs.append(c) + +class ObjType(Tree): + def __init__(self, name): + Tree.__init__(self, 'objref') + self.setAttrib("name",name) + + def merge(self,t): + RepoId=t.attrs.get("id") + if RepoId: + self.setAttrib("id",RepoId) + #remove childs and replace by t childs + self.childs=[] + for c in t.childs: + self.childs.append(c) # IDL file reader @@ -584,81 +665,97 @@ ttsMap = { # class ModuleCatalogVisitor #-------------------------------------------------- class ModuleCatalogVisitor (idlvisitor.AstVisitor): - + def __init__(self, catalog): self.catalog = catalog self.EngineType = 0 - + self.currentScope=None + def visitAST(self, node): for n in node.declarations(): - n.accept(self) - + if n.mainFile(): + n.accept(self) + def visitModule(self, node): + self.currentScope=node for n in node.definitions(): n.accept(self) - + def visitInterface(self, node): - if node.mainFile(): self.EngineType = 0 - + for i in node.inherits(): s = i.scopedName(); - if ((s[0] == "Engines") & (s[1] == "Component")): + if s[0] == "Engines": + if s[1] == "EngineComponent": self.EngineType = 1; break - - Comp = Component(node.identifier()) - - self.currentInterface = Comp.createInterface(node.identifier()) - - for c in node.callables(): + if s[1] == "Superv_Component": + self.EngineType = 2; break + + if self.EngineType: + #This interface is a SALOME component + Comp = Component(node.identifier()) + + self.currentInterface = Comp.createInterface(node.identifier()) + + for c in node.callables(): if isinstance(c, idlast.Operation): c.accept(self) - for c in node.declarations(): + for c in node.declarations(): if isinstance(c, idlast.Struct): c.accept(self) - - for i in node.comments(): + + for i in node.comments(): self.currentInterface.comments.append(str(i)) - self.currentInterface.processDataStreams() - - if (self.EngineType): - global nb_components - nb_components = nb_components + 1 - self.catalog.mergeComponent(Comp) + if self.EngineType == 2: + self.currentInterface.processDataStreams() + + global nb_components + nb_components = nb_components + 1 + self.catalog.mergeComponent(Comp) + + else: + #This interface is not a component : use it as a DataType + t=ObjType("/".join(node.scopedName())) + for i in node.inherits(): + t.addNamedChild("base","/".join(i.scopedName())) + self.catalog.mergeType(t) self.EngineType = 0 - + def visitOperation(self, node): self.currentService = self.currentInterface.createService \ (node.identifier()) - + node.returnType().accept(self) if (self.currentType != "void"): self.currentService.createOutParameter \ ("return", self.currentType) - + for c in node.parameters(): c.accept(self) for i in node.comments(): self.currentInterface.comments.append(str(i)) - + def visitDeclaredType(self, type): - self.currentType = type.name() - + name=type.name() + scoped_name="/".join(type.scopedName()) + self.currentType = scoped_name + def visitBaseType(self, type): self.currentType = ttsMap[type.kind()] - + def visitStringType(self, type): self.currentType = "string" - + def visitParameter(self, node): node.paramType().accept(self) if node.is_in(): @@ -667,32 +764,84 @@ class ModuleCatalogVisitor (idlvisitor.AstVisitor): if node.is_out(): self.currentService.createOutParameter \ (node.identifier(), self.currentType) - + + def visitSequenceType(self,type): + type.seqType().accept(self) + if type.bound() == 0: + self.contentType=self.currentType + self.currentType = "sequence" + else: + self.currentType = None + + def visitTypedef(self, node): + if node.constrType(): + node.aliasType().decl().accept(self) + + node.aliasType().accept(self) + type = self.currentType + if not type: + return + decll = [] + for d in node.declarators(): + d.accept(self) + if self.__result_declarator: + decll.append(self.__result_declarator) + if type == "sequence": + #it's a sequence type + for name in decll: + scoped_name="/".join(self.currentScope.scopedName()+[name]) + self.catalog.mergeType(SeqType(scoped_name,self.contentType)) + #else: + #it's an alias + # for name in decll: + # scoped_name="/".join(self.currentScope.scopedName()+[name]) + # self.catalog.mergeType(Type(scoped_name,type)) + + def visitStruct(self, node): + t=StructType("/".join(node.scopedName())) + for m in node.members(): + if m.constrType(): + m.memberType().decl().accept(self) + + m.memberType().accept(self) + type = self.currentType + for d in m.declarators(): + d.accept(self) + t.addChild(Member(self.__result_declarator,type)) + + self.catalog.mergeType(t) + + def visitDeclarator(self, node): + if node.sizes(): + self.__result_declarator =None + else: + self.__result_declarator =node.identifier() + #-------------------------------------------------- # parse idl and store xml file #-------------------------------------------------- def run(tree, args): - + CatalogFileName=getParamValue("catalog", "CatalogModulePersonnel.xml", args) if re.compile(".*?.xml$").match(CatalogFileName, 1) is None: CatalogFileName = CatalogFileName + '.xml' - #========= Read parameters ====================== + #========= Read parameters ====================== common_data["ICON"] = getParamValue("icon", "", args) - common_data["AUTHOR"] = getParamValue("author", os.getenv("USER"), args) + common_data["AUTHOR"] = getParamValue("author", getUserName(), args) common_data["VERSION"] = getParamValue("version", "1", args) - common_data["COMP_NAME"] = getParamValue("name", "", args) + common_data["COMP_NAME"] = getParamValue("name", "", args) common_data["COMP_UNAME"] = getParamValue("username", "", args) common_data["COMP_TYPE"] = getParamValue("type", "OTHER", args) common_data["COMP_MULT"] = getParamValue("multistudy", "1", args) common_data["COMP_IMPL"] = getParamValue("impltype", "1", args) print common_data - + remove_comp = getParamValue("remove", "", args) - - #================================================== - + + #================================================== + if (os.path.exists(CatalogFileName)): print "Importing", CatalogFileName C = Catalog(CatalogFileName) @@ -701,15 +850,15 @@ def run(tree, args): C = Catalog() print "Reading idl file" - + visitor = ModuleCatalogVisitor(C) tree.accept(visitor) ## C.Dump() - + if remove_comp : C.removeComponent(remove_comp) - + if (os.path.exists(CatalogFileName)): print "Updating", CatalogFileName CatalogFileName_old = CatalogFileName + '_old' @@ -717,7 +866,7 @@ def run(tree, args): else: CatalogFileName_old = "" print "Writing", CatalogFileName - + CatalogFileName_new = CatalogFileName + '_new' f=open(CatalogFileName_new, 'w') f.write("\n\n") @@ -727,13 +876,11 @@ def run(tree, args): os.rename(CatalogFileName_new, CatalogFileName) if ((CatalogFileName_old != "") & os.path.exists(CatalogFileName_old)): os.unlink(CatalogFileName_old) - + print if __name__ == "__main__": print - print "Usage : omniidl -bIDLparser [-I]* -Wbcatalog=[,icon=][,version=][,author=][,name=][,username=][,multistudy=] " + print "Usage : omniidl -bIDLparser [-I]* -Wbcatalog=[,icon=][,version=][,author=][,name=][,username=][,multistudy=][,impltype=] " print - -