add optional strings stage
s-ol
1 year, 11 months ago
|
0 |
#!/usr/bin/env python3
|
|
1 |
""" strings.py
|
|
2 |
Replaces literal strings with byte-slices
|
|
3 |
|
|
4 |
>>> from io import StringIO
|
|
5 |
>>> # doctest: +REPORT_NDIFF
|
|
6 |
... print(subv.join_all(strings(StringIO('''
|
|
7 |
... == data 0x80500000
|
|
8 |
... E_MAGIC:
|
|
9 |
... @@/string "Invalid DTB magic!\\\\n\\\\0"
|
|
10 |
... S_TOTALSZ:
|
|
11 |
... @@/string "Total Size: \\\\0"
|
|
12 |
... S_DASH:
|
|
13 |
... @@/string " - \\\\0"
|
|
14 |
... '''[1:-1]))))
|
|
15 |
== data 0x80500000
|
|
16 |
E_MAGIC:
|
|
17 |
49/8 6e/8 76/8 61/8 6c/8 69/8 64/8 20/8 44/8 54/8 42/8 20/8 6d/8 61/8 67/8 69/8 63/8 21/8 a/8 0/8
|
|
18 |
S_TOTALSZ:
|
|
19 |
54/8 6f/8 74/8 61/8 6c/8 20/8 53/8 69/8 7a/8 65/8 3a/8 20/8 0/8
|
|
20 |
S_DASH:
|
|
21 |
20/8 2d/8 20/8 0/8
|
|
22 |
"""
|
|
23 |
|
|
24 |
import subv
|
|
25 |
from ast import literal_eval
|
|
26 |
|
|
27 |
@subv.with_parsed_lines
|
|
28 |
def strings(iter):
|
|
29 |
for segment, line in iter:
|
|
30 |
if line["type"] == "special" and line["special"][0] == ('@@', 'string'):
|
|
31 |
string = literal_eval(line["special"][1])
|
|
32 |
result = {
|
|
33 |
"type": "instr",
|
|
34 |
"instr": [(byte, 8) for byte in string.encode('utf-8')],
|
|
35 |
"comment": None,
|
|
36 |
}
|
|
37 |
|
|
38 |
yield subv.format(result)
|
|
39 |
else:
|
|
40 |
yield line["raw"]
|
|
41 |
|
|
42 |
if __name__ == "__main__":
|
|
43 |
import sys
|
|
44 |
|
|
45 |
for line in strings(sys.stdin):
|
|
46 |
print(line)
|
74 | 74 |
return (parts[1],)
|
75 | 75 |
else:
|
76 | 76 |
raise ValueError("invalid segment line")
|
|
77 |
|
|
78 |
|
|
79 |
def parse_special(line):
|
|
80 |
"""parse a special-line.
|
|
81 |
|
|
82 |
>>> parse_special('@@/test "hello/123 asd"')
|
|
83 |
[('@@', 'test'), '"hello/123 asd"']
|
|
84 |
>>> parse_special('@@/test @@/123 @@/uuu')
|
|
85 |
[('@@', 'test'), '@@/123 @@/uuu']
|
|
86 |
"""
|
|
87 |
parts = white.split(line, maxsplit=1)
|
|
88 |
parts[0] = parse_part(parts[0])
|
|
89 |
return parts
|
77 | 90 |
|
78 | 91 |
|
79 | 92 |
def parse_label(line):
|
|
155 | 168 |
'instr'
|
156 | 169 |
>>> classify('ff/8 0/3 2/5')
|
157 | 170 |
'instr'
|
|
171 |
>>> classify('@@/8')
|
|
172 |
'special'
|
|
173 |
>>> classify('@@/test 123 "asdx"')
|
|
174 |
'special'
|
158 | 175 |
"""
|
159 | 176 |
if line == "":
|
160 | 177 |
return "empty"
|
|
162 | 179 |
return "segment"
|
163 | 180 |
elif line.endswith(":"): # label
|
164 | 181 |
return "label"
|
|
182 |
elif line.startswith("@@/"):
|
|
183 |
return "special"
|
165 | 184 |
else:
|
166 | 185 |
return "instr"
|
167 | 186 |
|
|
184 | 203 |
parsed = parse_label(clean)
|
185 | 204 |
elif type == "instr":
|
186 | 205 |
parsed = parse_instr(clean)
|
|
206 |
elif type == "special":
|
|
207 |
parsed = parse_special(clean)
|
187 | 208 |
else:
|
188 | 209 |
parsed = None
|
189 | 210 |
|
|
323 | 344 |
if line["comment"]:
|
324 | 345 |
packed = packed + " # " + line["comment"]
|
325 | 346 |
return packed
|
326 | |
elif type == "empty":
|
|
347 |
elif type == "empty" or type == "special":
|
327 | 348 |
return line["raw"]
|
328 | 349 |
else:
|
329 | 350 |
raise NotImplementedError("type {}".format(type))
|
19 | 19 |
|
20 | 20 |
msg "OUTPUTTING TO $BASE.*"
|
21 | 21 |
|
|
22 |
msg UNSTRINGING...
|
|
23 |
./strings.py <"$INPUT" >"$BASE.string"
|
22 | 24 |
msg VALIDATING...
|
23 | |
./validate.py <"$INPUT" >"$BASE.valid"
|
|
25 |
./validate.py <"$BASE.string" >"$BASE.valid"
|
24 | 26 |
msg SURVEYING...
|
25 | 27 |
./survey.py <"$BASE.valid" >"$BASE.survey"
|
26 | 28 |
msg FORMATTING...
|