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 strip_name(self.base_ctype)!="void":
150 self.csize += "*sizeof(%s)"%self.base_ctype
151 elif s.kind=="array" and s.size==1:
152 self.csize = "*%s"%s.name
154 sys.stderr.write("Could not determine size for array parameter '%s[%s]' of function '%s'\n"%(self.name, self.size, self.func.name))
155 elif self.kind=="reference":
156 self.csize = "sizeof(%s)"%self.base_ctype
158 def __init__(self, name, pnames):
160 self.ret = Function.Parameter(self, "ret")
161 self.params = [Function.Parameter(self, n) for n in pnames]
164 def get_param(self, pname):
165 for p in self.params:
168 raise KeyError, pname
170 def set_category(self, cat):
173 def compsize(self, size, btype):
179 for c in size.replace(',', '/').split('/'):
180 param = self.get_param(c)
182 sys.stderr.write("Compsize '%s' for function '%s' failed: No parameter '%s'\n"%(size, self.name, c))
188 cn = strip_name(param.type)
189 if cn.endswith("Type"):
190 res += "typesize(%s)"%param.name
192 elif cn.endswith("Format"):
193 res += "formatsize(%s)"%param.name
194 elif param.name=="pname" or cn.endswith("Parameter") or (param.name=="target" and cn=="enum"):
195 res += "paramsize(%s)"%param.name
196 elif param.name=="buffer" and cn=="enum":
197 res += "buffersize(%s)"%param.name
198 elif (cn=="SizeI" or cn.endswith("Int32")) and not param.size:
201 sys.stderr.write("Compsize '%s' for function '%s' failed: Parameter '%s' has unknown type '%s'\n"%(size, self.name, param.name, param.type))
204 res += "*sizeof(%s)"%btype
207 def finalize(self, typemap, iomap):
208 self.ret.derive_ctype(typemap, iomap)
209 for p in self.params:
210 p.derive_ctype(typemap, iomap)
211 for p in self.params:
216 def __init__(self, name, category, value):
218 self.category = category
223 def __init__(self, fn):
224 self.mode = "functions"
230 for line in InputFile(fn):
232 if not literal and text:
233 self.add_section(text, literal)
235 text += line[1:]+"\n"
238 parts = line[1:].split()
239 if parts[0]=="handcode":
240 self.handcode.append(parts[1])
241 elif parts[0]=="mode":
244 sys.stderr.write("Unknown keyword '%s'\n"%parts[0])
247 self.add_section(text, literal)
252 self.add_section(text, literal)
254 def add_section(self, text, literal):
256 self.sections.append(text)
258 self.sections.append(compile(text, "-", "exec"))
260 def write(self, str, *args):
261 sys.stdout.write(str%args)
263 def writeln(self, str, *args):
264 sys.stdout.write(str%args+"\n")
266 def process_function(self, code, func):
267 if func.name in self.handcode:
275 "params": func.params
279 def process_enum(self, code, enum):
280 if enum.value is None:
290 def process_sections(self, objects, handler):
291 for sect in self.sections:
298 def process(self, apis):
299 if self.mode=="functions":
302 typemap = Typemap(api.typemap)
303 iomap = IOmap(api.iomap)
304 for spec in api.specs:
305 funcs = read_spec(spec, api.prefix)
306 for err in api.errata:
307 read_spec(err, api.prefix, funcs)
308 funcs = [f for f in funcs if f.name not in api.ignore_funcs and f.category not in api.ignore_categs]
310 func.finalize(typemap, iomap)
311 names = [f.name for f in funcs]
312 functions = [f for f in functions if f.name not in names]+funcs
313 self.process_sections(functions, self.process_function)
314 elif self.mode=="enums":
317 for spec in api.enumspecs:
318 ens = read_enums(spec, api.enumprefix)
320 enums.sort(lambda x, y: cmp(x.value, y.value)*2+cmp(x.category, y.category))
321 self.process_sections(enums, self.process_enum)
325 def __init__(self, fn):
332 self.enumprefix = None
333 self.ignore_categs = []
334 self.ignore_funcs = []
336 path = os.path.split(fn)[0]
338 for line in InputFile(fn):
340 if parts[0]=="typemap":
341 self.typemap = os.path.join(path, parts[1])
342 elif parts[0]=="iomap":
343 self.iomap = os.path.join(path, parts[1])
344 elif parts[0]=="spec":
345 self.specs.append(os.path.join(path, parts[1]))
346 elif parts[0]=="errata":
347 self.errata.append(os.path.join(path, parts[1]))
348 elif parts[0]=="prefix":
349 self.prefix = parts[1]
350 elif parts[0]=="enumspec":
351 self.enumspecs.append(os.path.join(path, parts[1]))
352 elif parts[0]=="enumprefix":
353 self.enumprefix = parts[1]
354 elif parts[0]=="ignore":
355 if parts[1]=="category":
356 self.ignore_categs.append(parts[2])
357 elif parts[1]=="function":
358 self.ignore_funcs.append(parts[2])
360 sys.stderr.write("Unknown keyword '%s'\n", parts[0])
363 def read_spec(fn, prefix, funcs=None):
368 for line in InputFile(fn):
369 if line.find(':')>=0:
371 elif line[0]=='\t' and cur_func:
373 if parts[0]=="return":
374 cur_func.ret.set_type(parts[1], "out", "value")
375 elif parts[0]=="param":
376 bracket = parts[4].find('[')
378 parts.insert(5, parts[4][bracket:])
379 parts[4] = parts[4][:bracket]
381 param = cur_func.get_param(parts[1])
382 param.set_type(parts[2], parts[3], parts[4])
383 if len(parts)==6 or (len(parts)>6 and parts[6]!="retained"):
384 param.set_size(parts[5][1:-1])
385 elif parts[0]=="category":
386 cur_func.set_category(parts[1])
387 elif parts[0]=="glxvendorglx" and cur_func.category=="glx":
388 cur_func.set_category("glxext")
390 paren = line.find('(')
392 cparen = line.rfind(')')
394 pnames = [n.strip() for n in line[paren+1:cparen].split(",")]
397 fname = prefix+line[:paren]
404 cur_func = Function(prefix+line[:paren], pnames)
405 funcs.append(cur_func)
409 def read_enums(fn, prefix):
413 for line in InputFile(fn):
415 parts = line[:line.find(':')].split()
416 if len(parts)==2 and parts[1]=="enum":
421 enums.append(Enum(prefix+parts[2], cur_categ, None))
424 enums.append(Enum(prefix+parts[0], cur_categ, int(parts[2], 0)))
425 except ValueError, e:
426 sys.stderr.write("Syntax error in %s: %s\n"%(fn, e))
431 if n.name==e.name and n.value is not None:
434 sys.stderr.write("Could not find value for enum reference %s in category %s\n"%(e.name, e.category))
438 parser = optparse.OptionParser()
439 parser.add_option("--depends", dest="depends", default=False)
440 (options, args) = parser.parse_args()
442 template = Template(args[0])
449 if template.mode=="functions":
452 deps.append(api.typemap)
453 deps.append(api.iomap)
454 elif template.mode=="enums":
456 deps += api.enumspecs
457 sys.stdout.write("%s: %s\n"%(options.depends, " ".join(deps)))
459 template.process(apis)