+
+ def write_header(self, fn):
+ out = file(fn, "w")
+ self.write_header_intro(out)
+ self.write_enum_definitions(out)
+ self.write_function_pointer_declarations(out)
+ out.write("extern Extension %s;\n"%self.target_ext.name)
+ self.write_header_outro(out)
+
+ def write_source(self, fn):
+ out = file(fn, "w")
+ self.write_source_intro(out)
+ self.write_function_pointer_definitions(out)
+ self.write_init_function(out)
+ ext_name = self.target_ext.name
+ out.write("\nExtension %s(\"GL_%s\", init_%s);\n"%(ext_name, ext_name, ext_name.lower()))
+ self.write_source_outro(out)
+
+
+class ExtensionParser:
+ def __init__(self, host_api):
+ self.host_api = host_api
+ self.target_ext = None
+ self.core_version = None
+ self.deprecated_version = None
+ self.secondary_exts = []
+ self.backport_ext = None
+ self.ignore_things = []
+
+ def parse(self, fn):
+ for line in open(fn):
+ line = line.strip()
+ if line.startswith("#"):
+ continue
+
+ parts = line.split()
+ keyword = parts[0]
+
+ if keyword=="extension":
+ self.target_ext = parts[1]
+ elif keyword=="core_version":
+ if parts[1]==self.host_api:
+ self.core_version = Version(*map(int, parts[2].split('.')))
+ elif keyword=="deprecated":
+ if parts[1]==self.host_api:
+ self.deprecated_version = Version(*map(int, parts[2].split('.')))
+ elif keyword=="secondary":
+ self.secondary_exts.append(parts[1])
+ elif keyword=="backport":
+ self.backport_ext = parts[1]
+ elif keyword=="ignore":
+ self.ignore_things.append(parts[1])
+
+
+def get_extension(api_map, ext_name):
+ main_api = api_map["gl"]
+ ext = main_api.extensions.get(ext_name)
+ if ext:
+ return ext
+
+ for a in api_map.itervalues():
+ ext = a.extensions.get(ext_name)
+ if ext:
+ return ext
+
+def collect_things(host_api, target_ext, secondary, ignore):
+ ext_things = [t for n, t in target_ext.things.iteritems() if n not in ignore]
+ core_things = target_ext.api.core_things
+
+ things = []
+ for t in ext_things:
+ found_in_core = False
+ for a in t.aliases:
+ if a in core_things:
+ things.append(core_things[a])
+ found_in_core = True
+ if not found_in_core:
+ things.append(t)
+
+ for s in secondary:
+ for t in s.things.itervalues():
+ for a in t.aliases:
+ if a in core_things and core_things[a] not in things:
+ things.append(core_things[a])
+
+ return things
+
+def main():
+ if len(sys.argv)<2:
+ print """Usage:
+ extgen.py [api] <extfile> [<outfile>]
+
+Reads gl.xml and generates C++ source files to use an OpenGL extension
+described in <extfile>. If <outfile> is absent, the extension's lowercased
+name is used. Anything after the last dot in <outfile> is removed and
+replaced with cpp and h."""
+ sys.exit(0)
+
+ host_api_name = "gl"
+
+ i = 1
+ if sys.argv[i].startswith("gl"):
+ host_api_name = sys.argv[i]
+ i += 1
+
+ ext_parser = ExtensionParser(host_api_name)
+ ext_parser.parse(sys.argv[i])
+ i += 1
+
+ if i<len(sys.argv):
+ out_base = os.path.splitext(sys.argv[i])[0]
+ else:
+ out_base = ext_parser.target_ext.lower()
+
+ xml_parser = GlXmlParser(host_api_name, ext_parser.target_ext)
+ xml_parser.parse_file("gl.xml")
+ xml_parser.parse_file("gl.fixes.xml")
+ xml_parser.finalize()
+
+ host_api = xml_parser.apis[host_api_name]
+ target_ext = get_extension(xml_parser.apis, ext_parser.target_ext)
+ secondary_exts = [get_extension(xml_parser.apis, s) for s in ext_parser.secondary_exts]
+ things = collect_things(host_api, target_ext, secondary_exts, ext_parser.ignore_things)
+
+ generator = SourceGenerator(host_api, target_ext, things)
+ if ext_parser.core_version:
+ generator.core_version = ext_parser.core_version
+ if ext_parser.deprecated_version:
+ generator.deprecated_version = ext_parser.deprecated_version
+ generator.write_header(out_base+".h")
+ generator.write_source(out_base+".cpp")
+
+if __name__=="__main__":
+ main()