blob: c295c140f36341ee8231eb58242804d0b5ad0041 [file] [log] [blame]
// RUN: %empty-directory(%t)
// RUN: %target-build-swift %s -o %t/a.out
// RUN: %target-run %t/a.out | %FileCheck %s
// REQUIRES: executable_test
// REQUIRES: objc_interop
import Foundation
#if os(macOS)
import AppKit
typealias XXColor = NSColor
#endif
#if os(iOS) || os(tvOS) || os(watchOS)
import UIKit
typealias XXColor = UIColor
#endif
// Exercise some common APIs that make use of C pointer arguments.
//
// Typed C pointers
//
let rgb = CGColorSpaceCreateDeviceRGB()
let cgRed = CGColor(colorSpace: rgb, components: [1.0, 0.0, 0.0, 1.0])!
let nsRed = XXColor(cgColor: cgRed)
var r: CGFloat = 0.5, g: CGFloat = 0.5, b: CGFloat = 0.5, a: CGFloat = 0.5
#if os(macOS)
nsRed!.getRed(&r, green: &g, blue: &b, alpha: &a)
#else
nsRed.getRed(&r, green: &g, blue: &b, alpha: &a)
#endif
// CHECK-LABEL: Red is:
print("Red is:")
print("<\(r) \(g) \(b) \(a)>") // CHECK-NEXT: <1.0 0.0 0.0 1.0>
//
// Void C pointers
//
// FIXME: Array type annotation should not be required
let data = NSData(bytes: [1.5, 2.25, 3.125] as [Double],
length: MemoryLayout<Double>.size * 3)
var fromData = [0.25, 0.25, 0.25]
let notFromData = fromData
data.getBytes(&fromData, length: MemoryLayout<Double>.size * 3)
// CHECK-LABEL: Data is:
print("Data is:")
print(fromData[0]) // CHECK-NEXT: 1.5
print(fromData[1]) // CHECK-NEXT: 2.25
print(fromData[2]) // CHECK-NEXT: 3.125
// CHECK-LABEL: Independent data is:
print("Independent data is:")
print(notFromData[0]) // CHECK-NEXT: 0.25
print(notFromData[1]) // CHECK-NEXT: 0.25
print(notFromData[2]) // CHECK-NEXT: 0.25
//
// ObjC pointers
//
class Canary: NSObject {
deinit {
print("died")
}
}
var CanaryAssocObjectHandle: UInt8 = 0
// Attach an associated object with a loud deinit so we can see that the
// error died.
func hangCanary(_ o: AnyObject) {
objc_setAssociatedObject(o, &CanaryAssocObjectHandle, Canary(),
.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
// CHECK-LABEL: NSError out:
print("NSError out:")
autoreleasepool {
do {
let s = try NSString(contentsOfFile: "/hopefully/does/not/exist\u{1B}",
encoding: String.Encoding.utf8.rawValue)
_preconditionFailure("file should not actually exist")
} catch {
print(error._code) // CHECK-NEXT: 260
hangCanary(error as NSError)
}
}
// The result error should have died with the autorelease pool
// CHECK-NEXT: died
class DumbString: NSString {
override func character(at x: Int) -> unichar { _preconditionFailure("nope") }
override var length: Int { return 0 }
convenience init(contentsOfFile s: String, encoding: String.Encoding) throws {
self.init()
throw NSError(domain: "Malicious Mischief", code: 594, userInfo: nil)
}
}
// CHECK-LABEL: NSError in:
print("NSError in:")
autoreleasepool {
do {
try DumbString(contentsOfFile: "foo", encoding: .utf8)
} catch {
print(error._domain) // CHECK-NEXT: Malicious Mischief
print(error._code) // CHECK-NEXT: 594
hangCanary(error as NSError)
}
}
// The result error should have died with the autorelease pool
// CHECK-NEXT: died
let s = "Hello World"
puts(s)
// CHECK-NEXT: Hello World
//
// C function pointers
//
var unsorted = [3, 14, 15, 9, 2, 6, 5]
qsort(&unsorted, unsorted.count, MemoryLayout.size(ofValue: unsorted[0])) { a, b in
return Int32(a!.load(as: Int.self) - b!.load(as: Int.self))
}
// CHECK-NEXT: [2, 3, 5, 6, 9, 14, 15]
print(unsorted)