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