mirror of
https://github.com/mappu/miqt.git
synced 2024-12-22 08:58:37 +00:00
genbindings: QString parameter forwarding with custom preamble
This commit is contained in:
parent
618b68aaf9
commit
0c275047c3
@ -5,6 +5,14 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (p CppParameter) RenderTypeCpp() string {
|
||||
ret := p.ParameterType
|
||||
if p.Pointer || p.ByRef {
|
||||
ret += "*"
|
||||
}
|
||||
return ret // ignore const
|
||||
}
|
||||
|
||||
func emitParametersCpp(params []CppParameter, selfType string) string {
|
||||
tmp := make([]string, 0, len(params)+1)
|
||||
|
||||
@ -13,12 +21,24 @@ func emitParametersCpp(params []CppParameter, selfType string) string {
|
||||
}
|
||||
|
||||
for _, p := range params {
|
||||
tmp = append(tmp, p.RenderTypeCpp()+" "+p.ParameterName)
|
||||
if p.ParameterType == "QString" {
|
||||
// The Go code has called this with two arguments: char* and len
|
||||
// Declare that we take two parameters
|
||||
tmp = append(tmp, "const char* "+p.ParameterName+", size_t "+p.ParameterName+"_Strlen")
|
||||
|
||||
} else if (p.ByRef || p.Pointer) && p.ParameterType[0] == 'Q' {
|
||||
// Pointer to Qt type
|
||||
// Replace with taking our PQ typedef by value
|
||||
tmp = append(tmp, "P"+p.ParameterType+" "+p.ParameterName)
|
||||
} else {
|
||||
// RenderTypeCpp renders both pointer+reference as pointers
|
||||
tmp = append(tmp, p.RenderTypeCpp()+" "+p.ParameterName)
|
||||
}
|
||||
}
|
||||
return strings.Join(tmp, ", ")
|
||||
}
|
||||
|
||||
func emitParametersNames(params []CppParameter, selfType string) string {
|
||||
func emitParametersCABI2CppForwarding(params []CppParameter, selfType string) (preamble string, forwarding string) {
|
||||
tmp := make([]string, 0, len(params)+1)
|
||||
|
||||
if selfType != "" {
|
||||
@ -26,9 +46,22 @@ func emitParametersNames(params []CppParameter, selfType string) string {
|
||||
}
|
||||
|
||||
for _, p := range params {
|
||||
tmp = append(tmp, p.ParameterName)
|
||||
if p.ParameterType == "QString" {
|
||||
// The CABI has accepted two parameters - need to convert to one real QString
|
||||
// Create it on the stack
|
||||
preamble += "\tQString " + p.ParameterName + "_QString(" + p.ParameterName + ", " + p.ParameterName + "_Strlen);\n"
|
||||
tmp = append(tmp, p.ParameterName+"_QString")
|
||||
|
||||
} else if p.ByRef {
|
||||
// We changed RenderTypeCpp() to render this as a pointer
|
||||
// Need to dereference so we can pass as reference to the actual Qt C++ function
|
||||
tmp = append(tmp, "*"+p.ParameterName)
|
||||
} else {
|
||||
tmp = append(tmp, p.ParameterName)
|
||||
}
|
||||
}
|
||||
return strings.Join(tmp, ", ")
|
||||
|
||||
return preamble, strings.Join(tmp, ", ")
|
||||
}
|
||||
|
||||
func emitBindingHeader(src *CppParsedHeader, filename string) (string, error) {
|
||||
@ -83,9 +116,16 @@ func emitBindingCpp(src *CppParsedHeader, filename string) (string, error) {
|
||||
for _, c := range src.Classes {
|
||||
|
||||
for i, ctor := range c.Ctors {
|
||||
preamble, forwarding := emitParametersCABI2CppForwarding(ctor.Parameters, "")
|
||||
ret.WriteString(fmt.Sprintf(
|
||||
"P%s %s_new%s(%s) {\n\treturn new %s(%s);\n}\n\n", c.ClassName, maybeSuffix(i), emitParametersCpp(ctor.Parameters, ""),
|
||||
c.ClassName, emitParametersNames(ctor.Parameters, ""),
|
||||
"P%s %s_new%s(%s) {\n"+
|
||||
"%s"+
|
||||
"\treturn new %s(%s);\n"+
|
||||
"}\n"+
|
||||
"\n",
|
||||
c.ClassName, maybeSuffix(i), emitParametersCpp(ctor.Parameters, ""),
|
||||
preamble,
|
||||
c.ClassName, forwarding,
|
||||
))
|
||||
}
|
||||
|
||||
@ -97,8 +137,17 @@ func emitBindingCpp(src *CppParsedHeader, filename string) (string, error) {
|
||||
shouldReturn = ""
|
||||
}
|
||||
|
||||
ret.WriteString(fmt.Sprintf("%s %s_%s(%s) {\n\t%sstatic_cast<%s*>(self)->%s(%s);\n}\n\n", m.ReturnType.RenderTypeCpp(), c.ClassName, m.SafeMethodName(), emitParametersCpp(m.Parameters, "P"+c.ClassName),
|
||||
shouldReturn, c.ClassName, m.MethodName, emitParametersNames(m.Parameters, c.ClassName),
|
||||
preamble, forwarding := emitParametersCABI2CppForwarding(m.Parameters, c.ClassName)
|
||||
|
||||
ret.WriteString(fmt.Sprintf(
|
||||
"%s %s_%s(%s) {\n"+
|
||||
"%s"+
|
||||
"\t%sstatic_cast<%s*>(self)->%s(%s);\n"+
|
||||
"}\n"+
|
||||
"\n",
|
||||
m.ReturnType.RenderTypeCpp(), c.ClassName, m.SafeMethodName(), emitParametersCpp(m.Parameters, "P"+c.ClassName),
|
||||
preamble,
|
||||
shouldReturn, c.ClassName, m.MethodName, forwarding,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,22 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (p CppParameter) RenderTypeGo() string {
|
||||
if p.Pointer && p.ParameterType == "char" {
|
||||
return "string"
|
||||
}
|
||||
if p.ParameterType == "QString" {
|
||||
return "string"
|
||||
}
|
||||
|
||||
ret := ""
|
||||
if p.ByRef || p.Pointer {
|
||||
ret += "*"
|
||||
}
|
||||
ret += p.ParameterType
|
||||
return ret // ignore const
|
||||
}
|
||||
|
||||
func emitParametersGo(params []CppParameter) string {
|
||||
tmp := make([]string, 0, len(params))
|
||||
for _, p := range params {
|
||||
@ -14,6 +30,38 @@ func emitParametersGo(params []CppParameter) string {
|
||||
return strings.Join(tmp, ", ")
|
||||
}
|
||||
|
||||
func emitParametersGo2CABIForwarding(params []CppParameter) (preamble string, fowarding string) {
|
||||
tmp := make([]string, 0, len(params))
|
||||
for _, p := range params {
|
||||
if p.ParameterType == "QString" {
|
||||
// Go: convert string -> char* and len
|
||||
// CABI: convert char* and len -> real QString
|
||||
preamble += p.ParameterName + "_Cstring := C.CString(" + p.ParameterName + ")\n"
|
||||
preamble += "defer C.free(" + p.ParameterName + "_Cstring)\n"
|
||||
tmp = append(tmp, p.ParameterName+"_Cstring, len("+p.ParameterName+")")
|
||||
|
||||
// TODO handle the return type as a pointer parameter
|
||||
|
||||
} else if p.Pointer && p.ParameterType == "char" {
|
||||
// Single char* argument
|
||||
preamble += p.ParameterName + "_Cstring := C.CString(" + p.ParameterName + ")\n"
|
||||
preamble += "defer C.free(" + p.ParameterName + "_Cstring)\n"
|
||||
tmp = append(tmp, p.ParameterName+"_Cstring")
|
||||
|
||||
} else if (p.Pointer || p.ByRef) && p.ParameterType[0] == 'Q' {
|
||||
// The C++ type is a pointer to Qt class
|
||||
// We want our functions to accept the Go wrapper type, and forward as cPointer()
|
||||
tmp = append(tmp, p.ParameterName+".cPointer()")
|
||||
|
||||
} else {
|
||||
// Default
|
||||
tmp = append(tmp, p.ParameterName)
|
||||
}
|
||||
}
|
||||
|
||||
return preamble, strings.Join(tmp, ", ")
|
||||
}
|
||||
|
||||
func emitGo(src *CppParsedHeader) (string, error) {
|
||||
|
||||
ret := strings.Builder{}
|
||||
@ -47,10 +95,11 @@ import "C"
|
||||
`)
|
||||
|
||||
for i, ctor := range c.Ctors {
|
||||
preamble, forwarding := emitParametersGo2CABIForwarding(ctor.Parameters)
|
||||
ret.WriteString(`
|
||||
// New` + c.ClassName + maybeSuffix(i) + ` constructs a new ` + c.ClassName + ` object.
|
||||
func New` + c.ClassName + maybeSuffix(i) + `(` + emitParametersGo(ctor.Parameters) + `) {
|
||||
ret := C.` + c.ClassName + `_new` + maybeSuffix(i) + `(` + emitParametersNames(ctor.Parameters, "") + `)
|
||||
` + preamble + ` ret := C.` + c.ClassName + `_new` + maybeSuffix(i) + `(` + forwarding + `)
|
||||
return &` + c.ClassName + `{h: ret}
|
||||
}
|
||||
|
||||
@ -67,9 +116,11 @@ import "C"
|
||||
returnTypeDecl = ""
|
||||
}
|
||||
|
||||
preamble, forwarding := emitParametersGo2CABIForwarding(m.Parameters)
|
||||
|
||||
ret.WriteString(`
|
||||
func (this *` + c.ClassName + `) ` + m.SafeMethodName() + `(` + emitParametersGo(m.Parameters) + `) ` + returnTypeDecl + ` {
|
||||
` + shouldReturn + ` C.` + c.ClassName + `_` + m.SafeMethodName() + `(` + emitParametersNames(m.Parameters, c.ClassName) + `)
|
||||
` + preamble + shouldReturn + ` C.` + c.ClassName + `_` + m.SafeMethodName() + `(` + forwarding + `)
|
||||
}
|
||||
|
||||
`)
|
||||
|
@ -12,36 +12,6 @@ type CppParameter struct {
|
||||
ByRef bool
|
||||
}
|
||||
|
||||
func (p CppParameter) RenderTypeCpp() string {
|
||||
ret := ""
|
||||
if p.ByRef {
|
||||
ret += "&"
|
||||
}
|
||||
ret += p.ParameterType
|
||||
if p.Pointer {
|
||||
ret += "*"
|
||||
}
|
||||
return ret // ignore const
|
||||
}
|
||||
|
||||
func (p CppParameter) RenderTypeGo() string {
|
||||
if p.Pointer && p.ParameterType == "char" {
|
||||
return "string"
|
||||
}
|
||||
|
||||
ret := ""
|
||||
if p.ByRef || p.Pointer {
|
||||
/*
|
||||
if p.ParameterType[0] == 'Q' {
|
||||
ret += "C.P" // use our void typedef instead
|
||||
} else {
|
||||
*/
|
||||
ret += "*"
|
||||
}
|
||||
ret += p.ParameterType
|
||||
return ret // ignore const
|
||||
}
|
||||
|
||||
type CppProperty struct {
|
||||
PropertyName string
|
||||
PropertyType string
|
||||
|
Loading…
Reference in New Issue
Block a user