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