support marking data types as linux-only

This commit is contained in:
mappu 2024-09-01 17:50:58 +12:00
parent 8fe215955f
commit 2323c12b55
9 changed files with 110 additions and 14 deletions

View File

@ -511,6 +511,11 @@ extern "C" {
cClassName := cabiClassName(c.ClassName)
for i, ctor := range c.Ctors {
if ctor.LinuxOnly {
ret.WriteString("#ifdef Q_OS_LINUX\n\n")
}
preamble, forwarding := emitParametersCABI2CppForwarding(ctor.Parameters)
ret.WriteString(fmt.Sprintf(
"%s* %s_new%s(%s) {\n"+
@ -522,6 +527,10 @@ extern "C" {
preamble,
c.ClassName, forwarding,
))
if ctor.LinuxOnly {
ret.WriteString("#endif /* Q_OS_LINUX */\n\n")
}
}
for _, m := range c.Methods {
@ -657,6 +666,10 @@ extern "C" {
callTarget = "const_cast<const " + c.ClassName + "*>(self)->"
}
if m.LinuxOnly {
ret.WriteString("#ifdef Q_OS_LINUX\n\n")
}
ret.WriteString(fmt.Sprintf(
"%s %s_%s(%s) {\n"+
"%s"+
@ -682,6 +695,11 @@ extern "C" {
"\n",
)
}
if m.LinuxOnly {
ret.WriteString("#endif /* Q_OS_LINUX */\n\n")
}
}
// Delete

View File

@ -347,7 +347,23 @@ import "C"
for i, ctor := range c.Ctors {
preamble, forwarding := gfs.emitParametersGo2CABIForwarding(ctor)
ret.WriteString(`
if ctor.LinuxOnly {
gfs.imports["runtime"] = struct{}{}
ret.WriteString(`
// New` + goClassName + maybeSuffix(i) + ` constructs a new ` + c.ClassName + ` object.
func New` + goClassName + maybeSuffix(i) + `(` + emitParametersGo(ctor.Parameters) + `) *` + goClassName + ` {
if runtime.GOOS == "linux" {
` + preamble + ` ret := C.` + goClassName + `_new` + maybeSuffix(i) + `(` + forwarding + `)
return new` + goClassName + `(ret)
} else {
panic("Unsupported OS")
}
}
`)
} else {
ret.WriteString(`
// New` + goClassName + maybeSuffix(i) + ` constructs a new ` + c.ClassName + ` object.
func New` + goClassName + maybeSuffix(i) + `(` + emitParametersGo(ctor.Parameters) + `) *` + goClassName + ` {
` + preamble + ` ret := C.` + goClassName + `_new` + maybeSuffix(i) + `(` + forwarding + `)
@ -355,6 +371,7 @@ import "C"
}
`)
}
}
for _, m := range c.Methods {
@ -478,14 +495,31 @@ import "C"
receiverAndMethod = goClassName + `_` + m.SafeMethodName()
}
ret.WriteString(`
if m.LinuxOnly {
gfs.imports["runtime"] = struct{}{}
ret.WriteString(`
func ` + receiverAndMethod + `(` + emitParametersGo(m.Parameters) + `) ` + returnTypeDecl + ` {
if runtime.GOOS == "linux" {
` + preamble +
shouldReturn + ` C.` + goClassName + `_` + m.SafeMethodName() + `(` + forwarding + `)
` + afterword + `
} else {
panic("Unsupported OS")
}
}
`)
} else {
ret.WriteString(`
func ` + receiverAndMethod + `(` + emitParametersGo(m.Parameters) + `) ` + returnTypeDecl + ` {
` + preamble +
shouldReturn + ` C.` + goClassName + `_` + m.SafeMethodName() + `(` + forwarding + `)
shouldReturn + ` C.` + goClassName + `_` + m.SafeMethodName() + `(` + forwarding + `)
` + afterword + `}
`)
}
// Add Connect() wrappers for signal functions
if m.IsSignal && !m.HasHiddenParams {
gfs.imports["unsafe"] = struct{}{}

View File

@ -225,3 +225,17 @@ func CheckComplexity(p CppParameter, isReturnType bool) error {
// Should be OK
return nil
}
// LinuxWindowsCompatCheck checks if the parameter is incompatible between the
// generated headers (generated on Linux) with other OSes such as Windows.
// These methods will be blocked on non-Linux OSes.
func LinuxWindowsCompatCheck(p CppParameter) bool {
if p.TypeAlias == "Q_PID" {
return true // int64 on Linux, _PROCESS_INFORMATION* on Windows
}
if p.ParameterType == "QSocketDescriptor::DescriptorType" {
return true // uintptr_t-compatible on Linux, void* on Windows
}
return false
}

View File

@ -20,11 +20,6 @@ func init() {
KnownTypedefs["WId"] = CppTypedef{"WId", parseSingleTypeString("uintptr_t")}
// This is a uint64 PID on Linux/mac and a PROCESS_INFORMATION* on Windows
// A uintptr should be tolerable for both cases until we do better
// @ref https://doc.qt.io/qt-5/qprocess.html#Q_PID-typedef
KnownTypedefs["Q_PID"] = CppTypedef{"WId", parseSingleTypeString("uintptr_t")}
// QString is deleted from this binding
KnownTypedefs["QStringList"] = CppTypedef{"QStringList", parseSingleTypeString("QList<QString>")}
@ -186,6 +181,7 @@ type CppMethod struct {
IsSignal bool
IsConst bool
HasHiddenParams bool // Set to true if there is an overload with more parameters
LinuxOnly bool
}
func IsArgcArgv(params []CppParameter, pos int) bool {

View File

@ -33,17 +33,33 @@ func astTransformTypedefs(parsed *CppParsedHeader) {
for j, m := range c.Methods {
for k, p := range m.Parameters {
m.Parameters[k] = applyTypedefs(p)
transformed := applyTypedefs(p)
m.Parameters[k] = transformed
if LinuxWindowsCompatCheck(transformed) {
m.LinuxOnly = true
}
}
m.ReturnType = applyTypedefs(m.ReturnType)
// Also apply OS compatibility rules
if LinuxWindowsCompatCheck(m.ReturnType) {
m.LinuxOnly = true
}
c.Methods[j] = m
}
for j, m := range c.Ctors {
for k, p := range m.Parameters {
m.Parameters[k] = applyTypedefs(p)
transformed := applyTypedefs(p)
m.Parameters[k] = transformed
if LinuxWindowsCompatCheck(transformed) {
m.LinuxOnly = true
}
}
c.Ctors[j] = m

View File

@ -352,10 +352,14 @@ uintptr_t QProcess_State(QProcess* self) {
return static_cast<uintptr_t>(ret);
}
#ifdef Q_OS_LINUX
int64_t QProcess_Pid(QProcess* self) {
return const_cast<const QProcess*>(self)->pid();
}
#endif /* Q_OS_LINUX */
long long QProcess_ProcessId(QProcess* self) {
return const_cast<const QProcess*>(self)->processId();
}

View File

@ -450,8 +450,13 @@ func (this *QProcess) State() uintptr {
}
func (this *QProcess) Pid() int64 {
ret := C.QProcess_Pid(this.h)
return (int64)(ret)
if runtime.GOOS == "linux" {
ret := C.QProcess_Pid(this.h)
return (int64)(ret)
} else {
panic("Unsupported OS")
}
}
func (this *QProcess) ProcessId() int64 {

View File

@ -108,10 +108,14 @@ QSocketDescriptor* QSocketDescriptor_new2(QSocketDescriptor* param1) {
return new QSocketDescriptor(*param1);
}
#ifdef Q_OS_LINUX
QSocketDescriptor* QSocketDescriptor_new3(uintptr_t descriptor) {
return new QSocketDescriptor(static_cast<QSocketDescriptor::DescriptorType>(descriptor));
}
#endif /* Q_OS_LINUX */
bool QSocketDescriptor_IsValid(QSocketDescriptor* self) {
return const_cast<const QSocketDescriptor*>(self)->isValid();
}

View File

@ -9,6 +9,7 @@ package qt
import "C"
import (
"runtime"
"unsafe"
)
@ -185,8 +186,12 @@ func NewQSocketDescriptor2(param1 *QSocketDescriptor) *QSocketDescriptor {
// NewQSocketDescriptor3 constructs a new QSocketDescriptor object.
func NewQSocketDescriptor3(descriptor uintptr) *QSocketDescriptor {
ret := C.QSocketDescriptor_new3((C.uintptr_t)(descriptor))
return newQSocketDescriptor(ret)
if runtime.GOOS == "linux" {
ret := C.QSocketDescriptor_new3((C.uintptr_t)(descriptor))
return newQSocketDescriptor(ret)
} else {
panic("Unsupported OS")
}
}
func (this *QSocketDescriptor) IsValid() bool {