import subprocess
import sys
-from unpickle import Unpickler, Dumper
+from unpickle import Unpickler, Dumper, Rebuilder
from highlight import ColorHighlighter, LessHighlighter
'glGetString',
'glXGetClientString',
'glXGetCurrentDisplay',
+ 'glXGetCurrentContext',
'glXGetProcAddress',
'glXGetProcAddressARB',
'wglGetProcAddress',
])
+class Blob:
+ '''Data-less proxy for bytearrays, to save memory.'''
+
+ def __init__(self, size, hash):
+ self.size = size
+ self.hash = hash
+
+ def __repr__(self):
+ return 'blob(%u)' % self.size
+
+ def __eq__(self, other):
+ return isinstance(other, Blob) and self.size == other.size and self.hash == other.hash
+
+ def __hash__(self):
+ return self.hash
+
+
+class BlobReplacer(Rebuilder):
+ '''Replace blobs with proxys.'''
+
+ def visitByteArray(self, obj):
+ return Blob(len(obj), hash(str(obj)))
+
+ def visitCall(self, call):
+ call.args = map(self.visit, call.args)
+ call.ret = self.visit(call.ret)
+
+
class Loader(Unpickler):
def __init__(self, stream):
Unpickler.__init__(self, stream)
self.calls = []
+ self.rebuilder = BlobReplacer()
def handleCall(self, call):
if call.functionName not in ignoredFunctionNames:
+ self.rebuilder.visitCall(call)
self.calls.append(call)
- hash(call)
def readtrace(trace, calls):
stdout = subprocess.PIPE,
)
- calls = []
parser = Loader(p.stdout)
parser.parse()
return parser.calls
a_call = self.a[alo + i]
b_call = self.b[blo + i]
assert a_call.functionName == b_call.functionName
- assert len(a_call.args) == len(b_call.args)
self.dumpCallNos(a_call.no, b_call.no)
self.highlighter.bold(True)
self.highlighter.write(b_call.functionName)
self.highlighter.bold(False)
self.highlighter.write('(')
sep = ''
- for j in xrange(len(b_call.args)):
+ numArgs = max(len(a_call.args), len(b_call.args))
+ for j in xrange(numArgs):
self.highlighter.write(sep)
- self.replace_value(a_call.args[j], b_call.args[j])
+ try:
+ a_arg = a_call.args[j]
+ except IndexError:
+ pass
+ try:
+ b_arg = b_call.args[j]
+ except IndexError:
+ pass
+ self.replace_value(a_arg, b_arg)
sep = ', '
self.highlighter.write(')')
if a_call.ret is not None or b_call.ret is not None:
def replace_dissimilar(self, alo, ahi, blo, bhi):
assert alo < ahi and blo < bhi
if bhi - blo < ahi - alo:
- first = self.insert(blo, bhi)
- second = self.delete(alo, ahi)
+ self.insert(alo, alo, blo, bhi)
+ self.delete(alo, ahi, bhi, bhi)
else:
- first = self.delete(alo, ahi)
- second = self.insert(blo, bhi)
-
- for g in first, second:
- for line in g:
- yield line
+ self.delete(alo, ahi, blo, blo)
+ self.insert(ahi, ahi, blo, bhi)
def replace_value(self, a, b):
if b == a:
escape = "\33["
def delete(self, alo, ahi, blo, bhi):
+ assert alo < ahi
+ assert blo == bhi
for i in xrange(alo, ahi):
call = self.a[i]
self.highlighter.write('- ')
self.dumpCall(call)
def insert(self, alo, ahi, blo, bhi):
+ assert alo == ahi
+ assert blo < bhi
for i in xrange(blo, bhi):
call = self.b[i]
self.highlighter.write('+ ')
self.dumpCall(call)
def equal(self, alo, ahi, blo, bhi):
+ assert alo < ahi and blo < bhi
+ assert ahi - alo == bhi - blo
for i in xrange(0, bhi - blo):
self.highlighter.write(' ')
a_call = self.a[alo + i]
if aNo is None:
self.highlighter.write(' '*self.aSpace)
else:
- aStr = str(aNo)
+ aNoStr = str(aNo)
self.highlighter.strike()
self.highlighter.color(self.delete_color)
- self.highlighter.write(str(aNo))
+ self.highlighter.write(aNoStr)
self.highlighter.normal()
- self.aSpace = len(aStr)
+ self.aSpace = len(aNoStr)
self.highlighter.write(' ')
if bNo is None:
- self.highlighter.write(' '*self.aSpace)
+ self.highlighter.write(' '*self.bSpace)
else:
- bStr = str(bNo)
+ bNoStr = str(bNo)
self.highlighter.color(self.insert_color)
- self.highlighter.write(str(bNo))
+ self.highlighter.write(bNoStr)
self.highlighter.normal()
- self.bSpace = len(bStr)
+ self.bSpace = len(bNoStr)
self.highlighter.write(' ')
def dumpCall(self, call):
help='apitrace command [default: %default]')
optparser.add_option(
'-c', '--calls', metavar='CALLSET',
- type="string", dest="calls", default='1-10000',
+ type="string", dest="calls", default='*',
help="calls to compare [default: %default]")
optparser.add_option(
'--ref-calls', metavar='CALLSET',
highlighter = ColorHighlighter()
differ = SDiffer(ref_calls, src_calls, highlighter, options.call_nos)
- differ.diff()
+ try:
+ differ.diff()
+ except IOError:
+ pass
if __name__ == '__main__':