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
 | 
			
		||||
var nst = ns.NSStringWithGoString
 | 
			
		||||
 | 
			
		||||
func pb1() {
 | 
			
		||||
func pb1(self ns.GButton, super ns.GButtonSupermethods) {
 | 
			
		||||
	fmt.Println("Pushed button 1")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func pb2() {
 | 
			
		||||
func pb2(self ns.GButton, super ns.GButtonSupermethods) {
 | 
			
		||||
	fmt.Println("Pushed button 2")
 | 
			
		||||
	a.Terminate(a)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func db() {
 | 
			
		||||
func db(self ns.GButton, super ns.GButtonSupermethods) {
 | 
			
		||||
	fmt.Println("button deallocated")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func didFinishLaunching(n *ns.NSNotification) {
 | 
			
		||||
func didFinishLaunching(self ns.AppDelegate, n *ns.NSNotification) {
 | 
			
		||||
	fmt.Println("Go: did finish launching")
 | 
			
		||||
	fmt.Printf("Notification: %s\n", n.Name().UTF8String())
 | 
			
		||||
	//Set up an NSWindow
 | 
			
		||||
	win = ns.NSWindowAlloc().InitWithContentRectStyleMask(
 | 
			
		||||
		ns.NSMakeRect(200, 200, 600, 600),
 | 
			
		||||
		ns.NSWindowStyleMaskTitled|ns.NSWindowStyleMaskClosable|
 | 
			
		||||
			ns.NSWindowStyleMaskResizable,
 | 
			
		||||
		ns.NSBackingStoreBuffered,
 | 
			
		||||
		ns.NSWindowStyleMask(ns.NSWindowStyleMaskTitled|ns.NSWindowStyleMaskClosable|
 | 
			
		||||
			ns.NSWindowStyleMaskResizable),
 | 
			
		||||
		ns.NSBackingStoreType(ns.NSBackingStoreBuffered),
 | 
			
		||||
		0,
 | 
			
		||||
	)
 | 
			
		||||
	// 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(
 | 
			
		||||
		nst("H:|-[b1]"), 0, nil, viewmap))
 | 
			
		||||
	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)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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")
 | 
			
		||||
	return 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func willTerminate(n *ns.NSNotification) {
 | 
			
		||||
func willTerminate(self ns.AppDelegate, n *ns.NSNotification) {
 | 
			
		||||
	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.Printf("Notification: %s\n", n.Name().UTF8String())
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -132,7 +132,7 @@ func app() {
 | 
			
		|||
	// Lock OS thread because Cocoa uses thread-local storage
 | 
			
		||||
	runtime.LockOSThread()
 | 
			
		||||
	a = ns.NSApplicationSharedApplication()
 | 
			
		||||
	a.SetActivationPolicy(ns.NSApplicationActivationPolicyRegular)
 | 
			
		||||
	a.SetActivationPolicy(ns.NSApplicationActivationPolicy(ns.NSApplicationActivationPolicyRegular))
 | 
			
		||||
 | 
			
		||||
	// Set up an AppDelegate
 | 
			
		||||
	// assign it to a global variable so it doesn't get garbage collected
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
# nswrap.yaml
 | 
			
		||||
inputfiles:
 | 
			
		||||
    - /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/Foundation.framework/Headers/Foundation.h
 | 
			
		||||
    - /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/AppKit.framework/Headers/AppKit.h
 | 
			
		||||
 | 
			
		||||
classes:
 | 
			
		||||
    - NSAutoreleasePool
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,14 +5,14 @@ import "C"
 | 
			
		|||
import (
 | 
			
		||||
	"encoding/binary"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"git.wow.st/gmp/nswrap/examples/bluetooth/ns"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"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")
 | 
			
		||||
	switch cm.CBManager.State() {
 | 
			
		||||
	switch ns.NSInteger(cm.CBManager.State()) {
 | 
			
		||||
	case ns.CBManagerStateUnknown:
 | 
			
		||||
		fmt.Printf("  unknown\n")
 | 
			
		||||
	case ns.CBManagerStateResetting:
 | 
			
		||||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ func updateState(c *ns.CBCentralManager) {
 | 
			
		|||
	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")
 | 
			
		||||
	c.StopScan()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -51,7 +51,7 @@ func discoverPeripheral(c *ns.CBCentralManager, p *ns.CBPeripheral, d *ns.NSDict
 | 
			
		|||
	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")
 | 
			
		||||
 | 
			
		||||
	// 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")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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")
 | 
			
		||||
	p.Services().ObjectEnumerator().ForIn(func(o *ns.Id) bool {
 | 
			
		||||
		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")
 | 
			
		||||
	uuid := s.UUID()
 | 
			
		||||
	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")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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) {
 | 
			
		||||
		v := chr.Value()
 | 
			
		||||
		fmt.Printf("Heart rate: %d\n", hr(v))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
inputfiles:
 | 
			
		||||
    - /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/Foundation.framework/Headers/Foundation.h
 | 
			
		||||
    - /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/CoreBluetooth.framework/Headers/CoreBluetooth.h
 | 
			
		||||
 | 
			
		||||
classes:
 | 
			
		||||
    - NSObject
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ func main() {
 | 
			
		|||
	fmt.Printf("\nNSArray.ObjectEnumerator().ForIn():\n")
 | 
			
		||||
	x := 0
 | 
			
		||||
	a.ObjectEnumerator().ForIn(func(o *ns.Id) bool {
 | 
			
		||||
		fmt.Printf("%d: %s\n",x,o.NSString())
 | 
			
		||||
		fmt.Printf("%d: %s\n", x, o.NSString())
 | 
			
		||||
		x++
 | 
			
		||||
		return true
 | 
			
		||||
	})
 | 
			
		||||
| 
						 | 
				
			
			@ -72,7 +72,7 @@ func main() {
 | 
			
		|||
		}
 | 
			
		||||
		return true
 | 
			
		||||
	})
 | 
			
		||||
	fmt.Printf("a = %p a.NSArray = %p\n",a,&a.NSArray)
 | 
			
		||||
	fmt.Printf("a = %p a.NSArray = %p\n", a, &a.NSArray)
 | 
			
		||||
	fmt.Printf("\nNSArrayWithObjects() (length 1)\n")
 | 
			
		||||
	a2 = ns.NSArrayWithObjects(n1)
 | 
			
		||||
	a2.ObjectEnumerator().ForIn(func(o *ns.Id) bool {
 | 
			
		||||
| 
						 | 
				
			
			@ -109,8 +109,8 @@ func main() {
 | 
			
		|||
	oarr := make([]*ns.Id, 0, 5)
 | 
			
		||||
	fmt.Printf("Length of oarr is %d\n", len(oarr))
 | 
			
		||||
	karr := make([]*ns.Id, 0, 5)
 | 
			
		||||
	fmt.Printf("\nGetObjects()\n")
 | 
			
		||||
	d.GetObjects(&oarr, &karr, 4)
 | 
			
		||||
	fmt.Printf("\nGetObjectsAndKeysCount()\n")
 | 
			
		||||
	d.GetObjectsAndKeysCount(&oarr, &karr, 4)
 | 
			
		||||
	fmt.Printf("Length of oarr is now %d\n", len(oarr))
 | 
			
		||||
	for i, k := range karr {
 | 
			
		||||
		fmt.Printf("-- %s -> %s\n", k.NSString(), oarr[i].NSString())
 | 
			
		||||
| 
						 | 
				
			
			@ -119,11 +119,11 @@ func main() {
 | 
			
		|||
	err := make([]*ns.NSError, 1)
 | 
			
		||||
	n1 = ns.NSStringWithContentsOfURLEncoding(ns.NSURLWithGoString("http://captive.apple.com"), ns.NSUTF8StringEncoding, &err)
 | 
			
		||||
	if len(err) == 0 {
 | 
			
		||||
		fmt.Printf("n1 = %s\n",n1)
 | 
			
		||||
		fmt.Printf("n1 = %s\n", n1)
 | 
			
		||||
	}
 | 
			
		||||
	n1 = ns.NSStringWithContentsOfURLEncoding(ns.NSURLWithGoString("htttypo://example.com"), ns.NSUTF8StringEncoding, &err)
 | 
			
		||||
	if len(err) > 0 {
 | 
			
		||||
		fmt.Printf("err[0] = %p -> %p\n",err[0],err[0].Ptr())
 | 
			
		||||
		fmt.Printf("err[0] = %p -> %p\n", err[0], err[0].Ptr())
 | 
			
		||||
		fmt.Printf("err: %s\n", err[0].LocalizedDescription())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -137,26 +137,26 @@ func main() {
 | 
			
		|||
	fmt.Printf("\nArrayWithObjects\n")
 | 
			
		||||
	a2 = ns.NSArrayWithObjects(gs1, gs2)
 | 
			
		||||
	a2.ObjectEnumerator().ForIn(func(o *ns.Id) bool {
 | 
			
		||||
		fmt.Printf("--%s\n",o.NSString())
 | 
			
		||||
		fmt.Printf("--%s\n", o.NSString())
 | 
			
		||||
		return true
 | 
			
		||||
	})
 | 
			
		||||
	dir,e := os.Getwd()
 | 
			
		||||
	dir, e := os.Getwd()
 | 
			
		||||
	if e != nil {
 | 
			
		||||
		fmt.Printf("Failed to get current working directory. %s\n",err)
 | 
			
		||||
		fmt.Printf("Failed to get current working directory. %s\n", err)
 | 
			
		||||
		os.Exit(-1)
 | 
			
		||||
	}
 | 
			
		||||
	path := nst(dir)
 | 
			
		||||
	filter := ns.NSArrayWithObjects(nst("ast"),nst("yaml"))
 | 
			
		||||
	ost := make([]*ns.NSString,0,1)
 | 
			
		||||
	oar:= make([]*ns.NSArray,0,1)
 | 
			
		||||
	filter := ns.NSArrayWithObjects(nst("ast"), nst("yaml"))
 | 
			
		||||
	ost := make([]*ns.NSString, 0, 1)
 | 
			
		||||
	oar := make([]*ns.NSArray, 0, 1)
 | 
			
		||||
	fmt.Printf("\nCompletePathIntoString()\n")
 | 
			
		||||
	i := path.CompletePathIntoString(&ost,0,&oar,filter)
 | 
			
		||||
	fmt.Printf("%d matches\n",i)
 | 
			
		||||
	i := path.CompletePathIntoString(&ost, 0, &oar, filter)
 | 
			
		||||
	fmt.Printf("%d matches\n", i)
 | 
			
		||||
	if i > 0 {
 | 
			
		||||
		fmt.Printf("ost = %s\n",ost[0])
 | 
			
		||||
		fmt.Printf("ost = %s\n", ost[0])
 | 
			
		||||
		fmt.Printf("oar =\n")
 | 
			
		||||
		oar[0].ObjectEnumerator().ForIn(func(o *ns.Id) bool {
 | 
			
		||||
			fmt.Printf("--%s\n",o.NSString())
 | 
			
		||||
			fmt.Printf("--%s\n", o.NSString())
 | 
			
		||||
			return true
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
inputfiles:
 | 
			
		||||
    - /System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
 | 
			
		||||
    - /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
 | 
			
		||||
classes:
 | 
			
		||||
    - NSAutoreleasePool
 | 
			
		||||
    - NSArray
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,25 +2,24 @@ package main
 | 
			
		|||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
	"git.wow.st/gmp/nswrap/examples/functions/ns"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	var s ns.Stat
 | 
			
		||||
	ns.Puts(ns.CharWithGoString("Hi there"))
 | 
			
		||||
	ret := ns.Fstat(3,&s)
 | 
			
		||||
	fmt.Printf("Fstat: %d\n",ret)
 | 
			
		||||
	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)
 | 
			
		||||
	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))
 | 
			
		||||
	fmt.Printf("file contents:\n%s\n", string(chr))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
inputfiles:
 | 
			
		||||
  - /usr/include/stdio.h
 | 
			
		||||
  - /usr/include/stdlib.h
 | 
			
		||||
  - /usr/include/sys/stat.h
 | 
			
		||||
  - /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/stdio.h
 | 
			
		||||
  - /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/stdlib.h
 | 
			
		||||
  - /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/stat.h
 | 
			
		||||
sysimports:
 | 
			
		||||
  - stdio.h
 | 
			
		||||
  - stdlib.h
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,8 +9,8 @@ import (
 | 
			
		|||
	"git.wow.st/gmp/nswrap/examples/gc/ns"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func releaseX(x int) func (ns.MyClassSupermethods) {
 | 
			
		||||
	return func(super ns.MyClassSupermethods) {
 | 
			
		||||
func releaseX(x int) func(ns.MyClass, ns.MyClassSupermethods) {
 | 
			
		||||
	return func(self ns.MyClass, super ns.MyClassSupermethods) {
 | 
			
		||||
		//fmt.Printf("--release %d\n", x)
 | 
			
		||||
		super.Release() // comment out for leak
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -19,7 +19,7 @@ func releaseX(x int) func (ns.MyClassSupermethods) {
 | 
			
		|||
func memtest1() {
 | 
			
		||||
	fmt.Println("memtest1 started")
 | 
			
		||||
	for {
 | 
			
		||||
		arr := make([]*ns.MyClass,1000)
 | 
			
		||||
		arr := make([]*ns.MyClass, 1000)
 | 
			
		||||
		for i := 0; i < 1000; i++ {
 | 
			
		||||
			// Alloc methods set a finalizer that causes the Go GC to
 | 
			
		||||
			// Release these objects.
 | 
			
		||||
| 
						 | 
				
			
			@ -33,7 +33,7 @@ func memtest1() {
 | 
			
		|||
		// Manually run the Go GC at every loop iteration. May not be needed
 | 
			
		||||
		// in a real program.
 | 
			
		||||
		runtime.GC()
 | 
			
		||||
		time.Sleep(time.Second/50)
 | 
			
		||||
		time.Sleep(time.Second / 50)
 | 
			
		||||
		//fmt.Printf("Loop complete\n")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -42,8 +42,8 @@ func memtest2() {
 | 
			
		|||
	fmt.Println("memtest2 started")
 | 
			
		||||
	i := 0
 | 
			
		||||
	for {
 | 
			
		||||
		o1 := ns.NSStringAlloc().InitWithGoString(fmt.Sprintf("two string %d",i))
 | 
			
		||||
		o2 := ns.NSStringWithGoString(fmt.Sprintf("two string %d",i))
 | 
			
		||||
		o1 := ns.NSStringAlloc().InitWithGoString(fmt.Sprintf("two string %d", i))
 | 
			
		||||
		o2 := ns.NSStringWithGoString(fmt.Sprintf("two string %d", i))
 | 
			
		||||
 | 
			
		||||
		// NSWrap runs object constructors inside an @autoreleasepool block,
 | 
			
		||||
		// and then calls "retain" on them before returning to Go. A Go
 | 
			
		||||
| 
						 | 
				
			
			@ -58,9 +58,9 @@ func memtest2() {
 | 
			
		|||
		// init methods in Objective-C always return a retained object.
 | 
			
		||||
		// init may or may not return the same object that was sent in.
 | 
			
		||||
 | 
			
		||||
		a1 = a1.InitWithObjects(o1,o2,o3,o4)
 | 
			
		||||
		a1 = a1.InitWithObjects(o1, o2, o3, o4)
 | 
			
		||||
 | 
			
		||||
		a2 := ns.NSArrayWithObjects(o1,o2,o3,o4)
 | 
			
		||||
		a2 := ns.NSArrayWithObjects(o1, o2, o3, o4)
 | 
			
		||||
 | 
			
		||||
		// you can always nest alloc and init.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -74,7 +74,7 @@ func memtest2() {
 | 
			
		|||
		_ = a3
 | 
			
		||||
 | 
			
		||||
		runtime.GC()
 | 
			
		||||
		time.Sleep(time.Second/50)
 | 
			
		||||
		time.Sleep(time.Second / 50)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -121,7 +121,7 @@ func memtest4() {
 | 
			
		|||
		_ = o1
 | 
			
		||||
		_ = c1
 | 
			
		||||
		runtime.GC()
 | 
			
		||||
		time.Sleep(time.Second/50)
 | 
			
		||||
		time.Sleep(time.Second / 50)
 | 
			
		||||
		c1.Free() // you need to manually free UTF8Strings
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -134,7 +134,7 @@ func memtest5() {
 | 
			
		|||
		// a new NSString object at each loop iteration and cannot be reusing
 | 
			
		||||
		// the same string object.
 | 
			
		||||
 | 
			
		||||
		str := ns.NSStringWithGoString(fmt.Sprintf("blue string %d",i))
 | 
			
		||||
		str := ns.NSStringWithGoString(fmt.Sprintf("blue string %d", i))
 | 
			
		||||
 | 
			
		||||
		// SubstringFromIndex should be returning a newly allocated NSString,
 | 
			
		||||
		// which is getting retained by NSWrap and released by a Go GC
 | 
			
		||||
| 
						 | 
				
			
			@ -146,7 +146,7 @@ func memtest5() {
 | 
			
		|||
		u := sub.UTF8String()
 | 
			
		||||
		u2 := sub2.UTF8String()
 | 
			
		||||
		u3 := sub3.UTF8String()
 | 
			
		||||
		time.Sleep(time.Second/50)
 | 
			
		||||
		time.Sleep(time.Second / 50)
 | 
			
		||||
		runtime.GC()
 | 
			
		||||
		i++
 | 
			
		||||
		u.Free()
 | 
			
		||||
| 
						 | 
				
			
			@ -160,30 +160,29 @@ func memtest5() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func tmpdict(i int) *ns.NSString {
 | 
			
		||||
	o1 := ns.NSStringWithGoString(fmt.Sprintf("temp string 1-%d",i))
 | 
			
		||||
	o2 := ns.NSStringWithGoString(fmt.Sprintf("temp string 2-%d",i))
 | 
			
		||||
	k1 := ns.NSStringWithGoString(fmt.Sprintf("temp key 1-%d",i))
 | 
			
		||||
	k2 := ns.NSStringWithGoString(fmt.Sprintf("temp key 2-%d",i))
 | 
			
		||||
	dict := ns.NSDictionaryWithObjectsAndKeys(o1,k1,o2,k2)
 | 
			
		||||
	o1 := ns.NSStringWithGoString(fmt.Sprintf("temp string 1-%d", i))
 | 
			
		||||
	o2 := ns.NSStringWithGoString(fmt.Sprintf("temp string 2-%d", i))
 | 
			
		||||
	k1 := ns.NSStringWithGoString(fmt.Sprintf("temp key 1-%d", i))
 | 
			
		||||
	k2 := ns.NSStringWithGoString(fmt.Sprintf("temp key 2-%d", i))
 | 
			
		||||
	dict := ns.NSDictionaryWithObjectsAndKeys(o1, k1, o2, k2)
 | 
			
		||||
	ret := dict.ValueForKey(k1)
 | 
			
		||||
	//fmt.Printf("tmpdict(): string = %s\n",ret.NSString())
 | 
			
		||||
 | 
			
		||||
	defer runtime.GC() // o1, o2, k1, k2, and dict can be released after we return
 | 
			
		||||
	defer runtime.GC()    // o1, o2, k1, k2, and dict can be released after we return
 | 
			
		||||
	return ret.NSString() // should be retained by NSDictionary.ValueForKey()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func tmparr(i int) *ns.NSString {
 | 
			
		||||
	o1 := ns.NSStringWithGoString(fmt.Sprintf("temp string 3-%d",i))
 | 
			
		||||
	o2 := ns.NSStringWithGoString(fmt.Sprintf("temp string 4-%d",i))
 | 
			
		||||
	arr := ns.NSArrayWithObjects(o1,o2)
 | 
			
		||||
	os := make([]*ns.Id,0,2)
 | 
			
		||||
	arr.GetObjects(&os, ns.NSMakeRange(0,2))
 | 
			
		||||
	o1 := ns.NSStringWithGoString(fmt.Sprintf("temp string 3-%d", i))
 | 
			
		||||
	o2 := ns.NSStringWithGoString(fmt.Sprintf("temp string 4-%d", i))
 | 
			
		||||
	arr := ns.NSArrayWithObjects(o1, o2)
 | 
			
		||||
	os := make([]*ns.Id, 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()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func memtest6() {
 | 
			
		||||
	fmt.Println("memtest6 started")
 | 
			
		||||
	i := 0
 | 
			
		||||
| 
						 | 
				
			
			@ -193,13 +192,13 @@ func memtest6() {
 | 
			
		|||
		time.Sleep(time.Second / 5)
 | 
			
		||||
		u1 := s1.String() // make sure s1 and s2 are still available
 | 
			
		||||
		u2 := s2.String()
 | 
			
		||||
		e1 := fmt.Sprintf("temp string 1-%d",i)
 | 
			
		||||
		e1 := fmt.Sprintf("temp string 1-%d", i)
 | 
			
		||||
		if u1 != e1 {
 | 
			
		||||
			fmt.Printf("tmpdict() error: %s != %s\n",u1,e1)
 | 
			
		||||
			fmt.Printf("tmpdict() error: %s != %s\n", u1, e1)
 | 
			
		||||
		}
 | 
			
		||||
		e2 := fmt.Sprintf("temp string 4-%d",i)
 | 
			
		||||
		e2 := fmt.Sprintf("temp string 4-%d", i)
 | 
			
		||||
		if u2 != e2 {
 | 
			
		||||
			fmt.Printf("tmparr() error: %s != %s\n",u2,e2)
 | 
			
		||||
			fmt.Printf("tmparr() error: %s != %s\n", u2, e2)
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
		i++
 | 
			
		||||
| 
						 | 
				
			
			@ -221,7 +220,7 @@ func main() {
 | 
			
		|||
	go func() {
 | 
			
		||||
		for {
 | 
			
		||||
			// print a progress indicator
 | 
			
		||||
			fmt.Printf("t = %s\n",time.Now())
 | 
			
		||||
			fmt.Printf("t = %s\n", time.Now())
 | 
			
		||||
			time.Sleep(time.Second * 10)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
inputfiles:
 | 
			
		||||
    - /System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
 | 
			
		||||
    - /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
 | 
			
		||||
classes:
 | 
			
		||||
    - NSAutoreleasePool
 | 
			
		||||
    - NSArray
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,13 +10,13 @@ import (
 | 
			
		|||
	"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
 | 
			
		||||
	//struct is provided here.
 | 
			
		||||
	fmt.Println("--dealloc called")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func release(super ns.MyClassSupermethods) {
 | 
			
		||||
func release(self ns.MyClass, super ns.MyClassSupermethods) {
 | 
			
		||||
	fmt.Println("--release called")
 | 
			
		||||
	super.Release() // comment out for leak
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -92,19 +92,19 @@ func memtest3() {
 | 
			
		|||
		ns.Autoreleasepool(func() {
 | 
			
		||||
			arr := ns.NSMutableArrayAlloc().Init()
 | 
			
		||||
			arr.Autorelease()
 | 
			
		||||
			arr.AddObject(ns.NSStringWithGoString(fmt.Sprintf("my string %d",i)))
 | 
			
		||||
			s1 := ns.NSStringWithGoString(fmt.Sprintf("my other string %d",i))
 | 
			
		||||
			fmt.Printf("%s\n",arr.ObjectAtIndex(0).NSString())
 | 
			
		||||
			arr.AddObject(ns.NSStringWithGoString(fmt.Sprintf("my string %d", i)))
 | 
			
		||||
			s1 := ns.NSStringWithGoString(fmt.Sprintf("my other string %d", i))
 | 
			
		||||
			fmt.Printf("%s\n", arr.ObjectAtIndex(0).NSString())
 | 
			
		||||
			_ = s1
 | 
			
		||||
 | 
			
		||||
			for x := 0; x < 3; x++ {
 | 
			
		||||
				ns.Autoreleasepool(func() {
 | 
			
		||||
					str := arr.ObjectAtIndex(0).NSString()
 | 
			
		||||
					fmt.Printf("%d->%s\n",x,str) // does not leak in an autorelease pool
 | 
			
		||||
					fmt.Printf("%d->%s\n", x, str) // does not leak in an autorelease pool
 | 
			
		||||
					time.Sleep(time.Second / 5)
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
			time.Sleep(time.Second/2)
 | 
			
		||||
			time.Sleep(time.Second / 2)
 | 
			
		||||
			i++
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
inputfiles:
 | 
			
		||||
    - /System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
 | 
			
		||||
    - /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
 | 
			
		||||
classes:
 | 
			
		||||
    - NSAutoreleasePool
 | 
			
		||||
    - NSArray
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,7 @@ import (
 | 
			
		|||
	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")
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,21 +26,21 @@ func incr() func(bool) (int, float64) {
 | 
			
		|||
		if b == 0 {
 | 
			
		||||
			return i, 0.0
 | 
			
		||||
		} else {
 | 
			
		||||
			return i, (b/float64(i)) * 100
 | 
			
		||||
			return i, (b / float64(i)) * 100
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type tracker struct {
 | 
			
		||||
	add, drop func(*ns.Id)
 | 
			
		||||
	check func()
 | 
			
		||||
	i func(bool) (int, float64)
 | 
			
		||||
	check     func()
 | 
			
		||||
	i         func(bool) (int, float64)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type record struct {
 | 
			
		||||
	ptr unsafe.Pointer
 | 
			
		||||
	ptr   unsafe.Pointer
 | 
			
		||||
	goPtr *ns.Id
 | 
			
		||||
	when time.Time
 | 
			
		||||
	when  time.Time
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newTracker() (func(*ns.Id), func(*ns.Id), func()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -54,35 +54,35 @@ func newTracker() (func(*ns.Id), func(*ns.Id), func()) {
 | 
			
		|||
			select {
 | 
			
		||||
			case x := <-addch:
 | 
			
		||||
				mux.Lock()
 | 
			
		||||
					data = append(data,record{
 | 
			
		||||
						x.Ptr(),
 | 
			
		||||
						x,
 | 
			
		||||
						time.Now(),
 | 
			
		||||
					})
 | 
			
		||||
				data = append(data, record{
 | 
			
		||||
					x.Ptr(),
 | 
			
		||||
					x,
 | 
			
		||||
					time.Now(),
 | 
			
		||||
				})
 | 
			
		||||
				mux.Unlock()
 | 
			
		||||
			case x := <-dropch:
 | 
			
		||||
				mux.Lock()
 | 
			
		||||
					data = append(data,record{
 | 
			
		||||
						nil,
 | 
			
		||||
						x,
 | 
			
		||||
						time.Now(),
 | 
			
		||||
					})
 | 
			
		||||
				data = append(data, record{
 | 
			
		||||
					nil,
 | 
			
		||||
					x,
 | 
			
		||||
					time.Now(),
 | 
			
		||||
				})
 | 
			
		||||
				mux.Unlock()
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	add := func(x *ns.Id) {
 | 
			
		||||
		addch<- x
 | 
			
		||||
		addch <- x
 | 
			
		||||
	}
 | 
			
		||||
	drop := func(x *ns.Id) {
 | 
			
		||||
		dropch<- x
 | 
			
		||||
		dropch <- x
 | 
			
		||||
	}
 | 
			
		||||
	check := func() {
 | 
			
		||||
		live := map[unsafe.Pointer]*ns.Id{}
 | 
			
		||||
		bad := false
 | 
			
		||||
		mux.Lock()
 | 
			
		||||
		for _,r := range data {
 | 
			
		||||
		for _, r := range data {
 | 
			
		||||
			if r.ptr != nil {
 | 
			
		||||
				if live[r.ptr] != nil {
 | 
			
		||||
					fmt.Printf("COLLISION: %p & %p -> %p\n", r.goPtr, live[r.ptr], r.ptr)
 | 
			
		||||
| 
						 | 
				
			
			@ -90,10 +90,10 @@ func newTracker() (func(*ns.Id), func(*ns.Id), func()) {
 | 
			
		|||
				}
 | 
			
		||||
				live[r.ptr] = r.goPtr
 | 
			
		||||
			} else {
 | 
			
		||||
				delete(live,r.ptr)
 | 
			
		||||
				delete(live, r.ptr)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		fmt.Printf("Checked %d records -- ",len(data))
 | 
			
		||||
		fmt.Printf("Checked %d records -- ", len(data))
 | 
			
		||||
		if bad {
 | 
			
		||||
			fmt.Printf("failed\n")
 | 
			
		||||
		} else {
 | 
			
		||||
| 
						 | 
				
			
			@ -101,25 +101,25 @@ func newTracker() (func(*ns.Id), func(*ns.Id), func()) {
 | 
			
		|||
		}
 | 
			
		||||
		mux.Unlock()
 | 
			
		||||
	}
 | 
			
		||||
	return add,drop,check
 | 
			
		||||
	return add, drop, check
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func mkstrings(t tracker) {
 | 
			
		||||
	for {
 | 
			
		||||
		//fmt.Printf("main thread: %t\n",ns.NSThreadIsMainThread())
 | 
			
		||||
		x,b := t.i(false)
 | 
			
		||||
		str := fmt.Sprintf("string %d",x)
 | 
			
		||||
		x, b := t.i(false)
 | 
			
		||||
		str := fmt.Sprintf("string %d", x)
 | 
			
		||||
		s := ns.NSStringWithGoString(str)
 | 
			
		||||
		//t.add(&s.Id)
 | 
			
		||||
		for j := 0; j < 10; j++ {
 | 
			
		||||
			sout := s.String()
 | 
			
		||||
			if str != sout {
 | 
			
		||||
				_,b = t.i(true)
 | 
			
		||||
				_, b = t.i(true)
 | 
			
		||||
				fmt.Printf("%3.2f%% -- %d: '%s' '%s'\n", b, x, str, sout)
 | 
			
		||||
			}
 | 
			
		||||
			time.Sleep(time.Second/1000)
 | 
			
		||||
			time.Sleep(time.Second / 1000)
 | 
			
		||||
		}
 | 
			
		||||
		if x % 1000 == 0 {
 | 
			
		||||
		if x%1000 == 0 {
 | 
			
		||||
			fmt.Printf("%3.2f%% -- %s\n", b, time.Now().Format("03:04:05.000"))
 | 
			
		||||
		}
 | 
			
		||||
		//t.drop(&s.Id)
 | 
			
		||||
| 
						 | 
				
			
			@ -145,7 +145,7 @@ func main() {
 | 
			
		|||
	go func() {
 | 
			
		||||
		for {
 | 
			
		||||
			runtime.GC()
 | 
			
		||||
			time.Sleep(time.Second/100)
 | 
			
		||||
			time.Sleep(time.Second / 100)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
inputfiles:
 | 
			
		||||
    - /System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
 | 
			
		||||
    - /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
 | 
			
		||||
classes:
 | 
			
		||||
    - NSString
 | 
			
		||||
    - 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.
										
									
								
							
							
								
								
									
										66
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								main.go
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -12,7 +12,10 @@ import (
 | 
			
		|||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"git.wow.st/gmp/nswrap/ast"
 | 
			
		||||
	"git.wow.st/gmp/nswrap/types"
 | 
			
		||||
	"git.wow.st/gmp/nswrap/wrap"
 | 
			
		||||
 | 
			
		||||
	"github.com/a8m/envsubst"
 | 
			
		||||
	"gopkg.in/yaml.v2"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -26,22 +29,26 @@ var autoadd = []string{
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
type conf struct {
 | 
			
		||||
	Positions     bool
 | 
			
		||||
	Package       string
 | 
			
		||||
	Inputfiles    []string
 | 
			
		||||
	Astfile       string
 | 
			
		||||
	Debugast      bool
 | 
			
		||||
	Classes       []string
 | 
			
		||||
	Functions     []string
 | 
			
		||||
	Enums         []string
 | 
			
		||||
	Delegates     map[string]map[string][]string
 | 
			
		||||
	Subclasses    map[string]map[string][]string
 | 
			
		||||
	Frameworks    []string
 | 
			
		||||
	Frameworkdirs []string
 | 
			
		||||
	Imports       []string
 | 
			
		||||
	Sysimports    []string
 | 
			
		||||
	Pragma        []string
 | 
			
		||||
	Vaargs        int
 | 
			
		||||
	Positions      bool
 | 
			
		||||
	Package        string
 | 
			
		||||
	Inputfiles     []string
 | 
			
		||||
	Astfile        string
 | 
			
		||||
	Debugast       bool
 | 
			
		||||
	Classes        []string
 | 
			
		||||
	Functions      []string
 | 
			
		||||
	FunctionIgnore []string
 | 
			
		||||
	Enums          []string
 | 
			
		||||
	Delegates      map[string]map[string][]string
 | 
			
		||||
	Subclasses     map[string]map[string][]string
 | 
			
		||||
	Frameworks     []string
 | 
			
		||||
	Libraries      []string
 | 
			
		||||
	Frameworkdirs  []string
 | 
			
		||||
	Imports        []string
 | 
			
		||||
	Sysimports     []string
 | 
			
		||||
	Pragma         []string
 | 
			
		||||
	Typesubs       map[string]string
 | 
			
		||||
	Vaargs         int
 | 
			
		||||
	Clang          string
 | 
			
		||||
	//Arc flag for debugging only, builds will break
 | 
			
		||||
	Arc         bool
 | 
			
		||||
	Autorelease bool
 | 
			
		||||
| 
						 | 
				
			
			@ -233,7 +240,12 @@ func Start() (err error) {
 | 
			
		|||
		}
 | 
			
		||||
		cargs = append(cargs, Config.Inputfiles...)
 | 
			
		||||
		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 clang fails it still prints out the AST, so we have to run it
 | 
			
		||||
			// again to get the real error.
 | 
			
		||||
| 
						 | 
				
			
			@ -281,12 +293,14 @@ func Start() (err error) {
 | 
			
		|||
	w := wrap.NewWrapper(Debug)
 | 
			
		||||
	w.Package = Config.Package
 | 
			
		||||
	w.Frameworks = Config.Frameworks
 | 
			
		||||
	w.Libraries = Config.Libraries
 | 
			
		||||
	w.Frameworkdirs = Config.Frameworkdirs
 | 
			
		||||
	w.Import(Config.Imports)
 | 
			
		||||
	w.SysImport(Config.Sysimports)
 | 
			
		||||
	w.Pragmas = Config.Pragma
 | 
			
		||||
	w.Delegate(Config.Delegates)
 | 
			
		||||
	w.Subclass(Config.Subclasses)
 | 
			
		||||
	types.Typesubs = Config.Typesubs
 | 
			
		||||
	if Config.Vaargs == 0 {
 | 
			
		||||
		Config.Vaargs = 16
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -305,7 +319,7 @@ func Start() (err error) {
 | 
			
		|||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if matches(x.Name, autoadd) {
 | 
			
		||||
					Config.Classes = append(Config.Classes,x.Name)
 | 
			
		||||
					Config.Classes = append(Config.Classes, x.Name)
 | 
			
		||||
				}
 | 
			
		||||
			case *ast.ObjCCategoryDecl:
 | 
			
		||||
				w.AddCategory(x)
 | 
			
		||||
| 
						 | 
				
			
			@ -314,7 +328,8 @@ func Start() (err error) {
 | 
			
		|||
					w.AddTypedef(x.Name, x.Type)
 | 
			
		||||
				}
 | 
			
		||||
			case *ast.FunctionDecl:
 | 
			
		||||
				if matches(x.Name, Config.Functions) {
 | 
			
		||||
				if matches(x.Name, Config.Functions) &&
 | 
			
		||||
					!matches(x.Name, Config.FunctionIgnore) {
 | 
			
		||||
					w.AddFunction(x)
 | 
			
		||||
				}
 | 
			
		||||
			case *ast.ObjCProtocolDecl:
 | 
			
		||||
| 
						 | 
				
			
			@ -341,9 +356,18 @@ func main() {
 | 
			
		|||
		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 {
 | 
			
		||||
		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)
 | 
			
		||||
	}
 | 
			
		||||
	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
 | 
			
		||||
//passed to Seq(...)
 | 
			
		||||
func Children(ps ...Parser) Parser {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ import (
 | 
			
		|||
)
 | 
			
		||||
 | 
			
		||||
var Gogc bool
 | 
			
		||||
var Typesubs map[string]string
 | 
			
		||||
 | 
			
		||||
//super is a map recording which class is the parent of each other class
 | 
			
		||||
var super map[string]string
 | 
			
		||||
| 
						 | 
				
			
			@ -201,25 +202,45 @@ func (t *Type) GoType() string {
 | 
			
		|||
	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 {
 | 
			
		||||
	ct = strings.Title(ct)
 | 
			
		||||
	ct = strings.ReplaceAll(ct, " ", "")
 | 
			
		||||
	ct = strings.TrimPrefix(ct, "Struct")
 | 
			
		||||
	ct = swapstars(ct)
 | 
			
		||||
	if len(ct) > 0 && ct[0] == '*' && IsGoInterface(ct[1:]) {
 | 
			
		||||
		return ct
 | 
			
		||||
		return typeSub(ct)
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	if ct == "Id" {
 | 
			
		||||
		ct = "*Id"
 | 
			
		||||
	}
 | 
			
		||||
	if ShouldWrap(ct) {
 | 
			
		||||
		return ct
 | 
			
		||||
		return typeSub(ct)
 | 
			
		||||
	}
 | 
			
		||||
	if len(ct) > 4 && ct[len(ct)-4:len(ct)] == "Void" {
 | 
			
		||||
		ct = ct[:len(ct)-5] + "unsafe.Pointer"
 | 
			
		||||
	}
 | 
			
		||||
	return ct
 | 
			
		||||
	return typeSub(ct)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *Type) CType() string {
 | 
			
		||||
| 
						 | 
				
			
			@ -271,20 +292,32 @@ func (t *Type) GoTypeDecl(fin bool) string {
 | 
			
		|||
type %s = %s
 | 
			
		||||
`, gt, tdgt)
 | 
			
		||||
		}
 | 
			
		||||
		cgt := td.CGoType()
 | 
			
		||||
		eq := ""
 | 
			
		||||
		if len(cgt) > 9 && cgt[:9] == "C.struct_" {
 | 
			
		||||
			//cgt = "C." + cgt[9:]
 | 
			
		||||
			eq = "= "
 | 
			
		||||
		}
 | 
			
		||||
		return fmt.Sprintf(`
 | 
			
		||||
type %s %s
 | 
			
		||||
`, gt, td.CGoType())
 | 
			
		||||
type %s %s%s
 | 
			
		||||
`, gt, eq, cgt)
 | 
			
		||||
	}
 | 
			
		||||
	if Debug {
 | 
			
		||||
		fmt.Printf("  writing GoTypeDecl for %s\n",gt)
 | 
			
		||||
		fmt.Printf("  writing GoTypeDecl for %s\n", gt)
 | 
			
		||||
	}
 | 
			
		||||
	switch gt {
 | 
			
		||||
	case "", "Void":
 | 
			
		||||
		return ""
 | 
			
		||||
	default:
 | 
			
		||||
		cgt := t.CGoType()
 | 
			
		||||
		eq := ""
 | 
			
		||||
		if len(cgt) > 9 && cgt[:9] == "C.struct_" {
 | 
			
		||||
			//cgt = "C." + cgt[9:]
 | 
			
		||||
			eq = "= "
 | 
			
		||||
		}
 | 
			
		||||
		return fmt.Sprintf(`
 | 
			
		||||
type %s %s
 | 
			
		||||
`, gt, t.CGoType())
 | 
			
		||||
type %s %s%s
 | 
			
		||||
`, gt, eq, cgt)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -292,12 +325,12 @@ func (t *Type) GoInterfaceDecl(fin bool) string {
 | 
			
		|||
	ct := t.CType()
 | 
			
		||||
	gt := t.GoType()
 | 
			
		||||
	if Debug {
 | 
			
		||||
		fmt.Printf("  writing GoInterfaceDecl for %s\n",gt)
 | 
			
		||||
		fmt.Printf("  writing GoInterfaceDecl for %s\n", gt)
 | 
			
		||||
	}
 | 
			
		||||
	if gt[0] == '*' {
 | 
			
		||||
		gt = gt[1:] // dereference wrapped types
 | 
			
		||||
		ct = ct[:len(ct)-1]
 | 
			
		||||
		fmt.Printf("  dereferenced %s\n",gt)
 | 
			
		||||
		//fmt.Printf("  dereferenced %s\n", gt)
 | 
			
		||||
	}
 | 
			
		||||
	super := Super(ct)
 | 
			
		||||
	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
 | 
			
		||||
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 {
 | 
			
		||||
		//fmt.Println("nil sent to GoToC")
 | 
			
		||||
		return ""
 | 
			
		||||
| 
						 | 
				
			
			@ -407,7 +440,7 @@ func GoToC(sname, name string, pnames, snames []string, rtype *Type, ptypes []*T
 | 
			
		|||
				rtgt = "*Id"
 | 
			
		||||
			}
 | 
			
		||||
			ret.WriteString(fmt.Sprintf(
 | 
			
		||||
	`ret := &%s{}
 | 
			
		||||
				`ret := &%s{}
 | 
			
		||||
	ret.ptr = unsafe.Pointer(`, rtgt[1:]))
 | 
			
		||||
		case TypedefShouldWrap(rtgt):
 | 
			
		||||
			isptr = true
 | 
			
		||||
| 
						 | 
				
			
			@ -416,7 +449,7 @@ func GoToC(sname, name string, pnames, snames []string, rtype *Type, ptypes []*T
 | 
			
		|||
				rtgt = "*Id"
 | 
			
		||||
			}
 | 
			
		||||
			ret.WriteString(fmt.Sprintf(
 | 
			
		||||
	`ret := &%s{}
 | 
			
		||||
				`ret := &%s{}
 | 
			
		||||
	ret.ptr = unsafe.Pointer(`, rtgt[1:]))
 | 
			
		||||
		default:
 | 
			
		||||
			if rtgt == "BOOL" {
 | 
			
		||||
| 
						 | 
				
			
			@ -444,7 +477,11 @@ func GoToC(sname, name string, pnames, snames []string, rtype *Type, ptypes []*T
 | 
			
		|||
		case TypedefShouldWrap(ptgt) && !pt.Variadic && !fun:
 | 
			
		||||
			p = pn + ".Ptr()"
 | 
			
		||||
		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:
 | 
			
		||||
			p = "unsafe.Pointer(&" + p + ")"
 | 
			
		||||
		case pt.IsPointer() && !fun:
 | 
			
		||||
| 
						 | 
				
			
			@ -472,8 +509,11 @@ func GoToC(sname, name string, pnames, snames []string, rtype *Type, ptypes []*T
 | 
			
		|||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		ptgt := ptypes[i].GoType()
 | 
			
		||||
		if !(len(ptgt) > 2 && ptgt[:1] == "*" && PtrShouldWrap(ptgt[1:])) {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		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)
 | 
			
		||||
		}
 | 
			
		||||
		ptgt = ptgt[2:]
 | 
			
		||||
| 
						 | 
				
			
			@ -482,6 +522,7 @@ func GoToC(sname, name string, pnames, snames []string, rtype *Type, ptypes []*T
 | 
			
		|||
		}
 | 
			
		||||
		dogc := ""
 | 
			
		||||
		if Gogc {
 | 
			
		||||
			goImports["runtime"] = true
 | 
			
		||||
			dogc = fmt.Sprintf(`
 | 
			
		||||
			runtime.SetFinalizer((*%s)[i], func(o *%s) {
 | 
			
		||||
				o.Release()
 | 
			
		||||
| 
						 | 
				
			
			@ -503,12 +544,17 @@ func GoToC(sname, name string, pnames, snames []string, rtype *Type, ptypes []*T
 | 
			
		|||
	if rt != "void" {
 | 
			
		||||
		cmp := ""
 | 
			
		||||
		if sw {
 | 
			
		||||
			ka := ""
 | 
			
		||||
			if !cm {
 | 
			
		||||
				goImports["runtime"] = true
 | 
			
		||||
				ka = "runtime.KeepAlive(o); "
 | 
			
		||||
			}
 | 
			
		||||
			if !cm && sname != "copy" && sname != "mutableCopy" {
 | 
			
		||||
				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(`
 | 
			
		||||
	if ret.ptr == nil { return ret }%s`,cmp))
 | 
			
		||||
	if ret.ptr == nil { %sreturn ret }%s`, ka, cmp))
 | 
			
		||||
		}
 | 
			
		||||
		if fin {
 | 
			
		||||
			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)
 | 
			
		||||
	`, rtgt)
 | 
			
		||||
			}
 | 
			
		||||
			goImports["runtime"] = true
 | 
			
		||||
			ret.WriteString(fmt.Sprintf(`
 | 
			
		||||
	%sruntime.SetFinalizer(ret, func(o %s) {
 | 
			
		||||
		%so.Release()
 | 
			
		||||
	})`, dbg, rtgt, dbg2))
 | 
			
		||||
		}
 | 
			
		||||
		if !cm {
 | 
			
		||||
			goImports["runtime"] = true
 | 
			
		||||
			ret.WriteString(`
 | 
			
		||||
	runtime.KeepAlive(o)`)
 | 
			
		||||
		}
 | 
			
		||||
		ret.WriteString(`
 | 
			
		||||
	return ret`)
 | 
			
		||||
	} else {
 | 
			
		||||
		if !cm {
 | 
			
		||||
			goImports["runtime"] = true
 | 
			
		||||
			ret.WriteString(`
 | 
			
		||||
	runtime.KeepAlive(o)`)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return ret.String()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,8 +72,8 @@ func TestType(t *testing.T) {
 | 
			
		|||
	str = "NSString**"
 | 
			
		||||
	n = &Node{"TypeName", "", []*Node{
 | 
			
		||||
		&Node{"TypedefName", "NSString", []*Node{}},
 | 
			
		||||
			&Node{"Pointer", "*", []*Node{}},
 | 
			
		||||
			&Node{"Pointer", "*", []*Node{}}}}
 | 
			
		||||
		&Node{"Pointer", "*", []*Node{}},
 | 
			
		||||
		&Node{"Pointer", "*", []*Node{}}}}
 | 
			
		||||
	chk_newtype()
 | 
			
		||||
	chk(tp.IsPointer(), true)
 | 
			
		||||
	chk(tp.Typedef(), nil)
 | 
			
		||||
| 
						 | 
				
			
			@ -82,8 +82,8 @@ func TestType(t *testing.T) {
 | 
			
		|||
	str = "NSObject**"
 | 
			
		||||
	n = &Node{"TypeName", "", []*Node{
 | 
			
		||||
		&Node{"TypedefName", "NSObject", []*Node{}},
 | 
			
		||||
			&Node{"Pointer", "*", []*Node{}},
 | 
			
		||||
			&Node{"Pointer", "*", []*Node{}}}}
 | 
			
		||||
		&Node{"Pointer", "*", []*Node{}},
 | 
			
		||||
		&Node{"Pointer", "*", []*Node{}}}}
 | 
			
		||||
	chk_newtype()
 | 
			
		||||
	chk(tp.IsPointer(), true)
 | 
			
		||||
	nsopp := tp
 | 
			
		||||
| 
						 | 
				
			
			@ -272,40 +272,46 @@ func (o *Id) NSString() *NSString {
 | 
			
		|||
	ptypes := []*Type{nsop, nstp, tint, voidpp}
 | 
			
		||||
	pnames := []string{"p1", "p2", "p3", "p4"}
 | 
			
		||||
	snames := []string{"", "", "", ""}
 | 
			
		||||
	goImports := make(map[string]bool)
 | 
			
		||||
 | 
			
		||||
	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("")
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
	chk_gotoc(
 | 
			
		||||
		`ret := (C.myFun(p1.Ptr(), p2.Ptr(), (C.int)(p3), unsafe.Pointer(p4))) != 0
 | 
			
		||||
	runtime.KeepAlive(o)
 | 
			
		||||
	return ret`)
 | 
			
		||||
 | 
			
		||||
	rtype = voidpp
 | 
			
		||||
	chk_gotoc(
 | 
			
		||||
		`ret := (*unsafe.Pointer)(unsafe.Pointer(C.myFun(p1.Ptr(), p2.Ptr(), (C.int)(p3), unsafe.Pointer(p4))))
 | 
			
		||||
	runtime.KeepAlive(o)
 | 
			
		||||
	return ret`)
 | 
			
		||||
 | 
			
		||||
	rtype = nstp
 | 
			
		||||
	chk_gotoc(
 | 
			
		||||
		`ret := &NSString{}
 | 
			
		||||
	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 == o.ptr { return (*NSString)(unsafe.Pointer(o)) }
 | 
			
		||||
	if ret.ptr == nil { runtime.KeepAlive(o); return ret }
 | 
			
		||||
	if ret.ptr == o.ptr { runtime.KeepAlive(o); return (*NSString)(unsafe.Pointer(o)) }
 | 
			
		||||
	runtime.KeepAlive(o)
 | 
			
		||||
	return ret`)
 | 
			
		||||
 | 
			
		||||
	rtype = nsop
 | 
			
		||||
	chk_gotoc(
 | 
			
		||||
		`ret := &Id{}
 | 
			
		||||
	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 == o.ptr { return (*Id)(unsafe.Pointer(o)) }
 | 
			
		||||
	if ret.ptr == nil { runtime.KeepAlive(o); return ret }
 | 
			
		||||
	if ret.ptr == o.ptr { runtime.KeepAlive(o); return (*Id)(unsafe.Pointer(o)) }
 | 
			
		||||
	runtime.KeepAlive(o)
 | 
			
		||||
	return ret`)
 | 
			
		||||
 | 
			
		||||
	ptypes[1].Variadic = true
 | 
			
		||||
| 
						 | 
				
			
			@ -313,8 +319,9 @@ func (o *Id) NSString() *NSString {
 | 
			
		|||
	chk_gotoc(
 | 
			
		||||
		`ret := &Id{}
 | 
			
		||||
	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 == o.ptr { return (*Id)(unsafe.Pointer(o)) }
 | 
			
		||||
	if ret.ptr == nil { runtime.KeepAlive(o); return ret }
 | 
			
		||||
	if ret.ptr == o.ptr { runtime.KeepAlive(o); return (*Id)(unsafe.Pointer(o)) }
 | 
			
		||||
	runtime.KeepAlive(o)
 | 
			
		||||
	return ret`)
 | 
			
		||||
 | 
			
		||||
	ptypes[1].Variadic = false
 | 
			
		||||
| 
						 | 
				
			
			@ -334,8 +341,9 @@ func (o *Id) NSString() *NSString {
 | 
			
		|||
		}
 | 
			
		||||
		(*p2)[i].ptr = p2p[i]
 | 
			
		||||
	}
 | 
			
		||||
	if ret.ptr == nil { return ret }
 | 
			
		||||
	if ret.ptr == o.ptr { return (*Id)(unsafe.Pointer(o)) }
 | 
			
		||||
	if ret.ptr == nil { runtime.KeepAlive(o); return ret }
 | 
			
		||||
	if ret.ptr == o.ptr { runtime.KeepAlive(o); return (*Id)(unsafe.Pointer(o)) }
 | 
			
		||||
	runtime.KeepAlive(o)
 | 
			
		||||
	return ret`)
 | 
			
		||||
	snames[1] = ""
 | 
			
		||||
	snames[2] = "p3p"
 | 
			
		||||
| 
						 | 
				
			
			@ -355,11 +363,12 @@ func (o *Id) NSString() *NSString {
 | 
			
		|||
		}
 | 
			
		||||
		(*p3)[i].ptr = p3p[i]
 | 
			
		||||
	}
 | 
			
		||||
	if ret.ptr == nil { return ret }
 | 
			
		||||
	if ret.ptr == o.ptr { return (*Id)(unsafe.Pointer(o)) }
 | 
			
		||||
	if ret.ptr == nil { runtime.KeepAlive(o); return ret }
 | 
			
		||||
	if ret.ptr == o.ptr { runtime.KeepAlive(o); return (*Id)(unsafe.Pointer(o)) }
 | 
			
		||||
	runtime.KeepAlive(o)
 | 
			
		||||
	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.ptr = unsafe.Pointer(C.myFun(p1.Ptr(), p2.Ptr(), (*unsafe.Pointer)(unsafe.Pointer(&p3p[0])), p4))
 | 
			
		||||
	(*p3) = (*p3)[:cap(*p3)]
 | 
			
		||||
| 
						 | 
				
			
			@ -373,7 +382,8 @@ func (o *Id) NSString() *NSString {
 | 
			
		|||
		}
 | 
			
		||||
		(*p3)[i].ptr = p3p[i]
 | 
			
		||||
	}
 | 
			
		||||
	if ret.ptr == nil { return ret }
 | 
			
		||||
	if ret.ptr == o.ptr { return (*Id)(unsafe.Pointer(o)) }
 | 
			
		||||
	if ret.ptr == nil { runtime.KeepAlive(o); return ret }
 | 
			
		||||
	if ret.ptr == o.ptr { runtime.KeepAlive(o); return (*Id)(unsafe.Pointer(o)) }
 | 
			
		||||
	runtime.KeepAlive(o)
 | 
			
		||||
	return ret`)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -112,11 +112,27 @@ func ArrayDeclarator(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)),
 | 
			
		||||
		ZeroOrMore(Attribute),
 | 
			
		||||
	))(s, n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Attribute(s string, n *Node) (string, *Node) {
 | 
			
		||||
	return Seq(
 | 
			
		||||
		Word("__attribute__"),
 | 
			
		||||
		ChildOf(NewNode("parens"), Parenthesized(Parenthesized(
 | 
			
		||||
			Attr,
 | 
			
		||||
		))),
 | 
			
		||||
	)(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) {
 | 
			
		||||
	return OneOf(
 | 
			
		||||
		ParenAbstractDeclarator,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										458
									
								
								wrap/main.go
									
									
									
									
									
								
							
							
						
						
									
										458
									
								
								wrap/main.go
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user