Ignore svnversion.h, it's auto-generated. Ignore lemon and except.[ch], they're
[metze/wireshark/wip.git] / tools / wireshark_be.py
1 # -*- python -*-
2 #
3 # $Id$
4 #
5 #    File      : wireshark_be.py
6 #
7 #    Author    : Frank Singleton (frank.singleton@ericsson.com)
8 #
9 #    Copyright (C) 2001 Frank Singleton, Ericsson Inc.
10 #
11 #  This file is a backend to "omniidl", used to generate "Wireshark"
12 #  dissectors from IDL descriptions. The output language generated
13 #  is "C". It will generate code to use the GIOP/IIOP get_CDR_XXX API.
14 #
15 #  Please see packet-giop.h in Wireshark distro for API description.
16 #  Wireshark is available at http://www.wireshark.org/
17 #
18 #  Omniidl is part of the OmniOrb distribution, and is available at
19 #  http://omniorb.sourceforge.net
20 #
21 #  This program is free software; you can redistribute it and/or modify it
22 #  under the terms of the GNU General Public License as published by
23 #  the Free Software Foundation; either version 2 of the License, or
24 #  (at your option) any later version.
25 #
26 #  This program is distributed in the hope that it will be useful,
27 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
28 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
29 #  General Public License for more details.
30 #
31 #  You should have received a copy of the GNU General Public License
32 #  along with this program; if not, write to the Free Software
33 #  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
34 #
35 # Description:
36 #   
37 #   Omniidl Back-end which parses an IDL data structure provided by the frontend
38 #   and generates packet-idl-xxx.[ch] for compiling as a dissector in 
39 #   Wireshark IP protocol anlayser.
40 #
41 #  
42 #
43 #
44 # Strategy. 
45 #
46 # Crawl all the way down all branches until I hit  "Operation", "Enum", "Attribute",
47 # "Struct" and "Union" nodes.  Then store these nodes in lists.
48 #
49 # Pass these lists (via an object ref) to the src code
50 # generator (wireshark_gen) class and let it do the hard work ! 
51 #
52 #
53 # Dont forget structs can contain embedded structs etc .. so dont forget
54 # to peek inside and check :-)
55 #
56 #
57
58
59 """Wireshark IDL compiler back-end."""
60
61 from omniidl import idlast, idltype, idlvisitor, idlutil, output
62 import sys, string
63 from os import path
64 from wireshark_gen import wireshark_gen_C
65
66 #
67 # This class finds the "Operation" nodes ,Enum Nodes, "Attribute" nodes, Struct Nodes
68 # and Union Nodes. Then it hands them off to an instance of the source code generator
69 # class "wireshark_gen" 
70 #
71
72 class WiresharkVisitor:
73
74     DEBUG = 0                           # debug flag
75     
76     def __init__(self, st):
77         self.st = st
78         self.oplist = []                # list of operation nodes
79         self.enlist = []                # list of enum nodes
80         self.atlist = []                # list of attribute nodes
81         self.stlist = []                # list of struct nodes
82         self.unlist = []                # list of union nodes
83
84         
85     def visitAST(self, node):
86         if self.DEBUG:
87             print "XXX visitAST() node = ", node
88             
89         for n in node.declarations():
90             if isinstance(n, idlast.Module):
91                 self.visitModule(n)
92             if isinstance(n, idlast.Interface):
93                 self.visitInterface(n)
94             if isinstance(n, idlast.Operation):
95                 self.visitOperation(n)
96             if isinstance(n, idlast.Attribute):
97                 self.visitAttribute(n)
98             if isinstance(n, idlast.Enum):
99                 self.visitEnum(n)
100             if isinstance(n, idlast.Struct):
101                 self.visitStruct(n)
102             if isinstance(n, idlast.Union):
103                 self.visitUnion(n)
104
105             # Check for Typedef structs and unions
106             
107             if isinstance(n, idlast.Typedef):
108                 self.visitTypedef(n)    # who are you ?
109                 
110                 
111     def visitModule(self, node):
112         if self.DEBUG:
113             print "XXX visitModule() node = ", node
114             
115         for n in node.definitions():
116             if isinstance(n, idlast.Module):
117                 self.visitModule(n)    
118             if isinstance(n, idlast.Interface):
119                 self.visitInterface(n)   
120             if isinstance(n, idlast.Operation):
121                 self.visitOperation(n)   
122             if isinstance(n, idlast.Attribute):
123                 self.visitAttribute(n)
124             if isinstance(n, idlast.Enum):
125                 self.visitEnum(n)
126             if isinstance(n, idlast.Struct):
127                 self.visitStruct(n)
128             if isinstance(n, idlast.Union):
129                 self.visitUnion(n)
130
131             # Check for Typedef structs and unions
132             
133             if isinstance(n, idlast.Typedef):
134                 self.visitTypedef(n)    # who are you ?
135
136                                     
137     def visitInterface(self, node):
138         if self.DEBUG:
139             print "XXX visitInterface() node = ", node
140         
141         for c in node.callables():
142             if isinstance(c, idlast.Operation):
143                 self.visitOperation(c)
144             if isinstance(c, idlast.Attribute):
145                 self.visitAttribute(c)
146                 
147         for d in node.contents():
148             if isinstance(d, idlast.Enum):
149                 self.visitEnum(d)
150                 
151             if isinstance(d, idlast.Struct):
152                 self.visitStruct(d)
153
154             if isinstance(d, idlast.Union):
155                 self.visitUnion(d)
156                 
157             # Check for Typedef structs and unions
158
159             if isinstance(d, idlast.Typedef):
160                 self.visitTypedef(d)    # who are you ?
161                 
162
163                                 
164
165     #
166     # visitOperation
167     #
168     # populates the operations node list "oplist"
169     #
170     #
171     
172     def visitOperation(self,opnode):
173         if not opnode in self.oplist:
174             self.oplist.append(opnode)      # store operation node
175
176     #
177     # visitAttribute
178     #
179     # populates the attribute node list "atlist"
180     #
181     #
182     
183     def visitAttribute(self,atnode):
184         if not atnode in self.atlist:
185             self.atlist.append(atnode)      # store attribute node
186
187
188     #
189     # visitEnum
190     #
191     # populates the Enum node list "enlist"
192     #
193     #
194     
195     def visitEnum(self,enode):
196         if not enode in self.enlist:
197             self.enlist.append(enode)      # store enum node if unique
198
199     #
200     # visitTypedef
201     #
202     # Search to see if its a typedef'd struct, union, or enum
203     #
204     # eg: typdef enum colors {red, green, blue } mycolors;
205     #
206     
207     def visitTypedef(self,td):
208         d = td.aliasType()              # get Type, possibly Declared
209         if isinstance(d,idltype.Declared):
210             self.visitDeclared(d)
211         
212
213     #
214     # visitDeclared
215     #
216     # Search to see if its a struct, union, or enum
217     #
218     #
219     
220     def visitDeclared(self,d):
221         if isinstance(d,idltype.Declared):
222             sue = d.decl()             # grab the struct or union or enum 
223             
224             if isinstance(sue, idlast.Struct):
225                 self.visitStruct(sue)                
226             if isinstance(sue, idlast.Union):
227                 self.visitUnion(sue)
228             if isinstance(sue, idlast.Enum):
229                 self.visitEnum(sue)
230
231
232
233
234     #
235     # visitStruct
236     #
237     # populates the struct node list "stlist"
238     # and checks its members also
239     #
240     #
241     
242     def visitStruct(self,stnode):
243         if not stnode in self.stlist:        
244             self.stlist.append(stnode)      # store struct node if unique and avoid recursive loops
245                                             # if we come across recursive structs
246
247             for m in stnode.members():      # find embedded struct definitions within this
248                 mt = m.memberType()
249                 if isinstance(mt,idltype.Declared):
250                     self.visitDeclared(mt)      # if declared, then check it out 
251
252
253                                                 
254     #
255     # visitUnion
256     #
257     # populates the struct node list "unlist"
258     # and checks its members also
259     #
260     #
261     
262     def visitUnion(self,unnode):
263         if not unnode in self.unlist:
264             self.unlist.append(unnode)      # store union node if unique
265
266             if unnode.constrType():         # enum defined within switch type
267                 if isinstance(unnode.switchType(),idltype.Declared):
268                     self.visitDeclared(unnode.switchType())
269
270             for c in unnode.cases():
271                 ct =  c.caseType()
272                 if isinstance(ct,idltype.Declared):
273                     self.visitDeclared(ct)      # if declared, then check it out 
274                 
275         
276
277
278 def run(tree, args):
279
280     st = output.Stream(sys.stdout, 4)   # set indent for stream
281     ev = WiresharkVisitor(st)            # create visitor object
282     
283     ev.visitAST(tree)                   # go find some operations
284     
285     #
286     # Grab name of main IDL file being compiled.
287     # 
288     # Assumption: Name is of the form   abcdefg.xyz  (eg: CosNaming.idl)
289     #
290     
291     fname = path.basename(tree.file())    # grab basename only, dont care about path
292     nl = string.split(fname,".")[0]       # split name of main IDL file using "." as separator
293                                           # and grab first field (eg: CosNaming)
294
295     if ev.DEBUG:
296         for i in ev.oplist:
297             print "XXX - Operation node ", i, " repoId() = ", i.repoId()
298         for i in ev.atlist:
299             print "XXX - Attribute node ", i, " identifiers() = ", i.identifiers()
300         for i in ev.enlist:
301             print "XXX - Enum node ", i, " repoId() = ", i.repoId()                
302         for i in ev.stlist:
303             print "XXX - Struct node ", i, " repoId() = ", i.repoId()                                             
304         for i in ev.unlist:
305             print "XXX - Union node ", i, " repoId() = ", i.repoId()
306
307             
308     # create a C generator object
309     # and generate some C code
310
311
312
313     
314     eg = wireshark_gen_C(ev.st, string.upper(nl), string.lower(nl), string.capitalize(nl) + " Dissector Using GIOP API") 
315     eg.genCode(ev.oplist, ev.atlist, ev.enlist, ev.stlist, ev.unlist)    # pass them onto the C generator
316     
317
318