mapi/glapi: Generate sizeof() helpers instead of fixed sizes.
[mesa.git] / src / mapi / glapi / gen / gl_XML.py
index 3bbc794398f27356490293600a06d915ada0ef72..5b5f6e23b0a9159cedd6cad1a66f7b0f8c21463e 100644 (file)
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 
 # (C) Copyright IBM Corporation 2004, 2005
 # All Rights Reserved.
 # Authors:
 #    Ian Romanick <idr@us.ibm.com>
 
+from __future__ import print_function
+
+from collections import OrderedDict
 from decimal import Decimal
-import libxml2
-import re, sys, string
+import xml.etree.ElementTree as ET
+import re, sys
+import os.path
 import typeexpr
+import static_data
 
 
 def parse_GL_API( file_name, factory = None ):
-    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 )
-    ret = doc.xincludeProcess()
 
     if not factory:
         factory = gl_item_factory()
 
-    api = factory.create_item( "api", None, None )
-    api.process_element( doc )
+    api = factory.create_api()
+    api.parse_file( file_name )
 
     # After the XML has been processed, we need to go back and assign
     # dispatch offsets to the functions that request that their offsets
@@ -47,16 +49,14 @@ def parse_GL_API( file_name, factory = None ):
     # that are not part of the ABI.
 
     for func in api.functionIterateByCategory():
-        if func.assign_offset:
+        if func.assign_offset and func.offset < 0:
             func.offset = api.next_offset;
             api.next_offset += 1
 
-    doc.freeDoc()
-
     return api
 
 
-def is_attr_true( element, name ):
+def is_attr_true( element, name, default = "false" ):
     """Read a name value from an element's attributes.
 
     The value read from the attribute list must be either 'true' or
@@ -64,7 +64,7 @@ def is_attr_true( element, name ):
     value is 'true', non-zero will be returned.  An exception will be
     raised for any other value."""
 
-    value = element.nsProp( name, None )
+    value = element.get( name, default )
     if value == "true":
         return 1
     elif value == "false":
@@ -128,17 +128,17 @@ class gl_print_base(object):
     def printHeader(self):
         """Print the header associated with all files and call the printRealHeader method."""
 
-        print '/* DO NOT EDIT - This file generated automatically by %s script */' \
-                % (self.name)
-        print ''
-        print '/*'
-        print ' * ' + self.license.replace('\n', '\n * ')
-        print ' */'
-        print ''
+        print('/* DO NOT EDIT - This file generated automatically by %s script */' \
+                % (self.name))
+        print('')
+        print('/*')
+        print((' * ' + self.license.replace('\n', '\n * ')).replace(' \n', '\n'))
+        print(' */')
+        print('')
         if self.header_tag:
-            print '#if !defined( %s )' % (self.header_tag)
-            print '#  define %s' % (self.header_tag)
-            print ''
+            print('#if !defined( %s )' % (self.header_tag))
+            print('#  define %s' % (self.header_tag))
+            print('')
         self.printRealHeader();
         return
 
@@ -149,13 +149,13 @@ class gl_print_base(object):
         self.printRealFooter()
 
         if self.undef_list:
-            print ''
+            print('')
             for u in self.undef_list:
-                print "#  undef %s" % (u)
+                print("#  undef %s" % (u))
 
         if self.header_tag:
-            print ''
-            print '#endif /* !defined( %s ) */' % (self.header_tag)
+            print('')
+            print('#endif /* !defined( %s ) */' % (self.header_tag))
 
 
     def printRealHeader(self):
@@ -185,11 +185,11 @@ class gl_print_base(object):
         The name is also added to the file's undef_list.
         """
         self.undef_list.append("PURE")
-        print """#  if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
+        print("""#  if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
 #    define PURE __attribute__((pure))
 #  else
 #    define PURE
-#  endif"""
+#  endif""")
         return
 
 
@@ -205,11 +205,11 @@ class gl_print_base(object):
         """
 
         self.undef_list.append("FASTCALL")
-        print """#  if defined(__i386__) && defined(__GNUC__) && !defined(__CYGWIN__) && !defined(__MINGW32__)
+        print("""#  if defined(__i386__) && defined(__GNUC__) && !defined(__CYGWIN__) && !defined(__MINGW32__)
 #    define FASTCALL __attribute__((fastcall))
 #  else
 #    define FASTCALL
-#  endif"""
+#  endif""")
         return
 
 
@@ -225,11 +225,11 @@ class gl_print_base(object):
         """
 
         self.undef_list.append(S)
-        print """#  if (defined(__GNUC__) && !defined(__CYGWIN__) && !defined(__MINGW32__)) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590) && defined(__ELF__))
+        print("""#  if defined(__GNUC__) && !defined(__CYGWIN__) && !defined(__MINGW32__)
 #    define %s  __attribute__((visibility("%s")))
 #  else
 #    define %s
-#  endif""" % (S, s, S)
+#  endif""" % (S, s, S))
         return
 
 
@@ -245,17 +245,17 @@ class gl_print_base(object):
         """
 
         self.undef_list.append("NOINLINE")
-        print """#  if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
+        print("""#  if defined(__GNUC__)
 #    define NOINLINE __attribute__((noinline))
 #  else
 #    define NOINLINE
-#  endif"""
+#  endif""")
         return
 
 
 def real_function_name(element):
-    name = element.nsProp( "name", None )
-    alias = element.nsProp( "alias", None )
+    name = element.get( "name" )
+    alias = element.get( "alias" )
 
     if alias:
         return alias
@@ -284,7 +284,7 @@ def classify_category(name, number):
 
     try:
         core_version = float(name)
-    except Exception,e:
+    except Exception:
         core_version = 0.0
 
     if core_version > 0.0:
@@ -320,25 +320,26 @@ def create_parameter_string(parameters, include_names):
 
     if len(list) == 0: list = ["void"]
 
-    return string.join(list, ", ")
+    return ", ".join(list)
 
 
 class gl_item(object):
-    def __init__(self, element, context):
+    def __init__(self, element, context, category):
         self.context = context
-        self.name = element.nsProp( "name", None )
-        self.category = real_category_name( element.parent.nsProp( "name", None ) )
+        self.name = element.get( "name" )
+        self.category = real_category_name( category )
+
         return
 
 
 class gl_type( gl_item ):
-    def __init__(self, element, context):
-        gl_item.__init__(self, element, context)
-        self.size = int( element.nsProp( "size", None ), 0 )
+    def __init__(self, element, context, category):
+        gl_item.__init__(self, element, context, category)
+        self.size = int( element.get( "size" ), 0 )
 
         te = typeexpr.type_expression( None )
         tn = typeexpr.type_node()
-        tn.size = int( element.nsProp( "size", None ), 0 )
+        tn.size = int( element.get( "size" ), 0 )
         tn.integer = not is_attr_true( element, "float" )
         tn.unsigned = is_attr_true( element, "unsigned" )
         tn.pointer = is_attr_true( element, "pointer" )
@@ -354,17 +355,17 @@ class gl_type( gl_item ):
 
 
 class gl_enum( gl_item ):
-    def __init__(self, element, context):
-        gl_item.__init__(self, element, context)
-        self.value = int( element.nsProp( "value", None ), 0 )
+    def __init__(self, element, context, category):
+        gl_item.__init__(self, element, context, category)
+        self.value = int( element.get( "value" ), 0 )
 
-        temp = element.nsProp( "count", None )
+        temp = element.get( "count" )
         if not temp or temp == "?":
             self.default_count = -1
         else:
             try:
                 c = int(temp)
-            except Exception,e:
+            except Exception:
                 raise RuntimeError('Invalid count value "%s" for enum "%s" in function "%s" when an integer was expected.' % (temp, self.name, n))
 
             self.default_count = c
@@ -404,12 +405,12 @@ class gl_enum( gl_item ):
 
 class gl_parameter(object):
     def __init__(self, element, context):
-        self.name = element.nsProp( "name", None )
+        self.name = element.get( "name" )
 
-        ts = element.nsProp( "type", None )
+        ts = element.get( "type" )
         self.type_expr = typeexpr.type_expression( ts, context )
 
-        temp = element.nsProp( "variable_param", None )
+        temp = element.get( "variable_param" )
         if temp:
             self.count_parameter_list = temp.split( ' ' )
         else:
@@ -420,17 +421,17 @@ class gl_parameter(object):
         # statement will throw an exception, and the except block will
         # take over.
 
-        c = element.nsProp( "count", None )
+        c = element.get( "count" )
         try: 
             count = int(c)
             self.count = count
             self.counter = None
-        except Exception,e:
+        except Exception:
             count = 1
             self.count = 0
             self.counter = c
 
-        self.count_scale = int(element.nsProp( "count_scale", None ))
+        self.count_scale = int(element.get( "count_scale", "1" ))
 
         elements = (count * self.count_scale)
         if elements == 1:
@@ -450,19 +451,19 @@ class gl_parameter(object):
 
         # Pixel data has special parameters.
 
-        self.width      = element.nsProp('img_width',  None)
-        self.height     = element.nsProp('img_height', None)
-        self.depth      = element.nsProp('img_depth',  None)
-        self.extent     = element.nsProp('img_extent', None)
+        self.width      = element.get('img_width')
+        self.height     = element.get('img_height')
+        self.depth      = element.get('img_depth')
+        self.extent     = element.get('img_extent')
 
-        self.img_xoff   = element.nsProp('img_xoff',   None)
-        self.img_yoff   = element.nsProp('img_yoff',   None)
-        self.img_zoff   = element.nsProp('img_zoff',   None)
-        self.img_woff   = element.nsProp('img_woff',   None)
+        self.img_xoff   = element.get('img_xoff')
+        self.img_yoff   = element.get('img_yoff')
+        self.img_zoff   = element.get('img_zoff')
+        self.img_woff   = element.get('img_woff')
 
-        self.img_format = element.nsProp('img_format', None)
-        self.img_type   = element.nsProp('img_type',   None)
-        self.img_target = element.nsProp('img_target', None)
+        self.img_format = element.get('img_format')
+        self.img_type   = element.get('img_type')
+        self.img_target = element.get('img_target')
 
         self.img_pad_dimensions = is_attr_true( element, 'img_pad_dimensions' )
         self.img_null_flag      = is_attr_true( element, 'img_null_flag' )
@@ -564,7 +565,14 @@ class gl_parameter(object):
 
 
     def size_string(self, use_parens = 1):
-        s = self.size()
+        base_size_str = ""
+
+        count = self.get_element_count()
+        if count:
+            base_size_str = "%d * " % count
+
+        base_size_str += "sizeof(%s)" % ( self.get_base_type_string() )
+
         if self.counter or self.count_parameter_list:
             list = [ "compsize" ]
 
@@ -573,18 +581,18 @@ class gl_parameter(object):
             elif self.counter:
                 list = [ self.counter ]
 
-            if s > 1:
-                list.append( str(s) )
+            if self.size() > 1:
+                list.append( base_size_str )
 
             if len(list) > 1 and use_parens :
-                return "(%s)" % (string.join(list, " * "))
+                return "safe_mul(%s)" % ", ".join(list)
             else:
-                return string.join(list, " * ")
+                return " * ".join(list)
 
         elif self.is_image():
             return "compsize"
         else:
-            return str(s)
+            return base_size_str
 
 
     def format_string(self):
@@ -608,26 +616,17 @@ class gl_function( gl_item ):
         self.exec_flavor = 'mesa'
         self.desktop = True
         self.deprecated = None
-
-        # self.entry_point_api_map[name][api] is a decimal value
-        # indicating the earliest version of the given API in which
-        # each entry point exists.  Every entry point is included in
-        # the first level of the map; the second level of the map only
-        # lists APIs which contain the entry point in at least one
-        # version.  For example,
-        # self.entry_point_api_map['ClipPlanex'] == { 'es1':
-        # Decimal('1.1') }.
-        self.entry_point_api_map = {}
+        self.has_no_error_variant = False
 
         # self.api_map[api] is a decimal value indicating the earliest
         # version of the given API in which ANY alias for the function
         # exists.  The map only lists APIs which contain the function
         # in at least one version.  For example, for the ClipPlanex
-        # function, self.entry_point_api_map == { 'es1':
+        # function, self.api_map == { 'es1':
         # Decimal('1.1') }.
         self.api_map = {}
 
-        self.assign_offset = 0
+        self.assign_offset = False
 
         self.static_entry_points = []
 
@@ -648,36 +647,39 @@ class gl_function( gl_item ):
 
 
     def process_element(self, element):
-        name = element.nsProp( "name", None )
-        alias = element.nsProp( "alias", None )
+        name = element.get( "name" )
+        alias = element.get( "alias" )
 
-        if is_attr_true(element, "static_dispatch"):
+        if name in static_data.functions:
             self.static_entry_points.append(name)
 
         self.entry_points.append( name )
 
-        self.entry_point_api_map[name] = {}
         for api in ('es1', 'es2'):
-            version_str = element.nsProp(api, None)
+            version_str = element.get(api, 'none')
             assert version_str is not None
             if version_str != 'none':
                 version_decimal = Decimal(version_str)
-                self.entry_point_api_map[name][api] = version_decimal
                 if api not in self.api_map or \
                         version_decimal < self.api_map[api]:
                     self.api_map[api] = version_decimal
 
-        exec_flavor = element.nsProp('exec', None)
+        exec_flavor = element.get('exec')
         if exec_flavor:
             self.exec_flavor = exec_flavor
 
-        deprecated = element.nsProp('deprecated', None)
+        deprecated = element.get('deprecated', 'none')
         if deprecated != 'none':
             self.deprecated = Decimal(deprecated)
 
-        if not is_attr_true(element, 'desktop'):
+        if not is_attr_true(element, 'desktop', 'true'):
             self.desktop = False
 
+        if self.has_no_error_variant or is_attr_true(element, 'no_error'):
+            self.has_no_error_variant = True
+        else:
+            self.has_no_error_variant = False
+
         if alias:
             true_name = alias
         else:
@@ -686,16 +688,15 @@ class gl_function( gl_item ):
             # Only try to set the offset when a non-alias entry-point
             # is being processed.
 
-            offset = element.nsProp( "offset", None )
-            if offset:
-                try:
-                    o = int( offset )
-                    self.offset = o
-                except Exception, e:
-                    self.offset = -1
-                    if offset == "assign":
-                        self.assign_offset = 1
-
+            if name in static_data.offsets and static_data.offsets[name] <= static_data.MAX_OFFSETS:
+                self.offset = static_data.offsets[name]
+            elif name in static_data.offsets and static_data.offsets[name] > static_data.MAX_OFFSETS:
+                self.offset = static_data.offsets[name]
+                self.assign_offset = True
+            else:
+                if self.exec_flavor != "skip":
+                    raise RuntimeError("Entry-point %s is missing offset in static_data.py. Add one at the bottom of the list." % (name))
+                self.assign_offset = self.exec_flavor != "skip" or name in static_data.unused_functions
 
         if not self.name:
             self.name = true_name
@@ -712,16 +713,12 @@ class gl_function( gl_item ):
 
         parameters = []
         return_type = "void"
-        child = element.children
-        while child:
-            if child.type == "element":
-                if child.name == "return":
-                    return_type = child.nsProp( "type", None )
-                elif child.name == "param":
-                    param = self.context.factory.create_item( "parameter", child, self.context)
-                    parameters.append( param )
-
-            child = child.next
+        for child in element.getchildren():
+            if child.tag == "return":
+                return_type = child.get( "type", "void" )
+            elif child.tag == "param":
+                param = self.context.factory.create_parameter(child, self.context)
+                parameters.append( param )
 
 
         if self.initialized:
@@ -746,7 +743,7 @@ class gl_function( gl_item ):
                 if param.is_image():
                     self.images.append( param )
 
-        if element.children:
+        if element.getchildren():
             self.initialized = 1
             self.entry_point_parameters[name] = parameters
         else:
@@ -784,9 +781,9 @@ class gl_function( gl_item ):
 
     def parameterIterator(self, name = None):
         if name is not None:
-            return self.entry_point_parameters[name].__iter__();
+            return iter(self.entry_point_parameters[name]);
         else:
-            return self.parameters.__iter__();
+            return iter(self.parameters);
 
 
     def get_parameter_string(self, entrypoint = None):
@@ -828,44 +825,28 @@ class gl_function( gl_item ):
         else:
             return "_dispatch_stub_%u" % (self.offset)
 
-    def entry_points_for_api_version(self, api, version = None):
-        """Return a list of the entry point names for this function
-        which are supported in the given API (and optionally, version).
+class gl_item_factory(object):
+    """Factory to create objects derived from gl_item."""
 
-        Use the decimal.Decimal type to precisely express non-integer
-        versions.
-        """
-        result = []
-        for entry_point, api_to_ver in self.entry_point_api_map.iteritems():
-            if api not in api_to_ver:
-                continue
-            if version is not None and version < api_to_ver[api]:
-                continue
-            result.append(entry_point)
-        return result
+    def create_function(self, element, context):
+        return gl_function(element, context)
 
+    def create_type(self, element, context, category):
+        return gl_type(element, context, category)
 
-class gl_item_factory(object):
-    """Factory to create objects derived from gl_item."""
+    def create_enum(self, element, context, category):
+        return gl_enum(element, context, category)
 
-    def create_item(self, item_name, element, context):
-        if item_name == "function":
-            return gl_function(element, context)
-        if item_name == "type":
-            return gl_type(element, context)
-        elif item_name == "enum":
-            return gl_enum(element, context)
-        elif item_name == "parameter":
-            return gl_parameter(element, context)
-        elif item_name == "api":
-            return gl_api(self)
-        else:
-            return None
+    def create_parameter(self, element, context):
+        return gl_parameter(element, context)
+
+    def create_api(self):
+        return gl_api(self)
 
 
 class gl_api(object):
     def __init__(self, factory):
-        self.functions_by_name = {}
+        self.functions_by_name = OrderedDict()
         self.enums_by_name = {}
         self.types_by_name = {}
 
@@ -879,90 +860,63 @@ class gl_api(object):
         typeexpr.create_initial_types()
         return
 
-    def filter_functions(self, entry_point_list):
-        """Filter out entry points not in entry_point_list."""
-        functions_by_name = {}
-        for func in self.functions_by_name.itervalues():
-            entry_points = [ent for ent in func.entry_points if ent in entry_point_list]
-            if entry_points:
-                func.filter_entry_points(entry_points)
-                functions_by_name[func.name] = func
-
-        self.functions_by_name = functions_by_name
-
-    def filter_functions_by_api(self, api, version = None):
-        """Filter out entry points not in the given API (or
-        optionally, not in the given version of the given API).
-        """
-        functions_by_name = {}
-        for func in self.functions_by_name.itervalues():
-            entry_points = func.entry_points_for_api_version(api, version)
-            if entry_points:
-                func.filter_entry_points(entry_points)
-                functions_by_name[func.name] = func
-
-        self.functions_by_name = functions_by_name
-
-    def process_element(self, doc):
-        element = doc.children
-        while element.type != "element" or element.name != "OpenGLAPI":
-            element = element.next
-
-        if element:
-            self.process_OpenGLAPI(element)
-        return
+    def parse_file(self, file_name):
+        doc = ET.parse( file_name )
+        self.process_element(file_name, doc)
 
 
-    def process_OpenGLAPI(self, element):
-        child = element.children
-        while child:
-            if child.type == "element":
-                if child.name == "category":
-                    self.process_category( child )
-                elif child.name == "OpenGLAPI":
-                    self.process_OpenGLAPI( child )
+    def process_element(self, file_name, doc):
+        element = doc.getroot()
+        if element.tag == "OpenGLAPI":
+            self.process_OpenGLAPI(file_name, element)
+        return
+
 
-            child = child.next
+    def process_OpenGLAPI(self, file_name, element):
+        for child in element.getchildren():
+            if child.tag == "category":
+                self.process_category( child )
+            elif child.tag == "OpenGLAPI":
+                self.process_OpenGLAPI( file_name, child )
+            elif child.tag == '{http://www.w3.org/2001/XInclude}include':
+                href = child.get('href')
+                href = os.path.join(os.path.dirname(file_name), href)
+                self.parse_file(href)
 
         return
 
 
     def process_category(self, cat):
-        cat_name = cat.nsProp( "name", None )
-        cat_number = cat.nsProp( "number", None )
+        cat_name = cat.get( "name" )
+        cat_number = cat.get( "number" )
 
         [cat_type, key] = classify_category(cat_name, cat_number)
         self.categories[cat_type][key] = [cat_name, cat_number]
 
-        child = cat.children
-        while child:
-            if child.type == "element":
-                if child.name == "function":
-                    func_name = real_function_name( child )
-
-                    temp_name = child.nsProp( "name", None )
-                    self.category_dict[ temp_name ] = [cat_name, cat_number]
-
-                    if self.functions_by_name.has_key( func_name ):
-                        func = self.functions_by_name[ func_name ]
-                        func.process_element( child )
-                    else:
-                        func = self.factory.create_item( "function", child, self )
-                        self.functions_by_name[ func_name ] = func
+        for child in cat.getchildren():
+            if child.tag == "function":
+                func_name = real_function_name( child )
 
-                    if func.offset >= self.next_offset:
-                        self.next_offset = func.offset + 1
+                temp_name = child.get( "name" )
+                self.category_dict[ temp_name ] = [cat_name, cat_number]
 
+                if func_name in self.functions_by_name:
+                    func = self.functions_by_name[ func_name ]
+                    func.process_element( child )
+                else:
+                    func = self.factory.create_function( child, self )
+                    self.functions_by_name[ func_name ] = func
 
-                elif child.name == "enum":
-                    enum = self.factory.create_item( "enum", child, self )
-                    self.enums_by_name[ enum.name ] = enum
-                elif child.name == "type":
-                    t = self.factory.create_item( "type", child, self )
-                    self.types_by_name[ "GL" + t.name ] = t
+                if func.offset >= self.next_offset:
+                    self.next_offset = func.offset + 1
 
 
-            child = child.next
+            elif child.tag == "enum":
+                enum = self.factory.create_enum( child, self, cat_name )
+                self.enums_by_name[ enum.name ] = enum
+            elif child.tag == "type":
+                t = self.factory.create_type( child, self, cat_name )
+                self.types_by_name[ "GL" + t.name ] = t
 
         return
 
@@ -983,7 +937,7 @@ class gl_api(object):
             if (cat == None) or (cat == cat_name):
                 [func_cat_type, key] = classify_category(cat_name, cat_number)
 
-                if not lists[func_cat_type].has_key(key):
+                if key not in lists[func_cat_type]:
                     lists[func_cat_type][key] = {}
 
                 lists[func_cat_type][key][func.name] = func
@@ -991,28 +945,26 @@ class gl_api(object):
 
         functions = []
         for func_cat_type in range(0,4):
-            keys = lists[func_cat_type].keys()
-            keys.sort()
+            keys = sorted(lists[func_cat_type].keys())
 
             for key in keys:
-                names = lists[func_cat_type][key].keys()
-                names.sort()
+                names = sorted(lists[func_cat_type][key].keys())
 
                 for name in names:
                     functions.append(lists[func_cat_type][key][name])
 
-        return functions.__iter__()
+        return iter(functions)
 
 
     def functionIterateByOffset(self):
         max_offset = -1
-        for func in self.functions_by_name.itervalues():
+        for func in self.functions_by_name.values():
             if func.offset > max_offset:
                 max_offset = func.offset
 
 
         temp = [None for i in range(0, max_offset + 1)]
-        for func in self.functions_by_name.itervalues():
+        for func in self.functions_by_name.values():
             if func.offset != -1:
                 temp[ func.offset ] = func
 
@@ -1022,22 +974,21 @@ class gl_api(object):
             if temp[i]:
                 list.append(temp[i])
 
-        return list.__iter__();
+        return iter(list);
 
 
     def functionIterateAll(self):
-        return self.functions_by_name.itervalues()
+        return self.functions_by_name.values()
 
 
     def enumIterateByName(self):
-        keys = self.enums_by_name.keys()
-        keys.sort()
+        keys = sorted(self.enums_by_name.keys())
 
         list = []
         for enum in keys:
             list.append( self.enums_by_name[ enum ] )
 
-        return list.__iter__()
+        return iter(list)
 
 
     def categoryIterate(self):
@@ -1050,29 +1001,28 @@ class gl_api(object):
 
         list = []
         for cat_type in range(0,4):
-            keys = self.categories[cat_type].keys()
-            keys.sort()
+            keys = sorted(self.categories[cat_type].keys())
 
             for key in keys:
                 list.append(self.categories[cat_type][key])
 
-        return list.__iter__()
+        return iter(list)
 
 
     def get_category_for_name( self, name ):
-        if self.category_dict.has_key(name):
+        if name in self.category_dict:
             return self.category_dict[name]
         else:
             return ["<unknown category>", None]
 
 
     def typeIterate(self):
-        return self.types_by_name.itervalues()
+        return self.types_by_name.values()
 
 
     def find_type( self, type_name ):
         if type_name in self.types_by_name:
             return self.types_by_name[ type_name ].type_expr
         else:
-            print "Unable to find base type matching \"%s\"." % (type_name)
+            print("Unable to find base type matching \"%s\"." % (type_name))
             return None