-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)\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);\n"%iomap[f[1]])
- for p in f[2]:
- (t, c) = getread(f, p)
- out.write("\tpos += read_%s(%s&arg_%s, data+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("""static int decode_func(GlDecoder *dec, short func, const char *data)
-{
- switch(func)
- {
-""")
-for f in funcs:
- out.write("\t\tcase FUNC_%s: return decode_%s(dec, data);\n"%(f[0].upper(), f[0]))
-out.write(""" }
-
- return -1;
-}
-""")
-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()
+ 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)