source: buchla-68k/misc/gen-glob.py@ 6262b5c

Last change on this file since 6262b5c was 6262b5c, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Added include files for global functions and variables.

  • Property mode set to 100755
File size: 4.0 KB
Line 
1#!/usr/bin/env python3
2
3from sys import stdout
4from pycparser import c_ast, parse_file, c_generator
5
6cross_gcc = "/opt/cross-m68k/bin/m68k-none-elf-gcc"
7gen = c_generator.CGenerator()
8
9inc_map = {
10 "int8_t": "stdint.h",
11 "uint8_t": "stdint.h",
12 "int16_t": "stdint.h",
13 "uint16_t": "stdint.h",
14 "int32_t": "stdint.h",
15 "uint32_t": "stdint.h"
16}
17
18with open("misc/c-files.txt", "r") as f:
19 for path in f:
20 path = path.rstrip()
21
22 if path == "ram/wdfield.c": # breaks pycparser
23 continue
24
25 stdout.write("reading {} \r".format(path))
26 stdout.flush()
27
28 ast = parse_file(path, use_cpp = True, cpp_path = cross_gcc,
29 cpp_args = ["-E", "-I", "include", "-include", "predef.h"])
30 # ast.show()
31
32 funs = {}
33 vars = {}
34 incs = set()
35
36 for ext in ast.ext:
37 # assumes that includes come before .c files in c-files.txt, i.e.,
38 # that we've already seen the .h file, when its declarations are used
39 # by a .c file.
40
41 if ext.coord.file == path and path[-2:] == ".h":
42 if type(ext) is c_ast.Decl and \
43 type(ext.type) is c_ast.Struct:
44 inc_map[ext.type.name] = path.split("/")[-1]
45 continue
46
47 if type(ext) is c_ast.Decl and \
48 (type(ext.type) is c_ast.TypeDecl or \
49 type(ext.type) is c_ast.PtrDecl or \
50 type(ext.type) is c_ast.ArrayDecl):
51 decl = ext
52 map = vars
53
54 elif type(ext) is c_ast.FuncDef:
55 decl = ext.decl
56 map = funs
57
58 else:
59 continue
60
61 if "extern" in decl.storage or \
62 "static" in decl.storage:
63 continue
64
65 decl.storage = ["extern"]
66 decl.init = None
67
68 toks = gen.visit(decl).split(" ")
69
70 for tok in toks:
71 if tok in inc_map:
72 incs.add(inc_map[tok])
73
74 alig = ""
75
76 alig += toks[0] + "\t"
77 toks = toks[1:]
78
79 if toks[0] == "struct":
80 if len(toks[1]) > 7:
81 raise Exception("identifier too long: {}".format(toks[1]))
82
83 alig += toks[0] + "\t" + toks[1] + "\t"
84 toks = toks[2:]
85
86 else:
87 alig += toks[0] + ("\t\t" if len(toks[0]) < 8 else "\t")
88 toks = toks[1:]
89
90 map[decl.name] = alig + " ".join(toks) + ";"
91
92 file = path.split("/")[-1]
93 glob = []
94
95 if len(vars) > 0:
96 glob.append("/*")
97 glob.append(" =============================================================================")
98 glob.append("\t" + file + " -- global variables")
99 glob.append(" =============================================================================")
100 glob.append("*/")
101 glob.append("")
102
103 for _, out in sorted(vars.items()):
104 glob.append(out)
105
106 glob.append("")
107
108 if len(funs) > 0:
109 glob.append("/*")
110 glob.append(" =============================================================================")
111 glob.append("\t" + file + " -- global functions")
112 glob.append(" =============================================================================")
113 glob.append("*/")
114 glob.append("")
115
116 for _, out in sorted(funs.items()):
117 glob.append(out)
118
119 glob.append("")
120
121 if len(glob) == 0:
122 continue
123
124 head = []
125 head.append("#pragma once")
126 head.append("")
127
128 if len(incs) > 0:
129 for inc in sorted(incs):
130 head.append("#include \"{}\"".format(inc))
131
132 head.append("")
133
134 glob = head + glob
135
136 with open(path[:-2] + ".x", "w") as f:
137 print("\n".join(glob), file = f)
138
139 print("")
Note: See TracBrowser for help on using the repository browser.