diff options
author | Alon Zakai <alonzakai@gmail.com> | 2014-05-19 11:14:43 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2014-05-19 11:14:43 -0700 |
commit | 4ed0af723b235ae2504c65b6aaeb4b7c57fa435a (patch) | |
tree | d48ec10980f4b3787194c04ad086133413b6f1be | |
parent | a4ae7a1c29e7873f77ea4168e1c8c2c66a7cb34a (diff) |
add line bisector tool
-rw-r--r-- | tools/bisect_pair_lines.py | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/tools/bisect_pair_lines.py b/tools/bisect_pair_lines.py new file mode 100644 index 00000000..f698ef2a --- /dev/null +++ b/tools/bisect_pair_lines.py @@ -0,0 +1,63 @@ +''' +Given two similar files, for example one with an additional optimization pass, +and with different results, will bisect between them to find the smallest +diff that makes the outputs different. +Unlike bisect_pairs, this uses lines instead of diffs. We replace line by line. This assumes +the programs differ on each line but lines have not been added or removed +''' + +import os, sys, shutil +from subprocess import Popen, PIPE, STDOUT + +__rootpath__ = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) +def path_from_root(*pathelems): + return os.path.join(__rootpath__, *pathelems) +exec(open(path_from_root('tools', 'shared.py'), 'r').read()) + +file1 = open(sys.argv[1]).read() +file2 = open(sys.argv[2]).read() + +leftf = open('left', 'w') +leftf.write(file1) +leftf.close() + +rightf = open('right', 'w') +rightf.write(file2) +rightf.close() + +def run_code(name): + ret = run_js(name, stderr=PIPE, full_output=True) + # fix stack traces + ret = filter(lambda line: not line.startswith(' at ') and not name in line, ret.split('\n')) + return '\n'.join(ret) + +print 'running files' +left_result = run_code('left') +right_result = run_code('right') # right as in left-right, not as in correct +assert left_result != right_result + +low = 0 +high = file1.count('\n') + +print 'beginning bisection, %d lines' % high + +left_lines = file1.split('\n') +right_lines = file2.split('\n') + +while True: + mid = int((low + high)/2) + print low, high, ' current: %d' % mid, + open('middle', 'w').write('\n'.join(left_lines[:mid] + right_lines[mid:])) + shutil.copyfile('middle', 'middle' + str(mid)) + result = run_code('middle') + print result == left_result, result == right_result#, 'XXX', left_result, 'YYY', result, 'ZZZ', right_result + if mid == low or mid == high: break + if result == right_result: + low = mid + elif result == left_result: + high = mid + else: + raise Exception('new result!?!?') + +print 'middle%d is like left, middle%d is like right' % (mid+1, mid) + |