1 # Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License.
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 # See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
25 import string, sys, fpformat, re, os
29 from xml.sax.handler import *
30 from omniidl import idlast, idltype, idlvisitor, idlutil, output
32 #values of this map are used in some nodes defenition
33 common_data={"AUTHOR" : "",
41 #--------------------------------------------------
43 #--------------------------------------------------
45 print "ERROR : ", message
48 #--------------------------------------------------
49 # base class implementing tree
50 #--------------------------------------------------
53 def __init__(self, name = '', content = ''):
55 self.content = content
59 def addChild(self, tree):
61 self.childs.append(tree)
65 def addNamedChild(self, name, content = ''):
66 return self.addChild(Tree(name, content))
68 def replaceChild(self, tree):
72 if i.name == tree.name:
74 self.childs.insert(pos, tree)
78 return self.addChild(tree)
80 def insertFirstChild(self, tree):
82 self.childs.insert(0, tree)
85 def insertFirstNamedChild(self, name, content = ''):
86 return self.insertFirstChild(Tree(name, content))
88 def output_xml(self, f, depth=0):
91 s = string.ljust('', 4*depth)
92 s += '<' + self.name + '>'
93 if self.content != '':
96 if len(self.childs) > 0:
101 for i in self.childs:
105 s = '</' + self.name + '>\n'
106 if len(self.childs) > 0 :
107 s = string.ljust('', 4*depth) + s
110 def Dump(self, levels=-1, depth=0):
111 #Dumps the tree contents
113 if levels == 0: return
115 s = string.ljust('', 4*depth)
116 print s, self, self.content
117 for i in self.childs:
118 i.Dump(levels-1, depth+1)
121 #Returns list of the parents
130 def getChild(self, name, content=None):
132 # content == None, don't compare content
133 for i in self.childs:
135 if (content is None) | (i.content == content):
139 def getNode(self, name, content='', depth=-1):
142 # content == None, don't compare content
143 if (self.name == name):
144 if (content is None) | (self.content == content):
148 for i in self.childs:
149 n = i.getNode(name, content, depth-1)
150 if n: return n #return a value
166 #--------------------------------------------------
167 # implements inParameter tree
168 #--------------------------------------------------
169 class inParameter(Tree):
171 def __init__(self, name=None, type='', comment=''):
172 Tree.__init__(self, 'inParameter')
173 if name is None: return
175 self.addNamedChild('inParameter-type', type)
176 self.addNamedChild('inParameter-name', name)
177 self.addNamedChild('inParameter-comment', comment)
181 T = P.getChild('inParameter-type')
184 #--------------------------------------------------
185 # implements outParameter tree
186 #--------------------------------------------------
187 class outParameter(Tree):
189 def __init__(self, name=None, type='', comment = ''):
191 Tree.__init__(self, 'outParameter')
192 if name is None: return
194 self.addNamedChild('outParameter-type', type)
195 self.addNamedChild('outParameter-name', name)
196 self.addNamedChild('outParameter-comment', comment)
200 T = P.getChild('outParameter-type')
203 #--------------------------------------------------
204 # implements service tree
205 #--------------------------------------------------
208 def __init__(self, name=None):
210 Tree.__init__(self, 'component-service')
211 if name is None: return
213 self.addNamedChild('service-name', name)
214 self.addNamedChild('service-author',common_data["AUTHOR"])
215 self.addNamedChild('service-version',common_data["VERSION"])
216 self.addNamedChild('service-comment')
217 self.addNamedChild('service-by-default', "0")
218 self.addNamedChild('inParameter-list')
219 self.addNamedChild('outParameter-list')
221 def createInParameter(self, name, type):
222 L = self.getChild('inParameter-list')
224 error ("Service.createInParameter() : 'inParameter-list' is not found"); return None;
225 p = inParameter(name, type)
229 def createOutParameter(self, name, type):
230 L = self.getChild('outParameter-list')
232 error ("Service.createOutParameter() : 'outParameter-list' is not found"); return None;
233 p = outParameter(name, type)
240 L_ext = S.getChild('inParameter-list')
241 L_int = self.getChild('inParameter-list')
243 if L_ext is not None and L_int is not None:
245 L_merge = Tree('inParameter-list')
247 for i_ext in L_ext.childs:
248 # i_ext = <inParameter>
249 n_ext = i_ext.getChild('inParameter-name')
250 if n_ext is None: continue
253 for i_int in L_int.childs:
254 # i_int = <inParameter>
255 n_int = i_int.getChild('inParameter-name')
257 if n_int is None: continue
259 if (n_int.content == n_ext.content):
265 L_merge.addChild(i_int)
267 L_merge.addChild(i_ext)
269 self.replaceChild(L_merge)
271 else : error("Service.merge(): 'inParameter-list' is not found") #either L_ext or L_int is None
273 L_ext = S.getChild('outParameter-list')
274 L_int = self.getChild('outParameter-list')
276 if L_ext is None or L_int is None:
277 error ("Service.merge() : 'outParameter-list' is not found")
279 L_merge = Tree('outParameter-list')
281 for i_ext in L_ext.childs:
282 #i_ext = <outParameter>
284 n_ext = i_ext.getChild('outParameter-name')
285 if n_ext is None: continue
286 for i_int in L_int.childs:
287 n_int = i_int.getChild('outParameter-name')
288 if n_int is None: continue
289 if (n_int.content == n_ext.content):
295 L_merge.addChild(i_int)
297 L_merge.addChild(i_ext)
299 self.replaceChild(L_merge)
302 #--------------------------------------------------
303 # implements interface tree
304 #--------------------------------------------------
305 class Interface(Tree):
307 def __init__(self, name=None):
311 if name is None: return
313 self.addNamedChild('component-interface-name', name)
314 self.addNamedChild('component-interface-comment');
315 self.addNamedChild('component-service-list')
317 def createService(self, name):
318 L = self.getChild('component-service-list')
321 error ("Interface.createService() : 'component-service-list' is not found")
330 L_ext = I.getChild('component-service-list')
331 L_int = self.getChild('component-service-list')
333 if L_ext is None or L_int is None:
334 error("Interface.merge() : 'component-service-list' is not found!")
337 L_merge = Tree('component-service-list')
339 for i_ext in L_ext.childs:
342 n_ext = i_ext.getChild('service-name')
343 if n_ext is None: continue
345 for i_int in L_int.childs:
346 n_int = i_int.getChild('service-name')
347 if n_int is None: continue
348 if (n_int.content == n_ext.content):
354 L_merge.addChild(i_int)
356 L_merge.addChild(i_ext)
358 self.replaceChild(L_merge)
361 #--------------------------------------------------
362 # implements Component tree
363 #--------------------------------------------------
364 class Component(Tree):
365 def __init__(self, name=None):
366 Tree.__init__(self, 'component')
368 if name is None: return
370 self.addNamedChild('component-name', name)
371 self.addNamedChild('component-type',common_data["COMP_TYPE"])
372 self.addNamedChild('component-author',common_data["AUTHOR"])
373 self.addNamedChild('component-version',common_data["VERSION"])
374 self.addNamedChild('component-comment')
375 self.addNamedChild('component-multistudy', common_data["COMP_MULT"])
376 self.addNamedChild('component-icone',common_data["ICON"])
377 self.addNamedChild('constraint')
378 self.addNamedChild('component-interface-list')
380 def createInterface(self, name):
381 L = self.getChild('component-interface-list')
383 error("createInterface: No component-interface-list is found")
390 ext=C.getChild('component-author')
391 int=self.getChild('component-author')
392 if int is not None and ext is not None and len(ext.content):
393 int.content = ext.content
395 ext=C.getChild('component-type')
396 int=self.getChild('component-type')
397 if int is not None and ext is not None and len(ext.content):
398 int.content = ext.content
400 ext=C.getChild('component-icone')
401 int=self.getChild('component-icone')
402 if int is not None and ext is not None and len(ext.content):
403 int.content = ext.content
405 ext=C.getChild('component-version')
406 int=self.getChild('component-version')
407 if int is not None and ext is not None and len(ext.content):
408 int.content = ext.content
410 ext=C.getChild('component-comment')
411 int=self.getChild('component-comment')
412 if int is not None and ext is not None and len(ext.content):
413 int.content = ext.content
415 ext=C.getChild('component-multistudy')
416 int=self.getChild('component-multistudy')
417 if int is not None and ext is not None and len(ext.content):
418 int.content = ext.content
420 ext=C.getChild('constraint')
421 int=self.getChild('constraint')
422 if int is not None and ext is not None and len(ext.content):
423 int.content = ext.content
425 L_ext = C.getChild('component-interface-list')
426 L_int = self.getChild('component-interface-list')
427 if L_ext is None or L_int is None:
428 error("Component.merge : No component-interface-list is found")
430 L_merge = Tree('component-interface-list')
432 for i_ext in L_ext.childs:
434 n_ext = i_ext.getChild('component-interface-name')
436 if n_ext is None: continue
438 for i_int in L_int.childs:
439 n_int = i_int.getChild('component-interface-name')
440 if n_int is None: continue
441 if (n_int.content == n_ext.content):
447 L_merge.addChild(i_int)
449 L_merge.addChild(i_ext)
451 self.replaceChild(L_merge)
453 #--------------------------------------------------
454 # implements document tree
455 #--------------------------------------------------
456 class Catalog(ContentHandler, Tree):
457 def __init__(self, filename = None):
462 parser = xml.sax.make_parser()
463 parser.setContentHandler(self)
464 parser.parse(filename)
466 t = self.addNamedChild('begin-catalog')
467 t.addNamedChild('component-list')
469 n = self.getChild('begin-catalog')
471 error("Catalog.__init__ : No 'begin-catalog' is found!")
473 if n.getChild('path-prefix-list') is None:
474 n.insertFirstNamedChild('path-prefix-list')
475 if n.getChild('component-list') is None:
476 n.addNamedChild('component-list')
478 def removeComponent(self, name):
479 complist = self.getNode('component-list')
482 print "Catalog.removeComponent() : 'component-list' is not found"
484 for comp in complist.childs:
485 cname = comp.getChild('component-name')
486 if cname is not None:
487 if cname.content == name:
488 complist.childs.pop(idx)
489 print "Component " + name + " is removed"
492 def startDocument(self):
493 self.list.append(self)
495 def startElement(self, name, attrs):
496 p = self.list[len(self.list)-1]
498 if name == 'component':
499 e = p.addChild(Component())
500 elif name == 'component-interface-name':
501 e = p.addNamedChild(name)
502 elif name == 'component-service':
503 e = p.addChild(Service())
504 elif name == 'inParameter':
505 e = p.addChild(inParameter())
506 elif name == 'outParameter':
507 e = p.addChild(outParameter())
509 e = p.addNamedChild(name)
513 def endElement(self, name):
514 self.buffer = string.join(string.split(self.buffer), ' ')
515 p = self.list[len(self.list)-1]
516 p.content = self.buffer
521 def characters(self, ch):
524 def mergeComponent(self, comp):
526 L_int = self.getNode('component-list')
528 error("Catalog.mergeComponent : 'component-list' is not found")
533 n_ext = i_ext.getChild('component-name')
535 error("Catalog.mergeComponent : 'component-name' is not found")
537 for i_int in L_int.childs:
538 n_int = i_int.getChild('component-name')
539 if n_int is None: continue
541 if (n_int.content == n_ext.content):
546 print ' add component', n_ext.content
547 L_int.addChild(i_ext)
549 print ' replace component', n_ext.content
558 idltype.tk_void: "void",
559 idltype.tk_short: "short",
560 idltype.tk_long: "long",
561 idltype.tk_ushort: "unsigned short",
562 idltype.tk_ulong: "unsigned long",
563 idltype.tk_float: "float",
564 idltype.tk_double: "double",
565 idltype.tk_boolean: "boolean",
566 idltype.tk_char: "char",
567 idltype.tk_octet: "octet",
568 idltype.tk_any: "any",
569 idltype.tk_TypeCode: "CORBA::TypeCode",
570 idltype.tk_Principal: "CORBA::Principal",
571 idltype.tk_longlong: "long long",
572 idltype.tk_ulonglong: "unsigned long long",
573 idltype.tk_longdouble: "long double",
574 idltype.tk_wchar: "wchar"
578 #--------------------------------------------------
579 # class ModuleCatalogVisitor
580 #--------------------------------------------------
581 class ModuleCatalogVisitor (idlvisitor.AstVisitor):
583 def __init__(self, catalog):
584 self.catalog = catalog
587 def visitAST(self, node):
588 for n in node.declarations():
591 def visitModule(self, node):
592 for n in node.definitions():
595 def visitInterface(self, node):
600 for i in node.inherits():
602 if ((s[0] == "Engines") & (s[1] == "Component")):
603 self.EngineType = 1; break
605 if common_data["COMP_NAME"] : Comp = Component(common_data["COMP_NAME"])
606 else : Comp = Component(node.identifier())
608 self.currentInterface = Comp.createInterface(node.identifier())
610 for c in node.callables():
611 if isinstance(c, idlast.Operation):
614 if (self.EngineType):
615 self.catalog.mergeComponent(Comp)
619 def visitOperation(self, node):
621 self.currentService = self.currentInterface.createService \
624 for c in node.parameters():
627 node.returnType().accept(self)
628 if (self.currentType != "void"):
629 self.currentService.createOutParameter \
630 ("return", self.currentType)
633 def visitDeclaredType(self, type):
634 self.currentType = type.name()
636 def visitBaseType(self, type):
637 self.currentType = ttsMap[type.kind()]
639 def visitStringType(self, type):
640 self.currentType = "string"
642 def visitParameter(self, node):
643 node.paramType().accept(self)
645 self.currentService.createInParameter \
646 (node.identifier(), self.currentType)
648 self.currentService.createOutParameter \
649 (node.identifier(), self.currentType)
651 #--------------------------------------------------
652 # extract value of <param_name> from <args> list
653 # it's proposed that the matching <args> item
654 # looks like <param_name>=<value>, for example,
655 # catalog=/tmp/myxml.xml
656 #--------------------------------------------------
657 def getParamValue( param_name, args ):
658 pattern="^"+param_name+"="
660 res = "" #initial value
662 s = re.compile(pattern).search(opt)
669 #--------------------------------------------------
670 # parse idl and store xml file
671 #--------------------------------------------------
673 CatalogFileName=getParamValue("catalog",args)
674 if CatalogFileName is None:
675 CatalogFileName = 'CatalogModulePersonnel.xml'
677 if (re.compile(".*?.xml$").match(CatalogFileName, 1) is None):
678 CatalogFileName = CatalogFileName + '.xml'
680 #========= Read parameters ======================
681 common_data["ICON"] = getParamValue("icon",args) # get icon file
683 common_data["AUTHOR"] = getParamValue("author",args) # get author name
684 if common_data["AUTHOR"] is None: common_data["AUTHOR"] = os.getenv("USER");
686 common_data["VERSION"] = getParamValue("version",args) # get version
688 common_data["COMP_NAME"] = getParamValue("name",args) # get icon file
690 val = getParamValue("type",args) # get icon file
691 if val: common_data["COMP_TYPE"] = val
693 val = getParamValue("multistudy",args) # get icon file
694 if val : common_data["COMP_MULT"] = val
696 remove_comp = getParamValue("remove", args)
698 #==================================================
700 if (os.path.exists(CatalogFileName)):
701 print "Importing", CatalogFileName
702 C = Catalog(CatalogFileName)
704 print "Warning : ",CatalogFileName, " was not found."
707 print "Reading idl file"
709 visitor = ModuleCatalogVisitor(C)
713 C.removeComponent(remove_comp)
715 if (os.path.exists(CatalogFileName)):
716 print "Updating", CatalogFileName
717 CatalogFileName_old = CatalogFileName + '_old'
718 os.rename(CatalogFileName, CatalogFileName_old)
720 CatalogFileName_old = ""
721 print "Writing", CatalogFileName
723 CatalogFileName_new = CatalogFileName + '_new'
724 f=open(CatalogFileName_new, 'w')
725 f.write("<?xml version='1.0' encoding='us-ascii' ?>\n\n")
729 os.rename(CatalogFileName_new, CatalogFileName)
730 if ((CatalogFileName_old != "") & os.path.exists(CatalogFileName_old)):
731 os.unlink(CatalogFileName_old)
736 if __name__ == "__main__":
738 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>"