diff --git a/tools/scripts/move_only_function_specializations.py b/tools/scripts/move_only_function_specializations.py index a49b64e2f5..74ccbaa747 100644 --- a/tools/scripts/move_only_function_specializations.py +++ b/tools/scripts/move_only_function_specializations.py @@ -3,7 +3,7 @@ # This script generates the partial specializations of _Move_only_function_call in . -def specialization(cv, ref, ref_inv, noex, noex_val, callable): +def specialization(cv: str, ref: str, ref_inv: str, noex: str, noex_val: str, callable: str) -> str: return f"""template class _Move_only_function_call<_Rx(_Types...) {cv} {ref} {noex}> : public _Move_only_function_base<_Rx, {noex_val}, _Types...> {{ @@ -22,18 +22,21 @@ class _Move_only_function_call<_Rx(_Types...) {cv} {ref} {noex}> }}; """ -def ref_permutations(cv, noex, noex_val, trait): + +def ref_permutations(cv: str, noex: str, noex_val: str, trait: str) -> str: return specialization(cv, "", "&", noex, noex_val, \ f"{trait}<_Rx, {cv} _Vt, _Types...> && {trait}<_Rx, {cv} _Vt&, _Types...>") + "\n" \ + specialization(cv, "&", "&", noex, noex_val, f"{trait}<_Rx, {cv} _Vt&, _Types...>") + "\n" \ + specialization(cv, "&&", "&&", noex, noex_val, f"{trait}<_Rx, {cv} _Vt, _Types...>") -def cvref_permutations(noex, noex_val, trait): + +def cvref_permutations(noex: str, noex_val: str, trait: str) -> str: return ref_permutations("", noex, noex_val, trait) + "\n" \ + ref_permutations("const", noex, noex_val, trait) -print(cvref_permutations("", "false", "is_invocable_r_v") + "\n" \ - + "#ifdef __cpp_noexcept_function_type" + "\n" \ - + cvref_permutations("noexcept", "true", "is_nothrow_invocable_r_v") \ - + "#endif // __cpp_noexcept_function_type") +if __name__ == "__main__": + print(cvref_permutations("", "false", "is_invocable_r_v") + "\n" \ + + "#ifdef __cpp_noexcept_function_type" + "\n" \ + + cvref_permutations("noexcept", "true", "is_nothrow_invocable_r_v") \ + + "#endif // __cpp_noexcept_function_type") diff --git a/tools/scripts/print_failures.py b/tools/scripts/print_failures.py index cab9062b39..8a09e19f3d 100644 --- a/tools/scripts/print_failures.py +++ b/tools/scripts/print_failures.py @@ -9,29 +9,29 @@ import sys import xml.dom.minidom -if len(sys.argv) != 2: - sys.exit(f"Usage: python {sys.argv[0]} [TEST_LOG_FILENAME|TEST_RESULTS.xml]") -filename = sys.argv[1] -extension = os.path.splitext(filename)[1] - -with open(filename) as file: - if extension.casefold() == ".xml".casefold(): - test_xml = xml.dom.minidom.parse(file) - for testcase_elem in test_xml.getElementsByTagName("testcase"): - for failure_elem in testcase_elem.getElementsByTagName("failure"): - print("name: {}".format(testcase_elem.getAttribute("classname"))) - print("output: {}".format(failure_elem.firstChild.data)) - print("==================================================") - else: - test_log = json.load(file) - for result in test_log["tests"]: - if not result["code"] in ["PASS", "UNSUPPORTED", "XFAIL"]: - print("code: {}".format(result["code"])) - # Ignore result["elapsed"]. - print("name: {}".format(result["name"])) - # The JSON contains embedded CRLFs (which aren't affected by opening the file in text mode). - # If we don't replace these CRLFs with LFs here, this script will appear to be okay in the console, - # but redirecting it to a file will result in ugly double newlines. - print("output: {}".format(result["output"].replace("\r\n", "\n"))) - print("==================================================") +if __name__ == "__main__": + if len(sys.argv) != 2: + sys.exit(f"Usage: python {sys.argv[0]} [TEST_LOG_FILENAME|TEST_RESULTS.xml]") + filename = sys.argv[1] + extension = os.path.splitext(filename)[1] + with open(filename) as file: + if extension.casefold() == ".xml".casefold(): + test_xml = xml.dom.minidom.parse(file) + for testcase_elem in test_xml.getElementsByTagName("testcase"): + for failure_elem in testcase_elem.getElementsByTagName("failure"): + print(f"name: {testcase_elem.getAttribute('classname')}") + print(f"output: {failure_elem.firstChild.data}") + print("==================================================") + else: + test_log = json.load(file) + for result in test_log["tests"]: + if not result["code"] in ["PASS", "UNSUPPORTED", "XFAIL"]: + print(f"code: {result['code']}") + # Ignore result["elapsed"]. + print(f"name: {result['name']}") + # The JSON contains embedded CRLFs (which aren't affected by opening the file in text mode). + # If we don't replace these CRLFs with LFs here, this script will appear to be okay in the console, + # but redirecting it to a file will result in ugly double newlines. + print("output: {}".format(result["output"].replace("\r\n", "\n"))) + print("==================================================") diff --git a/tools/unicode_properties_parse/grapheme_break_property_data_gen.py b/tools/unicode_properties_parse/grapheme_break_property_data_gen.py index 55b4cb178d..316714dcf5 100644 --- a/tools/unicode_properties_parse/grapheme_break_property_data_gen.py +++ b/tools/unicode_properties_parse/grapheme_break_property_data_gen.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + from io import StringIO from pathlib import Path from dataclasses import dataclass, field @@ -13,11 +14,13 @@ class PropertyRange: upper: int = -1 prop: str = None + @dataclass class PropertyTable: lower_bounds: list[int] = field(default_factory=list) props_and_range: list[int] = field(default_factory=list) + LINE_REGEX = re.compile( r"^(?P[0-9A-F]{4,5})(?:\.\.(?P[0-9A-F]{4,5}))?\s*;\s*(?P\w+)") @@ -30,10 +33,10 @@ def parsePropertyLine(inputLine: str) -> Optional[PropertyRange]: if upper_str is not None: result.upper = int(upper_str, base=16) return result - else: return None + def compactPropertyRanges(input: list[PropertyRange]) -> list[PropertyRange]: """ Merges consecutive ranges with the same property to one range. @@ -218,6 +221,7 @@ def property_ranges_to_table(ranges: list[PropertyRange], props: list[str]) -> P result.props_and_range.append(size | (prop_idx << 12)) return result + def generate_cpp_data(prop_name: str, ranges: list[PropertyRange]) -> str: result = StringIO() prop_values = sorted(set(x.prop for x in ranges)) @@ -233,8 +237,6 @@ def generate_cpp_data(prop_name: str, ranges: list[PropertyRange]) -> str: return result.getvalue() - - def generate_data_tables() -> str: """ Generate Unicode data for inclusion into from @@ -262,5 +264,6 @@ def generate_data_tables() -> str: x for x in emoji_ranges if x.prop == "Extended_Pictographic"]) return "\n".join([gpb_cpp_data, emoji_cpp_data]) + if __name__ == "__main__": print(MSVC_FORMAT_UCD_TABLES_HPP_TEMPLATE.lstrip().format(content=generate_data_tables())) diff --git a/tools/unicode_properties_parse/grapheme_break_test_data_gen.py b/tools/unicode_properties_parse/grapheme_break_test_data_gen.py index e615910f81..6639449317 100644 --- a/tools/unicode_properties_parse/grapheme_break_test_data_gen.py +++ b/tools/unicode_properties_parse/grapheme_break_test_data_gen.py @@ -12,12 +12,15 @@ class BreakTestItem: breaks: list[int] = field(default_factory=list) code_points: list[int] = field(default_factory=list) + class CommentLine: pass + class EOF: pass + def parseBreakTestLine(input: TextIO) -> Optional[BreakTestItem]: result = BreakTestItem() while True: @@ -76,6 +79,7 @@ def lineToCppDataLineUtf32(line: BreakTestItem) -> str: [f"U'\\x{x:x}'" for x in line.code_points]), ','.join( [str(x) for x in line.breaks])) + def lineToCppDataLineUtf8(line: BreakTestItem) -> str: utf8_rep = str(array('L', line.code_points), encoding='utf-32').encode('utf-8') @@ -101,5 +105,6 @@ def generate_all() -> str: return cpp_template.format(len(lines), ','.join(map(lineToCppDataLineUtf32, lines)), ','.join(map(lineToCppDataLineUtf8, lines))) + if __name__ == "__main__": print(generate_all())