mirror of
https://github.com/GayPizzaSpecifications/padlab.git
synced 2025-08-03 05:10:56 +00:00
128 lines
2.7 KiB
Python
128 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
from typing import BinaryIO, TextIO
|
|
from os import SEEK_SET, SEEK_END
|
|
import re
|
|
|
|
|
|
label_invalid = re.compile(r"\W") # Turn invalid label chars into underscores
|
|
label_lstrip = re.compile(r"^[\d_]+") # Trim all underscores or numbers from the beginning
|
|
|
|
|
|
def sanitise_label(label: str) -> str:
|
|
tmp = label_invalid.sub("_", label, re.I)
|
|
return label_lstrip.sub("", tmp, re.I)
|
|
|
|
|
|
def bin2h(name: str, binf: BinaryIO, h: TextIO):
|
|
label = sanitise_label(name)
|
|
|
|
binf.seek(0, SEEK_END)
|
|
length = binf.tell()
|
|
binf.seek(0, SEEK_SET)
|
|
h.write(f"#define {label.upper()}_SIZE {length}\n")
|
|
|
|
whitespace = "\t"
|
|
h.write(f"static const unsigned char {label}[{length}] = {{\n{whitespace}")
|
|
|
|
for i, c in enumerate(binf.read()):
|
|
if i != 0:
|
|
h.write(", ")
|
|
if i % 16 == 0:
|
|
h.write(f"\n{whitespace}")
|
|
h.write(f"0x{c:02X}")
|
|
|
|
h.write("\n};\n")
|
|
|
|
|
|
def txt2h(name: str, txt: TextIO, h: TextIO):
|
|
h.write(f"static const char* const {sanitise_label(name)} = \n")
|
|
h.write("\"")
|
|
|
|
remap = {
|
|
"\a": "\\a", "\b": "\\b", "\f": "\\f", "\n": "\\n", "\r": "\\r",
|
|
"\t": "\\t", "\v": "\\v", "\\": "\\\\", "\"": "\\\""}
|
|
esc_numeric = False
|
|
for idx, c in enumerate(txt.read()):
|
|
if m := remap.get(c):
|
|
h.write(m)
|
|
else:
|
|
if (i := ord(c)) < 0x7F:
|
|
if c.isprintable() and not (esc_numeric and c.isnumeric()):
|
|
h.write(c)
|
|
else:
|
|
if i < 8:
|
|
h.write(f"\\{i:o}")
|
|
else:
|
|
h.write(f"\\x{i:02X}")
|
|
esc_numeric = True
|
|
continue
|
|
elif i < 0x10000:
|
|
h.write(f"\\u{i:04X}")
|
|
else:
|
|
h.write(f"\\U{i:08X}")
|
|
esc_numeric = False
|
|
|
|
h.write("\";\n")
|
|
|
|
|
|
def main():
|
|
usage = "Usage [-b data.bin] [-t text.txt] <out.h>"
|
|
|
|
binfiles = []
|
|
txtfiles = []
|
|
out = None
|
|
opt = None
|
|
for arg in sys.argv[1:]:
|
|
if opt is not None:
|
|
if opt == "b":
|
|
binfiles.append(arg)
|
|
elif opt == "t":
|
|
txtfiles.append(arg)
|
|
else:
|
|
sys.exit(usage)
|
|
opt = None
|
|
if arg.startswith("-"):
|
|
opt = arg[1:]
|
|
else:
|
|
out = Path(arg)
|
|
|
|
if opt is not None or out is None:
|
|
sys.exit(usage)
|
|
if len(binfiles) == 0 and len(txtfiles) == 0:
|
|
sys.exit(usage)
|
|
|
|
with out.open("w") as h:
|
|
guard = f"BIN2H_{sanitise_label(out.name).upper()}"
|
|
if not guard.endswith("_H"):
|
|
guard += "_H"
|
|
h.writelines([
|
|
"/*DO NOT EDIT*/\n",
|
|
"// Autogenerated by bin2h\n",
|
|
"\n",
|
|
f"#ifndef {guard}\n",
|
|
f"#define {guard}\n",
|
|
"\n"])
|
|
|
|
# Write binaries
|
|
for i in binfiles:
|
|
path = Path(i)
|
|
with path.open("rb") as file:
|
|
bin2h(path.name, file, h)
|
|
h.write("\n")
|
|
|
|
# Write texts
|
|
for i in txtfiles:
|
|
path = Path(i)
|
|
with path.open("r") as file:
|
|
txt2h(path.name, file, h)
|
|
h.write("\n")
|
|
|
|
h.write(f"#endif//{guard}\n")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|