Salome HOME
updated copyright message
[modules/kernel.git] / src / ModuleGenerator / IDLparser.py
1 #  -*- coding: iso-8859-1 -*-
2 # Copyright (C) 2007-2023  CEA, EDF, OPEN CASCADE
3 #
4 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
5 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 #
7 # This library is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU Lesser General Public
9 # License as published by the Free Software Foundation; either
10 # version 2.1 of the License, or (at your option) any later version.
11 #
12 # This library is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 # Lesser General Public License for more details.
16 #
17 # You should have received a copy of the GNU Lesser General Public
18 # License along with this library; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
20 #
21 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 #
23
24 import os
25 import os.path as osp
26 import re
27 import xml.sax
28
29 from xml.sax.handler import *
30 from omniidl import idlast, idltype, idlvisitor, idlutil, output
31 from salome_utils import getUserName
32
33 # parameters not found in IDL file, user's specified in optional parameters
34 common_data={"AUTHOR"     : "",
35              "ICON"       : "",
36              "VERSION"    : "",
37              "COMP_TYPE"  : "",
38              "COMP_NAME"  : "",
39              "COMP_UNAME" : "",
40              "COMP_IMPL"  : ""
41              }
42
43 nb_components = 0
44
45 #--------------------------------------------------
46 # extract value of <param_name> from <args> list
47 # it's proposed that the matching <args> item
48 # looks like <param_name>=<value>, for example,
49 # catalog=/tmp/myxml.xml
50 #--------------------------------------------------
51 def getParamValue( param_name, default_value, args ):
52     pattern="^"+param_name+"="
53
54     res = default_value        #initial value
55     for opt in args:
56         s = re.compile(pattern).search(opt)
57         if s:
58             res = opt[s.end():]
59             break     #found
60
61     return res
62
63
64 #--------------------------------------------------
65 # print error message
66 #--------------------------------------------------
67 def error (message):
68     print("ERROR : ", message)
69
70
71 #--------------------------------------------------
72 # base class implementing tree
73 #--------------------------------------------------
74 class Tree:
75
76     def __init__(self, name = '', content = '', key = None):
77         self.name = name
78         self.content = content
79         self.key = key
80         self.parent = None
81         self.childs = []
82         self.comments = []
83         self.attrs={}
84
85     def addChild(self, tree):
86         if tree is not None:
87             self.childs.append(tree)
88             tree.parent = self
89         return tree
90
91     def addNamedChild(self, name, content = ''):
92         return self.addChild(Tree(name, content))
93
94     def replaceChild(self, tree):
95          if tree is not None:
96             pos = 0
97             for i in self.childs:
98                 if (i.name == tree.name) & ((i.key is None) | (i.key == tree.key)):
99                     self.childs.pop(pos)
100                     self.childs.insert(pos, tree)
101                     return tree
102                 pos += 1
103
104          return self.addChild(tree)
105
106     def insertFirstChild(self, tree):
107         if tree is not None:
108             self.childs.insert(0, tree)
109         return tree
110
111     def insertFirstNamedChild(self, name, content = ''):
112         return self.insertFirstChild(Tree(name, content))
113
114     def output_xml(self, f, depth=0):
115         d = depth
116         if self.name != '':
117             s = ''.ljust(4*depth)
118             s += '<' + self.name
119             for k,v in list(self.attrs.items()):
120               s += ' ' + k + '="' + v + '"'
121             s += '>'
122             if self.content != '':
123                 s +=  self.content
124             else:
125                 if len(self.childs) > 0:
126                     s += '\n'
127             f.write(s)
128             d +=  1
129
130         for i in self.childs:
131             i.output_xml(f, d)
132
133         if self.name != '':
134             s = '</' + self.name + '>\n'
135             if len(self.childs) > 0 :
136                 s = ''.ljust(4*depth) + s
137             f.write(s)
138
139     def Dump(self, levels=-1, depth=0):
140         #Dumps the tree contents
141
142         if levels == 0: return
143
144         s = ''.ljust(4*depth)
145         print(s, self, self.content)
146         for i in self.childs:
147             i.Dump(levels-1, depth+1)
148
149     def parents(self):
150         #Returns list of the parents
151         l = []
152         p = self.parent
153         while p:
154             l.append(p)
155             l.append(p.name)
156             p = p.parent
157         return l
158
159     def getChild(self, name, content=None):
160         # return child node with a given name
161         # if content == None, don't compare contents
162         for i in self.childs:
163             if (i.name == name):
164                 if (content is None) | (i.content == content):
165                     return i
166         return None
167
168     def getNode(self, name, content='', depth=-1):
169         # recursive search of a node with a given name
170         # content == None, don't compare content
171         if (self.name == name):
172             if (content is None) | (self.content == content):
173                 return self
174
175         if (depth != 0):
176             for i in self.childs:
177                 n = i.getNode(name, content, depth-1)
178                 if n:  return n
179
180         return None
181
182     def __repr__(self):
183         s = '<'
184         if self.name != '':
185             s += self.name
186         else:
187             s +=  'None'
188         s += '>'
189         return s
190
191     def merge(self, t):
192         pass
193
194     def mergeChilds(self, t, list):
195         L_ext = t.getChild(list)
196         L_int = self.getChild(list)
197
198         L_merge = Tree(list)
199
200         for i_ext in L_ext.childs:
201             k_ext = i_ext.key
202             if k_ext is None:  continue
203             present = 0
204
205             for i_int in L_int.childs:
206                 k_int = i_int.key
207                 if k_int is None:  continue
208
209                 if (k_int == k_ext):
210                     present = 1
211                     break;
212
213             if present :
214                 i_int.merge(i_ext)
215                 L_merge.addChild(i_int)
216             else:
217                 L_merge.addChild(i_ext)
218
219         self.replaceChild(L_merge)
220
221     def setAttrib(self, name,value):
222       self.attrs[name]=value
223
224
225 #--------------------------------------------------
226 # implements parameter tree
227 #--------------------------------------------------
228 class parameter(Tree):
229
230     def __init__(self, name=None, mode = 'in', type='', comment='unknown'):
231         Tree.__init__(self, mode + 'Parameter', key=name)
232         self.mode = mode
233         if name is None:  return
234
235         self.addNamedChild(mode + 'Parameter-name', name)
236         self.addNamedChild(mode + 'Parameter-type', type)
237         self.addNamedChild(mode + 'Parameter-comment', comment)
238
239     def merge(self, P):
240
241         self.mode = P.mode
242         self.replaceChild(P.getChild(P.mode + 'Parameter-name'))
243         self.replaceChild(P.getChild(P.mode + 'Parameter-type'))
244         C = P.getChild(P.mode + 'Parameter-comment')
245         if C.content != 'unkonwn':
246             self.replaceChild(C)
247
248 #--------------------------------------------------
249 # implements dataStreamParameter tree
250 #--------------------------------------------------
251 class dataStreamParameter(parameter):
252
253     def __init__(self, name=None, mode='in', type='', dependency='', comment='unknown'):
254         parameter.__init__(self, name, mode, type, comment)
255         if name is None:  return
256
257         self.addNamedChild(mode + 'Parameter-dependency', dependency)
258         self.mode = mode
259
260     def merge(self, P):
261
262         parameter.merge(self, P)
263         self.replaceChild(P.getChild(mode + 'Parameter-dependency'))
264
265
266 def parseComment(comment):
267
268     spaces = '[\t\n ]*'
269     word = spaces + '([a-zA-Z][a-zA-Z0-9_]*)' + spaces
270
271     result = []
272     type = None
273     key = None
274
275     ## match :  // followed by a 'DataStreamPorts' string,
276     ## the service name, and a list of ports
277     pattern = '// *DataStreamPorts{,1}' + word
278     m = re.match(pattern, comment)
279
280     ## if there is a match, parse remaining part of comment
281     if m:
282         ## service
283         type = 'DataStreamPorts'
284         key = m.group(1)
285
286         sPorts = comment[m.end():]
287         pattern = word + '\('+word+','+word +','+word+'\)' \
288                   + spaces + ',{,1}' + spaces
289         while len(sPorts) > 0:
290             ## process next DataStreamPort
291             ## match a definition like xx(a,b,c) with a possible trailing ,
292             ## returns a tuple (xx, a, b, c) and
293             ## the remaining part of input string
294             m = re.match(pattern, sPorts)
295             if m is None:
296                 raise LookupError('format error in DataStreamPort definition : '+sPorts)
297             sPorts = sPorts[m.end():]
298             result.append(m.groups())
299
300     return type, key, result;
301
302 #--------------------------------------------------
303 # implements service tree
304 #--------------------------------------------------
305 class Service(Tree):
306
307     def __init__(self, name=None, comment = 'unknown'):
308
309         Tree.__init__(self, 'component-service', key=name)
310         if name is None:  return
311
312         self.addNamedChild('service-name', name)
313         self.addNamedChild('service-author',common_data["AUTHOR"])
314         self.addNamedChild('service-version',common_data["VERSION"])
315         self.addNamedChild('service-comment', comment)
316         self.addNamedChild('service-by-default', "0")
317         self.addNamedChild('inParameter-list')
318         self.addNamedChild('outParameter-list')
319         self.addNamedChild('DataStream-list')
320
321     def createInParameter(self, name, type):
322         L = self.getChild('inParameter-list')
323         p = parameter(name, 'in', type)
324         L.replaceChild(p)
325         return p
326
327     def createOutParameter(self, name, type):
328         L = self.getChild('outParameter-list')
329         p = parameter(name, 'out', type)
330         L.replaceChild(p)
331         return p
332
333     def createDataStreamParameter(self, p):
334         L = self.getChild('DataStream-list')
335         p = dataStreamParameter(p[0], p[2], p[1], p[3])
336         L.replaceChild(p)
337         return p
338
339     def merge(self, S):
340
341         self.replaceChild(S.getChild('service-author'))
342         self.replaceChild(S.getChild('service-version'))
343         self.replaceChild(S.getChild('service-by-default'))
344         C = S.getChild('service-comment')
345         if C.content != 'unkonwn':
346             self.replaceChild(C)
347
348         for L in ['inParameter-list', 'outParameter-list', 'DataStream-list']:
349            self.mergeChilds(S, L)
350
351
352 #--------------------------------------------------
353 # implements interface tree
354 #--------------------------------------------------
355 class Interface(Tree):
356
357     def __init__(self, name=None, comment='unknown'):
358
359         Tree.__init__(self, key=name)
360
361         if name is None:  return
362
363         self.addNamedChild('component-interface-name', name)
364         self.addNamedChild('component-interface-comment', comment);
365         self.addNamedChild('component-service-list')
366
367     def createService(self, name):
368         L = self.getChild('component-service-list')
369
370         if L is None:
371             error ("Interface.createService() : 'component-service-list' is not found")
372             return None
373
374         s = Service(name)
375         L.addChild(s)
376         return s
377
378     def findService(self, key):
379         L = self.getChild('component-service-list')
380         for S in L.childs:
381             if S.key == key:
382                 return S
383         return None
384
385     def merge(self, I):
386
387         C = S.getChild('component-interface-comment')
388         if C.content != 'unkonwn':
389             self.replaceChild(C)
390
391         self.mergeChilds(I, 'component-service-list')
392
393     def processDataStreams(self):
394         for sComment in self.comments:
395
396             type, key, result = parseComment(sComment)
397
398             if type == 'DataStreamPorts':
399                 Service = self.findService(key)
400                 if Service is None:
401                     raise LookupError('service ' + key + \
402                           ' not found in interface : ' + self.key)
403                 for p in result:
404                 ## process next DataStreamPort
405                     Service.createDataStreamParameter(p)
406
407
408 #--------------------------------------------------
409 # implements Component tree
410 #--------------------------------------------------
411 class Component(Tree):
412     def __init__(self, name=None):
413         Tree.__init__(self, 'component', key=name)
414         if name is None:  return
415
416 # ASV : fix for bug PAL8922 (Component name indicated by user in GUI is not taken into account
417         if common_data["COMP_NAME"] != '':
418             self.addNamedChild('component-name', common_data["COMP_NAME"])
419         else:
420             self.addNamedChild('component-name', name)
421
422 # ASV : if user name is NOT set, then use component-name instead.  Else - default.
423         if common_data["COMP_UNAME"] != '':
424             self.addNamedChild('component-username',   common_data["COMP_UNAME"])
425         else:
426             if common_data["COMP_NAME"] != '':
427                 self.addNamedChild('component-username', common_data["COMP_NAME"] )
428             else:
429                 self.addNamedChild('component-username',   name)
430
431         self.addNamedChild('component-type',       common_data["COMP_TYPE"])
432         self.addNamedChild('component-author',     common_data["AUTHOR"])
433         self.addNamedChild('component-version',    common_data["VERSION"])
434         self.addNamedChild('component-comment',    'unknown')
435         self.addNamedChild('component-impltype',   common_data["COMP_IMPL"])
436         self.addNamedChild('component-icone',      common_data["ICON"])
437         self.addNamedChild('constraint')
438         self.addNamedChild('component-interface-list')
439
440     def createInterface(self, name):
441         L = self.getChild('component-interface-list')
442         if L is None:
443             error("createInterface: No component-interface-list is found")
444             return None
445         i = Interface(name)
446         L.addChild(i)
447         return i
448
449     def merge(self, C):
450
451         for i in ['component-username', 'component-author',
452                   'component-type', 'component-icone', 'component-version',
453                   'component-impltype', 'constraint']:
454             ext = C.getChild(i)
455             int = self.getChild(i)
456             if int is None:
457                 int = ext
458             elif ext is not None and len(ext.content):
459                 int.content = ext.content
460
461         Cc = C.getChild('component-comment')
462         if Cc.content != 'unkonwn':
463             self.replaceChild(Cc)
464
465         self.mergeChilds(C, 'component-interface-list')
466
467 #--------------------------------------------------
468 # implements document tree
469 #--------------------------------------------------
470 class Catalog(ContentHandler, Tree):
471     def __init__(self, filename = None):
472         Tree.__init__(self)
473         self.buffer = ''
474         self.list = []
475         if (filename):
476             parser = xml.sax.make_parser()
477             parser.setContentHandler(self)
478             parser.parse(filename)
479         else:
480             t = self.addNamedChild('begin-catalog')
481             t.addNamedChild('type-list')
482             t.addNamedChild('component-list')
483
484         n = self.getChild('begin-catalog')
485         if n is None:
486             error("Catalog.__init__ : No 'begin-catalog' is found!")
487             return
488         if n.getChild('path-prefix-list') is None:
489             n.insertFirstNamedChild('path-prefix-list')
490         if n.getChild('type-list') is None:
491             p=n.childs.index(n.getChild('path-prefix-list'))
492             n.childs.insert(p+1,Tree('type-list'))
493         if n.getChild('component-list') is None:
494             n.addNamedChild('component-list')
495
496     def removeComponent(self, name):
497         complist = self.getNode('component-list')
498         idx = 0
499         if complist is None:
500             print("Catalog.removeComponent() : 'component-list' is not found")
501             return
502         for comp in complist.childs:
503             cname = comp.getChild('component-name')
504             if cname is not None:
505                 if cname.content == name:
506                     complist.childs.pop(idx)
507                     print("Component " + name + " is removed")
508             idx += 1
509
510     def startDocument(self):
511         self.list.append(self)
512
513     def startElement(self, name, attrs):
514         p = self.list[len(self.list)-1]
515         if name == 'component':
516             e = p.addChild(Component())
517         elif name == 'component-interface-name':
518             e = p.addNamedChild(name)
519         elif name == 'component-service':
520             e = p.addChild(Service())
521         elif name == 'inParameter':
522             e = p.addChild(parameter(mode='in'))
523         elif name == 'outParameter':
524             e = p.addChild(parameter(mode='out'))
525         elif name == 'sequence':
526             e = p.addChild(SeqType(attrs["name"],attrs["content"]))
527         elif name == 'objref':
528             e = p.addChild(ObjType(attrs["name"]))
529         elif name == 'struct':
530             e = p.addChild(StructType(attrs["name"]))
531         elif name == 'type':
532             e = p.addChild(Type(attrs["name"],attrs["kind"]))
533         elif name == 'member':
534             e = p.addChild(Member(attrs["name"],attrs["type"]))
535         else:
536             e = p.addNamedChild(name)
537         self.list.append(e)
538         self.buffer = ''
539
540     def endElement(self, name):
541         self.buffer = ' '.join(self.buffer.split())
542         p = self.list[len(self.list)-1]
543         p.content = self.buffer
544         if name == 'component':
545             p.key = p.getChild('component-name').content
546         self.buffer = ''
547         e = self.list.pop()
548
549     def characters(self, ch):
550         self.buffer += ch
551
552     def mergeComponent(self, comp):
553
554         L_int = self.getNode('component-list')
555         if   L_int is None:
556             error("Catalog.mergeComponent : 'component-list' is not found")
557             return
558
559         i_ext = comp
560         present = 0
561         n_ext = i_ext.key
562         for i_int in L_int.childs:
563             if (i_int.key == n_ext):
564                 present = 1
565                 break;
566
567         if present == 0:
568             print('   add component', i_ext.getChild('component-name').content)
569             L_int.addChild(i_ext)
570         else:
571             print('   replace component', i_ext.getChild('component-name').content)
572             i_int.merge(i_ext)
573
574     def mergeType(self, type):
575       L_int = self.getNode('type-list')
576       if L_int is None:
577         error("Catalog.mergeType : 'type-list' is not found")
578         return
579       for t in L_int.childs:
580         if t.attrs["name"] == type.attrs["name"]:
581           t.merge(type)
582           return
583
584       L_int.addChild(type)
585
586 class Member(Tree):
587   def __init__(self, name,type):
588     Tree.__init__(self, 'member')
589     self.setAttrib("name",name)
590     self.setAttrib("type",type)
591
592 class Type(Tree):
593   def __init__(self, name,kind):
594     Tree.__init__(self, 'type')
595     self.setAttrib("name",name)
596     self.setAttrib("kind",kind)
597
598   def merge(self,t):
599     self.setAttrib("kind",t.attrs["kind"])
600
601 class SeqType(Tree):
602   def __init__(self, name,content):
603     Tree.__init__(self, 'sequence')
604     self.setAttrib("name",name)
605     self.setAttrib("content",content)
606
607   def merge(self,t):
608     self.setAttrib("content",t.attrs["content"])
609
610 class StructType(Tree):
611   def __init__(self, name):
612     Tree.__init__(self, 'struct')
613     self.setAttrib("name",name)
614
615   def merge(self,t):
616     #remove childs and replace by t childs
617     self.childs=[]
618     for c in t.childs:
619       self.childs.append(c)
620
621 class ObjType(Tree):
622   def __init__(self, name):
623     Tree.__init__(self, 'objref')
624     self.setAttrib("name",name)
625
626   def merge(self,t):
627     RepoId=t.attrs.get("id")
628     if RepoId:
629       self.setAttrib("id",RepoId)
630     #remove childs and replace by t childs
631     self.childs=[]
632     for c in t.childs:
633       self.childs.append(c)
634
635 # IDL file reader
636
637 ttsMap = {
638     idltype.tk_void:       "void",
639     idltype.tk_short:      "short",
640     idltype.tk_long:       "long",
641     idltype.tk_ushort:     "unsigned short",
642     idltype.tk_ulong:      "unsigned long",
643     idltype.tk_float:      "float",
644     idltype.tk_double:     "double",
645     idltype.tk_boolean:    "boolean",
646     idltype.tk_char:       "char",
647     idltype.tk_octet:      "octet",
648     idltype.tk_any:        "any",
649     idltype.tk_TypeCode:   "CORBA::TypeCode",
650     idltype.tk_Principal:  "CORBA::Principal",
651     idltype.tk_longlong:   "long long",
652     idltype.tk_ulonglong:  "unsigned long long",
653     idltype.tk_longdouble: "long double",
654     idltype.tk_wchar:      "wchar"
655     }
656
657
658 #--------------------------------------------------
659 # class ModuleCatalogVisitor
660 #--------------------------------------------------
661 class ModuleCatalogVisitor (idlvisitor.AstVisitor):
662
663     def __init__(self, catalog):
664         self.catalog = catalog
665         self.EngineType = 0
666         self.currentScope=None
667
668     def visitAST(self, node):
669         for n in node.declarations():
670             if n.mainFile():
671               n.accept(self)
672
673     def visitModule(self, node):
674         self.currentScope=node
675         for n in node.definitions():
676             n.accept(self)
677
678     def visitInterface(self, node):
679         if node.mainFile():
680
681             self.EngineType = 0
682
683             for i in node.inherits():
684                 s = i.scopedName();
685                 if s[0] == "Engines":
686                   if s[1] == "EngineComponent":
687                     self.EngineType = 1; break
688                   if s[1] == "Superv_Component":
689                     self.EngineType = 2; break
690
691             if self.EngineType:
692               #This interface is a SALOME component
693               Comp = Component(node.identifier())
694
695               self.currentInterface = Comp.createInterface(node.identifier())
696
697               for c in node.callables():
698                 if isinstance(c, idlast.Operation):
699                     c.accept(self)
700
701               for c in node.declarations():
702                 if isinstance(c, idlast.Struct):
703                     c.accept(self)
704
705               for i in node.comments():
706                 self.currentInterface.comments.append(str(i))
707
708               if self.EngineType == 2:
709                 self.currentInterface.processDataStreams()
710
711               global nb_components
712               nb_components = nb_components + 1
713               self.catalog.mergeComponent(Comp)
714
715             else:
716               #This interface is not a component : use it as a DataType
717               t=ObjType("/".join(node.scopedName()))
718               for i in node.inherits():
719                 t.addNamedChild("base","/".join(i.scopedName()))
720               self.catalog.mergeType(t)
721
722             self.EngineType = 0
723
724
725     def visitOperation(self, node):
726
727         self.currentService = self.currentInterface.createService \
728                                        (node.identifier())
729
730         node.returnType().accept(self)
731         if (self.currentType != "void"):
732             self.currentService.createOutParameter \
733                 ("return", self.currentType)
734
735         for c in node.parameters():
736             c.accept(self)
737
738         for i in node.comments():
739             self.currentInterface.comments.append(str(i))
740
741
742     def visitDeclaredType(self, type):
743         name=type.name()
744         scoped_name="/".join(type.scopedName())
745         self.currentType = scoped_name
746
747     def visitBaseType(self, type):
748         self.currentType = ttsMap[type.kind()]
749
750     def visitStringType(self, type):
751         self.currentType = "string"
752
753     def visitWStringType(self, type):
754         self.currentType = "wstring"
755
756     def visitParameter(self, node):
757         node.paramType().accept(self)
758         if node.is_in():
759             self.currentService.createInParameter \
760                      (node.identifier(), self.currentType)
761         if node.is_out():
762             self.currentService.createOutParameter \
763                      (node.identifier(), self.currentType)
764
765     def visitSequenceType(self,type):
766       type.seqType().accept(self)
767       if type.bound() == 0:
768           self.contentType=self.currentType
769           self.currentType = "sequence"
770       else:
771           self.currentType = None
772
773     def visitTypedef(self, node):
774       if node.constrType():
775             node.aliasType().decl().accept(self)
776
777       node.aliasType().accept(self)
778       type  = self.currentType
779       if not type:
780         return
781       decll = []
782       for d in node.declarators():
783             d.accept(self)
784             if self.__result_declarator:
785               decll.append(self.__result_declarator)
786       if type == "sequence":
787         #it's a sequence type
788         for name in decll:
789           scoped_name="/".join(self.currentScope.scopedName()+[name])
790           self.catalog.mergeType(SeqType(scoped_name,self.contentType))
791       #else:
792         #it's an alias
793       #  for name in decll:
794       #    scoped_name="/".join(self.currentScope.scopedName()+[name])
795       #    self.catalog.mergeType(Type(scoped_name,type))
796
797     def visitStruct(self, node):
798       t=StructType("/".join(node.scopedName()))
799       for m in node.members():
800             if m.constrType():
801                 m.memberType().decl().accept(self)
802
803             m.memberType().accept(self)
804             type = self.currentType
805             for d in m.declarators():
806                 d.accept(self)
807                 t.addChild(Member(self.__result_declarator,type))
808
809       self.catalog.mergeType(t)
810
811     def visitDeclarator(self, node):
812         if node.sizes():
813           self.__result_declarator =None
814         else:
815           self.__result_declarator =node.identifier()
816
817 #--------------------------------------------------
818 # parse idl and store xml file
819 #--------------------------------------------------
820 def run(tree, args):
821
822     CatalogFileName=getParamValue("catalog", "CatalogModulePersonnel.xml", args)
823     if re.compile(".*?.xml$").match(CatalogFileName, 1) is None:
824         CatalogFileName = CatalogFileName + '.xml'
825
826     #=========  Read parameters  ======================
827     common_data["ICON"]       = getParamValue("icon",       "",                args)
828     common_data["AUTHOR"]     = getParamValue("author",     getUserName(),     args)
829     common_data["VERSION"]    = getParamValue("version",    "1",               args)
830     common_data["COMP_NAME"]  = getParamValue("name",       "",                args)
831     common_data["COMP_UNAME"] = getParamValue("username",   "",                args)
832     common_data["COMP_TYPE"]  = getParamValue("type",       "OTHER",           args)
833     common_data["COMP_IMPL"]  = getParamValue("impltype",   "1",               args)
834
835     print(common_data)
836
837     remove_comp = getParamValue("remove", "", args)
838
839     #==================================================
840
841     if (osp.exists(CatalogFileName)):
842         print("Importing", CatalogFileName)
843         C = Catalog(CatalogFileName)
844     else:
845         print("Creating ",CatalogFileName)
846         C = Catalog()
847
848     print("Reading idl file")
849
850     visitor = ModuleCatalogVisitor(C)
851     tree.accept(visitor)
852
853 ##    C.Dump()
854
855     if remove_comp :
856         C.removeComponent(remove_comp)
857
858     if (osp.exists(CatalogFileName)):
859         print("Updating", CatalogFileName)
860         CatalogFileName_old = CatalogFileName + '_old'
861         os.rename(CatalogFileName, CatalogFileName_old)
862     else:
863         CatalogFileName_old = ""
864         print("Writing", CatalogFileName)
865
866     CatalogFileName_new = CatalogFileName + '_new'
867     f=open(CatalogFileName_new, 'w')
868     f.write("<?xml version='1.0' encoding='us-ascii' ?>\n\n")
869     C.output_xml(f)
870     f.close()
871
872     os.rename(CatalogFileName_new, CatalogFileName)
873     if ((CatalogFileName_old != "") & osp.exists(CatalogFileName_old)):
874         os.unlink(CatalogFileName_old)
875
876     print()
877
878
879 if __name__ == "__main__":
880     print()
881     print("Usage : omniidl -bIDLparser [-I<catalog files directory>]* -Wbcatalog=<my_catalog.xml>[,icon=<pngfile>][,version=<num>][,author=<name>][,name=<component_name>][,username=<component_username>][,impltype=<implementation type : 0 (python), 1 (C++)>] <file.idl>")
882     print()