source: buchla-68k/misc/fix-types.py@ 411371e

Last change on this file since 411371e was 7258c6a, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Use standard integer types.

  • Property mode set to 100755
File size: 3.8 KB
Line 
1#!/usr/bin/env python3
2
3from sys import stdout
4from os import unlink
5from pycparser import c_ast, parse_file
6from re import escape, subn
7
8cross_gcc = "/opt/cross-m68k/bin/m68k-none-elf-gcc"
9
10class 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
117vis = Visitor()
118
119with 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("")
Note: See TracBrowser for help on using the repository browser.