blob: 2c0669f551a1666d777ff97d02719f3a29826129 [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)