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