1 import string, sys, fpformat, re, os
5 from xml.sax.handler import *
6 from omniidl import idlast, idltype, idlvisitor, idlutil, output
8 #values of this map are used in some nodes defenition
9 common_data={"AUTHOR" : "",
17 #--------------------------------------------------
19 #--------------------------------------------------
21 print "ERROR : ", message
24 #--------------------------------------------------
25 # base class implementing tree
26 #--------------------------------------------------
29 def __init__(self, name = '', content = ''):
31 self.content = content
35 def addChild(self, tree):
37 self.childs.append(tree)
41 def addNamedChild(self, name, content = ''):
42 return self.addChild(Tree(name, content))
44 def replaceChild(self, tree):
48 if i.name == tree.name:
50 self.childs.insert(pos, tree)
54 return self.addChild(tree)
56 def insertFirstChild(self, tree):
58 self.childs.insert(0, tree)
61 def insertFirstNamedChild(self, name, content = ''):
62 return self.insertFirstChild(Tree(name, content))
64 def output_xml(self, f, depth=0):
67 s = string.ljust('', 4*depth)
68 s += '<' + self.name + '>'
69 if self.content != '':
72 if len(self.childs) > 0:
81 s = '</' + self.name + '>\n'
82 if len(self.childs) > 0 :
83 s = string.ljust('', 4*depth) + s
86 def Dump(self, levels=-1, depth=0):
87 #Dumps the tree contents
89 if levels == 0: return
91 s = string.ljust('', 4*depth)
92 print s, self, self.content
94 i.Dump(levels-1, depth+1)
97 #Returns list of the parents
106 def getChild(self, name, content=None):
108 # content == None, don't compare content
109 for i in self.childs:
111 if (content is None) | (i.content == content):
115 def getNode(self, name, content='', depth=-1):
118 # content == None, don't compare content
119 if (self.name == name):
120 if (content is None) | (self.content == content):
124 for i in self.childs:
125 n = i.getNode(name, content, depth-1)
126 if n: return n #return a value
142 #--------------------------------------------------
143 # implements inParameter tree
144 #--------------------------------------------------
145 class inParameter(Tree):
147 def __init__(self, name=None, type='', comment=''):
148 Tree.__init__(self, 'inParameter')
149 if name is None: return
151 self.addNamedChild('inParameter-type', type)
152 self.addNamedChild('inParameter-name', name)
153 self.addNamedChild('inParameter-comment', comment)
157 T = P.getChild('inParameter-type')
160 #--------------------------------------------------
161 # implements outParameter tree
162 #--------------------------------------------------
163 class outParameter(Tree):
165 def __init__(self, name=None, type='', comment = ''):
167 Tree.__init__(self, 'outParameter')
168 if name is None: return
170 self.addNamedChild('outParameter-type', type)
171 self.addNamedChild('outParameter-name', name)
172 self.addNamedChild('outParameter-comment', comment)
176 T = P.getChild('outParameter-type')
179 #--------------------------------------------------
180 # implements service tree
181 #--------------------------------------------------
184 def __init__(self, name=None):
186 Tree.__init__(self, 'component-service')
187 if name is None: return
189 self.addNamedChild('service-name', name)
190 self.addNamedChild('service-author',common_data["AUTHOR"])
191 self.addNamedChild('service-version',common_data["VERSION"])
192 self.addNamedChild('service-comment')
193 self.addNamedChild('service-by-default', "0")
194 self.addNamedChild('inParameter-list')
195 self.addNamedChild('outParameter-list')
197 def createInParameter(self, name, type):
198 L = self.getChild('inParameter-list')
200 error ("Service.createInParameter() : 'inParameter-list' is not found"); return None;
201 p = inParameter(name, type)
205 def createOutParameter(self, name, type):
206 L = self.getChild('outParameter-list')
208 error ("Service.createOutParameter() : 'outParameter-list' is not found"); return None;
209 p = outParameter(name, type)
216 L_ext = S.getChild('inParameter-list')
217 L_int = self.getChild('inParameter-list')
219 if L_ext is not None and L_int is not None:
221 L_merge = Tree('inParameter-list')
223 for i_ext in L_ext.childs:
224 # i_ext = <inParameter>
225 n_ext = i_ext.getChild('inParameter-name')
226 if n_ext is None: continue
229 for i_int in L_int.childs:
230 # i_int = <inParameter>
231 n_int = i_int.getChild('inParameter-name')
233 if n_int is None: continue
235 if (n_int.content == n_ext.content):
241 L_merge.addChild(i_int)
243 L_merge.addChild(i_ext)
245 self.replaceChild(L_merge)
247 else : error("Service.merge(): 'inParameter-list' is not found") #either L_ext or L_int is None
249 L_ext = S.getChild('outParameter-list')
250 L_int = self.getChild('outParameter-list')
252 if L_ext is None or L_int is None:
253 error ("Service.merge() : 'outParameter-list' is not found")
255 L_merge = Tree('outParameter-list')
257 for i_ext in L_ext.childs:
258 #i_ext = <outParameter>
260 n_ext = i_ext.getChild('outParameter-name')
261 if n_ext is None: continue
262 for i_int in L_int.childs:
263 n_int = i_int.getChild('outParameter-name')
264 if n_int is None: continue
265 if (n_int.content == n_ext.content):
271 L_merge.addChild(i_int)
273 L_merge.addChild(i_ext)
275 self.replaceChild(L_merge)
278 #--------------------------------------------------
279 # implements interface tree
280 #--------------------------------------------------
281 class Interface(Tree):
283 def __init__(self, name=None):
287 if name is None: return
289 self.addNamedChild('component-interface-name', name)
290 self.addNamedChild('component-interface-comment');
291 self.addNamedChild('component-service-list')
293 def createService(self, name):
294 L = self.getChild('component-service-list')
297 error ("Interface.createService() : 'component-service-list' is not found")
306 L_ext = I.getChild('component-service-list')
307 L_int = self.getChild('component-service-list')
309 if L_ext is None or L_int is None:
310 error("Interface.merge() : 'component-service-list' is not found!")
313 L_merge = Tree('component-service-list')
315 for i_ext in L_ext.childs:
318 n_ext = i_ext.getChild('service-name')
319 if n_ext is None: continue
321 for i_int in L_int.childs:
322 n_int = i_int.getChild('service-name')
323 if n_int is None: continue
324 if (n_int.content == n_ext.content):
330 L_merge.addChild(i_int)
332 L_merge.addChild(i_ext)
334 self.replaceChild(L_merge)
337 #--------------------------------------------------
338 # implements Component tree
339 #--------------------------------------------------
340 class Component(Tree):
341 def __init__(self, name=None):
342 Tree.__init__(self, 'component')
344 if name is None: return
346 self.addNamedChild('component-name', name)
347 self.addNamedChild('component-type',common_data["COMP_TYPE"])
348 self.addNamedChild('component-author',common_data["AUTHOR"])
349 self.addNamedChild('component-version',common_data["VERSION"])
350 self.addNamedChild('component-comment')
351 self.addNamedChild('component-multistudy', common_data["COMP_MULT"])
352 self.addNamedChild('component-icone',common_data["ICON"])
353 self.addNamedChild('constraint')
354 self.addNamedChild('component-interface-list')
356 def createInterface(self, name):
357 L = self.getChild('component-interface-list')
359 error("createInterface: No component-interface-list is found")
366 ext=C.getChild('component-author')
367 int=self.getChild('component-author')
368 if int is not None and ext is not None and len(ext.content):
369 int.content = ext.content
371 ext=C.getChild('component-type')
372 int=self.getChild('component-type')
373 if int is not None and ext is not None and len(ext.content):
374 int.content = ext.content
376 ext=C.getChild('component-icone')
377 int=self.getChild('component-icone')
378 if int is not None and ext is not None and len(ext.content):
379 int.content = ext.content
381 ext=C.getChild('component-version')
382 int=self.getChild('component-version')
383 if int is not None and ext is not None and len(ext.content):
384 int.content = ext.content
386 ext=C.getChild('component-comment')
387 int=self.getChild('component-comment')
388 if int is not None and ext is not None and len(ext.content):
389 int.content = ext.content
391 ext=C.getChild('component-multistudy')
392 int=self.getChild('component-multistudy')
393 if int is not None and ext is not None and len(ext.content):
394 int.content = ext.content
396 ext=C.getChild('constraint')
397 int=self.getChild('constraint')
398 if int is not None and ext is not None and len(ext.content):
399 int.content = ext.content
401 L_ext = C.getChild('component-interface-list')
402 L_int = self.getChild('component-interface-list')
403 if L_ext is None or L_int is None:
404 error("Component.merge : No component-interface-list is found")
406 L_merge = Tree('component-interface-list')
408 for i_ext in L_ext.childs:
410 n_ext = i_ext.getChild('component-interface-name')
412 if n_ext is None: continue
414 for i_int in L_int.childs:
415 n_int = i_int.getChild('component-interface-name')
416 if n_int is None: continue
417 if (n_int.content == n_ext.content):
423 L_merge.addChild(i_int)
425 L_merge.addChild(i_ext)
427 self.replaceChild(L_merge)
429 #--------------------------------------------------
430 # implements document tree
431 #--------------------------------------------------
432 class Catalog(ContentHandler, Tree):
433 def __init__(self, filename = None):
438 parser = xml.sax.make_parser()
439 parser.setContentHandler(self)
440 parser.parse(filename)
442 t = self.addNamedChild('begin-catalog')
443 t.addNamedChild('component-list')
445 n = self.getChild('begin-catalog')
447 error("Catalog.__init__ : No 'begin-catalog' is found!")
449 if n.getChild('path-prefix-list') is None:
450 n.insertFirstNamedChild('path-prefix-list')
451 if n.getChild('component-list') is None:
452 n.addNamedChild('component-list')
454 def removeComponent(self, name):
455 complist = self.getNode('component-list')
458 print "Catalog.removeComponent() : 'component-list' is not found"
460 for comp in complist.childs:
461 cname = comp.getChild('component-name')
462 if cname is not None:
463 if cname.content == name:
464 complist.childs.pop(idx)
465 print "Component " + name + " is removed"
468 def startDocument(self):
469 self.list.append(self)
471 def startElement(self, name, attrs):
472 p = self.list[len(self.list)-1]
474 if name == 'component':
475 e = p.addChild(Component())
476 elif name == 'component-interface-name':
477 e = p.addNamedChild(name)
478 elif name == 'component-service':
479 e = p.addChild(Service())
480 elif name == 'inParameter':
481 e = p.addChild(inParameter())
482 elif name == 'outParameter':
483 e = p.addChild(outParameter())
485 e = p.addNamedChild(name)
489 def endElement(self, name):
490 self.buffer = string.join(string.split(self.buffer), ' ')
491 p = self.list[len(self.list)-1]
492 p.content = self.buffer
497 def characters(self, ch):
500 def mergeComponent(self, comp):
502 L_int = self.getNode('component-list')
504 error("Catalog.mergeComponent : 'component-list' is not found")
509 n_ext = i_ext.getChild('component-name')
511 error("Catalog.mergeComponent : 'component-name' is not found")
513 for i_int in L_int.childs:
514 n_int = i_int.getChild('component-name')
515 if n_int is None: continue
517 if (n_int.content == n_ext.content):
522 print ' add component', n_ext.content
523 L_int.addChild(i_ext)
525 print ' replace component', n_ext.content
534 idltype.tk_void: "void",
535 idltype.tk_short: "short",
536 idltype.tk_long: "long",
537 idltype.tk_ushort: "unsigned short",
538 idltype.tk_ulong: "unsigned long",
539 idltype.tk_float: "float",
540 idltype.tk_double: "double",
541 idltype.tk_boolean: "boolean",
542 idltype.tk_char: "char",
543 idltype.tk_octet: "octet",
544 idltype.tk_any: "any",
545 idltype.tk_TypeCode: "CORBA::TypeCode",
546 idltype.tk_Principal: "CORBA::Principal",
547 idltype.tk_longlong: "long long",
548 idltype.tk_ulonglong: "unsigned long long",
549 idltype.tk_longdouble: "long double",
550 idltype.tk_wchar: "wchar"
554 #--------------------------------------------------
555 # class ModuleCatalogVisitor
556 #--------------------------------------------------
557 class ModuleCatalogVisitor (idlvisitor.AstVisitor):
559 def __init__(self, catalog):
560 self.catalog = catalog
563 def visitAST(self, node):
564 for n in node.declarations():
567 def visitModule(self, node):
568 for n in node.definitions():
571 def visitInterface(self, node):
576 for i in node.inherits():
578 if ((s[0] == "Engines") & (s[1] == "Component")):
579 self.EngineType = 1; break
581 if common_data["COMP_NAME"] : Comp = Component(common_data["COMP_NAME"])
582 else : Comp = Component(node.identifier())
584 self.currentInterface = Comp.createInterface(node.identifier())
586 for c in node.callables():
587 if isinstance(c, idlast.Operation):
590 if (self.EngineType):
591 self.catalog.mergeComponent(Comp)
595 def visitOperation(self, node):
597 self.currentService = self.currentInterface.createService \
600 for c in node.parameters():
603 node.returnType().accept(self)
604 if (self.currentType != "void"):
605 self.currentService.createOutParameter \
606 ("return", self.currentType)
609 def visitDeclaredType(self, type):
610 self.currentType = type.name()
612 def visitBaseType(self, type):
613 self.currentType = ttsMap[type.kind()]
615 def visitStringType(self, type):
616 self.currentType = "string"
618 def visitParameter(self, node):
619 node.paramType().accept(self)
621 self.currentService.createInParameter \
622 (node.identifier(), self.currentType)
624 self.currentService.createOutParameter \
625 (node.identifier(), self.currentType)
627 #--------------------------------------------------
628 # extract value of <param_name> from <args> list
629 # it's proposed that the matching <args> item
630 # looks like <param_name>=<value>, for example,
631 # catalog=/tmp/myxml.xml
632 #--------------------------------------------------
633 def getParamValue( param_name, args ):
634 pattern="^"+param_name+"="
636 res = "" #initial value
638 s = re.compile(pattern).search(opt)
645 #--------------------------------------------------
646 # parse idl and store xml file
647 #--------------------------------------------------
649 CatalogFileName=getParamValue("catalog",args)
650 if CatalogFileName is None:
651 CatalogFileName = 'CatalogModulePersonnel.xml'
653 if (re.compile(".*?.xml$").match(CatalogFileName, 1) is None):
654 CatalogFileName = CatalogFileName + '.xml'
656 #========= Read parameters ======================
657 common_data["ICON"] = getParamValue("icon",args) # get icon file
659 common_data["AUTHOR"] = getParamValue("author",args) # get author name
660 if common_data["AUTHOR"] is None: common_data["AUTHOR"] = os.getenv("USER");
662 common_data["VERSION"] = getParamValue("version",args) # get version
664 common_data["COMP_NAME"] = getParamValue("name",args) # get icon file
666 val = getParamValue("type",args) # get icon file
667 if val: common_data["COMP_TYPE"] = val
669 val = getParamValue("multistudy",args) # get icon file
670 if val : common_data["COMP_MULT"] = val
672 remove_comp = getParamValue("remove", args)
674 #==================================================
676 if (os.path.exists(CatalogFileName)):
677 print "Importing", CatalogFileName
678 C = Catalog(CatalogFileName)
680 print "Warning : ",CatalogFileName, " was not found."
683 print "Reading idl file"
685 visitor = ModuleCatalogVisitor(C)
689 C.removeComponent(remove_comp)
691 if (os.path.exists(CatalogFileName)):
692 print "Updating", CatalogFileName
693 CatalogFileName_old = CatalogFileName + '_old'
694 os.rename(CatalogFileName, CatalogFileName_old)
696 CatalogFileName_old = ""
697 print "Writing", CatalogFileName
699 CatalogFileName_new = CatalogFileName + '_new'
700 f=open(CatalogFileName_new, 'w')
701 f.write("<?xml version='1.0' encoding='us-ascii' ?>\n\n")
705 os.rename(CatalogFileName_new, CatalogFileName)
706 if ((CatalogFileName_old != "") & os.path.exists(CatalogFileName_old)):
707 os.unlink(CatalogFileName_old)
712 if __name__ == "__main__":
714 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>"