9 def __init__(self, fn):
15 if h==0 or (h>0 and l[h-1].isspace()):
26 """Strips any vendor suffix and GL prefix from a name (but not GLX prefix)"""
29 if name.endswith(" *"):
32 elif name.endswith("Pointer"):
37 if name.startswith("const "):
41 if name.startswith("GL") and not name.startswith("GLX"):
43 if name.endswith(("EXT", "ARB", "SGI", "IBM", "ATI")):
44 return prefix+name[:-3]+suffix
45 elif name.endswith("SGIX"):
46 return prefix+name[:-4]+suffix
47 elif name.endswith(("NV", "HP")):
48 return prefix+name[:-2]+suffix
50 return prefix+name+suffix
54 def __init__(self, fn):
56 for line in InputFile(fn):
57 parts = [p.strip() for p in line.split(',')]
60 elif parts[3][-1]=='*' and parts[3][-2]!=' ':
61 parts[3] = parts[3][:-1]+" *"
62 self.map[tuple(parts[0:3])] = tuple(parts[3:6])
64 def wildcard_match(self, a, b):
69 def __getitem__(self, key):
71 return self.map[(key[0], "*", "*")]
73 for k, v in self.map.iteritems():
74 if strip_name(k[0])==strip_name(key[0]) and self.wildcard_match(k[1], key[1]) and self.wildcard_match(k[2], key[2]):
78 def update(self, other):
79 self.map.update(other.map)
83 def __init__(self, fn):
85 self.map["void"] = None
86 for line in InputFile(fn):
87 parts = [p.strip() for p in line.split(',')]
88 self.map[parts[0]] = tuple(parts[1:])
90 def __getitem__(self, key):
91 return self.map[strip_name(key)]
96 def __init__(self, func, name):
100 self.direction = "in"
107 def set_type(self, type, dir, kind):
112 def set_size(self, size):
113 if type(size)==str and size.isdigit():
114 self.size = int(size)
118 def derive_ctype(self, typemap, iomap):
119 m = typemap[(self.type, self.direction, self.kind)]
122 self.direction = m[1]
125 self.base_ctype = self.ctype
126 if self.kind=="value":
127 if self.base_ctype.startswith("const "):
128 self.base_ctype = self.base_ctype[6:]
130 if self.direction=="in":
131 self.ctype = "const "+self.ctype
132 self.ctype = self.ctype+" *"
133 self.io = iomap[self.base_ctype]
135 def derive_csize(self):
136 if self.kind=="array" and self.size is not None:
138 if type(self.size)==int:
139 self.csize = "%d*sizeof(%s)"%(self.size, self.base_ctype)
140 elif self.size.startswith("COMPSIZE("):
141 self.csize = self.func.compsize(self.size[9:-1], self.base_ctype)
142 elif self.size=="pname":
143 self.csize = "paramsize(pname)*sizeof(%s)"%self.base_ctype
145 s = self.func.get_param(self.size.split('*')[0])
146 if (s.type=="SizeI" or s.type.endswith("Int32") or s.type.startswith("BufferSize")):
148 self.csize = "%s"%self.size
149 if self.func.name.startswith("glUniformMatrix") and self.func.name[16]!='x':
150 self.csize += "*%d"%(int(self.func.name[15])**2)
151 elif self.func.name.startswith("glUniform") and self.func.name[9].isdigit():
152 self.csize += "*%s"%self.func.name[9]
153 if strip_name(self.base_ctype)!="void":
154 self.csize += "*sizeof(%s)"%self.base_ctype
155 elif s.kind=="array" and s.size==1:
156 self.csize = "*%s"%s.name
158 sys.stderr.write("Could not determine size for array parameter '%s[%s]' of function '%s'\n"%(self.name, self.size, self.func.name))
159 elif self.kind=="reference":
160 self.csize = "sizeof(%s)"%self.base_ctype
162 def __init__(self, name, pnames):
164 self.ret = Function.Parameter(self, "ret")
165 self.params = [Function.Parameter(self, n) for n in pnames]
168 def get_param(self, pname):
169 for p in self.params:
172 raise KeyError, pname
174 def set_category(self, cat):
177 def compsize(self, size, btype):
183 for c in size.replace(',', '/').split('/'):
184 param = self.get_param(c)
186 sys.stderr.write("Compsize '%s' for function '%s' failed: No parameter '%s'\n"%(size, self.name, c))
192 cn = strip_name(param.type)
193 if cn.endswith("Type"):
194 res += "typesize(%s)"%param.name
196 elif cn.endswith("Format"):
197 res += "formatsize(%s)"%param.name
198 elif param.name=="pname" or cn.endswith("Parameter") or (param.name=="target" and cn=="enum"):
199 res += "paramsize(%s)"%param.name
200 elif param.name=="buffer" and cn=="enum":
201 res += "buffersize(%s)"%param.name
202 elif (cn=="SizeI" or cn.endswith("Int32")) and not param.size:
205 sys.stderr.write("Compsize '%s' for function '%s' failed: Parameter '%s' has unknown type '%s'\n"%(size, self.name, param.name, param.type))
208 res += "*sizeof(%s)"%btype
211 def finalize(self, typemap, iomap):
212 self.ret.derive_ctype(typemap, iomap)
213 for p in self.params:
214 p.derive_ctype(typemap, iomap)
215 for p in self.params:
220 def __init__(self, name, category, value):
222 self.category = category
227 def __init__(self, fn):
228 self.mode = "functions"
234 for line in InputFile(fn):
236 if not literal and text:
237 self.add_section(text, literal)
239 text += line[1:]+"\n"
242 parts = line[1:].split()
243 if parts[0]=="handcode":
244 self.handcode.append(parts[1])
245 elif parts[0]=="mode":
248 sys.stderr.write("Unknown keyword '%s'\n"%parts[0])
251 self.add_section(text, literal)
256 self.add_section(text, literal)
258 def add_section(self, text, literal):
260 self.sections.append(text)
262 self.sections.append(compile(text, "-", "exec"))
264 def write(self, str, *args):
265 sys.stdout.write(str%args)
267 def writeln(self, str, *args):
268 sys.stdout.write(str%args+"\n")
270 def process_function(self, code, func):
271 if func.name in self.handcode:
279 "params": func.params
283 def process_enum(self, code, enum):
284 if enum.value is None:
294 def process_sections(self, objects, handler):
295 for sect in self.sections:
302 def process(self, apis):
303 if self.mode=="functions":
306 typemap = Typemap(api.typemap)
307 iomap = IOmap(api.iomap)
308 for spec in api.specs:
309 funcs = read_spec(spec, api.prefix)
310 funcs = [f for f in funcs if f.name not in api.ignore_funcs and f.category not in api.ignore_categs]
312 func.finalize(typemap, iomap)
313 names = [f.name for f in funcs]
314 functions = [f for f in functions if f.name not in names]+funcs
315 self.process_sections(functions, self.process_function)
316 elif self.mode=="enums":
319 for spec in api.enumspecs:
320 ens = read_enums(spec, api.enumprefix)
322 enums.sort(lambda x, y: cmp(x.value, y.value)*2+cmp(x.category, y.category))
323 self.process_sections(enums, self.process_enum)
327 def __init__(self, fn):
333 self.enumprefix = None
334 self.ignore_categs = []
335 self.ignore_funcs = []
337 path = os.path.split(fn)[0]
339 for line in InputFile(fn):
341 if parts[0]=="typemap":
342 self.typemap = os.path.join(path, parts[1])
343 elif parts[0]=="iomap":
344 self.iomap = os.path.join(path, parts[1])
345 elif parts[0]=="spec":
346 self.specs.append(os.path.join(path, parts[1]))
347 elif parts[0]=="prefix":
348 self.prefix = parts[1]
349 elif parts[0]=="enumspec":
350 self.enumspecs.append(os.path.join(path, parts[1]))
351 elif parts[0]=="enumprefix":
352 self.enumprefix = parts[1]
353 elif parts[0]=="ignore":
354 if parts[1]=="category":
355 self.ignore_categs.append(parts[2])
356 elif parts[1]=="function":
357 self.ignore_funcs.append(parts[2])
359 sys.stderr.write("Unknown keyword '%s'\n", parts[0])
362 def read_spec(fn, prefix):
366 for line in InputFile(fn):
367 if line.find(':')>=0:
369 elif line[0]=='\t' and cur_func:
371 if parts[0]=="return":
372 cur_func.ret.set_type(parts[1], "out", "value")
373 elif parts[0]=="param":
374 bracket = parts[4].find('[')
376 parts.insert(5, parts[4][bracket:])
377 parts[4] = parts[4][:bracket]
379 param = cur_func.get_param(parts[1])
380 param.set_type(parts[2], parts[3], parts[4])
381 if len(parts)==6 or (len(parts)>6 and parts[6]!="retained"):
382 param.set_size(parts[5][1:-1])
383 elif parts[0]=="category":
384 cur_func.set_category(parts[1])
385 elif parts[0]=="glxvendorglx" and cur_func.category=="glx":
386 cur_func.set_category("glxext")
388 paren = line.find('(')
390 cparen = line.rfind(')')
392 pnames = [n.strip() for n in line[paren+1:cparen].split(",")]
395 cur_func = Function(prefix+line[:paren], pnames)
396 funcs.append(cur_func)
400 def read_enums(fn, prefix):
404 for line in InputFile(fn):
406 parts = line[:line.find(':')].split()
407 if len(parts)==2 and parts[1]=="enum":
412 enums.append(Enum(prefix+parts[2], cur_categ, None))
415 enums.append(Enum(prefix+parts[0], cur_categ, int(parts[2], 0)))
416 except ValueError, e:
417 sys.stderr.write("Syntax error in %s: %s\n"%(fn, e))
422 if n.name==e.name and n.value is not None:
425 sys.stderr.write("Could not find value for enum reference %s in category %s\n"%(e.name, e.category))
429 parser = optparse.OptionParser()
430 parser.add_option("--depends", dest="depends", default=False)
431 (options, args) = parser.parse_args()
433 template = Template(args[0])
440 if template.mode=="functions":
443 deps.append(api.typemap)
444 deps.append(api.iomap)
445 elif template.mode=="enums":
447 deps += api.enumspecs
448 sys.stdout.write("%s: %s\n"%(options.depends, " ".join(deps)))
450 template.process(apis)