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 | ||||||
|  |  | ||||||
|  | @ -46,7 +46,7 @@ func main() { | ||||||
| 	fmt.Printf("\nNSArray.ObjectEnumerator().ForIn():\n") | 	fmt.Printf("\nNSArray.ObjectEnumerator().ForIn():\n") | ||||||
| 	x := 0 | 	x := 0 | ||||||
| 	a.ObjectEnumerator().ForIn(func(o *ns.Id) bool { | 	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++ | 		x++ | ||||||
| 		return true | 		return true | ||||||
| 	}) | 	}) | ||||||
|  | @ -72,7 +72,7 @@ func main() { | ||||||
| 		} | 		} | ||||||
| 		return true | 		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") | 	fmt.Printf("\nNSArrayWithObjects() (length 1)\n") | ||||||
| 	a2 = ns.NSArrayWithObjects(n1) | 	a2 = ns.NSArrayWithObjects(n1) | ||||||
| 	a2.ObjectEnumerator().ForIn(func(o *ns.Id) bool { | 	a2.ObjectEnumerator().ForIn(func(o *ns.Id) bool { | ||||||
|  | @ -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()) | ||||||
|  | @ -119,11 +119,11 @@ func main() { | ||||||
| 	err := make([]*ns.NSError, 1) | 	err := make([]*ns.NSError, 1) | ||||||
| 	n1 = ns.NSStringWithContentsOfURLEncoding(ns.NSURLWithGoString("http://captive.apple.com"), ns.NSUTF8StringEncoding, &err) | 	n1 = ns.NSStringWithContentsOfURLEncoding(ns.NSURLWithGoString("http://captive.apple.com"), ns.NSUTF8StringEncoding, &err) | ||||||
| 	if len(err) == 0 { | 	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) | 	n1 = ns.NSStringWithContentsOfURLEncoding(ns.NSURLWithGoString("htttypo://example.com"), ns.NSUTF8StringEncoding, &err) | ||||||
| 	if len(err) > 0 { | 	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()) | 		fmt.Printf("err: %s\n", err[0].LocalizedDescription()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -137,26 +137,26 @@ func main() { | ||||||
| 	fmt.Printf("\nArrayWithObjects\n") | 	fmt.Printf("\nArrayWithObjects\n") | ||||||
| 	a2 = ns.NSArrayWithObjects(gs1, gs2) | 	a2 = ns.NSArrayWithObjects(gs1, gs2) | ||||||
| 	a2.ObjectEnumerator().ForIn(func(o *ns.Id) bool { | 	a2.ObjectEnumerator().ForIn(func(o *ns.Id) bool { | ||||||
| 		fmt.Printf("--%s\n",o.NSString()) | 		fmt.Printf("--%s\n", o.NSString()) | ||||||
| 		return true | 		return true | ||||||
| 	}) | 	}) | ||||||
| 	dir,e := os.Getwd() | 	dir, e := os.Getwd() | ||||||
| 	if e != nil { | 	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) | 		os.Exit(-1) | ||||||
| 	} | 	} | ||||||
| 	path := nst(dir) | 	path := nst(dir) | ||||||
| 	filter := ns.NSArrayWithObjects(nst("ast"),nst("yaml")) | 	filter := ns.NSArrayWithObjects(nst("ast"), nst("yaml")) | ||||||
| 	ost := make([]*ns.NSString,0,1) | 	ost := make([]*ns.NSString, 0, 1) | ||||||
| 	oar:= make([]*ns.NSArray,0,1) | 	oar := make([]*ns.NSArray, 0, 1) | ||||||
| 	fmt.Printf("\nCompletePathIntoString()\n") | 	fmt.Printf("\nCompletePathIntoString()\n") | ||||||
| 	i := path.CompletePathIntoString(&ost,0,&oar,filter) | 	i := path.CompletePathIntoString(&ost, 0, &oar, filter) | ||||||
| 	fmt.Printf("%d matches\n",i) | 	fmt.Printf("%d matches\n", i) | ||||||
| 	if i > 0 { | 	if i > 0 { | ||||||
| 		fmt.Printf("ost = %s\n",ost[0]) | 		fmt.Printf("ost = %s\n", ost[0]) | ||||||
| 		fmt.Printf("oar =\n") | 		fmt.Printf("oar =\n") | ||||||
| 		oar[0].ObjectEnumerator().ForIn(func(o *ns.Id) bool { | 		oar[0].ObjectEnumerator().ForIn(func(o *ns.Id) bool { | ||||||
| 			fmt.Printf("--%s\n",o.NSString()) | 			fmt.Printf("--%s\n", o.NSString()) | ||||||
| 			return true | 			return true | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -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,25 +2,24 @@ 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() { | ||||||
| 	var s ns.Stat | 	var s ns.Stat | ||||||
| 	ns.Puts(ns.CharWithGoString("Hi there")) | 	ns.Puts(ns.CharWithGoString("Hi there")) | ||||||
| 	ret := ns.Fstat(3,&s) | 	ret := ns.Fstat(3, &s) | ||||||
| 	fmt.Printf("Fstat: %d\n",ret) | 	fmt.Printf("Fstat: %d\n", ret) | ||||||
| 
 | 
 | ||||||
| 	fmt.Printf("Opening file\n") | 	fmt.Printf("Opening file\n") | ||||||
| 	f := ns.Fopen(ns.CharWithGoString("nswrap.yaml"),ns.CharWithGoString("r")) | 	f := ns.Fopen(ns.CharWithGoString("nswrap.yaml"), ns.CharWithGoString("r")) | ||||||
| 	ret = ns.Fstat(3,&s) | 	ret = ns.Fstat(3, &s) | ||||||
| 	fmt.Printf("Fstat: %d\n",ret) | 	fmt.Printf("Fstat: %d\n", ret) | ||||||
| 	chr := make([]byte,4096) | 	chr := make([]byte, 4096) | ||||||
| 	i := ns.Fread(unsafe.Pointer(&chr[0]), 1, 4096, f) | 	i := ns.Fread(unsafe.Pointer(&chr[0]), 1, 4096, f) | ||||||
| 	if i < 4096 { | 	if i < 4096 { | ||||||
| 		chr = chr[:i] | 		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: | 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
 | ||||||
| 	} | 	} | ||||||
|  | @ -19,7 +19,7 @@ func releaseX(x int) func (ns.MyClassSupermethods) { | ||||||
| func memtest1() { | func memtest1() { | ||||||
| 	fmt.Println("memtest1 started") | 	fmt.Println("memtest1 started") | ||||||
| 	for { | 	for { | ||||||
| 		arr := make([]*ns.MyClass,1000) | 		arr := make([]*ns.MyClass, 1000) | ||||||
| 		for i := 0; i < 1000; i++ { | 		for i := 0; i < 1000; i++ { | ||||||
| 			// Alloc methods set a finalizer that causes the Go GC to
 | 			// Alloc methods set a finalizer that causes the Go GC to
 | ||||||
| 			// Release these objects.
 | 			// Release these objects.
 | ||||||
|  | @ -33,7 +33,7 @@ func memtest1() { | ||||||
| 		// Manually run the Go GC at every loop iteration. May not be needed
 | 		// Manually run the Go GC at every loop iteration. May not be needed
 | ||||||
| 		// in a real program.
 | 		// in a real program.
 | ||||||
| 		runtime.GC() | 		runtime.GC() | ||||||
| 		time.Sleep(time.Second/50) | 		time.Sleep(time.Second / 50) | ||||||
| 		//fmt.Printf("Loop complete\n")
 | 		//fmt.Printf("Loop complete\n")
 | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | @ -42,8 +42,8 @@ func memtest2() { | ||||||
| 	fmt.Println("memtest2 started") | 	fmt.Println("memtest2 started") | ||||||
| 	i := 0 | 	i := 0 | ||||||
| 	for { | 	for { | ||||||
| 		o1 := ns.NSStringAlloc().InitWithGoString(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)) | 		o2 := ns.NSStringWithGoString(fmt.Sprintf("two string %d", i)) | ||||||
| 
 | 
 | ||||||
| 		// NSWrap runs object constructors inside an @autoreleasepool block,
 | 		// NSWrap runs object constructors inside an @autoreleasepool block,
 | ||||||
| 		// and then calls "retain" on them before returning to Go. A Go
 | 		// 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 methods in Objective-C always return a retained object.
 | ||||||
| 		// init may or may not return the same object that was sent in.
 | 		// 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.
 | 		// you can always nest alloc and init.
 | ||||||
| 
 | 
 | ||||||
|  | @ -74,7 +74,7 @@ func memtest2() { | ||||||
| 		_ = a3 | 		_ = a3 | ||||||
| 
 | 
 | ||||||
| 		runtime.GC() | 		runtime.GC() | ||||||
| 		time.Sleep(time.Second/50) | 		time.Sleep(time.Second / 50) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -121,7 +121,7 @@ func memtest4() { | ||||||
| 		_ = o1 | 		_ = o1 | ||||||
| 		_ = c1 | 		_ = c1 | ||||||
| 		runtime.GC() | 		runtime.GC() | ||||||
| 		time.Sleep(time.Second/50) | 		time.Sleep(time.Second / 50) | ||||||
| 		c1.Free() // you need to manually free UTF8Strings
 | 		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
 | 		// a new NSString object at each loop iteration and cannot be reusing
 | ||||||
| 		// the same string object.
 | 		// 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,
 | 		// SubstringFromIndex should be returning a newly allocated NSString,
 | ||||||
| 		// which is getting retained by NSWrap and released by a Go GC
 | 		// which is getting retained by NSWrap and released by a Go GC
 | ||||||
|  | @ -146,7 +146,7 @@ func memtest5() { | ||||||
| 		u := sub.UTF8String() | 		u := sub.UTF8String() | ||||||
| 		u2 := sub2.UTF8String() | 		u2 := sub2.UTF8String() | ||||||
| 		u3 := sub3.UTF8String() | 		u3 := sub3.UTF8String() | ||||||
| 		time.Sleep(time.Second/50) | 		time.Sleep(time.Second / 50) | ||||||
| 		runtime.GC() | 		runtime.GC() | ||||||
| 		i++ | 		i++ | ||||||
| 		u.Free() | 		u.Free() | ||||||
|  | @ -160,30 +160,29 @@ func memtest5() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func tmpdict(i int) *ns.NSString { | func tmpdict(i int) *ns.NSString { | ||||||
| 	o1 := ns.NSStringWithGoString(fmt.Sprintf("temp string 1-%d",i)) | 	o1 := ns.NSStringWithGoString(fmt.Sprintf("temp string 1-%d", i)) | ||||||
| 	o2 := ns.NSStringWithGoString(fmt.Sprintf("temp string 2-%d",i)) | 	o2 := ns.NSStringWithGoString(fmt.Sprintf("temp string 2-%d", i)) | ||||||
| 	k1 := ns.NSStringWithGoString(fmt.Sprintf("temp key 1-%d",i)) | 	k1 := ns.NSStringWithGoString(fmt.Sprintf("temp key 1-%d", i)) | ||||||
| 	k2 := ns.NSStringWithGoString(fmt.Sprintf("temp key 2-%d",i)) | 	k2 := ns.NSStringWithGoString(fmt.Sprintf("temp key 2-%d", i)) | ||||||
| 	dict := ns.NSDictionaryWithObjectsAndKeys(o1,k1,o2,k2) | 	dict := ns.NSDictionaryWithObjectsAndKeys(o1, k1, o2, k2) | ||||||
| 	ret := dict.ValueForKey(k1) | 	ret := dict.ValueForKey(k1) | ||||||
| 	//fmt.Printf("tmpdict(): string = %s\n",ret.NSString())
 | 	//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()
 | 	return ret.NSString() // should be retained by NSDictionary.ValueForKey()
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func tmparr(i int) *ns.NSString { | func tmparr(i int) *ns.NSString { | ||||||
| 	o1 := ns.NSStringWithGoString(fmt.Sprintf("temp string 3-%d",i)) | 	o1 := ns.NSStringWithGoString(fmt.Sprintf("temp string 3-%d", i)) | ||||||
| 	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 | ||||||
|  | @ -193,13 +192,13 @@ func memtest6() { | ||||||
| 		time.Sleep(time.Second / 5) | 		time.Sleep(time.Second / 5) | ||||||
| 		u1 := s1.String() // make sure s1 and s2 are still available
 | 		u1 := s1.String() // make sure s1 and s2 are still available
 | ||||||
| 		u2 := s2.String() | 		u2 := s2.String() | ||||||
| 		e1 := fmt.Sprintf("temp string 1-%d",i) | 		e1 := fmt.Sprintf("temp string 1-%d", i) | ||||||
| 		if u1 != e1 { | 		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 { | 		if u2 != e2 { | ||||||
| 			fmt.Printf("tmparr() error: %s != %s\n",u2,e2) | 			fmt.Printf("tmparr() error: %s != %s\n", u2, e2) | ||||||
| 
 | 
 | ||||||
| 		} | 		} | ||||||
| 		i++ | 		i++ | ||||||
|  | @ -221,7 +220,7 @@ func main() { | ||||||
| 	go func() { | 	go func() { | ||||||
| 		for { | 		for { | ||||||
| 			// print a progress indicator
 | 			// print a progress indicator
 | ||||||
| 			fmt.Printf("t = %s\n",time.Now()) | 			fmt.Printf("t = %s\n", time.Now()) | ||||||
| 			time.Sleep(time.Second * 10) | 			time.Sleep(time.Second * 10) | ||||||
| 		} | 		} | ||||||
| 	}() | 	}() | ||||||
|  |  | ||||||
|  | @ -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
 | ||||||
| } | } | ||||||
|  | @ -92,19 +92,19 @@ func memtest3() { | ||||||
| 		ns.Autoreleasepool(func() { | 		ns.Autoreleasepool(func() { | ||||||
| 			arr := ns.NSMutableArrayAlloc().Init() | 			arr := ns.NSMutableArrayAlloc().Init() | ||||||
| 			arr.Autorelease() | 			arr.Autorelease() | ||||||
| 			arr.AddObject(ns.NSStringWithGoString(fmt.Sprintf("my string %d",i))) | 			arr.AddObject(ns.NSStringWithGoString(fmt.Sprintf("my string %d", i))) | ||||||
| 			s1 := ns.NSStringWithGoString(fmt.Sprintf("my other string %d",i)) | 			s1 := ns.NSStringWithGoString(fmt.Sprintf("my other string %d", i)) | ||||||
| 			fmt.Printf("%s\n",arr.ObjectAtIndex(0).NSString()) | 			fmt.Printf("%s\n", arr.ObjectAtIndex(0).NSString()) | ||||||
| 			_ = s1 | 			_ = s1 | ||||||
| 
 | 
 | ||||||
| 			for x := 0; x < 3; x++ { | 			for x := 0; x < 3; x++ { | ||||||
| 				ns.Autoreleasepool(func() { | 				ns.Autoreleasepool(func() { | ||||||
| 					str := arr.ObjectAtIndex(0).NSString() | 					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 / 5) | ||||||
| 				}) | 				}) | ||||||
| 			} | 			} | ||||||
| 			time.Sleep(time.Second/2) | 			time.Sleep(time.Second / 2) | ||||||
| 			i++ | 			i++ | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -26,21 +26,21 @@ func incr() func(bool) (int, float64) { | ||||||
| 		if b == 0 { | 		if b == 0 { | ||||||
| 			return i, 0.0 | 			return i, 0.0 | ||||||
| 		} else { | 		} else { | ||||||
| 			return i, (b/float64(i)) * 100 | 			return i, (b / float64(i)) * 100 | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type tracker struct { | type tracker struct { | ||||||
| 	add, drop func(*ns.Id) | 	add, drop func(*ns.Id) | ||||||
| 	check func() | 	check     func() | ||||||
| 	i func(bool) (int, float64) | 	i         func(bool) (int, float64) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type record struct { | type record struct { | ||||||
| 	ptr unsafe.Pointer | 	ptr   unsafe.Pointer | ||||||
| 	goPtr *ns.Id | 	goPtr *ns.Id | ||||||
| 	when time.Time | 	when  time.Time | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func newTracker() (func(*ns.Id), func(*ns.Id), func()) { | func newTracker() (func(*ns.Id), func(*ns.Id), func()) { | ||||||
|  | @ -54,35 +54,35 @@ func newTracker() (func(*ns.Id), func(*ns.Id), func()) { | ||||||
| 			select { | 			select { | ||||||
| 			case x := <-addch: | 			case x := <-addch: | ||||||
| 				mux.Lock() | 				mux.Lock() | ||||||
| 					data = append(data,record{ | 				data = append(data, record{ | ||||||
| 						x.Ptr(), | 					x.Ptr(), | ||||||
| 						x, | 					x, | ||||||
| 						time.Now(), | 					time.Now(), | ||||||
| 					}) | 				}) | ||||||
| 				mux.Unlock() | 				mux.Unlock() | ||||||
| 			case x := <-dropch: | 			case x := <-dropch: | ||||||
| 				mux.Lock() | 				mux.Lock() | ||||||
| 					data = append(data,record{ | 				data = append(data, record{ | ||||||
| 						nil, | 					nil, | ||||||
| 						x, | 					x, | ||||||
| 						time.Now(), | 					time.Now(), | ||||||
| 					}) | 				}) | ||||||
| 				mux.Unlock() | 				mux.Unlock() | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	}() | 	}() | ||||||
| 
 | 
 | ||||||
| 	add := func(x *ns.Id) { | 	add := func(x *ns.Id) { | ||||||
| 		addch<- x | 		addch <- x | ||||||
| 	} | 	} | ||||||
| 	drop := func(x *ns.Id) { | 	drop := func(x *ns.Id) { | ||||||
| 		dropch<- x | 		dropch <- x | ||||||
| 	} | 	} | ||||||
| 	check := func() { | 	check := func() { | ||||||
| 		live := map[unsafe.Pointer]*ns.Id{} | 		live := map[unsafe.Pointer]*ns.Id{} | ||||||
| 		bad := false | 		bad := false | ||||||
| 		mux.Lock() | 		mux.Lock() | ||||||
| 		for _,r := range data { | 		for _, r := range data { | ||||||
| 			if r.ptr != nil { | 			if r.ptr != nil { | ||||||
| 				if live[r.ptr] != nil { | 				if live[r.ptr] != nil { | ||||||
| 					fmt.Printf("COLLISION: %p & %p -> %p\n", r.goPtr, live[r.ptr], r.ptr) | 					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 | 				live[r.ptr] = r.goPtr | ||||||
| 			} else { | 			} 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 { | 		if bad { | ||||||
| 			fmt.Printf("failed\n") | 			fmt.Printf("failed\n") | ||||||
| 		} else { | 		} else { | ||||||
|  | @ -101,25 +101,25 @@ func newTracker() (func(*ns.Id), func(*ns.Id), func()) { | ||||||
| 		} | 		} | ||||||
| 		mux.Unlock() | 		mux.Unlock() | ||||||
| 	} | 	} | ||||||
| 	return add,drop,check | 	return add, drop, check | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func mkstrings(t tracker) { | func mkstrings(t tracker) { | ||||||
| 	for { | 	for { | ||||||
| 		//fmt.Printf("main thread: %t\n",ns.NSThreadIsMainThread())
 | 		//fmt.Printf("main thread: %t\n",ns.NSThreadIsMainThread())
 | ||||||
| 		x,b := t.i(false) | 		x, b := t.i(false) | ||||||
| 		str := fmt.Sprintf("string %d",x) | 		str := fmt.Sprintf("string %d", x) | ||||||
| 		s := ns.NSStringWithGoString(str) | 		s := ns.NSStringWithGoString(str) | ||||||
| 		//t.add(&s.Id)
 | 		//t.add(&s.Id)
 | ||||||
| 		for j := 0; j < 10; j++ { | 		for j := 0; j < 10; j++ { | ||||||
| 			sout := s.String() | 			sout := s.String() | ||||||
| 			if str != sout { | 			if str != sout { | ||||||
| 				_,b = t.i(true) | 				_, b = t.i(true) | ||||||
| 				fmt.Printf("%3.2f%% -- %d: '%s' '%s'\n", b, x, str, sout) | 				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")) | 			fmt.Printf("%3.2f%% -- %s\n", b, time.Now().Format("03:04:05.000")) | ||||||
| 		} | 		} | ||||||
| 		//t.drop(&s.Id)
 | 		//t.drop(&s.Id)
 | ||||||
|  | @ -145,7 +145,7 @@ func main() { | ||||||
| 	go func() { | 	go func() { | ||||||
| 		for { | 		for { | ||||||
| 			runtime.GC() | 			runtime.GC() | ||||||
| 			time.Sleep(time.Second/100) | 			time.Sleep(time.Second / 100) | ||||||
| 		} | 		} | ||||||
| 	}() | 	}() | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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.
										
									
								
							
							
								
								
									
										66
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								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" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -26,22 +29,26 @@ var autoadd = []string{ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type conf struct { | type conf struct { | ||||||
| 	Positions     bool | 	Positions      bool | ||||||
| 	Package       string | 	Package        string | ||||||
| 	Inputfiles    []string | 	Inputfiles     []string | ||||||
| 	Astfile       string | 	Astfile        string | ||||||
| 	Debugast      bool | 	Debugast       bool | ||||||
| 	Classes       []string | 	Classes        []string | ||||||
| 	Functions     []string | 	Functions      []string | ||||||
| 	Enums         []string | 	FunctionIgnore []string | ||||||
| 	Delegates     map[string]map[string][]string | 	Enums          []string | ||||||
| 	Subclasses    map[string]map[string][]string | 	Delegates      map[string]map[string][]string | ||||||
| 	Frameworks    []string | 	Subclasses     map[string]map[string][]string | ||||||
| 	Frameworkdirs []string | 	Frameworks     []string | ||||||
| 	Imports       []string | 	Libraries      []string | ||||||
| 	Sysimports    []string | 	Frameworkdirs  []string | ||||||
| 	Pragma        []string | 	Imports        []string | ||||||
| 	Vaargs        int | 	Sysimports     []string | ||||||
|  | 	Pragma         []string | ||||||
|  | 	Typesubs       map[string]string | ||||||
|  | 	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 | ||||||
| 	} | 	} | ||||||
|  | @ -305,7 +319,7 @@ func Start() (err error) { | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				if matches(x.Name, autoadd) { | 				if matches(x.Name, autoadd) { | ||||||
| 					Config.Classes = append(Config.Classes,x.Name) | 					Config.Classes = append(Config.Classes, x.Name) | ||||||
| 				} | 				} | ||||||
| 			case *ast.ObjCCategoryDecl: | 			case *ast.ObjCCategoryDecl: | ||||||
| 				w.AddCategory(x) | 				w.AddCategory(x) | ||||||
|  | @ -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,20 +292,32 @@ 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) | ||||||
| 	} | 	} | ||||||
| 	switch gt { | 	switch gt { | ||||||
| 	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) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -292,12 +325,12 @@ func (t *Type) GoInterfaceDecl(fin bool) string { | ||||||
| 	ct := t.CType() | 	ct := t.CType() | ||||||
| 	gt := t.GoType() | 	gt := t.GoType() | ||||||
| 	if Debug { | 	if Debug { | ||||||
| 		fmt.Printf("  writing GoInterfaceDecl for %s\n",gt) | 		fmt.Printf("  writing GoInterfaceDecl for %s\n", gt) | ||||||
| 	} | 	} | ||||||
| 	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 "" | ||||||
|  | @ -407,7 +440,7 @@ func GoToC(sname, name string, pnames, snames []string, rtype *Type, ptypes []*T | ||||||
| 				rtgt = "*Id" | 				rtgt = "*Id" | ||||||
| 			} | 			} | ||||||
| 			ret.WriteString(fmt.Sprintf( | 			ret.WriteString(fmt.Sprintf( | ||||||
| 	`ret := &%s{} | 				`ret := &%s{} | ||||||
| 	ret.ptr = unsafe.Pointer(`, rtgt[1:])) | 	ret.ptr = unsafe.Pointer(`, rtgt[1:])) | ||||||
| 		case TypedefShouldWrap(rtgt): | 		case TypedefShouldWrap(rtgt): | ||||||
| 			isptr = true | 			isptr = true | ||||||
|  | @ -416,7 +449,7 @@ func GoToC(sname, name string, pnames, snames []string, rtype *Type, ptypes []*T | ||||||
| 				rtgt = "*Id" | 				rtgt = "*Id" | ||||||
| 			} | 			} | ||||||
| 			ret.WriteString(fmt.Sprintf( | 			ret.WriteString(fmt.Sprintf( | ||||||
| 	`ret := &%s{} | 				`ret := &%s{} | ||||||
| 	ret.ptr = unsafe.Pointer(`, rtgt[1:])) | 	ret.ptr = unsafe.Pointer(`, rtgt[1:])) | ||||||
| 		default: | 		default: | ||||||
| 			if rtgt == "BOOL" { | 			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: | 		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,8 +509,11 @@ 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) | ||||||
| 		} | 		} | ||||||
| 		ptgt = ptgt[2:] | 		ptgt = ptgt[2:] | ||||||
|  | @ -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() | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -72,8 +72,8 @@ func TestType(t *testing.T) { | ||||||
| 	str = "NSString**" | 	str = "NSString**" | ||||||
| 	n = &Node{"TypeName", "", []*Node{ | 	n = &Node{"TypeName", "", []*Node{ | ||||||
| 		&Node{"TypedefName", "NSString", []*Node{}}, | 		&Node{"TypedefName", "NSString", []*Node{}}, | ||||||
| 			&Node{"Pointer", "*", []*Node{}}, | 		&Node{"Pointer", "*", []*Node{}}, | ||||||
| 			&Node{"Pointer", "*", []*Node{}}}} | 		&Node{"Pointer", "*", []*Node{}}}} | ||||||
| 	chk_newtype() | 	chk_newtype() | ||||||
| 	chk(tp.IsPointer(), true) | 	chk(tp.IsPointer(), true) | ||||||
| 	chk(tp.Typedef(), nil) | 	chk(tp.Typedef(), nil) | ||||||
|  | @ -82,8 +82,8 @@ func TestType(t *testing.T) { | ||||||
| 	str = "NSObject**" | 	str = "NSObject**" | ||||||
| 	n = &Node{"TypeName", "", []*Node{ | 	n = &Node{"TypeName", "", []*Node{ | ||||||
| 		&Node{"TypedefName", "NSObject", []*Node{}}, | 		&Node{"TypedefName", "NSObject", []*Node{}}, | ||||||
| 			&Node{"Pointer", "*", []*Node{}}, | 		&Node{"Pointer", "*", []*Node{}}, | ||||||
| 			&Node{"Pointer", "*", []*Node{}}}} | 		&Node{"Pointer", "*", []*Node{}}}} | ||||||
| 	chk_newtype() | 	chk_newtype() | ||||||
| 	chk(tp.IsPointer(), true) | 	chk(tp.IsPointer(), true) | ||||||
| 	nsopp := tp | 	nsopp := tp | ||||||
|  | @ -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, | ||||||
|  |  | ||||||
							
								
								
									
										456
									
								
								wrap/main.go
									
									
									
									
									
								
							
							
						
						
									
										456
									
								
								wrap/main.go
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user