all_types = {}
+
+class Visitor:
+
+ def visit(self, type, *args, **kwargs):
+ return type.visit(self, *args, **kwargs)
+
+ __call__ = visit
+
+ def visit_void(self, type, *args, **kwargs):
+ raise NotImplementedError
+
+ def visit_literal(self, type, *args, **kwargs):
+ raise NotImplementedError
+
+ def visit_const(self, type, *args, **kwargs):
+ raise NotImplementedError
+
+ def visit_struct(self, type, *args, **kwargs):
+ raise NotImplementedError
+
+ def visit_array(self, type, *args, **kwargs):
+ raise NotImplementedError
+
+ def visit_enum(self, type, *args, **kwargs):
+ raise NotImplementedError
+
+ def visit_bitmask(self, type, *args, **kwargs):
+ raise NotImplementedError
+
+ def visit_pointer(self, type, *args, **kwargs):
+ raise NotImplementedError
+
+ def visit_alias(self, type, *args, **kwargs):
+ raise NotImplementedError
+
+ def visit_opaque(self, type, *args, **kwargs):
+ raise NotImplementedError
+
+
class Type:
__seq = 0
def __str__(self):
return self.expr
+ def visit(self, visitor, *args, **kwargs):
+ raise NotImplementedError
+
def isoutput(self):
return False
def __init__(self):
Type.__init__(self, "void")
+ def visit(self, visitor, *args, **kwargs):
+ return visitor.visit_void(self, *args, **kwargs)
+
Void = _Void()
Concrete.__init__(self, expr)
self.format = format
+ def visit(self, visitor, *args, **kwargs):
+ return visitor.visit_literal(self, *args, **kwargs)
+
def _dump(self, instance):
print ' Log::Literal%s(%s);' % (self.format, instance)
self.type = type
+ def visit(self, visitor, *args, **kwargs):
+ return visitor.visit_const(self, *args, **kwargs)
+
def dump(self, instance):
self.type.dump(instance)
Type.__init__(self, type.expr + " *", 'P' + type.id)
self.type = type
+ def visit(self, visitor, *args, **kwargs):
+ return visitor.visit_pointer(self, *args, **kwargs)
+
def dump(self, instance):
print ' if(%s) {' % instance
print ' Log::BeginPointer("%s", (const void *)%s);' % (self.type, instance)
Concrete.__init__(self, name)
self.values = values
+ def visit(self, visitor, *args, **kwargs):
+ return visitor.visit_enum(self, *args, **kwargs)
+
def _dump(self, instance):
print ' switch(%s) {' % instance
for value in self.values:
print ' }'
-class FakeEnum(Enum):
-
- def __init__(self, type, values):
- Enum.__init__(self, type.expr, values)
- self.type = type
+def FakeEnum(type, values):
+ return Enum(type.expr, values)
-class Flags(Concrete):
+class Bitmask(Concrete):
def __init__(self, type, values):
Concrete.__init__(self, type.expr)
self.type = type
self.values = values
+ def visit(self, visitor, *args, **kwargs):
+ return visitor.visit_bitmask(self, *args, **kwargs)
+
def _dump(self, instance):
print ' %s l_Value = %s;' % (self.type, instance)
print ' Log::BeginBitmask("%s");' % (self.type,)
print ' }'
print ' Log::EndBitmask();'
+Flags = Bitmask
+
class Array(Type):
self.type = type
self.length = length
+ def visit(self, visitor, *args, **kwargs):
+ return visitor.visit_array(self, *args, **kwargs)
+
def dump(self, instance):
index = '__i' + self.type.id
print ' Log::BeginArray("%s", %s);' % (self.type, self.length)
self.name = name
self.members = members
+ def visit(self, visitor, *args, **kwargs):
+ return visitor.visit_struct(self, *args, **kwargs)
+
def _dump(self, instance):
print ' Log::BeginStruct("%s");' % (self.name,)
for type, name in self.members:
Type.__init__(self, name)
self.type = type
+ def visit(self, visitor, *args, **kwargs):
+ return visitor.visit_alias(self, *args, **kwargs)
+
def dump(self, instance):
self.type.dump(instance)
def __init__(self):
Type.__init__(self, "char *")
+ def visit(self, visitor, *args, **kwargs):
+ return visitor.visit_literal(self, *args, **kwargs)
+
def dump(self, instance):
print ' Log::LiteralString((const char *)%s);' % instance
def __init__(self):
Type.__init__(self, "void")
+ def visit(self, visitor, *args, **kwargs):
+ return visitor.visit_opaque(self, *args, **kwargs)
+
def dump(self, instance):
print ' Log::LiteralOpaque();'
return True
-def extract_value(arg_type, arg_value):
- if isinstance(arg_type, base.Literal):
- return 'Trace::as%s(%s)' % (arg_type.format, value)
- if isinstance(arg_type, base.Enum):
- return 'Trace::asSInt(%s)' % (value)
- if isinstance(arg_type, (base.Alias, base.Flags)):
- return extract_value(arg_type.type, value)
- assert false
- return '0'
+class ValueExtractor(base.Visitor):
+
+ def visit_literal(self, type, lvalue, rvalue):
+ #print ' %s = static_cast<%s>(Trace::as%s(%s));' % (lvalue, type, type.format, rvalue)
+ print ' %s = Trace::as%s(%s);' % (lvalue, type.format, rvalue)
+
+ def visit_alias(self, type, lvalue, rvalue):
+ self.visit(type.type, lvalue, rvalue)
+
+ def visit_enum(self, type, lvalue, rvalue):
+ #print ' %s = static_cast<%s>(Trace::as%s(%s));' % (lvalue, type, 'SInt', rvalue)
+ print ' %s = Trace::as%s(%s);' % (lvalue, 'SInt', rvalue)
+
+ def visit_bitmask(self, type, lvalue, rvalue):
+ self.visit(type.type, lvalue, rvalue)
+
+
+
+def retrace_function(function):
+ print 'static void retrace_%s(Trace::Call &call) {' % function.name
+ if not function.name.startswith('glX'):
+ success = True
+ for arg_type, arg_name in function.args:
+ print ' %s %s;' % (arg_type, arg_name)
+ for arg_type, arg_name in function.args:
+ rvalue = 'call.arg("%s")' % (arg_name,)
+ lvalue = arg_name
+ try:
+ ValueExtractor().visit(arg_type, lvalue, rvalue)
+ except NotImplementedError:
+ success = False
+ print ' %s = 0; // FIXME' % arg_name
+ if not success:
+ print ' std::cerr << "warning: unsupported call %s\\n";' % function.name
+ print ' return;'
+ arg_names = ", ".join([arg_name for arg_type, arg_name in function.args])
+ print ' %s(%s);' % (function.name, arg_names)
+ print '}'
+ print
if __name__ == '__main__':
functions = filter(is_function_supported, libgl.functions)
- for function in functions:
- print 'static void retrace_%s(Trace::Call &call) {' % function.name
- for arg_type, arg_name in function.args:
- print ' %s %s;' % (arg_type, arg_name)
- for arg_type, arg_name in function.args:
- value = 'call.get_arg("%s")' % (arg_name,)
- value = extract_value(arg_type, value)
- print ' %s = static_cast<%s>(%s);' % (arg_name, arg_type, value)
- arg_names = ", ".join([arg_name for arg_type, arg_name in function.args])
- print ' %s(%s);' % (function.name, arg_names)
- print '}'
- print
+ for function in libgl.functions:
+ retrace_function(function)
print 'static bool retrace_call(Trace::Call &call) {'
- for function in functions:
+ for function in libgl.functions:
print ' if (call.name == "%s") {' % function.name
print ' retrace_%s(call);' % function.name
print ' return true;'
print ' }'
- print ' std::cerr << "Unsupported call " << call.name << "\\n";'
+ print ' std::cerr << "warning: unsupported call " << call.name << "\\n";'
print ' return false;'
print '}'
print '''