#!/usr/bin/env python3 from sys import stdout from pickle import dump from pycparser import c_ast, parse_file cross_gcc = "/opt/cross-m68k/bin/m68k-none-elf-gcc" class Visitor(c_ast.NodeVisitor): def __init__(self): self.path = None self.void = True self.proto = [] def visit_Return(self, node): if node.expr is not None: self.void = False self.generic_visit(node) def visit_Decl(self, node): node.storage = [x for x in node.storage if x != "register" and x != "static" and x != "extern"] self.generic_visit(node) def visit_FuncDef(self, node): if node.coord.file != self.path: return self.generic_visit(node) # Convert K&R parameter declarations to ANSI. if node.param_decls is not None: node.decl.type.args.params = node.param_decls node.param_decls = None # Turn "foobar()" into "foobar(void)". if node.decl.type.args is None: node.decl.type.args = c_ast.Typename(None, [], c_ast.TypeDecl(None, [], c_ast.ID("void"))) # Override default int type, if necessary. if self.void: node.decl.type.type.type = c_ast.ID("void") self.proto.append(node.decl) self.void = True def visit_path(self, path, ast): self.path = path self.visit(ast) self.path = None def store_proto(self, path): with open(path, "wb") as f: dump(self.proto, f) path_ast = [] with open("misc/c-files.txt", "r") as f: for path in f: path = path.rstrip() if path == "ram/wdfield.c": # breaks pycparser continue stdout.write("parsing {} \r".format(path)) stdout.flush() ast = parse_file(path, use_cpp = True, cpp_path = cross_gcc, cpp_args = ["-E", "-I", "include", "-include", "predef.h"]) path_ast.append((path, ast)) # ast.show() print("") vis = Visitor() for (path, ast) in path_ast: stdout.write("visiting {} \r".format(path)) stdout.flush() vis.visit_path(path, ast) print("") vis.store_proto("proto.dat")