Add *.sbr files to the clean target.
[obnox/wireshark/wip.git] / tools / wireshark_gen.py
1 # -*- python -*-
2 #
3 # $Id$
4 #
5 # wireshark_gen.py (part of idl2wrs)
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 CORBA 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.wiresharl.org/
17 #
18 #  Omniidl is part of the OmniOrb distribution, and is available at
19 #  http://www.uk.research.att.com/omniORB/omniORB.html
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., 59 Temple Place - Suite 330, Boston, MA
34 #  02111-1307, USA.
35 #
36 # Description:
37 #
38 #   Omniidl Back-end which parses an IDL list of "Operation" nodes
39 #   passed from wireshark_be2.py and generates "C" code for compiling
40 #   as a plugin for the  Wireshark IP Protocol Analyser.
41 #
42 #
43 # Strategy (sneaky but ...)
44 #
45 # problem: I dont know what variables to declare until AFTER the helper functions
46 # have been built, so ...
47 #
48 # There are 2 passes through genHelpers, the first one is there just to
49 # make sure the fn_hash data struct is populated properly.
50 # The second pass is the real thing, generating code and declaring
51 # variables (from the 1st pass) properly.
52 #
53
54
55 """Wireshark IDL compiler back-end."""
56
57 from omniidl import idlast, idltype, idlutil, output
58 import sys, string
59 import tempfile
60
61 #
62 # Output class, generates "C" src code for the sub-dissector
63 #
64 # in:
65 #
66 #
67 # self - me
68 # st   - output stream
69 # node - a reference to an Operations object.
70 # name - scoped name (Module::Module::Interface:: .. ::Operation
71 #
72
73
74
75 #
76 # TODO -- FS
77 #
78 # 1. generate hf[] data for searchable fields (but what is searchable?)
79 # 2. add item instead of add_text()
80 # 3. sequence handling [done]
81 # 4. User Exceptions [done]
82 # 5. Fix arrays, and structs containing arrays [done]
83 # 6. Handle pragmas.
84 # 7. Exception can be common to many operations, so handle them outside the
85 #    operation helper functions [done]
86 # 8. Automatic variable declaration [done, improve, still get some collisions.add variable delegator function ]
87 #    For example, mutlidimensional arrays.
88 # 9. wchar and wstring handling [giop API needs improving]
89 # 10. Support Fixed [done]
90 # 11. Support attributes (get/set) [started, needs language mapping option, perhaps wireshark GUI option
91 #     to set the attribute function prefix or suffix ? ] For now the prefix is "_get" and "_set"
92 #     eg: attribute string apple  =>   _get_apple and _set_apple
93 #
94 # 12. Implement IDL "union" code [done]
95 # 13. Implement support for plugins [done]
96 # 14. Dont generate code for empty operations (cf: exceptions without members)
97 # 15. Generate code to display Enums numerically and symbolically [done]
98 # 16. Place structs/unions in subtrees
99 # 17. Recursive struct and union handling [done ]
100 # 18. Improve variable naming for display (eg: structs, unions etc)
101 #
102 # Also test, Test, TEST
103 #
104
105
106
107 #
108 #   Strategy:
109 #    For every operation and attribute do
110 #       For return val and all parameters do
111 #       find basic IDL type for each parameter
112 #       output get_CDR_xxx
113 #       output exception handling code
114 #       output attribute handling code
115 #
116 #
117
118 class wireshark_gen_C:
119
120
121     #
122     # Turn DEBUG stuff on/off
123     #
124
125     DEBUG = 0
126
127     #
128     # Some string constants for our templates
129     #
130     c_u_octet8    = "guint64   u_octet8;"  
131     c_s_octet8    = "gint64    s_octet8;"  
132     c_u_octet4    = "guint32   u_octet4;"
133     c_s_octet4    = "gint32    s_octet4;"
134     c_u_octet2    = "guint16   u_octet2;"
135     c_s_octet2    = "gint16    s_octet2;"
136     c_u_octet1    = "guint8    u_octet1;"
137     c_s_octet1    = "gint8     s_octet1;"
138
139     c_float       = "gfloat    my_float;"
140     c_double      = "gdouble   my_double;"
141
142     c_seq         = "gchar   *seq = NULL;"          # pointer to buffer of gchars
143     c_i           = "guint32   i_";                 # loop index
144     c_i_lim       = "guint32   u_octet4_loop_";     # loop limit
145     c_u_disc      = "guint32   disc_u_";            # unsigned int union discriminant variable name (enum)
146     c_s_disc      = "gint32    disc_s_";            # signed int union discriminant variable name (other cases, except Enum)
147
148     #
149     # Constructor
150     #
151
152     def __init__(self, st, protocol_name, dissector_name ,description):
153         self.st = output.Stream(tempfile.TemporaryFile(),4) # for first pass only
154
155         self.st_save = st               # where 2nd pass should go
156         self.protoname = protocol_name  # Protocol Name (eg: ECHO)
157         self.dissname = dissector_name  # Dissector name (eg: echo)
158         self.description = description  # Detailed Protocol description (eg: Echo IDL Example)
159         self.exlist = []                # list of exceptions used in operations.
160         #self.curr_sname                # scoped name of current opnode or exnode I am visiting, used for generating "C" var declares
161         self.fn_hash = {}               # top level hash to contain key = function/exception and val = list of variable declarations
162                                         # ie a hash of lists
163         self.fn_hash_built = 0          # flag to indicate the 1st pass is complete, and the fn_hash is correctly
164                                         # populated with operations/vars and exceptions/vars
165
166
167     #
168     # genCode()
169     #
170     # Main entry point, controls sequence of
171     # generated code.
172     #
173     #
174
175     def genCode(self,oplist, atlist, enlist, stlist, unlist):   # operation,attribute,enums,struct and union lists
176
177
178         self.genHelpers(oplist,stlist,unlist)  # sneaky .. call it now, to populate the fn_hash
179                                         # so when I come to that operation later, I have the variables to
180                                         # declare already.
181
182         self.genExceptionHelpers(oplist) # sneaky .. call it now, to populate the fn_hash
183                                          # so when I come to that exception later, I have the variables to
184                                          # declare already.
185
186         self.genAttributeHelpers(atlist) # sneaky .. call it now, to populate the fn_hash
187                                          # so when I come to that exception later, I have the variables to
188                                          # declare already.
189
190
191         self.fn_hash_built = 1          # DONE, so now I know , see genOperation()
192
193         self.st = self.st_save
194         self.genHeader()                # initial dissector comments
195         self.genEthCopyright()          # Wireshark Copyright comments.
196         self.genGPL()                   # GPL license
197         self.genIncludes()
198         self.genDeclares(oplist,atlist,enlist,stlist,unlist)
199         self.genProtocol()
200         self.genRegisteredFields()
201         self.genOpList(oplist)          # string constant declares for operation names
202         self.genExList(oplist)          # string constant declares for user exceptions
203         self.genAtList(atlist)          # string constant declares for Attributes
204         self.genEnList(enlist)          # string constant declares for Enums
205
206
207         self.genExceptionHelpers(oplist)   # helper function to decode user exceptions that have members
208         self.genExceptionDelegator(oplist) # finds the helper function to decode a user exception
209         self.genAttributeHelpers(atlist)   # helper function to decode "attributes"
210
211         self.genHelpers(oplist,stlist,unlist)  # operation, struct and union decode helper functions
212
213         self.genMainEntryStart(oplist)
214         self.genOpDelegator(oplist)
215         self.genAtDelegator(atlist)
216         self.genMainEntryEnd()
217
218         self.gen_proto_register()
219         self.gen_proto_reg_handoff(oplist)
220         self.gen_plugin_register()
221
222         #self.dumpvars()                 # debug
223
224
225
226     #
227     # genHeader
228     #
229     # Generate Standard Wireshark Header Comments
230     #
231     #
232
233     def genHeader(self):
234         self.st.out(self.template_Header,dissector_name=self.dissname)
235         if self.DEBUG:
236             print "XXX genHeader"
237
238
239
240
241     #
242     # genEthCopyright
243     #
244     # Wireshark Copyright Info
245     #
246     #
247
248     def genEthCopyright(self):
249         if self.DEBUG:
250             print "XXX genEthCopyright"
251         self.st.out(self.template_wireshark_copyright)
252
253
254     #
255     # genGPL
256     #
257     # GPL licencse
258     #
259     #
260
261     def genGPL(self):
262         if self.DEBUG:
263             print "XXX genGPL"
264
265         self.st.out(self.template_GPL)
266
267     #
268     # genIncludes
269     #
270     # GPL licencse
271     #
272     #
273
274     def genIncludes(self):
275         if self.DEBUG:
276             print "XXX genIncludes"
277
278         self.st.out(self.template_Includes)
279
280
281     #
282     # denDeclares
283     #
284     # generate function prototypes if required
285     #
286     # Currently this is used for struct and union helper function declarations.
287     #
288
289
290     def genDeclares(self,oplist,atlist,enlist,stlist,unlist):
291         if self.DEBUG:
292             print "XXX genDeclares"
293
294         # prototype for start_dissecting()
295
296         self.st.out(self.template_prototype_start_dissecting)
297
298         # struct prototypes
299
300         self.st.out(self.template_prototype_struct_start)
301         for st in stlist:
302             #print st.repoId()
303             sname = self.namespace(st, "_")
304
305             self.st.out(self.template_prototype_struct_body, stname=st.repoId(),name=sname)
306         self.st.out(self.template_prototype_struct_end)
307
308         # union prototypes
309
310         self.st.out(self.template_prototype_union_start)
311         for un in unlist:
312             sname = self.namespace(un, "_")
313             self.st.out(self.template_prototype_union_body, unname=un.repoId(),name=sname)
314         self.st.out(self.template_prototype_union_end)
315
316
317
318
319     #
320     # genProtocol
321     #
322     #
323
324     def genProtocol(self):
325         self.st.out(self.template_protocol, dissector_name=self.dissname)
326         self.st.out(self.template_init_boundary)
327
328
329     #
330     # genProtoAndRegisteredFields
331     #
332     #
333
334     def genRegisteredFields(self):
335         self.st.out(self.template_registered_fields )
336
337
338
339     #
340     # genMainEntryStart
341     #
342
343     def genMainEntryStart(self,oplist):
344         self.st.out(self.template_main_dissector_start, dissname=self.dissname, disprot=self.protoname)
345         self.st.inc_indent()
346         self.st.out(self.template_main_dissector_switch_msgtype_start)
347         self.st.out(self.template_main_dissector_switch_msgtype_start_request_reply)
348         self.st.inc_indent()
349
350
351     #
352     # genMainEntryEnd
353     #
354
355     def genMainEntryEnd(self):
356
357         self.st.out(self.template_main_dissector_switch_msgtype_end_request_reply)
358         self.st.dec_indent()
359         self.st.out(self.template_main_dissector_switch_msgtype_all_other_msgtype)
360         self.st.dec_indent()
361         self.st.out(self.template_main_dissector_end)
362
363
364     #
365     # genOpList
366     #
367     # in: oplist
368     #
369     # out: C code for IDL operations
370     #
371     # eg:
372     #
373     # static const char Penguin_Echo_echoShort_op[] = "echoShort" ;
374     #
375
376     def genOpList(self,oplist):
377         self.st.out(self.template_comment_operations_start)
378
379         for n in oplist:
380             sname = self.namespace(n, "_")
381             opname = n.identifier()
382             self.st.out(self.template_operations_declare, sname=sname, opname=opname)
383
384         self.st.out(self.template_comment_operations_end)
385
386     #
387     # genExList
388     #
389     # in: oplist
390     #
391     # out: C code for IDL User Exceptions that contain members
392     #
393     # eg:
394     #
395     # static const char user_exception_tux_bad_value[] = "IDL:tux/bad_value:1.0" ;
396     #
397
398     def genExList(self,oplist):
399
400         self.st.out(self.template_comment_user_exceptions_string_declare_start)
401
402         exlist = self.get_exceptionList(oplist) # grab list of ALL UNIQUE exception nodes
403
404         for ex in exlist:
405             if self.DEBUG:
406                 print "XXX Exception " , ex.repoId()
407                 print "XXX Exception Identifier" , ex.identifier()
408                 print "XXX Exception Scoped Name" , ex.scopedName()
409
410             if (ex.members()):          # only if has members
411                 sname = self.namespace(ex, "_")
412                 exname = ex.repoId()
413                 self.st.out(self.template_user_exceptions_declare,  sname=sname, exname=ex.repoId())
414
415         self.st.out(self.template_comment_user_exceptions_string_declare_end)
416
417     #
418     # genAtList
419     #
420     # in: atlist
421     #
422     # out: C code for IDL attribute decalarations.
423     #
424     # NOTE: Mapping of attributes to  operation(function) names is tricky.
425     #
426     # The actual accessor function names are language-mapping specific. The attribute name
427     # is subject to OMG IDL's name scoping rules; the accessor function names are
428     # guaranteed not to collide with any legal operation names specifiable in OMG IDL.
429     #
430     # eg:
431     #
432     # static const char get_Penguin_Echo_get_width_at[] = "get_width" ;
433     # static const char set_Penguin_Echo_set_width_at[] = "set_width" ;
434     #
435     # or:
436     #
437     # static const char get_Penguin_Echo_get_width_at[] = "_get_width" ;
438     # static const char set_Penguin_Echo_set_width_at[] = "_set_width" ;
439     #
440     # TODO: Implement some language dependant templates to handle naming conventions
441     #       language <=> attribute. for C, C++. Java etc
442     #
443     # OR, just add a runtime GUI option to select language binding for attributes -- FS
444     #
445     #
446     #
447     # ie: def genAtlist(self,atlist,language)
448     #
449
450
451
452     def genAtList(self,atlist):
453         self.st.out(self.template_comment_attributes_start)
454
455         for n in atlist:
456             for i in n.declarators():   #
457                 sname = self.namespace(i, "_")
458                 atname = i.identifier()
459                 self.st.out(self.template_attributes_declare_Java_get, sname=sname, atname=atname)
460                 if not n.readonly():
461                     self.st.out(self.template_attributes_declare_Java_set, sname=sname, atname=atname)
462
463         self.st.out(self.template_comment_attributes_end)
464
465
466     #
467     # genEnList
468     #
469     # in: enlist
470     #
471     # out: C code for IDL Enum decalarations using "static const value_string" template
472     #
473
474
475
476     def genEnList(self,enlist):
477
478         self.st.out(self.template_comment_enums_start)
479
480         for enum in enlist:
481             sname = self.namespace(enum, "_")
482
483             self.st.out(self.template_comment_enum_comment, ename=enum.repoId())
484             self.st.out(self.template_value_string_start, valstringname=sname)
485             for enumerator in enum.enumerators():
486                 self.st.out(self.template_value_string_entry, intval=str(self.valFromEnum(enum,enumerator)), description=enumerator.identifier())
487
488
489             #atname = n.identifier()
490             self.st.out(self.template_value_string_end, valstringname=sname)
491
492         self.st.out(self.template_comment_enums_end)
493
494
495
496
497
498
499
500
501
502
503     #
504     # genExceptionDelegator
505     #
506     # in: oplist
507     #
508     # out: C code for User exception delegator
509     #
510     # eg:
511     #
512     #
513
514     def genExceptionDelegator(self,oplist):
515
516         self.st.out(self.template_main_exception_delegator_start)
517         self.st.inc_indent()
518
519         exlist = self.get_exceptionList(oplist) # grab list of ALL UNIQUE exception nodes
520
521         for ex in exlist:
522             if self.DEBUG:
523                 print "XXX Exception " , ex.repoId()
524                 print "XXX Exception Identifier" , ex.identifier()
525                 print "XXX Exception Scoped Name" , ex.scopedName()
526
527             if (ex.members()):          # only if has members
528                 sname = self.namespace(ex, "_")
529                 exname = ex.repoId()
530                 self.st.out(self.template_ex_delegate_code,  sname=sname, exname=ex.repoId())
531
532         self.st.dec_indent()
533         self.st.out(self.template_main_exception_delegator_end)
534
535
536     #
537     # genAttribueHelpers()
538     #
539     # Generate private helper functions to decode Attributes.
540     #
541     # in: atlist
542     #
543     # For readonly attribute - generate get_xxx()
544     # If NOT readonly attribute - also generate set_xxx()
545     #
546
547     def genAttributeHelpers(self,atlist):
548         if self.DEBUG:
549             print "XXX genAttributeHelpers: atlist = ", atlist
550
551         self.st.out(self.template_attribute_helpers_start)
552
553         for attrib in atlist:
554             for decl in attrib.declarators():
555                 self.genAtHelper(attrib,decl,"get") # get accessor
556                 if not attrib.readonly():
557                     self.genAtHelper(attrib,decl,"set") # set accessor
558
559         self.st.out(self.template_attribute_helpers_end)
560
561     #
562     # genAtHelper()
563     #
564     # Generate private helper functions to decode an attribute
565     #
566     # in: at - attribute node
567     # in: decl - declarator belonging to this attribute
568     # in: order - to generate a "get" or "set" helper
569
570     def genAtHelper(self,attrib,decl,order):
571         if self.DEBUG:
572             print "XXX genAtHelper"
573
574         sname = order + "_" + self.namespace(decl, "_")  # must use set or get prefix to avoid collision
575         self.curr_sname = sname                    # update current opnode/exnode scoped name
576
577         if not self.fn_hash_built:
578             self.fn_hash[sname] = []        # init empty list as val for this sname key
579                                             # but only if the fn_hash is not already built
580
581         self.st.out(self.template_attribute_helper_function_start, sname=sname, atname=decl.repoId())
582         self.st.inc_indent()
583
584         self.st.out(self.template_helper_function_vars_start)
585         self.dumpCvars(sname)
586         self.st.out(self.template_helper_function_vars_end )
587
588         #
589         # TODO - attributes are simple types, so remove array handling
590         #
591
592         if decl.sizes():        # an array
593             indices = self.get_indices_from_sizes(decl.sizes())
594             string_indices = '%i ' % indices # convert int to string
595             self.st.out(self.template_get_CDR_array_comment, aname=decl.identifier(), asize=string_indices)
596             self.st.out(self.template_get_CDR_array_start, aname=decl.identifier(), aval=string_indices)
597             self.addvar(self.c_i + decl.identifier() + ";")
598
599             self.st.inc_indent()
600
601             self.getCDR3(attrib.attrType(), decl.identifier() )
602
603             self.st.dec_indent()
604             self.st.out(self.template_get_CDR_array_end)
605
606
607         else:
608
609             self.getCDR3(attrib.attrType(), decl.identifier() )
610
611         self.st.dec_indent()
612         self.st.out(self.template_attribute_helper_function_end)
613
614
615
616     #
617     # genExceptionHelpers()
618     #
619     # Generate private helper functions to decode Exceptions used
620     # within operations
621     #
622     # in: oplist
623     #
624
625
626     def genExceptionHelpers(self,oplist):
627         exlist = self.get_exceptionList(oplist) # grab list of exception nodes
628         if self.DEBUG:
629             print "XXX genExceptionHelpers: exlist = ", exlist
630
631         self.st.out(self.template_exception_helpers_start)
632         for ex in exlist:
633             if (ex.members()):          # only if has members
634                 #print "XXX Exception = " + ex.identifier()
635                 self.genExHelper(ex)
636
637         self.st.out(self.template_exception_helpers_end)
638
639
640     #
641     # genExhelper()
642     #
643     # Generate private helper functions to decode User Exceptions
644     #
645     # in: exnode ( an exception node)
646     #
647
648     def genExHelper(self,ex):
649         if self.DEBUG:
650             print "XXX genExHelper"
651
652         sname = self.namespace(ex, "_")
653         self.curr_sname = sname         # update current opnode/exnode scoped name
654         if not self.fn_hash_built:
655             self.fn_hash[sname] = []        # init empty list as val for this sname key
656                                             # but only if the fn_hash is not already built
657
658         self.st.out(self.template_exception_helper_function_start, sname=sname, exname=ex.repoId())
659         self.st.inc_indent()
660
661         self.st.out(self.template_helper_function_vars_start)
662         self.dumpCvars(sname)
663         self.st.out(self.template_helper_function_vars_end )
664
665
666         for m in ex.members():
667             #print "XXX genExhelper, member = ", m, "member type = ", m.memberType()
668
669
670             for decl in m.declarators():
671                 #print "XXX genExhelper, d = ", decl
672                 if decl.sizes():        # an array
673                     indices = self.get_indices_from_sizes(decl.sizes())
674                     string_indices = '%i ' % indices # convert int to string
675                     self.st.out(self.template_get_CDR_array_comment, aname=decl.identifier(), asize=string_indices)
676                     self.st.out(self.template_get_CDR_array_start, aname=decl.identifier(), aval=string_indices)
677                     self.addvar(self.c_i + decl.identifier() + ";")
678
679                     self.st.inc_indent()
680                     self.getCDR3(m.memberType(), ex.identifier() + "_" + decl.identifier() )
681
682                     self.st.dec_indent()
683                     self.st.out(self.template_get_CDR_array_end)
684
685
686                 else:
687                     self.getCDR3(m.memberType(), ex.identifier() + "_" + decl.identifier() )
688
689         self.st.dec_indent()
690         self.st.out(self.template_exception_helper_function_end)
691
692
693     #
694     # genHelpers()
695     #
696     # Generate private helper functions for each IDL operation.
697     # Generate private helper functions for each IDL struct.
698     # Generate private helper functions for each IDL union.
699     #
700     #
701     # in: oplist, stlist, unlist
702     #
703
704
705     def genHelpers(self,oplist,stlist,unlist):
706         for op in oplist:
707             self.genOperation(op)
708         for st in stlist:
709             self.genStructHelper(st)
710         for un in unlist:
711             self.genUnionHelper(un)
712
713     #
714     # genOperation()
715     #
716     # Generate private helper functions for a specificIDL operation.
717     #
718     # in: opnode
719     #
720
721     def genOperation(self,opnode):
722         if self.DEBUG:
723             print "XXX genOperation called"
724
725         sname = self.namespace(opnode, "_")
726         if not self.fn_hash_built:
727             self.fn_hash[sname] = []        # init empty list as val for this sname key
728                                             # but only if the fn_hash is not already built
729
730         self.curr_sname = sname         # update current opnode's scoped name
731         opname = opnode.identifier()
732
733         self.st.out(self.template_helper_function_comment, repoid=opnode.repoId() )
734
735         self.st.out(self.template_helper_function_start, sname=sname)
736         self.st.inc_indent()
737
738         self.st.out(self.template_helper_function_vars_start)
739         self.dumpCvars(sname)
740         self.st.out(self.template_helper_function_vars_end )
741
742
743         self.st.out(self.template_helper_switch_msgtype_start)
744
745         self.st.out(self.template_helper_switch_msgtype_request_start)
746         self.st.inc_indent()
747         self.genOperationRequest(opnode)
748         self.st.out(self.template_helper_switch_msgtype_request_end)
749         self.st.dec_indent()
750
751         self.st.out(self.template_helper_switch_msgtype_reply_start)
752         self.st.inc_indent()
753
754         self.st.out(self.template_helper_switch_rep_status_start)
755
756
757         self.st.out(self.template_helper_switch_msgtype_reply_no_exception_start)
758         self.st.inc_indent()
759         self.genOperationReply(opnode)
760         self.st.out(self.template_helper_switch_msgtype_reply_no_exception_end)
761         self.st.dec_indent()
762
763         self.st.out(self.template_helper_switch_msgtype_reply_user_exception_start)
764         self.st.inc_indent()
765         self.genOpExceptions(opnode)
766         self.st.out(self.template_helper_switch_msgtype_reply_user_exception_end)
767         self.st.dec_indent()
768
769         self.st.out(self.template_helper_switch_msgtype_reply_default_start)
770         self.st.out(self.template_helper_switch_msgtype_reply_default_end)
771
772         self.st.out(self.template_helper_switch_rep_status_end)
773
774         self.st.dec_indent()
775
776         self.st.out(self.template_helper_switch_msgtype_default_start)
777         self.st.out(self.template_helper_switch_msgtype_default_end)
778
779         self.st.out(self.template_helper_switch_msgtype_end)
780         self.st.dec_indent()
781
782
783         self.st.out(self.template_helper_function_end, sname=sname)
784
785
786
787
788     #
789     # Decode function parameters for a GIOP request message
790     #
791     #
792
793     def genOperationRequest(self,opnode):
794         for p in opnode.parameters():
795             if p.is_in():
796                 if self.DEBUG:
797                     print "XXX parameter = " ,p
798                     print "XXX parameter type = " ,p.paramType()
799                     print "XXX parameter type kind = " ,p.paramType().kind()
800
801                 self.getCDR3(p.paramType(),p.identifier())
802
803
804     #
805     # Decode function parameters for a GIOP reply message
806     #
807
808
809     def genOperationReply(self,opnode):
810
811         rt = opnode.returnType()        # get return type
812         if self.DEBUG:
813             print "XXX opnode  = " , opnode
814             print "XXX return type  = " , rt
815             print "XXX return type.unalias  = " , rt.unalias()
816             print "XXX return type.kind()  = " , rt.kind();
817
818
819         if (rt.kind() == idltype.tk_alias): # a typdef return val possibly ?
820             #self.getCDR3(rt.decl().alias().aliasType(),"dummy")    # return value maybe a typedef
821             #self.get_CDR_alias(rt, "Operation_Return_Value" )
822             self.get_CDR_alias(rt, rt.name() )
823
824         else:
825             self.getCDR3(rt, "Operation_Return_Value")    # return value is NOT an alias
826
827         for p in opnode.parameters():
828             if p.is_out():              # out or inout
829                 self.getCDR3(p.paramType(),p.identifier())
830
831         #self.st.dec_indent()
832
833     def genOpExceptions(self,opnode):
834         for ex in opnode.raises():
835             if ex.members():
836                 #print ex.members()
837                 for m in ex.members():
838                     t=0
839                     #print m.memberType(), m.memberType().kind()
840     #
841     # Delegator for Operations
842     #
843
844     def genOpDelegator(self,oplist):
845         for op in oplist:
846             iname = "/".join(op.scopedName()[:-1])
847             opname = op.identifier()
848             sname = self.namespace(op, "_")
849             self.st.out(self.template_op_delegate_code, interface=iname, sname=sname)
850
851     #
852     # Delegator for Attributes
853     #
854
855     def genAtDelegator(self,atlist):
856         for a in atlist:
857             for i in a.declarators():
858                 atname = i.identifier()
859                 sname = self.namespace(i, "_")
860                 self.st.out(self.template_at_delegate_code_get, sname=sname)
861                 if not a.readonly():
862                     self.st.out(self.template_at_delegate_code_set, sname=sname)
863
864
865     #
866     # Add a variable declaration to the hash of list
867     #
868
869     def addvar(self, var):
870         if not ( var in self.fn_hash[self.curr_sname] ):
871             self.fn_hash[self.curr_sname].append(var)
872
873     #
874     # Print the variable declaration from  the hash of list
875     #
876
877
878     def dumpvars(self):
879         for fn in self.fn_hash.keys():
880             print "FN = " + fn
881             for v in self.fn_hash[fn]:
882                 print "-> " + v
883     #
884     # Print the "C" variable declaration from  the hash of list
885     # for a given scoped operation name (eg: tux_penguin_eat)
886     #
887
888
889     def dumpCvars(self, sname):
890             for v in self.fn_hash[sname]:
891                 self.st.out(v)
892
893
894     #
895     # Given an enum node, and a enumerator node, return
896     # the enumerator's numerical value.
897     #
898     # eg: enum Color {red,green,blue} should return
899     # val = 1 for green
900     #
901
902     def valFromEnum(self,enumNode, enumeratorNode):
903         if self.DEBUG:
904             print "XXX valFromEnum, enumNode = ", enumNode, " from ", enumNode.repoId()
905             print "XXX valFromEnum, enumeratorNode = ", enumeratorNode, " from ", enumeratorNode.repoId()
906
907         if isinstance(enumeratorNode,idlast.Enumerator):
908             value = enumNode.enumerators().index(enumeratorNode)
909             return value
910
911
912 ## tk_null               = 0
913 ## tk_void               = 1
914 ## tk_short              = 2
915 ## tk_long               = 3
916 ## tk_ushort             = 4
917 ## tk_ulong              = 5
918 ## tk_float              = 6
919 ## tk_double             = 7
920 ## tk_boolean            = 8
921 ## tk_char               = 9
922 ## tk_octet              = 10
923 ## tk_any                = 11
924 ## tk_TypeCode           = 12
925 ## tk_Principal          = 13
926 ## tk_objref             = 14
927 ## tk_struct             = 15
928 ## tk_union              = 16
929 ## tk_enum               = 17
930 ## tk_string             = 18
931 ## tk_sequence           = 19
932 ## tk_array              = 20
933 ## tk_alias              = 21
934 ## tk_except             = 22
935 ## tk_longlong           = 23
936 ## tk_ulonglong          = 24
937 ## tk_longdouble         = 25
938 ## tk_wchar              = 26
939 ## tk_wstring            = 27
940 ## tk_fixed              = 28
941 ## tk_value              = 29
942 ## tk_value_box          = 30
943 ## tk_native             = 31
944 ## tk_abstract_interface = 32
945
946
947     #
948     # getCDR()
949     #
950     # This is the main "iterator" function. It takes a node, and tries to output
951     # a get_CDR_XXX accessor method(s). It can call itself multiple times
952     # if I find nested structures etc.
953     #
954
955     def getCDR3(self,type,name="fred"):
956
957         pt = type.unalias().kind()      # param CDR type
958         pn = name                       # param name
959
960         if self.DEBUG:
961             print "XXX getCDR3: kind = " , pt
962
963         if pt == idltype.tk_ulong:
964             self.get_CDR_ulong(pn)
965         elif pt == idltype.tk_longlong:
966             self.get_CDR_longlong(pn)
967         elif pt == idltype.tk_ulonglong:
968             self.get_CDR_ulonglong(pn)
969         elif pt ==  idltype.tk_void:
970             self.get_CDR_void(pn)
971         elif pt ==  idltype.tk_short:
972             self.get_CDR_short(pn)
973         elif pt ==  idltype.tk_long:
974             self.get_CDR_long(pn)
975         elif pt ==  idltype.tk_ushort:
976             self.get_CDR_ushort(pn)
977         elif pt ==  idltype.tk_float:
978             self.get_CDR_float(pn)
979         elif pt ==  idltype.tk_double:
980             self.get_CDR_double(pn)
981         elif pt == idltype.tk_fixed:
982             self.get_CDR_fixed(type.unalias(),pn)
983         elif pt ==  idltype.tk_boolean:
984             self.get_CDR_boolean(pn)
985         elif pt ==  idltype.tk_char:
986             self.get_CDR_char(pn)
987         elif pt ==  idltype.tk_octet:
988             self.get_CDR_octet(pn)
989         elif pt ==  idltype.tk_any:
990             self.get_CDR_any(pn)
991         elif pt ==  idltype.tk_string:
992             self.get_CDR_string(pn)
993         elif pt ==  idltype.tk_wstring:
994             self.get_CDR_wstring(pn)
995         elif pt ==  idltype.tk_wchar:
996             self.get_CDR_wchar(pn)
997         elif pt ==  idltype.tk_enum:
998             #print type.decl()
999             self.get_CDR_enum(pn,type)
1000             #self.get_CDR_enum(pn)
1001
1002         elif pt ==  idltype.tk_struct:
1003             self.get_CDR_struct(type,pn)
1004         elif pt ==  idltype.tk_TypeCode: # will I ever get here ?
1005             self.get_CDR_TypeCode(pn)
1006         elif pt == idltype.tk_sequence and \
1007                  type.unalias().seqType().kind() == idltype.tk_octet:
1008             self.get_CDR_sequence_octet(type,pn)
1009         elif pt == idltype.tk_sequence:
1010             self.get_CDR_sequence(type,pn)
1011         elif pt == idltype.tk_objref:
1012             self.get_CDR_objref(type,pn)
1013         elif pt == idltype.tk_array:
1014             self.get_CDR_array(type,pn)
1015         elif pt == idltype.tk_union:
1016             self.get_CDR_union(type,pn)
1017         elif pt == idltype.tk_alias:
1018             if self.DEBUG:
1019                 print "XXXXX Alias type XXXXX " , type
1020             self.get_CDR_alias(type,pn)
1021         else:
1022             self.genWARNING("Unknown typecode = " + '%i ' % pt) # put comment in source code
1023
1024
1025     #
1026     # get_CDR_XXX methods are here ..
1027     #
1028     #
1029
1030
1031     def get_CDR_ulong(self,pn):
1032         self.st.out(self.template_get_CDR_ulong, varname=pn)
1033         self.addvar(self.c_u_octet4)
1034
1035     def get_CDR_short(self,pn):
1036         self.st.out(self.template_get_CDR_short, varname=pn)
1037         self.addvar(self.c_s_octet2)
1038
1039     def get_CDR_void(self,pn):
1040         self.st.out(self.template_get_CDR_void, varname=pn)
1041
1042     def get_CDR_long(self,pn):
1043         self.st.out(self.template_get_CDR_long, varname=pn)
1044         self.addvar(self.c_s_octet4)
1045
1046     def get_CDR_ushort(self,pn):
1047         self.st.out(self.template_get_CDR_ushort, varname=pn)
1048         self.addvar(self.c_u_octet2)
1049
1050     def get_CDR_float(self,pn):
1051         self.st.out(self.template_get_CDR_float, varname=pn)
1052         self.addvar(self.c_float)
1053
1054     def get_CDR_double(self,pn):
1055         self.st.out(self.template_get_CDR_double, varname=pn)
1056         self.addvar(self.c_double)
1057
1058     def get_CDR_longlong(self,pn):
1059         self.st.out(self.template_get_CDR_longlong, varname=pn)
1060         self.addvar(self.c_s_octet8)
1061
1062     def get_CDR_ulonglong(self,pn):
1063         self.st.out(self.template_get_CDR_ulonglong, varname=pn)
1064         self.addvar(self.c_u_octet8)
1065
1066     def get_CDR_boolean(self,pn):
1067         self.st.out(self.template_get_CDR_boolean, varname=pn)
1068         self.addvar(self.c_u_octet1)
1069
1070     def get_CDR_fixed(self,type,pn):
1071         if self.DEBUG:
1072             print "XXXX calling get_CDR_fixed, type = ", type
1073             print "XXXX calling get_CDR_fixed, type.digits() = ", type.digits()
1074             print "XXXX calling get_CDR_fixed, type.scale() = ", type.scale()
1075
1076         string_digits = '%i ' % type.digits() # convert int to string
1077         string_scale  = '%i ' % type.scale()  # convert int to string
1078         string_length  = '%i ' % self.dig_to_len(type.digits())  # how many octets to hilight for a number of digits
1079
1080         self.st.out(self.template_get_CDR_fixed, varname=pn, digits=string_digits, scale=string_scale, length=string_length )
1081         self.addvar(self.c_seq)
1082
1083
1084     def get_CDR_char(self,pn):
1085         self.st.out(self.template_get_CDR_char, varname=pn)
1086         self.addvar(self.c_u_octet1)
1087
1088     def get_CDR_octet(self,pn):
1089         self.st.out(self.template_get_CDR_octet, varname=pn)
1090         self.addvar(self.c_u_octet1)
1091
1092     def get_CDR_any(self,pn):
1093         self.st.out(self.template_get_CDR_any, varname=pn)
1094
1095     def get_CDR_enum(self,pn,type):
1096         #self.st.out(self.template_get_CDR_enum, varname=pn)
1097         sname = self.namespace(type.unalias(), "_")
1098         self.st.out(self.template_get_CDR_enum_symbolic, valstringarray=sname,varname=pn)
1099
1100
1101         self.addvar(self.c_u_octet4)
1102
1103     def get_CDR_string(self,pn):
1104         self.st.out(self.template_get_CDR_string, varname=pn)
1105         self.addvar(self.c_u_octet4)
1106         self.addvar(self.c_seq)
1107
1108     def get_CDR_wstring(self,pn):
1109         self.st.out(self.template_get_CDR_wstring, varname=pn)
1110         self.addvar(self.c_u_octet4)
1111         self.addvar(self.c_seq)
1112
1113     def get_CDR_wchar(self,pn):
1114         self.st.out(self.template_get_CDR_wchar, varname=pn)
1115         self.addvar(self.c_s_octet1)
1116         self.addvar(self.c_seq)
1117
1118     def get_CDR_TypeCode(self,pn):
1119         self.st.out(self.template_get_CDR_TypeCode, varname=pn)
1120         self.addvar(self.c_u_octet4)
1121
1122     def get_CDR_objref(self,type,pn):
1123         self.st.out(self.template_get_CDR_object)
1124
1125     def get_CDR_sequence_len(self,pn):
1126         self.st.out(self.template_get_CDR_sequence_length, seqname=pn)
1127         self.addvar(self.c_u_octet4)
1128
1129
1130
1131     def get_CDR_union(self,type,pn):
1132         if self.DEBUG:
1133             print "XXX Union type =" , type, " pn = ",pn
1134             print "XXX Union type.decl()" , type.decl()
1135             print "XXX Union Scoped Name" , type.scopedName()
1136
1137        #  If I am a typedef union {..}; node then find the union node
1138
1139         if isinstance(type.decl(), idlast.Declarator):
1140             ntype = type.decl().alias().aliasType().decl()
1141         else:
1142             ntype = type.decl()         # I am a union node
1143
1144         if self.DEBUG:
1145             print "XXX Union ntype =" , ntype
1146
1147         sname = self.namespace(ntype, "_")
1148         self.st.out(self.template_union_start, name=sname )
1149
1150         # Output a call to the union helper function so I can handle recursive union also.
1151
1152         self.st.out(self.template_decode_union,name=sname)
1153
1154         self.st.out(self.template_union_end, name=sname )
1155
1156
1157     #
1158     # Code to generate Union Helper functions
1159     #
1160     # in: un - a union node
1161     #
1162     #
1163
1164
1165     def genUnionHelper(self,un):
1166         if self.DEBUG:
1167             print "XXX Union type =" , un
1168             print "XXX Union type.decl()" , un.decl()
1169             print "XXX Union Scoped Name" , un.scopedName()
1170
1171         sname = self.namespace(un, "_")
1172         self.curr_sname = sname         # update current opnode/exnode/stnode/unnode scoped name
1173         if not self.fn_hash_built:
1174             self.fn_hash[sname] = []        # init empty list as val for this sname key
1175                                             # but only if the fn_hash is not already built
1176
1177         self.st.out(self.template_union_helper_function_start, sname=sname, unname=un.repoId())
1178         self.st.inc_indent()
1179
1180         self.st.out(self.template_helper_function_vars_start)
1181         self.dumpCvars(sname)
1182         self.st.out(self.template_helper_function_vars_end )
1183
1184         st = un.switchType().unalias() # may be typedef switch type, so find real type
1185
1186         self.st.out(self.template_comment_union_code_start, uname=un.repoId() )
1187
1188         self.getCDR3(st,un.identifier());
1189
1190         # Depending on what kind of discriminant I come accross (enum,integer,char,
1191         # short, boolean), make sure I cast the return value of the get_XXX accessor
1192         # to an appropriate value. Omniidl idlast.CaseLabel.value() accessor will
1193         # return an integer, or an Enumerator object that is then converted to its
1194         # integer equivalent.
1195         #
1196         #
1197         # NOTE - May be able to skip some of this stuff, but leave it in for now -- FS
1198         #
1199
1200         if (st.kind() == idltype.tk_enum):
1201             std = st.decl()
1202             self.st.out(self.template_comment_union_code_discriminant, uname=std.repoId() )
1203             self.st.out(self.template_union_code_save_discriminant_enum, discname=un.identifier() )
1204             self.addvar(self.c_s_disc + un.identifier() + ";")
1205
1206         elif (st.kind() == idltype.tk_long):
1207             self.st.out(self.template_union_code_save_discriminant_long, discname=un.identifier() )
1208             self.addvar(self.c_s_disc + un.identifier() + ";")
1209
1210         elif (st.kind() == idltype.tk_ulong):
1211             self.st.out(self.template_union_code_save_discriminant_ulong, discname=un.identifier() )
1212             self.addvar(self.c_s_disc + un.identifier() + ";")
1213
1214         elif (st.kind() == idltype.tk_short):
1215             self.st.out(self.template_union_code_save_discriminant_short, discname=un.identifier() )
1216             self.addvar(self.c_s_disc + un.identifier() + ";")
1217
1218         elif (st.kind() == idltype.tk_ushort):
1219             self.st.out(self.template_union_code_save_discriminant_ushort, discname=un.identifier() )
1220             self.addvar(self.c_s_disc + un.identifier() + ";")
1221
1222         elif (st.kind() == idltype.tk_boolean):
1223             self.st.out(self.template_union_code_save_discriminant_boolean, discname=un.identifier()  )
1224             self.addvar(self.c_s_disc + un.identifier() + ";")
1225
1226         elif (st.kind() == idltype.tk_char):
1227             self.st.out(self.template_union_code_save_discriminant_char, discname=un.identifier() )
1228             self.addvar(self.c_s_disc + un.identifier() + ";")
1229
1230         else:
1231             print "XXX Unknown st.kind() = ", st.kind()
1232
1233         #
1234         # Loop over all cases in this union
1235         #
1236
1237         for uc in un.cases():           # for all UnionCase objects in this union
1238             for cl in uc.labels():      # for all Caselabel objects in this UnionCase
1239
1240                 # get integer value, even if discriminant is
1241                 # an Enumerator node
1242
1243                 if isinstance(cl.value(),idlast.Enumerator):
1244                     if self.DEBUG:
1245                         print "XXX clv.identifier()", cl.value().identifier()
1246                         print "XXX clv.repoId()", cl.value().repoId()
1247                         print "XXX clv.scopedName()", cl.value().scopedName()
1248
1249                     # find index of enumerator in enum declaration
1250                     # eg: RED is index 0 in enum Colors { RED, BLUE, GREEN }
1251
1252                     clv = self.valFromEnum(std,cl.value())
1253
1254                 else:
1255                     clv = cl.value()
1256
1257                 #print "XXX clv = ",clv
1258
1259                 #
1260                 # if char, dont convert to int, but put inside single quotes so that it is understood by C.
1261                 # eg: if (disc == 'b')..
1262                 #
1263                 # TODO : handle \xxx chars generically from a function or table lookup rather than
1264                 #        a whole bunch of "if" statements. -- FS
1265
1266
1267                 if (st.kind() == idltype.tk_char):
1268                     if (clv == '\n'):          # newline
1269                         string_clv = "'\\n'"
1270                     elif (clv == '\t'):        # tab
1271                         string_clv = "'\\t'"
1272                     else:
1273                         string_clv = "'" + clv + "'"
1274                 else:
1275                     string_clv = '%i ' % clv
1276
1277                 #
1278                 # If default case, then skp comparison with discriminator
1279                 #
1280
1281                 if not cl.default():
1282                     self.st.out(self.template_comment_union_code_label_compare_start, discname=un.identifier(),labelval=string_clv )
1283                     self.st.inc_indent()
1284                 else:
1285                     self.st.out(self.template_comment_union_code_label_default_start  )
1286
1287
1288                 self.getCDR3(uc.caseType(),uc.declarator().identifier())
1289
1290                 if not cl.default():
1291                     self.st.dec_indent()
1292                     self.st.out(self.template_comment_union_code_label_compare_end )
1293                 else:
1294                     self.st.out(self.template_comment_union_code_label_default_end  )
1295
1296         self.st.dec_indent()
1297         self.st.out(self.template_union_helper_function_end)
1298
1299
1300
1301     #
1302     # Currently, get_CDR_alias is geared to finding typdef
1303     #
1304
1305     def get_CDR_alias(self,type,pn):
1306         if self.DEBUG:
1307             print "XXX get_CDR_alias, type = " ,type , " pn = " , pn
1308             print "XXX get_CDR_alias, type.decl() = " ,type.decl()
1309             print "XXX get_CDR_alias, type.decl().alias() = " ,type.decl().alias()
1310
1311         decl = type.decl()              # get declarator object
1312
1313         if (decl.sizes()):        # a typedef array
1314             indices = self.get_indices_from_sizes(decl.sizes())
1315             string_indices = '%i ' % indices # convert int to string
1316             self.st.out(self.template_get_CDR_array_comment, aname=pn, asize=string_indices)
1317
1318             self.st.out(self.template_get_CDR_array_start, aname=pn, aval=string_indices)
1319             self.addvar(self.c_i + pn + ";")
1320             self.st.inc_indent()
1321             self.getCDR3(type.decl().alias().aliasType(),  pn )
1322
1323             self.st.dec_indent()
1324             self.st.out(self.template_get_CDR_array_end)
1325
1326
1327         else:                           # a simple typdef
1328             if self.DEBUG:
1329                 print "XXX get_CDR_alias, type = " ,type , " pn = " , pn
1330                 print "XXX get_CDR_alias, type.decl() = " ,type.decl()
1331
1332             self.getCDR3(type, decl.identifier() )
1333
1334
1335
1336
1337
1338
1339     #
1340     # Handle structs, including recursive
1341     #
1342
1343     def get_CDR_struct(self,type,pn):
1344
1345         #  If I am a typedef struct {..}; node then find the struct node
1346
1347         if isinstance(type.decl(), idlast.Declarator):
1348             ntype = type.decl().alias().aliasType().decl()
1349         else:
1350             ntype = type.decl()         # I am a struct node
1351
1352         sname = self.namespace(ntype, "_")
1353         self.st.out(self.template_structure_start, name=sname )
1354
1355         # Output a call to the struct helper function so I can handle recursive structs also.
1356
1357         self.st.out(self.template_decode_struct,name=sname)
1358
1359         self.st.out(self.template_structure_end, name=sname )
1360
1361     #
1362     # genStructhelper()
1363     #
1364     # Generate private helper functions to decode a struct
1365     #
1366     # in: stnode ( a struct node)
1367     #
1368
1369     def genStructHelper(self,st):
1370         if self.DEBUG:
1371             print "XXX genStructHelper"
1372
1373         sname = self.namespace(st, "_")
1374         self.curr_sname = sname         # update current opnode/exnode/stnode scoped name
1375         if not self.fn_hash_built:
1376             self.fn_hash[sname] = []        # init empty list as val for this sname key
1377                                             # but only if the fn_hash is not already built
1378
1379         self.st.out(self.template_struct_helper_function_start, sname=sname, stname=st.repoId())
1380         self.st.inc_indent()
1381
1382         self.st.out(self.template_helper_function_vars_start)
1383         self.dumpCvars(sname)
1384         self.st.out(self.template_helper_function_vars_end )
1385
1386         for m in st.members():
1387             for decl in m.declarators():
1388                 if decl.sizes():        # an array
1389                     indices = self.get_indices_from_sizes(decl.sizes())
1390                     string_indices = '%i ' % indices # convert int to string
1391                     self.st.out(self.template_get_CDR_array_comment, aname=decl.identifier(), asize=string_indices)
1392                     self.st.out(self.template_get_CDR_array_start, aname=decl.identifier(), aval=string_indices)
1393                     self.addvar(self.c_i + decl.identifier() + ";")
1394
1395                     self.st.inc_indent()
1396                     self.getCDR3(m.memberType(), st.identifier() + "_" + decl.identifier() )
1397                     self.st.dec_indent()
1398                     self.st.out(self.template_get_CDR_array_end)
1399
1400
1401                 else:
1402                     self.getCDR3(m.memberType(), st.identifier() + "_" + decl.identifier() )
1403
1404         self.st.dec_indent()
1405         self.st.out(self.template_struct_helper_function_end)
1406
1407
1408
1409
1410
1411     #
1412     # Generate code to access a sequence of a type
1413     #
1414
1415
1416     def get_CDR_sequence(self,type, pn):
1417         self.st.out(self.template_get_CDR_sequence_length, seqname=pn )
1418         self.st.out(self.template_get_CDR_sequence_loop_start, seqname=pn )
1419         self.addvar(self.c_i_lim + pn + ";" )
1420         self.addvar(self.c_i + pn + ";")
1421
1422         self.st.inc_indent()
1423         self.getCDR3(type.unalias().seqType(), pn ) # and start all over with the type
1424         self.st.dec_indent()
1425
1426         self.st.out(self.template_get_CDR_sequence_loop_end)
1427
1428
1429     #
1430     # Generate code to access a sequence of octet
1431     #
1432
1433     def get_CDR_sequence_octet(self,type, pn):
1434         self.st.out(self.template_get_CDR_sequence_length, seqname=pn)
1435         self.st.out(self.template_get_CDR_sequence_octet, seqname=pn)
1436         self.addvar(self.c_i_lim + pn + ";")
1437         self.addvar("gchar * binary_seq_" + pn + ";")
1438         self.addvar("gchar * text_seq_" + pn + ";")
1439
1440
1441     #
1442     # Generate code to access arrays,
1443     #
1444     # This is handled elsewhere. Arrays are either typedefs or in
1445     # structs
1446     #
1447     # TODO - Remove this
1448     #
1449
1450     def get_CDR_array(self,type, decl):
1451         if self.DEBUG:
1452             print "XXX get_CDR_array called "
1453             print "XXX array size = " ,decl.sizes()
1454
1455
1456    #
1457    # namespace()
1458    #
1459    # in - op node
1460    #
1461    # out - scoped operation name, using sep character instead of "::"
1462    #
1463    # eg: Penguin::Echo::echoWString => Penguin_Echo_echoWString if sep = "_"
1464    #
1465    #
1466
1467     def namespace(self,node,sep):
1468         sname = string.replace(idlutil.ccolonName(node.scopedName()), '::', sep)
1469         #print "XXX namespace: sname = " + sname
1470         return sname
1471
1472
1473     #
1474     # generate code for plugin initialisation
1475     #
1476
1477     def gen_plugin_register(self):
1478         self.st.out(self.template_plugin_register, description=self.description, protocol_name=self.protoname, dissector_name=self.dissname)
1479
1480     #
1481     # generate  register_giop_user_module code, and register only
1482     # unique interfaces that contain operations. Also output
1483     # a heuristic register in case we want to use that.
1484     #
1485     # TODO - make this a command line option
1486     #
1487     # -e explicit
1488     # -h heuristic
1489     #
1490
1491
1492
1493     def gen_proto_reg_handoff(self, oplist):
1494
1495         self.st.out(self.template_proto_reg_handoff_start, dissector_name=self.dissname)
1496         self.st.inc_indent()
1497
1498         for iname in self.get_intlist(oplist):
1499             self.st.out(self.template_proto_reg_handoff_body, dissector_name=self.dissname, protocol_name=self.protoname, interface=iname )
1500
1501         self.st.out(self.template_proto_reg_handoff_heuristic, dissector_name=self.dissname,  protocol_name=self.protoname)
1502         self.st.dec_indent()
1503
1504         self.st.out(self.template_proto_reg_handoff_end)
1505
1506
1507
1508     #
1509     # generate  proto_register_<protoname> code,
1510     #
1511
1512
1513     def gen_proto_register(self):
1514         self.st.out(self.template_proto_register, description=self.description, protocol_name=self.protoname, dissector_name=self.dissname)
1515
1516
1517     #
1518     # in - oplist[]
1519     #
1520     # out - a list of unique interface names. This will be used in
1521     # register_giop_user_module(dissect_giop_auto, "TEST IDL", "Penguin/Echo" );   so the operation
1522     # name must be removed from the scope. And we also only want unique interfaces.
1523     #
1524
1525     def get_intlist(self,oplist):
1526         int_hash = {}                   # holds a hash of unique interfaces
1527         for op in oplist:
1528             sc = op.scopedName()        # eg: penguin,tux,bite
1529             sc1 = sc[:-1]               # drop last entry
1530             sn = idlutil.slashName(sc1)         # penguin/tux
1531             if not int_hash.has_key(sn):
1532                 int_hash[sn] = 0;       # dummy val, but at least key is unique
1533         ret = int_hash.keys()
1534         ret.sort()
1535         return ret
1536
1537
1538
1539     #
1540     # in - oplist[]
1541     #
1542     # out - a list of exception nodes (unique). This will be used in
1543     # to generate dissect_exception_XXX functions.
1544     #
1545
1546
1547
1548     def get_exceptionList(self,oplist):
1549         ex_hash = {}                   # holds a hash of unique exceptions.
1550         for op in oplist:
1551             for ex in op.raises():
1552                 if not ex_hash.has_key(ex):
1553                     ex_hash[ex] = 0; # dummy val, but at least key is unique
1554                     if self.DEBUG:
1555                         print "XXX Exception = " + ex.identifier()
1556         ret = ex_hash.keys()
1557         ret.sort()
1558         return ret
1559
1560
1561
1562     #
1563     # Simple function to take a list of array sizes and find the
1564     # total number of elements
1565     #
1566     #
1567     # eg: temp[4][3] = 12 elements
1568     #
1569
1570     def get_indices_from_sizes(self,sizelist):
1571         val = 1;
1572         for i in sizelist:
1573             val = val * i
1574
1575         return val
1576
1577     #
1578     # Determine how many octets contain requested number
1579     # of digits for an "fixed" IDL type  "on the wire"
1580     #
1581
1582     def dig_to_len(self,dignum):
1583         return (dignum/2) + 1
1584
1585
1586
1587     #
1588     # Output some TODO comment
1589     #
1590
1591
1592     def genTODO(self,message):
1593         self.st.out(self.template_debug_TODO, message=message)
1594
1595     #
1596     # Output some WARNING comment
1597     #
1598
1599
1600     def genWARNING(self,message):
1601         self.st.out(self.template_debug_WARNING, message=message)
1602
1603     #
1604     # Templates for C code
1605     #
1606
1607     template_comment_operations_start = """\
1608 /*
1609  * IDL Operations Start
1610  */
1611  """
1612     template_operations_declare = """static const char @sname@_op[] = \"@opname@\" ;"""
1613
1614     template_comment_operations_end = """
1615 /*
1616  * IDL Operations End
1617  */
1618 """
1619     template_helper_function_comment = """\
1620 /*
1621  * @repoid@
1622  */
1623 """
1624     template_helper_function_vars_start = """
1625 /* Operation specific Variable declarations Begin */
1626 """
1627     template_helper_function_vars_end = """
1628 /* Operation specific Variable declarations End */
1629 """
1630     template_helper_function_start = """\
1631 static void decode_@sname@(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, int *offset _U_, MessageHeader *header, gchar *operation _U_, gboolean stream_is_big_endian _U_) {
1632 """
1633     template_helper_function_end = """\
1634 }
1635 """
1636     #
1637     # proto_reg_handoff() templates
1638     #
1639
1640     template_proto_reg_handoff_start = """
1641 /* register me as handler for these interfaces */
1642
1643 void proto_register_handoff_giop_@dissector_name@(void) {
1644
1645 """
1646     template_proto_reg_handoff_body = """
1647 /* Register for Explicit Dissection */
1648
1649 register_giop_user_module(dissect_@dissector_name@, \"@protocol_name@\", \"@interface@\", proto_@dissector_name@ );     /* explicit dissector */
1650 """
1651     template_proto_reg_handoff_heuristic = """
1652 /* Register for Heuristic Dissection */
1653
1654 register_giop_user(dissect_@dissector_name@, \"@protocol_name@\" ,proto_@dissector_name@);     /* heuristic dissector */
1655 """
1656     template_proto_reg_handoff_end = """
1657 }
1658 """
1659
1660     #
1661     # Initialize the protocol
1662     #
1663
1664     template_protocol = """
1665 /* Initialise the protocol and subtree pointers */
1666
1667 static int proto_@dissector_name@ = -1;
1668
1669 static gint ett_@dissector_name@ = -1;
1670 """
1671     #
1672     # Initialize the boundary Alignment
1673     #
1674
1675     template_init_boundary = """
1676 /* Initialise the initial Alignment */
1677
1678 static guint32  boundary = GIOP_HEADER_SIZE;  /* initial value */
1679 """
1680     #
1681     # Initialize the Registered fields
1682     #
1683
1684     template_registered_fields = """
1685
1686 /* Initialise the Registered fields */
1687
1688 /* TODO - Use registered fields */
1689 """
1690     #
1691     # plugin_register and plugin_reg_handoff templates
1692     #
1693
1694     template_plugin_register = """
1695 #ifndef ENABLE_STATIC
1696
1697 G_MODULE_EXPORT void
1698 plugin_register(void)
1699 {
1700    if (proto_@dissector_name@ == -1) {
1701      proto_register_giop_@dissector_name@();
1702    }
1703 }
1704
1705 G_MODULE_EXPORT void
1706 plugin_reg_handoff(void){
1707    proto_register_handoff_giop_@dissector_name@();
1708 }
1709 #endif
1710 """
1711     #
1712     # proto_register_<dissector name>(void) templates
1713     #
1714
1715     template_proto_register = """
1716
1717 /* Register the protocol with Wireshark */
1718
1719 void proto_register_giop_@dissector_name@(void) {
1720
1721    /* setup list of header fields */
1722
1723    static hf_register_info hf[] = {
1724         /* field that indicates the currently ongoing request/reply exchange */
1725                 {&hf_operationrequest, {"Request_Operation","@protocol_name@.Request_Operation",FT_STRING,BASE_NONE,NULL,0x0,NULL,HFILL}},
1726
1727       /* no fields yet */
1728
1729    };
1730
1731    /* setup protocol subtree array */
1732
1733    static gint *ett[] = {
1734       &ett_@dissector_name@,
1735    };
1736
1737    /* Register the protocol name and description */
1738
1739    proto_@dissector_name@ = proto_register_protocol(\"@description@\" , \"@protocol_name@\", \"giop-@dissector_name@\" );
1740
1741    proto_register_field_array(proto_@dissector_name@, hf, array_length(hf));
1742
1743    proto_register_subtree_array(ett,array_length(ett));
1744
1745 }
1746 """
1747     #
1748     # template for delegation code
1749     #
1750     
1751     template_op_delegate_code = """\
1752 if (strcmp(operation, @sname@_op) == 0
1753     && (!idlname || strcmp(idlname, \"@interface@\") == 0)) {
1754    process_RequestOperation();  /* fill-up Request_Operation field & info column */
1755    tree = start_dissecting(tvb, pinfo, ptree, offset);
1756    decode_@sname@(tvb, pinfo, tree, offset, header, operation, stream_is_big_endian);
1757    return TRUE;
1758 }
1759 """
1760     #
1761     # Templates for the helper functions
1762     #
1763     #
1764     #
1765
1766     template_helper_switch_msgtype_start = """\
1767
1768 switch(header->message_type) {
1769 """
1770     template_helper_switch_msgtype_default_start = """\
1771 default:
1772
1773     /* Unknown GIOP Exception */
1774
1775     g_warning("Unknown GIOP Message");
1776 """
1777     template_helper_switch_msgtype_default_end = """\
1778 break;
1779 """
1780     template_helper_switch_msgtype_end = """\
1781 } /* switch(header->message_type) */
1782 """
1783     template_helper_switch_msgtype_request_start = """\
1784 case Request:
1785 """
1786     template_helper_switch_msgtype_request_end = """\
1787 break;
1788 """
1789     template_helper_switch_msgtype_reply_start = """\
1790 case Reply:
1791 """
1792     template_helper_switch_msgtype_reply_no_exception_start = """\
1793 case NO_EXCEPTION:
1794 """
1795     template_helper_switch_msgtype_reply_no_exception_end = """\
1796 break;
1797 """    
1798     template_helper_switch_msgtype_reply_user_exception_start = """\
1799 case USER_EXCEPTION:
1800 """
1801     template_helper_switch_msgtype_reply_user_exception_end = """\
1802 break;
1803 """
1804     template_helper_switch_msgtype_reply_default_start = """\
1805 default:
1806
1807     /* Unknown Exception */
1808
1809     g_warning("Unknown Exception ");
1810 """
1811     template_helper_switch_msgtype_reply_default_end = """\
1812     break;
1813 """
1814     template_helper_switch_msgtype_reply_end = """\
1815 break;
1816 """
1817     template_helper_switch_msgtype_default_start = """\
1818 default:
1819
1820     /* Unknown GIOP Message */
1821
1822     g_warning("Unknown GIOP Message");
1823 """
1824     template_helper_switch_msgtype_default_end = """\
1825     break;
1826 """
1827     template_helper_switch_rep_status_start = """\
1828 switch(header->rep_status) {
1829 """
1830     template_helper_switch_rep_status_default_start = """\
1831 default:
1832
1833     /* Unknown Reply Status */
1834
1835     g_warning("Unknown Reply Status");
1836 """
1837     template_helper_switch_rep_status_default_end = """\
1838     break;
1839 """
1840     template_helper_switch_rep_status_end = """\
1841
1842 }   /* switch(header->message_type) */
1843
1844 break;
1845 """
1846     
1847     #
1848     # Templates for get_CDR_xxx accessors
1849     #
1850
1851     template_get_CDR_ulong = """\
1852 u_octet4 = get_CDR_ulong(tvb,offset,stream_is_big_endian, boundary);
1853 if (tree) {
1854    proto_tree_add_text(tree,tvb,*offset-4,4,"@varname@ = %u",u_octet4);
1855 }
1856 """
1857     template_get_CDR_short = """\
1858 s_octet2 = get_CDR_short(tvb,offset,stream_is_big_endian, boundary);
1859 if (tree) {
1860    proto_tree_add_text(tree,tvb,*offset-2,2,"@varname@ = %i",s_octet2);
1861 }
1862 """
1863     template_get_CDR_void = """\
1864 /* Function returns void */
1865 """
1866     template_get_CDR_long = """\
1867 s_octet4 = get_CDR_long(tvb,offset,stream_is_big_endian, boundary);
1868 if (tree) {
1869    proto_tree_add_text(tree,tvb,*offset-4,4,"@varname@ = %i",s_octet4);
1870 }
1871 """
1872     template_get_CDR_ushort = """\
1873 u_octet2 = get_CDR_ushort(tvb,offset,stream_is_big_endian, boundary);
1874 if (tree) {
1875    proto_tree_add_text(tree,tvb,*offset-2,2,"@varname@ = %u",u_octet2);
1876 }
1877 """
1878     template_get_CDR_float = """\
1879 my_float = get_CDR_float(tvb,offset,stream_is_big_endian, boundary);
1880 if (tree) {
1881    proto_tree_add_text(tree,tvb,*offset-4,4,"@varname@ = %.6e",my_float);
1882 }
1883 """
1884     template_get_CDR_double = """\
1885 my_double = get_CDR_double(tvb,offset,stream_is_big_endian, boundary);
1886 if (tree) {
1887    proto_tree_add_text(tree,tvb,*offset-8,8,"@varname@ = %.15e",my_double);
1888 }
1889 """
1890     template_get_CDR_longlong = """\
1891 s_octet8 = get_CDR_long_long(tvb,offset,stream_is_big_endian, boundary);
1892 if (tree) {
1893    proto_tree_add_text(tree,tvb,*offset-8,8,"@varname@ = %" G_GINT64_MODIFIER "d",s_octet8);
1894 }
1895 """
1896     template_get_CDR_ulonglong = """\
1897 u_octet8 = get_CDR_ulong_long(tvb,offset,stream_is_big_endian, boundary);
1898 if (tree) {
1899    proto_tree_add_text(tree,tvb,*offset-8,8,"@varname@ = %" G_GINT64_MODIFIER "u",u_octet8);
1900 }
1901 """
1902     template_get_CDR_boolean = """\
1903 u_octet1 = get_CDR_boolean(tvb,offset);
1904 if (tree) {
1905    proto_tree_add_text(tree,tvb,*offset-1,1,"@varname@ = %u",u_octet1);
1906 }
1907 """
1908     template_get_CDR_char = """\
1909 u_octet1 = get_CDR_char(tvb,offset);
1910 if (tree) {
1911    proto_tree_add_text(tree,tvb,*offset-1,1,"@varname@ = %u",u_octet1);
1912 }
1913 """
1914     template_get_CDR_octet = """\
1915 u_octet1 = get_CDR_octet(tvb,offset);
1916 if (tree) {
1917    proto_tree_add_text(tree,tvb,*offset-1,1,"@varname@ = %u",u_octet1);
1918 }
1919 """
1920     template_get_CDR_any = """\
1921 get_CDR_any(tvb,tree,offset,stream_is_big_endian, boundary, header);
1922 """
1923     template_get_CDR_fixed = """\
1924 get_CDR_fixed(tvb, &seq, offset, @digits@, @scale@);
1925 if (tree) {
1926    proto_tree_add_text(tree,tvb,*offset-@length@, @length@, "@varname@ < @digits@, @scale@> = %s",seq);
1927 }
1928
1929 g_free(seq);          /*  free buffer  */
1930 seq = NULL;
1931 """
1932     template_get_CDR_enum_symbolic = """\
1933
1934 u_octet4 = get_CDR_enum(tvb,offset,stream_is_big_endian, boundary);
1935 if (tree) {
1936    proto_tree_add_text(tree,tvb,*offset-4,4,"@varname@  = %u (%s)",u_octet4,val_to_str(u_octet4,@valstringarray@,"Unknown Enum Value"));
1937 }
1938 """
1939     template_get_CDR_string = """\
1940 u_octet4 = get_CDR_string(tvb, &seq, offset, stream_is_big_endian, boundary);
1941 if (tree) {
1942    proto_tree_add_text(tree,tvb,*offset-u_octet4,u_octet4,"@varname@ (%u) = %s",
1943       u_octet4, (u_octet4 > 0) ? seq : \"\");
1944 }
1945
1946 g_free(seq);          /*  free buffer  */
1947 seq = NULL;
1948 """
1949     template_get_CDR_wstring = """\
1950 u_octet4 = get_CDR_wstring(tvb, &seq, offset, stream_is_big_endian, boundary, header);
1951 if (tree) {
1952    proto_tree_add_text(tree,tvb,*offset-u_octet4,u_octet4,"@varname@ (%u) = %s",
1953       u_octet4, (u_octet4 > 0) ? seq : \"\");
1954 }
1955
1956 g_free(seq);          /*  free buffer  */
1957 seq = NULL;
1958 """
1959     template_get_CDR_wchar = """\
1960 s_octet1 = get_CDR_wchar(tvb, &seq, offset, header);
1961 if (tree) {
1962     if (s_octet1 > 0)
1963         proto_tree_add_text(tree,tvb,*offset-1-s_octet1,1,"length = %u",s_octet1);
1964
1965     if (s_octet1 < 0)
1966         s_octet1 = -s_octet1;
1967
1968     if (s_octet1 > 0)
1969         proto_tree_add_text(tree,tvb,*offset-s_octet1,s_octet1,"@varname@ = %s",seq);
1970
1971 }
1972
1973 g_free(seq);          /*  free buffer  */
1974 seq = NULL;
1975 """
1976     template_get_CDR_TypeCode = """\
1977 u_octet4 = get_CDR_typeCode(tvb, tree, offset, stream_is_big_endian, boundary, header);
1978
1979 """
1980
1981     template_get_CDR_object = """\
1982 get_CDR_object(tvb, pinfo, tree, offset, stream_is_big_endian, boundary);
1983
1984 """
1985     template_get_CDR_sequence_length = """\
1986 u_octet4_loop_@seqname@ = get_CDR_ulong(tvb, offset, stream_is_big_endian, boundary);
1987 if (tree) {
1988    proto_tree_add_text(tree,tvb,*offset-4, 4 ,"Seq length of @seqname@ = %u",u_octet4_loop_@seqname@);
1989 }
1990 """
1991     template_get_CDR_sequence_loop_start = """\
1992 for (i_@seqname@=0; i_@seqname@ < u_octet4_loop_@seqname@; i_@seqname@++) {
1993 """
1994     template_get_CDR_sequence_loop_end = """\
1995 }
1996 """
1997
1998     template_get_CDR_sequence_octet = """\
1999 if (u_octet4_loop_@seqname@ > 0 && tree) {
2000     get_CDR_octet_seq(tvb, &binary_seq_@seqname@, offset,
2001         u_octet4_loop_@seqname@);
2002     text_seq_@seqname@ = make_printable_string(binary_seq_@seqname@,
2003         u_octet4_loop_@seqname@);
2004     proto_tree_add_text(tree, tvb, *offset - u_octet4_loop_@seqname@,
2005         u_octet4_loop_@seqname@, \"@seqname@: %s\", text_seq_@seqname@);
2006     g_free(binary_seq_@seqname@);
2007     g_free(text_seq_@seqname@);
2008 }
2009 """
2010     template_get_CDR_array_start = """\
2011 for (i_@aname@=0; i_@aname@ < @aval@; i_@aname@++) {
2012 """
2013     template_get_CDR_array_end = """\
2014 }
2015 """
2016     template_get_CDR_array_comment = """\
2017 /* Array: @aname@[ @asize@]  */
2018 """
2019     template_structure_start = """\
2020 /*  Begin struct \"@name@\"  */
2021 """
2022     template_structure_end = """\
2023 /*  End struct \"@name@\"  */
2024 """
2025
2026     template_union_start = """\
2027 /*  Begin union \"@name@\"  */
2028 """
2029     template_union_end = """\
2030 /*  End union \"@name@\"  */
2031 """
2032
2033 #
2034 # Program Header Template
2035 #
2036
2037     template_Header = """\
2038 /* packet-@dissector_name@.c
2039  *
2040  * $Id$
2041  *
2042  * Routines for IDL dissection
2043  *
2044  * Autogenerated from idl2wrs
2045  * Copyright 2001 Frank Singleton <frank.singleton@@ericsson.com>
2046  */
2047
2048 """
2049
2050     template_wireshark_copyright = """\
2051 /*
2052  * Wireshark - Network traffic analyzer
2053  * By Gerald Combs
2054  * Copyright 1999 - 2006 Gerald Combs
2055  */
2056
2057 static int hf_operationrequest = -1;/* Request_Operation field */
2058
2059 """
2060
2061
2062
2063 #
2064 # GPL Template
2065 #
2066
2067
2068     template_GPL = """\
2069 /*
2070  * This program is free software; you can redistribute it and/or
2071  * modify it under the terms of the GNU General Public License
2072  * as published by the Free Software Foundation; either version 2
2073  * of the License, or (at your option) any later version.
2074  *
2075  * This program is distributed in the hope that it will be useful,
2076  * but WITHOUT ANY WARRANTY; without even the implied warranty of
2077  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2078  * GNU General Public License for more details.
2079  *
2080  * You should have received a copy of the GNU General Public License
2081  * along with this program; if not, write to the Free Software
2082  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
2083  */
2084 """
2085
2086 #
2087 # Includes template
2088 #
2089
2090     template_Includes = """\
2091
2092 #ifdef HAVE_CONFIG_H
2093 # include "config.h"
2094 #endif
2095
2096 #include <gmodule.h>
2097
2098 #include <string.h>
2099 #include <glib.h>
2100 #include <epan/packet.h>
2101 #include <epan/proto.h>
2102 #include <epan/dissectors/packet-giop.h>
2103
2104 #ifndef ENABLE_STATIC
2105 G_MODULE_EXPORT const gchar version[] = "0.0.1";
2106 #endif
2107
2108 #ifdef _MSC_VER
2109 /* disable warning: "unreference local variable" */
2110 #pragma warning(disable:4101)
2111 #endif
2112 """
2113
2114
2115 #
2116 # Main dissector entry templates
2117 #
2118
2119     template_main_dissector_start = """\
2120 /*
2121  * Called once we accept the packet as being for us; it sets the
2122  * Protocol and Info columns and creates the top-level protocol
2123  * tree item.
2124  */
2125 static proto_tree *start_dissecting(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ptree, int *offset) {
2126
2127     proto_item *ti = NULL;
2128     proto_tree *tree = NULL;            /* init later, inside if(tree) */
2129
2130     col_set_str(pinfo->cinfo, COL_PROTOCOL, \"@disprot@\");
2131
2132     /*
2133      * Do not clear COL_INFO, as nothing is being written there by
2134      * this dissector yet. So leave it as is from the GIOP dissector.
2135      * TODO: add something useful to COL_INFO
2136      *     col_clear(pinfo->cinfo, COL_INFO);
2137      */
2138
2139     if (ptree) {
2140         ti = proto_tree_add_item(ptree, proto_@dissname@, tvb, *offset, -1, ENC_NA);
2141         tree = proto_item_add_subtree(ti, ett_@dissname@);
2142     }
2143     return tree;
2144 }
2145
2146 static gboolean dissect_@dissname@(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ptree, int *offset, MessageHeader *header, gchar *operation, gchar *idlname) {
2147
2148     gboolean stream_is_big_endian;                        /* big endianess */
2149     proto_tree *tree _U_;
2150 #define process_RequestOperation(){ \\
2151                 proto_item *pi; \\
2152         if(header->message_type == Reply){ col_append_fstr(pinfo->cinfo, COL_INFO, " op = %s",operation); }; /* fill-up info column */ \\
2153             pi=proto_tree_add_string_format_value(ptree,hf_operationrequest,tvb,0,0,operation," %s",operation);PROTO_ITEM_SET_GENERATED(pi); /* fill-up the field */ \\
2154    };
2155
2156     stream_is_big_endian = is_big_endian(header);         /* get endianess  */
2157
2158     /* If we have a USER Exception, then decode it and return */
2159
2160     if ((header->message_type == Reply) && (header->rep_status == USER_EXCEPTION)) {
2161
2162        return decode_user_exception(tvb, pinfo, ptree, offset, header, operation, stream_is_big_endian);
2163
2164     }
2165 """
2166     template_main_dissector_switch_msgtype_start = """\
2167 switch(header->message_type) {
2168 """
2169     template_main_dissector_switch_msgtype_start_request_reply = """\
2170 case Request:
2171 case Reply:
2172 """
2173     template_main_dissector_switch_msgtype_end_request_reply = """\
2174
2175 break;
2176 """
2177     template_main_dissector_switch_msgtype_all_other_msgtype = """\
2178 case CancelRequest:
2179 case LocateRequest:
2180 case LocateReply:
2181 case CloseConnection:
2182 case MessageError:
2183 case Fragment:
2184    return FALSE;      /* not handled yet */
2185
2186 default:
2187    return FALSE;      /* not handled yet */
2188
2189 }   /* switch */
2190 """
2191     template_main_dissector_end = """\
2192
2193     return FALSE;
2194
2195 }  /* End of main dissector  */
2196 """
2197
2198
2199
2200
2201
2202
2203
2204 #-------------------------------------------------------------#
2205 #             Exception handling templates                    #
2206 #-------------------------------------------------------------#
2207
2208
2209
2210
2211
2212
2213
2214     template_exception_helpers_start = """\
2215 /*  Begin Exception Helper Functions  */
2216
2217 """
2218     template_exception_helpers_end = """\
2219
2220 /*  End Exception Helper Functions  */
2221 """
2222
2223
2224
2225 #
2226 # Templates for declaration of string constants for user exceptions.
2227 #
2228
2229     template_comment_user_exceptions_string_declare_start = """\
2230 /*  Begin Exception (containing members) String  Declare  */
2231
2232 """
2233     template_user_exceptions_declare = """static const char user_exception_@sname@[] = \"@exname@\" ; """
2234
2235
2236     template_comment_user_exceptions_string_declare_end = """\
2237
2238 /*  End Exception (containing members) String Declare  */
2239 """
2240
2241
2242
2243
2244 #
2245 # template for Main delegator for exception handling
2246 #
2247
2248     template_main_exception_delegator_start = """\
2249 /*
2250  * Main delegator for exception handling
2251  *
2252  */
2253
2254 static gboolean decode_user_exception(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *ptree _U_, int *offset _U_, MessageHeader *header, gchar *operation _U_, gboolean stream_is_big_endian _U_) {
2255
2256     /*gboolean stream_is_big_endian _U_;*/                        /* big endianess */
2257     proto_tree *tree _U_;
2258
2259     if (!header->exception_id)
2260         return FALSE;
2261 """
2262
2263
2264 #
2265 # template for exception delegation code body
2266 #
2267     template_ex_delegate_code = """\
2268 if (strcmp(header->exception_id, user_exception_@sname@) == 0) {
2269    tree = start_dissecting(tvb, pinfo, ptree, offset);
2270    decode_ex_@sname@(tvb, pinfo, tree, offset, header, operation, stream_is_big_endian);   /*  @exname@  */
2271    return TRUE;
2272 }
2273 """
2274
2275
2276 #
2277 # End of Main delegator for exception handling
2278 #
2279
2280     template_main_exception_delegator_end = """\
2281
2282
2283     return FALSE;    /* user exception not found */
2284
2285 }
2286 """
2287
2288 #
2289 # template for exception helper code
2290 #
2291
2292
2293     template_exception_helper_function_start = """\
2294 /* Exception = @exname@ */
2295
2296 static void decode_ex_@sname@(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, int *offset _U_, MessageHeader *header _U_, gchar *operation _U_, gboolean stream_is_big_endian _U_) {
2297 """
2298
2299     template_exception_helper_function_end = """\
2300 }
2301 """
2302
2303
2304 #
2305 # template for struct helper code
2306 #
2307
2308
2309     template_struct_helper_function_start = """\
2310 /* Struct = @stname@ */
2311
2312 static void decode_@sname@_st(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, int *offset _U_, MessageHeader *header _U_, gchar *operation _U_, gboolean stream_is_big_endian _U_) {
2313 """
2314
2315     template_struct_helper_function_end = """\
2316 }
2317 """
2318
2319 #
2320 # template for union helper code
2321 #
2322
2323
2324     template_union_helper_function_start = """\
2325 /* Union = @unname@ */
2326
2327 static void decode_@sname@_un(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, int *offset _U_, MessageHeader *header _U_, gchar *operation _U_, gboolean stream_is_big_endian _U_) {
2328 """
2329
2330     template_union_helper_function_end = """\
2331 }
2332 """
2333
2334
2335
2336 #-------------------------------------------------------------#
2337 #             Value string  templates                         #
2338 #-------------------------------------------------------------#
2339
2340     template_value_string_start = """\
2341 static const value_string @valstringname@[] = {
2342 """
2343     template_value_string_entry = """\
2344    { @intval@, \"@description@\" }, """
2345
2346     template_value_string_end = """\
2347    { 0,       NULL },
2348 };
2349 """
2350
2351
2352
2353 #-------------------------------------------------------------#
2354 #             Enum   handling templates                       #
2355 #-------------------------------------------------------------#
2356
2357     template_comment_enums_start = """\
2358 /*
2359  * IDL Enums Start
2360  */
2361  """
2362     template_comment_enums_end = """\
2363 /*
2364  * IDL Enums End
2365  */
2366  """
2367     template_comment_enum_comment = """\
2368 /*
2369  * Enum = @ename@
2370  */
2371  """
2372
2373
2374
2375 #-------------------------------------------------------------#
2376 #             Attribute handling templates                    #
2377 #-------------------------------------------------------------#
2378
2379
2380     template_comment_attributes_start = """\
2381 /*
2382  * IDL Attributes Start
2383  */
2384  """
2385
2386     #
2387     # get/set accessor method names are language mapping dependant.
2388     #
2389
2390     template_attributes_declare_Java_get = """static const char get_@sname@_at[] = \"_get_@atname@\" ;"""
2391     template_attributes_declare_Java_set = """static const char set_@sname@_at[] = \"_set_@atname@\" ;"""
2392
2393     template_comment_attributes_end = """
2394 /*
2395  * IDL Attributes End
2396  */
2397 """
2398
2399
2400     #
2401     # template for Attribute delegation code
2402     #
2403     # Note: _get_xxx() should only be called for Reply with NO_EXCEPTION
2404     # Note: _set_xxx() should only be called for Request
2405     #
2406     #
2407
2408     template_at_delegate_code_get = """\
2409 if (strcmp(operation, get_@sname@_at) == 0 && (header->message_type == Reply) && (header->rep_status == NO_EXCEPTION) ) {
2410    tree = start_dissecting(tvb, pinfo, ptree, offset);
2411    decode_get_@sname@_at(tvb, pinfo, tree, offset, header, operation, stream_is_big_endian);
2412    return TRUE;
2413 }
2414 """
2415     template_at_delegate_code_set = """\
2416 if (strcmp(operation, set_@sname@_at) == 0 && (header->message_type == Request) ) {
2417    tree = start_dissecting(tvb, pinfo, ptree, offset);
2418    decode_set_@sname@_at(tvb, pinfo, tree, offset, header, operation, stream_is_big_endian);
2419    return TRUE;
2420 }
2421 """
2422     template_attribute_helpers_start = """\
2423 /*  Begin Attribute Helper Functions  */
2424 """
2425     template_attribute_helpers_end = """\
2426
2427 /*  End Attribute Helper Functions  */
2428 """
2429
2430 #
2431 # template for attribute helper code
2432 #
2433
2434
2435     template_attribute_helper_function_start = """\
2436
2437 /* Attribute = @atname@ */
2438
2439 static void decode_@sname@_at(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, int *offset _U_, MessageHeader *header _U_, gchar *operation _U_, gboolean stream_is_big_endian _U_) {
2440 """
2441
2442     template_attribute_helper_function_end = """\
2443 }
2444 """
2445
2446
2447 #-------------------------------------------------------------#
2448 #                     Debugging  templates                    #
2449 #-------------------------------------------------------------#
2450
2451     #
2452     # Template for outputting TODO "C" comments
2453     # so user know I need ti improve something.
2454     #
2455
2456     template_debug_TODO = """\
2457
2458 /* TODO - @message@ */
2459 """
2460     #
2461     # Template for outputting WARNING "C" comments
2462     # so user know if I have found a problem.
2463     #
2464
2465     template_debug_WARNING = """\
2466 /* WARNING - @message@ */
2467 """
2468
2469
2470
2471 #-------------------------------------------------------------#
2472 #                     IDL Union  templates                    #
2473 #-------------------------------------------------------------#
2474
2475     template_comment_union_code_start = """\
2476 /*
2477  * IDL Union Start - @uname@
2478  */
2479  """
2480     template_comment_union_code_end = """
2481 /*
2482  * IDL union End - @uname@
2483  */
2484 """
2485     template_comment_union_code_discriminant = """\
2486 /*
2487  * IDL Union - Discriminant - @uname@
2488  */
2489  """
2490     #
2491     # Cast Unions types to something appropriate
2492     # Enum value cast to guint32, all others cast to gint32
2493     # as omniidl accessor returns integer or Enum.
2494     #
2495
2496     template_union_code_save_discriminant_enum = """\
2497 disc_s_@discname@ = (gint32) u_octet4;     /* save Enum Value  discriminant and cast to gint32 */
2498 """
2499     template_union_code_save_discriminant_long = """\
2500 disc_s_@discname@ = (gint32) s_octet4;     /* save gint32 discriminant and cast to gint32 */
2501 """
2502
2503     template_union_code_save_discriminant_ulong = """\
2504 disc_s_@discname@ = (gint32) u_octet4;     /* save guint32 discriminant and cast to gint32 */
2505 """
2506     template_union_code_save_discriminant_short = """\
2507 disc_s_@discname@ = (gint32) s_octet2;     /* save gint16 discriminant and cast to gint32 */
2508 """
2509
2510     template_union_code_save_discriminant_ushort = """\
2511 disc_s_@discname@ = (gint32) u_octet2;     /* save guint16 discriminant and cast to gint32 */
2512 """
2513     template_union_code_save_discriminant_char = """\
2514 disc_s_@discname@ = (gint32) u_octet1;     /* save guint1 discriminant and cast to gint32 */
2515 """
2516     template_union_code_save_discriminant_boolean = """\
2517 disc_s_@discname@ = (gint32) u_octet1;     /* save guint1 discriminant and cast to gint32 */
2518 """
2519     template_comment_union_code_label_compare_start = """\
2520 if (disc_s_@discname@ == @labelval@) {
2521  """
2522     template_comment_union_code_label_compare_end = """\
2523     return;     /* End Compare for this discriminant type */
2524 }
2525  """
2526
2527
2528     template_comment_union_code_label_default_start = """
2529 /* Default Union Case Start */
2530 """
2531     template_comment_union_code_label_default_end = """\
2532 /* Default Union Case End */
2533  """
2534
2535     #
2536     # Templates for function prototypes.
2537     # This is used in genDeclares() for declaring function prototypes
2538     # for structs and union helper functions.
2539     #
2540
2541     template_prototype_start_dissecting = """
2542 static proto_tree *start_dissecting(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ptree, int *offset);
2543
2544 """
2545     template_prototype_struct_start = """
2546 /* Struct prototype declaration Start */
2547 """
2548     template_prototype_struct_end = """
2549 /* Struct prototype declaration End */
2550 """
2551     template_prototype_struct_body = """
2552 /* Struct = @stname@ */
2553
2554 static void decode_@name@_st(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, int *offset _U_, MessageHeader *header _U_, gchar *operation _U_, gboolean stream_is_big_endian _U_);
2555 """
2556     template_decode_struct = """
2557
2558 decode_@name@_st(tvb, pinfo, tree, offset, header, operation, stream_is_big_endian);
2559 """
2560     template_prototype_union_start = """
2561 /* Union prototype declaration Start */
2562 """
2563     template_prototype_union_end = """
2564 /* Union prototype declaration End */
2565
2566 """
2567     template_prototype_union_body = """
2568
2569 /* Union = @unname@ */
2570
2571 static void decode_@name@_un(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, int *offset _U_, MessageHeader *header _U_, gchar *operation _U_, gboolean stream_is_big_endian _U_);
2572
2573 """
2574     template_decode_union = """
2575 decode_@name@_un(tvb, pinfo, tree, offset, header, operation, stream_is_big_endian);
2576 """
2577