1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
// RUN: %empty-directory(%t)
// RUN: %target-build-swift %s -o %t/a.out
// RUN: %target-codesign %t/a.out
// RUN: %target-run %t/a.out | %FileCheck %s
// REQUIRES: executable_test
// REQUIRES: objc_interop
import Foundation
#if canImport(AppKit)
import AppKit
typealias XXColor = NSColor
#elseif canImport(UIKit)
import UIKit
typealias XXColor = UIColor
#else
#error("Unsupported platform")
#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)
|