pycparser kan met een beetje "masseren" de C opdrachten parsen. Onderstaande vind de main functie in een C bestand.
import check50.internal
from pycparser import c_ast, parse_file, c_generator
def get_main(filename: str) -> c_ast.FuncDef | None:
main = None
class FuncDefVisitor(c_ast.NodeVisitor):
def visit_FuncDef(self, node):
if node.decl.name == "main":
nonlocal main
main = node
fake_libc_include = check50.internal.check_dir.parent / "fake_libc_include"
ast = parse_file(
filename,
use_cpp=True,
cpp_path='clang',
cpp_args=[
'-E', # preprocess using clang
'-nostdinc', # strictly use fake libc
'-D__attribute__(x)=', # pycparser does not support __attribute__, so delete
f'-I{fake_libc_include}' # include fake libc (just typedefs and headers)
]
)
visitor = FuncDefVisitor()
visitor.visit(ast)
return main
Bijvoorbeeld
>>> print(get_main("functions.c").coord)
functions.c:8:5
fake_libc_include is nodig om libc te spoofen. In bovenstaande voorbeeld staat deze map direct naast de checks, vandaar check50.internal.check_dir.parent / "fake_libc_include"
pycparser kan met een beetje "masseren" de C opdrachten parsen. Onderstaande vind de main functie in een C bestand.
Bijvoorbeeld