X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=genwrap.py;fp=genwrap.py;h=0000000000000000000000000000000000000000;hb=ac7c37d7b9a42289bf221934c2e474025adf8cf4;hp=07dd914f09d20b9a5bcda4adf6fa2000f33caf52;hpb=c6dc0db8e133362e2e6402ba006f99b3b69dfce0;p=gldbg.git diff --git a/genwrap.py b/genwrap.py deleted file mode 100755 index 07dd914..0000000 --- a/genwrap.py +++ /dev/null @@ -1,354 +0,0 @@ -#!/usr/bin/python -# $Id$ - -import sys -import os - -class InputFile: - def __init__(self, fn): - self.file = open(fn) - - def __iter__(self): - for l in self.file: - h = l.find("#") - if h==0 or (h>0 and l[h-1].isspace()): - l = l[:h] - - l = l.rstrip() - if not l: - continue - - yield l - - -def strip_name(name): - """Strips any vendor suffix and GL prefix from a name (but not GLX prefix)""" - - suffix = "" - if name.endswith(" *"): - suffix = " *" - name = name[:-2] - elif name.endswith("Pointer"): - suffix = "Pointer" - name = name[:-7] - - prefix = "" - if name.startswith("const "): - prefix = "const " - name = name[6:] - - if name.startswith("GL") and not name.startswith("GLX"): - name = name[2:] - if name.endswith(("EXT", "ARB", "SGI", "IBM", "ATI")): - return prefix+name[:-3]+suffix - elif name.endswith("SGIX"): - return prefix+name[:-4]+suffix - elif name.endswith(("NV", "HP")): - return prefix+name[:-2]+suffix - else: - return prefix+name+suffix - - -class Typemap: - def __init__(self, fn): - self.map = {} - for line in InputFile(fn): - parts = [p.strip() for p in line.split(',')] - if parts[3]=="*": - parts[3] = parts[0] - elif parts[3][-1]=='*' and parts[3][-2]!=' ': - parts[3] = parts[3][:-1]+" *" - self.map[tuple(parts[0:3])] = tuple(parts[3:6]) - - def wildcard_match(self, a, b): - if a=="*" or b=="*": - return True - return a==b - - def __getitem__(self, key): - try: - return self.map[(key[0], "*", "*")] - except KeyError: - for k, v in self.map.iteritems(): - 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]): - return v - raise KeyError, key - - def update(self, other): - self.map.update(other.map) - - -class IOmap: - def __init__(self, fn): - self.map = {} - self.map["void"] = None - for line in InputFile(fn): - parts = [p.strip() for p in line.split(',')] - self.map[parts[0]] = tuple(parts[1:]) - - def __getitem__(self, key): - return self.map[strip_name(key)] - - -class Function: - class Parameter: - def __init__(self, func, name): - self.func = func - self.name = name - self.type = None - self.direction = "in" - self.kind = "value" - self.size = None - self.ctype = None - self.csize = None - self.io = None - - def set_type(self, type, dir, kind): - self.type = type - self.direction = dir - self.kind = kind - - def set_size(self, size): - if type(size)==str and size.isdigit(): - self.size = int(size) - else: - self.size = size - - def derive_ctype(self): - m = typemap[(self.type, self.direction, self.kind)] - self.ctype = m[0] - if m[1]!="*": - self.direction = m[1] - if m[2]!="*": - self.kind = m[2] - self.base_ctype = self.ctype - if self.kind=="value": - if self.base_ctype.startswith("const "): - self.base_ctype = self.base_ctype[6:] - else: - if self.direction=="in": - self.ctype = "const "+self.ctype - self.ctype = self.ctype+" *" - self.io = iomap[self.base_ctype] - - def derive_csize(self): - if self.kind=="array" and self.size is not None: - self.csize = None - if type(self.size)==int: - self.csize = "%d*sizeof(%s)"%(self.size, self.base_ctype) - elif self.size.startswith("COMPSIZE("): - self.csize = self.func.compsize(self.size[9:-1], self.base_ctype) - elif self.size=="pname": - self.csize = "paramsize(pname)*sizeof(%s)"%self.base_ctype - else: - s = self.func.get_param(self.size.split('*')[0]) - if (s.type=="SizeI" or s.type.endswith("Int32") or s.type.startswith("BufferSize")): - if s.kind=="value": - self.csize = "%s"%self.size - if self.func.name.startswith("glUniformMatrix") and self.func.name[16]!='x': - self.csize += "*%d"%(int(self.func.name[15])**2) - elif self.func.name.startswith("glUniform") and self.func.name[9].isdigit(): - self.csize += "*%s"%self.func.name[9] - if strip_name(self.base_ctype)!="void": - self.csize += "*sizeof(%s)"%self.base_ctype - elif s.kind=="array" and s.size==1: - self.csize = "*%s"%s.name - if not self.csize: - sys.stderr.write("Could not determine size for array parameter '%s[%s]' of function '%s'\n"%(self.name, self.size, self.func.name)) - elif self.kind=="reference": - self.csize = "sizeof(%s)"%self.base_ctype - - def __init__(self, name, pnames): - self.name = name - self.ret = Function.Parameter(self, "ret") - self.params = [Function.Parameter(self, n) for n in pnames] - self.category = None - - def get_param(self, pname): - for p in self.params: - if p.name==pname: - return p - raise KeyError, pname - - def set_category(self, cat): - self.category = cat - - def compsize(self, size, btype): - if not size: - return - - res = "" - have_type = False - for c in size.replace(',', '/').split('/'): - param = self.get_param(c) - if not param: - sys.stderr.write("Compsize '%s' for function '%s' failed: No parameter '%s'\n"%(size, self.name, c)) - return - - if res: - res += "*" - - cn = strip_name(param.type) - if cn.endswith("Type"): - res += "typesize(%s)"%param.name - have_type = True - elif cn.endswith("Format"): - res += "formatsize(%s)"%param.name - elif param.name=="pname" or cn.endswith("Parameter") or (param.name=="target" and cn=="enum"): - res += "paramsize(%s)"%param.name - elif param.name=="buffer" and cn=="enum": - res += "buffersize(%s)"%param.name - elif (cn=="SizeI" or cn.endswith("Int32")) and not param.size: - res += param.name - else: - sys.stderr.write("Compsize '%s' for function '%s' failed: Parameter '%s' has unknown type '%s'\n"%(size, self.name, param.name, param.type)) - return - if not have_type: - res += "*sizeof(%s)"%btype - return res - - def finalize(self): - self.ret.derive_ctype() - for p in self.params: - p.derive_ctype() - for p in self.params: - p.derive_csize() - - -class Template: - def __init__(self, fn): - self.sections = [] - self.handcode = [] - - literal = True - text = "" - for line in InputFile(fn): - if line[0]==':': - if not literal and text: - self.add_section(text, literal) - text = "" - text += line[1:]+"\n" - literal = True - elif line[0]=='!': - parts = line[1:].split() - if parts[0]=="handcode": - self.handcode.append(parts[1]) - else: - if literal and text: - self.add_section(text, literal) - text = "" - text += line+"\n" - literal = False - if text: - self.add_section(text, literal) - - def add_section(self, text, literal): - if literal: - self.sections.append(text) - else: - self.sections.append(compile(text, "-", "exec")) - - def write(self, str, *args): - sys.stdout.write(str%args) - - def writeln(self, str, *args): - sys.stdout.write(str%args+"\n") - - def process(self, functions): - for sect in self.sections: - if type(sect)==str: - print sect - else: - for func in functions: - if func.name in self.handcode: - continue - globals = { - "w": self.write, - "wl": self.writeln, - "func": func, - "ret": func.ret, - "params": func.params - } - eval(sect, globals) - - -class Files: - def __init__(self, fn): - self.typemap = None - self.iomap = None - self.specs = [] - self.prefix = None - self.ignore_categs = [] - self.ignore_funcs = [] - - for line in InputFile(fn): - parts = line.split() - if parts[0]=="typemap": - self.typemap = parts[1] - elif parts[0]=="iomap": - self.iomap = parts[1] - elif parts[0]=="spec": - self.specs.append(parts[1]) - elif parts[0]=="prefix": - self.prefix = parts[1] - elif parts[0]=="ignore": - if parts[1]=="category": - self.ignore_categs.append(parts[2]) - elif parts[1]=="function": - self.ignore_funcs.append(parts[2]) - else: - sys.stderr.write("Unknown keyword '%s'\n", parts[0]) - - -def read_spec(fn, prefix): - funcs = [] - cur_func = None - for line in InputFile(fn): - if line.find(':')>=0: - continue - elif line[0]=='\t' and cur_func: - parts = line.split() - if parts[0]=="return": - cur_func.ret.set_type(parts[1], "out", "value") - elif parts[0]=="param": - bracket = parts[4].find('[') - if bracket>=0: - parts.insert(5, parts[4][bracket:]) - parts[4] = parts[4][:bracket] - - param = cur_func.get_param(parts[1]) - param.set_type(parts[2], parts[3], parts[4]) - if len(parts)==6 or (len(parts)>6 and parts[6]!="retained"): - param.set_size(parts[5][1:-1]) - elif parts[0]=="category": - cur_func.set_category(parts[1]) - elif parts[0]=="glxvendorglx" and cur_func.category=="glx": - cur_func.set_category("glxext") - else: - paren = line.find('(') - if paren>0: - cparen = line.rfind(')') - if cparen>paren+1: - pnames = [n.strip() for n in line[paren+1:cparen].split(",")] - else: - pnames = [] - cur_func = Function(prefix+line[:paren], pnames) - funcs.append(cur_func) - return funcs - -template = Template(sys.argv[1]) -functions = [] -for i in sys.argv[2:]: - files = Files(i) - - typemap = Typemap(files.typemap) - iomap = IOmap(files.iomap) - for s in files.specs: - funcs = read_spec(s, files.prefix) - funcs = [f for f in funcs if f.name not in files.ignore_funcs and f.category not in files.ignore_categs] - for f in funcs: - f.finalize() - names = [f.name for f in funcs] - functions = [f for f in functions if f.name not in names]+funcs - -template.process(functions)