X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;ds=inline;f=genwrap.py;fp=genwrap.py;h=35e343952c26f8f7be422e235b66cb1b145e1771;hb=9d1825d591a7261b1cff620ba535d333352984bf;hp=0000000000000000000000000000000000000000;hpb=0d8cbda1c894f14f0c3b23f12729456020ec71b3;p=gldbg.git diff --git a/genwrap.py b/genwrap.py new file mode 100755 index 0000000..35e3439 --- /dev/null +++ b/genwrap.py @@ -0,0 +1,325 @@ +#!/usr/bin/python +# $Id$ + +import sys +import os + +outdir="gensrc" + +typemap = {} +for line in open("gl.tm"): + if line[0]=='#': + continue + parts = [p.strip() for p in line.split(',')] + typemap[parts[0]] = parts[3] +typemap["void"] = "void" + +def getparam(func, name): + for p in func[2]: + if p[0]==name: + return p + +funcs = [] +cur_func = None +for line in open("gl.spec"): + if line[0]=='#' or line.find(':')>=0: + continue + elif line[0]=='\t' and cur_func: + parts = line.split() + if parts[0]=="return": + cur_func[1] = typemap[parts[1]] + elif parts[0]=="param": + p = getparam(cur_func, parts[1]) + p[2] = parts[2] + p[1] = typemap[parts[2]] + if parts[4]=="array": + p[1] += " *" + if parts[3]=="in": + p[1] = "const "+p[1] + s = parts[5][1:-1] + if s.isdigit(): + p[3] = int(s) + elif s=="": + p[3] = "~" + else: + p[3] = s + else: + paren = line.find('(') + if paren>0: + cparen = line.rfind(')') + if cparen>paren+1: + args = line[paren+1:cparen].split(", ") + else: + args = [] + cur_func = [line[:paren], None, [[a, None, None, 0] for a in args]] + funcs.append(cur_func) + +fmtmap = {"GLenum":"%#x", + "GLboolean":"%i", + "GLbitfield":"%#x", + "GLbyte":"%i", + "GLshort":"%i", + "GLint":"%i", + "GLubyte":"%u", + "GLushort":"%u", + "GLuint":"%u", + "GLsizei":"%i", + "GLfloat":"%f", + "GLclampf":"%f", + "GLdouble":"%lf", + "GLclampd":"%lf", + "const GLubyte *":"%s", + "GLchar *":"%s", + "GLcharARB *":"%s", + "GLvoid*":"%p", + "GLsizeiptr":"%p", + "GLsizeiptrARB":"%p", + "GLintptr":"%p", + "GLintptrARB":"%p", + "GLhandleARB":"%i", + "GLhalfNV":"%#x", + "GLuint64EXT":"%lld"} + +iomap = {"GLenum":"int", + "GLboolean":"char", + "GLbitfield":"int", + "GLbyte":"char", + "GLshort":"short", + "GLint":"int", + "GLubyte":"char", + "GLushort":"short", + "GLuint":"int", + "GLsizei":"int", + "GLfloat":"float", + "GLclampf":"float", + "GLdouble":"double", + "GLclampd":"double", + "const GLubyte *":"string", + "GLchar *":"string", + "GLcharARB *":"string", + "GLvoid*":"pointer", + "GLsizeiptr":"int", + "GLsizeiptrARB":"int", + "GLintptr":"int", + "GLintptrARB":"int", + "GLhandleARB":"int", + "GLhalfNV":"short", + "GLuint64EXT":"longlong"} + +def basetype(type, is_array): + if type.startswith("const "): + type = type[6:] + if is_array and type.endswith(" *"): + type = type[:-2] + return type + +def compsize(func, size, ptype): + if not size: + return + + res = "" + have_type = False + for c in size.split('/'): + p = getparam(func, c) + if not p: + return + + if res: + res += "*" + + cn = p[2] + if cn.endswith(("EXT", "ARB", "SGI", "IBM", "ATI")): + cn = cn[:-3] + elif cn.endswith("SGIX"): + cn = cn[:-4] + elif cn.endswith(("NV", "HP")): + cn = cn[:-2] + if cn.endswith("Type"): + res += "typesize(%s)"%p[0] + have_type = True + elif cn.endswith("Format"): + res += "formatsize(%s)"%p[0] + elif cn.endswith(("Parameter", "ParameterPName", "ParameterName")) or cn=="GetPName": + res += "paramsize(%s)"%p[0] + elif cn=="MapTarget": + res += "mapsize(%s)"%p[0] + elif (cn=="SizeI" or cn.endswith("Int32")) and p[3]==0: + res += p[0] + else: + return + if not have_type: + res += "*sizeof(%s)"%ptype + return res + +def getfmt(param): + ptype = basetype(param[1], param[3]!=0) + if param[3]: + if type(param[3])==int: + return ("{%s}"%(", ".join([fmtmap[ptype]]*param[3])), ", ".join("%s[%d]"%(param[0], i) for i in range(param[3]))) + else: + return ("%p", param[0]) + else: + return (fmtmap[ptype], param[0]) + +def getwrite(func, param): + ptype = basetype(param[1], param[3]!=0) + if param[3]: + if type(param[3])==int: + size = "%d*sizeof(%s)"%(param[3], ptype) + elif param[3].startswith("COMPSIZE("): + size = compsize(func, param[3][9:-1], ptype) + if not size: + print "Compsize '%s' for function '%s' failed"%(param[3][9:-1], func[0]) + return ("pointer", None) + elif param[3]=="~" and (param[2]=="charARB" or param[2]=="Char"): + return ("string", None) + else: + s = getparam(func, param[3].split('*')[0]) + if s and (s[2]=="SizeI" or s[2].endswith("Int32")) and s[3]==0: + size = "%s*sizeof(%s)"%(param[3], ptype) + if func[0].startswith("Uniform") and func[0][8]!='u' and func[0][7].isdigit(): + size += "*%s"%func[0][7] + else: + print "Could not determine size for array parameter '%s[%s]' of function '%s'"%(param[0], param[3], func[0]) + return ("pointer", None) + return ("data", size) + else: + return (iomap[ptype], None) + +def getread(func, param): + ptype = basetype(param[1], param[3]!=0) + if param[3]: + return ("data", "(const void **)") + else: + return (iomap[ptype], "") + +# Write out function enums + +out = open(os.path.join(outdir, "functions.enum"), "w"); +out.write("""enum Function +{ + FUNC_NONE, +""") +for f in funcs: + out.write("\tFUNC_%s,\n"%f[0].upper()) +out.write("};\n") +out.close() + +# Write out wrapper functions for transmitting side + +out = open(os.path.join(outdir, "glwrap.funcs"), "w"); +for f in funcs: + 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]))) + + out.write("\tstatic %s (*orig)(%s) = NULL;\n"%(f[1], ", ".join(p[1] for p in f[2]))) + if f[1]!="void": + out.write("\t%s ret;\n"%f[1]) + out.write("\tif(!orig)\n\t\torig = glsym(\"gl%s\");\n"%f[0]) + + out.write("\t") + if f[1]!="void": + out.write("ret = ") + out.write("orig(%s);\n"%(", ".join(p[0] for p in f[2]))) + + out.write("\tbegin_packet(FUNC_%s);\n"%f[0].upper()) + if f[1]!="void": + out.write("\twrite_%s(ret);\n"%iomap[f[1]]) + for p in f[2]: + (t, s) = getwrite(f, p) + out.write("\twrite_%s(%s"%(t, p[0])) + if s: + out.write(", %s"%s) + out.write(");\n") + out.write("\tsend_packet();\n") + + if f[1]!="void": + out.write("\treturn ret;\n") + out.write("}\n\n") +out.close() + +# Write out decoder stuff + +out = open(os.path.join(outdir, "gldecoder.struct"), "w") +out.write("typedef struct sGlDecoder\n{\n") +out.write("\tvoid *user_data;\n") +out.write("\tvoid (*destroy)(void *);\n") +for f in funcs: + out.write("\tvoid (*%s)(void *"%f[0]) + if f[1]!="void": + out.write(", %s"%f[1]) + if f[2]: + out.write(", %s"%(", ".join(p[1] for p in f[2]))) + out.write(");\n") +out.write("} GlDecoder;\n") + +out = open(os.path.join(outdir, "gldecoder.funcs"), "w") +for f in funcs: + out.write("static unsigned decode_%s(GlDecoder *dec, const char *data, unsigned len)\n{\n"%(f[0])) + out.write("\tunsigned pos = 0;\n") + if f[1]!="void": + out.write("\t%s ret;\n"%f[1]) + for p in f[2]: + out.write("\t%s arg_%s;\n"%(p[1], p[0])) + if f[1]!="void": + out.write("\tpos += read_%s(&ret, data+pos, len);\n"%iomap[f[1]]) + for p in f[2]: + (t, c) = getread(f, p) + out.write("\tpos += read_%s(%s&arg_%s, data+pos, len-pos);\n"%(t, c, p[0])) + out.write("\tif(dec->%s)\n"%f[0]) + out.write("\t\tdec->%s(dec->user_data"%f[0]) + if f[1]!="void": + out.write(", ret") + if f[2]: + out.write(", %s"%(", ".join("arg_"+p[0] for p in f[2]))) + out.write(");\n") + out.write("\treturn pos;\n") + out.write("}\n\n") + +out.write("""unsigned gldecoder_decode(GlDecoder *dec, const char *data, unsigned len) +{ + unsigned pos = 0; + short func; + + pos += read_short(&func, data, len); + switch(func) + { +""") +for f in funcs: + out.write("\t\tcase FUNC_%s: pos += decode_%s(dec, data+pos, len); break;\n"%(f[0].upper(), f[0])) +out.write(""" } + + return pos; +} +""") +out.close() + +# Write out print stuff + +out = open(os.path.join(outdir, "glprint.funcs"), "w") +for f in funcs: + out.write("static void print_%s(void *user_data"%f[0]) + if f[1]!="void": + out.write(", %s ret"%f[1]) + if f[2]: + out.write(", %s"%(", ".join("%s %s"%(p[1], p[0]) for p in f[2]))) + out.write(")\n{\n") + out.write("\tGlPrintData *gpd = (GlPrintData *)user_data;\n") + + m = [getfmt(p) for p in f[2]] + out.write("\tsnprintf(gpd->buffer, gpd->bufsize, \"%s(%s)"%(f[0], ", ".join(p[0] for p in m))) + if f[1]!="void": + out.write(" = %s"%fmtmap[f[1]]) + out.write("\"") + if m: + out.write(", %s"%(", ".join(p[1] for p in m))) + if f[1]!="void": + out.write(", ret") + out.write(");\n") + + out.write("}\n\n") + +out.write("static void init_print(GlDecoder *dec)\n{\n") +for f in funcs: + out.write("\tdec->%s = print_%s;\n"%(f[0], f[0])) +out.write("}\n") +out.close()