import platform
import optparse
-import os
+import os.path
import shutil
import subprocess
import sys
import tempfile
-import time
-def stripdump(trace, fifo):
- dump = subprocess.Popen(
- args = [
+class Dumper:
+
+ def __init__(self, trace, calls):
+ self.output = tempfile.NamedTemporaryFile()
+
+ dump_args = [
options.apitrace,
'dump',
'--color=never',
+ '--call-nos=no',
'--arg-names=no',
- '--calls=' + options.calls,
+ '--calls=' + calls,
trace
- ],
- stdout = subprocess.PIPE,
- universal_newlines = True,
- )
-
- sed = subprocess.Popen(
- args = [
- 'sed',
- '-e', r's/\r$//g',
- '-e', r's/^[0-9]\+ //',
- '-e', r's/hdc = \w\+/hdc/g',
- ],
- stdin = dump.stdout,
- stdout = open(fifo, 'wt'),
- universal_newlines = True,
- )
+ ]
- # XXX: Avoid a weird race condition
- time.sleep(0.01)
+ self.dump = subprocess.Popen(
+ args = dump_args,
+ stdout = self.output,
+ universal_newlines = True,
+ )
if platform.system() == 'Windows':
end_insert = '\33[0m'
-def diff(traces):
- fifodir = tempfile.mkdtemp()
- try:
- fifos = []
- for i in range(len(traces)):
- trace = traces[i]
- fifo = os.path.join(fifodir, str(i))
- stripdump(trace, fifo)
- fifos.append(fifo)
-
- # TODO use difflib instead
- if options.diff == 'diff':
- diff_args = [
- 'diff',
- '--speed-large-files',
- '--old-line-format=' + start_delete + '%l' + end_delete + '\n',
- '--new-line-format=' + start_insert + '%l' + end_insert + '\n',
- ]
- elif options.diff == 'sdiff':
- diff_args = [
- 'sdiff',
- '--width=%u' % options.width,
- '--speed-large-files',
- ]
- elif options.diff == 'wdiff':
- diff_args = [
- 'wdiff',
- #'--terminal',
- '--avoid-wraps',
- '--start-delete=' + start_delete,
- '--end-delete=' + end_delete,
- '--start-insert=' + start_insert,
- '--end-insert=' + end_insert,
- ]
- else:
- assert False
- diff_args += fifos
-
- diff = subprocess.Popen(
- args = diff_args,
- stdout = subprocess.PIPE,
- universal_newlines = True,
- )
+def diff(ref_trace, src_trace):
+
+ ref_dumper = Dumper(ref_trace, options.ref_calls)
+ src_dumper = Dumper(src_trace, options.src_calls)
+
+ # TODO use difflib instead
+ if options.diff == 'diff':
+ diff_args = [
+ 'diff',
+ '--speed-large-files',
+ '--old-line-format=' + start_delete + '%l' + end_delete + '\n',
+ '--new-line-format=' + start_insert + '%l' + end_insert + '\n',
+ ]
+ elif options.diff == 'sdiff':
+ diff_args = [
+ 'sdiff',
+ '--width=%u' % options.width,
+ '--speed-large-files',
+ ]
+ elif options.diff == 'wdiff':
+ diff_args = [
+ 'wdiff',
+ #'--terminal',
+ '--avoid-wraps',
+ '--start-delete=' + start_delete,
+ '--end-delete=' + end_delete,
+ '--start-insert=' + start_insert,
+ '--end-insert=' + end_insert,
+ ]
+ else:
+ assert False
+ diff_args += [ref_dumper.output.name, src_dumper.output.name]
+ ref_dumper.dump.wait()
+ src_dumper.dump.wait()
+
+ less = None
+ if sys.stdout.isatty():
less = subprocess.Popen(
args = ['less', '-FRXn'],
- stdin = diff.stdout
+ stdin = subprocess.PIPE
)
- less.wait()
+ diff_stdout = less.stdin
+ else:
+ diff_stdout = None
- finally:
- shutil.rmtree(fifodir)
+ diff = subprocess.Popen(
+ args = diff_args,
+ stdout = diff_stdout,
+ universal_newlines = True,
+ )
+
+ diff.wait()
+
+ if less is not None:
+ less.wait()
def which(executable):
'''Main program.
'''
- if which('wdiff'):
- default_diff = 'wdiff'
- elif which('sdiff'):
- default_diff = 'sdiff'
- else:
- default_diff = 'diff'
-
+ # Determine default options
default_width = columns()
# Parse command line options
optparser.add_option(
'-d', '--diff',
type="choice", choices=('diff', 'sdiff', 'wdiff'),
- dest="diff", default=default_diff,
- help="diff program: diff, sdiff, or wdiff [default: %default]")
+ dest="diff", default=None,
+ help="diff program: wdiff, sdiff, or diff [default: auto]")
optparser.add_option(
'-c', '--calls', metavar='CALLSET',
type="string", dest="calls", default='1-10000',
help="calls to compare [default: %default]")
+ optparser.add_option(
+ '--ref-calls', metavar='CALLSET',
+ type="string", dest="ref_calls", default=None,
+ help="calls to compare from reference trace")
+ optparser.add_option(
+ '--src-calls', metavar='CALLSET',
+ type="string", dest="src_calls", default=None,
+ help="calls to compare from source trace")
optparser.add_option(
'-w', '--width', metavar='NUM',
type="string", dest="width", default=default_width,
if len(args) != 2:
optparser.error("incorrect number of arguments")
- diff(args)
+ if options.diff is None:
+ if which('wdiff'):
+ options.diff = 'wdiff'
+ else:
+ sys.stderr.write('warning: wdiff not found\n')
+ if which('sdiff'):
+ options.diff = 'sdiff'
+ else:
+ sys.stderr.write('warning: sdiff not found\n')
+ options.diff = 'diff'
+
+ if options.ref_calls is None:
+ options.ref_calls = options.calls
+ if options.src_calls is None:
+ options.src_calls = options.calls
+
+ diff(*args)
if __name__ == '__main__':