1bab5fee51fd96341c16c76426252ec338dad109
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 collections
import OrderedDict
28 from decimal
import Decimal
29 import xml
.etree
.ElementTree
as ET
30 import re
, sys
, string
36 def parse_GL_API( file_name
, factory
= None ):
39 factory
= gl_item_factory()
41 api
= factory
.create_api()
42 api
.parse_file( file_name
)
44 # After the XML has been processed, we need to go back and assign
45 # dispatch offsets to the functions that request that their offsets
46 # be assigned by the scripts. Typically this means all functions
47 # that are not part of the ABI.
49 for func
in api
.functionIterateByCategory():
50 if func
.assign_offset
:
51 func
.offset
= api
.next_offset
;
57 def is_attr_true( element
, name
, default
= "false" ):
58 """Read a name value from an element's attributes.
60 The value read from the attribute list must be either 'true' or
61 'false'. If the value is 'false', zero will be returned. If the
62 value is 'true', non-zero will be returned. An exception will be
63 raised for any other value."""
65 value
= element
.get( name
, default
)
68 elif value
== "false":
71 raise RuntimeError('Invalid value "%s" for boolean "%s".' % (value
, name
))
74 class gl_print_base(object):
75 """Base class of all API pretty-printers.
77 In the model-view-controller pattern, this is the view. Any derived
78 class will want to over-ride the printBody, printRealHader, and
79 printRealFooter methods. Some derived classes may want to over-ride
80 printHeader and printFooter, or even Print (though this is unlikely).
84 # Name of the script that is generating the output file.
85 # Every derived class should set this to the name of its
91 # License on the *generated* source file. This may differ
92 # from the license on the script that is generating the file.
93 # Every derived class should set this to some reasonable
96 # See license.py for an example of a reasonable value.
98 self
.license
= "The license for this file is unspecified."
101 # The header_tag is the name of the C preprocessor define
102 # used to prevent multiple inclusion. Typically only
103 # generated C header files need this to be set. Setting it
104 # causes code to be generated automatically in printHeader
107 self
.header_tag
= None
110 # List of file-private defines that must be undefined at the
111 # end of the file. This can be used in header files to define
112 # names for use in the file, then undefine them at the end of
119 def Print(self
, api
):
126 def printHeader(self
):
127 """Print the header associated with all files and call the printRealHeader method."""
129 print '/* DO NOT EDIT - This file generated automatically by %s script */' \
133 print (' * ' + self
.license
.replace('\n', '\n * ')).replace(' \n', '\n')
137 print '#if !defined( %s )' % (self
.header_tag
)
138 print '# define %s' % (self
.header_tag
)
140 self
.printRealHeader();
144 def printFooter(self
):
145 """Print the header associated with all files and call the printRealFooter method."""
147 self
.printRealFooter()
151 for u
in self
.undef_list
:
152 print "# undef %s" % (u
)
156 print '#endif /* !defined( %s ) */' % (self
.header_tag
)
159 def printRealHeader(self
):
160 """Print the "real" header for the created file.
162 In the base class, this function is empty. All derived
163 classes should over-ride this function."""
167 def printRealFooter(self
):
168 """Print the "real" footer for the created file.
170 In the base class, this function is empty. All derived
171 classes should over-ride this function."""
176 """Conditionally define `PURE' function attribute.
178 Conditionally defines a preprocessor macro `PURE' that wraps
179 GCC's `pure' function attribute. The conditional code can be
180 easilly adapted to other compilers that support a similar
183 The name is also added to the file's undef_list.
185 self
.undef_list
.append("PURE")
186 print """# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
187 # define PURE __attribute__((pure))
194 def printFastcall(self
):
195 """Conditionally define `FASTCALL' function attribute.
197 Conditionally defines a preprocessor macro `FASTCALL' that
198 wraps GCC's `fastcall' function attribute. The conditional
199 code can be easilly adapted to other compilers that support a
202 The name is also added to the file's undef_list.
205 self
.undef_list
.append("FASTCALL")
206 print """# if defined(__i386__) && defined(__GNUC__) && !defined(__CYGWIN__) && !defined(__MINGW32__)
207 # define FASTCALL __attribute__((fastcall))
214 def printVisibility(self
, S
, s
):
215 """Conditionally define visibility function attribute.
217 Conditionally defines a preprocessor macro name S that wraps
218 GCC's visibility function attribute. The visibility used is
219 the parameter s. The conditional code can be easilly adapted
220 to other compilers that support a similar feature.
222 The name is also added to the file's undef_list.
225 self
.undef_list
.append(S
)
226 print """# if defined(__GNUC__) && !defined(__CYGWIN__) && !defined(__MINGW32__)
227 # define %s __attribute__((visibility("%s")))
230 # endif""" % (S
, s
, S
)
234 def printNoinline(self
):
235 """Conditionally define `NOINLINE' function attribute.
237 Conditionally defines a preprocessor macro `NOINLINE' that
238 wraps GCC's `noinline' function attribute. The conditional
239 code can be easilly adapted to other compilers that support a
242 The name is also added to the file's undef_list.
245 self
.undef_list
.append("NOINLINE")
246 print """# if defined(__GNUC__)
247 # define NOINLINE __attribute__((noinline))
254 def real_function_name(element
):
255 name
= element
.get( "name" )
256 alias
= element
.get( "alias" )
264 def real_category_name(c
):
265 if re
.compile("[1-9][0-9]*[.][0-9]+").match(c
):
266 return "GL_VERSION_" + c
.replace(".", "_")
271 def classify_category(name
, number
):
272 """Based on the category name and number, select a numerical class for it.
274 Categories are divided into four classes numbered 0 through 3. The
277 0. Core GL versions, sorted by version number.
278 1. ARB extensions, sorted by extension number.
279 2. Non-ARB extensions, sorted by extension number.
280 3. Un-numbered extensions, sorted by extension name.
284 core_version
= float(name
)
288 if core_version
> 0.0:
291 elif name
.startswith("GL_ARB_") or name
.startswith("GLX_ARB_") or name
.startswith("WGL_ARB_"):
303 return [cat_type
, key
]
306 def create_parameter_string(parameters
, include_names
):
307 """Create a parameter string from a list of gl_parameters."""
315 list.append( p
.string() )
317 list.append( p
.type_string() )
319 if len(list) == 0: list = ["void"]
321 return string
.join(list, ", ")
324 class gl_item(object):
325 def __init__(self
, element
, context
, category
):
326 self
.context
= context
327 self
.name
= element
.get( "name" )
328 self
.category
= real_category_name( category
)
333 class gl_type( gl_item
):
334 def __init__(self
, element
, context
, category
):
335 gl_item
.__init
__(self
, element
, context
, category
)
336 self
.size
= int( element
.get( "size" ), 0 )
338 te
= typeexpr
.type_expression( None )
339 tn
= typeexpr
.type_node()
340 tn
.size
= int( element
.get( "size" ), 0 )
341 tn
.integer
= not is_attr_true( element
, "float" )
342 tn
.unsigned
= is_attr_true( element
, "unsigned" )
343 tn
.pointer
= is_attr_true( element
, "pointer" )
344 tn
.name
= "GL" + self
.name
345 te
.set_base_type_node( tn
)
351 def get_type_expression(self
):
352 return self
.type_expr
355 class gl_enum( gl_item
):
356 def __init__(self
, element
, context
, category
):
357 gl_item
.__init
__(self
, element
, context
, category
)
358 self
.value
= int( element
.get( "value" ), 0 )
360 temp
= element
.get( "count" )
361 if not temp
or temp
== "?":
362 self
.default_count
= -1
367 raise RuntimeError('Invalid count value "%s" for enum "%s" in function "%s" when an integer was expected.' % (temp
, self
.name
, n
))
369 self
.default_count
= c
375 """Calculate a 'priority' for this enum name.
377 When an enum is looked up by number, there may be many
378 possible names, but only one is the 'prefered' name. The
379 priority is used to select which name is the 'best'.
381 Highest precedence is given to core GL name. ARB extension
382 names have the next highest, followed by EXT extension names.
383 Vendor extension names are the lowest.
386 if self
.name
.endswith( "_BIT" ):
391 if self
.category
.startswith( "GL_VERSION_" ):
393 elif self
.category
.startswith( "GL_ARB_" ):
395 elif self
.category
.startswith( "GL_EXT_" ):
400 return priority
+ bias
404 class gl_parameter(object):
405 def __init__(self
, element
, context
):
406 self
.name
= element
.get( "name" )
408 ts
= element
.get( "type" )
409 self
.type_expr
= typeexpr
.type_expression( ts
, context
)
411 temp
= element
.get( "variable_param" )
413 self
.count_parameter_list
= temp
.split( ' ' )
415 self
.count_parameter_list
= []
417 # The count tag can be either a numeric string or the name of
418 # a variable. If it is the name of a variable, the int(c)
419 # statement will throw an exception, and the except block will
422 c
= element
.get( "count" )
432 self
.count_scale
= int(element
.get( "count_scale", "1" ))
434 elements
= (count
* self
.count_scale
)
438 #if ts == "GLdouble":
439 # print '/* stack size -> %s = %u (before)*/' % (self.name, self.type_expr.get_stack_size())
440 # print '/* # elements = %u */' % (elements)
441 self
.type_expr
.set_elements( elements
)
442 #if ts == "GLdouble":
443 # print '/* stack size -> %s = %u (after) */' % (self.name, self.type_expr.get_stack_size())
445 self
.is_client_only
= is_attr_true( element
, 'client_only' )
446 self
.is_counter
= is_attr_true( element
, 'counter' )
447 self
.is_output
= is_attr_true( element
, 'output' )
450 # Pixel data has special parameters.
452 self
.width
= element
.get('img_width')
453 self
.height
= element
.get('img_height')
454 self
.depth
= element
.get('img_depth')
455 self
.extent
= element
.get('img_extent')
457 self
.img_xoff
= element
.get('img_xoff')
458 self
.img_yoff
= element
.get('img_yoff')
459 self
.img_zoff
= element
.get('img_zoff')
460 self
.img_woff
= element
.get('img_woff')
462 self
.img_format
= element
.get('img_format')
463 self
.img_type
= element
.get('img_type')
464 self
.img_target
= element
.get('img_target')
466 self
.img_pad_dimensions
= is_attr_true( element
, 'img_pad_dimensions' )
467 self
.img_null_flag
= is_attr_true( element
, 'img_null_flag' )
468 self
.img_send_null
= is_attr_true( element
, 'img_send_null' )
470 self
.is_padding
= is_attr_true( element
, 'padding' )
474 def compatible(self
, other
):
479 return self
.is_pointer()
482 def is_pointer(self
):
483 return self
.type_expr
.is_pointer()
493 def is_variable_length(self
):
494 return len(self
.count_parameter_list
) or self
.counter
498 count
= self
.type_expr
.get_element_count()
500 if (self
.size() / count
) == 8:
510 return self
.type_expr
.original_string
+ " " + self
.name
513 def type_string(self
):
514 return self
.type_expr
.original_string
517 def get_base_type_string(self
):
518 return self
.type_expr
.get_base_name()
521 def get_dimensions(self
):
523 return [ 0, "0", "0", "0", "0" ]
543 return [ dim
, w
, h
, d
, e
]
546 def get_stack_size(self
):
547 return self
.type_expr
.get_stack_size()
554 return self
.type_expr
.get_element_size()
557 def get_element_count(self
):
558 c
= self
.type_expr
.get_element_count()
565 def size_string(self
, use_parens
= 1):
567 if self
.counter
or self
.count_parameter_list
:
568 list = [ "compsize" ]
570 if self
.counter
and self
.count_parameter_list
:
571 list.append( self
.counter
)
573 list = [ self
.counter
]
576 list.append( str(s
) )
578 if len(list) > 1 and use_parens
:
579 return "safe_mul(%s)" % (string
.join(list, ", "))
581 return string
.join(list, " * ")
583 elif self
.is_image():
589 def format_string(self
):
590 if self
.type_expr
.original_string
== "GLenum":
593 return self
.type_expr
.format_string()
596 class gl_function( gl_item
):
597 def __init__(self
, element
, context
):
598 self
.context
= context
601 self
.entry_points
= []
602 self
.return_type
= "void"
607 self
.exec_flavor
= 'mesa'
609 self
.deprecated
= None
610 self
.has_no_error_variant
= False
612 # self.entry_point_api_map[name][api] is a decimal value
613 # indicating the earliest version of the given API in which
614 # each entry point exists. Every entry point is included in
615 # the first level of the map; the second level of the map only
616 # lists APIs which contain the entry point in at least one
617 # version. For example,
618 # self.entry_point_api_map['ClipPlanex'] == { 'es1':
620 self
.entry_point_api_map
= {}
622 # self.api_map[api] is a decimal value indicating the earliest
623 # version of the given API in which ANY alias for the function
624 # exists. The map only lists APIs which contain the function
625 # in at least one version. For example, for the ClipPlanex
626 # function, self.entry_point_api_map == { 'es1':
630 self
.assign_offset
= False
632 self
.static_entry_points
= []
634 # Track the parameter string (for the function prototype)
635 # for each entry-point. This is done because some functions
636 # change their prototype slightly when promoted from extension
637 # to ARB extension to core. glTexImage3DEXT and glTexImage3D
638 # are good examples of this. Scripts that need to generate
639 # code for these differing aliases need to real prototype
640 # for each entry-point. Otherwise, they may generate code
641 # that won't compile.
643 self
.entry_point_parameters
= {}
645 self
.process_element( element
)
650 def process_element(self
, element
):
651 name
= element
.get( "name" )
652 alias
= element
.get( "alias" )
654 if name
in static_data
.functions
:
655 self
.static_entry_points
.append(name
)
657 self
.entry_points
.append( name
)
659 self
.entry_point_api_map
[name
] = {}
660 for api
in ('es1', 'es2'):
661 version_str
= element
.get(api
, 'none')
662 assert version_str
is not None
663 if version_str
!= 'none':
664 version_decimal
= Decimal(version_str
)
665 self
.entry_point_api_map
[name
][api
] = version_decimal
666 if api
not in self
.api_map
or \
667 version_decimal
< self
.api_map
[api
]:
668 self
.api_map
[api
] = version_decimal
670 exec_flavor
= element
.get('exec')
672 self
.exec_flavor
= exec_flavor
674 deprecated
= element
.get('deprecated', 'none')
675 if deprecated
!= 'none':
676 self
.deprecated
= Decimal(deprecated
)
678 if not is_attr_true(element
, 'desktop', 'true'):
681 if self
.has_no_error_variant
or is_attr_true(element
, 'no_error'):
682 self
.has_no_error_variant
= True
684 self
.has_no_error_variant
= False
691 # Only try to set the offset when a non-alias entry-point
692 # is being processed.
694 if name
in static_data
.offsets
:
695 self
.offset
= static_data
.offsets
[name
]
698 self
.assign_offset
= self
.exec_flavor
!= "skip" or name
in static_data
.unused_functions
701 self
.name
= true_name
702 elif self
.name
!= true_name
:
703 raise RuntimeError("Function true name redefined. Was %s, now %s." % (self
.name
, true_name
))
706 # There are two possible cases. The first time an entry-point
707 # with data is seen, self.initialized will be 0. On that
708 # pass, we just fill in the data. The next time an
709 # entry-point with data is seen, self.initialized will be 1.
710 # On that pass we have to make that the new values match the
711 # valuse from the previous entry-point.
715 for child
in element
.getchildren():
716 if child
.tag
== "return":
717 return_type
= child
.get( "type", "void" )
718 elif child
.tag
== "param":
719 param
= self
.context
.factory
.create_parameter(child
, self
.context
)
720 parameters
.append( param
)
724 if self
.return_type
!= return_type
:
725 raise RuntimeError( "Return type changed in %s. Was %s, now %s." % (name
, self
.return_type
, return_type
))
727 if len(parameters
) != len(self
.parameters
):
728 raise RuntimeError( "Parameter count mismatch in %s. Was %d, now %d." % (name
, len(self
.parameters
), len(parameters
)))
730 for j
in range(0, len(parameters
)):
732 p2
= self
.parameters
[j
]
733 if not p1
.compatible( p2
):
734 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
))
737 if true_name
== name
or not self
.initialized
:
738 self
.return_type
= return_type
739 self
.parameters
= parameters
741 for param
in self
.parameters
:
743 self
.images
.append( param
)
745 if element
.getchildren():
747 self
.entry_point_parameters
[name
] = parameters
749 self
.entry_point_parameters
[name
] = []
753 def filter_entry_points(self
, entry_point_list
):
754 """Filter out entry points not in entry_point_list."""
755 if not self
.initialized
:
756 raise RuntimeError('%s is not initialized yet' % self
.name
)
759 for ent
in self
.entry_points
:
760 if ent
not in entry_point_list
:
761 if ent
in self
.static_entry_points
:
762 self
.static_entry_points
.remove(ent
)
763 self
.entry_point_parameters
.pop(ent
)
765 entry_points
.append(ent
)
768 raise RuntimeError('%s has no entry point after filtering' % self
.name
)
770 self
.entry_points
= entry_points
771 if self
.name
not in entry_points
:
772 # use the first remaining entry point
773 self
.name
= entry_points
[0]
774 self
.parameters
= self
.entry_point_parameters
[entry_points
[0]]
776 def get_images(self
):
777 """Return potentially empty list of input images."""
781 def parameterIterator(self
, name
= None):
783 return self
.entry_point_parameters
[name
].__iter
__();
785 return self
.parameters
.__iter
__();
788 def get_parameter_string(self
, entrypoint
= None):
790 params
= self
.entry_point_parameters
[ entrypoint
]
792 params
= self
.parameters
794 return create_parameter_string( params
, 1 )
796 def get_called_parameter_string(self
):
800 for p
in self
.parameterIterator():
803 p_string
= p_string
+ comma
+ p
.name
810 return (self
.offset
>= 0 and not self
.assign_offset
)
812 def is_static_entry_point(self
, name
):
813 return name
in self
.static_entry_points
815 def dispatch_name(self
):
816 if self
.name
in self
.static_entry_points
:
819 return "_dispatch_stub_%u" % (self
.offset
)
821 def static_name(self
, name
):
822 if name
in self
.static_entry_points
:
825 return "_dispatch_stub_%u" % (self
.offset
)
827 def entry_points_for_api_version(self
, api
, version
= None):
828 """Return a list of the entry point names for this function
829 which are supported in the given API (and optionally, version).
831 Use the decimal.Decimal type to precisely express non-integer
835 for entry_point
, api_to_ver
in self
.entry_point_api_map
.iteritems():
836 if api
not in api_to_ver
:
838 if version
is not None and version
< api_to_ver
[api
]:
840 result
.append(entry_point
)
844 class gl_item_factory(object):
845 """Factory to create objects derived from gl_item."""
847 def create_function(self
, element
, context
):
848 return gl_function(element
, context
)
850 def create_type(self
, element
, context
, category
):
851 return gl_type(element
, context
, category
)
853 def create_enum(self
, element
, context
, category
):
854 return gl_enum(element
, context
, category
)
856 def create_parameter(self
, element
, context
):
857 return gl_parameter(element
, context
)
859 def create_api(self
):
863 class gl_api(object):
864 def __init__(self
, factory
):
865 self
.functions_by_name
= OrderedDict()
866 self
.enums_by_name
= {}
867 self
.types_by_name
= {}
869 self
.category_dict
= {}
870 self
.categories
= [{}, {}, {}, {}]
872 self
.factory
= factory
876 typeexpr
.create_initial_types()
879 def filter_functions(self
, entry_point_list
):
880 """Filter out entry points not in entry_point_list."""
881 functions_by_name
= {}
882 for func
in self
.functions_by_name
.itervalues():
883 entry_points
= [ent
for ent
in func
.entry_points
if ent
in entry_point_list
]
885 func
.filter_entry_points(entry_points
)
886 functions_by_name
[func
.name
] = func
888 self
.functions_by_name
= functions_by_name
890 def filter_functions_by_api(self
, api
, version
= None):
891 """Filter out entry points not in the given API (or
892 optionally, not in the given version of the given API).
894 functions_by_name
= {}
895 for func
in self
.functions_by_name
.itervalues():
896 entry_points
= func
.entry_points_for_api_version(api
, version
)
898 func
.filter_entry_points(entry_points
)
899 functions_by_name
[func
.name
] = func
901 self
.functions_by_name
= functions_by_name
904 def parse_file(self
, file_name
):
905 doc
= ET
.parse( file_name
)
906 self
.process_element(file_name
, doc
)
909 def process_element(self
, file_name
, doc
):
910 element
= doc
.getroot()
911 if element
.tag
== "OpenGLAPI":
912 self
.process_OpenGLAPI(file_name
, element
)
916 def process_OpenGLAPI(self
, file_name
, element
):
917 for child
in element
.getchildren():
918 if child
.tag
== "category":
919 self
.process_category( child
)
920 elif child
.tag
== "OpenGLAPI":
921 self
.process_OpenGLAPI( file_name
, child
)
922 elif child
.tag
== '{http://www.w3.org/2001/XInclude}include':
923 href
= child
.get('href')
924 href
= os
.path
.join(os
.path
.dirname(file_name
), href
)
925 self
.parse_file(href
)
930 def process_category(self
, cat
):
931 cat_name
= cat
.get( "name" )
932 cat_number
= cat
.get( "number" )
934 [cat_type
, key
] = classify_category(cat_name
, cat_number
)
935 self
.categories
[cat_type
][key
] = [cat_name
, cat_number
]
937 for child
in cat
.getchildren():
938 if child
.tag
== "function":
939 func_name
= real_function_name( child
)
941 temp_name
= child
.get( "name" )
942 self
.category_dict
[ temp_name
] = [cat_name
, cat_number
]
944 if self
.functions_by_name
.has_key( func_name
):
945 func
= self
.functions_by_name
[ func_name
]
946 func
.process_element( child
)
948 func
= self
.factory
.create_function( child
, self
)
949 self
.functions_by_name
[ func_name
] = func
951 if func
.offset
>= self
.next_offset
:
952 self
.next_offset
= func
.offset
+ 1
955 elif child
.tag
== "enum":
956 enum
= self
.factory
.create_enum( child
, self
, cat_name
)
957 self
.enums_by_name
[ enum
.name
] = enum
958 elif child
.tag
== "type":
959 t
= self
.factory
.create_type( child
, self
, cat_name
)
960 self
.types_by_name
[ "GL" + t
.name
] = t
965 def functionIterateByCategory(self
, cat
= None):
966 """Iterate over functions by category.
968 If cat is None, all known functions are iterated in category
969 order. See classify_category for details of the ordering.
970 Within a category, functions are sorted by name. If cat is
971 not None, then only functions in that category are iterated.
973 lists
= [{}, {}, {}, {}]
975 for func
in self
.functionIterateAll():
976 [cat_name
, cat_number
] = self
.category_dict
[func
.name
]
978 if (cat
== None) or (cat
== cat_name
):
979 [func_cat_type
, key
] = classify_category(cat_name
, cat_number
)
981 if not lists
[func_cat_type
].has_key(key
):
982 lists
[func_cat_type
][key
] = {}
984 lists
[func_cat_type
][key
][func
.name
] = func
988 for func_cat_type
in range(0,4):
989 keys
= lists
[func_cat_type
].keys()
993 names
= lists
[func_cat_type
][key
].keys()
997 functions
.append(lists
[func_cat_type
][key
][name
])
999 return functions
.__iter
__()
1002 def functionIterateByOffset(self
):
1004 for func
in self
.functions_by_name
.itervalues():
1005 if func
.offset
> max_offset
:
1006 max_offset
= func
.offset
1009 temp
= [None for i
in range(0, max_offset
+ 1)]
1010 for func
in self
.functions_by_name
.itervalues():
1011 if func
.offset
!= -1:
1012 temp
[ func
.offset
] = func
1016 for i
in range(0, max_offset
+ 1):
1018 list.append(temp
[i
])
1020 return list.__iter
__();
1023 def functionIterateAll(self
):
1024 return self
.functions_by_name
.itervalues()
1027 def enumIterateByName(self
):
1028 keys
= self
.enums_by_name
.keys()
1033 list.append( self
.enums_by_name
[ enum
] )
1035 return list.__iter
__()
1038 def categoryIterate(self
):
1039 """Iterate over categories.
1041 Iterate over all known categories in the order specified by
1042 classify_category. Each iterated value is a tuple of the
1043 name and number (which may be None) of the category.
1047 for cat_type
in range(0,4):
1048 keys
= self
.categories
[cat_type
].keys()
1052 list.append(self
.categories
[cat_type
][key
])
1054 return list.__iter
__()
1057 def get_category_for_name( self
, name
):
1058 if self
.category_dict
.has_key(name
):
1059 return self
.category_dict
[name
]
1061 return ["<unknown category>", None]
1064 def typeIterate(self
):
1065 return self
.types_by_name
.itervalues()
1068 def find_type( self
, type_name
):
1069 if type_name
in self
.types_by_name
:
1070 return self
.types_by_name
[ type_name
].type_expr
1072 print "Unable to find base type matching \"%s\"." % (type_name
)