qapi: allow unions to contain further unions
[qemu/armbru.git] / scripts / modinfo-generate.py
blobb1538fcced77e01805f6c8ff4d52b1f887a7ebc8
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
4 import os
5 import sys
7 def print_array(name, values):
8 if len(values) == 0:
9 return
10 list = ", ".join(values)
11 print(" .%s = ((const char*[]){ %s, NULL })," % (name, list))
13 def parse_line(line):
14 kind = ""
15 data = ""
16 get_kind = False
17 get_data = False
18 for item in line.split():
19 if item == "MODINFO_START":
20 get_kind = True
21 continue
22 if item.startswith("MODINFO_END"):
23 get_data = False
24 continue
25 if get_kind:
26 kind = item
27 get_kind = False
28 get_data = True
29 continue
30 if get_data:
31 data += " " + item
32 continue
33 return (kind, data)
35 def generate(name, lines, enabled):
36 arch = ""
37 objs = []
38 deps = []
39 opts = []
40 for line in lines:
41 if line.find("MODINFO_START") != -1:
42 (kind, data) = parse_line(line)
43 if kind == 'obj':
44 objs.append(data)
45 elif kind == 'dep':
46 deps.append(data)
47 elif kind == 'opts':
48 opts.append(data)
49 elif kind == 'arch':
50 arch = data;
51 elif kind == 'kconfig':
52 # don't add a module which dependency is not enabled
53 # in kconfig
54 if data.strip() not in enabled:
55 print(" /* module {} isn't enabled in Kconfig. */"
56 .format(data.strip()))
57 print("/* },{ */")
58 return None
59 else:
60 print("unknown:", kind)
61 exit(1)
63 print(" .name = \"%s\"," % name)
64 if arch != "":
65 print(" .arch = %s," % arch)
66 print_array("objs", objs)
67 print_array("deps", deps)
68 print_array("opts", opts)
69 print("},{")
70 return {dep.strip('" ') for dep in deps}
72 def print_pre():
73 print("/* generated by scripts/modinfo-generate.py */")
74 print("#include \"qemu/osdep.h\"")
75 print("#include \"qemu/module.h\"")
76 print("const QemuModinfo qemu_modinfo[] = {{")
78 def print_post():
79 print(" /* end of list */")
80 print("}};")
82 def main(args):
83 if len(args) < 3 or args[0] != '--devices':
84 print('Expected: modinfo-generate.py --devices '
85 'config-device.mak [modinfo files]', file=sys.stderr)
86 exit(1)
88 # get all devices enabled in kconfig, from *-config-device.mak
89 enabled = set()
90 with open(args[1]) as file:
91 for line in file.readlines():
92 config = line.split('=')
93 if config[1].rstrip() == 'y':
94 enabled.add(config[0][7:]) # remove CONFIG_
96 deps = set()
97 modules = set()
98 print_pre()
99 for modinfo in args[2:]:
100 with open(modinfo) as f:
101 lines = f.readlines()
102 print(" /* %s */" % modinfo)
103 (basename, _) = os.path.splitext(modinfo)
104 moddeps = generate(basename, lines, enabled)
105 if moddeps is not None:
106 modules.add(basename)
107 deps.update(moddeps)
108 print_post()
110 error = False
111 for dep in deps.difference(modules):
112 print("Dependency {} cannot be satisfied".format(dep),
113 file=sys.stderr)
114 error = True
116 if error:
117 exit(1)
119 if __name__ == "__main__":
120 main(sys.argv[1:])