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