2 # (C) Copyright IBM Corporation 2004, 2005
5 # Permission is hereby granted, free of charge, to any person obtaining a
6 # copy of this software and associated documentation files (the "Software"),
7 # to deal in the Software without restriction, including without limitation
8 # on the rights to use, copy, modify, merge, publish, distribute, sub
9 # license, and/or sell copies of the Software, and to permit persons to whom
10 # the Software is furnished to do so, subject to the following conditions:
12 # The above copyright notice and this permission notice (including the next
13 # paragraph) shall be included in all copies or substantial portions of the
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 # IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 # Ian Romanick <idr@us.ibm.com>
27 from decimal
import Decimal
28 import xml
.etree
.ElementTree
as ET
29 import re
, sys
, string
35 def parse_GL_API( file_name
, factory
= None ):
38 factory
= gl_item_factory()
40 api
= factory
.create_api()
41 api
.parse_file( file_name
)
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.
48 for func
in api
.functionIterateByCategory():
49 if func
.assign_offset
:
50 func
.offset
= api
.next_offset
;
56 def is_attr_true( element
, name
, default
= "false" ):
57 """Read a name value from an element's attributes.
59 The value read from the attribute list must be either 'true' or
60 'false'. If the value is 'false', zero will be returned. If the
61 value is 'true', non-zero will be returned. An exception will be
62 raised for any other value."""
64 value
= element
.get( name
, default
)
67 elif value
== "false":
70 raise RuntimeError('Invalid value "%s" for boolean "%s".' % (value
, name
))
73 class gl_print_base(object):
74 """Base class of all API pretty-printers.
76 In the model-view-controller pattern, this is the view. Any derived
77 class will want to over-ride the printBody, printRealHader, and
78 printRealFooter methods. Some derived classes may want to over-ride
79 printHeader and printFooter, or even Print (though this is unlikely).
83 # Name of the script that is generating the output file.
84 # Every derived class should set this to the name of its
90 # License on the *generated* source file. This may differ
91 # from the license on the script that is generating the file.
92 # Every derived class should set this to some reasonable
95 # See license.py for an example of a reasonable value.
97 self
.license
= "The license for this file is unspecified."
100 # The header_tag is the name of the C preprocessor define
101 # used to prevent multiple inclusion. Typically only
102 # generated C header files need this to be set. Setting it
103 # causes code to be generated automatically in printHeader
106 self
.header_tag
= None
109 # List of file-private defines that must be undefined at the
110 # end of the file. This can be used in header files to define
111 # names for use in the file, then undefine them at the end of
118 def Print(self
, api
):
125 def printHeader(self
):
126 """Print the header associated with all files and call the printRealHeader method."""
128 print '/* DO NOT EDIT - This file generated automatically by %s script */' \
132 print (' * ' + self
.license
.replace('\n', '\n * ')).replace(' \n', '\n')
136 print '#if !defined( %s )' % (self
.header_tag
)
137 print '# define %s' % (self
.header_tag
)
139 self
.printRealHeader();
143 def printFooter(self
):
144 """Print the header associated with all files and call the printRealFooter method."""
146 self
.printRealFooter()
150 for u
in self
.undef_list
:
151 print "# undef %s" % (u
)
155 print '#endif /* !defined( %s ) */' % (self
.header_tag
)
158 def printRealHeader(self
):
159 """Print the "real" header for the created file.
161 In the base class, this function is empty. All derived
162 classes should over-ride this function."""
166 def printRealFooter(self
):
167 """Print the "real" footer for the created file.
169 In the base class, this function is empty. All derived
170 classes should over-ride this function."""
175 """Conditionally define `PURE' function attribute.
177 Conditionally defines a preprocessor macro `PURE' that wraps
178 GCC's `pure' function attribute. The conditional code can be
179 easilly adapted to other compilers that support a similar
182 The name is also added to the file's undef_list.
184 self
.undef_list
.append("PURE")
185 print """# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
186 # define PURE __attribute__((pure))
193 def printFastcall(self
):
194 """Conditionally define `FASTCALL' function attribute.
196 Conditionally defines a preprocessor macro `FASTCALL' that
197 wraps GCC's `fastcall' function attribute. The conditional
198 code can be easilly adapted to other compilers that support a
201 The name is also added to the file's undef_list.
204 self
.undef_list
.append("FASTCALL")
205 print """# if defined(__i386__) && defined(__GNUC__) && !defined(__CYGWIN__) && !defined(__MINGW32__)
206 # define FASTCALL __attribute__((fastcall))
213 def printVisibility(self
, S
, s
):
214 """Conditionally define visibility function attribute.
216 Conditionally defines a preprocessor macro name S that wraps
217 GCC's visibility function attribute. The visibility used is
218 the parameter s. The conditional code can be easilly adapted
219 to other compilers that support a similar feature.
221 The name is also added to the file's undef_list.
224 self
.undef_list
.append(S
)
225 print """# if defined(__GNUC__) && !defined(__CYGWIN__) && !defined(__MINGW32__)
226 # define %s __attribute__((visibility("%s")))
229 # endif""" % (S
, s
, S
)
233 def printNoinline(self
):
234 """Conditionally define `NOINLINE' function attribute.
236 Conditionally defines a preprocessor macro `NOINLINE' that
237 wraps GCC's `noinline' function attribute. The conditional
238 code can be easilly adapted to other compilers that support a
241 The name is also added to the file's undef_list.
244 self
.undef_list
.append("NOINLINE")
245 print """# if defined(__GNUC__)
246 # define NOINLINE __attribute__((noinline))
253 def real_function_name(element
):
254 name
= element
.get( "name" )
255 alias
= element
.get( "alias" )
263 def real_category_name(c
):
264 if re
.compile("[1-9][0-9]*[.][0-9]+").match(c
):
265 return "GL_VERSION_" + c
.replace(".", "_")
270 def classify_category(name
, number
):
271 """Based on the category name and number, select a numerical class for it.
273 Categories are divided into four classes numbered 0 through 3. The
276 0. Core GL versions, sorted by version number.
277 1. ARB extensions, sorted by extension number.
278 2. Non-ARB extensions, sorted by extension number.
279 3. Un-numbered extensions, sorted by extension name.
283 core_version
= float(name
)
287 if core_version
> 0.0:
290 elif name
.startswith("GL_ARB_") or name
.startswith("GLX_ARB_") or name
.startswith("WGL_ARB_"):
302 return [cat_type
, key
]
305 def create_parameter_string(parameters
, include_names
):
306 """Create a parameter string from a list of gl_parameters."""
314 list.append( p
.string() )
316 list.append( p
.type_string() )
318 if len(list) == 0: list = ["void"]
320 return string
.join(list, ", ")
323 class gl_item(object):
324 def __init__(self
, element
, context
, category
):
325 self
.context
= context
326 self
.name
= element
.get( "name" )
327 self
.category
= real_category_name( category
)
332 class gl_type( gl_item
):
333 def __init__(self
, element
, context
, category
):
334 gl_item
.__init
__(self
, element
, context
, category
)
335 self
.size
= int( element
.get( "size" ), 0 )
337 te
= typeexpr
.type_expression( None )
338 tn
= typeexpr
.type_node()
339 tn
.size
= int( element
.get( "size" ), 0 )
340 tn
.integer
= not is_attr_true( element
, "float" )
341 tn
.unsigned
= is_attr_true( element
, "unsigned" )
342 tn
.pointer
= is_attr_true( element
, "pointer" )
343 tn
.name
= "GL" + self
.name
344 te
.set_base_type_node( tn
)
350 def get_type_expression(self
):
351 return self
.type_expr
354 class gl_enum( gl_item
):
355 def __init__(self
, element
, context
, category
):
356 gl_item
.__init
__(self
, element
, context
, category
)
357 self
.value
= int( element
.get( "value" ), 0 )
359 temp
= element
.get( "count" )
360 if not temp
or temp
== "?":
361 self
.default_count
= -1
366 raise RuntimeError('Invalid count value "%s" for enum "%s" in function "%s" when an integer was expected.' % (temp
, self
.name
, n
))
368 self
.default_count
= c
374 """Calculate a 'priority' for this enum name.
376 When an enum is looked up by number, there may be many
377 possible names, but only one is the 'prefered' name. The
378 priority is used to select which name is the 'best'.
380 Highest precedence is given to core GL name. ARB extension
381 names have the next highest, followed by EXT extension names.
382 Vendor extension names are the lowest.
385 if self
.name
.endswith( "_BIT" ):
390 if self
.category
.startswith( "GL_VERSION_" ):
392 elif self
.category
.startswith( "GL_ARB_" ):
394 elif self
.category
.startswith( "GL_EXT_" ):
399 return priority
+ bias
403 class gl_parameter(object):
404 def __init__(self
, element
, context
):
405 self
.name
= element
.get( "name" )
407 ts
= element
.get( "type" )
408 self
.type_expr
= typeexpr
.type_expression( ts
, context
)
410 temp
= element
.get( "variable_param" )
412 self
.count_parameter_list
= temp
.split( ' ' )
414 self
.count_parameter_list
= []
416 # The count tag can be either a numeric string or the name of
417 # a variable. If it is the name of a variable, the int(c)
418 # statement will throw an exception, and the except block will
421 c
= element
.get( "count" )
431 self
.count_scale
= int(element
.get( "count_scale", "1" ))
433 elements
= (count
* self
.count_scale
)
437 #if ts == "GLdouble":
438 # print '/* stack size -> %s = %u (before)*/' % (self.name, self.type_expr.get_stack_size())
439 # print '/* # elements = %u */' % (elements)
440 self
.type_expr
.set_elements( elements
)
441 #if ts == "GLdouble":
442 # print '/* stack size -> %s = %u (after) */' % (self.name, self.type_expr.get_stack_size())
444 self
.is_client_only
= is_attr_true( element
, 'client_only' )
445 self
.is_counter
= is_attr_true( element
, 'counter' )
446 self
.is_output
= is_attr_true( element
, 'output' )
449 # Pixel data has special parameters.
451 self
.width
= element
.get('img_width')
452 self
.height
= element
.get('img_height')
453 self
.depth
= element
.get('img_depth')
454 self
.extent
= element
.get('img_extent')
456 self
.img_xoff
= element
.get('img_xoff')
457 self
.img_yoff
= element
.get('img_yoff')
458 self
.img_zoff
= element
.get('img_zoff')
459 self
.img_woff
= element
.get('img_woff')
461 self
.img_format
= element
.get('img_format')
462 self
.img_type
= element
.get('img_type')
463 self
.img_target
= element
.get('img_target')
465 self
.img_pad_dimensions
= is_attr_true( element
, 'img_pad_dimensions' )
466 self
.img_null_flag
= is_attr_true( element
, 'img_null_flag' )
467 self
.img_send_null
= is_attr_true( element
, 'img_send_null' )
469 self
.is_padding
= is_attr_true( element
, 'padding' )
473 def compatible(self
, other
):
478 return self
.is_pointer()
481 def is_pointer(self
):
482 return self
.type_expr
.is_pointer()
492 def is_variable_length(self
):
493 return len(self
.count_parameter_list
) or self
.counter
497 count
= self
.type_expr
.get_element_count()
499 if (self
.size() / count
) == 8:
509 return self
.type_expr
.original_string
+ " " + self
.name
512 def type_string(self
):
513 return self
.type_expr
.original_string
516 def get_base_type_string(self
):
517 return self
.type_expr
.get_base_name()
520 def get_dimensions(self
):
522 return [ 0, "0", "0", "0", "0" ]
542 return [ dim
, w
, h
, d
, e
]
545 def get_stack_size(self
):
546 return self
.type_expr
.get_stack_size()
553 return self
.type_expr
.get_element_size()
556 def get_element_count(self
):
557 c
= self
.type_expr
.get_element_count()
564 def size_string(self
, use_parens
= 1):
566 if self
.counter
or self
.count_parameter_list
:
567 list = [ "compsize" ]
569 if self
.counter
and self
.count_parameter_list
:
570 list.append( self
.counter
)
572 list = [ self
.counter
]
575 list.append( str(s
) )
577 if len(list) > 1 and use_parens
:
578 return "safe_mul(%s)" % (string
.join(list, ", "))
580 return string
.join(list, " * ")
582 elif self
.is_image():
588 def format_string(self
):
589 if self
.type_expr
.original_string
== "GLenum":
592 return self
.type_expr
.format_string()
595 class gl_function( gl_item
):
596 def __init__(self
, element
, context
):
597 self
.context
= context
600 self
.entry_points
= []
601 self
.return_type
= "void"
606 self
.exec_flavor
= 'mesa'
608 self
.deprecated
= None
609 self
.has_no_error_variant
= False
611 # self.entry_point_api_map[name][api] is a decimal value
612 # indicating the earliest version of the given API in which
613 # each entry point exists. Every entry point is included in
614 # the first level of the map; the second level of the map only
615 # lists APIs which contain the entry point in at least one
616 # version. For example,
617 # self.entry_point_api_map['ClipPlanex'] == { 'es1':
619 self
.entry_point_api_map
= {}
621 # self.api_map[api] is a decimal value indicating the earliest
622 # version of the given API in which ANY alias for the function
623 # exists. The map only lists APIs which contain the function
624 # in at least one version. For example, for the ClipPlanex
625 # function, self.entry_point_api_map == { 'es1':
629 self
.assign_offset
= False
631 self
.static_entry_points
= []
633 # Track the parameter string (for the function prototype)
634 # for each entry-point. This is done because some functions
635 # change their prototype slightly when promoted from extension
636 # to ARB extension to core. glTexImage3DEXT and glTexImage3D
637 # are good examples of this. Scripts that need to generate
638 # code for these differing aliases need to real prototype
639 # for each entry-point. Otherwise, they may generate code
640 # that won't compile.
642 self
.entry_point_parameters
= {}
644 self
.process_element( element
)
649 def process_element(self
, element
):
650 name
= element
.get( "name" )
651 alias
= element
.get( "alias" )
653 if name
in static_data
.functions
:
654 self
.static_entry_points
.append(name
)
656 self
.entry_points
.append( name
)
658 self
.entry_point_api_map
[name
] = {}
659 for api
in ('es1', 'es2'):
660 version_str
= element
.get(api
, 'none')
661 assert version_str
is not None
662 if version_str
!= 'none':
663 version_decimal
= Decimal(version_str
)
664 self
.entry_point_api_map
[name
][api
] = version_decimal
665 if api
not in self
.api_map
or \
666 version_decimal
< self
.api_map
[api
]:
667 self
.api_map
[api
] = version_decimal
669 exec_flavor
= element
.get('exec')
671 self
.exec_flavor
= exec_flavor
673 deprecated
= element
.get('deprecated', 'none')
674 if deprecated
!= 'none':
675 self
.deprecated
= Decimal(deprecated
)
677 if not is_attr_true(element
, 'desktop', 'true'):
680 if self
.has_no_error_variant
or is_attr_true(element
, 'no_error'):
681 self
.has_no_error_variant
= True
683 self
.has_no_error_variant
= False
690 # Only try to set the offset when a non-alias entry-point
691 # is being processed.
693 if name
in static_data
.offsets
:
694 self
.offset
= static_data
.offsets
[name
]
697 self
.assign_offset
= self
.exec_flavor
!= "skip" or name
in static_data
.unused_functions
700 self
.name
= true_name
701 elif self
.name
!= true_name
:
702 raise RuntimeError("Function true name redefined. Was %s, now %s." % (self
.name
, true_name
))
705 # There are two possible cases. The first time an entry-point
706 # with data is seen, self.initialized will be 0. On that
707 # pass, we just fill in the data. The next time an
708 # entry-point with data is seen, self.initialized will be 1.
709 # On that pass we have to make that the new values match the
710 # valuse from the previous entry-point.
714 for child
in element
.getchildren():
715 if child
.tag
== "return":
716 return_type
= child
.get( "type", "void" )
717 elif child
.tag
== "param":
718 param
= self
.context
.factory
.create_parameter(child
, self
.context
)
719 parameters
.append( param
)
723 if self
.return_type
!= return_type
:
724 raise RuntimeError( "Return type changed in %s. Was %s, now %s." % (name
, self
.return_type
, return_type
))
726 if len(parameters
) != len(self
.parameters
):
727 raise RuntimeError( "Parameter count mismatch in %s. Was %d, now %d." % (name
, len(self
.parameters
), len(parameters
)))
729 for j
in range(0, len(parameters
)):
731 p2
= self
.parameters
[j
]
732 if not p1
.compatible( p2
):
733 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
))
736 if true_name
== name
or not self
.initialized
:
737 self
.return_type
= return_type
738 self
.parameters
= parameters
740 for param
in self
.parameters
:
742 self
.images
.append( param
)
744 if element
.getchildren():
746 self
.entry_point_parameters
[name
] = parameters
748 self
.entry_point_parameters
[name
] = []
752 def filter_entry_points(self
, entry_point_list
):
753 """Filter out entry points not in entry_point_list."""
754 if not self
.initialized
:
755 raise RuntimeError('%s is not initialized yet' % self
.name
)
758 for ent
in self
.entry_points
:
759 if ent
not in entry_point_list
:
760 if ent
in self
.static_entry_points
:
761 self
.static_entry_points
.remove(ent
)
762 self
.entry_point_parameters
.pop(ent
)
764 entry_points
.append(ent
)
767 raise RuntimeError('%s has no entry point after filtering' % self
.name
)
769 self
.entry_points
= entry_points
770 if self
.name
not in entry_points
:
771 # use the first remaining entry point
772 self
.name
= entry_points
[0]
773 self
.parameters
= self
.entry_point_parameters
[entry_points
[0]]
775 def get_images(self
):
776 """Return potentially empty list of input images."""
780 def parameterIterator(self
, name
= None):
782 return self
.entry_point_parameters
[name
].__iter
__();
784 return self
.parameters
.__iter
__();
787 def get_parameter_string(self
, entrypoint
= None):
789 params
= self
.entry_point_parameters
[ entrypoint
]
791 params
= self
.parameters
793 return create_parameter_string( params
, 1 )
795 def get_called_parameter_string(self
):
799 for p
in self
.parameterIterator():
802 p_string
= p_string
+ comma
+ p
.name
809 return (self
.offset
>= 0 and not self
.assign_offset
)
811 def is_static_entry_point(self
, name
):
812 return name
in self
.static_entry_points
814 def dispatch_name(self
):
815 if self
.name
in self
.static_entry_points
:
818 return "_dispatch_stub_%u" % (self
.offset
)
820 def static_name(self
, name
):
821 if name
in self
.static_entry_points
:
824 return "_dispatch_stub_%u" % (self
.offset
)
826 def entry_points_for_api_version(self
, api
, version
= None):
827 """Return a list of the entry point names for this function
828 which are supported in the given API (and optionally, version).
830 Use the decimal.Decimal type to precisely express non-integer
834 for entry_point
, api_to_ver
in self
.entry_point_api_map
.iteritems():
835 if api
not in api_to_ver
:
837 if version
is not None and version
< api_to_ver
[api
]:
839 result
.append(entry_point
)
843 class gl_item_factory(object):
844 """Factory to create objects derived from gl_item."""
846 def create_function(self
, element
, context
):
847 return gl_function(element
, context
)
849 def create_type(self
, element
, context
, category
):
850 return gl_type(element
, context
, category
)
852 def create_enum(self
, element
, context
, category
):
853 return gl_enum(element
, context
, category
)
855 def create_parameter(self
, element
, context
):
856 return gl_parameter(element
, context
)
858 def create_api(self
):
862 class gl_api(object):
863 def __init__(self
, factory
):
864 self
.functions_by_name
= {}
865 self
.enums_by_name
= {}
866 self
.types_by_name
= {}
868 self
.category_dict
= {}
869 self
.categories
= [{}, {}, {}, {}]
871 self
.factory
= factory
875 typeexpr
.create_initial_types()
878 def filter_functions(self
, entry_point_list
):
879 """Filter out entry points not in entry_point_list."""
880 functions_by_name
= {}
881 for func
in self
.functions_by_name
.itervalues():
882 entry_points
= [ent
for ent
in func
.entry_points
if ent
in entry_point_list
]
884 func
.filter_entry_points(entry_points
)
885 functions_by_name
[func
.name
] = func
887 self
.functions_by_name
= functions_by_name
889 def filter_functions_by_api(self
, api
, version
= None):
890 """Filter out entry points not in the given API (or
891 optionally, not in the given version of the given API).
893 functions_by_name
= {}
894 for func
in self
.functions_by_name
.itervalues():
895 entry_points
= func
.entry_points_for_api_version(api
, version
)
897 func
.filter_entry_points(entry_points
)
898 functions_by_name
[func
.name
] = func
900 self
.functions_by_name
= functions_by_name
903 def parse_file(self
, file_name
):
904 doc
= ET
.parse( file_name
)
905 self
.process_element(file_name
, doc
)
908 def process_element(self
, file_name
, doc
):
909 element
= doc
.getroot()
910 if element
.tag
== "OpenGLAPI":
911 self
.process_OpenGLAPI(file_name
, element
)
915 def process_OpenGLAPI(self
, file_name
, element
):
916 for child
in element
.getchildren():
917 if child
.tag
== "category":
918 self
.process_category( child
)
919 elif child
.tag
== "OpenGLAPI":
920 self
.process_OpenGLAPI( file_name
, child
)
921 elif child
.tag
== '{http://www.w3.org/2001/XInclude}include':
922 href
= child
.get('href')
923 href
= os
.path
.join(os
.path
.dirname(file_name
), href
)
924 self
.parse_file(href
)
929 def process_category(self
, cat
):
930 cat_name
= cat
.get( "name" )
931 cat_number
= cat
.get( "number" )
933 [cat_type
, key
] = classify_category(cat_name
, cat_number
)
934 self
.categories
[cat_type
][key
] = [cat_name
, cat_number
]
936 for child
in cat
.getchildren():
937 if child
.tag
== "function":
938 func_name
= real_function_name( child
)
940 temp_name
= child
.get( "name" )
941 self
.category_dict
[ temp_name
] = [cat_name
, cat_number
]
943 if self
.functions_by_name
.has_key( func_name
):
944 func
= self
.functions_by_name
[ func_name
]
945 func
.process_element( child
)
947 func
= self
.factory
.create_function( child
, self
)
948 self
.functions_by_name
[ func_name
] = func
950 if func
.offset
>= self
.next_offset
:
951 self
.next_offset
= func
.offset
+ 1
954 elif child
.tag
== "enum":
955 enum
= self
.factory
.create_enum( child
, self
, cat_name
)
956 self
.enums_by_name
[ enum
.name
] = enum
957 elif child
.tag
== "type":
958 t
= self
.factory
.create_type( child
, self
, cat_name
)
959 self
.types_by_name
[ "GL" + t
.name
] = t
964 def functionIterateByCategory(self
, cat
= None):
965 """Iterate over functions by category.
967 If cat is None, all known functions are iterated in category
968 order. See classify_category for details of the ordering.
969 Within a category, functions are sorted by name. If cat is
970 not None, then only functions in that category are iterated.
972 lists
= [{}, {}, {}, {}]
974 for func
in self
.functionIterateAll():
975 [cat_name
, cat_number
] = self
.category_dict
[func
.name
]
977 if (cat
== None) or (cat
== cat_name
):
978 [func_cat_type
, key
] = classify_category(cat_name
, cat_number
)
980 if not lists
[func_cat_type
].has_key(key
):
981 lists
[func_cat_type
][key
] = {}
983 lists
[func_cat_type
][key
][func
.name
] = func
987 for func_cat_type
in range(0,4):
988 keys
= lists
[func_cat_type
].keys()
992 names
= lists
[func_cat_type
][key
].keys()
996 functions
.append(lists
[func_cat_type
][key
][name
])
998 return functions
.__iter
__()
1001 def functionIterateByOffset(self
):
1003 for func
in self
.functions_by_name
.itervalues():
1004 if func
.offset
> max_offset
:
1005 max_offset
= func
.offset
1008 temp
= [None for i
in range(0, max_offset
+ 1)]
1009 for func
in self
.functions_by_name
.itervalues():
1010 if func
.offset
!= -1:
1011 temp
[ func
.offset
] = func
1015 for i
in range(0, max_offset
+ 1):
1017 list.append(temp
[i
])
1019 return list.__iter
__();
1022 def functionIterateAll(self
):
1023 return self
.functions_by_name
.itervalues()
1026 def enumIterateByName(self
):
1027 keys
= self
.enums_by_name
.keys()
1032 list.append( self
.enums_by_name
[ enum
] )
1034 return list.__iter
__()
1037 def categoryIterate(self
):
1038 """Iterate over categories.
1040 Iterate over all known categories in the order specified by
1041 classify_category. Each iterated value is a tuple of the
1042 name and number (which may be None) of the category.
1046 for cat_type
in range(0,4):
1047 keys
= self
.categories
[cat_type
].keys()
1051 list.append(self
.categories
[cat_type
][key
])
1053 return list.__iter
__()
1056 def get_category_for_name( self
, name
):
1057 if self
.category_dict
.has_key(name
):
1058 return self
.category_dict
[name
]
1060 return ["<unknown category>", None]
1063 def typeIterate(self
):
1064 return self
.types_by_name
.itervalues()
1067 def find_type( self
, type_name
):
1068 if type_name
in self
.types_by_name
:
1069 return self
.types_by_name
[ type_name
].type_expr
1071 print "Unable to find base type matching \"%s\"." % (type_name
)