import hashlib import re import shlex import sys start = re.escape("/*[") end = re.escape("]*/") start_line = re.compile(start + "(?P\w+) input\\]") body_prefix = "" stop_line = re.compile("\\[(?P\w+) start generated code" + end) checksum_line = re.compile(start + "(?P\w+) end generated code: (?P.+)" + end) state_verbatim = 'verbatim' state_clinic_input = 'clinic_input' state_clinic_output = 'clinic_output' def compute_checksum(input, length=None): input = input or '' s = hashlib.sha1(input.encode('utf-8')).hexdigest() if length: s = s[:length] return s def fail(*a): print("Error in", repr(filename), "on line", str(line_number) + ":") print(*a) sys.exit(-1) def reset(): global input global output global state input = [] output = [] state = state_verbatim input = output = state = None for filename in sys.argv[1:]: reset() with open(filename, "rt") as f: for line_number, line in enumerate(f.read().splitlines(True), 1): if state == state_verbatim: match = start_line.match(line) if match: dsl_name = match.group('dsl_name') state = state_clinic_input elif state == state_clinic_input: match = stop_line.match(line) if match: got = match.group('dsl_name') if got != dsl_name: fail("Error: mismatched dsl name! Expected", repr(dsl_name), "but got", repr(got)) state = state_clinic_output else: input.append(line) elif state == state_clinic_output: match = checksum_line.match(line) if match: got = match.group('dsl_name') if got != dsl_name: fail("Error: mismatched dsl name! Expected", repr(dsl_name), "but got", repr(got)) # print("found block:", repr(input[:5]), repr(output[:5])) d = {} for field in shlex.split(match.group('arguments')): name, equals, value = field.partition('=') if not equals: fail("Malformed arguments to checksum line") d[name.strip()] = value.strip() if 'checksum' in d: checksum = d['checksum'] input_checksum = None else: checksum = d['output'] input_checksum = d['input'] output = ''.join(output) computed = compute_checksum(output, len(checksum)) # print("checksum", checksum, "computed", computed) if checksum != computed: fail("Output checksum mismatch! Someone modified the output text!") if input_checksum: input = ''.join(input) computed = compute_checksum(input, len(input_checksum)) # print("input_checksum", input_checksum, "computed", computed) if input_checksum != computed: fail("Input checksum mismatch! Clinic generated code is out of date!") reset() # print() else: output.append(line)