2 Process raw qstr file and output qstr data with length, hash and data bytes. 4 This script works with Python 2.6, 2.7, 3.3 and 3.4. 7 from __future__
import print_function
16 if platform.python_version_tuple()[0] ==
'2':
17 bytes_cons =
lambda val, enc=
None: bytearray(val)
18 from htmlentitydefs
import codepoint2name
19 elif platform.python_version_tuple()[0] ==
'3':
21 from html.entities
import codepoint2name
24 codepoint2name[ord(
'-')] =
'hyphen';
27 codepoint2name[ord(
' ')] =
'space' 28 codepoint2name[ord(
'\'')] =
'squot' 29 codepoint2name[ord(
',')] =
'comma' 30 codepoint2name[ord(
'.')] =
'dot' 31 codepoint2name[ord(
':')] =
'colon' 32 codepoint2name[ord(
';')] =
'semicolon' 33 codepoint2name[ord(
'/')] =
'slash' 34 codepoint2name[ord(
'%')] =
'percent' 35 codepoint2name[ord(
'#')] =
'hash' 36 codepoint2name[ord(
'(')] =
'paren_open' 37 codepoint2name[ord(
')')] =
'paren_close' 38 codepoint2name[ord(
'[')] =
'bracket_open' 39 codepoint2name[ord(
']')] =
'bracket_close' 40 codepoint2name[ord(
'{')] =
'brace_open' 41 codepoint2name[ord(
'}')] =
'brace_close' 42 codepoint2name[ord(
'*')] =
'star' 43 codepoint2name[ord(
'!')] =
'bang' 44 codepoint2name[ord(
'\\')] =
'backslash' 45 codepoint2name[ord(
'+')] =
'plus' 46 codepoint2name[ord(
'$')] =
'dollar' 47 codepoint2name[ord(
'=')] =
'equals' 48 codepoint2name[ord(
'?')] =
'question' 49 codepoint2name[ord(
'@')] =
'at_sign' 50 codepoint2name[ord(
'^')] =
'caret' 51 codepoint2name[ord(
'|')] =
'pipe' 52 codepoint2name[ord(
'~')] =
'tilde' 58 hash = (hash * 33) ^ b
60 return (hash & ((1 << (8 * bytes_hash)) - 1))
or 1
66 name = codepoint2name[c]
69 return "_" + name +
'_' 70 return re.sub(
r'[^A-Za-z0-9_]', esc_char, qst)
76 for infile
in infiles:
77 with open(infile,
'rt')
as f:
82 match = re.match(
r'^QCFG\((.+), (.+)\)', line)
84 value = match.group(2)
85 if value[0] ==
'(' and value[-1] ==
')':
88 qcfgs[match.group(1)] = value
92 match = re.match(
r'^Q\((.*)\)$', line)
117 elif ident.startswith(
"__"):
119 qstrs[ident] = (order, ident, qstr)
122 sys.stderr.write(
"ERROR: Empty preprocessor output - check for errors above\n")
131 if all(32 <= ord(c) <= 126
and c !=
'\\' and c !=
'"' for c
in qstr):
136 qdata =
''.join((
'\\x%02x' % b)
for b
in qbytes)
137 if qlen >= (1 << (8 * cfg_bytes_len)):
138 print(
'qstr is too long:', qstr)
140 qlen_str = (
'\\x%02x' * cfg_bytes_len) % tuple(((qlen >> (8 * i)) & 0xff)
for i
in range(cfg_bytes_len))
141 qhash_str = (
'\\x%02x' * cfg_bytes_hash) % tuple(((qhash >> (8 * i)) & 0xff)
for i
in range(cfg_bytes_hash))
142 return '(const byte*)"%s%s" "%s"' % (qhash_str, qlen_str, qdata)
146 cfg_bytes_len = int(qcfgs[
'BYTES_IN_LEN'])
147 cfg_bytes_hash = int(qcfgs[
'BYTES_IN_HASH'])
150 print(
'// This file was automatically generated by makeqstrdata.py')
154 print(
'QDEF(MP_QSTR_NULL, (const byte*)"%s%s" "")' % (
'\\x00' * cfg_bytes_hash,
'\\x00' * cfg_bytes_len))
157 for order, ident, qstr
in sorted(qstrs.values(), key=
lambda x: x[0]):
158 qbytes =
make_bytes(cfg_bytes_len, cfg_bytes_hash, qstr)
159 print(
'QDEF(MP_QSTR_%s, %s)' % (ident, qbytes))
165 if __name__ ==
"__main__":
def make_bytes(cfg_bytes_len, cfg_bytes_hash, qstr)
def compute_hash(qstr, bytes_hash)
def print_qstr_data(qcfgs, qstrs)
def parse_input_headers(infiles)