diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -8,7 +8,6 @@ import abc import ast import atexit -import clinic import collections import contextlib import functools @@ -898,13 +897,21 @@ def parse_clinic_block(self, dsl_name): input_add, input_output = text_accumulator() self.block_start_line_number = self.line_number + 1 - stop_line = self.language.stop_line.format(dsl_name=dsl_name) + '\n' + stop_line = self.language.stop_line.format(dsl_name=dsl_name) body_prefix = self.language.body_prefix.format(dsl_name=dsl_name) + def is_stop_line(line): + # make sure to recognize stop line even if it + # doesn't end with EOL (it could be the very end of the file) + if not line.startswith(stop_line): + return False + remainder = line[len(stop_line):] + return (not remainder) or remainder.isspace() + # consume body of program while self.input: line = self._line() - if line == stop_line or self.is_start_line(line): + if is_stop_line(line) or self.is_start_line(line): break if body_prefix: line = line.lstrip() @@ -1390,7 +1397,8 @@ data is a CRenderData instance. """ self.parameter = parameter - name = ensure_legal_c_identifier(self.name) + original_name = self.name + name = ensure_legal_c_identifier(original_name) # declarations d = self.declaration() @@ -1408,7 +1416,7 @@ data.impl_arguments.append(self.length_name()) # keywords - data.keywords.append(name) + data.keywords.append(original_name) # format_units if self.is_optional() and '|' not in data.format_units: diff --git a/Tools/clinic/clinic_test.py b/Tools/clinic/clinic_test.py --- a/Tools/clinic/clinic_test.py +++ b/Tools/clinic/clinic_test.py @@ -54,6 +54,25 @@ _module_and_class = clinic.Clinic._module_and_class +class ClinicWholeFileTest(TestCase): + def test_eol(self): + # regression test: + # clinic's block parser didn't recognize + # the "end line" for the block if it + # didn't end in "\n" (as in, the last) + # byte of the file was '/'. + # so it woudl spit out an end line for you. + # and since you really already had one, + # the last line of the block got corrupted. + c = clinic.Clinic(clinic.CLanguage()) + raw = "/*[clinic]\nfoo\n[clinic]*/" + cooked = c.parse(raw).splitlines() + end_line = cooked[2].rstrip() + # this test is redundant, it's just here explicitly to catch + # the regression test so we don't forget what it looked like + self.assertNotEqual(end_line, "[clinic]*/[clinic]*/") + self.assertEqual(end_line, "[clinic]*/") + class ClinicGroupPermuterTest(TestCase):