| // 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 |
| } |