]> git.tdb.fi Git - libs/gl.git/blobdiff - scripts/extgen.py
Get function pointers on OS X through weak symbols
[libs/gl.git] / scripts / extgen.py
index 4333cf37345f176d06fdf52abe2e6f30d8cc1f0c..7ab8abc3fc83ad8efebe031dc859866d98d6dda0 100755 (executable)
@@ -69,6 +69,8 @@ class Thing:
 class Function(Thing):
        def __init__(self, name):
                Thing.__init__(self, name, Thing.FUNCTION)
+               self.return_type = "void"
+               self.params = []
                self.typedef = None
                self.vectorequiv = None
 
@@ -103,7 +105,8 @@ def parse_file(fn):
        root = doc.documentElement
        commands = get_nested_elements(root, "commands/command")
        for cmd in commands:
-               name = get_text_contents(get_nested_elements(cmd, "proto/name")[0])
+               proto = cmd.getElementsByTagName("proto")[0]
+               name = get_text_contents(proto.getElementsByTagName("name")[0])
                func = things.get(name)
                if not func:
                        func = Function(name)
@@ -117,6 +120,19 @@ def parse_file(fn):
                if vec:
                        func.vectorequiv = vec[0].getAttribute("name")
 
+               ptype = proto.getElementsByTagName("ptype")
+               if ptype:
+                       func.return_type = get_text_contents(ptype[0])
+               else:
+                       for c in proto.childNodes:
+                               if c.nodeType==xml.dom.Node.TEXT_NODE and c.data.strip():
+                                       func.return_type = c.data.strip()
+                                       break
+
+               params = cmd.getElementsByTagName("param")
+               for p in params:
+                       func.params.append(get_text_contents(p))
+
        enums = get_nested_elements(root, "enums/enum")
        for en in enums:
                name = en.getAttribute("name")
@@ -236,21 +252,26 @@ out.write("""
 
 namespace Msp {
 namespace GL {
+
 """)
 
 if funcs or enums:
-       out.write("\n#ifndef GL_%s\n"%ext)
-       for f in funcs:
-               out.write("typedef int (*%s)(...);\n"%f.typedef)
-       if funcs and enums:
-               out.write("\n")
-       for e in enums:
-               out.write("#define %s 0x%04X\n"%(e.name, e.value))
-       out.write("#endif\n\n")
+       if funcs:
+               out.write("#if defined(__APPLE__) || !defined(GL_%s)\n"%ext)
+               for f in funcs:
+                       out.write("typedef %s (*%s)(%s);\n"%(f.return_type, f.typedef, ", ".join(f.params)))
+               out.write("#endif\n\n")
+
+       if enums:
+               out.write("#ifndef GL_%s\n"%ext)
+               for e in enums:
+                       out.write("#define %s 0x%04X\n"%(e.name, e.value))
+               out.write("#endif\n\n")
+
        for f in funcs:
                out.write("extern %s %s;\n"%(f.typedef, f.name))
 
-out.write("\nextern Extension %s;\n"%ext)
+out.write("extern Extension %s;\n"%ext)
 
 out.write("""
 } // namespace GL
@@ -263,12 +284,17 @@ out = file(out_base+".cpp", "w")
 out.write("#include \"%s.h\"\n"%ext.lower())
 
 out.write("""
+#ifdef __APPLE__
+#define GET_PROC_ADDRESS(x) ::x
+#else
+#define GET_PROC_ADDRESS(x) get_proc_address(#x)
+#endif
+
 namespace Msp {
 namespace GL {
+
 """)
 
-if funcs:
-       out.write("\n")
 for f in funcs:
        out.write("%s %s = 0;\n"%(f.typedef, f.name))
 
@@ -279,17 +305,19 @@ if ver:
        if backport_ext:
                out.write(" || is_supported(\"GL_%s\")"%backport_ext)
        out.write(")\n\t{\n")
-       for f in funcs:
-               out.write("\t\t%s = reinterpret_cast<%s>(get_proc_address(\"%s\"));\n"%(f.name, f.typedef, f.name))
+       if funcs:
+               for f in funcs:
+                       out.write("\t\t%s = reinterpret_cast<%s>(GET_PROC_ADDRESS(%s));\n"%(f.name, f.typedef, f.name))
        out.write("\t\treturn Extension::CORE;\n")
        out.write("\t}\n")
 if ext!=backport_ext:
        out.write("\tif(is_supported(\"GL_%s\"))\n\t{\n"%(ext))
-       for f in funcs:
-               n = f.name
-               if f.source:
-                       n = f.source.name
-               out.write("\t\t%s = reinterpret_cast<%s>(get_proc_address(\"%s\"));\n"%(f.name, f.typedef, n))
+       if funcs:
+               for f in funcs:
+                       n = f.name
+                       if f.source:
+                               n = f.source.name
+                       out.write("\t\t%s = reinterpret_cast<%s>(GET_PROC_ADDRESS(%s));\n"%(f.name, f.typedef, n))
        out.write("\t\treturn Extension::EXTENSION;\n")
        out.write("\t}\n")
 out.write("#endif\n")