#!/usr/bin/env python3 from sys import stdout from os import unlink from pycparser import c_ast, parse_file from re import escape, subn cross_gcc = "/opt/cross-m68k/bin/m68k-none-elf-gcc" class Visitor(c_ast.NodeVisitor): def reset(self): self.path = None self.orig = None self.subst = None def __init__(self): self.reset() def visit_IdentifierType(self, node): if node.coord.file != self.path or self.subst is not None: return new = None if node.names == ["char"]: new = "int8_t" elif node.names == ["unsigned", "char"]: new = "uint8_t" elif node.names == ["short"] or \ node.names == ["int"]: new = "int16_t" elif node.names == ["unsigned", "short"] or \ node.names == ["unsigned", "int"] or \ node.names == ["unsigned"] or \ node.names == ["uint"] or \ node.names == ["UWORD16"]: new = "uint16_t" elif node.names == ["long"]: new = "int32_t" elif node.names == ["unsigned", "long"]: new = "uint32_t" elif node.names == ["void"] or \ node.names == ["int8_t"] or \ node.names == ["uint8_t"] or \ node.names == ["int16_t"] or \ node.names == ["uint16_t"] or \ node.names == ["int32_t"] or \ node.names == ["uint32_t"] or \ node.names == ["va_list"] or \ node.names == ["jmp_buf"] or \ node.names == ["BOOL"] or \ node.names == ["FILE"] or \ node.names == ["io_arg"] or \ node.names == ["LPF"]: pass else: raise Exception("unknown type: {}".format(node.names)) if new is None: self.generic_visit(node) return self.subst = (node.coord.line, node.names, new) def get_ast(self): with open(self.path, "w") as f: f.write(self.orig) ast = parse_file(self.path, use_cpp = True, cpp_path = cross_gcc, cpp_args = ["-E", "-I", "include", "-include", "predef.h"]) # ast.show() unlink(self.path) return ast def fix(self, path, orig): self.path = path self.orig = orig while True: self.visit(self.get_ast()) if self.subst is None: break lines = self.orig.split("\n") (line, old, new) = self.subst beg = line - 3 if line > 3 else 0 end = line + 2 if line < len(lines) - 2 else len(lines) focus = "\n".join(lines[beg : end]) old_re = "[\t ]".join([escape(x) for x in old]) + "([\t \)])" (focus, n) = subn(old_re, new + "\g<1>", focus, 1) if n != 1: print(focus) raise Exception("error while replacing {} with {} in {}:{}". \ format(old_re, new, self.path, line)) self.orig = "\n".join(lines[: beg]) + \ "\n" + focus + "\n" + \ "\n".join(lines[end :]) self.subst = None fixed = self.orig self.reset() return fixed vis = Visitor() 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("fixing {} \r".format(path)) stdout.flush() with open(path, "r") as f: orig = f.read() segs = path.split("/") path_ = "/".join(segs[:-1] + ["_" + segs[-1]]) fixed = vis.fix(path_, orig) with open(path, "w") as f: f.write(fixed) print("")