]> git.tdb.fi Git - libs/gl.git/blob - scripts/extgen.py
Function pointer typedefs for core functions are not available everywhere
[libs/gl.git] / scripts / extgen.py
1 #!/usr/bin/python
2
3 import sys
4
5 if len(sys.argv)<2:
6         print """Usage:
7   extgen.py <extension> [<version>] [<secondary> ...]"
8
9 Reads gl.spec and generates files to use <extension>.  Any promoted functions
10 are exposed with their promoted names.  If <secondary> extensions are given,
11 any promoted functions from those are pulled in as well.  <version> can be
12 given to override the version where <extension> was promoted to core."""
13         sys.exit(0)
14
15 ext = sys.argv[1]
16 exttype = ext.split('_')[0]
17 secondary = sys.argv[2:]
18 ver = None
19 if secondary and secondary[0][0].isdigit():
20         ver = secondary.pop(0)
21 bp_ext = None
22
23 class Function:
24         def __init__(self, name):
25                 self.name = name
26                 self.typedef = None
27                 self.version = None
28                 self.category = None
29                 self.vectorequiv = None
30                 self.aliases = []
31                 self.extfunc = None
32
33 funcs = {}
34 cur_func = None
35
36 def parse_file(fn):
37         for line in open(fn):
38                 if line[0]=='#' or line.find(':')>=0:
39                         continue
40                 elif line[0]=='\t':
41                         if cur_func:
42                                 parts = line.split()
43                                 if parts[0]=="category":
44                                         cur_func.category = parts[1]
45                                 elif parts[0]=="vectorequiv":
46                                         cur_func.vectorequiv = parts[1]
47                                 elif parts[0]=="alias":
48                                         cur_func.aliases.append(parts[1])
49                                 elif parts[0]=="version":
50                                         cur_func.version = parts[1]
51                                 elif parts[0]=="delete":
52                                         del funcs[cur_func.name]
53                                         cur_func = None
54                 else:
55                         paren = line.find('(')
56                         if paren>0:
57                                 name = line[:paren]
58                                 if name in funcs:
59                                         cur_func = funcs[name]
60                                 else:
61                                         cur_func = Function(name)
62                                         funcs[name] = cur_func
63
64 parse_file("gl.spec")
65 parse_file("gl.spec.fixes")
66
67 for f in funcs.itervalues():
68         if f.category==ext or f.category in secondary:
69                 if not f.aliases and f.vectorequiv:
70                         for g in funcs.itervalues():
71                                 if g!=f and g.vectorequiv==f.vectorequiv and f.name.startswith(g.name):
72                                         f.aliases.append(g.name)
73                                         break
74
75                 for a in f.aliases:
76                         if a in funcs:
77                                 funcs[a].extfunc = f
78
79 def is_relevant(f):
80         if f.category==ext and not f.aliases:
81                 return True
82         if f.extfunc:
83                 e = f.extfunc
84                 if e.category==ext or e.category in secondary:
85                         return True
86         return False
87
88 funcs = [f for f in funcs.itervalues() if is_relevant(f)]
89 funcs.sort(key=(lambda f: f.name))
90
91 for f in funcs:
92         if f.extfunc:
93                 f.typedef = "PFNGL%sPROC"%f.extfunc.name.upper()
94                 if not ver:
95                         ver = f.version
96                 if not f.category.startswith("VERSION_"):
97                         bp_ext = f.category
98         else:
99                 f.typedef = "PFNGL%sPROC"%f.name.upper()
100                 if not f.name.endswith(exttype):
101                         bp_ext = f.category
102
103 if ver:
104         ver = map(int, ver.split('.'))
105
106 out = file(ext.lower()+".h", "w")
107 out.write("#ifndef MSP_GL_%s_\n"%ext.upper())
108 out.write("#define MSP_GL_%s_\n"%ext.upper())
109
110 out.write("""
111 #include "extension.h"
112 #include "gl.h"
113 #include <GL/glext.h>
114
115 namespace Msp {
116 namespace GL {
117 """)
118
119 if funcs:
120         out.write("\n")
121 for f in funcs:
122         out.write("extern %s gl%s;\n"%(f.typedef, f.name))
123
124 out.write("\nextern Extension %s;\n"%ext)
125
126 out.write("""
127 } // namespace GL
128 } // namespace Msp
129
130 #endif
131 """)
132
133 out = file(ext.lower()+".cpp", "w")
134 out.write("#include \"%s.h\"\n"%ext.lower())
135
136 out.write("""
137 namespace Msp {
138 namespace GL {
139 """)
140
141 if funcs:
142         out.write("\n")
143 for f in funcs:
144         out.write("%s gl%s = 0;\n"%(f.typedef, f.name))
145
146 out.write("\nExtension::SupportLevel init_%s()\n{\n"%ext.lower())
147 if ver:
148         out.write("\tif(is_version_at_least(%d, %d)"%tuple(ver))
149         if bp_ext:
150                 out.write(" || is_supported(\"GL_%s\")"%bp_ext)
151         out.write(")\n\t{\n")
152         for f in funcs:
153                 out.write("\t\tgl%s = reinterpret_cast<%s>(get_proc_address(\"gl%s\"));\n"%(f.name, f.typedef, f.name))
154         out.write("\t\treturn Extension::CORE;\n")
155         out.write("\t}\n")
156 if ext!=bp_ext:
157         out.write("\tif(is_supported(\"GL_%s\"))\n\t{\n"%(ext))
158         for f in funcs:
159                 n = f.name
160                 if f.extfunc:
161                         n = f.extfunc.name
162                 out.write("\t\tgl%s = reinterpret_cast<%s>(get_proc_address(\"gl%s\"));\n"%(f.name, f.typedef, n))
163         out.write("\t\treturn Extension::EXTENSION;\n")
164         out.write("\t}\n")
165 out.write("\treturn Extension::UNSUPPORTED;\n")
166 out.write("}\n")
167
168 out.write("\nExtension %s(\"GL_%s\", init_%s);\n"%(ext, ext, ext.lower()))
169
170 out.write("""
171 } // namespace GL
172 } // namespace Msp
173 """)