2020-08-16 07:11:40 +02:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
from os import path
|
2020-08-18 02:19:21 +02:00
|
|
|
from os import remove
|
2020-08-19 02:52:52 +02:00
|
|
|
from sys import argv
|
2020-08-16 07:11:40 +02:00
|
|
|
import re
|
|
|
|
from glob import glob
|
|
|
|
|
|
|
|
DIR = path.dirname(__file__)
|
2020-08-20 18:11:03 +02:00
|
|
|
C_FILES = glob(path.join(DIR, "src/*.c"))
|
|
|
|
ASM_FILES = glob(path.join(DIR, "asm/nonmatchings/**/*.s"))
|
2020-08-16 07:11:40 +02:00
|
|
|
|
|
|
|
def strip_c_comments(text):
|
|
|
|
def replacer(match):
|
|
|
|
s = match.group(0)
|
|
|
|
if s.startswith('/'):
|
|
|
|
return " "
|
|
|
|
else:
|
|
|
|
return s
|
|
|
|
pattern = re.compile(
|
|
|
|
r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
|
|
|
|
re.DOTALL | re.MULTILINE
|
|
|
|
)
|
|
|
|
return re.sub(pattern, replacer, text)
|
|
|
|
|
|
|
|
c_func_pattern = re.compile(
|
|
|
|
r"^[^\s]+\s+([^\s(]+)\(([^\n)]*)\)\s+{",
|
|
|
|
re.MULTILINE
|
|
|
|
)
|
|
|
|
def funcs_in_c(text):
|
2020-08-19 03:45:26 +02:00
|
|
|
return (match.group(1) for match in c_func_pattern.finditer(text))
|
|
|
|
|
|
|
|
asm_func_pattern = re.compile(
|
|
|
|
r"INCLUDE_(?:API_)?ASM\([^,]+, ([^,)]+)",
|
|
|
|
re.MULTILINE
|
|
|
|
)
|
|
|
|
def include_asms_in_c(text):
|
|
|
|
return (match.group(1) for match in asm_func_pattern.finditer(text))
|
2020-08-16 07:11:40 +02:00
|
|
|
|
|
|
|
matched = []
|
2020-08-19 03:45:26 +02:00
|
|
|
asm = []
|
2020-08-16 07:11:40 +02:00
|
|
|
for filename in C_FILES:
|
|
|
|
with open(filename, "r") as file:
|
2020-08-19 03:45:26 +02:00
|
|
|
text = strip_c_comments(file.read())
|
|
|
|
matched.extend((m for m in funcs_in_c(text) if not m in matched))
|
|
|
|
asm.extend((m for m in include_asms_in_c(text) if not m in asm))
|
2020-08-16 07:11:40 +02:00
|
|
|
|
|
|
|
non_matched = [path.splitext(path.basename(filename))[0] for filename in ASM_FILES]
|
2020-08-19 03:45:26 +02:00
|
|
|
|
|
|
|
partial_matched = [f for f in matched if f in asm]
|
|
|
|
matched = [f for f in matched if not f in partial_matched]
|
|
|
|
matched_but_undeleted_asm = [f for f in matched if f in non_matched and not f in partial_matched]
|
2020-08-16 07:11:40 +02:00
|
|
|
|
2020-08-19 02:52:52 +02:00
|
|
|
if __name__ == "__main__":
|
|
|
|
if "--help" in argv:
|
|
|
|
print("--fail-matched-undeleted exit with error code 1 if matched function(s) exist in asm/nonmatchings/")
|
|
|
|
print("--delete-matched delete matched function(s) from asm/nonmatchings/ without asking")
|
|
|
|
exit()
|
2020-08-18 02:19:21 +02:00
|
|
|
|
2020-08-19 02:52:52 +02:00
|
|
|
total = len(matched) + len(non_matched)
|
2020-08-19 03:45:26 +02:00
|
|
|
print(f"{len(matched)}+{len(partial_matched)} / {total} functions ({(len(matched) / total) * 100:.2f}% matched)")
|
2020-08-19 02:52:52 +02:00
|
|
|
|
|
|
|
if len(matched_but_undeleted_asm) > 0:
|
|
|
|
print(f"The following functions have been matched but still exist in asm/nonmatchings/: {' '.join(matched_but_undeleted_asm)}")
|
|
|
|
|
|
|
|
if "--fail-matched-undeleted" in argv:
|
|
|
|
exit(1)
|
2020-08-19 03:47:02 +02:00
|
|
|
elif "--delete-matched" in argv or input("Delete them [y/N]? ").upper() == "Y":
|
|
|
|
for func in matched_but_undeleted_asm:
|
|
|
|
file = glob(path.join(DIR, f"../asm/nonmatchings/*/{func}.s"))[0]
|
|
|
|
remove(file)
|
2020-08-19 03:45:26 +02:00
|
|
|
elif len(asm) != len(non_matched):
|
|
|
|
print(f"warning: number of INCLUDE_ASM macros ({len(asm)}) != number of asm files ({len(non_matched)})")
|