]> git.tdb.fi Git - gldbg.git/blob - genwrap.py
Initial revision
[gldbg.git] / genwrap.py
1 #!/usr/bin/python
2 # $Id$
3
4 import sys
5 import os
6
7 outdir="gensrc"
8
9 typemap = {}
10 for line in open("gl.tm"):
11         if line[0]=='#':
12                 continue
13         parts = [p.strip() for p in line.split(',')]
14         typemap[parts[0]] = parts[3]
15 typemap["void"] = "void"
16
17 def getparam(func, name):
18         for p in func[2]:
19                 if p[0]==name:
20                         return p
21
22 funcs = []
23 cur_func = None
24 for line in open("gl.spec"):
25         if line[0]=='#' or line.find(':')>=0:
26                 continue
27         elif line[0]=='\t' and cur_func:
28                 parts = line.split()
29                 if parts[0]=="return":
30                         cur_func[1] = typemap[parts[1]]
31                 elif parts[0]=="param":
32                         p = getparam(cur_func, parts[1])
33                         p[2] = parts[2]
34                         p[1] = typemap[parts[2]]
35                         if parts[4]=="array":
36                                 p[1] += " *"
37                                 if parts[3]=="in":
38                                         p[1] = "const "+p[1]
39                                 s = parts[5][1:-1]
40                                 if s.isdigit():
41                                         p[3] = int(s)
42                                 elif s=="":
43                                         p[3] = "~"
44                                 else:
45                                         p[3] = s
46         else:
47                 paren = line.find('(')
48                 if paren>0:
49                         cparen = line.rfind(')')
50                         if cparen>paren+1:
51                                 args = line[paren+1:cparen].split(", ")
52                         else:
53                                 args = []
54                         cur_func = [line[:paren], None, [[a, None, None, 0] for a in args]]
55                         funcs.append(cur_func)
56
57 fmtmap = {"GLenum":"%#x",
58         "GLboolean":"%i",
59         "GLbitfield":"%#x",
60         "GLbyte":"%i",
61         "GLshort":"%i",
62         "GLint":"%i",
63         "GLubyte":"%u",
64         "GLushort":"%u",
65         "GLuint":"%u",
66         "GLsizei":"%i",
67         "GLfloat":"%f",
68         "GLclampf":"%f",
69         "GLdouble":"%lf",
70         "GLclampd":"%lf",
71         "const GLubyte *":"%s",
72         "GLchar *":"%s",
73         "GLcharARB *":"%s",
74         "GLvoid*":"%p",
75         "GLsizeiptr":"%p",
76         "GLsizeiptrARB":"%p",
77         "GLintptr":"%p",
78         "GLintptrARB":"%p",
79         "GLhandleARB":"%i",
80         "GLhalfNV":"%#x",
81         "GLuint64EXT":"%lld"}
82
83 iomap = {"GLenum":"int",
84         "GLboolean":"char",
85         "GLbitfield":"int",
86         "GLbyte":"char",
87         "GLshort":"short",
88         "GLint":"int",
89         "GLubyte":"char",
90         "GLushort":"short",
91         "GLuint":"int",
92         "GLsizei":"int",
93         "GLfloat":"float",
94         "GLclampf":"float",
95         "GLdouble":"double",
96         "GLclampd":"double",
97         "const GLubyte *":"string",
98         "GLchar *":"string",
99         "GLcharARB *":"string",
100         "GLvoid*":"pointer",
101         "GLsizeiptr":"int",
102         "GLsizeiptrARB":"int",
103         "GLintptr":"int",
104         "GLintptrARB":"int",
105         "GLhandleARB":"int",
106         "GLhalfNV":"short",
107         "GLuint64EXT":"longlong"}
108
109 def basetype(type, is_array):
110         if type.startswith("const "):
111                 type = type[6:]
112         if is_array and type.endswith(" *"):
113                 type = type[:-2]
114         return type
115
116 def compsize(func, size, ptype):
117         if not size:
118                 return
119
120         res = ""
121         have_type = False
122         for c in size.split('/'):
123                 p = getparam(func, c)
124                 if not p:
125                         return
126
127                 if res:
128                         res += "*"
129
130                 cn = p[2]
131                 if cn.endswith(("EXT", "ARB", "SGI", "IBM", "ATI")):
132                         cn = cn[:-3]
133                 elif cn.endswith("SGIX"):
134                         cn = cn[:-4]
135                 elif cn.endswith(("NV", "HP")):
136                         cn = cn[:-2]
137                 if cn.endswith("Type"):
138                         res += "typesize(%s)"%p[0]
139                         have_type = True
140                 elif cn.endswith("Format"):
141                         res += "formatsize(%s)"%p[0]
142                 elif cn.endswith(("Parameter", "ParameterPName", "ParameterName")) or cn=="GetPName":
143                         res += "paramsize(%s)"%p[0]
144                 elif cn=="MapTarget":
145                         res += "mapsize(%s)"%p[0]
146                 elif (cn=="SizeI" or cn.endswith("Int32")) and p[3]==0:
147                         res += p[0]
148                 else:
149                         return
150         if not have_type:
151                 res += "*sizeof(%s)"%ptype
152         return res
153
154 def getfmt(param):
155         ptype = basetype(param[1], param[3]!=0)
156         if param[3]:
157                 if type(param[3])==int:
158                         return ("{%s}"%(", ".join([fmtmap[ptype]]*param[3])), ", ".join("%s[%d]"%(param[0], i) for i in range(param[3])))
159                 else:
160                         return ("%p", param[0])
161         else:
162                 return (fmtmap[ptype], param[0])
163
164 def getwrite(func, param):
165         ptype = basetype(param[1], param[3]!=0)
166         if param[3]:
167                 if type(param[3])==int:
168                         size = "%d*sizeof(%s)"%(param[3], ptype)
169                 elif param[3].startswith("COMPSIZE("):
170                         size = compsize(func, param[3][9:-1], ptype)
171                         if not size:
172                                 print "Compsize '%s' for function '%s' failed"%(param[3][9:-1], func[0])
173                                 return ("pointer", None)
174                 elif param[3]=="~" and (param[2]=="charARB" or param[2]=="Char"):
175                         return ("string", None)
176                 else:
177                         s = getparam(func, param[3].split('*')[0])
178                         if s and (s[2]=="SizeI" or s[2].endswith("Int32")) and s[3]==0:
179                                 size = "%s*sizeof(%s)"%(param[3], ptype)
180                                 if func[0].startswith("Uniform") and func[0][8]!='u' and func[0][7].isdigit():
181                                         size += "*%s"%func[0][7]
182                         else:
183                                 print "Could not determine size for array parameter '%s[%s]' of function '%s'"%(param[0], param[3], func[0])
184                                 return ("pointer", None)
185                 return ("data", size)
186         else:
187                 return (iomap[ptype], None)
188
189 def getread(func, param):
190         ptype = basetype(param[1], param[3]!=0)
191         if param[3]:
192                 return ("data", "(const void **)")
193         else:
194                 return (iomap[ptype], "")
195
196 # Write out function enums
197
198 out = open(os.path.join(outdir, "functions.enum"), "w");
199 out.write("""enum Function
200 {
201         FUNC_NONE,
202 """)
203 for f in funcs:
204         out.write("\tFUNC_%s,\n"%f[0].upper())
205 out.write("};\n")
206 out.close()
207
208 # Write out wrapper functions for transmitting side
209
210 out = open(os.path.join(outdir, "glwrap.funcs"), "w");
211 for f in funcs:
212         out.write("%s GLAPIENTRY gl%s(%s)\n{\n"%(f[1], f[0], ", ".join("%s %s"%(p[1], p[0]) for p in f[2])))
213
214         out.write("\tstatic %s (*orig)(%s) = NULL;\n"%(f[1], ", ".join(p[1] for p in f[2])))
215         if f[1]!="void":
216                 out.write("\t%s ret;\n"%f[1])
217         out.write("\tif(!orig)\n\t\torig = glsym(\"gl%s\");\n"%f[0])
218
219         out.write("\t")
220         if f[1]!="void":
221                 out.write("ret = ")
222         out.write("orig(%s);\n"%(", ".join(p[0] for p in f[2])))
223
224         out.write("\tbegin_packet(FUNC_%s);\n"%f[0].upper())
225         if f[1]!="void":
226                 out.write("\twrite_%s(ret);\n"%iomap[f[1]])
227         for p in f[2]:
228                 (t, s) = getwrite(f, p)
229                 out.write("\twrite_%s(%s"%(t, p[0]))
230                 if s:
231                         out.write(", %s"%s)
232                 out.write(");\n")
233         out.write("\tsend_packet();\n")
234
235         if f[1]!="void":
236                 out.write("\treturn ret;\n")
237         out.write("}\n\n")
238 out.close()
239
240 # Write out decoder stuff
241
242 out = open(os.path.join(outdir, "gldecoder.struct"), "w")
243 out.write("typedef struct sGlDecoder\n{\n")
244 out.write("\tvoid *user_data;\n")
245 out.write("\tvoid (*destroy)(void *);\n")
246 for f in funcs:
247         out.write("\tvoid (*%s)(void *"%f[0])
248         if f[1]!="void":
249                 out.write(", %s"%f[1])
250         if f[2]:
251                 out.write(", %s"%(", ".join(p[1] for p in f[2])))
252         out.write(");\n")
253 out.write("} GlDecoder;\n")
254
255 out = open(os.path.join(outdir, "gldecoder.funcs"), "w")
256 for f in funcs:
257         out.write("static unsigned decode_%s(GlDecoder *dec, const char *data, unsigned len)\n{\n"%(f[0]))
258         out.write("\tunsigned pos = 0;\n")
259         if f[1]!="void":
260                 out.write("\t%s ret;\n"%f[1])
261         for p in f[2]:
262                 out.write("\t%s arg_%s;\n"%(p[1], p[0]))
263         if f[1]!="void":
264                 out.write("\tpos += read_%s(&ret, data+pos, len);\n"%iomap[f[1]])
265         for p in f[2]:
266                 (t, c) = getread(f, p)
267                 out.write("\tpos += read_%s(%s&arg_%s, data+pos, len-pos);\n"%(t, c, p[0]))
268         out.write("\tif(dec->%s)\n"%f[0])
269         out.write("\t\tdec->%s(dec->user_data"%f[0])
270         if f[1]!="void":
271                 out.write(", ret")
272         if f[2]:
273                 out.write(", %s"%(", ".join("arg_"+p[0] for p in f[2])))
274         out.write(");\n")
275         out.write("\treturn pos;\n")
276         out.write("}\n\n")
277
278 out.write("""unsigned gldecoder_decode(GlDecoder *dec, const char *data, unsigned len)
279 {
280         unsigned pos = 0;
281         short func;
282
283         pos += read_short(&func, data, len);
284         switch(func)
285         {
286 """)
287 for f in funcs:
288         out.write("\t\tcase FUNC_%s: pos += decode_%s(dec, data+pos, len); break;\n"%(f[0].upper(), f[0]))
289 out.write("""   }
290
291         return pos;
292 }
293 """)
294 out.close()
295
296 # Write out print stuff
297
298 out = open(os.path.join(outdir, "glprint.funcs"), "w")
299 for f in funcs:
300         out.write("static void print_%s(void *user_data"%f[0])
301         if f[1]!="void":
302                 out.write(", %s ret"%f[1])
303         if f[2]:
304                 out.write(", %s"%(", ".join("%s %s"%(p[1], p[0]) for p in f[2])))
305         out.write(")\n{\n")
306         out.write("\tGlPrintData *gpd = (GlPrintData *)user_data;\n")
307
308         m = [getfmt(p) for p in f[2]]
309         out.write("\tsnprintf(gpd->buffer, gpd->bufsize, \"%s(%s)"%(f[0], ", ".join(p[0] for p in m)))
310         if f[1]!="void":
311                 out.write(" = %s"%fmtmap[f[1]])
312         out.write("\"")
313         if m:
314                 out.write(", %s"%(", ".join(p[1] for p in m)))
315         if f[1]!="void":
316                 out.write(", ret")
317         out.write(");\n")
318
319         out.write("}\n\n")
320
321 out.write("static void init_print(GlDecoder *dec)\n{\n")
322 for f in funcs:
323         out.write("\tdec->%s = print_%s;\n"%(f[0], f[0]))
324 out.write("}\n")
325 out.close()