]> git.cworth.org Git - apitrace/blobdiff - stdapi.py
tracerepack: Don't fail when temp file is in different filesystem.
[apitrace] / stdapi.py
index 8dca958b1edabc4c183fa856c9b515cb976b2850..8852345884a69ce26b081a755201d9aa12e050bc 100644 (file)
--- a/stdapi.py
+++ b/stdapi.py
@@ -1,6 +1,6 @@
 ##########################################################################
 #
-# Copyright 2008-2009 VMware, Inc.
+# Copyright 2008-2010 VMware, Inc.
 # All Rights Reserved.
 #
 # Permission is hereby granted, free of charge, to any person obtaining a copy
 import debug
 
 
-all_types = {}
-
-
-class Visitor:
-
-    def visit(self, type, *args, **kwargs):
-        return type.visit(self, *args, **kwargs)
-
-    def visit_void(self, void, *args, **kwargs):
-        raise NotImplementedError
-
-    def visit_literal(self, literal, *args, **kwargs):
-        raise NotImplementedError
-
-    def visit_string(self, string, *args, **kwargs):
-        raise NotImplementedError
-
-    def visit_const(self, const, *args, **kwargs):
-        raise NotImplementedError
-
-    def visit_struct(self, struct, *args, **kwargs):
-        raise NotImplementedError
-
-    def visit_array(self, array, *args, **kwargs):
-        raise NotImplementedError
-
-    def visit_blob(self, blob, *args, **kwargs):
-        raise NotImplementedError
-
-    def visit_enum(self, enum, *args, **kwargs):
-        raise NotImplementedError
-
-    def visit_bitmask(self, bitmask, *args, **kwargs):
-        raise NotImplementedError
-
-    def visit_pointer(self, pointer, *args, **kwargs):
-        raise NotImplementedError
-
-    def visit_handle(self, handle, *args, **kwargs):
-        raise NotImplementedError
-
-    def visit_alias(self, alias, *args, **kwargs):
-        raise NotImplementedError
-
-    def visit_opaque(self, opaque, *args, **kwargs):
-        raise NotImplementedError
-
-    def visit_interface(self, interface, *args, **kwargs):
-        raise NotImplementedError
-
-
-class OnceVisitor(Visitor):
-
-    def __init__(self):
-        self.__visited = set()
-
-    def visit(self, type, *args, **kwargs):
-        if type not in self.__visited:
-            self.__visited.add(type)
-            return type.visit(self, *args, **kwargs)
-        return None
-
-
-class Rebuilder(Visitor):
-
-    def visit_void(self, void):
-        return void
-
-    def visit_literal(self, literal):
-        return literal
-
-    def visit_string(self, string):
-        return string
-
-    def visit_const(self, const):
-        return Const(const.type)
-
-    def visit_struct(self, struct):
-        members = [self.visit(member) for member in struct.members]
-        return Struct(struct.name, members)
-
-    def visit_array(self, array):
-        type = self.visit(array.type)
-        return Array(type, array.length)
-
-    def visit_blob(self, blob):
-        type = self.visit(blob.type)
-        return Blob(type, blob.size)
-
-    def visit_enum(self, enum):
-        return enum
-
-    def visit_bitmask(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 visit_handle(self, handle):
-        type = self.visit(handle.type)
-        return Handle(handle.name, type, handle.range)
-
-    def visit_alias(self, alias):
-        type = self.visit(alias.type)
-        return Alias(alias.expr, type)
-
-    def visit_opaque(self, opaque):
-        return opaque
-
-
 class Type:
 
+    __all = {}
     __seq = 0
 
     def __init__(self, expr, id = ''):
@@ -153,12 +42,12 @@ class Type:
 
         id = id.replace(' ', '_')
         
-        if id in all_types:
+        if id in Type.__all:
             Type.__seq += 1
             id += str(Type.__seq)
         
-        assert id not in all_types
-        all_types[id] = self
+        assert id not in Type.__all
+        Type.__all[id] = self
 
         self.id = id
 
@@ -181,24 +70,6 @@ class _Void(Type):
 Void = _Void()
 
 
-class Concrete(Type):
-
-    def decl(self):
-        print 'static void Dump%s(const %s &value);' % (self.id, self.expr)
-    
-    def impl(self):
-        print 'static void Dump%s(const %s &value) {' % (self.id, self.expr)
-        self._dump("value");
-        print '}'
-        print
-    
-    def _dump(self, instance):
-        raise NotImplementedError
-    
-    def dump(self, instance):
-        print '    Dump%s(%s);' % (self.id, instance)
-    
-
 class Literal(Type):
 
     def __init__(self, expr, format, base=10):
@@ -238,11 +109,12 @@ class Pointer(Type):
 
 class Handle(Type):
 
-    def __init__(self, name, type, range=None):
+    def __init__(self, name, type, range=None, key=None):
         Type.__init__(self, type.expr, 'P' + type.id)
         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)
@@ -252,14 +124,10 @@ def ConstPointer(type):
     return Pointer(Const(type))
 
 
-class Enum(Concrete):
-
-    __vid = 0
+class Enum(Type):
 
     def __init__(self, name, values):
-        Concrete.__init__(self, name)
-        self.vid = Enum.__vid
-        Enum.__vid += len(values)
+        Type.__init__(self, name)
         self.values = list(values)
     
     def visit(self, visitor, *args, **kwargs):
@@ -270,10 +138,10 @@ def FakeEnum(type, values):
     return Enum(type.expr, values)
 
 
-class Bitmask(Concrete):
+class Bitmask(Type):
 
     def __init__(self, type, values):
-        Concrete.__init__(self, type.expr)
+        Type.__init__(self, type.expr)
         self.type = type
         self.values = values
 
@@ -305,10 +173,10 @@ class Blob(Type):
         return visitor.visit_blob(self, *args, **kwargs)
 
 
-class Struct(Concrete):
+class Struct(Type):
 
     def __init__(self, name, members):
-        Concrete.__init__(self, name)
+        Type.__init__(self, name)
         self.name = name
         self.members = members
 
@@ -347,7 +215,7 @@ class Function:
 
     __id = 0
 
-    def __init__(self, type, name, args, call = '', fail = None, sideeffects=True, hidden=False):
+    def __init__(self, type, name, args, call = '', fail = None, sideeffects=True):
         self.id = Function.__id
         Function.__id += 1
 
@@ -357,8 +225,12 @@ class Function:
         self.args = []
         index = 0
         for arg in args:
-            if isinstance(arg, tuple):
-                arg_type, arg_name = arg
+            if not isinstance(arg, Arg):
+                if isinstance(arg, tuple):
+                    arg_type, arg_name = arg
+                else:
+                    arg_type = arg
+                    arg_name = "arg%u" % index
                 arg = Arg(arg_type, arg_name)
             arg.index = index
             index += 1
@@ -367,7 +239,6 @@ class Function:
         self.call = call
         self.fail = fail
         self.sideeffects = sideeffects
-        self.hidden = False
 
     def prototype(self, name=None):
         if name is not None:
@@ -395,7 +266,7 @@ def StdFunction(*args, **kwargs):
 
 
 def FunctionPointer(type, name, args, **kwargs):
-    # XXX
+    # XXX: We should probably treat function pointers (callbacks or not) in a generic fashion
     return Opaque(name)
 
 
@@ -407,9 +278,12 @@ class Interface(Type):
         self.base = base
         self.methods = []
 
+    def visit(self, visitor, *args, **kwargs):
+        return visitor.visit_interface(self, *args, **kwargs)
+
     def itermethods(self):
         if self.base is not None:
-            for method in self.stdapi.itermethods():
+            for method in self.base.itermethods():
                 yield method
         for method in self.methods:
             yield method
@@ -420,9 +294,8 @@ class Method(Function):
 
     def __init__(self, type, name, args):
         Function.__init__(self, type, name, args, call = '__stdcall')
-
-
-towrap = []
+        for index in range(len(self.args)):
+            self.args[index].index = index + 1
 
 
 def WrapPointer(type):
@@ -438,6 +311,7 @@ class String(Type):
     def visit(self, visitor, *args, **kwargs):
         return visitor.visit_string(self, *args, **kwargs)
 
+# C string (i.e., zero terminated)
 CString = String()
 
 
@@ -461,6 +335,115 @@ def OpaqueBlob(type, size):
     return Opaque(type.expr + ' *')
 
 
+class Visitor:
+
+    def visit(self, type, *args, **kwargs):
+        return type.visit(self, *args, **kwargs)
+
+    def visit_void(self, void, *args, **kwargs):
+        raise NotImplementedError
+
+    def visit_literal(self, literal, *args, **kwargs):
+        raise NotImplementedError
+
+    def visit_string(self, string, *args, **kwargs):
+        raise NotImplementedError
+
+    def visit_const(self, const, *args, **kwargs):
+        raise NotImplementedError
+
+    def visit_struct(self, struct, *args, **kwargs):
+        raise NotImplementedError
+
+    def visit_array(self, array, *args, **kwargs):
+        raise NotImplementedError
+
+    def visit_blob(self, blob, *args, **kwargs):
+        raise NotImplementedError
+
+    def visit_enum(self, enum, *args, **kwargs):
+        raise NotImplementedError
+
+    def visit_bitmask(self, bitmask, *args, **kwargs):
+        raise NotImplementedError
+
+    def visit_pointer(self, pointer, *args, **kwargs):
+        raise NotImplementedError
+
+    def visit_handle(self, handle, *args, **kwargs):
+        raise NotImplementedError
+
+    def visit_alias(self, alias, *args, **kwargs):
+        raise NotImplementedError
+
+    def visit_opaque(self, opaque, *args, **kwargs):
+        raise NotImplementedError
+
+    def visit_interface(self, interface, *args, **kwargs):
+        raise NotImplementedError
+
+
+class OnceVisitor(Visitor):
+
+    def __init__(self):
+        self.__visited = set()
+
+    def visit(self, type, *args, **kwargs):
+        if type not in self.__visited:
+            self.__visited.add(type)
+            return type.visit(self, *args, **kwargs)
+        return None
+
+
+class Rebuilder(Visitor):
+
+    def visit_void(self, void):
+        return void
+
+    def visit_literal(self, literal):
+        return literal
+
+    def visit_string(self, string):
+        return string
+
+    def visit_const(self, const):
+        return Const(const.type)
+
+    def visit_struct(self, struct):
+        members = [(self.visit(type), name) for type, name in struct.members]
+        return Struct(struct.name, members)
+
+    def visit_array(self, array):
+        type = self.visit(array.type)
+        return Array(type, array.length)
+
+    def visit_blob(self, blob):
+        type = self.visit(blob.type)
+        return Blob(type, blob.size)
+
+    def visit_enum(self, enum):
+        return enum
+
+    def visit_bitmask(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 visit_handle(self, handle):
+        type = self.visit(handle.type)
+        return Handle(handle.name, type, range=handle.range, key=handle.key)
+
+    def visit_alias(self, alias):
+        type = self.visit(alias.type)
+        return Alias(alias.expr, type)
+
+    def visit_opaque(self, opaque):
+        return opaque
+
+
 class Collector(Visitor):
     '''Collect.'''
 
@@ -516,12 +499,17 @@ class Collector(Visitor):
         pass
 
     def visit_interface(self, interface):
-        pass
+        if interface.base is not None:
+            self.visit(interface.base)
+        for method in interface.itermethods():
+            for arg in method.args:
+                self.visit(arg.type)
+            self.visit(method.type)
 
 
 class API:
 
-    def __init__(self, name):
+    def __init__(self, name = None):
         self.name = name
         self.headers = []
         self.functions = []
@@ -535,7 +523,7 @@ class API:
             collector.visit(function.type)
         for interface in self.interfaces:
             collector.visit(interface)
-            for method in interface.methods:
+            for method in interface.itermethods():
                 for arg in method.args:
                     collector.visit(arg.type)
                 collector.visit(method.type)
@@ -554,6 +542,17 @@ class API:
     def add_interfaces(self, interfaces):
         self.interfaces.extend(interfaces)
 
+    def add_api(self, api):
+        self.headers.extend(api.headers)
+        self.add_functions(api.functions)
+        self.add_interfaces(api.interfaces)
+
+    def get_function_by_name(self, name):
+        for function in self.functions:
+            if function.name == name:
+                return function
+        return None
+
 
 Bool = Literal("bool", "Bool")
 SChar = Literal("signed char", "SInt")
@@ -567,7 +566,7 @@ UInt = Literal("unsigned int", "UInt")
 ULong = Literal("unsigned long", "UInt")
 ULongLong = Literal("unsigned long long", "UInt")
 Float = Literal("float", "Float")
-Double = Literal("double", "Float")
+Double = Literal("double", "Double")
 SizeT = Literal("size_t", "UInt")
 WString = Literal("wchar_t *", "WString")