mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-23 14:58:09 +00:00
135 lines
3.5 KiB
Python
Executable File
135 lines
3.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import glob
|
|
import os
|
|
import re
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
|
|
CORE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
|
EXTMOD_PATH = os.path.join(CORE_DIR, "embed", "extmod")
|
|
MOCKS_PATH = os.path.join(CORE_DIR, "mocks", "generated")
|
|
|
|
COMMENT_PREFIX = "/// "
|
|
|
|
current_indent = 0
|
|
current_class = None
|
|
current_method = None
|
|
current_package = None
|
|
|
|
|
|
def split_to_parts(line, mod_desc=None):
|
|
global current_indent
|
|
global current_class
|
|
global current_method
|
|
global current_package
|
|
|
|
if line.startswith("package: "):
|
|
current_package = line[9:].strip()
|
|
return
|
|
|
|
if line.startswith("mock:global"):
|
|
current_indent = 0
|
|
current_class = None
|
|
return
|
|
|
|
if line.startswith("class "):
|
|
current_class = line[6:].split("(")[0].strip(":")
|
|
current_indent = 0
|
|
|
|
yield (current_package, "\n\n")
|
|
yield (current_package, "# " + mod_desc + "\n")
|
|
|
|
elif line.startswith("def "):
|
|
current_method = line[4:].split("(")[0]
|
|
|
|
if current_class is None:
|
|
yield (current_package, "\n\n")
|
|
yield (current_package, "# " + mod_desc + "\n")
|
|
else:
|
|
yield (current_package, "\n")
|
|
current_indent = 4
|
|
|
|
line = current_indent * " " + line
|
|
|
|
yield (current_package, line)
|
|
|
|
|
|
def store_to_file(dest, parts):
|
|
for package, line in parts:
|
|
package = package.replace(".", "/")
|
|
dirpath = os.path.join(dest, os.path.dirname(package))
|
|
filename = os.path.basename(package) + ".pyi"
|
|
filepath = os.path.join(dirpath, filename)
|
|
|
|
os.makedirs(dirpath, exist_ok=True)
|
|
|
|
if os.path.isdir(os.path.join(dest, package)):
|
|
if not line.strip():
|
|
continue
|
|
print("Package exists: {}".format(package))
|
|
print("You should set 'package:' in {}".format(line.strip()))
|
|
sys.exit(1)
|
|
|
|
if not os.path.exists(filepath):
|
|
with open(filepath, "a") as f:
|
|
f.write("from typing import *\n")
|
|
|
|
with open(filepath, "a") as f:
|
|
f.write(line)
|
|
|
|
|
|
def build_module(mod_file, dest):
|
|
global current_indent
|
|
global current_class
|
|
global current_package
|
|
|
|
filename = os.path.basename(mod_file)
|
|
assert filename.startswith("mod")
|
|
assert filename.endswith(".c") or filename.endswith(".h")
|
|
# modfoobar-xyz.h -> foobar-xyz
|
|
name = filename[3:-2]
|
|
|
|
current_indent = 0
|
|
current_class = None
|
|
current_package = name.split("-")[0]
|
|
mod_desc = re.sub(r"^.*/embed/", "", mod_file)
|
|
|
|
for l in open(mod_file):
|
|
if not l.startswith(COMMENT_PREFIX):
|
|
continue
|
|
|
|
l = l[len(COMMENT_PREFIX) :] # .strip()
|
|
store_to_file(dest, split_to_parts(l, mod_desc))
|
|
|
|
|
|
def build_directory(src, dest):
|
|
for modfile in sorted(glob.glob(os.path.join(src, "**", "mod*.[ch]"))):
|
|
build_module(modfile, dest)
|
|
|
|
|
|
def do_check():
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
build_directory(EXTMOD_PATH, tmpdir)
|
|
diff_out = subprocess.run(
|
|
["diff", "-ur", MOCKS_PATH, tmpdir],
|
|
stdout=subprocess.PIPE,
|
|
universal_newlines=True,
|
|
).stdout
|
|
if diff_out.strip():
|
|
print(diff_out, end="")
|
|
sys.exit(1)
|
|
|
|
|
|
def do_generate():
|
|
shutil.rmtree(MOCKS_PATH)
|
|
build_directory(EXTMOD_PATH, MOCKS_PATH)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) > 1 and sys.argv[1] == "--check":
|
|
do_check()
|
|
else:
|
|
do_generate()
|