+# 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+#
+#
+#
+# File : IDLparser.py
+# Module : SALOME
+
import string, sys, fpformat, re, os
import xml.sax
import pdb
from xml.sax.handler import *
from omniidl import idlast, idltype, idlvisitor, idlutil, output
-#values of this map are used in some nodes defenition
-common_data={"AUTHOR" : "",
- "ICON" : "",
- "VERSION" : "",
- "COMP_TYPE": "",
- "COMP_NAME": "",
- "COMP_MULT": "1"
+# parameters not found in IDL file, user's specified in optional parameters
+common_data={"AUTHOR" : "",
+ "ICON" : "",
+ "VERSION" : "",
+ "COMP_TYPE" : "",
+ "COMP_NAME" : "",
+ "COMP_UNAME" : "",
+ "COMP_MULT" : "",
+ "COMP_IMPL" : ""
}
+nb_components = 0
+
+#--------------------------------------------------
+# extract value of <param_name> from <args> list
+# it's proposed that the matching <args> item
+# looks like <param_name>=<value>, for example,
+# catalog=/tmp/myxml.xml
+#--------------------------------------------------
+def getParamValue( param_name, default_value, args ):
+ pattern=param_name+"="
+
+ res = default_value #initial value
+ for opt in args:
+ s = re.compile(pattern).search(opt)
+ if s:
+ res = opt[s.end():]
+ break #found
+
+ return res
+
+
#--------------------------------------------------
# print error message
#--------------------------------------------------
#--------------------------------------------------
class Tree:
- def __init__(self, name = '', content = ''):
+ def __init__(self, name = '', content = '', key = None):
self.name = name
self.content = content
+ self.key = key
self.parent = None
self.childs = []
+ self.comments = []
def addChild(self, tree):
if tree is not None:
if tree is not None:
pos = 0
for i in self.childs:
- if i.name == tree.name:
+ if (i.name == tree.name) & ((i.key is None) | (i.key == tree.key)):
self.childs.pop(pos)
self.childs.insert(pos, tree)
return tree
return l
def getChild(self, name, content=None):
-
- # content == None, don't compare content
+ # return child node with a given name
+ # if content == None, don't compare contents
for i in self.childs:
if (i.name == name):
if (content is None) | (i.content == content):
return None
def getNode(self, name, content='', depth=-1):
-
- # recursive search
+ # recursive search of a node with a given name
# content == None, don't compare content
if (self.name == name):
if (content is None) | (self.content == content):
if (depth != 0):
for i in self.childs:
n = i.getNode(name, content, depth-1)
- if n: return n #return a value
+ if n: return n
return None
def merge(self, t):
pass
+
+ def mergeChilds(self, t, list):
+ L_ext = t.getChild(list)
+ 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)
+
+
#--------------------------------------------------
-# implements inParameter tree
+# implements parameter tree
#--------------------------------------------------
-class inParameter(Tree):
+class parameter(Tree):
- def __init__(self, name=None, type='', comment=''):
- Tree.__init__(self, 'inParameter')
+ 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('inParameter-type', type)
- self.addNamedChild('inParameter-name', name)
- self.addNamedChild('inParameter-comment', comment)
-
+ self.addNamedChild(mode + 'Parameter-name', name)
+ self.addNamedChild(mode + 'Parameter-type', type)
+ self.addNamedChild(mode + 'Parameter-comment', comment)
+
def merge(self, P):
- T = P.getChild('inParameter-type')
- self.replaceChild(T)
+ self.mode = P.mode
+ self.replaceChild(P.getChild(P.mode + 'Parameter-name'))
+ self.replaceChild(P.getChild(P.mode + 'Parameter-type'))
+ C = P.getChild(P.mode + 'Parameter-comment')
+ if C.content != 'unkonwn':
+ self.replaceChild(C)
#--------------------------------------------------
-# implements outParameter tree
+# implements dataStreamParameter tree
#--------------------------------------------------
-class outParameter(Tree):
+class dataStreamParameter(parameter):
- def __init__(self, name=None, type='', comment = ''):
-
- Tree.__init__(self, 'outParameter')
+ 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('outParameter-type', type)
- self.addNamedChild('outParameter-name', name)
- self.addNamedChild('outParameter-comment', comment)
+ self.addNamedChild(mode + 'Parameter-dependency', dependency)
+ self.mode = mode
def merge(self, P):
- T = P.getChild('outParameter-type')
- self.replaceChild(T)
+ parameter.merge(self, P)
+ self.replaceChild(P.getChild(mode + 'Parameter-dependency'))
+
+
+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
+ m = re.match(pattern, comment)
+
+ ## if there is a match, parse remaining part of comment
+ if m:
+ ## service
+ type = 'DataStreamPorts'
+ key = m.group(1)
+
+ sPorts = comment[m.end():]
+ pattern = word + '\('+word+','+word +','+word+'\)' \
+ + spaces + ',{,1}' + spaces
+ while len(sPorts) > 0:
+ ## process next DataStreamPort
+ ## match a definition like xx(a,b,c) with a possible trailing ,
+ ## returns a tuple (xx, a, b, c) and
+ ## the remaining part of input string
+ m = re.match(pattern, sPorts)
+ if m is None:
+ raise LookupError, \
+ '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):
+ def __init__(self, name=None, comment = 'unknown'):
- Tree.__init__(self, 'component-service')
+ 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"])
- self.addNamedChild('service-comment')
+ self.addNamedChild('service-comment', comment)
self.addNamedChild('service-by-default', "0")
self.addNamedChild('inParameter-list')
self.addNamedChild('outParameter-list')
+ self.addNamedChild('DataStream-list')
def createInParameter(self, name, type):
L = self.getChild('inParameter-list')
- if L is None:
- error ("Service.createInParameter() : 'inParameter-list' is not found"); return None;
- p = inParameter(name, type)
- L.addChild(p)
+ p = parameter(name, 'in', type)
+ L.replaceChild(p)
return p
def createOutParameter(self, name, type):
L = self.getChild('outParameter-list')
- if L is None:
- error ("Service.createOutParameter() : 'outParameter-list' is not found"); return None;
- p = outParameter(name, type)
- L.addChild(p)
+ p = parameter(name, 'out', type)
+ L.replaceChild(p)
return p
-
+ def createDataStreamParameter(self, p):
+ L = self.getChild('DataStream-list')
+ p = dataStreamParameter(p[0], p[2], p[1], p[3])
+ L.replaceChild(p)
+ return p
+
def merge(self, S):
-
- L_ext = S.getChild('inParameter-list')
- L_int = self.getChild('inParameter-list')
-
- if L_ext is not None and L_int is not None:
- L_merge = Tree('inParameter-list')
-
- for i_ext in L_ext.childs:
- # i_ext = <inParameter>
- n_ext = i_ext.getChild('inParameter-name')
- if n_ext is None: continue
- present = 0
-
- for i_int in L_int.childs:
- # i_int = <inParameter>
- n_int = i_int.getChild('inParameter-name')
-
- if n_int is None: continue
-
- if (n_int.content == n_ext.content):
- 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)
-
- else : error("Service.merge(): 'inParameter-list' is not found") #either L_ext or L_int is None
+ self.replaceChild(S.getChild('service-author'))
+ self.replaceChild(S.getChild('service-version'))
+ self.replaceChild(S.getChild('service-by-default'))
+ C = S.getChild('service-comment')
+ if C.content != 'unkonwn':
+ self.replaceChild(C)
- L_ext = S.getChild('outParameter-list')
- L_int = self.getChild('outParameter-list')
-
- if L_ext is None or L_int is None:
- error ("Service.merge() : 'outParameter-list' is not found")
+ for L in ['inParameter-list', 'outParameter-list', 'DataStream-list']:
+ self.mergeChilds(S, L)
- L_merge = Tree('outParameter-list')
-
- for i_ext in L_ext.childs:
- #i_ext = <outParameter>
- present = 0
- n_ext = i_ext.getChild('outParameter-name')
- if n_ext is None: continue
- for i_int in L_int.childs:
- n_int = i_int.getChild('outParameter-name')
- if n_int is None: continue
- if (n_int.content == n_ext.content):
- 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)
#--------------------------------------------------
#--------------------------------------------------
class Interface(Tree):
- def __init__(self, name=None):
+ def __init__(self, name=None, comment='unknown'):
- Tree.__init__(self)
+ Tree.__init__(self, key=name)
if name is None: return
self.addNamedChild('component-interface-name', name)
- self.addNamedChild('component-interface-comment');
+ self.addNamedChild('component-interface-comment', comment);
self.addNamedChild('component-service-list')
def createService(self, name):
L.addChild(s)
return s
+ def findService(self, key):
+ L = self.getChild('component-service-list')
+ for S in L.childs:
+ if S.key == key:
+ return S
+ return None
+
def merge(self, I):
- L_ext = I.getChild('component-service-list')
- L_int = self.getChild('component-service-list')
-
- if L_ext is None or L_int is None:
- error("Interface.merge() : 'component-service-list' is not found!")
- return
-
- L_merge = Tree('component-service-list')
-
- for i_ext in L_ext.childs:
-
- present = 0
- n_ext = i_ext.getChild('service-name')
- if n_ext is None: continue
-
- for i_int in L_int.childs:
- n_int = i_int.getChild('service-name')
- if n_int is None: continue
- if (n_int.content == n_ext.content):
- present = 1
- break;
-
- if present == 0:
- i_int.merge(i_ext)
- L_merge.addChild(i_int)
- else:
- L_merge.addChild(i_ext)
-
- self.replaceChild(L_merge)
+ C = S.getChild('component-interface-comment')
+ if C.content != 'unkonwn':
+ self.replaceChild(C)
+
+ self.mergeChilds(I, 'component-service-list')
+
+ def processDataStreams(self):
+ for sComment in self.comments:
+
+ type, key, result = parseComment(sComment)
+
+ if type == 'DataStreamPorts':
+ Service = self.findService(key)
+ if Service is None:
+ raise LookupError, \
+ 'service ' + key + \
+ ' not found in interface : ' + self.key
+ for p in result:
+ ## process next DataStreamPort
+ Service.createDataStreamParameter(p)
#--------------------------------------------------
#--------------------------------------------------
class Component(Tree):
def __init__(self, name=None):
- Tree.__init__(self, 'component')
+ Tree.__init__(self, 'component', key=name)
+ if name is None: return
+
+ self.addNamedChild('component-name', name)
- if name is None: return
-
- self.addNamedChild('component-name', 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')
+ if common_data["COMP_UNAME"] != '':
+ self.addNamedChild('component-username', common_data["COMP_UNAME"])
+ 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-icone',common_data["ICON"])
+ self.addNamedChild('component-icone', common_data["ICON"])
self.addNamedChild('constraint')
self.addNamedChild('component-interface-list')
return i
def merge(self, C):
- ext=C.getChild('component-author')
- int=self.getChild('component-author')
- if int is not None and ext is not None and len(ext.content):
- int.content = ext.content
-
- ext=C.getChild('component-type')
- int=self.getChild('component-type')
- if int is not None and ext is not None and len(ext.content):
- int.content = ext.content
-
- ext=C.getChild('component-icone')
- int=self.getChild('component-icone')
- if int is not None and ext is not None and len(ext.content):
- int.content = ext.content
-
- ext=C.getChild('component-version')
- int=self.getChild('component-version')
- if int is not None and ext is not None and len(ext.content):
- int.content = ext.content
-
- ext=C.getChild('component-comment')
- int=self.getChild('component-comment')
- if int is not None and ext is not None and len(ext.content):
- int.content = ext.content
-
- ext=C.getChild('component-multistudy')
- int=self.getChild('component-multistudy')
- if int is not None and ext is not None and len(ext.content):
- int.content = ext.content
-
- ext=C.getChild('constraint')
- int=self.getChild('constraint')
- if int is not None and ext is not None and len(ext.content):
- int.content = ext.content
-
- L_ext = C.getChild('component-interface-list')
- L_int = self.getChild('component-interface-list')
- if L_ext is None or L_int is None:
- error("Component.merge : No component-interface-list is found")
- return
- L_merge = Tree('component-interface-list')
-
- for i_ext in L_ext.childs:
- present = 0
- n_ext = i_ext.getChild('component-interface-name')
- if n_ext is None: continue
-
- for i_int in L_int.childs:
- n_int = i_int.getChild('component-interface-name')
- if n_int is None: continue
- if (n_int.content == n_ext.content):
- present = 1
- break;
+ for i in ['component-username', 'component-author',
+ 'component-type', 'component-icone', 'component-version',
+ 'component-multistudy', '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
- if present :
- i_int.merge(i_ext)
- L_merge.addChild(i_int)
- else:
- L_merge.addChild(i_ext)
+ Cc = C.getChild('component-comment')
+ if Cc.content != 'unkonwn':
+ self.replaceChild(Cc)
- self.replaceChild(L_merge)
+ self.mergeChilds(C, 'component-interface-list')
#--------------------------------------------------
# implements document tree
def startElement(self, name, attrs):
p = self.list[len(self.list)-1]
-
if name == 'component':
e = p.addChild(Component())
elif name == 'component-interface-name':
elif name == 'component-service':
e = p.addChild(Service())
elif name == 'inParameter':
- e = p.addChild(inParameter())
+ e = p.addChild(parameter(mode='in'))
elif name == 'outParameter':
- e = p.addChild(outParameter())
+ e = p.addChild(parameter(mode='out'))
else:
e = p.addNamedChild(name)
self.list.append(e)
self.buffer = string.join(string.split(self.buffer), ' ')
p = self.list[len(self.list)-1]
p.content = self.buffer
+ if name == 'component':
+ p.key = p.getChild('component-name').content
self.buffer = ''
e = self.list.pop()
-
def characters(self, ch):
self.buffer += ch
i_ext = comp
present = 0
- n_ext = i_ext.getChild('component-name')
- if n_ext is None:
- error("Catalog.mergeComponent : 'component-name' is not found")
- return
+ n_ext = i_ext.key
for i_int in L_int.childs:
- n_int = i_int.getChild('component-name')
- if n_int is None: continue
-
- if (n_int.content == n_ext.content):
+ if (i_int.key == n_ext):
present = 1
break;
if present == 0:
- print ' add component', n_ext.content
+ print ' add component', i_ext.getChild('component-name').content
L_int.addChild(i_ext)
else:
- print ' replace component', n_ext.content
+ print ' replace component', i_ext.getChild('component-name').content
i_int.merge(i_ext)
n.accept(self)
def visitInterface(self, node):
+
if node.mainFile():
self.EngineType = 0
if ((s[0] == "Engines") & (s[1] == "Component")):
self.EngineType = 1; break
- if common_data["COMP_NAME"] : Comp = Component(common_data["COMP_NAME"])
- else : Comp = Component(node.identifier())
+ Comp = Component(node.identifier())
self.currentInterface = Comp.createInterface(node.identifier())
if isinstance(c, idlast.Operation):
c.accept(self)
- if (self.EngineType):
+ for c in node.declarations():
+ if isinstance(c, idlast.Struct):
+ c.accept(self)
+
+ 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)
self.EngineType = 0
+
def visitOperation(self, node):
self.currentService = self.currentInterface.createService \
(node.identifier())
-
+
for c in node.parameters():
c.accept(self)
if (self.currentType != "void"):
self.currentService.createOutParameter \
("return", self.currentType)
+
+ for i in node.comments():
+ self.currentInterface.comments.append(str(i))
def visitDeclaredType(self, type):
self.currentService.createOutParameter \
(node.identifier(), self.currentType)
-#--------------------------------------------------
-# extract value of <param_name> from <args> list
-# it's proposed that the matching <args> item
-# looks like <param_name>=<value>, for example,
-# catalog=/tmp/myxml.xml
-#--------------------------------------------------
-def getParamValue( param_name, args ):
- pattern="^"+param_name+"="
-
- res = "" #initial value
- for opt in args:
- s = re.compile(pattern).search(opt)
- if s:
- res = opt[s.end():]
- break #found
-
- return res
-
#--------------------------------------------------
# parse idl and store xml file
#--------------------------------------------------
def run(tree, args):
- CatalogFileName=getParamValue("catalog",args)
- if CatalogFileName is None:
- CatalogFileName = 'CatalogModulePersonnel.xml'
- if (re.compile(".*?.xml$").match(CatalogFileName, 1) is None):
+ CatalogFileName=getParamValue("catalog", "CatalogModulePersonnel.xml", args)
+ if re.compile(".*?.xml$").match(CatalogFileName, 1) is None:
CatalogFileName = CatalogFileName + '.xml'
#========= Read parameters ======================
- common_data["ICON"] = getParamValue("icon",args) # get icon file
-
- common_data["AUTHOR"] = getParamValue("author",args) # get author name
- if common_data["AUTHOR"] is None: common_data["AUTHOR"] = os.getenv("USER");
+ common_data["ICON"] = getParamValue("icon", "", args)
+ common_data["AUTHOR"] = getParamValue("author", os.getenv("USER"), args)
+ common_data["VERSION"] = getParamValue("version", "1", 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
- common_data["VERSION"] = getParamValue("version",args) # get version
-
- common_data["COMP_NAME"] = getParamValue("name",args) # get icon file
-
- val = getParamValue("type",args) # get icon file
- if val: common_data["COMP_TYPE"] = val
-
- val = getParamValue("multistudy",args) # get icon file
- if val : common_data["COMP_MULT"] = val
-
- remove_comp = getParamValue("remove", args)
+ remove_comp = getParamValue("remove", "", args)
#==================================================
print "Importing", CatalogFileName
C = Catalog(CatalogFileName)
else:
- print "Warning : ",CatalogFileName, " was not found."
+ print "Creating ",CatalogFileName
C = Catalog()
-
+
print "Reading idl file"
visitor = ModuleCatalogVisitor(C)
tree.accept(visitor)
+## C.Dump()
+
if remove_comp :
C.removeComponent(remove_comp)
if __name__ == "__main__":
print
- print "Usage : omniidl -bIDLparser -Wbcatalog=<my_catalog.xml>[,icon=<pngfile>][,version=<num>][,author=<name>][,name=<component_name>][,multistudy=<component_multistudy>][,remove=component_name] <file.idl>"
+ print "Usage : omniidl -bIDLparser [-I<catalog files directory>]* -Wbcatalog=<my_catalog.xml>[,icon=<pngfile>][,version=<num>][,author=<name>][,name=<component_name>][,username=<component_username>][,multistudy=<component_multistudy>] <file.idl>"
print
+
+