Divide categories into four groups as they are processed from the XML. Add
[mesa.git] / src / mesa / glapi / gl_XML.py
1 #!/usr/bin/env python
2
3 # (C) Copyright IBM Corporation 2004, 2005
4 # All Rights Reserved.
5 #
6 # Permission is hereby granted, free of charge, to any person obtaining a
7 # copy of this software and associated documentation files (the "Software"),
8 # to deal in the Software without restriction, including without limitation
9 # on the rights to use, copy, modify, merge, publish, distribute, sub
10 # license, and/or sell copies of the Software, and to permit persons to whom
11 # the Software is furnished to do so, subject to the following conditions:
12 #
13 # The above copyright notice and this permission notice (including the next
14 # paragraph) shall be included in all copies or substantial portions of the
15 # Software.
16 #
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20 # IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 # IN THE SOFTWARE.
24 #
25 # Authors:
26 # Ian Romanick <idr@us.ibm.com>
27
28 import libxml2
29 import re, sys, string
30 import typeexpr
31
32
33 def parse_GL_API( file_name, factory = None ):
34 doc = libxml2.readFile( file_name, None, libxml2.XML_PARSE_XINCLUDE + libxml2.XML_PARSE_NOBLANKS + libxml2.XML_PARSE_DTDVALID + libxml2.XML_PARSE_DTDATTR + libxml2.XML_PARSE_DTDLOAD + libxml2.XML_PARSE_NOENT )
35 ret = doc.xincludeProcess()
36
37 if not factory:
38 factory = gl_item_factory()
39
40 api = factory.create_item( "api", None, None )
41 api.process_element( doc )
42
43 # After the XML has been processed, we need to go back and assign
44 # dispatch offsets to the functions that request that their offsets
45 # be assigned by the scripts. Typically this means all functions
46 # that are not part of the ABI.
47
48 for func in api.functionIterateByCategory():
49 if func.assign_offset:
50 func.offset = api.next_offset;
51 api.next_offset += 1
52
53 doc.freeDoc()
54
55 return api
56
57
58 def is_attr_true( element, name ):
59 """Read a name value from an element's attributes.
60
61 The value read from the attribute list must be either 'true' or
62 'false'. If the value is 'false', zero will be returned. If the
63 value is 'true', non-zero will be returned. An exception will be
64 raised for any other value."""
65
66 value = element.nsProp( name, None )
67 if value == "true":
68 return 1
69 elif value == "false":
70 return 0
71 else:
72 raise RuntimeError('Invalid value "%s" for boolean "%s".' % (value, name))
73
74
75 class gl_print_base:
76 """Base class of all API pretty-printers.
77
78 In the model-view-controller pattern, this is the view. Any derived
79 class will want to over-ride the printBody, printRealHader, and
80 printRealFooter methods. Some derived classes may want to over-ride
81 printHeader and printFooter, or even Print (though this is unlikely).
82 """
83
84 def __init__(self):
85 # Name of the script that is generating the output file.
86 # Every derived class should set this to the name of its
87 # source file.
88
89 self.name = "a"
90
91
92 # License on the *generated* source file. This may differ
93 # from the license on the script that is generating the file.
94 # Every derived class should set this to some reasonable
95 # value.
96 #
97 # See license.py for an example of a reasonable value.
98
99 self.license = "The license for this file is unspecified."
100
101
102 # The header_tag is the name of the C preprocessor define
103 # used to prevent multiple inclusion. Typically only
104 # generated C header files need this to be set. Setting it
105 # causes code to be generated automatically in printHeader
106 # and printFooter.
107
108 self.header_tag = None
109
110
111 # List of file-private defines that must be undefined at the
112 # end of the file. This can be used in header files to define
113 # names for use in the file, then undefine them at the end of
114 # the header file.
115
116 self.undef_list = []
117 return
118
119
120 def Print(self, api):
121 self.printHeader()
122 self.printBody(api)
123 self.printFooter()
124 return
125
126
127 def printHeader(self):
128 """Print the header associated with all files and call the printRealHeader method."""
129
130 print '/* DO NOT EDIT - This file generated automatically by %s script */' \
131 % (self.name)
132 print ''
133 print '/*'
134 print ' * ' + self.license.replace('\n', '\n * ')
135 print ' */'
136 print ''
137 if self.header_tag:
138 print '#if !defined( %s )' % (self.header_tag)
139 print '# define %s' % (self.header_tag)
140 print ''
141 self.printRealHeader();
142 return
143
144
145 def printFooter(self):
146 """Print the header associated with all files and call the printRealFooter method."""
147
148 self.printRealFooter()
149
150 if self.undef_list:
151 print ''
152 for u in self.undef_list:
153 print "# undef %s" % (u)
154
155 if self.header_tag:
156 print ''
157 print '#endif /* !defined( %s ) */' % (self.header_tag)
158
159
160 def printRealHeader(self):
161 """Print the "real" header for the created file.
162
163 In the base class, this function is empty. All derived
164 classes should over-ride this function."""
165 return
166
167
168 def printRealFooter(self):
169 """Print the "real" footer for the created file.
170
171 In the base class, this function is empty. All derived
172 classes should over-ride this function."""
173 return
174
175
176 def printPure(self):
177 """Conditionally define `PURE' function attribute.
178
179 Conditionally defines a preprocessor macro `PURE' that wraps
180 GCC's `pure' function attribute. The conditional code can be
181 easilly adapted to other compilers that support a similar
182 feature.
183
184 The name is also added to the file's undef_list.
185 """
186 self.undef_list.append("PURE")
187 print """# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
188 # define PURE __attribute__((pure))
189 # else
190 # define PURE
191 # endif"""
192 return
193
194
195 def printFastcall(self):
196 """Conditionally define `FASTCALL' function attribute.
197
198 Conditionally defines a preprocessor macro `FASTCALL' that
199 wraps GCC's `fastcall' function attribute. The conditional
200 code can be easilly adapted to other compilers that support a
201 similar feature.
202
203 The name is also added to the file's undef_list.
204 """
205
206 self.undef_list.append("FASTCALL")
207 print """# if defined(__i386__) && defined(__GNUC__) && !defined(__CYGWIN__) && !defined(__MINGW32__)
208 # define FASTCALL __attribute__((fastcall))
209 # else
210 # define FASTCALL
211 # endif"""
212 return
213
214
215 def printVisibility(self, S, s):
216 """Conditionally define visibility function attribute.
217
218 Conditionally defines a preprocessor macro name S that wraps
219 GCC's visibility function attribute. The visibility used is
220 the parameter s. The conditional code can be easilly adapted
221 to other compilers that support a similar feature.
222
223 The name is also added to the file's undef_list.
224 """
225
226 self.undef_list.append(S)
227 print """# if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__)
228 # define %s __attribute__((visibility("%s")))
229 # else
230 # define %s
231 # endif""" % (S, s, S)
232 return
233
234
235 def printNoinline(self):
236 """Conditionally define `NOINLINE' function attribute.
237
238 Conditionally defines a preprocessor macro `NOINLINE' that
239 wraps GCC's `noinline' function attribute. The conditional
240 code can be easilly adapted to other compilers that support a
241 similar feature.
242
243 The name is also added to the file's undef_list.
244 """
245
246 self.undef_list.append("NOINLINE")
247 print """# if defined(__GNUC__)
248 # define NOINLINE __attribute__((noinline))
249 # else
250 # define NOINLINE
251 # endif"""
252 return
253
254
255 def real_function_name(element):
256 name = element.nsProp( "name", None )
257 alias = element.nsProp( "alias", None )
258
259 if alias:
260 return alias
261 else:
262 return name
263
264
265 def real_category_name(c):
266 if re.compile("[1-9][0-9]*[.][0-9]+").match(c):
267 return "GL_VERSION_" + c.replace(".", "_")
268 else:
269 return c
270
271
272 def classify_category(name, number):
273 """Based on the category name and number, select a numerical class for it.
274
275 Categories are divided into four classes numbered 0 through 3. The
276 classes are:
277
278 0. Core GL versions, sorted by version number.
279 1. ARB extensions, sorted by extension number.
280 2. Non-ARB extensions, sorted by extension number.
281 3. Un-numbered extensions, sorted by extension name.
282 """
283
284 try:
285 core_version = float(name)
286 except Exception,e:
287 core_version = 0.0
288
289 if core_version > 0.0:
290 cat_type = 0
291 key = name
292 elif name.startswith("GL_ARB_") or name.startswith("GLX_ARB_") or name.startswith("WGL_ARB_"):
293 cat_type = 1
294 key = int(number)
295 else:
296 if number != None:
297 cat_type = 2
298 key = int(number)
299 else:
300 cat_type = 3
301 key = name
302
303
304 return [cat_type, key]
305
306
307 def create_parameter_string(parameters, include_names):
308 """Create a parameter string from a list of gl_parameters."""
309
310 list = []
311 for p in parameters:
312 if include_names:
313 list.append( p.string() )
314 else:
315 list.append( p.type_string() )
316
317 if len(list) == 0: list = ["void"]
318
319 return string.join(list, ", ")
320
321
322 class gl_item:
323 def __init__(self, element, context):
324 self.context = context
325 self.name = element.nsProp( "name", None )
326 self.category = real_category_name( element.parent.nsProp( "name", None ) )
327 return
328
329
330 class gl_type( gl_item ):
331 def __init__(self, element, context):
332 gl_item.__init__(self, element, context)
333 self.size = int( element.nsProp( "size", None ), 0 )
334
335 te = typeexpr.type_expression( None )
336 tn = typeexpr.type_node()
337 tn.size = int( element.nsProp( "size", None ), 0 )
338 tn.integer = not is_attr_true( element, "float" )
339 tn.unsigned = is_attr_true( element, "unsigned" )
340 tn.name = "GL" + self.name
341 te.set_base_type_node( tn )
342
343 self.type_expr = te
344 return
345
346
347 def get_type_expression(self):
348 return self.type_expr
349
350
351 class gl_enum( gl_item ):
352 def __init__(self, element, context):
353 gl_item.__init__(self, element, context)
354 self.value = int( element.nsProp( "value", None ), 0 )
355
356 temp = element.nsProp( "count", None )
357 if not temp or temp == "?":
358 self.default_count = -1
359 else:
360 try:
361 c = int(temp)
362 except Exception,e:
363 raise RuntimeError('Invalid count value "%s" for enum "%s" in function "%s" when an integer was expected.' % (temp, self.name, n))
364
365 self.default_count = c
366
367 return
368
369
370 def priority(self):
371 """Calculate a 'priority' for this enum name.
372
373 When an enum is looked up by number, there may be many
374 possible names, but only one is the 'prefered' name. The
375 priority is used to select which name is the 'best'.
376
377 Highest precedence is given to core GL name. ARB extension
378 names have the next highest, followed by EXT extension names.
379 Vendor extension names are the lowest.
380 """
381
382 if self.name.endswith( "_BIT" ):
383 bias = 1
384 else:
385 bias = 0
386
387 if self.category.startswith( "GL_VERSION_" ):
388 priority = 0
389 elif self.category.startswith( "GL_ARB_" ):
390 priority = 2
391 elif self.category.startswith( "GL_EXT_" ):
392 priority = 4
393 else:
394 priority = 6
395
396 return priority + bias
397
398
399
400 class gl_parameter:
401 def __init__(self, element, context):
402 self.name = element.nsProp( "name", None )
403
404 ts = element.nsProp( "type", None )
405 self.type_expr = typeexpr.type_expression( ts, context )
406
407 temp = element.nsProp( "variable_param", None )
408 if temp:
409 self.count_parameter_list = temp.split( ' ' )
410 else:
411 self.count_parameter_list = []
412
413 # The count tag can be either a numeric string or the name of
414 # a variable. If it is the name of a variable, the int(c)
415 # statement will throw an exception, and the except block will
416 # take over.
417
418 c = element.nsProp( "count", None )
419 try:
420 count = int(c)
421 self.count = count
422 self.counter = None
423 except Exception,e:
424 count = 1
425 self.count = 0
426 self.counter = c
427
428 self.count_scale = int(element.nsProp( "count_scale", None ))
429
430 elements = (count * self.count_scale)
431 if elements == 1:
432 elements = 0
433
434 #if ts == "GLdouble":
435 # print '/* stack size -> %s = %u (before)*/' % (self.name, self.type_expr.get_stack_size())
436 # print '/* # elements = %u */' % (elements)
437 self.type_expr.set_elements( elements )
438 #if ts == "GLdouble":
439 # print '/* stack size -> %s = %u (after) */' % (self.name, self.type_expr.get_stack_size())
440
441 self.is_counter = is_attr_true( element, 'counter' )
442 self.is_output = is_attr_true( element, 'output' )
443
444
445 # Pixel data has special parameters.
446
447 self.width = element.nsProp('img_width', None)
448 self.height = element.nsProp('img_height', None)
449 self.depth = element.nsProp('img_depth', None)
450 self.extent = element.nsProp('img_extent', None)
451
452 self.img_xoff = element.nsProp('img_xoff', None)
453 self.img_yoff = element.nsProp('img_yoff', None)
454 self.img_zoff = element.nsProp('img_zoff', None)
455 self.img_woff = element.nsProp('img_woff', None)
456
457 self.img_format = element.nsProp('img_format', None)
458 self.img_type = element.nsProp('img_type', None)
459 self.img_target = element.nsProp('img_target', None)
460
461 self.img_pad_dimensions = is_attr_true( element, 'img_pad_dimensions' )
462 self.img_null_flag = is_attr_true( element, 'img_null_flag' )
463 self.img_send_null = is_attr_true( element, 'img_send_null' )
464
465 return
466
467
468 def compatible(self, other):
469 return 1
470
471
472 def is_array(self):
473 return self.is_pointer()
474
475
476 def is_pointer(self):
477 return self.type_expr.is_pointer()
478
479
480 def is_image(self):
481 if self.width:
482 return 1
483 else:
484 return 0
485
486
487 def is_variable_length(self):
488 return len(self.count_parameter_list) or self.counter
489
490
491 def is_64_bit(self):
492 count = self.type_expr.get_element_count()
493 if count:
494 if (self.size() / count) == 8:
495 return 1
496 else:
497 if self.size() == 8:
498 return 1
499
500 return 0
501
502
503 def string(self):
504 return self.type_expr.original_string + " " + self.name
505
506
507 def type_string(self):
508 return self.type_expr.original_string
509
510
511 def get_base_type_string(self):
512 return self.type_expr.get_base_name()
513
514
515 def get_dimensions(self):
516 if not self.width:
517 return [ 0, "0", "0", "0", "0" ]
518
519 dim = 1
520 w = self.width
521 h = "1"
522 d = "1"
523 e = "1"
524
525 if self.height:
526 dim = 2
527 h = self.height
528
529 if self.depth:
530 dim = 3
531 d = self.depth
532
533 if self.extent:
534 dim = 4
535 e = self.extent
536
537 return [ dim, w, h, d, e ]
538
539
540 def get_stack_size(self):
541 return self.type_expr.get_stack_size()
542
543
544 def size(self):
545 if self.is_image():
546 return 0
547 else:
548 return self.type_expr.get_element_size()
549
550
551 def get_element_count(self):
552 c = self.type_expr.get_element_count()
553 if c == 0:
554 return 1
555
556 return c
557
558
559 def size_string(self, use_parens = 1):
560 s = self.size()
561 if self.counter or self.count_parameter_list:
562 list = [ "compsize" ]
563
564 if self.counter and self.count_parameter_list:
565 list.append( self.counter )
566 elif self.counter:
567 list = [ self.counter ]
568
569 if s > 1:
570 list.append( str(s) )
571
572 if len(list) > 1 and use_parens :
573 return "(%s)" % (string.join(list, " * "))
574 else:
575 return string.join(list, " * ")
576
577 elif self.is_image():
578 return "compsize"
579 else:
580 return str(s)
581
582
583 def format_string(self):
584 if self.type_expr.original_string == "GLenum":
585 return "0x%x"
586 else:
587 return self.type_expr.format_string()
588
589
590
591 class gl_function( gl_item ):
592 def __init__(self, element, context):
593 self.context = context
594 self.name = None
595
596 self.entry_points = []
597 self.return_type = "void"
598 self.parameters = []
599 self.offset = -1
600 self.initialized = 0
601 self.images = []
602
603 self.assign_offset = 0
604
605 self.static_entry_points = []
606
607 # Track the parameter string (for the function prototype)
608 # for each entry-point. This is done because some functions
609 # change their prototype slightly when promoted from extension
610 # to ARB extension to core. glTexImage3DEXT and glTexImage3D
611 # are good examples of this. Scripts that need to generate
612 # code for these differing aliases need to real prototype
613 # for each entry-point. Otherwise, they may generate code
614 # that won't compile.
615
616 self.parameter_strings = {}
617
618 self.process_element( element )
619
620 return
621
622
623 def process_element(self, element):
624 name = element.nsProp( "name", None )
625 alias = element.nsProp( "alias", None )
626
627 if is_attr_true(element, "static_dispatch"):
628 self.static_entry_points.append(name)
629
630 self.entry_points.append( name )
631 if alias:
632 true_name = alias
633 else:
634 true_name = name
635
636 # Only try to set the offset when a non-alias
637 # entry-point is being processes.
638
639 offset = element.nsProp( "offset", None )
640 if offset:
641 try:
642 o = int( offset )
643 self.offset = o
644 except Exception, e:
645 self.offset = -1
646 if offset == "assign":
647 self.assign_offset = 1
648
649
650 if not self.name:
651 self.name = true_name
652 elif self.name != true_name:
653 raise RuntimeError("Function true name redefined. Was %s, now %s." % (self.name, true_name))
654
655
656 # There are two possible cases. The first time an entry-point
657 # with data is seen, self.initialized will be 0. On that
658 # pass, we just fill in the data. The next time an
659 # entry-point with data is seen, self.initialized will be 1.
660 # On that pass we have to make that the new values match the
661 # valuse from the previous entry-point.
662
663 parameters = []
664 return_type = "void"
665 child = element.children
666 while child:
667 if child.type == "element":
668 if child.name == "return":
669 return_type = child.nsProp( "type", None )
670 elif child.name == "param":
671 param = self.context.factory.create_item( "parameter", child, self.context)
672 parameters.append( param )
673
674 child = child.next
675
676
677 if self.initialized:
678 if self.return_type != return_type:
679 raise RuntimeError( "Return type changed in %s. Was %s, now %s." % (name, self.return_type, return_type))
680
681 if len(parameters) != len(self.parameters):
682 raise RuntimeError( "Parameter count mismatch in %s. Was %d, now %d." % (name, len(self.parameters), len(parameters)))
683
684 for j in range(0, len(parameters)):
685 p1 = parameters[j]
686 p2 = self.parameters[j]
687 if not p1.compatible( p2 ):
688 raise RuntimeError( 'Parameter type mismatch in %s. "%s" was "%s", now "%s".' % (name, p2.name, p2.type_expr.original_string, p1.type_expr.original_string))
689
690
691 if true_name == name or not self.initialized:
692 self.return_type = return_type
693 self.parameters = parameters
694
695 for param in self.parameters:
696 if param.is_image():
697 self.images.append( param )
698
699 if element.children:
700 self.initialized = 1
701 self.parameter_strings[name] = create_parameter_string(parameters, 1)
702 else:
703 self.parameter_strings[name] = None
704
705 return
706
707
708 def get_images(self):
709 """Return potentially empty list of input images."""
710 return self.images
711
712
713 def parameterIterator(self):
714 return self.parameters.__iter__();
715
716
717 def get_parameter_string(self, entrypoint = None):
718 if entrypoint:
719 s = self.parameter_strings[ entrypoint ]
720 if s:
721 return s
722
723 return create_parameter_string( self.parameters, 1 )
724
725 def is_static_entry_point(self, name):
726 return name in self.static_entry_points
727
728 def dispatch_name(self):
729 if self.name in self.static_entry_points:
730 return self.name
731 else:
732 return "_dispatch_stub_%u" % (self.offset)
733
734 def static_name(self, name):
735 if name in self.static_entry_points:
736 return name
737 else:
738 return "_dispatch_stub_%u" % (self.offset)
739
740
741 class gl_item_factory:
742 """Factory to create objects derived from gl_item."""
743
744 def create_item(self, item_name, element, context):
745 if item_name == "function":
746 return gl_function(element, context)
747 if item_name == "type":
748 return gl_type(element, context)
749 elif item_name == "enum":
750 return gl_enum(element, context)
751 elif item_name == "parameter":
752 return gl_parameter(element, context)
753 elif item_name == "api":
754 return gl_api(self)
755 else:
756 return None
757
758
759 class gl_api:
760 def __init__(self, factory):
761 self.functions_by_name = {}
762 self.enums_by_name = {}
763 self.types_by_name = {}
764
765 self.category_dict = {}
766 self.categories = [{}, {}, {}, {}]
767
768 self.factory = factory
769
770 self.next_offset = 0
771
772 typeexpr.create_initial_types()
773 return
774
775
776 def process_element(self, doc):
777 element = doc.children
778 while element.type != "element" or element.name != "OpenGLAPI":
779 element = element.next
780
781 if element:
782 self.process_OpenGLAPI(element)
783 return
784
785
786 def process_OpenGLAPI(self, element):
787 child = element.children
788 while child:
789 if child.type == "element":
790 if child.name == "category":
791 self.process_category( child )
792 elif child.name == "OpenGLAPI":
793 self.process_OpenGLAPI( child )
794
795 child = child.next
796
797 return
798
799
800 def process_category(self, cat):
801 cat_name = cat.nsProp( "name", None )
802 cat_number = cat.nsProp( "number", None )
803
804 [cat_type, key] = classify_category(cat_name, cat_number)
805 self.categories[cat_type][key] = [cat_name, cat_number]
806
807 child = cat.children
808 while child:
809 if child.type == "element":
810 if child.name == "function":
811 func_name = real_function_name( child )
812
813 temp_name = child.nsProp( "name", None )
814 self.category_dict[ temp_name ] = [cat_name, cat_number]
815
816 if self.functions_by_name.has_key( func_name ):
817 func = self.functions_by_name[ func_name ]
818 func.process_element( child )
819 else:
820 func = self.factory.create_item( "function", child, self )
821 self.functions_by_name[ func_name ] = func
822
823 if func.offset >= self.next_offset:
824 self.next_offset = func.offset + 1
825
826
827 elif child.name == "enum":
828 enum = self.factory.create_item( "enum", child, self )
829 self.enums_by_name[ enum.name ] = enum
830 elif child.name == "type":
831 t = self.factory.create_item( "type", child, self )
832 self.types_by_name[ "GL" + t.name ] = t
833
834
835 child = child.next
836
837 return
838
839
840 def functionIterateByCategory(self, cat = None):
841 """Iterate over functions by category.
842
843 If cat is None, all known functions are iterated in category
844 order. See classify_category for details of the ordering.
845 Within a category, functions are sorted by name. If cat is
846 not None, then only functions in that category are iterated.
847 """
848 lists = [{}, {}, {}, {}]
849
850 for func in self.functionIterateAll():
851 [cat_name, cat_number] = self.category_dict[func.name]
852
853 if (cat == None) or (cat == cat_name):
854 [func_cat_type, key] = classify_category(cat_name, cat_number)
855
856 if not lists[func_cat_type].has_key(key):
857 lists[func_cat_type][key] = {}
858
859 lists[func_cat_type][key][func.name] = func
860
861
862 functions = []
863 for func_cat_type in range(0,4):
864 keys = lists[func_cat_type].keys()
865 keys.sort()
866
867 for key in keys:
868 names = lists[func_cat_type][key].keys()
869 names.sort()
870
871 for name in names:
872 functions.append(lists[func_cat_type][key][name])
873
874 return functions.__iter__()
875
876
877 def functionIterateByOffset(self):
878 max_offset = -1
879 for func in self.functions_by_name.itervalues():
880 if func.offset > max_offset:
881 max_offset = func.offset
882
883
884 temp = [None for i in range(0, max_offset + 1)]
885 for func in self.functions_by_name.itervalues():
886 if func.offset != -1:
887 temp[ func.offset ] = func
888
889
890 list = []
891 for i in range(0, max_offset + 1):
892 if temp[i]:
893 list.append(temp[i])
894
895 return list.__iter__();
896
897
898 def functionIterateAll(self):
899 return self.functions_by_name.itervalues()
900
901
902 def enumIterateByName(self):
903 keys = self.enums_by_name.keys()
904 keys.sort()
905
906 list = []
907 for enum in keys:
908 list.append( self.enums_by_name[ enum ] )
909
910 return list.__iter__()
911
912
913 def categoryIterate(self):
914 """Iterate over categories.
915
916 Iterate over all known categories in the order specified by
917 classify_category. Each iterated value is a tuple of the
918 name and number (which may be None) of the category.
919 """
920
921 list = []
922 for cat_type in range(0,4):
923 keys = self.categories[cat_type].keys()
924 keys.sort()
925
926 for key in keys:
927 list.append(self.categories[cat_type][key])
928
929 return list.__iter__()
930
931
932 def get_category_for_name( self, name ):
933 if self.category_dict.has_key(name):
934 return self.category_dict[name]
935 else:
936 return ["<unknown category>", None]
937
938
939 def typeIterate(self):
940 return self.types_by_name.itervalues()
941
942
943 def find_type( self, type_name ):
944 if type_name in self.types_by_name:
945 return self.types_by_name[ type_name ].type_expr
946 else:
947 print "Unable to find base type matching \"%s\"." % (type_name)
948 return None