Complete conversion to pointer wrapped types. Update tests, fix
parameter handling for functions.
This commit is contained in:
parent
ac9eecafd8
commit
79bb282188
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -13,4 +13,6 @@ examples/memory/memory
|
||||||
examples/memory/ns
|
examples/memory/ns
|
||||||
examples/gc/gc
|
examples/gc/gc
|
||||||
examples/gc/ns
|
examples/gc/ns
|
||||||
|
examples/functions/functions
|
||||||
|
examples/functions/ns
|
||||||
ns-old
|
ns-old
|
||||||
|
|
|
@ -22,10 +22,6 @@ func pb2() {
|
||||||
|
|
||||||
func didFinishLaunching(n *ns.NSNotification) {
|
func didFinishLaunching(n *ns.NSNotification) {
|
||||||
fmt.Println("Go: did finish launching")
|
fmt.Println("Go: did finish launching")
|
||||||
fmt.Printf("Notification n = %p\n",n)
|
|
||||||
fmt.Printf("Notification n.Ptr() = %p\n",n.Ptr())
|
|
||||||
fmt.Printf("Notification n.Name() = %p\n",n.Name())
|
|
||||||
fmt.Printf("Notification n.Name().Ptr() = %p\n",n.Name().Ptr())
|
|
||||||
fmt.Printf("Notification: %s\n", n.Name().UTF8String())
|
fmt.Printf("Notification: %s\n", n.Name().UTF8String())
|
||||||
//Set up an NSWindow
|
//Set up an NSWindow
|
||||||
win = ns.NSWindowAlloc().InitWithContentRectStyleMask(
|
win = ns.NSWindowAlloc().InitWithContentRectStyleMask(
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"git.wow.st/gmp/nswrap/examples/bluetooth/ns"
|
"git.wow.st/gmp/nswrap/examples/bluetooth/ns"
|
||||||
)
|
)
|
||||||
|
|
||||||
func updateState(c ns.CBCentralManager) {
|
func updateState(c *ns.CBCentralManager) {
|
||||||
fmt.Printf("Go: did update state\n")
|
fmt.Printf("Go: did update state\n")
|
||||||
switch cm.CBManager.State() {
|
switch cm.CBManager.State() {
|
||||||
case ns.CBManagerStateUnknown:
|
case ns.CBManagerStateUnknown:
|
||||||
|
@ -23,11 +23,11 @@ func updateState(c ns.CBCentralManager) {
|
||||||
fmt.Printf(" powered off\n")
|
fmt.Printf(" powered off\n")
|
||||||
case ns.CBManagerStatePoweredOn:
|
case ns.CBManagerStatePoweredOn:
|
||||||
fmt.Printf(" powered on\n")
|
fmt.Printf(" powered on\n")
|
||||||
cm.ScanForPeripheralsWithServices(ns.NSArrayWithObjects(hrm_uuid), ns.NSDictionary{})
|
cm.ScanForPeripheralsWithServices(ns.NSArrayWithObjects(hrm_uuid), nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func discoverPeripheral(c ns.CBCentralManager, p ns.CBPeripheral, d ns.NSDictionary, rssi ns.NSNumber) {
|
func discoverPeripheral(c *ns.CBCentralManager, p *ns.CBPeripheral, d *ns.NSDictionary, rssi *ns.NSNumber) {
|
||||||
fmt.Printf("Did discover peripheral\n")
|
fmt.Printf("Did discover peripheral\n")
|
||||||
c.StopScan()
|
c.StopScan()
|
||||||
if peripheral.Ptr() != nil {
|
if peripheral.Ptr() != nil {
|
||||||
|
@ -35,26 +35,26 @@ func discoverPeripheral(c ns.CBCentralManager, p ns.CBPeripheral, d ns.NSDiction
|
||||||
}
|
}
|
||||||
peripheral = p
|
peripheral = p
|
||||||
peripheral.Retain()
|
peripheral.Retain()
|
||||||
c.ConnectPeripheral(peripheral, ns.NSDictionary{})
|
c.ConnectPeripheral(peripheral, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func connectPeripheral(c ns.CBCentralManager, p ns.CBPeripheral) {
|
func connectPeripheral(c *ns.CBCentralManager, p *ns.CBPeripheral) {
|
||||||
fmt.Printf("Did connect peripheral\n")
|
fmt.Printf("Did connect peripheral\n")
|
||||||
p.SetDelegate(cd)
|
p.SetDelegate(cd)
|
||||||
p.DiscoverServices(ns.NSArray{})
|
p.DiscoverServices(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func discoverServices(p ns.CBPeripheral, e ns.NSError) {
|
func discoverServices(p *ns.CBPeripheral, e *ns.NSError) {
|
||||||
fmt.Printf("Did discover services\n")
|
fmt.Printf("Did discover services\n")
|
||||||
p.Services().ObjectEnumerator().ForIn(func(o ns.Id) bool {
|
p.Services().ObjectEnumerator().ForIn(func(o *ns.Id) bool {
|
||||||
serv := o.CBService()
|
serv := o.CBService()
|
||||||
switch {
|
switch {
|
||||||
case serv.UUID().IsEqualTo(hrm_uuid):
|
case serv.UUID().IsEqualTo(hrm_uuid):
|
||||||
fmt.Printf("--heart rate monitor service\n")
|
fmt.Printf("--heart rate monitor service\n")
|
||||||
p.DiscoverCharacteristics(ns.NSArray{}, serv)
|
p.DiscoverCharacteristics(nil, serv)
|
||||||
case serv.UUID().IsEqualTo(ns.CBUUIDWithGoString("180A")):
|
case serv.UUID().IsEqualTo(ns.CBUUIDWithGoString("180A")):
|
||||||
fmt.Printf("--device information service\n")
|
fmt.Printf("--device information service\n")
|
||||||
p.DiscoverCharacteristics(ns.NSArray{}, serv)
|
p.DiscoverCharacteristics(nil, serv)
|
||||||
default:
|
default:
|
||||||
fmt.Printf("--unknown service\n")
|
fmt.Printf("--unknown service\n")
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ func discoverServices(p ns.CBPeripheral, e ns.NSError) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func hr(d ns.NSData) int {
|
func hr(d *ns.NSData) int {
|
||||||
if l := int(d.Length()); l < 4 {
|
if l := int(d.Length()); l < 4 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -75,11 +75,11 @@ func hr(d ns.NSData) int {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func discoverCharacteristics(p ns.CBPeripheral, s ns.CBService, e ns.NSError) {
|
func discoverCharacteristics(p *ns.CBPeripheral, s *ns.CBService, e *ns.NSError) {
|
||||||
fmt.Printf("Did discover characteristics\n")
|
fmt.Printf("Did discover characteristics\n")
|
||||||
fmt.Printf("----%s\n", s.UUID().UUIDString().UTF8String())
|
fmt.Printf("----%s\n", s.UUID().UUIDString().UTF8String())
|
||||||
if s.UUID().IsEqualTo(hrm_uuid) {
|
if s.UUID().IsEqualTo(hrm_uuid) {
|
||||||
s.Characteristics().ObjectEnumerator().ForIn(func(o ns.Id) bool {
|
s.Characteristics().ObjectEnumerator().ForIn(func(o *ns.Id) bool {
|
||||||
chr := o.CBCharacteristic()
|
chr := o.CBCharacteristic()
|
||||||
fmt.Printf("------%s\n", chr.UUID().UUIDString().UTF8String())
|
fmt.Printf("------%s\n", chr.UUID().UUIDString().UTF8String())
|
||||||
if chr.UUID().IsEqualTo(hrv_uuid) {
|
if chr.UUID().IsEqualTo(hrv_uuid) {
|
||||||
|
@ -92,7 +92,7 @@ func discoverCharacteristics(p ns.CBPeripheral, s ns.CBService, e ns.NSError) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateValue(p ns.CBPeripheral, chr ns.CBCharacteristic, e ns.NSError) {
|
func updateValue(p *ns.CBPeripheral, chr *ns.CBCharacteristic, e *ns.NSError) {
|
||||||
if chr.UUID().IsEqualTo(hrv_uuid) {
|
if chr.UUID().IsEqualTo(hrv_uuid) {
|
||||||
v := chr.Value()
|
v := chr.Value()
|
||||||
fmt.Printf("Heart rate: %d\n", hr(v))
|
fmt.Printf("Heart rate: %d\n", hr(v))
|
||||||
|
@ -100,11 +100,11 @@ func updateValue(p ns.CBPeripheral, chr ns.CBCharacteristic, e ns.NSError) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
hrm_uuid ns.CBUUID
|
hrm_uuid *ns.CBUUID
|
||||||
hrv_uuid ns.CBUUID
|
hrv_uuid *ns.CBUUID
|
||||||
cd ns.CBDelegate
|
cd *ns.CBDelegate
|
||||||
cm ns.CBCentralManager
|
cm *ns.CBCentralManager
|
||||||
peripheral ns.CBPeripheral
|
peripheral *ns.CBPeripheral
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -38,4 +38,4 @@ delegates:
|
||||||
- peripheralDidUpdateValueForCharacteristic
|
- peripheralDidUpdateValueForCharacteristic
|
||||||
|
|
||||||
pragma: [ clang diagnostic ignored "-Wformat-security" ]
|
pragma: [ clang diagnostic ignored "-Wformat-security" ]
|
||||||
gogc: true
|
#gogc: true
|
||||||
|
|
|
@ -8,6 +8,11 @@ import (
|
||||||
"git.wow.st/gmp/nswrap/examples/foundation/ns"
|
"git.wow.st/gmp/nswrap/examples/foundation/ns"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
gs1 *ns.NSString
|
||||||
|
gs2 *ns.NSString
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Printf("Creating some strings:\n")
|
fmt.Printf("Creating some strings:\n")
|
||||||
n1 := ns.NSStringWithUTF8String(ns.CharWithGoString("hi there"))
|
n1 := ns.NSStringWithUTF8String(ns.CharWithGoString("hi there"))
|
||||||
|
@ -64,6 +69,19 @@ func main() {
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
fmt.Printf("\nNSArrayWithObjects() (length 1)\n")
|
||||||
|
a2 = ns.NSArrayWithObjects(n1)
|
||||||
|
a2.ObjectEnumerator().ForIn(func(o *ns.Id) bool {
|
||||||
|
switch {
|
||||||
|
case o.IsKindOfClass(ns.NSStringClass()):
|
||||||
|
fmt.Println(o.NSString().UTF8String())
|
||||||
|
return true // continue enumeration
|
||||||
|
default:
|
||||||
|
fmt.Println("Unknown class")
|
||||||
|
return false // terminate enumeration
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
fmt.Printf("\nNSArrayWithObjects()\n")
|
fmt.Printf("\nNSArrayWithObjects()\n")
|
||||||
a2 = ns.NSArrayWithObjects(n1, n2, n3, s1)
|
a2 = ns.NSArrayWithObjects(n1, n2, n3, s1)
|
||||||
fmt.Printf("\nNSArray.ObjectEnumerator().ForIn():\n")
|
fmt.Printf("\nNSArray.ObjectEnumerator().ForIn():\n")
|
||||||
|
@ -101,4 +119,14 @@ func main() {
|
||||||
fmt.Printf("\nNSStringWithFormat()\n")
|
fmt.Printf("\nNSStringWithFormat()\n")
|
||||||
str := ns.NSStringWithFormat(nst("(%@) (%@)\n(%@)\n"), n2, n3, s1)
|
str := ns.NSStringWithFormat(nst("(%@) (%@)\n(%@)\n"), n2, n3, s1)
|
||||||
fmt.Printf("%s\n", str)
|
fmt.Printf("%s\n", str)
|
||||||
|
|
||||||
|
fmt.Printf("\nGlobal strings\n")
|
||||||
|
gs1 = ns.NSStringWithGoString("global string 1")
|
||||||
|
gs2 = ns.NSStringWithGoString("global string 2")
|
||||||
|
fmt.Printf("\nArrayWithObjects\n")
|
||||||
|
a2 = ns.NSArrayWithObjects(gs1, gs2)
|
||||||
|
a2.ObjectEnumerator().ForIn(func(o *ns.Id) bool {
|
||||||
|
fmt.Printf("--%s\n",o.NSString())
|
||||||
|
return true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
26
examples/functions/main.go
Normal file
26
examples/functions/main.go
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"unsafe"
|
||||||
|
"git.wow.st/gmp/nswrap/examples/functions/ns"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var s ns.Stat
|
||||||
|
ns.Puts(ns.CharWithGoString("Hi there"))
|
||||||
|
ret := ns.Fstat(3,&s)
|
||||||
|
fmt.Printf("Fstat: %d\n",ret)
|
||||||
|
|
||||||
|
fmt.Printf("Opening file\n")
|
||||||
|
f := ns.Fopen(ns.CharWithGoString("nswrap.yaml"),ns.CharWithGoString("r"))
|
||||||
|
ret = ns.Fstat(3,&s)
|
||||||
|
fmt.Printf("Fstat: %d\n",ret)
|
||||||
|
chr := make([]byte,4096)
|
||||||
|
i := ns.Fread(unsafe.Pointer(&chr[0]), 1, 4096, f)
|
||||||
|
if i < 4096 {
|
||||||
|
chr = chr[:i]
|
||||||
|
}
|
||||||
|
fmt.Printf("file contents:\n%s\n",string(chr))
|
||||||
|
}
|
||||||
|
|
17
examples/functions/nswrap.yaml
Normal file
17
examples/functions/nswrap.yaml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
inputfiles:
|
||||||
|
- /usr/include/stdio.h
|
||||||
|
- /usr/include/stdlib.h
|
||||||
|
- /usr/include/sys/stat.h
|
||||||
|
sysimports:
|
||||||
|
- stdio.h
|
||||||
|
- stdlib.h
|
||||||
|
- sys/stat.h
|
||||||
|
functions:
|
||||||
|
- sranddev
|
||||||
|
- cgetclose
|
||||||
|
- cgetset
|
||||||
|
- devname
|
||||||
|
- puts
|
||||||
|
- fstat
|
||||||
|
- fopen
|
||||||
|
- fread
|
108
types/convert.go
108
types/convert.go
|
@ -2,6 +2,7 @@ package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
@ -12,6 +13,7 @@ var super map[string]string
|
||||||
//wrapped is a map recording whether a given GoType is to be "wrapped" in a
|
//wrapped is a map recording whether a given GoType is to be "wrapped" in a
|
||||||
//go struct.
|
//go struct.
|
||||||
var wrapped map[string]bool
|
var wrapped map[string]bool
|
||||||
|
var tdptr map[string]bool
|
||||||
|
|
||||||
func ShouldWrap(gt string) bool {
|
func ShouldWrap(gt string) bool {
|
||||||
return wrapped[gt]
|
return wrapped[gt]
|
||||||
|
@ -21,6 +23,10 @@ func PtrShouldWrap(gt string) bool {
|
||||||
return gt != "" && gt[0] == '*' && wrapped[gt[1:]]
|
return gt != "" && gt[0] == '*' && wrapped[gt[1:]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TypedefShouldWrap(gt string) bool {
|
||||||
|
return tdptr[gt]
|
||||||
|
}
|
||||||
|
|
||||||
//goInterfaces records the names of top level Go interfaces.
|
//goInterfaces records the names of top level Go interfaces.
|
||||||
var goInterfaces map[string]bool
|
var goInterfaces map[string]bool
|
||||||
|
|
||||||
|
@ -52,6 +58,7 @@ var (
|
||||||
func init() {
|
func init() {
|
||||||
super = make(map[string]string)
|
super = make(map[string]string)
|
||||||
wrapped = make(map[string]bool)
|
wrapped = make(map[string]bool)
|
||||||
|
tdptr = make(map[string]bool)
|
||||||
goInterfaces = make(map[string]bool)
|
goInterfaces = make(map[string]bool)
|
||||||
TypeParameters = make(map[string]map[string]string)
|
TypeParameters = make(map[string]map[string]string)
|
||||||
typedefs = make(map[string]*Type)
|
typedefs = make(map[string]*Type)
|
||||||
|
@ -164,9 +171,6 @@ func (t *Type) BaseType() *Type {
|
||||||
if t == nil {
|
if t == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// if td := t.Typedef(); td != nil {
|
|
||||||
// return td.BaseType()
|
|
||||||
// }
|
|
||||||
ret := NewType(
|
ret := NewType(
|
||||||
t.Node.BaseType(),
|
t.Node.BaseType(),
|
||||||
t.Class,
|
t.Class,
|
||||||
|
@ -201,14 +205,12 @@ func _goType(ct string) string {
|
||||||
ct = strings.TrimPrefix(ct, "Struct")
|
ct = strings.TrimPrefix(ct, "Struct")
|
||||||
ct = swapstars(ct)
|
ct = swapstars(ct)
|
||||||
if len(ct) > 0 && ct[0] == '*' && IsGoInterface(ct[1:]) {
|
if len(ct) > 0 && ct[0] == '*' && IsGoInterface(ct[1:]) {
|
||||||
//return ct[1:]
|
return ct
|
||||||
return ct // ??
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ct == "Id" {
|
if ct == "Id" {
|
||||||
ct = "*Id"
|
ct = "*Id"
|
||||||
}
|
}
|
||||||
//if len(ct) > 1 && ShouldWrap(ct[1:]) {
|
|
||||||
if ShouldWrap(ct) {
|
if ShouldWrap(ct) {
|
||||||
return ct
|
return ct
|
||||||
}
|
}
|
||||||
|
@ -245,13 +247,32 @@ func (t *Type) _CType(attrib bool) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Type) GoTypeDecl() string {
|
func (t *Type) GoTypeDecl() string {
|
||||||
if wrapped[t.GoType()] {
|
gt := t.GoType()
|
||||||
|
if wrapped[gt] {
|
||||||
return t.GoInterfaceDecl()
|
return t.GoInterfaceDecl()
|
||||||
}
|
}
|
||||||
if t.Node.IsId() {
|
if t.Node.IsId() {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
gt := t.GoType()
|
if td := t.Typedef(); td != nil {
|
||||||
|
tdgt := td.GoType()
|
||||||
|
if ShouldWrap(tdgt) || PtrShouldWrap(tdgt) { // type alias
|
||||||
|
if PtrIsGoInterface(tdgt) {
|
||||||
|
tdgt = "*Id"
|
||||||
|
}
|
||||||
|
if IsGoInterface(tdgt) {
|
||||||
|
tdgt = "Id"
|
||||||
|
}
|
||||||
|
Wrap(gt)
|
||||||
|
tdptr[gt] = true
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
type %s = %s
|
||||||
|
`, gt, tdgt)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
type %s %s
|
||||||
|
`, gt, td.CGoType())
|
||||||
|
}
|
||||||
if Debug {
|
if Debug {
|
||||||
fmt.Printf(" writing GoTypeDecl for %s\n",gt)
|
fmt.Printf(" writing GoTypeDecl for %s\n",gt)
|
||||||
}
|
}
|
||||||
|
@ -376,20 +397,35 @@ func GoToC(name string, pnames, snames []string, rtype *Type, ptypes []*Type, fu
|
||||||
//fmt.Printf(" PtrIsGoInterface(%s) = true\n",rtgt)
|
//fmt.Printf(" PtrIsGoInterface(%s) = true\n",rtgt)
|
||||||
rtgt = "*Id"
|
rtgt = "*Id"
|
||||||
}
|
}
|
||||||
sw := PtrShouldWrap(rtgt) || rtgt == "*Id"
|
sw := PtrShouldWrap(rtgt) || rtgt == "*Id" || TypedefShouldWrap(rtgt)
|
||||||
|
isptr := rtype.IsPointer()
|
||||||
if rt != "void" {
|
if rt != "void" {
|
||||||
if sw {
|
switch {
|
||||||
|
case PtrShouldWrap(rtgt), rtgt == "*Id":
|
||||||
|
isptr = true
|
||||||
|
if PtrIsGoInterface(rtgt) {
|
||||||
|
rtgt = "*Id"
|
||||||
|
}
|
||||||
ret.WriteString(fmt.Sprintf(
|
ret.WriteString(fmt.Sprintf(
|
||||||
`ret := &%s{}
|
`ret := &%s{}
|
||||||
ret.ptr = `, rtgt[1:]))
|
ret.ptr = unsafe.Pointer(`, rtgt[1:]))
|
||||||
} else {
|
case TypedefShouldWrap(rtgt):
|
||||||
|
isptr = true
|
||||||
|
rtgt := rtype.Typedef().GoType()
|
||||||
|
if PtrIsGoInterface(rtgt) {
|
||||||
|
rtgt = "*Id"
|
||||||
|
}
|
||||||
|
ret.WriteString(fmt.Sprintf(
|
||||||
|
`ret := &%s{}
|
||||||
|
ret.ptr = unsafe.Pointer(`, rtgt[1:]))
|
||||||
|
default:
|
||||||
if rtgt == "BOOL" {
|
if rtgt == "BOOL" {
|
||||||
ret.WriteString("ret := (")
|
ret.WriteString("ret := (")
|
||||||
rtgt = "bool"
|
rtgt = "bool"
|
||||||
} else {
|
} else {
|
||||||
ret.WriteString("ret := (" + rtgt + ")(")
|
ret.WriteString("ret := (" + rtgt + ")(")
|
||||||
}
|
}
|
||||||
if rtype.IsPointer() {
|
if isptr {
|
||||||
ret.WriteString("unsafe.Pointer(")
|
ret.WriteString("unsafe.Pointer(")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -398,20 +434,25 @@ func GoToC(name string, pnames, snames []string, rtype *Type, ptypes []*Type, fu
|
||||||
parms := []string{}
|
parms := []string{}
|
||||||
for i := 0; i < len(pnames); i++ {
|
for i := 0; i < len(pnames); i++ {
|
||||||
pn, pt := pnames[i], ptypes[i]
|
pn, pt := pnames[i], ptypes[i]
|
||||||
|
ptgt := pt.GoType()
|
||||||
p := pn
|
p := pn
|
||||||
if (PtrShouldWrap(pt.GoType()) || PtrIsGoInterface(pt.GoType())) && !pt.Variadic {
|
switch {
|
||||||
|
case (PtrShouldWrap(ptgt) || PtrIsGoInterface(ptgt)) && !pt.Variadic:
|
||||||
p = pn + ".Ptr()"
|
p = pn + ".Ptr()"
|
||||||
} else {
|
case TypedefShouldWrap(ptgt) && !pt.Variadic && fun:
|
||||||
switch {
|
p = "(" + pt.CGoType() + ")(" + pn + ".Ptr())"
|
||||||
case snames[i] != "":
|
case TypedefShouldWrap(ptgt) && !pt.Variadic && !fun:
|
||||||
p = "unsafe.Pointer(&" + snames[i] + "[0])"
|
p = pn + ".Ptr()"
|
||||||
case pt.Variadic:
|
case snames[i] != "":
|
||||||
p = "unsafe.Pointer(&" + p + ")"
|
p = "unsafe.Pointer(&" + snames[i] + "[0])"
|
||||||
case pt.IsPointer() && !fun:
|
case pt.Variadic:
|
||||||
p = "unsafe.Pointer(" + pn + ")"
|
p = "unsafe.Pointer(&" + p + ")"
|
||||||
default:
|
case pt.IsPointer() && !fun:
|
||||||
p = "(" + pt.CGoType() + ")(" + pn + ")"
|
p = "unsafe.Pointer(" + pn + ")"
|
||||||
}
|
case pt.IsPointer() && fun && pt.BaseType().CType() == "void":
|
||||||
|
p = pn
|
||||||
|
default:
|
||||||
|
p = "(" + pt.CGoType() + ")(" + pn + ")"
|
||||||
}
|
}
|
||||||
parms = append(parms, p)
|
parms = append(parms, p)
|
||||||
}
|
}
|
||||||
|
@ -419,9 +460,9 @@ func GoToC(name string, pnames, snames []string, rtype *Type, ptypes []*Type, fu
|
||||||
ret.WriteString(")")
|
ret.WriteString(")")
|
||||||
if rt != "void" && !sw {
|
if rt != "void" && !sw {
|
||||||
ret.WriteString(")")
|
ret.WriteString(")")
|
||||||
if rtype.IsPointer() {
|
}
|
||||||
ret.WriteString(")")
|
if isptr {
|
||||||
}
|
ret.WriteString(")")
|
||||||
}
|
}
|
||||||
if rt == "BOOL" {
|
if rt == "BOOL" {
|
||||||
ret.WriteString(" != 0")
|
ret.WriteString(" != 0")
|
||||||
|
@ -430,7 +471,12 @@ func GoToC(name string, pnames, snames []string, rtype *Type, ptypes []*Type, fu
|
||||||
if sname == "" {
|
if sname == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
ptgt := (ptypes[i].GoType())[2:]
|
ptgt := ptypes[i].GoType()
|
||||||
|
if len(ptgt) < 2 {
|
||||||
|
fmt.Printf("Error in function translation -- argument %s to %s should be pointer to pointer\n",pnames[i],name)
|
||||||
|
os.Exit(-1)
|
||||||
|
}
|
||||||
|
ptgt = ptgt[2:]
|
||||||
if IsGoInterface(ptgt) {
|
if IsGoInterface(ptgt) {
|
||||||
ptgt = "Id"
|
ptgt = "Id"
|
||||||
}
|
}
|
||||||
|
@ -450,7 +496,7 @@ func GoToC(name string, pnames, snames []string, rtype *Type, ptypes []*Type, fu
|
||||||
if rt != "void" {
|
if rt != "void" {
|
||||||
if fin {
|
if fin {
|
||||||
ret.WriteString(fmt.Sprintf(`
|
ret.WriteString(fmt.Sprintf(`
|
||||||
runtime.SetFinalizer(ret, func(o *%s) {
|
runtime.SetFinalizer(ret, func(o %s) {
|
||||||
o.Release()
|
o.Release()
|
||||||
})`,rtgt))
|
})`,rtgt))
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,12 @@ func TestType(t *testing.T) {
|
||||||
chk_newtype()
|
chk_newtype()
|
||||||
tint := tp
|
tint := tp
|
||||||
|
|
||||||
|
str = "id"
|
||||||
|
n = &Node{"TypeName", "", []*Node{
|
||||||
|
&Node{"TypedefName", "id", []*Node{}}}}
|
||||||
|
chk_newtype()
|
||||||
|
//nsid := tp
|
||||||
|
|
||||||
str = "NSObject"
|
str = "NSObject"
|
||||||
n = &Node{"TypeName", "", []*Node{
|
n = &Node{"TypeName", "", []*Node{
|
||||||
&Node{"TypedefName", "NSObject", []*Node{}}}}
|
&Node{"TypedefName", "NSObject", []*Node{}}}}
|
||||||
|
@ -63,6 +69,33 @@ func TestType(t *testing.T) {
|
||||||
chk_newtype()
|
chk_newtype()
|
||||||
nst := tp
|
nst := tp
|
||||||
|
|
||||||
|
str = "NSString**"
|
||||||
|
n = &Node{"TypeName", "", []*Node{
|
||||||
|
&Node{"TypedefName", "NSString", []*Node{}},
|
||||||
|
&Node{"Pointer", "*", []*Node{}},
|
||||||
|
&Node{"Pointer", "*", []*Node{}}}}
|
||||||
|
chk_newtype()
|
||||||
|
chk(tp.IsPointer(), true)
|
||||||
|
chk(tp.Typedef(), nil)
|
||||||
|
nstpp := tp
|
||||||
|
|
||||||
|
str = "NSObject**"
|
||||||
|
n = &Node{"TypeName", "", []*Node{
|
||||||
|
&Node{"TypedefName", "NSObject", []*Node{}},
|
||||||
|
&Node{"Pointer", "*", []*Node{}},
|
||||||
|
&Node{"Pointer", "*", []*Node{}}}}
|
||||||
|
chk_newtype()
|
||||||
|
chk(tp.IsPointer(), true)
|
||||||
|
nsopp := tp
|
||||||
|
|
||||||
|
str = "NSObject*"
|
||||||
|
n = &Node{"TypeName", "", []*Node{
|
||||||
|
&Node{"TypedefName", "NSObject", []*Node{}},
|
||||||
|
&Node{"Pointer", "*", []*Node{}}}}
|
||||||
|
chk_newtype()
|
||||||
|
chk(tp.IsPointer(), true)
|
||||||
|
nsop := tp
|
||||||
|
|
||||||
str = "NSString*"
|
str = "NSString*"
|
||||||
n = &Node{"TypeName", "", []*Node{
|
n = &Node{"TypeName", "", []*Node{
|
||||||
&Node{"TypedefName", "NSString", []*Node{}},
|
&Node{"TypedefName", "NSString", []*Node{}},
|
||||||
|
@ -70,14 +103,14 @@ func TestType(t *testing.T) {
|
||||||
chk_newtype()
|
chk_newtype()
|
||||||
chk(tp.IsPointer(), true)
|
chk(tp.IsPointer(), true)
|
||||||
chk(tp.Typedef(), nil)
|
chk(tp.Typedef(), nil)
|
||||||
tpNSString := tp
|
nstp := tp
|
||||||
|
|
||||||
str = "myTypedef"
|
str = "myTypedef"
|
||||||
AddTypedef("myTypedef", tp)
|
AddTypedef("myTypedef", tp)
|
||||||
n = &Node{"TypeName", "", []*Node{
|
n = &Node{"TypeName", "", []*Node{
|
||||||
&Node{"TypedefName", "myTypedef", []*Node{}}}}
|
&Node{"TypedefName", "myTypedef", []*Node{}}}}
|
||||||
chk_newtype()
|
chk_newtype()
|
||||||
chk(tp.Typedef(), tpNSString)
|
chk(tp.Typedef(), nstp)
|
||||||
|
|
||||||
str = "const NSArray <ObjectType * _Nonnull> *"
|
str = "const NSArray <ObjectType * _Nonnull> *"
|
||||||
n = &Node{"TypeName", "", []*Node{
|
n = &Node{"TypeName", "", []*Node{
|
||||||
|
@ -146,10 +179,6 @@ func TestType(t *testing.T) {
|
||||||
|
|
||||||
chk(tp.GoTypeDecl(), `
|
chk(tp.GoTypeDecl(), `
|
||||||
type MyTypedef **C.NSObject
|
type MyTypedef **C.NSObject
|
||||||
`)
|
|
||||||
chk(tp2.GoTypeDecl(), "")
|
|
||||||
chk(nst.GoTypeDecl(), `
|
|
||||||
type NSString C.NSString
|
|
||||||
`)
|
`)
|
||||||
str = "void"
|
str = "void"
|
||||||
n = &Node{"TypeName", "", []*Node{
|
n = &Node{"TypeName", "", []*Node{
|
||||||
|
@ -174,7 +203,7 @@ type NSString C.NSString
|
||||||
str = "NSObject*"
|
str = "NSObject*"
|
||||||
n, _ = Parse(str)
|
n, _ = Parse(str)
|
||||||
chk_newtype()
|
chk_newtype()
|
||||||
chk(tp.GoType(), "NSObject")
|
chk(tp.GoType(), "*NSObject")
|
||||||
|
|
||||||
Wrap("NSString")
|
Wrap("NSString")
|
||||||
chk(nso.GoTypeDecl(), `
|
chk(nso.GoTypeDecl(), `
|
||||||
|
@ -186,9 +215,9 @@ type NSObject interface {
|
||||||
|
|
||||||
chk(nst.GoTypeDecl(), `
|
chk(nst.GoTypeDecl(), `
|
||||||
type NSString struct { Id }
|
type NSString struct { Id }
|
||||||
func (o NSString) Ptr() unsafe.Pointer { return o.ptr }
|
func (o *NSString) Ptr() unsafe.Pointer { if o == nil { return nil }; return o.ptr }
|
||||||
func (o Id) NSString() NSString {
|
func (o *Id) NSString() *NSString {
|
||||||
ret := NSString{}
|
ret := &NSString{}
|
||||||
ret.ptr = o.ptr
|
ret.ptr = o.ptr
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
@ -242,12 +271,13 @@ func (o Id) NSString() NSString {
|
||||||
|
|
||||||
str = "GoToC"
|
str = "GoToC"
|
||||||
var rtype *Type
|
var rtype *Type
|
||||||
ptypes := []*Type{nst, nso, tint, voidpp}
|
ptypes := []*Type{nsop, nstp, tint, voidpp}
|
||||||
pnames := []string{"p1", "p2", "p3", "p4"}
|
pnames := []string{"p1", "p2", "p3", "p4"}
|
||||||
snames := []string{"", "", "", ""}
|
snames := []string{"", "", "", ""}
|
||||||
|
|
||||||
chk_gotoc := func(expected string) {
|
chk_gotoc := func(expected string) {
|
||||||
chk(GoToC("myFun", pnames, snames, rtype, ptypes, false), expected)
|
fmt.Printf("chk_gotoc\n")
|
||||||
|
chk(GoToC("myFun", pnames, snames, rtype, ptypes, false, false), expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
chk_gotoc("")
|
chk_gotoc("")
|
||||||
|
@ -265,61 +295,75 @@ func (o Id) NSString() NSString {
|
||||||
`ret := (*unsafe.Pointer)(unsafe.Pointer(C.myFun(p1.Ptr(), p2.Ptr(), (C.int)(p3), unsafe.Pointer(p4))))
|
`ret := (*unsafe.Pointer)(unsafe.Pointer(C.myFun(p1.Ptr(), p2.Ptr(), (C.int)(p3), unsafe.Pointer(p4))))
|
||||||
return ret`)
|
return ret`)
|
||||||
|
|
||||||
rtype = nst
|
rtype = nstp
|
||||||
chk_gotoc(
|
chk_gotoc(
|
||||||
`ret := NSString{}
|
`ret := &NSString{}
|
||||||
ret.ptr = C.myFun(p1.Ptr(), p2.Ptr(), (C.int)(p3), unsafe.Pointer(p4))
|
ret.ptr = unsafe.Pointer(C.myFun(p1.Ptr(), p2.Ptr(), (C.int)(p3), unsafe.Pointer(p4)))
|
||||||
return ret`)
|
return ret`)
|
||||||
|
|
||||||
rtype = nso
|
rtype = nsop
|
||||||
chk_gotoc(
|
chk_gotoc(
|
||||||
`ret := Id{}
|
`ret := &Id{}
|
||||||
ret.ptr = C.myFun(p1.Ptr(), p2.Ptr(), (C.int)(p3), unsafe.Pointer(p4))
|
ret.ptr = unsafe.Pointer(C.myFun(p1.Ptr(), p2.Ptr(), (C.int)(p3), unsafe.Pointer(p4)))
|
||||||
return ret`)
|
return ret`)
|
||||||
|
|
||||||
ptypes[1].Variadic = true
|
ptypes[1].Variadic = true
|
||||||
|
ptypes[0].Variadic = false
|
||||||
chk_gotoc(
|
chk_gotoc(
|
||||||
`ret := Id{}
|
`ret := &Id{}
|
||||||
ret.ptr = C.myFun(p1.Ptr(), unsafe.Pointer(&p2), (C.int)(p3), unsafe.Pointer(p4))
|
ret.ptr = unsafe.Pointer(C.myFun(p1.Ptr(), unsafe.Pointer(&p2), (C.int)(p3), unsafe.Pointer(p4)))
|
||||||
return ret`)
|
return ret`)
|
||||||
ptypes[1].Variadic = false
|
|
||||||
|
|
||||||
|
ptypes[1].Variadic = false
|
||||||
snames[1] = "p2p"
|
snames[1] = "p2p"
|
||||||
|
ptypes[1] = nsopp
|
||||||
chk_gotoc(
|
chk_gotoc(
|
||||||
`ret := Id{}
|
`ret := &Id{}
|
||||||
ret.ptr = C.myFun(p1.Ptr(), p2.Ptr(), (C.int)(p3), unsafe.Pointer(p4))
|
ret.ptr = unsafe.Pointer(C.myFun(p1.Ptr(), unsafe.Pointer(&p2p[0]), (C.int)(p3), unsafe.Pointer(p4)))
|
||||||
(*p2) = (*p2)[:cap(*p2)]
|
(*p2) = (*p2)[:cap(*p2)]
|
||||||
for i := 0; i < len(*p2); i++ {
|
for i := 0; i < len(*p2); i++ {
|
||||||
if p2p[i] == nil {
|
if p2p[i] == nil {
|
||||||
(*p2) = (*p2)[:i]
|
(*p2) = (*p2)[:i]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if (*p2)[i] == nil {
|
||||||
|
(*p2)[i] = &Id{}
|
||||||
|
}
|
||||||
(*p2)[i].ptr = p2p[i]
|
(*p2)[i].ptr = p2p[i]
|
||||||
}
|
}
|
||||||
return ret`)
|
return ret`)
|
||||||
snames[1] = ""
|
snames[1] = ""
|
||||||
snames[2] = "p3p"
|
snames[2] = "p3p"
|
||||||
|
ptypes[1] = nsop
|
||||||
|
ptypes[2] = nstpp
|
||||||
chk_gotoc(
|
chk_gotoc(
|
||||||
`ret := Id{}
|
`ret := &Id{}
|
||||||
ret.ptr = C.myFun(p1.Ptr(), p2.Ptr(), unsafe.Pointer(&p3p[0]), unsafe.Pointer(p4))
|
ret.ptr = unsafe.Pointer(C.myFun(p1.Ptr(), p2.Ptr(), unsafe.Pointer(&p3p[0]), unsafe.Pointer(p4)))
|
||||||
(*p3) = (*p3)[:cap(*p3)]
|
(*p3) = (*p3)[:cap(*p3)]
|
||||||
for i := 0; i < len(*p3); i++ {
|
for i := 0; i < len(*p3); i++ {
|
||||||
if p3p[i] == nil {
|
if p3p[i] == nil {
|
||||||
(*p3) = (*p3)[:i]
|
(*p3) = (*p3)[:i]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if (*p3)[i] == nil {
|
||||||
|
(*p3)[i] = &NSString{}
|
||||||
|
}
|
||||||
(*p3)[i].ptr = p3p[i]
|
(*p3)[i].ptr = p3p[i]
|
||||||
}
|
}
|
||||||
return ret`)
|
return ret`)
|
||||||
chk(GoToC("myFun", pnames, snames, rtype, ptypes, true),
|
|
||||||
`ret := Id{}
|
chk(GoToC("myFun", pnames, snames, rtype, ptypes, true, false),
|
||||||
ret.ptr = C.myFun(p1.Ptr(), p2.Ptr(), unsafe.Pointer(&p3p[0]), (**C.void)(p4))
|
`ret := &Id{}
|
||||||
|
ret.ptr = unsafe.Pointer(C.myFun(p1.Ptr(), p2.Ptr(), unsafe.Pointer(&p3p[0]), p4))
|
||||||
(*p3) = (*p3)[:cap(*p3)]
|
(*p3) = (*p3)[:cap(*p3)]
|
||||||
for i := 0; i < len(*p3); i++ {
|
for i := 0; i < len(*p3); i++ {
|
||||||
if p3p[i] == nil {
|
if p3p[i] == nil {
|
||||||
(*p3) = (*p3)[:i]
|
(*p3) = (*p3)[:i]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if (*p3)[i] == nil {
|
||||||
|
(*p3)[i] = &NSString{}
|
||||||
|
}
|
||||||
(*p3)[i].ptr = p3p[i]
|
(*p3)[i].ptr = p3p[i]
|
||||||
}
|
}
|
||||||
return ret`)
|
return ret`)
|
||||||
|
|
|
@ -236,6 +236,7 @@ func TypeQualifier(s string, n *Node) (string, *Node) {
|
||||||
Word("const"),
|
Word("const"),
|
||||||
Word("restrict"),
|
Word("restrict"),
|
||||||
Word("volatile"),
|
Word("volatile"),
|
||||||
|
Word("__restrict"),
|
||||||
))(s, n)
|
))(s, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -209,6 +209,24 @@ func TestParse(t *testing.T) {
|
||||||
-<TypeSpecifier> 'int'
|
-<TypeSpecifier> 'int'
|
||||||
-<Pointer> '*'
|
-<Pointer> '*'
|
||||||
-<Function> ''
|
-<Function> ''
|
||||||
|
`)
|
||||||
|
runParseTest(`int *(char*)`,
|
||||||
|
`<TypeName> ''
|
||||||
|
-<TypeSpecifier> 'int'
|
||||||
|
-<Pointer> '*'
|
||||||
|
-<Function> ''
|
||||||
|
--<ParameterDeclaration> ''
|
||||||
|
---<TypeSpecifier> 'char'
|
||||||
|
---<Pointer> '*'
|
||||||
|
`)
|
||||||
|
runParseTest(`RANGE *(char*)`,
|
||||||
|
`<TypeName> ''
|
||||||
|
-<TypedefName> 'RANGE'
|
||||||
|
-<Pointer> '*'
|
||||||
|
-<Function> ''
|
||||||
|
--<ParameterDeclaration> ''
|
||||||
|
---<TypeSpecifier> 'char'
|
||||||
|
---<Pointer> '*'
|
||||||
`)
|
`)
|
||||||
runParseTest(`int (*)(void)`,
|
runParseTest(`int (*)(void)`,
|
||||||
`<TypeName> ''
|
`<TypeName> ''
|
||||||
|
|
11
wrap/main.go
11
wrap/main.go
|
@ -319,11 +319,14 @@ func (w *Wrapper) gpntp(m *Method) ([]string, []string, []*types.Type, string) {
|
||||||
ns = append(ns, "o")
|
ns = append(ns, "o")
|
||||||
tps = append(tps, types.NewTypeFromString(m.Class+"*", ""))
|
tps = append(tps, types.NewTypeFromString(m.Class+"*", ""))
|
||||||
}
|
}
|
||||||
for _, p := range m.Parameters {
|
for i, p := range m.Parameters {
|
||||||
gname := p.Vname
|
gname := p.Vname
|
||||||
if goreserved[gname] {
|
if goreserved[gname] {
|
||||||
gname = gname + "_"
|
gname = gname + "_"
|
||||||
}
|
}
|
||||||
|
if gname == "" {
|
||||||
|
gname = fmt.Sprintf("p%d",i)
|
||||||
|
}
|
||||||
ns = append(ns, gname)
|
ns = append(ns, gname)
|
||||||
tps = append(tps, p.Type)
|
tps = append(tps, p.Type)
|
||||||
}
|
}
|
||||||
|
@ -1688,14 +1691,14 @@ func (d %s) %sCallback(f func(%s)%s) {
|
||||||
} else {
|
} else {
|
||||||
gt2 = gtypes[i][j-1]
|
gt2 = gtypes[i][j-1]
|
||||||
}
|
}
|
||||||
if types.IsGoInterface(gt2) || types.ShouldWrap(gt2) {
|
if types.PtrIsGoInterface(gt2) {
|
||||||
gt2 = "*Id"
|
gt2 = "*Id"
|
||||||
}
|
}
|
||||||
if gt2 == "*Id" {
|
if gt2 == "*Id" || types.PtrShouldWrap(gt2) {
|
||||||
garglist = append(garglist, fmt.Sprintf(
|
garglist = append(garglist, fmt.Sprintf(
|
||||||
`a%d`, j))
|
`a%d`, j))
|
||||||
gargconv = append(gargconv, fmt.Sprintf(
|
gargconv = append(gargconv, fmt.Sprintf(
|
||||||
` a%d := %s{}; a%d.ptr = %s`, j, gt2, j, vnames[i][j]))
|
` a%d := &%s{}; a%d.ptr = %s`, j, gt2[1:], j, vnames[i][j]))
|
||||||
} else {
|
} else {
|
||||||
garglist = append(garglist, fmt.Sprintf(
|
garglist = append(garglist, fmt.Sprintf(
|
||||||
`(%s)(%s)`, gt2, vnames[i][j]))
|
`(%s)(%s)`, gt2, vnames[i][j]))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user