mirror of
https://github.com/boostorg/parser.git
synced 2026-01-19 16:32:13 +00:00
114 lines
3.3 KiB
Python
Executable File
114 lines
3.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# Copyright (c) 2024 T. Zachary Laine
|
|
#
|
|
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
# Get the latest version of the data file at:
|
|
# https://www.unicode.org/Public/UCD/latest/ucd/CaseFolding.txt
|
|
|
|
import itertools
|
|
|
|
f = open('CaseFolding.txt')
|
|
|
|
lines = f.readlines()
|
|
|
|
lines = filter(
|
|
lambda x: False if (x.startswith('#') or x == '\n' or ' T;' in x or ' S;' in x) else True,
|
|
lines)
|
|
|
|
lines = list(map(lambda x: x.split(';')[:-1], lines))
|
|
|
|
f_line_indices = list(filter(lambda i: ' F;' in lines[i], range(len(lines))))
|
|
|
|
# Remove all C; lines that come before a F; line that applies to the same code
|
|
# point.
|
|
for f_idx in reversed(f_line_indices):
|
|
prev = f_idx - 1
|
|
if 0 <= prev:
|
|
if lines[f_idx][0] == lines[prev][0]:
|
|
lines = lines[:prev] + lines[prev + 1:]
|
|
|
|
max_mapping_len = 1
|
|
for line in lines:
|
|
mappings = line[2].strip().split(' ')
|
|
max_mapping_len = max(len(mappings), max_mapping_len)
|
|
|
|
def print_cps():
|
|
print('// Initial code points from CaseFolding.txt')
|
|
print('char32_t const cps[] = {')
|
|
str_ = ''
|
|
idx = 0
|
|
max_per_line = 8
|
|
for cp in map(lambda x: '0x' + x[0], lines):
|
|
str_ += cp + ', '
|
|
idx += 1
|
|
if (idx % max_per_line) == 0:
|
|
print(' ' + str_)
|
|
str_ = ''
|
|
if idx % max_per_line:
|
|
print(' ' + str_)
|
|
print('};\n')
|
|
print(f'char32_t const max_test_cp = 0x{lines[-1][0]} + 100;\n')
|
|
|
|
|
|
array_t = f'std::array<uint32_t, {max_mapping_len} + 1>'
|
|
|
|
def print_test(line):
|
|
num_mapping_cps = len(line[2].strip().split(' '))
|
|
mapping = ', '.join(map(lambda x: '0x' + x, line[2].strip().split(' ')))
|
|
trailing = ', 0' * (max_mapping_len + 1 - num_mapping_cps)
|
|
zeros = ', 0' * (max_mapping_len)
|
|
print(f''' {{
|
|
{array_t} const expected = {{ {mapping}{trailing} }};
|
|
{array_t} result = {{ 0{zeros} }};
|
|
boost::parser::detail::case_fold(0x{line[0]}, result.begin());
|
|
EXPECT_EQ(result, expected);
|
|
}}''')
|
|
|
|
def print_tests():
|
|
idx = 0
|
|
max_per_TEST = 50
|
|
print(f'TEST(case_folding, hits_{int(idx / max_per_TEST)}) {{')
|
|
for line in lines:
|
|
idx += 1
|
|
if (idx % max_per_TEST) == 0:
|
|
print(f'''}}
|
|
|
|
TEST(case_folding, test_{int(idx / max_per_TEST)}) {{''')
|
|
print_test(line)
|
|
print('}\n')
|
|
|
|
print('''// Copyright (c) 2024 T. Zachary Laine
|
|
//
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
// Warning: This header is auto-generated (see misc/generate_case_fold_tests.py).
|
|
|
|
#include <boost/parser/parser.hpp>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
|
''')
|
|
|
|
print_cps()
|
|
print_tests()
|
|
|
|
print(f'''TEST(case_folding, misses) {{
|
|
char32_t next_cp = 0;
|
|
for (char32_t const * it = cps; it != std::end(cps); ++it) {{
|
|
for (char32_t cp = next_cp; cp < *it; ++cp) {{
|
|
{array_t} const expected = {{ cp, 0 }};
|
|
{array_t} result = {{ 0 }};
|
|
auto const first = result.data();
|
|
auto const last = boost::parser::detail::case_fold(cp, first);
|
|
EXPECT_TRUE(std::equal(first, last, expected.begin()));
|
|
EXPECT_EQ(result, expected);
|
|
}}
|
|
next_cp = *it + 1;
|
|
}}
|
|
}}''')
|