Comprehensive update, add some GC fixes, update examples to new MacOS
header file layout.
This commit is contained in:
parent
acc8cab583
commit
8b3a956bbe
|
@ -12,28 +12,28 @@ import (
|
||||||
//Shortcut for literal NSStrings
|
//Shortcut for literal NSStrings
|
||||||
var nst = ns.NSStringWithGoString
|
var nst = ns.NSStringWithGoString
|
||||||
|
|
||||||
func pb1() {
|
func pb1(self ns.GButton, super ns.GButtonSupermethods) {
|
||||||
fmt.Println("Pushed button 1")
|
fmt.Println("Pushed button 1")
|
||||||
}
|
}
|
||||||
|
|
||||||
func pb2() {
|
func pb2(self ns.GButton, super ns.GButtonSupermethods) {
|
||||||
fmt.Println("Pushed button 2")
|
fmt.Println("Pushed button 2")
|
||||||
a.Terminate(a)
|
a.Terminate(a)
|
||||||
}
|
}
|
||||||
|
|
||||||
func db() {
|
func db(self ns.GButton, super ns.GButtonSupermethods) {
|
||||||
fmt.Println("button deallocated")
|
fmt.Println("button deallocated")
|
||||||
}
|
}
|
||||||
|
|
||||||
func didFinishLaunching(n *ns.NSNotification) {
|
func didFinishLaunching(self ns.AppDelegate, n *ns.NSNotification) {
|
||||||
fmt.Println("Go: did finish launching")
|
fmt.Println("Go: did finish launching")
|
||||||
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(
|
||||||
ns.NSMakeRect(200, 200, 600, 600),
|
ns.NSMakeRect(200, 200, 600, 600),
|
||||||
ns.NSWindowStyleMaskTitled|ns.NSWindowStyleMaskClosable|
|
ns.NSWindowStyleMask(ns.NSWindowStyleMaskTitled|ns.NSWindowStyleMaskClosable|
|
||||||
ns.NSWindowStyleMaskResizable,
|
ns.NSWindowStyleMaskResizable),
|
||||||
ns.NSBackingStoreBuffered,
|
ns.NSBackingStoreType(ns.NSBackingStoreBuffered),
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
// We do not need to retain this because we are in garbage collection mode
|
// We do not need to retain this because we are in garbage collection mode
|
||||||
|
@ -103,21 +103,21 @@ func didFinishLaunching(n *ns.NSNotification) {
|
||||||
cv.AddConstraints(ns.NSLayoutConstraintsWithVisualFormat(
|
cv.AddConstraints(ns.NSLayoutConstraintsWithVisualFormat(
|
||||||
nst("H:|-[b1]"), 0, nil, viewmap))
|
nst("H:|-[b1]"), 0, nil, viewmap))
|
||||||
cv.AddConstraints(ns.NSLayoutConstraintsWithVisualFormat(
|
cv.AddConstraints(ns.NSLayoutConstraintsWithVisualFormat(
|
||||||
nst("H:[b1]-[b2]"), ns.NSLayoutFormatAlignAllBaseline, nil, viewmap))
|
nst("H:[b1]-[b2]"), ns.NSLayoutFormatOptions(ns.NSLayoutFormatAlignAllBaseline), nil, viewmap))
|
||||||
|
|
||||||
a.ActivateIgnoringOtherApps(1)
|
a.ActivateIgnoringOtherApps(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func shouldTerminateAfterLastWindowClosed(s *ns.NSApplication) ns.BOOL {
|
func shouldTerminateAfterLastWindowClosed(self ns.AppDelegate, s *ns.NSApplication) ns.BOOL {
|
||||||
fmt.Println("Go: should terminate after last window closed")
|
fmt.Println("Go: should terminate after last window closed")
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func willTerminate(n *ns.NSNotification) {
|
func willTerminate(self ns.AppDelegate, n *ns.NSNotification) {
|
||||||
fmt.Println("Go: will terminate")
|
fmt.Println("Go: will terminate")
|
||||||
}
|
}
|
||||||
|
|
||||||
func didBecomeActive(n *ns.NSNotification) {
|
func didBecomeActive(self ns.AppDelegate, n *ns.NSNotification) {
|
||||||
fmt.Println("Go: did become active")
|
fmt.Println("Go: did become active")
|
||||||
fmt.Printf("Notification: %s\n", n.Name().UTF8String())
|
fmt.Printf("Notification: %s\n", n.Name().UTF8String())
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ func app() {
|
||||||
// Lock OS thread because Cocoa uses thread-local storage
|
// Lock OS thread because Cocoa uses thread-local storage
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
a = ns.NSApplicationSharedApplication()
|
a = ns.NSApplicationSharedApplication()
|
||||||
a.SetActivationPolicy(ns.NSApplicationActivationPolicyRegular)
|
a.SetActivationPolicy(ns.NSApplicationActivationPolicy(ns.NSApplicationActivationPolicyRegular))
|
||||||
|
|
||||||
// Set up an AppDelegate
|
// Set up an AppDelegate
|
||||||
// assign it to a global variable so it doesn't get garbage collected
|
// assign it to a global variable so it doesn't get garbage collected
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# nswrap.yaml
|
# nswrap.yaml
|
||||||
inputfiles:
|
inputfiles:
|
||||||
- /System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
|
- /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
|
||||||
- /System/Library/Frameworks/AppKit.framework/Headers/AppKit.h
|
- /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/AppKit.framework/Headers/AppKit.h
|
||||||
|
|
||||||
classes:
|
classes:
|
||||||
- NSAutoreleasePool
|
- NSAutoreleasePool
|
||||||
|
|
|
@ -5,14 +5,14 @@ import "C"
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"git.wow.st/gmp/nswrap/examples/bluetooth/ns"
|
||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
"git.wow.st/gmp/nswrap/examples/bluetooth/ns"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func updateState(c *ns.CBCentralManager) {
|
func updateState(self ns.CBDelegate, c *ns.CBCentralManager) {
|
||||||
fmt.Printf("Go: did update state\n")
|
fmt.Printf("Go: did update state\n")
|
||||||
switch cm.CBManager.State() {
|
switch ns.NSInteger(cm.CBManager.State()) {
|
||||||
case ns.CBManagerStateUnknown:
|
case ns.CBManagerStateUnknown:
|
||||||
fmt.Printf(" unknown\n")
|
fmt.Printf(" unknown\n")
|
||||||
case ns.CBManagerStateResetting:
|
case ns.CBManagerStateResetting:
|
||||||
|
@ -30,7 +30,7 @@ func updateState(c *ns.CBCentralManager) {
|
||||||
fmt.Printf("Go: updateState returning\n")
|
fmt.Printf("Go: updateState returning\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func discoverPeripheral(c *ns.CBCentralManager, p *ns.CBPeripheral, d *ns.NSDictionary, rssi *ns.NSNumber) {
|
func discoverPeripheral(self ns.CBDelegate, 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()
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ func discoverPeripheral(c *ns.CBCentralManager, p *ns.CBPeripheral, d *ns.NSDict
|
||||||
c.ConnectPeripheral(peripheral, nil)
|
c.ConnectPeripheral(peripheral, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func connectPeripheral(c *ns.CBCentralManager, p *ns.CBPeripheral) {
|
func connectPeripheral(self ns.CBDelegate, c *ns.CBCentralManager, p *ns.CBPeripheral) {
|
||||||
fmt.Printf("Did connect peripheral\n")
|
fmt.Printf("Did connect peripheral\n")
|
||||||
|
|
||||||
// set ourselves up as a peripheral delegate
|
// set ourselves up as a peripheral delegate
|
||||||
|
@ -64,7 +64,7 @@ func connectPeripheral(c *ns.CBCentralManager, p *ns.CBPeripheral) {
|
||||||
fmt.Printf("Go: discoverPeripheral returning\n")
|
fmt.Printf("Go: discoverPeripheral returning\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func discoverServices(p *ns.CBPeripheral, e *ns.NSError) {
|
func discoverServices(self ns.CBDelegate, 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()
|
||||||
|
@ -97,7 +97,7 @@ func hr(d *ns.NSData) int {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func discoverCharacteristics(p *ns.CBPeripheral, s *ns.CBService, e *ns.NSError) {
|
func discoverCharacteristics(self ns.CBDelegate, p *ns.CBPeripheral, s *ns.CBService, e *ns.NSError) {
|
||||||
fmt.Printf("Did discover characteristics\n")
|
fmt.Printf("Did discover characteristics\n")
|
||||||
uuid := s.UUID()
|
uuid := s.UUID()
|
||||||
fmt.Printf("----%s\n", uuid.UUIDString())
|
fmt.Printf("----%s\n", uuid.UUIDString())
|
||||||
|
@ -117,7 +117,7 @@ func discoverCharacteristics(p *ns.CBPeripheral, s *ns.CBService, e *ns.NSError)
|
||||||
fmt.Printf("Go: discoverCharacteristics returning\n")
|
fmt.Printf("Go: discoverCharacteristics returning\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateValue(p *ns.CBPeripheral, chr *ns.CBCharacteristic, e *ns.NSError) {
|
func updateValue(self ns.CBDelegate, 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))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
inputfiles:
|
inputfiles:
|
||||||
- /System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
|
- /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
|
||||||
- /System/Library/Frameworks/CoreBluetooth.framework/Headers/CoreBluetooth.h
|
- /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/CoreBluetooth.framework/Headers/CoreBluetooth.h
|
||||||
|
|
||||||
classes:
|
classes:
|
||||||
- NSObject
|
- NSObject
|
||||||
|
|
|
@ -109,8 +109,8 @@ func main() {
|
||||||
oarr := make([]*ns.Id, 0, 5)
|
oarr := make([]*ns.Id, 0, 5)
|
||||||
fmt.Printf("Length of oarr is %d\n", len(oarr))
|
fmt.Printf("Length of oarr is %d\n", len(oarr))
|
||||||
karr := make([]*ns.Id, 0, 5)
|
karr := make([]*ns.Id, 0, 5)
|
||||||
fmt.Printf("\nGetObjects()\n")
|
fmt.Printf("\nGetObjectsAndKeysCount()\n")
|
||||||
d.GetObjects(&oarr, &karr, 4)
|
d.GetObjectsAndKeysCount(&oarr, &karr, 4)
|
||||||
fmt.Printf("Length of oarr is now %d\n", len(oarr))
|
fmt.Printf("Length of oarr is now %d\n", len(oarr))
|
||||||
for i, k := range karr {
|
for i, k := range karr {
|
||||||
fmt.Printf("-- %s -> %s\n", k.NSString(), oarr[i].NSString())
|
fmt.Printf("-- %s -> %s\n", k.NSString(), oarr[i].NSString())
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
inputfiles:
|
inputfiles:
|
||||||
- /System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
|
- /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
|
||||||
classes:
|
classes:
|
||||||
- NSAutoreleasePool
|
- NSAutoreleasePool
|
||||||
- NSArray
|
- NSArray
|
||||||
|
|
|
@ -2,8 +2,8 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"unsafe"
|
|
||||||
"git.wow.st/gmp/nswrap/examples/functions/ns"
|
"git.wow.st/gmp/nswrap/examples/functions/ns"
|
||||||
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -23,4 +23,3 @@ func main() {
|
||||||
}
|
}
|
||||||
fmt.Printf("file contents:\n%s\n", string(chr))
|
fmt.Printf("file contents:\n%s\n", string(chr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
inputfiles:
|
inputfiles:
|
||||||
- /usr/include/stdio.h
|
- /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/stdio.h
|
||||||
- /usr/include/stdlib.h
|
- /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/stdlib.h
|
||||||
- /usr/include/sys/stat.h
|
- /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/stat.h
|
||||||
sysimports:
|
sysimports:
|
||||||
- stdio.h
|
- stdio.h
|
||||||
- stdlib.h
|
- stdlib.h
|
||||||
|
|
|
@ -9,8 +9,8 @@ import (
|
||||||
"git.wow.st/gmp/nswrap/examples/gc/ns"
|
"git.wow.st/gmp/nswrap/examples/gc/ns"
|
||||||
)
|
)
|
||||||
|
|
||||||
func releaseX(x int) func (ns.MyClassSupermethods) {
|
func releaseX(x int) func(ns.MyClass, ns.MyClassSupermethods) {
|
||||||
return func(super ns.MyClassSupermethods) {
|
return func(self ns.MyClass, super ns.MyClassSupermethods) {
|
||||||
//fmt.Printf("--release %d\n", x)
|
//fmt.Printf("--release %d\n", x)
|
||||||
super.Release() // comment out for leak
|
super.Release() // comment out for leak
|
||||||
}
|
}
|
||||||
|
@ -177,13 +177,12 @@ func tmparr(i int) *ns.NSString {
|
||||||
o2 := ns.NSStringWithGoString(fmt.Sprintf("temp string 4-%d", i))
|
o2 := ns.NSStringWithGoString(fmt.Sprintf("temp string 4-%d", i))
|
||||||
arr := ns.NSArrayWithObjects(o1, o2)
|
arr := ns.NSArrayWithObjects(o1, o2)
|
||||||
os := make([]*ns.Id, 0, 2)
|
os := make([]*ns.Id, 0, 2)
|
||||||
arr.GetObjects(&os, ns.NSMakeRange(0,2))
|
arr.GetObjectsRange(&os, ns.NSMakeRange(0, 2))
|
||||||
|
|
||||||
defer runtime.GC() // collect o1, o2 and arr
|
defer runtime.GC() // collect o1, o2 and arr
|
||||||
return os[1].NSString() // should have been retained by NSArray.GetObjects()
|
return os[1].NSString() // should have been retained by NSArray.GetObjects()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func memtest6() {
|
func memtest6() {
|
||||||
fmt.Println("memtest6 started")
|
fmt.Println("memtest6 started")
|
||||||
i := 0
|
i := 0
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
inputfiles:
|
inputfiles:
|
||||||
- /System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
|
- /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
|
||||||
classes:
|
classes:
|
||||||
- NSAutoreleasePool
|
- NSAutoreleasePool
|
||||||
- NSArray
|
- NSArray
|
||||||
|
|
|
@ -10,13 +10,13 @@ import (
|
||||||
"git.wow.st/gmp/nswrap/examples/memory/ns"
|
"git.wow.st/gmp/nswrap/examples/memory/ns"
|
||||||
)
|
)
|
||||||
|
|
||||||
func dealloc() {
|
func dealloc(self ns.MyClass, super ns.MyClassSupermethods) {
|
||||||
//[super dealloc] is called for you automatically, so no Supermethods
|
//[super dealloc] is called for you automatically, so no Supermethods
|
||||||
//struct is provided here.
|
//struct is provided here.
|
||||||
fmt.Println("--dealloc called")
|
fmt.Println("--dealloc called")
|
||||||
}
|
}
|
||||||
|
|
||||||
func release(super ns.MyClassSupermethods) {
|
func release(self ns.MyClass, super ns.MyClassSupermethods) {
|
||||||
fmt.Println("--release called")
|
fmt.Println("--release called")
|
||||||
super.Release() // comment out for leak
|
super.Release() // comment out for leak
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
inputfiles:
|
inputfiles:
|
||||||
- /System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
|
- /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
|
||||||
classes:
|
classes:
|
||||||
- NSAutoreleasePool
|
- NSAutoreleasePool
|
||||||
- NSArray
|
- NSArray
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
ns "git.wow.st/gmp/nswrap/examples/simple/ClassOne"
|
ns "git.wow.st/gmp/nswrap/examples/simple/ClassOne"
|
||||||
)
|
)
|
||||||
|
|
||||||
func cb(super ns.ClassThreeSupermethods) ns.Int {
|
func cb(self ns.ClassThree, super ns.ClassThreeSupermethods) ns.Int {
|
||||||
fmt.Printf("In Go callback\n")
|
fmt.Printf("In Go callback\n")
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
inputfiles:
|
inputfiles:
|
||||||
- /System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
|
- /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
|
||||||
classes:
|
classes:
|
||||||
- NSString
|
- NSString
|
||||||
- NSThread
|
- NSThread
|
||||||
|
|
31
examples/subclass/main.go
Normal file
31
examples/subclass/main.go
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.wow.st/gmp/nswrap/examples/subclass/ns"
|
||||||
|
)
|
||||||
|
|
||||||
|
func c1release(self ns.C1, super ns.C1Supermethods) {
|
||||||
|
fmt.Printf("c1release()\n")
|
||||||
|
super.Release()
|
||||||
|
fmt.Printf("c1release() done\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func c2myMethod(self ns.C2) {
|
||||||
|
fmt.Printf("c2myMethod()\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Printf("Starting\n")
|
||||||
|
|
||||||
|
c1 := ns.C1Alloc()
|
||||||
|
c1.ReleaseCallback(c1release)
|
||||||
|
c1.Release()
|
||||||
|
|
||||||
|
c2 := ns.C2Alloc()
|
||||||
|
c2.MyMethodCallback(c2myMethod)
|
||||||
|
c2.Release()
|
||||||
|
|
||||||
|
fmt.Printf("Done\n")
|
||||||
|
}
|
58
examples/subclass/ns/exports.go
Normal file
58
examples/subclass/ns/exports.go
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
package ns
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo CFLAGS: -x objective-c -fno-objc-arc
|
||||||
|
#cgo LDFLAGS: -framework Foundation
|
||||||
|
#pragma clang diagnostic ignored "-Wformat-security"
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
//export C1Dealloc
|
||||||
|
func C1Dealloc(o unsafe.Pointer) {
|
||||||
|
C1Mux.RLock()
|
||||||
|
cb := C1Lookup[o].Dealloc
|
||||||
|
C1Mux.RUnlock()
|
||||||
|
if cb == nil { return }
|
||||||
|
self := C1{}
|
||||||
|
self.ptr = o
|
||||||
|
super := C1Supermethods{
|
||||||
|
self.SuperDealloc,
|
||||||
|
self.SuperRelease,
|
||||||
|
}
|
||||||
|
cb(self, super)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export C1Release
|
||||||
|
func C1Release(o unsafe.Pointer) {
|
||||||
|
C1Mux.RLock()
|
||||||
|
cb := C1Lookup[o].Release
|
||||||
|
C1Mux.RUnlock()
|
||||||
|
if cb == nil { return }
|
||||||
|
self := C1{}
|
||||||
|
self.ptr = o
|
||||||
|
super := C1Supermethods{
|
||||||
|
self.SuperDealloc,
|
||||||
|
self.SuperRelease,
|
||||||
|
}
|
||||||
|
cb(self, super)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export C2MyMethod
|
||||||
|
func C2MyMethod(o unsafe.Pointer) {
|
||||||
|
C2Mux.RLock()
|
||||||
|
cb := C2Lookup[o].MyMethod
|
||||||
|
C2Mux.RUnlock()
|
||||||
|
if cb == nil { return }
|
||||||
|
self := C2{}
|
||||||
|
self.ptr = o
|
||||||
|
cb(self)
|
||||||
|
}
|
9042
examples/subclass/ns/main.go
Normal file
9042
examples/subclass/ns/main.go
Normal file
File diff suppressed because it is too large
Load Diff
26
examples/subclass/nswrap.yaml
Normal file
26
examples/subclass/nswrap.yaml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
inputfiles: [ /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h ]
|
||||||
|
classes:
|
||||||
|
- NSObject
|
||||||
|
- NSString
|
||||||
|
subclasses:
|
||||||
|
c1:
|
||||||
|
NSObject:
|
||||||
|
- dealloc
|
||||||
|
- release
|
||||||
|
c2:
|
||||||
|
NSObject:
|
||||||
|
- -(void)myMethod
|
||||||
|
# c3:
|
||||||
|
# NSObject:
|
||||||
|
# - -(void)myMethod:(int)i
|
||||||
|
# c4:
|
||||||
|
# NSObject:
|
||||||
|
# - release
|
||||||
|
# - -(int)myMethod:(int)i
|
||||||
|
# c5:
|
||||||
|
# NSObject:
|
||||||
|
# - release
|
||||||
|
# - -(void)myMethod
|
||||||
|
|
||||||
|
frameworks: [ Foundation ]
|
||||||
|
pragma: [ clang diagnostic ignored "-Wformat-security" ]
|
BIN
examples/subclass/subclass
Executable file
BIN
examples/subclass/subclass
Executable file
Binary file not shown.
32
main.go
32
main.go
|
@ -12,7 +12,10 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.wow.st/gmp/nswrap/ast"
|
"git.wow.st/gmp/nswrap/ast"
|
||||||
|
"git.wow.st/gmp/nswrap/types"
|
||||||
"git.wow.st/gmp/nswrap/wrap"
|
"git.wow.st/gmp/nswrap/wrap"
|
||||||
|
|
||||||
|
"github.com/a8m/envsubst"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -33,15 +36,19 @@ type conf struct {
|
||||||
Debugast bool
|
Debugast bool
|
||||||
Classes []string
|
Classes []string
|
||||||
Functions []string
|
Functions []string
|
||||||
|
FunctionIgnore []string
|
||||||
Enums []string
|
Enums []string
|
||||||
Delegates map[string]map[string][]string
|
Delegates map[string]map[string][]string
|
||||||
Subclasses map[string]map[string][]string
|
Subclasses map[string]map[string][]string
|
||||||
Frameworks []string
|
Frameworks []string
|
||||||
|
Libraries []string
|
||||||
Frameworkdirs []string
|
Frameworkdirs []string
|
||||||
Imports []string
|
Imports []string
|
||||||
Sysimports []string
|
Sysimports []string
|
||||||
Pragma []string
|
Pragma []string
|
||||||
|
Typesubs map[string]string
|
||||||
Vaargs int
|
Vaargs int
|
||||||
|
Clang string
|
||||||
//Arc flag for debugging only, builds will break
|
//Arc flag for debugging only, builds will break
|
||||||
Arc bool
|
Arc bool
|
||||||
Autorelease bool
|
Autorelease bool
|
||||||
|
@ -233,7 +240,12 @@ func Start() (err error) {
|
||||||
}
|
}
|
||||||
cargs = append(cargs, Config.Inputfiles...)
|
cargs = append(cargs, Config.Inputfiles...)
|
||||||
fmt.Printf("Generating AST\n")
|
fmt.Printf("Generating AST\n")
|
||||||
astPP, err = exec.Command("clang", cargs...).Output()
|
clang := "clang"
|
||||||
|
if Config.Clang != "" {
|
||||||
|
clang = Config.Clang
|
||||||
|
}
|
||||||
|
fmt.Printf("%s %s\n", clang, strings.Join(cargs, " "))
|
||||||
|
astPP, err = exec.Command(clang, cargs...).Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If clang fails it still prints out the AST, so we have to run it
|
// If clang fails it still prints out the AST, so we have to run it
|
||||||
// again to get the real error.
|
// again to get the real error.
|
||||||
|
@ -281,12 +293,14 @@ func Start() (err error) {
|
||||||
w := wrap.NewWrapper(Debug)
|
w := wrap.NewWrapper(Debug)
|
||||||
w.Package = Config.Package
|
w.Package = Config.Package
|
||||||
w.Frameworks = Config.Frameworks
|
w.Frameworks = Config.Frameworks
|
||||||
|
w.Libraries = Config.Libraries
|
||||||
w.Frameworkdirs = Config.Frameworkdirs
|
w.Frameworkdirs = Config.Frameworkdirs
|
||||||
w.Import(Config.Imports)
|
w.Import(Config.Imports)
|
||||||
w.SysImport(Config.Sysimports)
|
w.SysImport(Config.Sysimports)
|
||||||
w.Pragmas = Config.Pragma
|
w.Pragmas = Config.Pragma
|
||||||
w.Delegate(Config.Delegates)
|
w.Delegate(Config.Delegates)
|
||||||
w.Subclass(Config.Subclasses)
|
w.Subclass(Config.Subclasses)
|
||||||
|
types.Typesubs = Config.Typesubs
|
||||||
if Config.Vaargs == 0 {
|
if Config.Vaargs == 0 {
|
||||||
Config.Vaargs = 16
|
Config.Vaargs = 16
|
||||||
}
|
}
|
||||||
|
@ -314,7 +328,8 @@ func Start() (err error) {
|
||||||
w.AddTypedef(x.Name, x.Type)
|
w.AddTypedef(x.Name, x.Type)
|
||||||
}
|
}
|
||||||
case *ast.FunctionDecl:
|
case *ast.FunctionDecl:
|
||||||
if matches(x.Name, Config.Functions) {
|
if matches(x.Name, Config.Functions) &&
|
||||||
|
!matches(x.Name, Config.FunctionIgnore) {
|
||||||
w.AddFunction(x)
|
w.AddFunction(x)
|
||||||
}
|
}
|
||||||
case *ast.ObjCProtocolDecl:
|
case *ast.ObjCProtocolDecl:
|
||||||
|
@ -341,9 +356,18 @@ func main() {
|
||||||
defer pprof.StopCPUProfile()
|
defer pprof.StopCPUProfile()
|
||||||
}
|
}
|
||||||
|
|
||||||
confbytes, err := ioutil.ReadFile("nswrap.yaml")
|
conffile := "nswrap.yaml"
|
||||||
|
if len(os.Args) > 1 {
|
||||||
|
conffile = os.Args[1]
|
||||||
|
}
|
||||||
|
confbytes, err := ioutil.ReadFile(conffile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("%s\n\nFATAL ERROR: Configuration file must be present in directory where nswrap\nis invoked.\n", err)
|
fmt.Printf("%s\n\nFATAL ERROR: Configuration file not found (default: nswrap.yaml)\n", err)
|
||||||
|
os.Exit(-1)
|
||||||
|
}
|
||||||
|
confbytes, err = envsubst.Bytes(confbytes)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("FATAL ERROR: Shell string variable substitution faled: %s\n", err)
|
||||||
os.Exit(-1)
|
os.Exit(-1)
|
||||||
}
|
}
|
||||||
if err = yaml.UnmarshalStrict(confbytes, &Config); err != nil {
|
if err = yaml.UnmarshalStrict(confbytes, &Config); err != nil {
|
||||||
|
|
|
@ -42,7 +42,7 @@ func ChildOf(ret *Node, p Parser) Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Children takes a parser returns a parser that adds the children of its
|
//Children takes a parser and returns a parser that adds the children of its
|
||||||
//output node to the tree. If multiple parsers are passed in, they are
|
//output node to the tree. If multiple parsers are passed in, they are
|
||||||
//passed to Seq(...)
|
//passed to Seq(...)
|
||||||
func Children(ps ...Parser) Parser {
|
func Children(ps ...Parser) Parser {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var Gogc bool
|
var Gogc bool
|
||||||
|
var Typesubs map[string]string
|
||||||
|
|
||||||
//super is a map recording which class is the parent of each other class
|
//super is a map recording which class is the parent of each other class
|
||||||
var super map[string]string
|
var super map[string]string
|
||||||
|
@ -201,25 +202,45 @@ func (t *Type) GoType() string {
|
||||||
return _goType(t.CType())
|
return _goType(t.CType())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func typeSub(gt string) string {
|
||||||
|
if Typesubs == nil {
|
||||||
|
return gt
|
||||||
|
}
|
||||||
|
i := 0
|
||||||
|
for ; i < len(gt); i++ {
|
||||||
|
if gt[i] != '*' {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gtp := gt[:i]
|
||||||
|
gte := gt[i:]
|
||||||
|
for k, v := range Typesubs {
|
||||||
|
if gte == k {
|
||||||
|
return gtp + v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gt
|
||||||
|
}
|
||||||
|
|
||||||
func _goType(ct string) string {
|
func _goType(ct string) string {
|
||||||
ct = strings.Title(ct)
|
ct = strings.Title(ct)
|
||||||
ct = strings.ReplaceAll(ct, " ", "")
|
ct = strings.ReplaceAll(ct, " ", "")
|
||||||
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
|
return typeSub(ct)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ct == "Id" {
|
if ct == "Id" {
|
||||||
ct = "*Id"
|
ct = "*Id"
|
||||||
}
|
}
|
||||||
if ShouldWrap(ct) {
|
if ShouldWrap(ct) {
|
||||||
return ct
|
return typeSub(ct)
|
||||||
}
|
}
|
||||||
if len(ct) > 4 && ct[len(ct)-4:len(ct)] == "Void" {
|
if len(ct) > 4 && ct[len(ct)-4:len(ct)] == "Void" {
|
||||||
ct = ct[:len(ct)-5] + "unsafe.Pointer"
|
ct = ct[:len(ct)-5] + "unsafe.Pointer"
|
||||||
}
|
}
|
||||||
return ct
|
return typeSub(ct)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Type) CType() string {
|
func (t *Type) CType() string {
|
||||||
|
@ -271,9 +292,15 @@ func (t *Type) GoTypeDecl(fin bool) string {
|
||||||
type %s = %s
|
type %s = %s
|
||||||
`, gt, tdgt)
|
`, gt, tdgt)
|
||||||
}
|
}
|
||||||
|
cgt := td.CGoType()
|
||||||
|
eq := ""
|
||||||
|
if len(cgt) > 9 && cgt[:9] == "C.struct_" {
|
||||||
|
//cgt = "C." + cgt[9:]
|
||||||
|
eq = "= "
|
||||||
|
}
|
||||||
return fmt.Sprintf(`
|
return fmt.Sprintf(`
|
||||||
type %s %s
|
type %s %s%s
|
||||||
`, gt, td.CGoType())
|
`, gt, eq, cgt)
|
||||||
}
|
}
|
||||||
if Debug {
|
if Debug {
|
||||||
fmt.Printf(" writing GoTypeDecl for %s\n", gt)
|
fmt.Printf(" writing GoTypeDecl for %s\n", gt)
|
||||||
|
@ -282,9 +309,15 @@ type %s %s
|
||||||
case "", "Void":
|
case "", "Void":
|
||||||
return ""
|
return ""
|
||||||
default:
|
default:
|
||||||
|
cgt := t.CGoType()
|
||||||
|
eq := ""
|
||||||
|
if len(cgt) > 9 && cgt[:9] == "C.struct_" {
|
||||||
|
//cgt = "C." + cgt[9:]
|
||||||
|
eq = "= "
|
||||||
|
}
|
||||||
return fmt.Sprintf(`
|
return fmt.Sprintf(`
|
||||||
type %s %s
|
type %s %s%s
|
||||||
`, gt, t.CGoType())
|
`, gt, eq, cgt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,7 +330,7 @@ func (t *Type) GoInterfaceDecl(fin bool) string {
|
||||||
if gt[0] == '*' {
|
if gt[0] == '*' {
|
||||||
gt = gt[1:] // dereference wrapped types
|
gt = gt[1:] // dereference wrapped types
|
||||||
ct = ct[:len(ct)-1]
|
ct = ct[:len(ct)-1]
|
||||||
fmt.Printf(" dereferenced %s\n",gt)
|
//fmt.Printf(" dereferenced %s\n", gt)
|
||||||
}
|
}
|
||||||
super := Super(ct)
|
super := Super(ct)
|
||||||
if super == "" {
|
if super == "" {
|
||||||
|
@ -384,7 +417,7 @@ func (t *Type) CToGo(cval string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call a C function from Go with a given return type and parameter types
|
// Call a C function from Go with a given return type and parameter types
|
||||||
func GoToC(sname, name string, pnames, snames []string, rtype *Type, ptypes []*Type, fun, fin bool, cm bool) string {
|
func GoToC(sname, name string, pnames, snames []string, rtype *Type, ptypes []*Type, fun, fin bool, cm bool, goImports map[string]bool) string {
|
||||||
if rtype == nil {
|
if rtype == nil {
|
||||||
//fmt.Println("nil sent to GoToC")
|
//fmt.Println("nil sent to GoToC")
|
||||||
return ""
|
return ""
|
||||||
|
@ -444,7 +477,11 @@ func GoToC(sname, name string, pnames, snames []string, rtype *Type, ptypes []*T
|
||||||
case TypedefShouldWrap(ptgt) && !pt.Variadic && !fun:
|
case TypedefShouldWrap(ptgt) && !pt.Variadic && !fun:
|
||||||
p = pn + ".Ptr()"
|
p = pn + ".Ptr()"
|
||||||
case snames[i] != "":
|
case snames[i] != "":
|
||||||
p = "(*unsafe.Pointer)(unsafe.Pointer(&" + snames[i] + "[0]))"
|
cast := pt.CGoType()
|
||||||
|
if len(ptgt) > 2 && ptgt[:1] == "*" && PtrShouldWrap(ptgt[1:]) {
|
||||||
|
cast = "*unsafe.Pointer"
|
||||||
|
}
|
||||||
|
p = fmt.Sprintf("(%s)(unsafe.Pointer(&%s[0]))", cast, snames[i])
|
||||||
case pt.Variadic:
|
case pt.Variadic:
|
||||||
p = "unsafe.Pointer(&" + p + ")"
|
p = "unsafe.Pointer(&" + p + ")"
|
||||||
case pt.IsPointer() && !fun:
|
case pt.IsPointer() && !fun:
|
||||||
|
@ -472,6 +509,9 @@ func GoToC(sname, name string, pnames, snames []string, rtype *Type, ptypes []*T
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
ptgt := ptypes[i].GoType()
|
ptgt := ptypes[i].GoType()
|
||||||
|
if !(len(ptgt) > 2 && ptgt[:1] == "*" && PtrShouldWrap(ptgt[1:])) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if len(ptgt) < 2 {
|
if len(ptgt) < 2 {
|
||||||
fmt.Printf("Error in function translation -- argument %s to %s should be pointer to pointer\n", pnames[i], name)
|
fmt.Printf("Error in function translation -- argument %s to %s should be pointer to pointer\n", pnames[i], name)
|
||||||
os.Exit(-1)
|
os.Exit(-1)
|
||||||
|
@ -482,6 +522,7 @@ func GoToC(sname, name string, pnames, snames []string, rtype *Type, ptypes []*T
|
||||||
}
|
}
|
||||||
dogc := ""
|
dogc := ""
|
||||||
if Gogc {
|
if Gogc {
|
||||||
|
goImports["runtime"] = true
|
||||||
dogc = fmt.Sprintf(`
|
dogc = fmt.Sprintf(`
|
||||||
runtime.SetFinalizer((*%s)[i], func(o *%s) {
|
runtime.SetFinalizer((*%s)[i], func(o *%s) {
|
||||||
o.Release()
|
o.Release()
|
||||||
|
@ -503,12 +544,17 @@ func GoToC(sname, name string, pnames, snames []string, rtype *Type, ptypes []*T
|
||||||
if rt != "void" {
|
if rt != "void" {
|
||||||
cmp := ""
|
cmp := ""
|
||||||
if sw {
|
if sw {
|
||||||
|
ka := ""
|
||||||
|
if !cm {
|
||||||
|
goImports["runtime"] = true
|
||||||
|
ka = "runtime.KeepAlive(o); "
|
||||||
|
}
|
||||||
if !cm && sname != "copy" && sname != "mutableCopy" {
|
if !cm && sname != "copy" && sname != "mutableCopy" {
|
||||||
cmp = fmt.Sprintf(`
|
cmp = fmt.Sprintf(`
|
||||||
if ret.ptr == o.ptr { return (%s)(unsafe.Pointer(o)) }`,rtgt)
|
if ret.ptr == o.ptr { %sreturn (%s)(unsafe.Pointer(o)) }`, ka, rtgt)
|
||||||
}
|
}
|
||||||
ret.WriteString(fmt.Sprintf(`
|
ret.WriteString(fmt.Sprintf(`
|
||||||
if ret.ptr == nil { return ret }%s`,cmp))
|
if ret.ptr == nil { %sreturn ret }%s`, ka, cmp))
|
||||||
}
|
}
|
||||||
if fin {
|
if fin {
|
||||||
dbg := ""
|
dbg := ""
|
||||||
|
@ -519,13 +565,25 @@ func GoToC(sname, name string, pnames, snames []string, rtype *Type, ptypes []*T
|
||||||
dbg2 = fmt.Sprintf(`fmt.Printf("Finalizer (%s): release %%p -> %%p\n", o, o.ptr)
|
dbg2 = fmt.Sprintf(`fmt.Printf("Finalizer (%s): release %%p -> %%p\n", o, o.ptr)
|
||||||
`, rtgt)
|
`, rtgt)
|
||||||
}
|
}
|
||||||
|
goImports["runtime"] = true
|
||||||
ret.WriteString(fmt.Sprintf(`
|
ret.WriteString(fmt.Sprintf(`
|
||||||
%sruntime.SetFinalizer(ret, func(o %s) {
|
%sruntime.SetFinalizer(ret, func(o %s) {
|
||||||
%so.Release()
|
%so.Release()
|
||||||
})`, dbg, rtgt, dbg2))
|
})`, dbg, rtgt, dbg2))
|
||||||
|
}
|
||||||
|
if !cm {
|
||||||
|
goImports["runtime"] = true
|
||||||
|
ret.WriteString(`
|
||||||
|
runtime.KeepAlive(o)`)
|
||||||
}
|
}
|
||||||
ret.WriteString(`
|
ret.WriteString(`
|
||||||
return ret`)
|
return ret`)
|
||||||
|
} else {
|
||||||
|
if !cm {
|
||||||
|
goImports["runtime"] = true
|
||||||
|
ret.WriteString(`
|
||||||
|
runtime.KeepAlive(o)`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ret.String()
|
return ret.String()
|
||||||
}
|
}
|
||||||
|
|
|
@ -272,40 +272,46 @@ func (o *Id) NSString() *NSString {
|
||||||
ptypes := []*Type{nsop, nstp, tint, voidpp}
|
ptypes := []*Type{nsop, nstp, tint, voidpp}
|
||||||
pnames := []string{"p1", "p2", "p3", "p4"}
|
pnames := []string{"p1", "p2", "p3", "p4"}
|
||||||
snames := []string{"", "", "", ""}
|
snames := []string{"", "", "", ""}
|
||||||
|
goImports := make(map[string]bool)
|
||||||
|
|
||||||
chk_gotoc := func(expected string) {
|
chk_gotoc := func(expected string) {
|
||||||
chk(GoToC("myFun", "myFun", pnames, snames, rtype, ptypes, false, false, false), expected)
|
chk(GoToC("myFun", "myFun", pnames, snames, rtype, ptypes, false, false, false, goImports), expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
chk_gotoc("")
|
chk_gotoc("")
|
||||||
|
|
||||||
rtype = void
|
rtype = void
|
||||||
chk_gotoc(`C.myFun(p1.Ptr(), p2.Ptr(), (C.int)(p3), unsafe.Pointer(p4))`)
|
chk_gotoc(`C.myFun(p1.Ptr(), p2.Ptr(), (C.int)(p3), unsafe.Pointer(p4))
|
||||||
|
runtime.KeepAlive(o)`)
|
||||||
|
|
||||||
rtype = bl
|
rtype = bl
|
||||||
chk_gotoc(
|
chk_gotoc(
|
||||||
`ret := (C.myFun(p1.Ptr(), p2.Ptr(), (C.int)(p3), unsafe.Pointer(p4))) != 0
|
`ret := (C.myFun(p1.Ptr(), p2.Ptr(), (C.int)(p3), unsafe.Pointer(p4))) != 0
|
||||||
|
runtime.KeepAlive(o)
|
||||||
return ret`)
|
return ret`)
|
||||||
|
|
||||||
rtype = voidpp
|
rtype = voidpp
|
||||||
chk_gotoc(
|
chk_gotoc(
|
||||||
`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))))
|
||||||
|
runtime.KeepAlive(o)
|
||||||
return ret`)
|
return ret`)
|
||||||
|
|
||||||
rtype = nstp
|
rtype = nstp
|
||||||
chk_gotoc(
|
chk_gotoc(
|
||||||
`ret := &NSString{}
|
`ret := &NSString{}
|
||||||
ret.ptr = unsafe.Pointer(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)))
|
||||||
if ret.ptr == nil { return ret }
|
if ret.ptr == nil { runtime.KeepAlive(o); return ret }
|
||||||
if ret.ptr == o.ptr { return (*NSString)(unsafe.Pointer(o)) }
|
if ret.ptr == o.ptr { runtime.KeepAlive(o); return (*NSString)(unsafe.Pointer(o)) }
|
||||||
|
runtime.KeepAlive(o)
|
||||||
return ret`)
|
return ret`)
|
||||||
|
|
||||||
rtype = nsop
|
rtype = nsop
|
||||||
chk_gotoc(
|
chk_gotoc(
|
||||||
`ret := &Id{}
|
`ret := &Id{}
|
||||||
ret.ptr = unsafe.Pointer(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)))
|
||||||
if ret.ptr == nil { return ret }
|
if ret.ptr == nil { runtime.KeepAlive(o); return ret }
|
||||||
if ret.ptr == o.ptr { return (*Id)(unsafe.Pointer(o)) }
|
if ret.ptr == o.ptr { runtime.KeepAlive(o); return (*Id)(unsafe.Pointer(o)) }
|
||||||
|
runtime.KeepAlive(o)
|
||||||
return ret`)
|
return ret`)
|
||||||
|
|
||||||
ptypes[1].Variadic = true
|
ptypes[1].Variadic = true
|
||||||
|
@ -313,8 +319,9 @@ func (o *Id) NSString() *NSString {
|
||||||
chk_gotoc(
|
chk_gotoc(
|
||||||
`ret := &Id{}
|
`ret := &Id{}
|
||||||
ret.ptr = unsafe.Pointer(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)))
|
||||||
if ret.ptr == nil { return ret }
|
if ret.ptr == nil { runtime.KeepAlive(o); return ret }
|
||||||
if ret.ptr == o.ptr { return (*Id)(unsafe.Pointer(o)) }
|
if ret.ptr == o.ptr { runtime.KeepAlive(o); return (*Id)(unsafe.Pointer(o)) }
|
||||||
|
runtime.KeepAlive(o)
|
||||||
return ret`)
|
return ret`)
|
||||||
|
|
||||||
ptypes[1].Variadic = false
|
ptypes[1].Variadic = false
|
||||||
|
@ -334,8 +341,9 @@ func (o *Id) NSString() *NSString {
|
||||||
}
|
}
|
||||||
(*p2)[i].ptr = p2p[i]
|
(*p2)[i].ptr = p2p[i]
|
||||||
}
|
}
|
||||||
if ret.ptr == nil { return ret }
|
if ret.ptr == nil { runtime.KeepAlive(o); return ret }
|
||||||
if ret.ptr == o.ptr { return (*Id)(unsafe.Pointer(o)) }
|
if ret.ptr == o.ptr { runtime.KeepAlive(o); return (*Id)(unsafe.Pointer(o)) }
|
||||||
|
runtime.KeepAlive(o)
|
||||||
return ret`)
|
return ret`)
|
||||||
snames[1] = ""
|
snames[1] = ""
|
||||||
snames[2] = "p3p"
|
snames[2] = "p3p"
|
||||||
|
@ -355,11 +363,12 @@ func (o *Id) NSString() *NSString {
|
||||||
}
|
}
|
||||||
(*p3)[i].ptr = p3p[i]
|
(*p3)[i].ptr = p3p[i]
|
||||||
}
|
}
|
||||||
if ret.ptr == nil { return ret }
|
if ret.ptr == nil { runtime.KeepAlive(o); return ret }
|
||||||
if ret.ptr == o.ptr { return (*Id)(unsafe.Pointer(o)) }
|
if ret.ptr == o.ptr { runtime.KeepAlive(o); return (*Id)(unsafe.Pointer(o)) }
|
||||||
|
runtime.KeepAlive(o)
|
||||||
return ret`)
|
return ret`)
|
||||||
|
|
||||||
chk(GoToC("myFun", "myFun", pnames, snames, rtype, ptypes, true, false, false),
|
chk(GoToC("myFun", "myFun", pnames, snames, rtype, ptypes, true, false, false, goImports),
|
||||||
`ret := &Id{}
|
`ret := &Id{}
|
||||||
ret.ptr = unsafe.Pointer(C.myFun(p1.Ptr(), p2.Ptr(), (*unsafe.Pointer)(unsafe.Pointer(&p3p[0])), p4))
|
ret.ptr = unsafe.Pointer(C.myFun(p1.Ptr(), p2.Ptr(), (*unsafe.Pointer)(unsafe.Pointer(&p3p[0])), p4))
|
||||||
(*p3) = (*p3)[:cap(*p3)]
|
(*p3) = (*p3)[:cap(*p3)]
|
||||||
|
@ -373,7 +382,8 @@ func (o *Id) NSString() *NSString {
|
||||||
}
|
}
|
||||||
(*p3)[i].ptr = p3p[i]
|
(*p3)[i].ptr = p3p[i]
|
||||||
}
|
}
|
||||||
if ret.ptr == nil { return ret }
|
if ret.ptr == nil { runtime.KeepAlive(o); return ret }
|
||||||
if ret.ptr == o.ptr { return (*Id)(unsafe.Pointer(o)) }
|
if ret.ptr == o.ptr { runtime.KeepAlive(o); return (*Id)(unsafe.Pointer(o)) }
|
||||||
|
runtime.KeepAlive(o)
|
||||||
return ret`)
|
return ret`)
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,11 +112,27 @@ func ArrayDeclarator(s string, n *Node) (string, *Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func FunctionDeclarator(s string, n *Node) (string, *Node) {
|
func FunctionDeclarator(s string, n *Node) (string, *Node) {
|
||||||
return ChildOf(NewNode("Function"),
|
return ChildOf(NewNode("Function"), Seq(
|
||||||
Parenthesized(Opt(ParameterList)),
|
Parenthesized(Opt(ParameterList)),
|
||||||
|
ZeroOrMore(Attribute),
|
||||||
|
))(s, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Attribute(s string, n *Node) (string, *Node) {
|
||||||
|
return Seq(
|
||||||
|
Word("__attribute__"),
|
||||||
|
ChildOf(NewNode("parens"), Parenthesized(Parenthesized(
|
||||||
|
Attr,
|
||||||
|
))),
|
||||||
)(s, n)
|
)(s, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Attr(s string, n *Node) (string, *Node) {
|
||||||
|
return NodeNamed("Attribute", OneOf(
|
||||||
|
Word("noreturn"),
|
||||||
|
))(s, n)
|
||||||
|
}
|
||||||
|
|
||||||
func DirectAbstractDeclarator(s string, n *Node) (string, *Node) {
|
func DirectAbstractDeclarator(s string, n *Node) (string, *Node) {
|
||||||
return OneOf(
|
return OneOf(
|
||||||
ParenAbstractDeclarator,
|
ParenAbstractDeclarator,
|
||||||
|
|
306
wrap/main.go
306
wrap/main.go
|
@ -32,6 +32,7 @@ type Wrapper struct {
|
||||||
Subclasses map[string]*Subclass
|
Subclasses map[string]*Subclass
|
||||||
Protocols map[string]*Protocol
|
Protocols map[string]*Protocol
|
||||||
Frameworks []string
|
Frameworks []string
|
||||||
|
Libraries []string
|
||||||
Frameworkdirs []string
|
Frameworkdirs []string
|
||||||
Pragmas []string
|
Pragmas []string
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ type Wrapper struct {
|
||||||
|
|
||||||
func NewWrapper(debug bool) *Wrapper {
|
func NewWrapper(debug bool) *Wrapper {
|
||||||
Debug = debug
|
Debug = debug
|
||||||
types.Debug = Debug
|
//types.Debug = Debug
|
||||||
if Debug {
|
if Debug {
|
||||||
fmt.Println("// Debug mode")
|
fmt.Println("// Debug mode")
|
||||||
}
|
}
|
||||||
|
@ -82,15 +83,23 @@ func (o *Id) Ptr() unsafe.Pointer { if o == nil { return nil }; return o.ptr }
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Wrapper) Import(ss []string) {
|
func (w *Wrapper) Import(ss []string) {
|
||||||
|
if len(ss) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
for _, s := range ss {
|
for _, s := range ss {
|
||||||
w.cImports.WriteString("\n#import \"" + s + "\"\n")
|
w.cImports.WriteString("\n#import \"" + s + "\"\n")
|
||||||
}
|
}
|
||||||
|
w.cImports.WriteString("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Wrapper) SysImport(ss []string) {
|
func (w *Wrapper) SysImport(ss []string) {
|
||||||
|
if len(ss) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
for _, s := range ss {
|
for _, s := range ss {
|
||||||
w.cImports.WriteString("\n#import <" + s + ">\n")
|
w.cImports.WriteString("\n#import <" + s + ">\n")
|
||||||
}
|
}
|
||||||
|
w.cImports.WriteString("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Wrapper) Delegate(ds map[string]map[string][]string) {
|
func (w *Wrapper) Delegate(ds map[string]map[string][]string) {
|
||||||
|
@ -103,11 +112,11 @@ func (w *Wrapper) Subclass(ds map[string]map[string][]string) {
|
||||||
Overrides: []string{},
|
Overrides: []string{},
|
||||||
NewMethods: []string{},
|
NewMethods: []string{},
|
||||||
}
|
}
|
||||||
if len(ds) == 0 {
|
if len(v) == 0 {
|
||||||
fmt.Printf("No superclass specified for subclass %s\n", k)
|
fmt.Printf("No superclass specified for subclass %s\n", k)
|
||||||
os.Exit(-1)
|
os.Exit(-1)
|
||||||
}
|
}
|
||||||
if len(ds) > 1 {
|
if len(v) > 1 {
|
||||||
fmt.Printf("Multiple inheritance not permitted for subclass %s\n", k)
|
fmt.Printf("Multiple inheritance not permitted for subclass %s\n", k)
|
||||||
os.Exit(-1)
|
os.Exit(-1)
|
||||||
}
|
}
|
||||||
|
@ -165,8 +174,7 @@ func (m *Method) ShouldFinalize() bool {
|
||||||
// NSWrap will not send a 'retain' message to these objects before returning
|
// NSWrap will not send a 'retain' message to these objects before returning
|
||||||
// them to Go.
|
// them to Go.
|
||||||
func IsRetained(name string) bool {
|
func IsRetained(name string) bool {
|
||||||
return (
|
return ((len(name) >= 3 && name[:3] == "new") ||
|
||||||
(len(name) >= 3 && name[:3] == "new") ||
|
|
||||||
(len(name) >= 4 && name[:4] == "init") ||
|
(len(name) >= 4 && name[:4] == "init") ||
|
||||||
(len(name) >= 4 && name[:4] == "copy") ||
|
(len(name) >= 4 && name[:4] == "copy") ||
|
||||||
(len(name) >= 5 && name[:5] == "alloc") ||
|
(len(name) >= 5 && name[:5] == "alloc") ||
|
||||||
|
@ -195,7 +203,6 @@ func (i *Interface) IsRetainedProperty(name string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Fully disambiguated method name (m.GoName + all parameter names)
|
//Fully disambiguated method name (m.GoName + all parameter names)
|
||||||
func (m *Method) LongName() string {
|
func (m *Method) LongName() string {
|
||||||
ret := m.GoName
|
ret := m.GoName
|
||||||
|
@ -208,13 +215,19 @@ func (m *Method) LongName() string {
|
||||||
func (m *Method) HasUnsupportedType() bool {
|
func (m *Method) HasUnsupportedType() bool {
|
||||||
return m.Type.IsFunction() ||
|
return m.Type.IsFunction() ||
|
||||||
m.Type.IsFunctionPtr() ||
|
m.Type.IsFunctionPtr() ||
|
||||||
|
m.Type.CGoType() == "C.longdouble" ||
|
||||||
m.hasUnsupportedParam()
|
m.hasUnsupportedParam()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EnumConstant struct {
|
||||||
|
name string
|
||||||
|
tp *types.Type
|
||||||
|
}
|
||||||
|
|
||||||
type Enum struct {
|
type Enum struct {
|
||||||
Name string
|
Name string
|
||||||
Type *types.Type
|
Type *types.Type
|
||||||
Constants []string
|
Constants []EnumConstant
|
||||||
}
|
}
|
||||||
|
|
||||||
type Protocol struct {
|
type Protocol struct {
|
||||||
|
@ -291,6 +304,9 @@ func (m Method) hasUnsupportedParam() bool {
|
||||||
if pt := p.Type.PointsTo(); pt.IsValist() {
|
if pt := p.Type.PointsTo(); pt.IsValist() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
if p.Type.CGoType() == "C.longdouble" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -309,6 +325,8 @@ func (w Wrapper) cparamlist(m *Method) (string, string, string) {
|
||||||
switch {
|
switch {
|
||||||
case len(gt) > 2 && gt[:1] == "*" && types.PtrShouldWrap(gt[1:]):
|
case len(gt) > 2 && gt[:1] == "*" && types.PtrShouldWrap(gt[1:]):
|
||||||
tp = "void**"
|
tp = "void**"
|
||||||
|
case len(gt) > 3 && gt[:2] == "**":
|
||||||
|
tp = p.Type.CType()
|
||||||
case wp || p.Type.IsPointer() || p.Type.Variadic:
|
case wp || p.Type.IsPointer() || p.Type.Variadic:
|
||||||
tp = "void*"
|
tp = "void*"
|
||||||
default:
|
default:
|
||||||
|
@ -403,6 +421,7 @@ func (w *Wrapper) gpntp(m *Method) ([]string, []string, []string, []*types.Type,
|
||||||
ns[i] = ns[i] + "s"
|
ns[i] = ns[i] + "s"
|
||||||
}
|
}
|
||||||
if len(gt) > 2 && gt[:1] == "*" && types.PtrShouldWrap(gt[1:]) {
|
if len(gt) > 2 && gt[:1] == "*" && types.PtrShouldWrap(gt[1:]) {
|
||||||
|
|
||||||
x := gt[1:]
|
x := gt[1:]
|
||||||
if types.PtrIsGoInterface(x) {
|
if types.PtrIsGoInterface(x) {
|
||||||
x = "*Id"
|
x = "*Id"
|
||||||
|
@ -410,6 +429,10 @@ func (w *Wrapper) gpntp(m *Method) ([]string, []string, []string, []*types.Type,
|
||||||
gt = "*[]" + x
|
gt = "*[]" + x
|
||||||
snames[i] = "goSlice" + strconv.Itoa(i)
|
snames[i] = "goSlice" + strconv.Itoa(i)
|
||||||
}
|
}
|
||||||
|
if len(gt) > 3 && gt[:2] == "**" {
|
||||||
|
gt = "[]" + gt[1:]
|
||||||
|
snames[i] = ns[i]
|
||||||
|
}
|
||||||
ret = append(ret, ns[i]+" "+gt)
|
ret = append(ret, ns[i]+" "+gt)
|
||||||
}
|
}
|
||||||
return ns, pnames, snames, tps, strings.Join(ret, ", ")
|
return ns, pnames, snames, tps, strings.Join(ret, ", ")
|
||||||
|
@ -428,7 +451,6 @@ func (w *Wrapper) AddInterface(n *ast.ObjCInterfaceDecl) {
|
||||||
if Debug {
|
if Debug {
|
||||||
fmt.Printf("ast.ObjCInterfaceDecl: %s\n", n.Name)
|
fmt.Printf("ast.ObjCInterfaceDecl: %s\n", n.Name)
|
||||||
}
|
}
|
||||||
//fmt.Printf("AddInterface(%s)\n",n.Name)
|
|
||||||
w.addIntCat(n.Name, n.Children())
|
w.addIntCat(n.Name, n.Children())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,9 +490,13 @@ func (w *Wrapper) AddFunction(n *ast.FunctionDecl) {
|
||||||
fmt.Printf("FunctionDecl: %s (%s) %s\n", n.Type, m.Type.CType(), n.Name)
|
fmt.Printf("FunctionDecl: %s (%s) %s\n", n.Type, m.Type.CType(), n.Name)
|
||||||
}
|
}
|
||||||
i := 0
|
i := 0
|
||||||
|
a := (*Avail)(&[]AvailAttr{})
|
||||||
for _, c := range n.Children() {
|
for _, c := range n.Children() {
|
||||||
switch x := c.(type) {
|
switch x := c.(type) {
|
||||||
case *ast.ParmVarDecl:
|
case *ast.ParmVarDecl:
|
||||||
|
if x.Type == "va_list" {
|
||||||
|
return // skip functions taking a va_list
|
||||||
|
}
|
||||||
p := &Parameter{
|
p := &Parameter{
|
||||||
Vname: x.Name,
|
Vname: x.Name,
|
||||||
Type: types.NewTypeFromString(x.Type, ""),
|
Type: types.NewTypeFromString(x.Type, ""),
|
||||||
|
@ -480,6 +506,8 @@ func (w *Wrapper) AddFunction(n *ast.FunctionDecl) {
|
||||||
if Debug {
|
if Debug {
|
||||||
fmt.Printf(" %s\n", p.Type.CType())
|
fmt.Printf(" %s\n", p.Type.CType())
|
||||||
}
|
}
|
||||||
|
case *ast.FormatAttr:
|
||||||
|
return // skip C variadic functions
|
||||||
case *ast.Variadic:
|
case *ast.Variadic:
|
||||||
p := &Parameter{
|
p := &Parameter{
|
||||||
Vname: "object",
|
Vname: "object",
|
||||||
|
@ -488,10 +516,14 @@ func (w *Wrapper) AddFunction(n *ast.FunctionDecl) {
|
||||||
p.Type.Variadic = true
|
p.Type.Variadic = true
|
||||||
m.Parameters = append(m.Parameters, p)
|
m.Parameters = append(m.Parameters, p)
|
||||||
i++
|
i++
|
||||||
|
case *ast.AvailabilityAttr, *ast.UnavailableAttr, *ast.DeprecatedAttr:
|
||||||
|
a.Add(x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if a.Available() {
|
||||||
w.Functions[n.Name] = m
|
w.Functions[n.Name] = m
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Wrapper) AddProtocol(n *ast.ObjCProtocolDecl) {
|
func (w *Wrapper) AddProtocol(n *ast.ObjCProtocolDecl) {
|
||||||
p := w.Protocols[n.Name]
|
p := w.Protocols[n.Name]
|
||||||
|
@ -585,7 +617,7 @@ func (w *Wrapper) AddEnum(n *ast.EnumDecl, rs []string) {
|
||||||
e := &Enum{
|
e := &Enum{
|
||||||
Name: n.Name, // NOTE: may be empty string
|
Name: n.Name, // NOTE: may be empty string
|
||||||
Type: tp,
|
Type: tp,
|
||||||
Constants: []string{},
|
Constants: []EnumConstant{},
|
||||||
}
|
}
|
||||||
for _, c := range n.Children() {
|
for _, c := range n.Children() {
|
||||||
switch x := c.(type) {
|
switch x := c.(type) {
|
||||||
|
@ -598,7 +630,9 @@ func (w *Wrapper) AddEnum(n *ast.EnumDecl, rs []string) {
|
||||||
if n.Name == "" && !matches(x.Name, rs) {
|
if n.Name == "" && !matches(x.Name, rs) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
e.Constants = append(e.Constants, x.Name)
|
tp := types.NewTypeFromString(x.Type, "")
|
||||||
|
e.Constants = append(e.Constants,
|
||||||
|
EnumConstant{name: x.Name, tp: tp})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if a.Available() && len(e.Constants) > 0 {
|
if a.Available() && len(e.Constants) > 0 {
|
||||||
|
@ -818,7 +852,7 @@ func (w *Wrapper) AddTypedef(n, t string) {
|
||||||
w._processType(tp)
|
w._processType(tp)
|
||||||
} else {
|
} else {
|
||||||
cgt := tp.CGoType()
|
cgt := tp.CGoType()
|
||||||
if Debug {
|
if Debug && false {
|
||||||
fmt.Printf(" processing un-wrapped type for %s -> %s\n", n, cgt)
|
fmt.Printf(" processing un-wrapped type for %s -> %s\n", n, cgt)
|
||||||
}
|
}
|
||||||
types.AddTypedef(n, tp)
|
types.AddTypedef(n, tp)
|
||||||
|
@ -846,15 +880,22 @@ func (w *Wrapper) _processType(bt *types.Type) {
|
||||||
if gt == "" {
|
if gt == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if gt == "LongDouble" { // not supported by cgo
|
||||||
|
return
|
||||||
|
}
|
||||||
if gt[0] == '*' {
|
if gt[0] == '*' {
|
||||||
w.processType(bt.PointsTo())
|
w.processType(bt.PointsTo())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if w.ProcessedTypes[gt] {
|
if w.ProcessedTypes[gt] {
|
||||||
if Debug { fmt.Printf(" -- already seen\n") }
|
if Debug {
|
||||||
|
fmt.Printf(" -- already seen\n")
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if Debug { fmt.Printf(" -- not yet seen\n") }
|
if Debug {
|
||||||
|
fmt.Printf(" -- not yet seen\n")
|
||||||
|
}
|
||||||
w.ProcessedTypes[gt] = true
|
w.ProcessedTypes[gt] = true
|
||||||
if gt == "Char" {
|
if gt == "Char" {
|
||||||
w.CharHelpers()
|
w.CharHelpers()
|
||||||
|
@ -903,7 +944,8 @@ func (c *Char) Free() {
|
||||||
func (w *Wrapper) StringHelpers() {
|
func (w *Wrapper) StringHelpers() {
|
||||||
ufree := ""
|
ufree := ""
|
||||||
if Gogc {
|
if Gogc {
|
||||||
ufree = "utf8.Free()\n\t"
|
w.goImports["runtime"] = true
|
||||||
|
ufree = "utf8.Free()\n\truntime.KeepAlive(o)\n\t"
|
||||||
}
|
}
|
||||||
w.goHelpers.WriteString(fmt.Sprintf(`
|
w.goHelpers.WriteString(fmt.Sprintf(`
|
||||||
func (o *NSString) String() string {
|
func (o *NSString) String() string {
|
||||||
|
@ -1098,17 +1140,28 @@ func %s%s(%s) %s {
|
||||||
vn := ns[lparm]
|
vn := ns[lparm]
|
||||||
vn = vn[:len(vn)-1]
|
vn = vn[:len(vn)-1]
|
||||||
ns[lparm] = vn
|
ns[lparm] = vn
|
||||||
|
dotptr := ""
|
||||||
|
if !fun {
|
||||||
|
dotptr = ".Ptr()"
|
||||||
|
}
|
||||||
w.goCode.WriteString(fmt.Sprintf(
|
w.goCode.WriteString(fmt.Sprintf(
|
||||||
` var %s [%d]unsafe.Pointer
|
` var %s [%d]unsafe.Pointer
|
||||||
for i,o := range %ss {
|
for i,o := range %ss {
|
||||||
%s[i] = o.Ptr()
|
%s[i] = o%s
|
||||||
|
}
|
||||||
|
`, vn, w.Vaargs, vn, vn, dotptr))
|
||||||
|
if fun {
|
||||||
|
cname = "_" + cname
|
||||||
}
|
}
|
||||||
`, vn, w.Vaargs, vn, vn))
|
|
||||||
}
|
}
|
||||||
for i, n := range ns {
|
for i, n := range ns {
|
||||||
if snames[i] == "" {
|
if snames[i] == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
gt := tps[i].GoType()
|
||||||
|
if !(len(gt) > 2 && gt[:1] == "*" && types.PtrShouldWrap(gt[1:])) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
w.goCode.WriteString(fmt.Sprintf(`
|
w.goCode.WriteString(fmt.Sprintf(`
|
||||||
%s := make([]unsafe.Pointer,cap(*%s))
|
%s := make([]unsafe.Pointer,cap(*%s))
|
||||||
for i := 0; i < len(*%s); i++ {
|
for i := 0; i < len(*%s); i++ {
|
||||||
|
@ -1117,7 +1170,7 @@ func %s%s(%s) %s {
|
||||||
`, snames[i], n, n, snames[i], n))
|
`, snames[i], n, n, snames[i], n))
|
||||||
}
|
}
|
||||||
w.goCode.WriteString(` ` +
|
w.goCode.WriteString(` ` +
|
||||||
types.GoToC(m.Name, cname, ns, snames, m.Type, tps, fun, constructor || m.ShouldFinalize(), m.ClassMethod) + "\n}\n")
|
types.GoToC(m.Name, cname, ns, snames, m.Type, tps, fun, constructor || m.ShouldFinalize(), m.ClassMethod, w.goImports) + "\n}\n")
|
||||||
|
|
||||||
cret := ""
|
cret := ""
|
||||||
if !m.isVoid() {
|
if !m.isVoid() {
|
||||||
|
@ -1131,22 +1184,24 @@ func %s%s(%s) %s {
|
||||||
}
|
}
|
||||||
cns, cntps, _ := w.cparamlist(m)
|
cns, cntps, _ := w.cparamlist(m)
|
||||||
if fun {
|
if fun {
|
||||||
return
|
// return
|
||||||
}
|
}
|
||||||
|
if !fun || len(tps) > 0 && tps[lparm].Variadic {
|
||||||
w.cCode.WriteString(fmt.Sprintf(`
|
w.cCode.WriteString(fmt.Sprintf(`
|
||||||
%s
|
%s
|
||||||
%s(%s) {
|
%s(%s) {
|
||||||
`, cmtype, cname, cntps))
|
`, cmtype, cname, cntps))
|
||||||
|
}
|
||||||
if len(tps) > 0 && tps[lparm].Variadic {
|
if len(tps) > 0 && tps[lparm].Variadic {
|
||||||
w.cCode.WriteString(fmt.Sprintf(
|
w.cCode.WriteString(fmt.Sprintf(
|
||||||
` %s* arr = %s;
|
` %s* arr = %s;
|
||||||
`, tps[lparm].CType(), ns[lparm]))
|
`, tps[lparm].CType(), ns[lparm]))
|
||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
case fun:
|
case fun && len(tps) > 0 && tps[lparm].Variadic:
|
||||||
w.cCode.WriteString(fmt.Sprintf(` %s%s(%s);
|
w.cCode.WriteString(fmt.Sprintf(` %s%s(%s);
|
||||||
}`, cret, m.Name, cns))
|
}`, cret, m.Name, cns))
|
||||||
case len(m.Name) >= 5 && m.Name[:5] == "alloc" && m.Class != "NSAutoreleasePool":
|
case !fun && len(m.Name) >= 5 && m.Name[:5] == "alloc" && m.Class != "NSAutoreleasePool":
|
||||||
if Autorelease {
|
if Autorelease {
|
||||||
w.cCode.WriteString(fmt.Sprintf(` %s[[%s %s] autorelease];
|
w.cCode.WriteString(fmt.Sprintf(` %s[[%s %s] autorelease];
|
||||||
}`, cret, cobj, w.objcparamlist(m)))
|
}`, cret, cobj, w.objcparamlist(m)))
|
||||||
|
@ -1154,7 +1209,7 @@ func %s%s(%s) %s {
|
||||||
w.cCode.WriteString(fmt.Sprintf(` %s[%s %s];
|
w.cCode.WriteString(fmt.Sprintf(` %s[%s %s];
|
||||||
}`, cret, cobj, w.objcparamlist(m)))
|
}`, cret, cobj, w.objcparamlist(m)))
|
||||||
}
|
}
|
||||||
default:
|
case !fun:
|
||||||
//if Gogc && !m.isVoid() {
|
//if Gogc && !m.isVoid() {
|
||||||
if Gogc {
|
if Gogc {
|
||||||
rtn := ""
|
rtn := ""
|
||||||
|
@ -1243,6 +1298,7 @@ func (o *%s) GC() {
|
||||||
%sruntime.SetFinalizer(o, func(o *%s) {
|
%sruntime.SetFinalizer(o, func(o *%s) {
|
||||||
%so.Release()
|
%so.Release()
|
||||||
})
|
})
|
||||||
|
runtime.KeepAlive(o)
|
||||||
}
|
}
|
||||||
`, cls, dbg, cls, dbg2))
|
`, cls, dbg, cls, dbg2))
|
||||||
}
|
}
|
||||||
|
@ -1300,14 +1356,10 @@ func (w *Wrapper) ProcessEnum(e *Enum) {
|
||||||
}
|
}
|
||||||
w.processType(e.Type)
|
w.processType(e.Type)
|
||||||
gtp := ""
|
gtp := ""
|
||||||
ctp := ""
|
if e.Type != nil {
|
||||||
if e.Name != "" {
|
|
||||||
gtp = e.Name
|
|
||||||
ctp = "C." + e.Name
|
|
||||||
} else {
|
|
||||||
gtp = e.Type.GoType()
|
gtp = e.Type.GoType()
|
||||||
ctp = e.Type.CGoType()
|
|
||||||
}
|
}
|
||||||
|
ctp := e.Type.CGoType()
|
||||||
if e.Type != nil {
|
if e.Type != nil {
|
||||||
if !w.ProcessedTypes[gtp] {
|
if !w.ProcessedTypes[gtp] {
|
||||||
w.goTypes.WriteString(fmt.Sprintf(`
|
w.goTypes.WriteString(fmt.Sprintf(`
|
||||||
|
@ -1316,13 +1368,12 @@ type %s %s
|
||||||
w.ProcessedTypes[gtp] = true
|
w.ProcessedTypes[gtp] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gtp = gtp + " "
|
|
||||||
if Debug {
|
if Debug {
|
||||||
fmt.Printf(" gtp = %s; ctp = %s\n", gtp, ctp)
|
fmt.Printf(" gtp = %s; ctp = %s\n", gtp, ctp)
|
||||||
}
|
}
|
||||||
for _, c := range e.Constants {
|
for _, c := range e.Constants {
|
||||||
w.goConst.WriteString(fmt.Sprintf(`const %s %s= C.%s
|
w.goConst.WriteString(fmt.Sprintf(`const %s %s= C.%s
|
||||||
`, c, gtp, c))
|
`, c.name, gtp, c.name))
|
||||||
}
|
}
|
||||||
w.goConst.WriteString("\n")
|
w.goConst.WriteString("\n")
|
||||||
}
|
}
|
||||||
|
@ -1337,6 +1388,7 @@ func (w *Wrapper) MethodFromSig(sig, class string) *Method {
|
||||||
}
|
}
|
||||||
sig = sig[1:]
|
sig = sig[1:]
|
||||||
rem, n := types.MethodSignature(sig, types.NewNode("AST"))
|
rem, n := types.MethodSignature(sig, types.NewNode("AST"))
|
||||||
|
fmt.Println(n.String())
|
||||||
if len(rem) > 0 {
|
if len(rem) > 0 {
|
||||||
fmt.Printf("Failed to parse method signature %s (%s)\n", sig, rem)
|
fmt.Printf("Failed to parse method signature %s (%s)\n", sig, rem)
|
||||||
os.Exit(-1)
|
os.Exit(-1)
|
||||||
|
@ -1439,8 +1491,6 @@ func (w *Wrapper) _ProcessDelSub(dname string, ps map[string][]string, nms []*Me
|
||||||
//4. Go type
|
//4. Go type
|
||||||
//5. Go constructor
|
//5. Go constructor
|
||||||
//6. Go dispatch database for callbacks
|
//6. Go dispatch database for callbacks
|
||||||
//7. Go superclass dispatch function
|
|
||||||
//8. Methods inherited from parent class
|
|
||||||
//To create (per method):
|
//To create (per method):
|
||||||
//1. ObjC function prototypes for go exports
|
//1. ObjC function prototypes for go exports
|
||||||
//2. Go callback registration functions
|
//2. Go callback registration functions
|
||||||
|
@ -1450,7 +1500,7 @@ func (w *Wrapper) _ProcessDelSub(dname string, ps map[string][]string, nms []*Me
|
||||||
//organize output into string builders
|
//organize output into string builders
|
||||||
var cprotos, ccode, gotypes, gocode, goexports strings.Builder
|
var cprotos, ccode, gotypes, gocode, goexports strings.Builder
|
||||||
|
|
||||||
//set up array of methods for this delegate
|
//set up array of methods for this delegate or subclass
|
||||||
methods := []*Method{}
|
methods := []*Method{}
|
||||||
sms := 0 // the number of methods that have super-methods
|
sms := 0 // the number of methods that have super-methods
|
||||||
gnames := []string{} // go names for methods
|
gnames := []string{} // go names for methods
|
||||||
|
@ -1473,41 +1523,54 @@ func (w *Wrapper) _ProcessDelSub(dname string, ps map[string][]string, nms []*Me
|
||||||
fmt.Printf("Failed to find interface %s for subclass %s\n", pname, dname)
|
fmt.Printf("Failed to find interface %s for subclass %s\n", pname, dname)
|
||||||
os.Exit(-1)
|
os.Exit(-1)
|
||||||
}
|
}
|
||||||
if Debug {
|
//if Debug {
|
||||||
fmt.Printf(" subclass for %s\n", pname)
|
fmt.Printf(" subclass for %s\n", pname)
|
||||||
}
|
//}
|
||||||
mc := NewMethodCollection(dname)
|
mc := NewMethodCollection(dname)
|
||||||
var addmeths func(s string)
|
var addmeths func(s string)
|
||||||
addmeths = func(s string) {
|
addmeths = func(s string) {
|
||||||
if sup := types.Super(s); w.Interfaces[sup] != nil {
|
if sup := types.Super(s); w.Interfaces[sup] != nil {
|
||||||
addmeths(sup)
|
addmeths(sup)
|
||||||
}
|
}
|
||||||
if Debug {
|
//if Debug {
|
||||||
fmt.Printf("Adding methods for interface %s\n", s)
|
fmt.Printf("Adding methods for interface %s\n", s)
|
||||||
}
|
//}
|
||||||
for _, m := range w.Interfaces[s].InstanceMethods.Methods {
|
for _, m := range w.Interfaces[s].InstanceMethods.Methods {
|
||||||
|
if m.Unavailable {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if Debug {
|
if Debug {
|
||||||
fmt.Printf(" -> %s\n", m.Name)
|
fmt.Printf(" -> %s\n", m.Name)
|
||||||
}
|
}
|
||||||
|
if matches(string(m.Name[0])+m.GoName[1:], pats) {
|
||||||
mc.Methods = append(mc.Methods, m)
|
mc.Methods = append(mc.Methods, m)
|
||||||
}
|
}
|
||||||
//mc.Methods = append(mc.Methods,w.Interfaces[s].InstanceMethods...)
|
}
|
||||||
for _, p := range w.Interfaces[s].Protocols {
|
for _, p := range w.Interfaces[s].Protocols {
|
||||||
if Debug {
|
if Debug {
|
||||||
fmt.Printf("Adding methods for protocol %s\n", p)
|
fmt.Printf("Adding methods for protocol %s\n", p)
|
||||||
}
|
}
|
||||||
for _, m := range w.Protocols[p].InstanceMethods.Methods {
|
for _, m := range w.Protocols[p].InstanceMethods.Methods {
|
||||||
|
if m.Unavailable {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if Debug {
|
if Debug {
|
||||||
fmt.Printf(" -> %s\n", m.Name)
|
fmt.Printf(" -> %s\n", m.Name)
|
||||||
}
|
}
|
||||||
|
if matches(string(m.Name[0])+m.GoName[1:], pats) {
|
||||||
mc.Methods = append(mc.Methods, m)
|
mc.Methods = append(mc.Methods, m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//for subclasses, add all superclass methods, depth first
|
//for subclasses, add all superclass methods, depth first
|
||||||
addmeths(interf.Name)
|
addmeths(interf.Name)
|
||||||
Disambiguate(mc)
|
Disambiguate(mc)
|
||||||
ms = mc.Methods
|
ms = mc.Methods
|
||||||
|
fmt.Printf("METHODS:\n")
|
||||||
|
for _, m := range ms {
|
||||||
|
fmt.Printf(" -> %s\n", m.Name)
|
||||||
|
}
|
||||||
} else { // not a subclass
|
} else { // not a subclass
|
||||||
proto := w.Protocols[pname]
|
proto := w.Protocols[pname]
|
||||||
if proto == nil {
|
if proto == nil {
|
||||||
|
@ -1526,30 +1589,40 @@ func (w *Wrapper) _ProcessDelSub(dname string, ps map[string][]string, nms []*Me
|
||||||
}
|
}
|
||||||
for _, m := range ms {
|
for _, m := range ms {
|
||||||
//note:we may have capitalized the first character to make a GoName...
|
//note:we may have capitalized the first character to make a GoName...
|
||||||
|
if m.HasUnsupportedType() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if Debug {
|
if Debug {
|
||||||
fmt.Printf("--Method: %s\n", m.Name)
|
fmt.Printf("--Method: %s\n", m.Name)
|
||||||
}
|
}
|
||||||
if !matches(string(m.Name[0])+m.GoName[1:], pats) {
|
if sub || !matches(string(m.Name[0])+m.GoName[1:], pats) {
|
||||||
//methods from superclass that we are not overriding
|
//methods from superclass that we are not overriding
|
||||||
supmeths = append(supmeths, m)
|
supmeths = append(supmeths, m)
|
||||||
|
if !sub {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if m.HasUnsupportedType() {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
methods = append(methods, m)
|
methods = append(methods, m)
|
||||||
gnames = append(gnames, m.GoName)
|
gnames = append(gnames, m.GoName)
|
||||||
if sub {
|
if sub {
|
||||||
sms = len(methods)
|
sms = len(methods)
|
||||||
|
if Debug {
|
||||||
|
fmt.Printf("sms = %d\n", sms)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//add new methods being defined for the subclass
|
//add new methods being defined for the subclass
|
||||||
if sub {
|
if sub {
|
||||||
for _, m := range nms {
|
for _, m := range nms {
|
||||||
|
//if Debug {
|
||||||
|
fmt.Printf("Adding method %s to subclass\n", m.Name)
|
||||||
|
//}
|
||||||
methods = append(methods, m)
|
methods = append(methods, m)
|
||||||
gnames = append(gnames, strings.Title(m.Name))
|
gnames = append(gnames, strings.Title(m.Name))
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
nms = methods
|
||||||
}
|
}
|
||||||
|
|
||||||
methprotos := make([]string, len(methods)) // objc method prototypes
|
methprotos := make([]string, len(methods)) // objc method prototypes
|
||||||
|
@ -1577,11 +1650,15 @@ func (w *Wrapper) _ProcessDelSub(dname string, ps map[string][]string, nms []*Me
|
||||||
getypes[i] = make([]string, len(m.Parameters)+1)
|
getypes[i] = make([]string, len(m.Parameters)+1)
|
||||||
vnames[i][0] = "self"
|
vnames[i][0] = "self"
|
||||||
getypes[i][0] = "unsafe.Pointer"
|
getypes[i][0] = "unsafe.Pointer"
|
||||||
gtypes[i] = make([]string, len(m.Parameters)+1)
|
//if m.Name == "dealloc" {
|
||||||
if m.Name != "dealloc" {
|
// gtypes[i] = make([]string, len(m.Parameters))
|
||||||
gtypes[i][0] = gname + "Supermethods"
|
//} else {
|
||||||
}
|
gtypes[i] = make([]string, len(m.Parameters)+2)
|
||||||
|
gtypes[i][0] = gname // self
|
||||||
|
gtypes[i][1] = gname + "Supermethods"
|
||||||
|
//}
|
||||||
if Debug {
|
if Debug {
|
||||||
|
fmt.Printf("len gtypes[%d] = %d\n", i, len(gtypes[i]))
|
||||||
fmt.Printf("%s: %s\n", dname, m.Name)
|
fmt.Printf("%s: %s\n", dname, m.Name)
|
||||||
}
|
}
|
||||||
var parms string
|
var parms string
|
||||||
|
@ -1597,11 +1674,19 @@ func (w *Wrapper) _ProcessDelSub(dname string, ps map[string][]string, nms []*Me
|
||||||
cparms = fmt.Sprintf("void* self, %s %s", pm.Type.Node.CType(), pm.Vname)
|
cparms = fmt.Sprintf("void* self, %s %s", pm.Type.Node.CType(), pm.Vname)
|
||||||
vnames[i][1] = pm.Vname
|
vnames[i][1] = pm.Vname
|
||||||
vpnames[i][0] = pm.Pname + ":" + pm.Vname
|
vpnames[i][0] = pm.Pname + ":" + pm.Vname
|
||||||
gtypes[i][1] = pm.Type.GoType()
|
//if m.Name == "dealloc" {
|
||||||
|
// gtypes[i][1] = pm.Type.GoType()
|
||||||
|
//} else {
|
||||||
|
gtypes[i][2] = pm.Type.GoType()
|
||||||
|
//}
|
||||||
if pm.Type.IsPointer() {
|
if pm.Type.IsPointer() {
|
||||||
getypes[i][1] = "unsafe.Pointer"
|
getypes[i][1] = "unsafe.Pointer"
|
||||||
} else {
|
} else {
|
||||||
getypes[i][1] = gtypes[i][1]
|
//if m.Name == "dealloc" {
|
||||||
|
// getypes[i][1] = gtypes[i][1]
|
||||||
|
//} else {
|
||||||
|
getypes[i][1] = gtypes[i][2]
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for j := 1; j < len(m.Parameters); j++ {
|
for j := 1; j < len(m.Parameters); j++ {
|
||||||
|
@ -1611,12 +1696,20 @@ func (w *Wrapper) _ProcessDelSub(dname string, ps map[string][]string, nms []*Me
|
||||||
cparms = cparms + fmt.Sprintf(", %s %s", pm.Type.Node.CType(), pm.Vname)
|
cparms = cparms + fmt.Sprintf(", %s %s", pm.Type.Node.CType(), pm.Vname)
|
||||||
vnames[i][j+1] = pm.Vname
|
vnames[i][j+1] = pm.Vname
|
||||||
vpnames[i][j] = pm.Pname + ":" + pm.Vname
|
vpnames[i][j] = pm.Pname + ":" + pm.Vname
|
||||||
gtypes[i][j+1] = pm.Type.GoType()
|
//if m.Name == "dealloc" {
|
||||||
|
// gtypes[i][j+1] = pm.Type.GoType()
|
||||||
|
//} else {
|
||||||
|
gtypes[i][j+2] = pm.Type.GoType()
|
||||||
|
//}
|
||||||
var getp string
|
var getp string
|
||||||
if pm.Type.IsPointer() {
|
if pm.Type.IsPointer() {
|
||||||
getp = "unsafe.Pointer"
|
getp = "unsafe.Pointer"
|
||||||
} else {
|
} else {
|
||||||
getp = gtypes[i][j+1]
|
//if m.Name == "dealloc" {
|
||||||
|
// getp = gtypes[i][j+1]
|
||||||
|
//} else {
|
||||||
|
getp = gtypes[i][j+2]
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
getypes[i][j+1] = getp
|
getypes[i][j+1] = getp
|
||||||
}
|
}
|
||||||
|
@ -1642,7 +1735,7 @@ func (w *Wrapper) _ProcessDelSub(dname string, ps map[string][]string, nms []*Me
|
||||||
if i < sms {
|
if i < sms {
|
||||||
_, cntps, _ := w.cparamlist(m)
|
_, cntps, _ := w.cparamlist(m)
|
||||||
sfunprotos[i] = fmt.Sprintf(
|
sfunprotos[i] = fmt.Sprintf(
|
||||||
`%s %s_super_%s(%s);`, ct, dname, m.Name, cntps)
|
`%s %s_super_%s(%s);`, ct, dname, m.GoName, cntps)
|
||||||
}
|
}
|
||||||
crtypes[i] = m.Type.CTypeAttrib()
|
crtypes[i] = m.Type.CTypeAttrib()
|
||||||
if m.Type.IsPointer() {
|
if m.Type.IsPointer() {
|
||||||
|
@ -1666,26 +1759,26 @@ func (w *Wrapper) _ProcessDelSub(dname string, ps map[string][]string, nms []*Me
|
||||||
{ }
|
{ }
|
||||||
%s
|
%s
|
||||||
`, dname, supcls, protos, strings.Join(methprotos, "\n")))
|
`, dname, supcls, protos, strings.Join(methprotos, "\n")))
|
||||||
havesupmethods := sms > 0
|
//havesupmethods := sms > 0
|
||||||
if sub {
|
if sub {
|
||||||
for i, sp := range smethprotos {
|
for _, sp := range smethprotos {
|
||||||
if methods[i].Name != "dealloc" {
|
//if methods[i].Name != "dealloc" {
|
||||||
ccode.WriteString(sp + "\n")
|
ccode.WriteString(sp + "\n")
|
||||||
} else {
|
//} else {
|
||||||
if sms == 1 {
|
// if sms == 1 {
|
||||||
havesupmethods = false
|
// havesupmethods = false
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ccode.WriteString(`
|
ccode.WriteString(`
|
||||||
@end
|
@end
|
||||||
`)
|
`)
|
||||||
if sub {
|
if sub {
|
||||||
for i, sf := range sfunprotos {
|
for _, sf := range sfunprotos {
|
||||||
if methods[i].Name != "dealloc" {
|
//if methods[i].Name != "dealloc" {
|
||||||
ccode.WriteString(sf + "\n")
|
ccode.WriteString(sf + "\n")
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1726,12 +1819,17 @@ func (w *Wrapper) _ProcessDelSub(dname string, ps map[string][]string, nms []*Me
|
||||||
%s[super %s];
|
%s[super %s];
|
||||||
}
|
}
|
||||||
`, smp, ret, strings.Join(vpnames[i], " "))
|
`, smp, ret, strings.Join(vpnames[i], " "))
|
||||||
|
var arp1, arp2 string
|
||||||
|
if vpnames[i][0] != "alloc" {
|
||||||
|
arp1 = "@autoreleasepool {\n\t\t"
|
||||||
|
arp2 = "\t}\n"
|
||||||
|
}
|
||||||
sfundecls[i] = fmt.Sprintf(`
|
sfundecls[i] = fmt.Sprintf(`
|
||||||
%s
|
%s
|
||||||
{
|
{
|
||||||
%s[(%s*)o super_%s];
|
%s%s[(%s*)o super_%s];
|
||||||
}
|
%s}
|
||||||
`, sfp, ret, dname, strings.Join(vpnames[i], " "))
|
`, sfp, arp1, ret, dname, strings.Join(vpnames[i], " "), arp2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ccode.WriteString(fmt.Sprintf(`
|
ccode.WriteString(fmt.Sprintf(`
|
||||||
|
@ -1739,20 +1837,20 @@ func (w *Wrapper) _ProcessDelSub(dname string, ps map[string][]string, nms []*Me
|
||||||
%s
|
%s
|
||||||
`, dname, strings.Join(methdecls, "\n")))
|
`, dname, strings.Join(methdecls, "\n")))
|
||||||
if sub {
|
if sub {
|
||||||
for i, sm := range smethdecls {
|
for _, sm := range smethdecls {
|
||||||
if methods[i].Name != "dealloc" {
|
//if methods[i].Name != "dealloc" {
|
||||||
ccode.WriteString(sm + "\n")
|
ccode.WriteString(sm + "\n")
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ccode.WriteString(`
|
ccode.WriteString(`
|
||||||
@end
|
@end
|
||||||
`)
|
`)
|
||||||
if sub {
|
if sub {
|
||||||
for i, sf := range sfundecls {
|
for _, sf := range sfundecls {
|
||||||
if methods[i].Name != "dealloc" {
|
//if methods[i].Name != "dealloc" {
|
||||||
ccode.WriteString(sf + "\n")
|
ccode.WriteString(sf + "\n")
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1790,7 +1888,9 @@ void*
|
||||||
}
|
}
|
||||||
if Gogc {
|
if Gogc {
|
||||||
w.goImports["runtime"] = true
|
w.goImports["runtime"] = true
|
||||||
if Debug { w.goImports["fmt"] = true }
|
if Debug {
|
||||||
|
w.goImports["fmt"] = true
|
||||||
|
}
|
||||||
finalizer = fmt.Sprintf(
|
finalizer = fmt.Sprintf(
|
||||||
`if ret.ptr == nil { return ret }
|
`if ret.ptr == nil { return ret }
|
||||||
%sruntime.SetFinalizer(ret,func(o *%s) {
|
%sruntime.SetFinalizer(ret,func(o *%s) {
|
||||||
|
@ -1826,15 +1926,18 @@ func (o *%s) GC() {
|
||||||
dispitems := make([]string, len(gnames))
|
dispitems := make([]string, len(gnames))
|
||||||
sdispitems := make([]string, sms)
|
sdispitems := make([]string, sms)
|
||||||
for i, n := range gnames {
|
for i, n := range gnames {
|
||||||
if !sub || sms == 0 {
|
if !sub || sms == 0 { // || !havesupmethods {
|
||||||
gtypes[i] = gtypes[i][1:]
|
gtypes[i] = append(gtypes[i][0:1], gtypes[i][2:]...)
|
||||||
|
//if sub && !havesupmethods {
|
||||||
|
// gtypes[i] = append(gtypes[i][:1],gtypes[i][2:]...)
|
||||||
|
// fmt.Printf("len gtypes[%d] = %d\n", i, len(gtypes[i]))
|
||||||
}
|
}
|
||||||
dispitems[i] = fmt.Sprintf(
|
dispitems[i] = fmt.Sprintf(
|
||||||
` %s func(%s)%s`, n, strings.Join(gtypes[i], ", "), grtypes[i])
|
` %s func(%s)%s`, n, strings.Join(gtypes[i], ", "), grtypes[i])
|
||||||
if sub && i < sms && methods[i].Name != "dealloc" {
|
if sub && i < sms { // && methods[i].Name != "dealloc" {
|
||||||
sdispitems[i] = fmt.Sprintf(
|
sdispitems[i] = fmt.Sprintf(
|
||||||
` %s func(%s)%s
|
` %s func(%s)%s
|
||||||
`, n, strings.Join(gtypes[i][1:], ", "), grtypes[i])
|
`, n, strings.Join(gtypes[i][2:], ", "), grtypes[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gocode.WriteString(fmt.Sprintf(`
|
gocode.WriteString(fmt.Sprintf(`
|
||||||
|
@ -1845,7 +1948,7 @@ var %sLookup = map[unsafe.Pointer]%sDispatch{}
|
||||||
var %sMux sync.RWMutex
|
var %sMux sync.RWMutex
|
||||||
`, gname, strings.Join(dispitems, "\n"), gname, gname, gname))
|
`, gname, strings.Join(dispitems, "\n"), gname, gname, gname))
|
||||||
w.goImports["sync"] = true
|
w.goImports["sync"] = true
|
||||||
if sub && sms > 0 && havesupmethods {
|
if sub && sms > 0 { // && havesupmethods {
|
||||||
gocode.WriteString(fmt.Sprintf(`
|
gocode.WriteString(fmt.Sprintf(`
|
||||||
type %sSupermethods struct {
|
type %sSupermethods struct {
|
||||||
%s
|
%s
|
||||||
|
@ -1872,18 +1975,21 @@ func (d %s) %sCallback(f func(%s)%s) {
|
||||||
`, gname, gnames[i], strings.Join(gtypes[i], ", "), grtypes[i], gname, gname, gnames[i], gname, gname))
|
`, gname, gnames[i], strings.Join(gtypes[i], ", "), grtypes[i], gname, gname, gnames[i], gname, gname))
|
||||||
//3. Go exported callback function wrappers
|
//3. Go exported callback function wrappers
|
||||||
earglist := []string{"o unsafe.Pointer"}
|
earglist := []string{"o unsafe.Pointer"}
|
||||||
garglist := []string{}
|
garglist := []string{"self"}
|
||||||
gargconv := []string{}
|
gargconv := []string{}
|
||||||
if sub && sms > 0 && m.Name != "dealloc" {
|
if sub && sms > 0 { // && m.Name != "dealloc" {
|
||||||
garglist = []string{"super"}
|
garglist = []string{"self", "super"}
|
||||||
}
|
}
|
||||||
for j := 1; j < len(vnames[i]); j++ {
|
for j := 1; j < len(vnames[i]); j++ {
|
||||||
earglist = append(earglist, vnames[i][j]+" "+getypes[i][j])
|
earglist = append(earglist, vnames[i][j]+" "+getypes[i][j])
|
||||||
var gt2 string
|
var gt2 string
|
||||||
if sub {
|
if sub {
|
||||||
gt2 = gtypes[i][j]
|
//fmt.Println(gtypes)
|
||||||
|
//fmt.Printf("%d %d\n",i,j)
|
||||||
|
gt2 = gtypes[i][j+1]
|
||||||
} else {
|
} else {
|
||||||
gt2 = gtypes[i][j-1]
|
gt2 = gtypes[i][j]
|
||||||
|
//gt2 = gtypes[i][j]
|
||||||
}
|
}
|
||||||
if types.PtrIsGoInterface(gt2) {
|
if types.PtrIsGoInterface(gt2) {
|
||||||
gt2 = "*Id"
|
gt2 = "*Id"
|
||||||
|
@ -1920,20 +2026,18 @@ func (d %s) %sCallback(f func(%s)%s) {
|
||||||
}
|
}
|
||||||
sdispentries := make([]string, sms)
|
sdispentries := make([]string, sms)
|
||||||
for i, _ := range sdispentries {
|
for i, _ := range sdispentries {
|
||||||
if methods[i].Name != "dealloc" {
|
//if methods[i].Name != "dealloc" {
|
||||||
sdispentries[i] = fmt.Sprintf(
|
sdispentries[i] = fmt.Sprintf(
|
||||||
` self.Super%s,
|
` self.Super%s,
|
||||||
`, gnames[i])
|
`, gnames[i])
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
sper := ""
|
sper := ""
|
||||||
if sub && sms > 0 && m.Name != "dealloc" {
|
if sub && sms > 0 { //&& m.Name != "dealloc" {
|
||||||
sper = fmt.Sprintf(
|
sper = fmt.Sprintf(
|
||||||
` self := %s{}
|
` super := %sSupermethods{
|
||||||
self.ptr = o
|
|
||||||
super := %sSupermethods{
|
|
||||||
%s }
|
%s }
|
||||||
`, gname, gname, strings.Join(sdispentries, ""))
|
`, gname, strings.Join(sdispentries, ""))
|
||||||
}
|
}
|
||||||
if len(gargconv) > 0 {
|
if len(gargconv) > 0 {
|
||||||
retn = "\n " + retn
|
retn = "\n " + retn
|
||||||
|
@ -1947,16 +2051,18 @@ func %s%s(%s)%s {
|
||||||
%scb := %sLookup[o].%s
|
%scb := %sLookup[o].%s
|
||||||
%sMux.RUnlock()
|
%sMux.RUnlock()
|
||||||
if cb == nil { return%s }
|
if cb == nil { return%s }
|
||||||
|
self := %s{}
|
||||||
|
self.ptr = o
|
||||||
%s%s%scb(%s)%s
|
%s%s%scb(%s)%s
|
||||||
}
|
}
|
||||||
`, gname, gnames[i], gname, gnames[i], strings.Join(earglist, ", "), crtype, gname, retdecl, gname, gnames[i], gname, retname, sper, strings.Join(gargconv, "\n"), retn, strings.Join(garglist, ", "), retnparen))
|
`, gname, gnames[i], gname, gnames[i], strings.Join(earglist, ", "), crtype, gname, retdecl, gname, gnames[i], gname, retname, gname, sper, strings.Join(gargconv, "\n"), retn, strings.Join(garglist, ", "), retnparen))
|
||||||
//4. Go wrapper functions for superclass methods
|
//4. Go wrapper functions for superclass methods
|
||||||
if !sub || i >= sms {
|
if !sub || i >= sms {
|
||||||
continue
|
continue
|
||||||
} // for subclasses only
|
} // for subclasses only
|
||||||
if m.Name == "dealloc" {
|
//if m.Name == "dealloc" {
|
||||||
continue
|
// continue
|
||||||
}
|
//}
|
||||||
grtype := m.Type.GoType()
|
grtype := m.Type.GoType()
|
||||||
if grtype == "Void" {
|
if grtype == "Void" {
|
||||||
grtype = ""
|
grtype = ""
|
||||||
|
@ -1984,7 +2090,7 @@ func (o *%s) Super%s(%s) %s {
|
||||||
}
|
}
|
||||||
`, vn, w.Vaargs, vn, vn))
|
`, vn, w.Vaargs, vn, vn))
|
||||||
}
|
}
|
||||||
gocode.WriteString("\t" + types.GoToC(m.Name, dname+"_super_"+m.Name, ns, snames, m.Type, tps, false, m.ShouldFinalize(), m.ClassMethod) + "\n}\n")
|
gocode.WriteString("\t" + types.GoToC(m.Name, dname+"_super_"+m.GoName, ns, snames, m.Type, tps, false, m.ShouldFinalize(), m.ClassMethod, w.goImports) + "\n}\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.cCode.WriteString(cprotos.String())
|
w.cCode.WriteString(cprotos.String())
|
||||||
|
@ -2191,6 +2297,13 @@ func (w *Wrapper) Wrap(toproc []string) {
|
||||||
}
|
}
|
||||||
ldflags = "-framework " + strings.Join(w.Frameworks, " -framework ")
|
ldflags = "-framework " + strings.Join(w.Frameworks, " -framework ")
|
||||||
}
|
}
|
||||||
|
if len(w.Frameworks) > 0 {
|
||||||
|
w.cImports.WriteString("")
|
||||||
|
}
|
||||||
|
if w.Libraries != nil && len(w.Libraries) > 0 {
|
||||||
|
ldflags = ldflags + "-l" + strings.Join(w.Libraries, " -l")
|
||||||
|
}
|
||||||
|
|
||||||
if w.Frameworkdirs != nil && len(w.Frameworkdirs) > 0 {
|
if w.Frameworkdirs != nil && len(w.Frameworkdirs) > 0 {
|
||||||
s := strings.Join(w.Frameworkdirs, " -F")
|
s := strings.Join(w.Frameworkdirs, " -F")
|
||||||
w.cgoFlags.WriteString(" -F" + s)
|
w.cgoFlags.WriteString(" -F" + s)
|
||||||
|
@ -2205,7 +2318,7 @@ func (w *Wrapper) Wrap(toproc []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
of.WriteString(w.cgoFlags.String() + "\n")
|
of.WriteString(w.cgoFlags.String() + "\n")
|
||||||
of.WriteString(w.cImports.String() + "\n")
|
of.WriteString(w.cImports.String())
|
||||||
|
|
||||||
of.WriteString(w.cCode.String())
|
of.WriteString(w.cCode.String())
|
||||||
imports := []string{}
|
imports := []string{}
|
||||||
|
@ -2227,16 +2340,15 @@ func init() {
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
of.WriteString(fmt.Sprintf(`
|
of.WriteString(fmt.Sprintf(
|
||||||
%s
|
`%s
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
%s
|
%s
|
||||||
)
|
)
|
||||||
%s
|
%s`, startThread, strings.Join(imports, "\n"), goInit))
|
||||||
`,startThread,strings.Join(imports,"\n"),goInit))
|
|
||||||
of.WriteString(w.goTypes.String())
|
of.WriteString(w.goTypes.String())
|
||||||
of.WriteString(w.goConst.String())
|
of.WriteString(w.goConst.String())
|
||||||
of.WriteString(w.goHelpers.String())
|
of.WriteString(w.goHelpers.String())
|
||||||
|
|
Loading…
Reference in New Issue
Block a user