a71c83a1d1
Ultimately all static strings should be qstr. This entry in the type structure is only used for printing error messages (to tell the type of the bad argument), and printing objects that don't supply a .print method.
74 lines
2.5 KiB
Python
74 lines
2.5 KiB
Python
import argparse
|
|
import re
|
|
|
|
# codepoint2name is different in Python 2 to Python 3
|
|
import platform
|
|
if platform.python_version_tuple()[0] == '2':
|
|
from htmlentitydefs import codepoint2name
|
|
elif platform.python_version_tuple()[0] == '3':
|
|
from html.entities import codepoint2name
|
|
|
|
# add some custom names to map characters that aren't in HTML
|
|
codepoint2name[ord('.')] = 'dot'
|
|
|
|
# this must match the equivalent function in qstr.c
|
|
def compute_hash(qstr):
|
|
hash = 0
|
|
for char in qstr:
|
|
hash += ord(char)
|
|
return hash & 0xffff
|
|
|
|
def do_work(infiles):
|
|
# read the qstrs in from the input files
|
|
qstrs = {}
|
|
for infile in infiles:
|
|
with open(infile, 'rt') as f:
|
|
line_number = 0
|
|
for line in f:
|
|
line_number += 1
|
|
line = line.strip()
|
|
|
|
# ignore blank lines and comments
|
|
if len(line) == 0 or line.startswith('//'):
|
|
continue
|
|
|
|
# verify line is of the correct form
|
|
match = re.match(r'Q\((.+)\)$', line)
|
|
if not match:
|
|
print('({}:{}) bad qstr format, got {}'.format(infile, line_number, line))
|
|
return False
|
|
|
|
# get the qstr value
|
|
qstr = match.group(1)
|
|
ident = re.sub(r'[^A-Za-z0-9_]', lambda s: "_" + codepoint2name[ord(s.group(0))] + "_", qstr)
|
|
|
|
# don't add duplicates
|
|
if ident in qstrs:
|
|
continue
|
|
|
|
# add the qstr to the list, with order number to retain original order in file
|
|
qstrs[ident] = (len(qstrs), ident, qstr)
|
|
|
|
# process the qstrs, printing out the generated C header file
|
|
print('// This file was automatically generated by makeqstrdata.py')
|
|
print('')
|
|
for order, ident, qstr in sorted(qstrs.values(), key=lambda x: x[0]):
|
|
qhash = compute_hash(qstr)
|
|
qlen = len(qstr)
|
|
print('Q({}, (const byte*)"\\x{:02x}\\x{:02x}\\x{:02x}\\x{:02x}" "{}")'.format(ident, qhash & 0xff, (qhash >> 8) & 0xff, qlen & 0xff, (qlen >> 8) & 0xff, qstr))
|
|
|
|
return True
|
|
|
|
def main():
|
|
arg_parser = argparse.ArgumentParser(description='Process raw qstr file and output qstr data with length, hash and data bytes')
|
|
arg_parser.add_argument('files', nargs='+', help='input file(s)')
|
|
args = arg_parser.parse_args()
|
|
|
|
result = do_work(args.files)
|
|
if not result:
|
|
print('exiting with error code')
|
|
exit(1)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|