64 строки
1.9 KiB
Python
64 строки
1.9 KiB
Python
'''
|
|
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)
|
|
|