mirror of
https://github.com/open-goal/jak-project
synced 2026-05-26 07:39:12 -04:00
60db0e5ef9
This updates `fmt` to the latest version and moves to just being a copy of their repo to make updating easier (no editing their cmake / figuring out which files to minimally include). The motivation for this is now that we switched to C++ 20, there were a ton of deprecated function usages that is going away in future compiler versions. This gets rid of all those warnings.
202 lines
6.0 KiB
Python
Vendored
Generated
202 lines
6.0 KiB
Python
Vendored
Generated
#!/usr/bin/env python3
|
|
|
|
# This script is based on
|
|
# https://github.com/rust-lang/rust/blob/master/library/core/src/unicode/printable.py
|
|
# distributed under https://github.com/rust-lang/rust/blob/master/LICENSE-MIT.
|
|
|
|
# This script uses the following Unicode tables:
|
|
# - UnicodeData.txt
|
|
|
|
|
|
from collections import namedtuple
|
|
import csv
|
|
import os
|
|
import subprocess
|
|
|
|
NUM_CODEPOINTS=0x110000
|
|
|
|
def to_ranges(iter):
|
|
current = None
|
|
for i in iter:
|
|
if current is None or i != current[1] or i in (0x10000, 0x20000):
|
|
if current is not None:
|
|
yield tuple(current)
|
|
current = [i, i + 1]
|
|
else:
|
|
current[1] += 1
|
|
if current is not None:
|
|
yield tuple(current)
|
|
|
|
def get_escaped(codepoints):
|
|
for c in codepoints:
|
|
if (c.class_ or "Cn") in "Cc Cf Cs Co Cn Zl Zp Zs".split() and c.value != ord(' '):
|
|
yield c.value
|
|
|
|
def get_file(f):
|
|
try:
|
|
return open(os.path.basename(f))
|
|
except FileNotFoundError:
|
|
subprocess.run(["curl", "-O", f], check=True)
|
|
return open(os.path.basename(f))
|
|
|
|
Codepoint = namedtuple('Codepoint', 'value class_')
|
|
|
|
def get_codepoints(f):
|
|
r = csv.reader(f, delimiter=";")
|
|
prev_codepoint = 0
|
|
class_first = None
|
|
for row in r:
|
|
codepoint = int(row[0], 16)
|
|
name = row[1]
|
|
class_ = row[2]
|
|
|
|
if class_first is not None:
|
|
if not name.endswith("Last>"):
|
|
raise ValueError("Missing Last after First")
|
|
|
|
for c in range(prev_codepoint + 1, codepoint):
|
|
yield Codepoint(c, class_first)
|
|
|
|
class_first = None
|
|
if name.endswith("First>"):
|
|
class_first = class_
|
|
|
|
yield Codepoint(codepoint, class_)
|
|
prev_codepoint = codepoint
|
|
|
|
if class_first is not None:
|
|
raise ValueError("Missing Last after First")
|
|
|
|
for c in range(prev_codepoint + 1, NUM_CODEPOINTS):
|
|
yield Codepoint(c, None)
|
|
|
|
def compress_singletons(singletons):
|
|
uppers = [] # (upper, # items in lowers)
|
|
lowers = []
|
|
|
|
for i in singletons:
|
|
upper = i >> 8
|
|
lower = i & 0xff
|
|
if len(uppers) == 0 or uppers[-1][0] != upper:
|
|
uppers.append((upper, 1))
|
|
else:
|
|
upper, count = uppers[-1]
|
|
uppers[-1] = upper, count + 1
|
|
lowers.append(lower)
|
|
|
|
return uppers, lowers
|
|
|
|
def compress_normal(normal):
|
|
# lengths 0x00..0x7f are encoded as 00, 01, ..., 7e, 7f
|
|
# lengths 0x80..0x7fff are encoded as 80 80, 80 81, ..., ff fe, ff ff
|
|
compressed = [] # [truelen, (truelenaux), falselen, (falselenaux)]
|
|
|
|
prev_start = 0
|
|
for start, count in normal:
|
|
truelen = start - prev_start
|
|
falselen = count
|
|
prev_start = start + count
|
|
|
|
assert truelen < 0x8000 and falselen < 0x8000
|
|
entry = []
|
|
if truelen > 0x7f:
|
|
entry.append(0x80 | (truelen >> 8))
|
|
entry.append(truelen & 0xff)
|
|
else:
|
|
entry.append(truelen & 0x7f)
|
|
if falselen > 0x7f:
|
|
entry.append(0x80 | (falselen >> 8))
|
|
entry.append(falselen & 0xff)
|
|
else:
|
|
entry.append(falselen & 0x7f)
|
|
|
|
compressed.append(entry)
|
|
|
|
return compressed
|
|
|
|
def print_singletons(uppers, lowers, uppersname, lowersname):
|
|
print(" static constexpr singleton {}[] = {{".format(uppersname))
|
|
for u, c in uppers:
|
|
print(" {{{:#04x}, {}}},".format(u, c))
|
|
print(" };")
|
|
print(" static constexpr unsigned char {}[] = {{".format(lowersname))
|
|
for i in range(0, len(lowers), 8):
|
|
print(" {}".format(" ".join("{:#04x},".format(l) for l in lowers[i:i+8])))
|
|
print(" };")
|
|
|
|
def print_normal(normal, normalname):
|
|
print(" static constexpr unsigned char {}[] = {{".format(normalname))
|
|
for v in normal:
|
|
print(" {}".format(" ".join("{:#04x},".format(i) for i in v)))
|
|
print(" };")
|
|
|
|
def main():
|
|
file = get_file("https://www.unicode.org/Public/UNIDATA/UnicodeData.txt")
|
|
|
|
codepoints = get_codepoints(file)
|
|
|
|
CUTOFF=0x10000
|
|
singletons0 = []
|
|
singletons1 = []
|
|
normal0 = []
|
|
normal1 = []
|
|
extra = []
|
|
|
|
for a, b in to_ranges(get_escaped(codepoints)):
|
|
if a > 2 * CUTOFF:
|
|
extra.append((a, b - a))
|
|
elif a == b - 1:
|
|
if a & CUTOFF:
|
|
singletons1.append(a & ~CUTOFF)
|
|
else:
|
|
singletons0.append(a)
|
|
elif a == b - 2:
|
|
if a & CUTOFF:
|
|
singletons1.append(a & ~CUTOFF)
|
|
singletons1.append((a + 1) & ~CUTOFF)
|
|
else:
|
|
singletons0.append(a)
|
|
singletons0.append(a + 1)
|
|
else:
|
|
if a >= 2 * CUTOFF:
|
|
extra.append((a, b - a))
|
|
elif a & CUTOFF:
|
|
normal1.append((a & ~CUTOFF, b - a))
|
|
else:
|
|
normal0.append((a, b - a))
|
|
|
|
singletons0u, singletons0l = compress_singletons(singletons0)
|
|
singletons1u, singletons1l = compress_singletons(singletons1)
|
|
normal0 = compress_normal(normal0)
|
|
normal1 = compress_normal(normal1)
|
|
|
|
print("""\
|
|
FMT_FUNC auto is_printable(uint32_t cp) -> bool {\
|
|
""")
|
|
print_singletons(singletons0u, singletons0l, 'singletons0', 'singletons0_lower')
|
|
print_singletons(singletons1u, singletons1l, 'singletons1', 'singletons1_lower')
|
|
print_normal(normal0, 'normal0')
|
|
print_normal(normal1, 'normal1')
|
|
print("""\
|
|
auto lower = static_cast<uint16_t>(cp);
|
|
if (cp < 0x10000) {
|
|
return is_printable(lower, singletons0,
|
|
sizeof(singletons0) / sizeof(*singletons0),
|
|
singletons0_lower, normal0, sizeof(normal0));
|
|
}
|
|
if (cp < 0x20000) {
|
|
return is_printable(lower, singletons1,
|
|
sizeof(singletons1) / sizeof(*singletons1),
|
|
singletons1_lower, normal1, sizeof(normal1));
|
|
}\
|
|
""")
|
|
for a, b in extra:
|
|
print(" if (0x{:x} <= cp && cp < 0x{:x}) return false;".format(a, a + b))
|
|
print("""\
|
|
return cp < 0x{:x};
|
|
}}\
|
|
""".format(NUM_CODEPOINTS))
|
|
|
|
if __name__ == '__main__':
|
|
main()
|