10 extgen.py <extension> [<version>] [<secondary> ...]"
12 Reads gl.spec and generates files to use <extension>. Any promoted functions
13 are exposed with their promoted names. If <secondary> extensions are given,
14 any promoted functions from those are pulled in as well. <version> can be
15 given to override the version where <extension> was promoted to core."""
20 if ext.endswith(".glext"):
27 if parts[0]=="extension":
29 elif parts[0]=="core_version":
31 elif parts[0]=="secondary":
32 secondary.append(parts[1])
34 out_base = os.path.splitext(sys.argv[2])[0]
36 secondary = sys.argv[2:]
38 if secondary and secondary[0][0].isdigit():
39 ver = secondary.pop(0)
41 exttype = ext.split('_')[0]
45 out_base = ext.lower()
48 def __init__(self, name):
53 self.vectorequiv = None
60 def get_nested_elements(elem, path):
62 head, tail = path.split('/', 1)
64 for e in elem.getElementsByTagName(head):
65 result += get_nested_elements(e, tail)
68 return elem.getElementsByTagName(path)
70 def get_text_contents(node):
72 for c in node.childNodes:
73 if c.nodeType==xml.dom.Node.TEXT_NODE or c.nodeType==xml.dom.Node.CDATA_SECTION_NODE:
76 result += get_text_contents(c)
80 doc = xml.dom.minidom.parse(fn)
81 root = doc.documentElement
82 commands = get_nested_elements(root, "commands/command")
84 name = get_text_contents(get_nested_elements(cmd, "proto/name")[0])
85 func = funcs.get(name)
90 aliases = cmd.getElementsByTagName("alias")
92 func.aliases.append(a.getAttribute("name"))
94 vec = cmd.getElementsByTagName("vecequiv")
96 func.vectorequiv = vec[0].getAttribute("name")
98 features = root.getElementsByTagName("feature")
100 api = feat.getAttribute("api")
102 version = feat.getAttribute("number")
104 commands = get_nested_elements(feat, "require/command")
106 name = c.getAttribute("name")
107 func = funcs.get(name)
109 func.version = version
111 if feat.getAttribute("name")=="MSPGL_REMOVE":
112 commands = get_nested_elements(feat, "remove/command")
114 name = c.getAttribute("name")
118 extensions = get_nested_elements(root, "extensions/extension")
119 for ext in extensions:
120 ext_name = ext.getAttribute("name")
121 if ext_name.startswith("GL_"):
122 ext_name = ext_name[3:]
123 supported = ext.getAttribute("supported").split('|')
124 if "gl" in supported:
125 commands = get_nested_elements(ext, "require/command")
127 name = c.getAttribute("name")
128 func = funcs.get(name)
130 func.category = ext_name
133 parse_file("gl.fixes.xml")
135 for f in funcs.itervalues():
136 if f.category==ext or f.category in secondary:
138 aliasfunc = funcs.get(a)
140 aliasfunc.extfunc = f
143 if f.category==ext and not f.aliases:
147 if e.category==ext or e.category in secondary:
151 funcs = [f for f in funcs.itervalues() if is_relevant(f)]
152 funcs.sort(key=(lambda f: f.name))
158 if f.category and not f.name.endswith(exttype):
162 f.typedef = "PFN%sPROC"%f.extfunc.name.upper()
164 f.typedef = "PFN%sPROC"%f.name.upper()
167 ver = map(int, ver.split('.'))
169 out = file(out_base+".h", "w")
170 out.write("#ifndef MSP_GL_%s_\n"%ext.upper())
171 out.write("#define MSP_GL_%s_\n"%ext.upper())
174 #include <msp/gl/extension.h>
175 #include <msp/gl/gl.h>
184 out.write("extern %s %s;\n"%(f.typedef, f.name))
186 out.write("\nextern Extension %s;\n"%ext)
195 out = file(out_base+".cpp", "w")
196 out.write("#include \"%s.h\"\n"%ext.lower())
206 out.write("%s %s = 0;\n"%(f.typedef, f.name))
208 out.write("\nExtension::SupportLevel init_%s()\n{\n"%ext.lower())
210 out.write("\tif(is_version_at_least(%d, %d)"%tuple(ver))
212 out.write(" || is_supported(\"GL_%s\")"%bp_ext)
213 out.write(")\n\t{\n")
215 out.write("\t\t%s = reinterpret_cast<%s>(get_proc_address(\"%s\"));\n"%(f.name, f.typedef, f.name))
216 out.write("\t\treturn Extension::CORE;\n")
219 out.write("\tif(is_supported(\"GL_%s\"))\n\t{\n"%(ext))
224 out.write("\t\t%s = reinterpret_cast<%s>(get_proc_address(\"%s\"));\n"%(f.name, f.typedef, n))
225 out.write("\t\treturn Extension::EXTENSION;\n")
227 out.write("\treturn Extension::UNSUPPORTED;\n")
230 out.write("\nExtension %s(\"GL_%s\", init_%s);\n"%(ext, ext, ext.lower()))