1 | #!/usr/bin/env python3
|
---|
2 |
|
---|
3 | from sys import stdout
|
---|
4 | from os import unlink
|
---|
5 | from pycparser import c_ast, parse_file
|
---|
6 | from re import escape, subn
|
---|
7 |
|
---|
8 | cross_gcc = "/opt/cross-m68k/bin/m68k-none-elf-gcc"
|
---|
9 |
|
---|
10 | class Visitor(c_ast.NodeVisitor):
|
---|
11 | def reset(self):
|
---|
12 | self.path = None
|
---|
13 | self.orig = None
|
---|
14 | self.subst = None
|
---|
15 |
|
---|
16 | def __init__(self):
|
---|
17 | self.reset()
|
---|
18 |
|
---|
19 | def visit_IdentifierType(self, node):
|
---|
20 | if node.coord.file != self.path or self.subst is not None:
|
---|
21 | return
|
---|
22 |
|
---|
23 | new = None
|
---|
24 |
|
---|
25 | if node.names == ["char"]:
|
---|
26 | new = "int8_t"
|
---|
27 |
|
---|
28 | elif node.names == ["unsigned", "char"]:
|
---|
29 | new = "uint8_t"
|
---|
30 |
|
---|
31 | elif node.names == ["short"] or \
|
---|
32 | node.names == ["int"]:
|
---|
33 | new = "int16_t"
|
---|
34 | elif node.names == ["unsigned", "short"] or \
|
---|
35 | node.names == ["unsigned", "int"] or \
|
---|
36 | node.names == ["unsigned"] or \
|
---|
37 | node.names == ["uint"] or \
|
---|
38 | node.names == ["UWORD16"]:
|
---|
39 | new = "uint16_t"
|
---|
40 |
|
---|
41 | elif node.names == ["long"]:
|
---|
42 | new = "int32_t"
|
---|
43 |
|
---|
44 | elif node.names == ["unsigned", "long"]:
|
---|
45 | new = "uint32_t"
|
---|
46 |
|
---|
47 | elif node.names == ["void"] or \
|
---|
48 | node.names == ["int8_t"] or \
|
---|
49 | node.names == ["uint8_t"] or \
|
---|
50 | node.names == ["int16_t"] or \
|
---|
51 | node.names == ["uint16_t"] or \
|
---|
52 | node.names == ["int32_t"] or \
|
---|
53 | node.names == ["uint32_t"] or \
|
---|
54 | node.names == ["va_list"] or \
|
---|
55 | node.names == ["jmp_buf"] or \
|
---|
56 | node.names == ["BOOL"] or \
|
---|
57 | node.names == ["FILE"] or \
|
---|
58 | node.names == ["io_arg"] or \
|
---|
59 | node.names == ["LPF"]:
|
---|
60 | pass
|
---|
61 |
|
---|
62 | else:
|
---|
63 | raise Exception("unknown type: {}".format(node.names))
|
---|
64 |
|
---|
65 | if new is None:
|
---|
66 | self.generic_visit(node)
|
---|
67 | return
|
---|
68 |
|
---|
69 | self.subst = (node.coord.line, node.names, new)
|
---|
70 |
|
---|
71 | def get_ast(self):
|
---|
72 | with open(self.path, "w") as f:
|
---|
73 | f.write(self.orig)
|
---|
74 |
|
---|
75 | ast = parse_file(self.path, use_cpp = True, cpp_path = cross_gcc,
|
---|
76 | cpp_args = ["-E", "-I", "include", "-include", "predef.h"])
|
---|
77 | # ast.show()
|
---|
78 |
|
---|
79 | unlink(self.path)
|
---|
80 | return ast
|
---|
81 |
|
---|
82 | def fix(self, path, orig):
|
---|
83 | self.path = path
|
---|
84 | self.orig = orig
|
---|
85 |
|
---|
86 | while True:
|
---|
87 | self.visit(self.get_ast())
|
---|
88 |
|
---|
89 | if self.subst is None:
|
---|
90 | break
|
---|
91 |
|
---|
92 | lines = self.orig.split("\n")
|
---|
93 | (line, old, new) = self.subst
|
---|
94 |
|
---|
95 | beg = line - 3 if line > 3 else 0
|
---|
96 | end = line + 2 if line < len(lines) - 2 else len(lines)
|
---|
97 |
|
---|
98 | focus = "\n".join(lines[beg : end])
|
---|
99 |
|
---|
100 | old_re = "[\t ]".join([escape(x) for x in old]) + "([\t \)])"
|
---|
101 | (focus, n) = subn(old_re, new + "\g<1>", focus, 1)
|
---|
102 |
|
---|
103 | if n != 1:
|
---|
104 | print(focus)
|
---|
105 | raise Exception("error while replacing {} with {} in {}:{}". \
|
---|
106 | format(old_re, new, self.path, line))
|
---|
107 |
|
---|
108 | self.orig = "\n".join(lines[: beg]) + \
|
---|
109 | "\n" + focus + "\n" + \
|
---|
110 | "\n".join(lines[end :])
|
---|
111 | self.subst = None
|
---|
112 |
|
---|
113 | fixed = self.orig
|
---|
114 | self.reset()
|
---|
115 | return fixed
|
---|
116 |
|
---|
117 | vis = Visitor()
|
---|
118 |
|
---|
119 | with open("misc/c-files.txt", "r") as f:
|
---|
120 | for path in f:
|
---|
121 | path = path.rstrip()
|
---|
122 |
|
---|
123 | if path == "ram/wdfield.c": # breaks pycparser
|
---|
124 | continue
|
---|
125 |
|
---|
126 | stdout.write("fixing {} \r".format(path))
|
---|
127 | stdout.flush()
|
---|
128 |
|
---|
129 | with open(path, "r") as f:
|
---|
130 | orig = f.read()
|
---|
131 |
|
---|
132 | segs = path.split("/")
|
---|
133 | path_ = "/".join(segs[:-1] + ["_" + segs[-1]])
|
---|
134 |
|
---|
135 | fixed = vis.fix(path_, orig)
|
---|
136 |
|
---|
137 | with open(path, "w") as f:
|
---|
138 | f.write(fixed)
|
---|
139 |
|
---|
140 | print("")
|
---|