From ef683c5d010a8da07c5e00eb9e143f0acd27f012 Mon Sep 17 00:00:00 2001 From: Christian Haas Date: Sat, 23 May 2020 13:30:31 +0200 Subject: [PATCH 01/15] Ignoring GoLand directory --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index eba8521..cdbfd6e 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,6 @@ wgl # Vim *.swp *.swo + +# GoLand +.idea/ From 5545d4dc20ca7da9bd57dde9363f6d09fe0caf88 Mon Sep 17 00:00:00 2001 From: Christian Haas Date: Sat, 23 May 2020 15:40:02 +0200 Subject: [PATCH 02/15] first attempt at providing overloads --- functions.go | 10 ++++++++++ tmpl/package.tmpl | 21 ++++++++++++++++++++- type.go | 3 +++ type_test.go | 30 ++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 type_test.go diff --git a/functions.go b/functions.go index 4a1f6e0..ffa91c3 100644 --- a/functions.go +++ b/functions.go @@ -8,6 +8,16 @@ type Function struct { GoName string // Go name of the function with the API prefix stripped Parameters []Parameter Return Type + Overloads []Overload +} + +// An Overload describes an alternative signature for the same function. +type Overload struct { + Name string // C name of the original function + GoName string // Go name of the original function + OverloadName string // Go name of the overload + Parameters []Parameter + Return Type } // A Parameter to a Function. diff --git a/tmpl/package.tmpl b/tmpl/package.tmpl index a44f6f6..b5f7259 100644 --- a/tmpl/package.tmpl +++ b/tmpl/package.tmpl @@ -19,7 +19,7 @@ package {{.Name}} //glow:rmspace {{define "paramsCDecl"}}{{range $i, $p := .}}{{if ne $i 0}}, {{end}}{{$p.Type.CType}} {{$p.CName}}{{end}}{{end}} -{{define "paramsCCall"}}{{range $i, $p := .}}{{if ne $i 0}}, {{end}}{{if $p.Type.IsDebugProc}}glowCDebugCallback{{else}}{{$p.CName}}{{end}}{{end}}{{end}} +{{define "paramsCCall"}}{{range $i, $p := .}}{{if ne $i 0}}, {{end}}{{if $p.Type.IsDebugProc}}glowCDebugCallback{{else}}{{if ge (len $p.Type.Cast) 1}}({{$p.Type.Cast}})({{end}}{{$p.CName}}{{if ge (len $p.Type.Cast) 1}}){{end}}{{end}}{{end}}{{end}} {{define "paramsGoDecl"}}{{range $i, $p := .}}{{if ne $i 0}}, {{end}}{{$p.GoName}} {{$p.Type.GoType}}{{end}}{{end}} {{define "paramsGoCall"}}{{range $i, $p := .}}{{if ne $i 0}}, {{end}}{{$p.Type.ConvertGoToC $p.GoName}}{{end}}{{end}} @@ -66,6 +66,11 @@ package {{.Name}} // static {{.Return.CType}} glow{{.GoName}}(GP{{toUpper .GoName}} fnptr{{if ge (len .Parameters) 1}}, {{end}}{{template "paramsCDecl" .Parameters}}) { // {{if not .Return.IsVoid}}return {{end}}(*fnptr)({{template "paramsCCall" .Parameters}}); // } +// {{range .Overloads}} +// static {{.Return.CType}} glow{{.OverloadName}}(GP{{toUpper .GoName}} fnptr{{if ge (len .Parameters) 1}}, {{end}}{{template "paramsCDecl" .Parameters}}) { +// {{if not .Return.IsVoid}}return {{end}}(*fnptr)({{template "paramsCCall" .Parameters}}); +// } +// {{end}} // {{end}} // import "C" @@ -95,6 +100,7 @@ func boolToInt(b bool) int { } {{define "bridgeCall"}}C.glow{{.GoName}}(gp{{.GoName}}{{if ge (len .Parameters) 1}}, {{end}}{{template "paramsGoCall" .Parameters}}){{end}} +{{define "overloadCall"}}C.glow{{.OverloadName}}(gp{{.GoName}}{{if ge (len .Parameters) 1}}, {{end}}{{template "paramsGoCall" .Parameters}}){{end}} {{range .Functions}} {{.Comment}} func {{.GoName}}({{template "paramsGoDecl" .Parameters}}){{if not .Return.IsVoid}} {{.Return.GoType}}{{end}} { @@ -107,6 +113,19 @@ func {{.GoName}}({{template "paramsGoDecl" .Parameters}}){{if not .Return.IsVoid return {{.Return.ConvertCToGo "ret"}} {{end}} } +{{range .Overloads}} + +func {{.OverloadName}}({{template "paramsGoDecl" .Parameters}}){{if not .Return.IsVoid}} {{.Return.GoType}}{{end}} { + {{range .Parameters}} + {{if .Type.IsDebugProc}}userDebugCallback = {{.GoName}}{{end}} + {{end}} + {{if .Return.IsVoid}}{{template "overloadCall" .}} + {{else}} + ret := {{template "overloadCall" .}} + return {{.Return.ConvertCToGo "ret"}} + {{end}} +} +{{end}} {{end}} //glow:keepspace diff --git a/type.go b/type.go index 036f975..6e42f52 100644 --- a/type.go +++ b/type.go @@ -10,6 +10,7 @@ type Type struct { Name string // Name of the type without modifiers PointerLevel int // Number of levels of declared indirection to the type CDefinition string // Raw C definition + Cast string // Raw C cast in case conversion is necessary } // A Typedef describes a C typedef statement. @@ -112,6 +113,8 @@ func (t Type) GoType() string { case "GLDEBUGPROC", "GLDEBUGPROCARB", "GLDEBUGPROCKHR": // Special case mapping to the type defined in debug.tmpl return "DebugProc" + case "uintptr_t": + return t.pointers() + "uintptr" } return "unsafe.Pointer" } diff --git a/type_test.go b/type_test.go new file mode 100644 index 0000000..e22a64a --- /dev/null +++ b/type_test.go @@ -0,0 +1,30 @@ +package main + +import "testing" + +func TestGoType(t *testing.T) { + tt := []struct { + in Type + expected string + }{ + { + in: Type{ + Name: "uintptr_t", + PointerLevel: 1, + CDefinition: "uintptr_t*", + Cast: "void *", + }, + expected: "*uintptr", + }, + } + + for _, tc := range tt { + tc := tc + t.Run(tc.in.String(), func(t *testing.T) { + goType := tc.in.GoType() + if goType != tc.expected { + t.Errorf("expected <%s>, got <%s>", tc.expected, goType) + } + }) + } +} From 65398df970c853c0134ef863ebf1cb15750ea788 Mon Sep 17 00:00:00 2001 From: Christian Haas Date: Sat, 23 May 2020 16:54:39 +0200 Subject: [PATCH 03/15] reading overload information from an XML file --- main.go | 13 ++++++++++++- overload.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ spec.go | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 overload.go diff --git a/main.go b/main.go index 6036ebf..5eed1ca 100644 --- a/main.go +++ b/main.go @@ -114,6 +114,7 @@ func performRestriction(pkg *Package, jsonPath string) { func parseSpecifications(xmlDir string) []*Specification { specDir := filepath.Join(xmlDir, "spec") + overloadDir := filepath.Join(xmlDir, "overload") specFiles, err := ioutil.ReadDir(specDir) if err != nil { log.Fatalln("error reading spec file entries:", err) @@ -124,7 +125,17 @@ func parseSpecifications(xmlDir string) []*Specification { if !strings.HasSuffix(specFile.Name(), "xml") { continue } - spec, err := NewSpecification(filepath.Join(specDir, specFile.Name())) + + registry, err := readSpecFile(filepath.Join(specDir, specFile.Name())) + if err != nil { + log.Fatalln("error reading XML spec file: ", specFile.Name(), err) + } + overloads, err := readOverloadFile(filepath.Join(overloadDir, specFile.Name())) + if err != nil { + log.Fatalln("error reading XML overload file: ", specFile.Name(), err) + } + fmt.Printf("overloads: %v\n", overloads) + spec, err := NewSpecification(*registry, overloads) if err != nil { log.Fatalln("error parsing specification:", specFile.Name(), err) } diff --git a/overload.go b/overload.go new file mode 100644 index 0000000..31055b0 --- /dev/null +++ b/overload.go @@ -0,0 +1,47 @@ +package main + +import ( + "encoding/xml" + "os" +) + +type xmlOverloads struct { + List []xmlOverload `xml:"overload"` +} + +type xmlOverload struct { + Name string `xml:"name,attr"` + OverloadName string `xml:"overloadName,attr"` + + ParameterChanges []xmlParameterChange `xml:"parameterChanges>change"` +} + +type xmlParameterChange struct { + // Index is the zero-based index of the parameter list. + Index int `xml:"index,attr"` + // Type describes a change in the type of a parameter. + Type xmlTypeChange `xml:"type"` +} + +type xmlTypeChange struct { + Name string `xml:"name,attr"` + PointerLevel int `xml:"pointerLevel,attr"` +} + +func readOverloadFile(file string) (xmlOverloads, error) { + var overloads xmlOverloads + + _, err := os.Stat(file) + if err != nil { + return overloads, nil + } + + f, err := os.Open(file) + if err != nil { + return overloads, err + } + defer f.Close() + + err = xml.NewDecoder(f).Decode(&overloads) + return overloads, err +} diff --git a/spec.go b/spec.go index 4c48d02..78e18de 100644 --- a/spec.go +++ b/spec.go @@ -180,6 +180,50 @@ func parseFunctions(commands []xmlCommand) (specFunctions, error) { return functions, nil } +func parseOverloads(functions specFunctions, overloads xmlOverloads) (specFunctions, error) { + for _, overloadInfo := range overloads.List { + found := false + for key, function := range functions { + if key.name == overloadInfo.Name { + found = true + err := overloadFunction(function, overloadInfo) + if err != nil { + return nil, err + } + } + } + if !found { + return nil, fmt.Errorf("function <%s> not found to overload", overloadInfo.Name) + } + } + return functions, nil +} + +func overloadFunction(function *Function, info xmlOverload) error { + overload := Overload{ + Name: function.Name, + GoName: function.GoName, + OverloadName: info.OverloadName, + Parameters: make([]Parameter, len(function.Parameters)), + Return: function.Return, + } + copy(overload.Parameters, function.Parameters) + for _, change := range info.ParameterChanges { + if (change.Index < 0) || (change.Index >= len(function.Parameters)) { + return fmt.Errorf("overload for <%s> has invalid parameter index", info.Name) + } + param := &overload.Parameters[change.Index] + + // store original type definition as a cast, as this most likely will be needed. + param.Type.Cast = param.Type.CDefinition + param.Type.PointerLevel = change.Type.PointerLevel + param.Type.Name = change.Type.Name + param.Type.CDefinition = change.Type.Name + " " + param.Type.pointers() + } + function.Overloads = append(function.Overloads, overload) + return nil +} + func parseSignature(signature xmlSignature) (name string, ctype Type, err error) { readingName := false readingType := false @@ -459,14 +503,14 @@ func (addRem *specAddRemSet) shouldInclude(pkgSpec *PackageSpec) bool { return true } -// NewSpecification creates a new specification based on an XML file. -func NewSpecification(file string) (*Specification, error) { - registry, err := readSpecFile(file) +// NewSpecification creates a new specification based on an XML registry. +func NewSpecification(registry xmlRegistry, overloads xmlOverloads) (*Specification, error) { + functions, err := parseFunctions(registry.Commands) if err != nil { return nil, err } - functions, err := parseFunctions(registry.Commands) + functions, err = parseOverloads(functions, overloads) if err != nil { return nil, err } From ffa35d595fd33b0a4f42deda36aba860507a3db3 Mon Sep 17 00:00:00 2001 From: Christian Haas Date: Sat, 23 May 2020 16:54:55 +0200 Subject: [PATCH 04/15] added example overloads file --- xml/overload/gl.xml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 xml/overload/gl.xml diff --git a/xml/overload/gl.xml b/xml/overload/gl.xml new file mode 100644 index 0000000..708104d --- /dev/null +++ b/xml/overload/gl.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + From c90bbed72528dab77a744814447abaf66f5e0e9b Mon Sep 17 00:00:00 2001 From: Christian Haas Date: Sat, 23 May 2020 17:03:37 +0200 Subject: [PATCH 05/15] allowing parameter names to be changed as well --- overload.go | 10 ++++++++-- spec.go | 16 +++++++++++----- xml/overload/gl.xml | 2 ++ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/overload.go b/overload.go index 31055b0..2988fbc 100644 --- a/overload.go +++ b/overload.go @@ -19,8 +19,14 @@ type xmlOverload struct { type xmlParameterChange struct { // Index is the zero-based index of the parameter list. Index int `xml:"index,attr"` - // Type describes a change in the type of a parameter. - Type xmlTypeChange `xml:"type"` + // Name describes a change of the parameter name. + Name *xmlNameChange `xml:"name"` + // Type describes a change of the parameter type. + Type *xmlTypeChange `xml:"type"` +} + +type xmlNameChange struct { + Value string `xml:"value,attr"` } type xmlTypeChange struct { diff --git a/spec.go b/spec.go index 78e18de..adb53f6 100644 --- a/spec.go +++ b/spec.go @@ -214,11 +214,17 @@ func overloadFunction(function *Function, info xmlOverload) error { } param := &overload.Parameters[change.Index] - // store original type definition as a cast, as this most likely will be needed. - param.Type.Cast = param.Type.CDefinition - param.Type.PointerLevel = change.Type.PointerLevel - param.Type.Name = change.Type.Name - param.Type.CDefinition = change.Type.Name + " " + param.Type.pointers() + if change.Type != nil { + // store original type definition as a cast, as this most likely will be needed. + param.Type.Cast = param.Type.CDefinition + param.Type.PointerLevel = change.Type.PointerLevel + param.Type.Name = change.Type.Name + param.Type.CDefinition = change.Type.Name + " " + param.Type.pointers() + } + if change.Name != nil { + fmt.Printf("name change\n") + param.Name = change.Name.Value + } } function.Overloads = append(function.Overloads, overload) return nil diff --git a/xml/overload/gl.xml b/xml/overload/gl.xml index 708104d..f98cb22 100644 --- a/xml/overload/gl.xml +++ b/xml/overload/gl.xml @@ -10,6 +10,7 @@ + @@ -17,6 +18,7 @@ + From fc28c39a018aea87a9aed7065830252cb52210b6 Mon Sep 17 00:00:00 2001 From: Christian Haas Date: Sat, 23 May 2020 17:04:33 +0200 Subject: [PATCH 06/15] removed debug printfs --- main.go | 1 - spec.go | 1 - 2 files changed, 2 deletions(-) diff --git a/main.go b/main.go index 5eed1ca..e0f5f7e 100644 --- a/main.go +++ b/main.go @@ -134,7 +134,6 @@ func parseSpecifications(xmlDir string) []*Specification { if err != nil { log.Fatalln("error reading XML overload file: ", specFile.Name(), err) } - fmt.Printf("overloads: %v\n", overloads) spec, err := NewSpecification(*registry, overloads) if err != nil { log.Fatalln("error parsing specification:", specFile.Name(), err) diff --git a/spec.go b/spec.go index adb53f6..96b638f 100644 --- a/spec.go +++ b/spec.go @@ -222,7 +222,6 @@ func overloadFunction(function *Function, info xmlOverload) error { param.Type.CDefinition = change.Type.Name + " " + param.Type.pointers() } if change.Name != nil { - fmt.Printf("name change\n") param.Name = change.Name.Value } } From b2aad416df42a75ac1e779731c327f87f67a3ca7 Mon Sep 17 00:00:00 2001 From: Christian Haas Date: Sat, 23 May 2020 17:05:30 +0200 Subject: [PATCH 07/15] removed obsolete attributes --- xml/overload/gl.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xml/overload/gl.xml b/xml/overload/gl.xml index f98cb22..74c959c 100644 --- a/xml/overload/gl.xml +++ b/xml/overload/gl.xml @@ -2,7 +2,7 @@ - + @@ -11,7 +11,7 @@ - + @@ -19,7 +19,7 @@ - + From 65d743f6d0d6772abda3fb4ed633f4ad4cc22af7 Mon Sep 17 00:00:00 2001 From: Christian Haas Date: Wed, 27 May 2020 07:35:25 +0200 Subject: [PATCH 08/15] using fixed suffix "WithOffset" for example overloads --- xml/overload/gl.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xml/overload/gl.xml b/xml/overload/gl.xml index 74c959c..d4139a4 100644 --- a/xml/overload/gl.xml +++ b/xml/overload/gl.xml @@ -7,7 +7,7 @@ - + @@ -15,7 +15,7 @@ - + From 8dda71e5a6b47b5145328683b3d5446c8b7bf687 Mon Sep 17 00:00:00 2001 From: Christian Haas Date: Sat, 30 May 2020 15:09:20 +0200 Subject: [PATCH 09/15] renamed List member to Overloads --- overload.go | 2 +- spec.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/overload.go b/overload.go index 2988fbc..cce1f46 100644 --- a/overload.go +++ b/overload.go @@ -6,7 +6,7 @@ import ( ) type xmlOverloads struct { - List []xmlOverload `xml:"overload"` + Overloads []xmlOverload `xml:"overload"` } type xmlOverload struct { diff --git a/spec.go b/spec.go index 96b638f..0c1ecff 100644 --- a/spec.go +++ b/spec.go @@ -181,7 +181,7 @@ func parseFunctions(commands []xmlCommand) (specFunctions, error) { } func parseOverloads(functions specFunctions, overloads xmlOverloads) (specFunctions, error) { - for _, overloadInfo := range overloads.List { + for _, overloadInfo := range overloads.Overloads { found := false for key, function := range functions { if key.name == overloadInfo.Name { From 6d57b8ac25951c6214706c7181dd4fb353064c0b Mon Sep 17 00:00:00 2001 From: Christian Haas Date: Sat, 30 May 2020 15:19:46 +0200 Subject: [PATCH 10/15] extracted single function getter --- spec.go | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/spec.go b/spec.go index 0c1ecff..0431fca 100644 --- a/spec.go +++ b/spec.go @@ -182,19 +182,14 @@ func parseFunctions(commands []xmlCommand) (specFunctions, error) { func parseOverloads(functions specFunctions, overloads xmlOverloads) (specFunctions, error) { for _, overloadInfo := range overloads.Overloads { - found := false - for key, function := range functions { - if key.name == overloadInfo.Name { - found = true - err := overloadFunction(function, overloadInfo) - if err != nil { - return nil, err - } - } - } - if !found { + function := functions.getByName(overloadInfo.Name) + if function == nil { return nil, fmt.Errorf("function <%s> not found to overload", overloadInfo.Name) } + err := overloadFunction(function, overloadInfo) + if err != nil { + return nil, err + } } return functions, nil } @@ -451,6 +446,15 @@ func (functions specFunctions) get(name, api string) *Function { return functions[specRef{name, ""}] } +func (functions specFunctions) getByName(name string) *Function { + for key, function := range functions { + if key.name == name { + return function + } + } + return nil +} + func (enums specEnums) get(name, api string) *Enum { enum, ok := enums[specRef{name, api}] if ok { From 9664fe728fc477e550490bd8aa68b5d6ee35e4d2 Mon Sep 17 00:00:00 2001 From: Christian Haas Date: Sat, 30 May 2020 15:36:09 +0200 Subject: [PATCH 11/15] removed unnecessary Name field from Overload --- functions.go | 1 - spec.go | 1 - 2 files changed, 2 deletions(-) diff --git a/functions.go b/functions.go index ffa91c3..ff713bb 100644 --- a/functions.go +++ b/functions.go @@ -13,7 +13,6 @@ type Function struct { // An Overload describes an alternative signature for the same function. type Overload struct { - Name string // C name of the original function GoName string // Go name of the original function OverloadName string // Go name of the overload Parameters []Parameter diff --git a/spec.go b/spec.go index 0431fca..dc7c4d8 100644 --- a/spec.go +++ b/spec.go @@ -196,7 +196,6 @@ func parseOverloads(functions specFunctions, overloads xmlOverloads) (specFuncti func overloadFunction(function *Function, info xmlOverload) error { overload := Overload{ - Name: function.Name, GoName: function.GoName, OverloadName: info.OverloadName, Parameters: make([]Parameter, len(function.Parameters)), From e33870311857f53f271c69f8d1ed49fef519a56f Mon Sep 17 00:00:00 2001 From: Christian Haas Date: Sat, 30 May 2020 16:14:23 +0200 Subject: [PATCH 12/15] added test for signature parsing --- spec_test.go | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 spec_test.go diff --git a/spec_test.go b/spec_test.go new file mode 100644 index 0000000..51a5fbf --- /dev/null +++ b/spec_test.go @@ -0,0 +1,71 @@ +package main + +import "testing" + +func TestParseSignature(t *testing.T) { + tt := []struct { + input string + expectedName string + expectedType Type + }{ + { + input: "const void *pointer", + expectedName: "pointer", + expectedType: Type{ + Name: "void", + PointerLevel: 1, + CDefinition: "const void *", + }, + }, + { + input: "GLsizei stride", + expectedName: "stride", + expectedType: Type{ + Name: "GLsizei", + PointerLevel: 0, + CDefinition: "GLsizei ", + }, + }, + { + input: "const GLuint *value", + expectedName: "value", + expectedType: Type{ + Name: "GLuint", + PointerLevel: 1, + CDefinition: "const GLuint *", + }, + }, + { + input: "GLuint baseAndCount[2]", + expectedName: "baseAndCount", + expectedType: Type{ + Name: "GLuint", + PointerLevel: 1, + CDefinition: "GLuint *", + }, + }, + } + + for _, tc := range tt { + tc := tc + t.Run(tc.input, func(t *testing.T) { + name, ctype, err := parseSignature(xmlSignature(tc.input)) + failed := false + if err != nil { + t.Logf("parseSignature returned error: %v", err) + failed = true + } + if name != tc.expectedName { + t.Logf("name [%s] does not match expected [%s]", name, tc.expectedName) + failed = true + } + if ctype != tc.expectedType { + t.Logf("type [%v] does not match expected [%v]", ctype, tc.expectedType) + failed = true + } + if failed { + t.Fail() + } + }) + } +} From f28200db4a249cebee5b0848cedd8f873f4b7837 Mon Sep 17 00:00:00 2001 From: Christian Haas Date: Sat, 30 May 2020 16:32:23 +0200 Subject: [PATCH 13/15] changed type change description for overloads to use c defintions --- overload.go | 3 +-- spec.go | 10 +++++++--- spec_test.go | 9 +++++++++ xml/overload/gl.xml | 6 +++--- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/overload.go b/overload.go index cce1f46..24420f6 100644 --- a/overload.go +++ b/overload.go @@ -30,8 +30,7 @@ type xmlNameChange struct { } type xmlTypeChange struct { - Name string `xml:"name,attr"` - PointerLevel int `xml:"pointerLevel,attr"` + Signature string `xml:"signature,attr"` } func readOverloadFile(file string) (xmlOverloads, error) { diff --git a/spec.go b/spec.go index dc7c4d8..eb58d9b 100644 --- a/spec.go +++ b/spec.go @@ -209,11 +209,15 @@ func overloadFunction(function *Function, info xmlOverload) error { param := &overload.Parameters[change.Index] if change.Type != nil { + _, ctype, err := parseSignature(xmlSignature(change.Type.Signature)) + if err != nil { + return fmt.Errorf("failed to parse signature of overload for <%s>: %v", info.Name, err) + } // store original type definition as a cast, as this most likely will be needed. param.Type.Cast = param.Type.CDefinition - param.Type.PointerLevel = change.Type.PointerLevel - param.Type.Name = change.Type.Name - param.Type.CDefinition = change.Type.Name + " " + param.Type.pointers() + param.Type.PointerLevel = ctype.PointerLevel + param.Type.Name = ctype.Name + param.Type.CDefinition = ctype.CDefinition } if change.Name != nil { param.Name = change.Name.Value diff --git a/spec_test.go b/spec_test.go index 51a5fbf..1f366d7 100644 --- a/spec_test.go +++ b/spec_test.go @@ -44,6 +44,15 @@ func TestParseSignature(t *testing.T) { CDefinition: "GLuint *", }, }, + { + input: "uintptr_t **", + expectedName: "", + expectedType: Type{ + Name: "uintptr_t", + PointerLevel: 2, + CDefinition: "uintptr_t **", + }, + }, } for _, tc := range tt { diff --git a/xml/overload/gl.xml b/xml/overload/gl.xml index d4139a4..34c7449 100644 --- a/xml/overload/gl.xml +++ b/xml/overload/gl.xml @@ -2,7 +2,7 @@ - + @@ -11,7 +11,7 @@ - + @@ -19,7 +19,7 @@ - + From 9ba163d345e2c0e4337fc4f7136078b25e1e83b1 Mon Sep 17 00:00:00 2001 From: Christian Haas Date: Sat, 30 May 2020 16:44:26 +0200 Subject: [PATCH 14/15] extended readme about overload function --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 23b486c..a53996a 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ Features: - Go functions that mirror the C specification using Go types. - Support for multiple OpenGL APIs (GL/GLES/EGL/WGL/GLX/EGL), versions, and profiles. - Support for extensions (including debug callbacks). +- Support for overloads to provide Go functions with different parameter signatures. See the [open issues](https://github.com/go-gl/glow/issues) for caveats about the current state of the implementation. @@ -15,6 +16,15 @@ Generated Packages Generated OpenGL binding packages are available in the [go-gl/gl](https://github.com/go-gl/gl) repository. +Overloads +--------- + +See subdirectory `xml/overload` for examples. The motivation here is to provide Go functions with different parameter signatures of existing OpenGL functions. + +For example, `glVertexAttribPointer(..., void *)` cannot be used with `gl.VertexAttribPointer(..., unsafe.Pointer)` when using arbitrary offset values. The `checkptr` safeguard will abort the program when doing so. +Overloads allow to create an additional `gl.VertexAttribPointerWithOffset(..., uintptr)`, which calls the original function with appropriate casts. + + Custom Packages --------------- From 8a40325db9174b2fc7ab4e037aa2131198000159 Mon Sep 17 00:00:00 2001 From: Christian Haas Date: Wed, 3 Jun 2020 16:52:54 +0200 Subject: [PATCH 15/15] Updated wording to be more explicit about overloads --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a53996a..861dff1 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Overloads See subdirectory `xml/overload` for examples. The motivation here is to provide Go functions with different parameter signatures of existing OpenGL functions. For example, `glVertexAttribPointer(..., void *)` cannot be used with `gl.VertexAttribPointer(..., unsafe.Pointer)` when using arbitrary offset values. The `checkptr` safeguard will abort the program when doing so. -Overloads allow to create an additional `gl.VertexAttribPointerWithOffset(..., uintptr)`, which calls the original function with appropriate casts. +Overloads allow the creation of an additional `gl.VertexAttribPointerWithOffset(..., uintptr)`, which calls the original OpenGL function with appropriate casts. Custom Packages