blob: 01ddd0d626222f22f72de93aa4ef8f08815a4ea9 [file] [log] [blame]
#!/usr/bin/env python
from argparse import ArgumentParser
from logging import basicConfig, DEBUG
from pathlib import Path
def generate(f):
unescaped = 0
print("const EscapeDct::Items EscapeDct::items = {", file=f)
for c in range(0x100):
if c == ord("\\"):
s = "\\\\"
elif c == ord("\b"):
s = "\\b"
elif c == ord("\f"):
s = "\\f"
elif c == ord("\n"):
s = "\\n"
elif c == ord("\r"):
s = "\\r"
elif c == ord("\t"):
s = "\\t"
elif c == ord('"'):
s = '\\"'
elif (c < 0x20) or (c >= 0x7F) or (chr(c) in "'&<>\\"):
s = f"\\u{c:04x}"
else:
s = f"{c:c}"
if c < 128:
unescaped |= 1 << c
t = (
[str(len(s))]
+ [f"'{c}'" if c != "\\" else f"'\\\\'" for c in s]
+ ["0"] * 6
)
l = ", ".join(t[:8])
print(f" {{ {l:35s} }}, /* 0x{c:02x} {chr(c)!r} */", file=f)
print("};", file=f)
escaped = unescaped ^ ((1 << 128) - 1)
print(
f"const std::uint64_t EscapeDct::is_escaped_lo = UINT64_C(0x{(escaped & ((1 << 64) - 1)):016x});",
file=f,
)
print(
f"const std::uint64_t EscapeDct::is_escaped_hi = UINT64_C(0x{(escaped >> 64):016x});",
file=f,
)
argparser = ArgumentParser(description="Generate src/_escape_dct.hpp")
argparser.add_argument(
"input", nargs="?", type=Path, default=Path("src/_escape_dct.hpp")
)
if __name__ == "__main__":
basicConfig(level=DEBUG)
args = argparser.parse_args()
with open(str(args.input.resolve()), "wt") as out:
generate(out)