Index: misc/gen-glob.py
===================================================================
--- misc/gen-glob.py	(revision 14ad9c9bc8a3ff4f25b2e00560c162bd8280d680)
+++ misc/gen-glob.py	(revision 6aa430b53ee38cdae99301c5e14c358ac29b4f87)
@@ -5,13 +5,28 @@
 
 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"
+class InclVis(c_ast.NodeVisitor):
+    def __init__(self, path):
+        self.path = path
+        self.typs = set()
+
+    def visit_Typedef(self, node):
+        if node.coord.file == self.path:
+            self.typs.add(node.name)
+
+        self.generic_visit(node)
+
+    def visit_Struct(self, node):
+        if node.coord.file == self.path and \
+           node.name is not None and node.decls is not None:
+            self.typs.add(node.name)
+
+        self.generic_visit(node)
+
+    def get_typs(self):
+        return self.typs
+
+typ_map = {
+    "void": None
 }
 
@@ -19,4 +34,56 @@
     for path in f:
         path = path.rstrip()
+
+        if len(path) < 8 or path[:8] != "include/":
+            continue
+
+        stdout.write("parsing {}                    \r".format(path))
+        stdout.flush()
+
+        ast = parse_file(path, use_cpp = True, cpp_path = cross_gcc,
+                         cpp_args = ["-E", "-I", "include"])
+        # ast.show()
+
+        vis = InclVis(path)
+        vis.visit(ast)
+
+        for typ in vis.get_typs():
+            if typ in typ_map:
+                raise Exception("redefinition of {}".format(typ))
+
+            typ_map[typ] = path[8:]
+
+class DeclVis(c_ast.NodeVisitor):
+    def __init__(self, typ_map):
+        self.typ_map = typ_map
+        self.typs = set()
+
+    def visit_IdentifierType(self, node):
+        if node.names[0] not in self.typ_map:
+            raise Exception("unknown type {} in {}:{}". \
+                            format(node.names[0], node.coord.file, node.coord.line))
+
+        self.typs.add(node.names[0])
+        self.generic_visit(node)
+
+    def visit_Struct(self, node):
+        if node.name not in self.typ_map:
+            raise Exception("unknown struct {} in {}:{}". \
+                            format(node.name, node.coord.file, node.coord.line))
+
+        self.typs.add(node.name)
+        self.generic_visit(node)
+
+    def get_typs(self):
+        return self.typs
+
+gen = c_generator.CGenerator()
+
+with open("misc/c-files.txt", "r") as f:
+    for path in f:
+        path = path.rstrip()
+
+        if len(path) >= 8 and path[:8] == "include/":
+            continue
 
         if path == "ram/wdfield.c": # breaks pycparser
@@ -30,29 +97,19 @@
         # ast.show()
 
+        incs = set()
         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.
+        for node in ast.ext:
+            if type(node) is c_ast.Decl and \
+               (type(node.type) is c_ast.TypeDecl or \
+                type(node.type) is c_ast.PtrDecl or \
+                type(node.type) is c_ast.ArrayDecl):
+                decl = node
+                dest = vars
 
-            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
+            elif type(node) is c_ast.FuncDef:
+                decl = node.decl
+                dest = funs
 
             else:
@@ -63,13 +120,15 @@
                 continue
 
+            vis = DeclVis(typ_map)
+            vis.visit(decl)
+
+            for typ in vis.get_typs():
+                if typ_map[typ] is not None:
+                    incs.add(typ_map[typ])
+
             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 = ""
 
@@ -87,6 +146,6 @@
                 alig += toks[0] + ("\t\t" if len(toks[0]) < 8 else "\t")
                 toks = toks[1:]
- 
-            map[decl.name] = alig + " ".join(toks) + ";"
+
+            dest[decl.name] = alig + " ".join(toks) + ";"
 
         file = path.split("/")[-1]
@@ -135,5 +194,5 @@
 
         with open(path[:-2] + ".x", "w") as f:
-            print("\n".join(glob), file = f)
+            f.write("\n".join(glob))
 
     print("")
Index: misc/proto.x
===================================================================
--- misc/proto.x	(revision 14ad9c9bc8a3ff4f25b2e00560c162bd8280d680)
+++ misc/proto.x	(revision 6aa430b53ee38cdae99301c5e14c358ac29b4f87)
@@ -100,3 +100,2 @@
 extern	void		vwputs(int16_t *obase, int16_t nw, int16_t fg, int16_t bg, int16_t row, int16_t col, int8_t *str);
 extern	void		xtrap15(void);
-
