X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=scripts%2Ftracediff2.py;h=255191e8c5bf93bd9a744ef558b4c28e7f386e2d;hb=0ee878906f76cfe44ea6206112179600501efe52;hp=13fcbd1ef991ffbd6e6c63e032b6f756eb09911c;hpb=686714aa50236aece6165a342ab7de723a8859af;p=apitrace diff --git a/scripts/tracediff2.py b/scripts/tracediff2.py index 13fcbd1..255191e 100755 --- a/scripts/tracediff2.py +++ b/scripts/tracediff2.py @@ -1,7 +1,7 @@ #!/usr/bin/env python ########################################################################## # -# Copyright 2011 Jose Fonseca +# Copyright 2011-2012 Jose Fonseca # All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy @@ -26,12 +26,13 @@ import difflib +import itertools import optparse import os.path import subprocess import sys -from unpickle import Unpickler +from unpickle import Unpickler, Dumper, Rebuilder from highlight import ColorHighlighter, LessHighlighter @@ -39,22 +40,52 @@ ignoredFunctionNames = set([ '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): @@ -69,7 +100,6 @@ def readtrace(trace, calls): stdout = subprocess.PIPE, ) - calls = [] parser = Loader(p.stdout) parser.parse() return parser.calls @@ -86,6 +116,7 @@ class SDiffer: self.callNos = callNos self.aSpace = 0 self.bSpace = 0 + self.dumper = Dumper() def diff(self): matcher = difflib.SequenceMatcher(self.isjunk, self.a, self.b) @@ -135,16 +166,24 @@ class SDiffer: 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: @@ -155,32 +194,30 @@ class SDiffer: 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: - self.highlighter.write(str(b)) + self.highlighter.write(self.dumper.visit(b)) else: self.highlighter.strike() self.highlighter.color(self.delete_color) - self.highlighter.write(str(a)) + self.highlighter.write(self.dumper.visit(a)) self.highlighter.normal() self.highlighter.write(" ") self.highlighter.color(self.insert_color) - self.highlighter.write(str(b)) + self.highlighter.write(self.dumper.visit(b)) self.highlighter.normal() 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('- ') @@ -190,6 +227,8 @@ class SDiffer: 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('+ ') @@ -198,6 +237,8 @@ class SDiffer: 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] @@ -214,30 +255,30 @@ class SDiffer: 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): self.highlighter.bold(True) self.highlighter.write(call.functionName) self.highlighter.bold(False) - self.highlighter.write('(' + ', '.join(map(repr, call.args)) + ')') + self.highlighter.write('(' + ', '.join(itertools.imap(self.dumper.visit, call.args)) + ')') if call.ret is not None: - self.highlighter.write(' = ' + repr(call.ret)) + self.highlighter.write(' = ' + self.dumper.visit(call.ret)) self.highlighter.normal() self.highlighter.write('\n') @@ -256,7 +297,7 @@ def main(): 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', @@ -290,7 +331,10 @@ def main(): highlighter = ColorHighlighter() differ = SDiffer(ref_calls, src_calls, highlighter, options.call_nos) - differ.diff() + try: + differ.diff() + except IOError: + pass if __name__ == '__main__':