]> git.cworth.org Git - apitrace/blobdiff - specs/stdapi.py
Handle variations of LockRect.
[apitrace] / specs / stdapi.py
index 1b9bf58ad5f5ab0f4b6cb57f5f6f275048e3f628..57e9aa6eb1fcacda7aa77e976b6f1c06dbb9334c 100644 (file)
@@ -30,54 +30,76 @@ import debug
 
 
 class Type:
+    """Base class for all types."""
 
-    __all = {}
-    __seq = 0
+    __tags = set()
 
-    def __init__(self, expr, id = ''):
+    def __init__(self, expr, tag = None):
         self.expr = expr
-        
-        for char in id:
-            assert char.isalnum() or char in '_ '
 
-        id = id.replace(' ', '_')
-        
-        if id in Type.__all:
-            Type.__seq += 1
-            id += str(Type.__seq)
-        
-        assert id not in Type.__all
-        Type.__all[id] = self
+        # Generate a default tag, used when naming functions that will operate
+        # on this type, so it should preferrably be something representative of
+        # the type.
+        if tag is None:
+            if expr is not None:
+                tag = ''.join([c for c in expr if c.isalnum() or c in '_'])
+            else:
+                tag = 'anonynoums'
+        else:
+            for c in tag:
+                assert c.isalnum() or c in '_'
+
+        # Ensure it is unique.
+        if tag in Type.__tags:
+            suffix = 1
+            while tag + str(suffix) in Type.__tags:
+                suffix += 1
+            tag += str(suffix)
+
+        assert tag not in Type.__tags
+        Type.__tags.add(tag)
 
-        self.id = id
+        self.tag = tag
 
     def __str__(self):
+        """Return the C/C++ type expression for this type."""
         return self.expr
 
     def visit(self, visitor, *args, **kwargs):
         raise NotImplementedError
 
+    def mutable(self):
+        '''Return a mutable version of this type.
+
+        Convenience wrapper around MutableRebuilder.'''
+        visitor = MutableRebuilder()
+        return visitor.visit(self)
 
 
 class _Void(Type):
+    """Singleton void type."""
 
     def __init__(self):
         Type.__init__(self, "void")
 
     def visit(self, visitor, *args, **kwargs):
-        return visitor.visit_void(self, *args, **kwargs)
+        return visitor.visitVoid(self, *args, **kwargs)
 
 Void = _Void()
 
 
 class Literal(Type):
+    """Class to describe literal types.
+
+    Types which are not defined in terms of other types, such as integers and
+    floats."""
 
-    def __init__(self, expr, format, base=10):
+    def __init__(self, expr, kind):
         Type.__init__(self, expr)
-        self.format = format
+        self.kind = kind
 
     def visit(self, visitor, *args, **kwargs):
-        return visitor.visit_literal(self, *args, **kwargs)
+        return visitor.visitLiteral(self, *args, **kwargs)
 
 
 class Const(Type):
@@ -96,35 +118,76 @@ class Const(Type):
             # The most legible
             expr = "const " + type.expr
 
-        Type.__init__(self, expr, 'C' + type.id)
+        Type.__init__(self, expr, 'C' + type.tag)
 
         self.type = type
 
     def visit(self, visitor, *args, **kwargs):
-        return visitor.visit_const(self, *args, **kwargs)
+        return visitor.visitConst(self, *args, **kwargs)
 
 
 class Pointer(Type):
 
     def __init__(self, type):
-        Type.__init__(self, type.expr + " *", 'P' + type.id)
+        Type.__init__(self, type.expr + " *", 'P' + type.tag)
+        self.type = type
+
+    def visit(self, visitor, *args, **kwargs):
+        return visitor.visitPointer(self, *args, **kwargs)
+
+
+class IntPointer(Type):
+    '''Integer encoded as a pointer.'''
+
+    def visit(self, visitor, *args, **kwargs):
+        return visitor.visitIntPointer(self, *args, **kwargs)
+
+
+class ObjPointer(Type):
+    '''Pointer to an object.'''
+
+    def __init__(self, type):
+        Type.__init__(self, type.expr + " *", 'P' + type.tag)
+        self.type = type
+
+    def visit(self, visitor, *args, **kwargs):
+        return visitor.visitObjPointer(self, *args, **kwargs)
+
+
+class LinearPointer(Type):
+    '''Pointer to a linear range of memory.'''
+
+    def __init__(self, type, size = None):
+        Type.__init__(self, type.expr + " *", 'P' + type.tag)
+        self.type = type
+        self.size = size
+
+    def visit(self, visitor, *args, **kwargs):
+        return visitor.visitLinearPointer(self, *args, **kwargs)
+
+
+class Reference(Type):
+    '''C++ references.'''
+
+    def __init__(self, type):
+        Type.__init__(self, type.expr + " &", 'R' + type.tag)
         self.type = type
 
     def visit(self, visitor, *args, **kwargs):
-        return visitor.visit_pointer(self, *args, **kwargs)
+        return visitor.visitReference(self, *args, **kwargs)
 
 
 class Handle(Type):
 
     def __init__(self, name, type, range=None, key=None):
-        Type.__init__(self, type.expr, 'P' + type.id)
+        Type.__init__(self, type.expr, 'P' + type.tag)
         self.name = name
         self.type = type
         self.range = range
         self.key = key
 
     def visit(self, visitor, *args, **kwargs):
-        return visitor.visit_handle(self, *args, **kwargs)
+        return visitor.visitHandle(self, *args, **kwargs)
 
 
 def ConstPointer(type):
@@ -133,12 +196,18 @@ def ConstPointer(type):
 
 class Enum(Type):
 
+    __id = 0
+
     def __init__(self, name, values):
         Type.__init__(self, name)
+
+        self.id = Enum.__id
+        Enum.__id += 1
+
         self.values = list(values)
-    
+
     def visit(self, visitor, *args, **kwargs):
-        return visitor.visit_enum(self, *args, **kwargs)
+        return visitor.visitEnum(self, *args, **kwargs)
 
 
 def FakeEnum(type, values):
@@ -147,13 +216,19 @@ def FakeEnum(type, values):
 
 class Bitmask(Type):
 
+    __id = 0
+
     def __init__(self, type, values):
         Type.__init__(self, type.expr)
+
+        self.id = Bitmask.__id
+        Bitmask.__id += 1
+
         self.type = type
         self.values = values
 
     def visit(self, visitor, *args, **kwargs):
-        return visitor.visit_bitmask(self, *args, **kwargs)
+        return visitor.visitBitmask(self, *args, **kwargs)
 
 Flags = Bitmask
 
@@ -166,7 +241,7 @@ class Array(Type):
         self.length = length
 
     def visit(self, visitor, *args, **kwargs):
-        return visitor.visit_array(self, *args, **kwargs)
+        return visitor.visitArray(self, *args, **kwargs)
 
 
 class Blob(Type):
@@ -177,18 +252,47 @@ class Blob(Type):
         self.size = size
 
     def visit(self, visitor, *args, **kwargs):
-        return visitor.visit_blob(self, *args, **kwargs)
+        return visitor.visitBlob(self, *args, **kwargs)
 
 
 class Struct(Type):
 
+    __id = 0
+
     def __init__(self, name, members):
         Type.__init__(self, name)
+
+        self.id = Struct.__id
+        Struct.__id += 1
+
         self.name = name
-        self.members = members
+        self.members = []
+
+        # Eliminate anonymous unions
+        for type, name in members:
+            if name is not None:
+                self.members.append((type, name))
+            else:
+                assert isinstance(type, Union)
+                assert type.name is None
+                self.members.extend(type.members)
 
     def visit(self, visitor, *args, **kwargs):
-        return visitor.visit_struct(self, *args, **kwargs)
+        return visitor.visitStruct(self, *args, **kwargs)
+
+
+class Union(Type):
+
+    __id = 0
+
+    def __init__(self, name, members):
+        Type.__init__(self, name)
+
+        self.id = Union.__id
+        Union.__id += 1
+
+        self.name = name
+        self.members = members
 
 
 class Alias(Type):
@@ -198,19 +302,14 @@ class Alias(Type):
         self.type = type
 
     def visit(self, visitor, *args, **kwargs):
-        return visitor.visit_alias(self, *args, **kwargs)
-
-
-def Out(type, name):
-    arg = Arg(type, name, output=True)
-    return arg
-
+        return visitor.visitAlias(self, *args, **kwargs)
 
 class Arg:
 
-    def __init__(self, type, name, output=False):
+    def __init__(self, type, name, input=True, output=False):
         self.type = type
         self.name = name
+        self.input = input
         self.output = output
         self.index = None
 
@@ -218,9 +317,20 @@ class Arg:
         return '%s %s' % (self.type, self.name)
 
 
+def In(type, name):
+    return Arg(type, name, input=True, output=False)
+
+def Out(type, name):
+    return Arg(type, name, input=False, output=True)
+
+def InOut(type, name):
+    return Arg(type, name, input=True, output=True)
+
+
 class Function:
 
-    __id = 0
+    # 0-3 are reserved to memcpy, malloc, free, and realloc
+    __id = 4
 
     def __init__(self, type, name, args, call = '', fail = None, sideeffects=True):
         self.id = Function.__id
@@ -266,6 +376,9 @@ class Function:
         s += ")"
         return s
 
+    def argNames(self):
+        return [arg.name for arg in self.args]
+
 
 def StdFunction(*args, **kwargs):
     kwargs.setdefault('call', '__stdcall')
@@ -286,36 +399,67 @@ class Interface(Type):
         self.methods = []
 
     def visit(self, visitor, *args, **kwargs):
-        return visitor.visit_interface(self, *args, **kwargs)
+        return visitor.visitInterface(self, *args, **kwargs)
+
+    def getMethodByName(self, name):
+        for method in self.iterMethods():
+            if method.name == name:
+                return method
+        return None
 
-    def itermethods(self):
+    def iterMethods(self):
         if self.base is not None:
-            for method in self.base.itermethods():
+            for method in self.base.iterMethods():
                 yield method
         for method in self.methods:
             yield method
         raise StopIteration
 
+    def iterBases(self):
+        iface = self
+        while iface is not None:
+            yield iface
+            iface = iface.base
+        raise StopIteration
+
+    def iterBaseMethods(self):
+        if self.base is not None:
+            for iface, method in self.base.iterBaseMethods():
+                yield iface, method
+        for method in self.methods:
+            yield self, method
+        raise StopIteration
+
 
 class Method(Function):
 
-    def __init__(self, type, name, args):
-        Function.__init__(self, type, name, args, call = '__stdcall')
+    def __init__(self, type, name, args, call = '__stdcall', const=False, sideeffects=True):
+        Function.__init__(self, type, name, args, call = call, sideeffects=sideeffects)
         for index in range(len(self.args)):
             self.args[index].index = index + 1
+        self.const = const
+
+    def prototype(self, name=None):
+        s = Function.prototype(self, name)
+        if self.const:
+            s += ' const'
+        return s
+
+
+def StdMethod(*args, **kwargs):
+    kwargs.setdefault('call', '__stdcall')
+    return Method(*args, **kwargs)
 
 
 class String(Type):
 
-    def __init__(self, expr = "char *", length = None):
+    def __init__(self, expr = "char *", length = None, kind = 'String'):
         Type.__init__(self, expr)
         self.length = length
+        self.kind = kind
 
     def visit(self, visitor, *args, **kwargs):
-        return visitor.visit_string(self, *args, **kwargs)
-
-# C string (i.e., zero terminated)
-CString = String()
+        return visitor.visitString(self, *args, **kwargs)
 
 
 class Opaque(Type):
@@ -325,7 +469,7 @@ class Opaque(Type):
         Type.__init__(self, expr)
 
     def visit(self, visitor, *args, **kwargs):
-        return visitor.visit_opaque(self, *args, **kwargs)
+        return visitor.visitOpaque(self, *args, **kwargs)
 
 
 def OpaquePointer(type, *args):
@@ -340,69 +484,107 @@ def OpaqueBlob(type, size):
 
 class Polymorphic(Type):
 
-    def __init__(self, default_type, switch_expr, switch_types):
-        Type.__init__(self, default_type.expr)
-        self.default_type = default_type
-        self.switch_expr = switch_expr
-        self.switch_types = switch_types
+    def __init__(self, switchExpr, switchTypes, defaultType, contextLess=True):
+        Type.__init__(self, defaultType.expr)
+        self.switchExpr = switchExpr
+        self.switchTypes = switchTypes
+        self.defaultType = defaultType
+        self.contextLess = contextLess
 
     def visit(self, visitor, *args, **kwargs):
-        return visitor.visit_polymorphic(self, *args, **kwargs)
+        return visitor.visitPolymorphic(self, *args, **kwargs)
+
+    def iterSwitch(self):
+        cases = [['default']]
+        types = [self.defaultType]
+
+        for expr, type in self.switchTypes:
+            case = 'case %s' % expr
+            try:
+                i = types.index(type)
+            except ValueError:
+                cases.append([case])
+                types.append(type)
+            else:
+                cases[i].append(case)
+
+        return zip(cases, types)
+
+
+def EnumPolymorphic(enumName, switchExpr, switchTypes, defaultType, contextLess=True):
+    enumValues = [expr for expr, type in switchTypes]
+    enum = Enum(enumName, enumValues)
+    polymorphic = Polymorphic(switchExpr, switchTypes, defaultType, contextLess)
+    return enum, polymorphic
 
 
 class Visitor:
+    '''Abstract visitor for the type hierarchy.'''
 
     def visit(self, type, *args, **kwargs):
         return type.visit(self, *args, **kwargs)
 
-    def visit_void(self, void, *args, **kwargs):
+    def visitVoid(self, void, *args, **kwargs):
         raise NotImplementedError
 
-    def visit_literal(self, literal, *args, **kwargs):
+    def visitLiteral(self, literal, *args, **kwargs):
         raise NotImplementedError
 
-    def visit_string(self, string, *args, **kwargs):
+    def visitString(self, string, *args, **kwargs):
         raise NotImplementedError
 
-    def visit_const(self, const, *args, **kwargs):
+    def visitConst(self, const, *args, **kwargs):
         raise NotImplementedError
 
-    def visit_struct(self, struct, *args, **kwargs):
+    def visitStruct(self, struct, *args, **kwargs):
         raise NotImplementedError
 
-    def visit_array(self, array, *args, **kwargs):
+    def visitArray(self, array, *args, **kwargs):
         raise NotImplementedError
 
-    def visit_blob(self, blob, *args, **kwargs):
+    def visitBlob(self, blob, *args, **kwargs):
         raise NotImplementedError
 
-    def visit_enum(self, enum, *args, **kwargs):
+    def visitEnum(self, enum, *args, **kwargs):
         raise NotImplementedError
 
-    def visit_bitmask(self, bitmask, *args, **kwargs):
+    def visitBitmask(self, bitmask, *args, **kwargs):
         raise NotImplementedError
 
-    def visit_pointer(self, pointer, *args, **kwargs):
+    def visitPointer(self, pointer, *args, **kwargs):
         raise NotImplementedError
 
-    def visit_handle(self, handle, *args, **kwargs):
+    def visitIntPointer(self, pointer, *args, **kwargs):
         raise NotImplementedError
 
-    def visit_alias(self, alias, *args, **kwargs):
+    def visitObjPointer(self, pointer, *args, **kwargs):
         raise NotImplementedError
 
-    def visit_opaque(self, opaque, *args, **kwargs):
+    def visitLinearPointer(self, pointer, *args, **kwargs):
         raise NotImplementedError
 
-    def visit_interface(self, interface, *args, **kwargs):
+    def visitReference(self, reference, *args, **kwargs):
         raise NotImplementedError
 
-    def visit_polymorphic(self, polymorphic, *args, **kwargs):
+    def visitHandle(self, handle, *args, **kwargs):
         raise NotImplementedError
-        #return self.visit(polymorphic.default_type, *args, **kwargs)
+
+    def visitAlias(self, alias, *args, **kwargs):
+        raise NotImplementedError
+
+    def visitOpaque(self, opaque, *args, **kwargs):
+        raise NotImplementedError
+
+    def visitInterface(self, interface, *args, **kwargs):
+        raise NotImplementedError
+
+    def visitPolymorphic(self, polymorphic, *args, **kwargs):
+        raise NotImplementedError
+        #return self.visit(polymorphic.defaultType, *args, **kwargs)
 
 
 class OnceVisitor(Visitor):
+    '''Visitor that guarantees that each type is visited only once.'''
 
     def __init__(self):
         self.__visited = set()
@@ -415,129 +597,213 @@ class OnceVisitor(Visitor):
 
 
 class Rebuilder(Visitor):
+    '''Visitor which rebuild types as it visits them.
 
-    def visit_void(self, void):
+    By itself it is a no-op -- it is intended to be overwritten.
+    '''
+
+    def visitVoid(self, void):
         return void
 
-    def visit_literal(self, literal):
+    def visitLiteral(self, literal):
         return literal
 
-    def visit_string(self, string):
+    def visitString(self, string):
         return string
 
-    def visit_const(self, const):
-        return Const(const.type)
+    def visitConst(self, const):
+        const_type = self.visit(const.type)
+        if const_type is const.type:
+            return const
+        else:
+            return Const(const_type)
 
-    def visit_struct(self, struct):
+    def visitStruct(self, struct):
         members = [(self.visit(type), name) for type, name in struct.members]
         return Struct(struct.name, members)
 
-    def visit_array(self, array):
+    def visitArray(self, array):
         type = self.visit(array.type)
         return Array(type, array.length)
 
-    def visit_blob(self, blob):
+    def visitBlob(self, blob):
         type = self.visit(blob.type)
         return Blob(type, blob.size)
 
-    def visit_enum(self, enum):
+    def visitEnum(self, enum):
         return enum
 
-    def visit_bitmask(self, bitmask):
+    def visitBitmask(self, bitmask):
         type = self.visit(bitmask.type)
         return Bitmask(type, bitmask.values)
 
-    def visit_pointer(self, pointer):
-        type = self.visit(pointer.type)
-        return Pointer(type)
+    def visitPointer(self, pointer):
+        pointer_type = self.visit(pointer.type)
+        if pointer_type is pointer.type:
+            return pointer
+        else:
+            return Pointer(pointer_type)
 
-    def visit_handle(self, handle):
-        type = self.visit(handle.type)
-        return Handle(handle.name, type, range=handle.range, key=handle.key)
+    def visitIntPointer(self, pointer):
+        return pointer
 
-    def visit_alias(self, alias):
-        type = self.visit(alias.type)
-        return Alias(alias.expr, type)
+    def visitObjPointer(self, pointer):
+        pointer_type = self.visit(pointer.type)
+        if pointer_type is pointer.type:
+            return pointer
+        else:
+            return ObjPointer(pointer_type)
+
+    def visitLinearPointer(self, pointer):
+        pointer_type = self.visit(pointer.type)
+        if pointer_type is pointer.type:
+            return pointer
+        else:
+            return LinearPointer(pointer_type)
+
+    def visitReference(self, reference):
+        reference_type = self.visit(reference.type)
+        if reference_type is reference.type:
+            return reference
+        else:
+            return Reference(reference_type)
+
+    def visitHandle(self, handle):
+        handle_type = self.visit(handle.type)
+        if handle_type is handle.type:
+            return handle
+        else:
+            return Handle(handle.name, handle_type, range=handle.range, key=handle.key)
 
-    def visit_opaque(self, opaque):
+    def visitAlias(self, alias):
+        alias_type = self.visit(alias.type)
+        if alias_type is alias.type:
+            return alias
+        else:
+            return Alias(alias.expr, alias_type)
+
+    def visitOpaque(self, opaque):
         return opaque
 
-    def visit_polymorphic(self, polymorphic):
-        default_type = self.visit(polymorphic.default_type)
-        switch_expr = polymorphic.switch_expr
-        switch_types = [(expr, self.visit(type)) for expr, type in polymorphic.switch_types]
-        return Polymorphic(default_type, switch_expr, switch_types)
+    def visitInterface(self, interface, *args, **kwargs):
+        return interface
 
+    def visitPolymorphic(self, polymorphic):
+        switchExpr = polymorphic.switchExpr
+        switchTypes = [(expr, self.visit(type)) for expr, type in polymorphic.switchTypes]
+        defaultType = self.visit(polymorphic.defaultType)
+        return Polymorphic(switchExpr, switchTypes, defaultType, polymorphic.contextLess)
 
-class Collector(Visitor):
-    '''Collect.'''
 
-    def __init__(self):
-        self.__visited = set()
-        self.types = []
+class MutableRebuilder(Rebuilder):
+    '''Type visitor which derives a mutable type.'''
 
-    def visit(self, type):
-        if type in self.__visited:
-            return
-        self.__visited.add(type)
-        Visitor.visit(self, type)
-        self.types.append(type)
+    def visitConst(self, const):
+        # Strip out const qualifier
+        return const.type
+
+    def visitAlias(self, alias):
+        # Tear the alias on type changes
+        type = self.visit(alias.type)
+        if type is alias.type:
+            return alias
+        return type
+
+    def visitReference(self, reference):
+        # Strip out references
+        return reference.type
 
-    def visit_void(self, literal):
+
+class Traverser(Visitor):
+    '''Visitor which all types.'''
+
+    def visitVoid(self, void, *args, **kwargs):
         pass
 
-    def visit_literal(self, literal):
+    def visitLiteral(self, literal, *args, **kwargs):
         pass
 
-    def visit_string(self, string):
+    def visitString(self, string, *args, **kwargs):
         pass
 
-    def visit_const(self, const):
-        self.visit(const.type)
+    def visitConst(self, const, *args, **kwargs):
+        self.visit(const.type, *args, **kwargs)
 
-    def visit_struct(self, struct):
+    def visitStruct(self, struct, *args, **kwargs):
         for type, name in struct.members:
-            self.visit(type)
+            self.visit(type, *args, **kwargs)
 
-    def visit_array(self, array):
-        self.visit(array.type)
+    def visitArray(self, array, *args, **kwargs):
+        self.visit(array.type, *args, **kwargs)
 
-    def visit_blob(self, array):
+    def visitBlob(self, array, *args, **kwargs):
         pass
 
-    def visit_enum(self, enum):
+    def visitEnum(self, enum, *args, **kwargs):
         pass
 
-    def visit_bitmask(self, bitmask):
-        self.visit(bitmask.type)
+    def visitBitmask(self, bitmask, *args, **kwargs):
+        self.visit(bitmask.type, *args, **kwargs)
+
+    def visitPointer(self, pointer, *args, **kwargs):
+        self.visit(pointer.type, *args, **kwargs)
+
+    def visitIntPointer(self, pointer, *args, **kwargs):
+        pass
 
-    def visit_pointer(self, pointer):
-        self.visit(pointer.type)
+    def visitObjPointer(self, pointer, *args, **kwargs):
+        self.visit(pointer.type, *args, **kwargs)
 
-    def visit_handle(self, handle):
-        self.visit(handle.type)
+    def visitLinearPointer(self, pointer, *args, **kwargs):
+        self.visit(pointer.type, *args, **kwargs)
 
-    def visit_alias(self, alias):
-        self.visit(alias.type)
+    def visitReference(self, reference, *args, **kwargs):
+        self.visit(reference.type, *args, **kwargs)
 
-    def visit_opaque(self, opaque):
+    def visitHandle(self, handle, *args, **kwargs):
+        self.visit(handle.type, *args, **kwargs)
+
+    def visitAlias(self, alias, *args, **kwargs):
+        self.visit(alias.type, *args, **kwargs)
+
+    def visitOpaque(self, opaque, *args, **kwargs):
         pass
 
-    def visit_interface(self, interface):
+    def visitInterface(self, interface, *args, **kwargs):
         if interface.base is not None:
-            self.visit(interface.base)
-        for method in interface.itermethods():
+            self.visit(interface.base, *args, **kwargs)
+        for method in interface.iterMethods():
             for arg in method.args:
-                self.visit(arg.type)
-            self.visit(method.type)
+                self.visit(arg.type, *args, **kwargs)
+            self.visit(method.type, *args, **kwargs)
+
+    def visitPolymorphic(self, polymorphic, *args, **kwargs):
+        self.visit(polymorphic.defaultType, *args, **kwargs)
+        for expr, type in polymorphic.switchTypes:
+            self.visit(type, *args, **kwargs)
+
+
+class Collector(Traverser):
+    '''Visitor which collects all unique types as it traverses them.'''
+
+    def __init__(self):
+        self.__visited = set()
+        self.types = []
+
+    def visit(self, type):
+        if type in self.__visited:
+            return
+        self.__visited.add(type)
+        Visitor.visit(self, type)
+        self.types.append(type)
 
-    def visit_polymorphic(self, polymorphic):
-        self.visit(polymorphic.default_type)
-        for expr, type in polymorphic.switch_types:
-            self.visit(type)
 
 
 class API:
+    '''API abstraction.
+
+    Essentially, a collection of types, functions, and interfaces.
+    '''
 
     def __init__(self, name = None):
         self.name = name
@@ -545,7 +811,7 @@ class API:
         self.functions = []
         self.interfaces = []
 
-    def all_types(self):
+    def getAllTypes(self):
         collector = Collector()
         for function in self.functions:
             for arg in function.args:
@@ -553,31 +819,39 @@ class API:
             collector.visit(function.type)
         for interface in self.interfaces:
             collector.visit(interface)
-            for method in interface.itermethods():
+            for method in interface.iterMethods():
                 for arg in method.args:
                     collector.visit(arg.type)
                 collector.visit(method.type)
         return collector.types
 
-    def add_function(self, function):
+    def getAllInterfaces(self):
+        types = self.getAllTypes()
+        interfaces = [type for type in types if isinstance(type, Interface)]
+        for interface in self.interfaces:
+            if interface not in interfaces:
+                interfaces.append(interface)
+        return interfaces
+
+    def addFunction(self, function):
         self.functions.append(function)
 
-    def add_functions(self, functions):
+    def addFunctions(self, functions):
         for function in functions:
-            self.add_function(function)
+            self.addFunction(function)
 
-    def add_interface(self, interface):
+    def addInterface(self, interface):
         self.interfaces.append(interface)
 
-    def add_interfaces(self, interfaces):
+    def addInterfaces(self, interfaces):
         self.interfaces.extend(interfaces)
 
-    def add_api(self, api):
+    def addApi(self, api):
         self.headers.extend(api.headers)
-        self.add_functions(api.functions)
-        self.add_interfaces(api.interfaces)
+        self.addFunctions(api.functions)
+        self.addInterfaces(api.interfaces)
 
-    def get_function_by_name(self, name):
+    def getFunctionByName(self, name):
         for function in self.functions:
             if function.name == name:
                 return function
@@ -598,7 +872,10 @@ ULongLong = Literal("unsigned long long", "UInt")
 Float = Literal("float", "Float")
 Double = Literal("double", "Double")
 SizeT = Literal("size_t", "UInt")
-WString = Literal("wchar_t *", "WString")
+
+# C string (i.e., zero terminated)
+CString = String()
+WString = String("wchar_t *", kind="WString")
 
 Int8 = Literal("int8_t", "SInt")
 UInt8 = Literal("uint8_t", "UInt")