#!/usr/bin/env python3 from sys import stdout from pycparser import c_ast, parse_file, c_generator cross_gcc = "/opt/cross-m68k/bin/m68k-none-elf-gcc" gen = c_generator.CGenerator() inc_map = { "int8_t": "stdint.h", "uint8_t": "stdint.h", "int16_t": "stdint.h", "uint16_t": "stdint.h", "int32_t": "stdint.h", "uint32_t": "stdint.h" } 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("reading {} \r".format(path)) stdout.flush() ast = parse_file(path, use_cpp = True, cpp_path = cross_gcc, cpp_args = ["-E", "-I", "include", "-include", "predef.h"]) # ast.show() funs = {} vars = {} incs = set() for ext in ast.ext: # assumes that includes come before .c files in c-files.txt, i.e., # that we've already seen the .h file, when its declarations are used # by a .c file. if ext.coord.file == path and path[-2:] == ".h": if type(ext) is c_ast.Decl and \ type(ext.type) is c_ast.Struct: inc_map[ext.type.name] = path.split("/")[-1] continue if type(ext) is c_ast.Decl and \ (type(ext.type) is c_ast.TypeDecl or \ type(ext.type) is c_ast.PtrDecl or \ type(ext.type) is c_ast.ArrayDecl): decl = ext map = vars elif type(ext) is c_ast.FuncDef: decl = ext.decl map = funs else: continue if "extern" in decl.storage or \ "static" in decl.storage: continue decl.storage = ["extern"] decl.init = None toks = gen.visit(decl).split(" ") for tok in toks: if tok in inc_map: incs.add(inc_map[tok]) alig = "" alig += toks[0] + "\t" toks = toks[1:] if toks[0] == "struct": if len(toks[1]) > 7: raise Exception("identifier too long: {}".format(toks[1])) alig += toks[0] + "\t" + toks[1] + "\t" toks = toks[2:] else: alig += toks[0] + ("\t\t" if len(toks[0]) < 8 else "\t") toks = toks[1:] map[decl.name] = alig + " ".join(toks) + ";" file = path.split("/")[-1] glob = [] if len(vars) > 0: glob.append("/*") glob.append(" =============================================================================") glob.append("\t" + file + " -- global variables") glob.append(" =============================================================================") glob.append("*/") glob.append("") for _, out in sorted(vars.items()): glob.append(out) glob.append("") if len(funs) > 0: glob.append("/*") glob.append(" =============================================================================") glob.append("\t" + file + " -- global functions") glob.append(" =============================================================================") glob.append("*/") glob.append("") for _, out in sorted(funs.items()): glob.append(out) glob.append("") if len(glob) == 0: continue head = [] head.append("#pragma once") head.append("") if len(incs) > 0: for inc in sorted(incs): head.append("#include \"{}\"".format(inc)) head.append("") glob = head + glob with open(path[:-2] + ".x", "w") as f: print("\n".join(glob), file = f) print("")