1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
COPYING = '''checker Copyright (C) 2010, 2011 MaskRay This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. '''
def rreplace(s1, s2, s3): p = s1.rfind(s2) return s1[:p] + s3 + s1[p+len(s2):] if p != -1 else s1
def test(s, pat1, pat2): p = s.find(pat1) if p == -1: return False q = s.find(pat2) while q != -1: if not p <= q < p+len(pat1): return True q = s.find(pat2, q+len(pat2)) return False
if __name__ == '__main__':
import math, sys, os, re, subprocess, threading, time, tempfile from optparse import OptionParser
def main():
def print_copying(): sys.stdout.write(COPYING) exit(0)
usage = '''usage: %prog source [input] [output] source - source file input - suffix of input files (default `in') output - suffix of output files (default `out')''' parser = OptionParser(usage=usage) parser.add_option('-p', '--path', action='store', dest='path', default='/tmp', help='specify the path of testdata') parser.add_option('-i', '--dataid', action='store', dest='dataid', default='', help='specify the data id') parser.add_option('-d', '--detail', action='store_true', dest='show_detail', default=False, help='show details') parser.add_option('-s', '--showtime', action='store_true', dest='show_time', default=False, help='show time used') parser.add_option('-t', '--time-limit', action='store', type='float', dest='time_limit', default=1.) parser.add_option('--version', action="callback", callback=lambda o, s, v, p: print_copying(), help="print the COPYING and exit") (options, args) = parser.parse_args()
options.path = os.path.expanduser(options.path) if len(args) < 1 or len(args) > 4: parser.print_usage() sys.exit(1) if len(args) < 2: args.append('in') if len(args) < 3: args.append('out') r = re.compile('\d+')
L = [file for file in os.listdir(options.path) if test(file, args[0], args[1])] for file in sorted(L, key = lambda x: int(r.findall(x)[-1] if r.findall(x) else sys.maxint)): if options.dataid != '' and (not r.findall(file) or r.findall(file)[-1] != options.dataid): continue print('---' + file + '---')
temp = tempfile.NamedTemporaryFile() sub = subprocess.Popen('./main', stdin=open(os.path.join(options.path, file)), stdout=temp) bgn = time.time() timer = threading.Timer(options.time_limit, sub.terminate) timer.start() ret = sub.wait() end = time.time() timer.cancel()
RESET = '\033[0m' if ret == -11: print('\033[1;34m' + 'runtime error' + RESET) elif ret == -15: print('\033[1;35m' + 'time limit exceed' + RESET) elif ret == 0: sys.stdout.write('\033[1m') sys.stdout.flush() with open(os.path.join(options.path, rreplace(file, args[1], args[2]))) as f: lines = f.readlines()
if len(lines) == 1 and re.search('''\d+\.\d+''', lines[0]): res = float(lines[0]) with open(temp.name) as f: lines = f.readlines() if len(lines) != 1: print('wrong answer' + RESET) elif math.isnan(float(lines[0])) or abs(float(lines[0])-res) > 1e-9: print('< %f\n---\n> %f\n' % (res, float(lines[0])) + RESET) elif 0 == os.system('diff --strip-trailing-cr %s %s %s' % ('' if options.show_detail else '-q', os.path.join(options.path, rreplace(file, args[1], args[2])), temp.name)) and options.show_time: print(RESET + '%.3f second(s)' % (end-bgn)) else: sys.stdout.write(RESET) sys.stdout.flush() else: print('\033[1;32m' + 'exit abnormally' + RESET)
main()
|