blob: 146826f07e02dd9b6bd232b2d18b2fe2c848ed59 [file] [log] [blame]
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build ignore
// The gendebug program takes gl.go and generates a version of it
// where each function includes tracing code that writes its arguments
// to the standard log.
package main
import (
"bytes"
"flag"
"fmt"
"go/ast"
"go/format"
"go/parser"
"go/printer"
"go/token"
"io/ioutil"
"log"
"os"
"strconv"
)
var enumWhitelist = []string{
"POINTS",
"LINES",
"LINE_LOOP",
"LINE_STRIP",
"TRIANGLES",
"TRIANGLE_STRIP",
"TRIANGLE_FAN",
"SRC_COLOR",
"ONE_MINUS_SRC_COLOR",
"SRC_ALPHA",
"ONE_MINUS_SRC_ALPHA",
"DST_ALPHA",
"ONE_MINUS_DST_ALPHA",
"DST_COLOR",
"ONE_MINUS_DST_COLOR",
"SRC_ALPHA_SATURATE",
"FUNC_ADD",
"BLEND_EQUATION",
"BLEND_EQUATION_RGB",
"BLEND_EQUATION_ALPHA",
"FUNC_SUBTRACT",
"FUNC_REVERSE_SUBTRACT",
"BLEND_DST_RGB",
"BLEND_SRC_RGB",
"BLEND_DST_ALPHA",
"BLEND_SRC_ALPHA",
"CONSTANT_COLOR",
"ONE_MINUS_CONSTANT_COLOR",
"CONSTANT_ALPHA",
"ONE_MINUS_CONSTANT_ALPHA",
"BLEND_COLOR",
"ARRAY_BUFFER",
"ELEMENT_ARRAY_BUFFER",
"ARRAY_BUFFER_BINDING",
"ELEMENT_ARRAY_BUFFER_BINDING",
"STREAM_DRAW",
"STATIC_DRAW",
"DYNAMIC_DRAW",
"BUFFER_SIZE",
"BUFFER_USAGE",
"CURRENT_VERTEX_ATTRIB",
"FRONT",
"BACK",
"FRONT_AND_BACK",
"TEXTURE_2D",
"CULL_FACE",
"BLEND",
"DITHER",
"STENCIL_TEST",
"DEPTH_TEST",
"SCISSOR_TEST",
"POLYGON_OFFSET_FILL",
"SAMPLE_ALPHA_TO_COVERAGE",
"SAMPLE_COVERAGE",
"INVALID_ENUM",
"INVALID_VALUE",
"INVALID_OPERATION",
"OUT_OF_MEMORY",
"CW",
"CCW",
"LINE_WIDTH",
"ALIASED_POINT_SIZE_RANGE",
"ALIASED_LINE_WIDTH_RANGE",
"CULL_FACE_MODE",
"FRONT_FACE",
"DEPTH_RANGE",
"DEPTH_WRITEMASK",
"DEPTH_CLEAR_VALUE",
"DEPTH_FUNC",
"STENCIL_CLEAR_VALUE",
"STENCIL_FUNC",
"STENCIL_FAIL",
"STENCIL_PASS_DEPTH_FAIL",
"STENCIL_PASS_DEPTH_PASS",
"STENCIL_REF",
"STENCIL_VALUE_MASK",
"STENCIL_WRITEMASK",
"STENCIL_BACK_FUNC",
"STENCIL_BACK_FAIL",
"STENCIL_BACK_PASS_DEPTH_FAIL",
"STENCIL_BACK_PASS_DEPTH_PASS",
"STENCIL_BACK_REF",
"STENCIL_BACK_VALUE_MASK",
"STENCIL_BACK_WRITEMASK",
"VIEWPORT",
"SCISSOR_BOX",
"COLOR_CLEAR_VALUE",
"COLOR_WRITEMASK",
"UNPACK_ALIGNMENT",
"PACK_ALIGNMENT",
"MAX_TEXTURE_SIZE",
"MAX_VIEWPORT_DIMS",
"SUBPIXEL_BITS",
"RED_BITS",
"GREEN_BITS",
"BLUE_BITS",
"ALPHA_BITS",
"DEPTH_BITS",
"STENCIL_BITS",
"POLYGON_OFFSET_UNITS",
"POLYGON_OFFSET_FACTOR",
"TEXTURE_BINDING_2D",
"SAMPLE_BUFFERS",
"SAMPLES",
"SAMPLE_COVERAGE_VALUE",
"SAMPLE_COVERAGE_INVERT",
"NUM_COMPRESSED_TEXTURE_FORMATS",
"COMPRESSED_TEXTURE_FORMATS",
"DONT_CARE",
"FASTEST",
"NICEST",
"GENERATE_MIPMAP_HINT",
"BYTE",
"UNSIGNED_BYTE",
"SHORT",
"UNSIGNED_SHORT",
"INT",
"UNSIGNED_INT",
"FLOAT",
"FIXED",
"DEPTH_COMPONENT",
"ALPHA",
"RGB",
"RGBA",
"LUMINANCE",
"LUMINANCE_ALPHA",
"UNSIGNED_SHORT_4_4_4_4",
"UNSIGNED_SHORT_5_5_5_1",
"UNSIGNED_SHORT_5_6_5",
"MAX_VERTEX_ATTRIBS",
"MAX_VERTEX_UNIFORM_VECTORS",
"MAX_VARYING_VECTORS",
"MAX_COMBINED_TEXTURE_IMAGE_UNITS",
"MAX_VERTEX_TEXTURE_IMAGE_UNITS",
"MAX_TEXTURE_IMAGE_UNITS",
"MAX_FRAGMENT_UNIFORM_VECTORS",
"SHADER_TYPE",
"DELETE_STATUS",
"LINK_STATUS",
"VALIDATE_STATUS",
"ATTACHED_SHADERS",
"ACTIVE_UNIFORMS",
"ACTIVE_UNIFORM_MAX_LENGTH",
"ACTIVE_ATTRIBUTES",
"ACTIVE_ATTRIBUTE_MAX_LENGTH",
"SHADING_LANGUAGE_VERSION",
"CURRENT_PROGRAM",
"NEVER",
"LESS",
"EQUAL",
"LEQUAL",
"GREATER",
"NOTEQUAL",
"GEQUAL",
"ALWAYS",
"KEEP",
"REPLACE",
"INCR",
"DECR",
"INVERT",
"INCR_WRAP",
"DECR_WRAP",
"VENDOR",
"RENDERER",
"VERSION",
"EXTENSIONS",
"NEAREST",
"LINEAR",
"NEAREST_MIPMAP_NEAREST",
"LINEAR_MIPMAP_NEAREST",
"NEAREST_MIPMAP_LINEAR",
"LINEAR_MIPMAP_LINEAR",
"TEXTURE_MAG_FILTER",
"TEXTURE_MIN_FILTER",
"TEXTURE_WRAP_S",
"TEXTURE_WRAP_T",
"TEXTURE",
"TEXTURE_CUBE_MAP",
"TEXTURE_BINDING_CUBE_MAP",
"TEXTURE_CUBE_MAP_POSITIVE_X",
"TEXTURE_CUBE_MAP_NEGATIVE_X",
"TEXTURE_CUBE_MAP_POSITIVE_Y",
"TEXTURE_CUBE_MAP_NEGATIVE_Y",
"TEXTURE_CUBE_MAP_POSITIVE_Z",
"TEXTURE_CUBE_MAP_NEGATIVE_Z",
"MAX_CUBE_MAP_TEXTURE_SIZE",
"TEXTURE0",
"TEXTURE1",
"TEXTURE2",
"TEXTURE3",
"TEXTURE4",
"TEXTURE5",
"TEXTURE6",
"TEXTURE7",
"TEXTURE8",
"TEXTURE9",
"TEXTURE10",
"TEXTURE11",
"TEXTURE12",
"TEXTURE13",
"TEXTURE14",
"TEXTURE15",
"TEXTURE16",
"TEXTURE17",
"TEXTURE18",
"TEXTURE19",
"TEXTURE20",
"TEXTURE21",
"TEXTURE22",
"TEXTURE23",
"TEXTURE24",
"TEXTURE25",
"TEXTURE26",
"TEXTURE27",
"TEXTURE28",
"TEXTURE29",
"TEXTURE30",
"TEXTURE31",
"ACTIVE_TEXTURE",
"REPEAT",
"CLAMP_TO_EDGE",
"MIRRORED_REPEAT",
"VERTEX_ATTRIB_ARRAY_ENABLED",
"VERTEX_ATTRIB_ARRAY_SIZE",
"VERTEX_ATTRIB_ARRAY_STRIDE",
"VERTEX_ATTRIB_ARRAY_TYPE",
"VERTEX_ATTRIB_ARRAY_NORMALIZED",
"VERTEX_ATTRIB_ARRAY_POINTER",
"VERTEX_ATTRIB_ARRAY_BUFFER_BINDING",
"IMPLEMENTATION_COLOR_READ_TYPE",
"IMPLEMENTATION_COLOR_READ_FORMAT",
"COMPILE_STATUS",
"INFO_LOG_LENGTH",
"SHADER_SOURCE_LENGTH",
"SHADER_COMPILER",
"SHADER_BINARY_FORMATS",
"NUM_SHADER_BINARY_FORMATS",
"LOW_FLOAT",
"MEDIUM_FLOAT",
"HIGH_FLOAT",
"LOW_INT",
"MEDIUM_INT",
"HIGH_INT",
"FRAMEBUFFER",
"RENDERBUFFER",
"RGBA4",
"RGB5_A1",
"RGB565",
"DEPTH_COMPONENT16",
"STENCIL_INDEX8",
"RENDERBUFFER_WIDTH",
"RENDERBUFFER_HEIGHT",
"RENDERBUFFER_INTERNAL_FORMAT",
"RENDERBUFFER_RED_SIZE",
"RENDERBUFFER_GREEN_SIZE",
"RENDERBUFFER_BLUE_SIZE",
"RENDERBUFFER_ALPHA_SIZE",
"RENDERBUFFER_DEPTH_SIZE",
"RENDERBUFFER_STENCIL_SIZE",
"FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE",
"FRAMEBUFFER_ATTACHMENT_OBJECT_NAME",
"FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL",
"FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE",
"COLOR_ATTACHMENT0",
"DEPTH_ATTACHMENT",
"STENCIL_ATTACHMENT",
"FRAMEBUFFER_COMPLETE",
"FRAMEBUFFER_INCOMPLETE_ATTACHMENT",
"FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT",
"FRAMEBUFFER_INCOMPLETE_DIMENSIONS",
"FRAMEBUFFER_UNSUPPORTED",
"FRAMEBUFFER_BINDING",
"RENDERBUFFER_BINDING",
"MAX_RENDERBUFFER_SIZE",
"INVALID_FRAMEBUFFER_OPERATION",
"DEPTH_BUFFER_BIT",
"STENCIL_BUFFER_BIT",
"COLOR_BUFFER_BIT",
"FLOAT_VEC2",
"FLOAT_VEC3",
"FLOAT_VEC4",
"INT_VEC2",
"INT_VEC3",
"INT_VEC4",
"BOOL",
"BOOL_VEC2",
"BOOL_VEC3",
"BOOL_VEC4",
"FLOAT_MAT2",
"FLOAT_MAT3",
"FLOAT_MAT4",
"SAMPLER_2D",
"SAMPLER_CUBE",
"FRAGMENT_SHADER",
"VERTEX_SHADER",
"FALSE",
"TRUE",
"ZERO",
"ONE",
"NO_ERROR",
"NONE",
"ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH",
"ACTIVE_UNIFORM_BLOCKS",
"ALREADY_SIGNALED",
"ANY_SAMPLES_PASSED",
"ANY_SAMPLES_PASSED_CONSERVATIVE",
"BLUE",
"BUFFER_ACCESS_FLAGS",
"BUFFER_MAP_LENGTH",
"BUFFER_MAP_OFFSET",
"BUFFER_MAPPED",
"BUFFER_MAP_POINTER",
"COLOR",
"COLOR_ATTACHMENT10",
"COLOR_ATTACHMENT1",
"COLOR_ATTACHMENT11",
"COLOR_ATTACHMENT12",
"COLOR_ATTACHMENT13",
"COLOR_ATTACHMENT14",
"COLOR_ATTACHMENT15",
"COLOR_ATTACHMENT2",
"COLOR_ATTACHMENT3",
"COLOR_ATTACHMENT4",
"COLOR_ATTACHMENT5",
"COLOR_ATTACHMENT6",
"COLOR_ATTACHMENT7",
"COLOR_ATTACHMENT8",
"COLOR_ATTACHMENT9",
"COMPARE_REF_TO_TEXTURE",
"COMPRESSED_R11_EAC",
"COMPRESSED_RG11_EAC",
"COMPRESSED_RGB8_ETC2",
"COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2",
"COMPRESSED_RGBA8_ETC2_EAC",
"COMPRESSED_SIGNED_R11_EAC",
"COMPRESSED_SIGNED_RG11_EAC",
"COMPRESSED_SRGB8_ALPHA8_ETC2_EAC",
"COMPRESSED_SRGB8_ETC2",
"COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2",
"CONDITION_SATISFIED",
"COPY_READ_BUFFER",
"COPY_READ_BUFFER_BINDING",
"COPY_WRITE_BUFFER",
"COPY_WRITE_BUFFER_BINDING",
"CURRENT_QUERY",
"DEPTH",
"DEPTH24_STENCIL8",
"DEPTH32F_STENCIL8",
"DEPTH_COMPONENT24",
"DEPTH_COMPONENT32F",
"DEPTH_STENCIL",
"DEPTH_STENCIL_ATTACHMENT",
"DRAW_BUFFER0",
"DRAW_BUFFER10",
"DRAW_BUFFER1",
"DRAW_BUFFER11",
"DRAW_BUFFER12",
"DRAW_BUFFER13",
"DRAW_BUFFER14",
"DRAW_BUFFER15",
"DRAW_BUFFER2",
"DRAW_BUFFER3",
"DRAW_BUFFER4",
"DRAW_BUFFER5",
"DRAW_BUFFER6",
"DRAW_BUFFER7",
"DRAW_BUFFER8",
"DRAW_BUFFER9",
"DRAW_FRAMEBUFFER",
"DRAW_FRAMEBUFFER_BINDING",
"DYNAMIC_COPY",
"DYNAMIC_READ",
"FLOAT_32_UNSIGNED_INT_24_8_REV",
"FLOAT_MAT2x3",
"FLOAT_MAT2x4",
"FLOAT_MAT3x2",
"FLOAT_MAT3x4",
"FLOAT_MAT4x2",
"FLOAT_MAT4x3",
"FRAGMENT_SHADER_DERIVATIVE_HINT",
"FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE",
"FRAMEBUFFER_ATTACHMENT_BLUE_SIZE",
"FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING",
"FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE",
"FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE",
"FRAMEBUFFER_ATTACHMENT_GREEN_SIZE",
"FRAMEBUFFER_ATTACHMENT_RED_SIZE",
"FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE",
"FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER",
"FRAMEBUFFER_DEFAULT",
"FRAMEBUFFER_INCOMPLETE_MULTISAMPLE",
"FRAMEBUFFER_UNDEFINED",
"GREEN",
"HALF_FLOAT",
"INT_2_10_10_10_REV",
"INTERLEAVED_ATTRIBS",
"INT_SAMPLER_2D",
"INT_SAMPLER_2D_ARRAY",
"INT_SAMPLER_3D",
"INT_SAMPLER_CUBE",
"INVALID_INDEX",
"MAJOR_VERSION",
"MAP_FLUSH_EXPLICIT_BIT",
"MAP_INVALIDATE_BUFFER_BIT",
"MAP_INVALIDATE_RANGE_BIT",
"MAP_READ_BIT",
"MAP_UNSYNCHRONIZED_BIT",
"MAP_WRITE_BIT",
"MAX",
"MAX_3D_TEXTURE_SIZE",
"MAX_ARRAY_TEXTURE_LAYERS",
"MAX_COLOR_ATTACHMENTS",
"MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS",
"MAX_COMBINED_UNIFORM_BLOCKS",
"MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS",
"MAX_DRAW_BUFFERS",
"MAX_ELEMENT_INDEX",
"MAX_ELEMENTS_INDICES",
"MAX_ELEMENTS_VERTICES",
"MAX_FRAGMENT_INPUT_COMPONENTS",
"MAX_FRAGMENT_UNIFORM_BLOCKS",
"MAX_FRAGMENT_UNIFORM_COMPONENTS",
"MAX_PROGRAM_TEXEL_OFFSET",
"MAX_SAMPLES",
"MAX_SERVER_WAIT_TIMEOUT",
"MAX_TEXTURE_LOD_BIAS",
"MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS",
"MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS",
"MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS",
"MAX_UNIFORM_BLOCK_SIZE",
"MAX_UNIFORM_BUFFER_BINDINGS",
"MAX_VARYING_COMPONENTS",
"MAX_VERTEX_OUTPUT_COMPONENTS",
"MAX_VERTEX_UNIFORM_BLOCKS",
"MAX_VERTEX_UNIFORM_COMPONENTS",
"MIN",
"MINOR_VERSION",
"MIN_PROGRAM_TEXEL_OFFSET",
"NUM_EXTENSIONS",
"NUM_PROGRAM_BINARY_FORMATS",
"NUM_SAMPLE_COUNTS",
"OBJECT_TYPE",
"PACK_ROW_LENGTH",
"PACK_SKIP_PIXELS",
"PACK_SKIP_ROWS",
"PIXEL_PACK_BUFFER",
"PIXEL_PACK_BUFFER_BINDING",
"PIXEL_UNPACK_BUFFER",
"PIXEL_UNPACK_BUFFER_BINDING",
"PRIMITIVE_RESTART_FIXED_INDEX",
"PROGRAM_BINARY_FORMATS",
"PROGRAM_BINARY_LENGTH",
"PROGRAM_BINARY_RETRIEVABLE_HINT",
"QUERY_RESULT",
"QUERY_RESULT_AVAILABLE",
"R11F_G11F_B10F",
"R16F",
"R16I",
"R16UI",
"R32F",
"R32I",
"R32UI",
"R8",
"R8I",
"R8_SNORM",
"R8UI",
"RASTERIZER_DISCARD",
"READ_BUFFER",
"READ_FRAMEBUFFER",
"READ_FRAMEBUFFER_BINDING",
"RED",
"RED_INTEGER",
"RENDERBUFFER_SAMPLES",
"RG",
"RG16F",
"RG16I",
"RG16UI",
"RG32F",
"RG32I",
"RG32UI",
"RG8",
"RG8I",
"RG8_SNORM",
"RG8UI",
"RGB10_A2",
"RGB10_A2UI",
"RGB16F",
"RGB16I",
"RGB16UI",
"RGB32F",
"RGB32I",
"RGB32UI",
"RGB8",
"RGB8I",
"RGB8_SNORM",
"RGB8UI",
"RGB9_E5",
"RGBA16F",
"RGBA16I",
"RGBA16UI",
"RGBA32F",
"RGBA32I",
"RGBA32UI",
"RGBA8",
"RGBA8I",
"RGBA8_SNORM",
"RGBA8UI",
"RGBA_INTEGER",
"RGB_INTEGER",
"RG_INTEGER",
"SAMPLER_2D_ARRAY",
"SAMPLER_2D_ARRAY_SHADOW",
"SAMPLER_2D_SHADOW",
"SAMPLER_3D",
"SAMPLER_BINDING",
"SAMPLER_CUBE_SHADOW",
"SEPARATE_ATTRIBS",
"SIGNALED",
"SIGNED_NORMALIZED",
"SRGB",
"SRGB8",
"SRGB8_ALPHA8",
"STATIC_COPY",
"STATIC_READ",
"STENCIL",
"STREAM_COPY",
"STREAM_READ",
"SYNC_CONDITION",
"SYNC_FENCE",
"SYNC_FLAGS",
"SYNC_FLUSH_COMMANDS_BIT",
"SYNC_GPU_COMMANDS_COMPLETE",
"SYNC_STATUS",
"TEXTURE_2D_ARRAY",
"TEXTURE_3D",
"TEXTURE_BASE_LEVEL",
"TEXTURE_BINDING_2D_ARRAY",
"TEXTURE_BINDING_3D",
"TEXTURE_COMPARE_FUNC",
"TEXTURE_COMPARE_MODE",
"TEXTURE_IMMUTABLE_FORMAT",
"TEXTURE_IMMUTABLE_LEVELS",
"TEXTURE_MAX_LEVEL",
"TEXTURE_MAX_LOD",
"TEXTURE_MIN_LOD",
"TEXTURE_SWIZZLE_A",
"TEXTURE_SWIZZLE_B",
"TEXTURE_SWIZZLE_G",
"TEXTURE_SWIZZLE_R",
"TEXTURE_WRAP_R",
"TIMEOUT_EXPIRED",
"TRANSFORM_FEEDBACK",
"TRANSFORM_FEEDBACK_ACTIVE",
"TRANSFORM_FEEDBACK_BINDING",
"TRANSFORM_FEEDBACK_BUFFER",
"TRANSFORM_FEEDBACK_BUFFER_BINDING",
"TRANSFORM_FEEDBACK_BUFFER_MODE",
"TRANSFORM_FEEDBACK_BUFFER_SIZE",
"TRANSFORM_FEEDBACK_BUFFER_START",
"TRANSFORM_FEEDBACK_PAUSED",
"TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN",
"TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH",
"TRANSFORM_FEEDBACK_VARYINGS",
"UNIFORM_ARRAY_STRIDE",
"UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES",
"UNIFORM_BLOCK_ACTIVE_UNIFORMS",
"UNIFORM_BLOCK_BINDING",
"UNIFORM_BLOCK_DATA_SIZE",
"UNIFORM_BLOCK_INDEX",
"UNIFORM_BLOCK_NAME_LENGTH",
"UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER",
"UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER",
"UNIFORM_BUFFER",
"UNIFORM_BUFFER_BINDING",
"UNIFORM_BUFFER_OFFSET_ALIGNMENT",
"UNIFORM_BUFFER_SIZE",
"UNIFORM_BUFFER_START",
"UNIFORM_IS_ROW_MAJOR",
"UNIFORM_MATRIX_STRIDE",
"UNIFORM_NAME_LENGTH",
"UNIFORM_OFFSET",
"UNIFORM_SIZE",
"UNIFORM_TYPE",
"UNPACK_IMAGE_HEIGHT",
"UNPACK_ROW_LENGTH",
"UNPACK_SKIP_IMAGES",
"UNPACK_SKIP_PIXELS",
"UNPACK_SKIP_ROWS",
"UNSIGNALED",
"UNSIGNED_INT_10F_11F_11F_REV",
"UNSIGNED_INT_2_10_10_10_REV",
"UNSIGNED_INT_24_8",
"UNSIGNED_INT_5_9_9_9_REV",
"UNSIGNED_INT_SAMPLER_2D",
"UNSIGNED_INT_SAMPLER_2D_ARRAY",
"UNSIGNED_INT_SAMPLER_3D",
"UNSIGNED_INT_SAMPLER_CUBE",
"UNSIGNED_INT_VEC2",
"UNSIGNED_INT_VEC3",
"UNSIGNED_INT_VEC4",
"UNSIGNED_NORMALIZED",
"VERTEX_ARRAY_BINDING",
"VERTEX_ATTRIB_ARRAY_DIVISOR",
"VERTEX_ATTRIB_ARRAY_INTEGER",
"WAIT_FAILED",
}
var outfile = flag.String("o", "", "result will be written to the file instead of stdout.")
var fset = new(token.FileSet)
func typeString(t ast.Expr) string {
buf := new(bytes.Buffer)
printer.Fprint(buf, fset, t)
return buf.String()
}
func typePrinter(t string) string {
switch t {
case "[]float32", "[]byte":
return "len(%d)"
}
return "%v"
}
func typePrinterArg(t, name string) string {
switch t {
case "[]float32", "[]byte":
return "len(" + name + ")"
}
return name
}
func die(err error) {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
func main() {
flag.Parse()
f, err := parser.ParseFile(fset, "consts.go", nil, parser.ParseComments)
if err != nil {
die(err)
}
entries := enum(f)
f, err = parser.ParseFile(fset, "gl.go", nil, parser.ParseComments)
if err != nil {
die(err)
}
buf := new(bytes.Buffer)
fmt.Fprint(buf, preamble)
fmt.Fprintf(buf, "func (v Enum) String() string {\n")
fmt.Fprintf(buf, "\tswitch v {\n")
for _, e := range dedup(entries) {
fmt.Fprintf(buf, "\tcase 0x%x: return %q\n", e.value, e.name)
}
fmt.Fprintf(buf, "\t%s\n", `default: return fmt.Sprintf("gl.Enum(0x%x)", uint32(v))`)
fmt.Fprintf(buf, "\t}\n")
fmt.Fprintf(buf, "}\n\n")
for _, d := range f.Decls {
// Before:
// func (ctx *context) StencilMask(mask uint32) {
// C.glStencilMask(C.GLuint(mask))
// }
//
// After:
// func (ctx *context) StencilMask(mask uint32) {
// defer func() {
// errstr := ctx.errDrain()
// log.Printf("gl.StencilMask(%v) %v", mask, errstr)
// }()
// C.glStencilMask(C.GLuint(mask))
// }
fn, ok := d.(*ast.FuncDecl)
if !ok {
continue
}
if fn.Recv == nil || fn.Recv.List[0].Names[0].Name != "ctx" {
continue
}
tname := "<unknown>"
t := fn.Recv.List[0].Type
if star, ok := t.(*ast.StarExpr); ok {
tname = "*" + star.X.(*ast.Ident).Name
} else if t, ok := t.(*ast.Ident); ok {
tname = t.Name
}
var (
params []string
paramTypes []string
results []string
resultTypes []string
)
// Print function signature.
fmt.Fprintf(buf, "func (ctx %s) %s(", tname, fn.Name.Name)
for i, p := range fn.Type.Params.List {
if i > 0 {
fmt.Fprint(buf, ", ")
}
ty := typeString(p.Type)
for i, n := range p.Names {
if i > 0 {
fmt.Fprint(buf, ", ")
}
fmt.Fprintf(buf, "%s ", n.Name)
params = append(params, n.Name)
paramTypes = append(paramTypes, ty)
}
fmt.Fprint(buf, ty)
}
fmt.Fprintf(buf, ") (")
if fn.Type.Results != nil {
for i, r := range fn.Type.Results.List {
if i > 0 {
fmt.Fprint(buf, ", ")
}
ty := typeString(r.Type)
if len(r.Names) == 0 {
name := fmt.Sprintf("r%d", i)
fmt.Fprintf(buf, "%s ", name)
results = append(results, name)
resultTypes = append(resultTypes, ty)
}
for i, n := range r.Names {
if i > 0 {
fmt.Fprint(buf, ", ")
}
fmt.Fprintf(buf, "%s ", n.Name)
results = append(results, n.Name)
resultTypes = append(resultTypes, ty)
}
fmt.Fprint(buf, ty)
}
}
fmt.Fprintf(buf, ") {\n")
// gl.GetError is used by errDrain, which will be made part of
// all functions. So do not apply it to gl.GetError to avoid
// infinite recursion.
skip := fn.Name.Name == "GetError"
if !skip {
// Insert a defer block for tracing.
fmt.Fprintf(buf, "defer func() {\n")
fmt.Fprintf(buf, "\terrstr := ctx.errDrain()\n")
switch fn.Name.Name {
case "GetUniformLocation", "GetAttribLocation":
fmt.Fprintf(buf, "\tr0.name = name\n")
}
fmt.Fprintf(buf, "\tlog.Printf(\"gl.%s(", fn.Name.Name)
for i, p := range paramTypes {
if i > 0 {
fmt.Fprint(buf, ", ")
}
fmt.Fprint(buf, typePrinter(p))
}
fmt.Fprintf(buf, ") ")
if len(resultTypes) > 1 {
fmt.Fprint(buf, "(")
}
for i, r := range resultTypes {
if i > 0 {
fmt.Fprint(buf, ", ")
}
fmt.Fprint(buf, typePrinter(r))
}
if len(resultTypes) > 1 {
fmt.Fprint(buf, ") ")
}
fmt.Fprintf(buf, "%%v\"")
for i, p := range paramTypes {
fmt.Fprintf(buf, ", %s", typePrinterArg(p, params[i]))
}
for i, r := range resultTypes {
fmt.Fprintf(buf, ", %s", typePrinterArg(r, results[i]))
}
fmt.Fprintf(buf, ", errstr)\n")
fmt.Fprintf(buf, "}()\n")
}
// Print original body of function.
for _, s := range fn.Body.List {
if c := enqueueCall(s); c != nil {
c.Fun.(*ast.SelectorExpr).Sel.Name = "enqueueDebug"
setEnqueueBlocking(c)
}
printer.Fprint(buf, fset, s)
fmt.Fprintf(buf, "\n")
}
fmt.Fprintf(buf, "}\n\n")
}
b, err := format.Source(buf.Bytes())
if err != nil {
os.Stdout.Write(buf.Bytes())
die(err)
}
if *outfile == "" {
os.Stdout.Write(b)
return
}
if err := ioutil.WriteFile(*outfile, b, 0666); err != nil {
die(err)
}
}
func enqueueCall(stmt ast.Stmt) *ast.CallExpr {
exprStmt, ok := stmt.(*ast.ExprStmt)
if !ok {
return nil
}
call, ok := exprStmt.X.(*ast.CallExpr)
if !ok {
return nil
}
fun, ok := call.Fun.(*ast.SelectorExpr)
if !ok {
return nil
}
if fun.Sel.Name != "enqueue" {
return nil
}
return call
}
func setEnqueueBlocking(c *ast.CallExpr) {
lit := c.Args[0].(*ast.CompositeLit)
for _, elt := range lit.Elts {
kv := elt.(*ast.KeyValueExpr)
if kv.Key.(*ast.Ident).Name == "blocking" {
kv.Value = &ast.Ident{Name: "true"}
return
}
}
lit.Elts = append(lit.Elts, &ast.KeyValueExpr{
Key: &ast.Ident{
NamePos: lit.Rbrace,
Name: "blocking",
},
Value: &ast.Ident{Name: "true"},
})
}
const preamble = `// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Code generated from gl.go using go generate. DO NOT EDIT.
// See doc.go for details.
//go:build (darwin || linux || openbsd || windows) && gldebug
package gl
import (
"fmt"
"log"
"math"
"sync/atomic"
"unsafe"
)
func (ctx *context) errDrain() string {
var errs []Enum
for {
e := ctx.GetError()
if e == 0 {
break
}
errs = append(errs, e)
}
if len(errs) > 0 {
return fmt.Sprintf(" error: %v", errs)
}
return ""
}
func (ctx *context) enqueueDebug(c call) uintptr {
numCalls := atomic.AddInt32(&ctx.debug, 1)
if numCalls > 1 {
panic("concurrent calls made to the same GL context")
}
defer func() {
if atomic.AddInt32(&ctx.debug, -1) > 0 {
select {} // block so you see us in the panic
}
}()
return ctx.enqueue(c)
}
`
type entry struct {
name string
value uint64
}
func genWhitelistMap(whitelist []string) map[string]bool {
m := make(map[string]bool)
for _, v := range enumWhitelist {
m[v] = true
}
return m
}
// enum builds a list of all GL constants that make up the gl.Enum type.
func enum(f *ast.File) []entry {
var entries []entry
whitelist := genWhitelistMap(enumWhitelist)
for _, d := range f.Decls {
gendecl, ok := d.(*ast.GenDecl)
if !ok {
continue
}
if gendecl.Tok != token.CONST {
continue
}
for _, s := range gendecl.Specs {
v, ok := s.(*ast.ValueSpec)
if !ok {
continue
}
if len(v.Names) != 1 || len(v.Values) != 1 {
continue
}
if _, ok := whitelist[v.Names[0].Name]; !ok {
continue
}
val, err := strconv.ParseUint(v.Values[0].(*ast.BasicLit).Value, 0, 64)
if err != nil {
log.Fatalf("enum %s: %v", v.Names[0].Name, err)
}
entries = append(entries, entry{v.Names[0].Name, val})
}
}
return entries
}
func dedup(entries []entry) []entry {
// Find all duplicates. Use "%d" as the name of any value with duplicates.
seen := make(map[uint64]int)
for _, e := range entries {
seen[e.value]++
}
var dedup []entry
for _, e := range entries {
switch seen[e.value] {
case 0: // skip, already here
case 1:
dedup = append(dedup, e)
default:
// value is duplicated
dedup = append(dedup, entry{fmt.Sprintf("%d", e.value), e.value})
seen[e.value] = 0
}
}
return dedup
}