diff --git a/CoreFoundation/Base.subproj/CFInternal.h b/CoreFoundation/Base.subproj/CFInternal.h index ccc58ee68f..a504aff3ca 100644 --- a/CoreFoundation/Base.subproj/CFInternal.h +++ b/CoreFoundation/Base.subproj/CFInternal.h @@ -216,7 +216,7 @@ extern void __CFGenericValidateType_(CFTypeRef cf, CFTypeID type, const char *fu #define __CFBitfield64GetValue(V, N1, N2) (((V) & __CFBitfield64Mask(N1, N2)) >> (N2)) #define __CFBitfield64SetValue(V, N1, N2, X) ((V) = ((V) & ~__CFBitfield64Mask(N1, N2)) | ((((uint64_t)X) << (N2)) & __CFBitfield64Mask(N1, N2))) -#if __LP64__ +#if __LP64__ || DEPLOYMENT_TARGET_ANDROID typedef uint64_t __CFInfoType; #define __CFInfoMask(N1, N2) __CFBitfield64Mask(N1, N2) #else diff --git a/CoreFoundation/Base.subproj/CFKnownLocations.c b/CoreFoundation/Base.subproj/CFKnownLocations.c index 2da610b213..e998e80803 100644 --- a/CoreFoundation/Base.subproj/CFKnownLocations.c +++ b/CoreFoundation/Base.subproj/CFKnownLocations.c @@ -45,7 +45,7 @@ CFURLRef _Nullable _CFKnownLocationCreatePreferencesURLForUser(CFKnownLocationUs } } -#elif !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS +#elif !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS && !DEPLOYMENT_TARGET_ANDROID /* Building for an OS that uses the FHS, BSD's hier(7), and/or the XDG specification for paths: diff --git a/CoreFoundation/Base.subproj/CFPlatform.c b/CoreFoundation/Base.subproj/CFPlatform.c index 52363ea6c2..97b7d1222e 100644 --- a/CoreFoundation/Base.subproj/CFPlatform.c +++ b/CoreFoundation/Base.subproj/CFPlatform.c @@ -297,6 +297,9 @@ CF_EXPORT CFStringRef CFCopyFullUserName(void) { uid_t euid; __CFGetUGIDs(&euid, NULL); struct passwd *upwd = getpwuid(euid ? euid : getuid()); +#if DEPLOYMENT_TARGET_ANDROID +#define pw_gecos pw_name +#endif if (upwd && upwd->pw_gecos) { result = CFStringCreateWithCString(kCFAllocatorSystemDefault, upwd->pw_gecos, kCFPlatformInterfaceStringEncoding); } diff --git a/CoreFoundation/Base.subproj/CFUtilities.c b/CoreFoundation/Base.subproj/CFUtilities.c index 03f7b8c3b1..c7f90cc65d 100644 --- a/CoreFoundation/Base.subproj/CFUtilities.c +++ b/CoreFoundation/Base.subproj/CFUtilities.c @@ -1000,6 +1000,7 @@ void CFLog1(CFLogLevel lev, CFStringRef message) { CFStringGetCString(message, buffer, maxLength, encoding); __android_log_print(priority, tag, "%s", buffer); + fprintf(stderr, "%s\n", buffer); if (buffer != &stack_buffer[0]) free(buffer); #else diff --git a/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h b/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h index 494c3dd45b..cfd376ab9c 100644 --- a/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h +++ b/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h @@ -403,6 +403,8 @@ static inline _Bool _withStackOrHeapBuffer(size_t amount, void (__attribute__((n static inline int _direntNameLength(struct dirent *entry) { #ifdef _D_EXACT_NAMLEN // defined on Linux return _D_EXACT_NAMLEN(entry); +#elif DEPLOYMENT_TARGET_ANDROID + return strlen(entry->d_name); #else return entry->d_namlen; #endif diff --git a/CoreFoundation/NumberDate.subproj/CFTimeZone.c b/CoreFoundation/NumberDate.subproj/CFTimeZone.c index 34ce79dc82..541af2c303 100644 --- a/CoreFoundation/NumberDate.subproj/CFTimeZone.c +++ b/CoreFoundation/NumberDate.subproj/CFTimeZone.c @@ -813,6 +813,15 @@ static CFTimeZoneRef __CFTimeZoneCreateSystem(void) { CFRelease(name); if (result) return result; } +#if DEPLOYMENT_TARGET_ANDROID + // Timezone database by name not available on Android. + // Approximate with gmtoff - could be general default. + struct tm info; + time_t now = time(NULL); + if (NULL != localtime_r(&now, &info)) { + return CFTimeZoneCreateWithTimeIntervalFromGMT(kCFAllocatorSystemDefault, info.tm_gmtoff); + } +#endif return CFTimeZoneCreateWithTimeIntervalFromGMT(kCFAllocatorSystemDefault, 0.0); } diff --git a/CoreFoundation/PlugIn.subproj/CFBundle.c b/CoreFoundation/PlugIn.subproj/CFBundle.c index 2b4f24291b..c6b9d16b1d 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle.c +++ b/CoreFoundation/PlugIn.subproj/CFBundle.c @@ -137,7 +137,7 @@ static void _CFBundleEnsureBundlesExistForImagePaths(CFArrayRef imagePaths); #pragma mark - -#if !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS +#if !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS && !DEPLOYMENT_TARGET_ANDROID // Functions and constants for FHS bundles: #define _CFBundleFHSDirectory_share CFSTR("share") @@ -162,10 +162,10 @@ static Boolean _CFBundleURLIsForFHSInstalledBundle(CFURLRef bundleURL) { return isFHSBundle; } -#endif // !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS +#endif // !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS && !DEPLOYMENT_TARGET_ANDROID Boolean _CFBundleSupportsFHSBundles() { -#if !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS +#if !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS && !DEPLOYMENT_TARGET_ANDROID return true; #else return false; @@ -714,7 +714,7 @@ static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL, bundle->_url = newURL; -#if !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS +#if !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS && !DEPLOYMENT_TARGET_ANDROID bundle->_isFHSInstalledBundle = _CFBundleURLIsForFHSInstalledBundle(newURL); #endif diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_Executable.c b/CoreFoundation/PlugIn.subproj/CFBundle_Executable.c index 568a6e495c..7e3b39d186 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle_Executable.c +++ b/CoreFoundation/PlugIn.subproj/CFBundle_Executable.c @@ -15,7 +15,7 @@ #include #endif -#if !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS +#if !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS && !DEPLOYMENT_TARGET_ANDROID #if DEPLOYMENT_TARGET_LINUX #if __LP64__ @@ -48,7 +48,7 @@ _kCFBundleFHSDirectory_lib #endif // DEPLOYMENT_TARGET_LINUX -#endif // !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS +#endif // !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS && !DEPLOYMENT_TARGET_ANDROID // This is here because on iPhoneOS with the dyld shared cache, we remove binaries from their // original locations on disk, so checking whether a binary's path exists is no longer sufficient. @@ -73,7 +73,7 @@ static CFURLRef _CFBundleCopyExecutableURLRaw(CFURLRef urlPath, CFStringRef exeN CFURLRef executableURL = NULL; if (!urlPath || !exeName) return NULL; -#if !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS +#if !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS && !DEPLOYMENT_TARGET_ANDROID if (!executableURL) { executableURL = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, exeName, kCFURLPOSIXPathStyle, false, urlPath); if (!_binaryLoadable(executableURL)) { @@ -203,7 +203,7 @@ static CFURLRef _CFBundleCopyExecutableURLInDirectory2(CFBundleRef bundle, CFURL Boolean doExecSearch = true; #endif -#if !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS +#if !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS && !DEPLOYMENT_TARGET_ANDROID if (lookupMainExe && bundle && bundle->_isFHSInstalledBundle) { // For a FHS installed bundle, the URL points to share/Bundle.resources, and the binary is in: @@ -227,13 +227,13 @@ static CFURLRef _CFBundleCopyExecutableURLInDirectory2(CFBundleRef bundle, CFURL CFRelease(prefixPath); } -#endif // !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS +#endif // !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS && !DEPLOYMENT_TARGET_ANDROID // Now, look for the executable inside the bundle. if (!foundIt && doExecSearch && 0 != version) { CFURLRef exeDirURL = NULL; -#if !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS +#if !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS && !DEPLOYMENT_TARGET_ANDROID if (bundle && bundle->_isFHSInstalledBundle) { CFURLRef withoutExtension = CFURLCreateCopyDeletingPathExtension(kCFAllocatorSystemDefault, url); CFStringRef lastPathComponent = CFURLCopyLastPathComponent(withoutExtension); @@ -248,7 +248,7 @@ static CFURLRef _CFBundleCopyExecutableURLInDirectory2(CFBundleRef bundle, CFURL CFRelease(libexec); CFRelease(exeDirName); } else -#endif // !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS +#endif // !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS && !DEPLOYMENT_TARGET_ANDROID if (1 == version) { exeDirURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundleExecutablesURLFromBase1, url); } else if (2 == version) { diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_Internal.h b/CoreFoundation/PlugIn.subproj/CFBundle_Internal.h index 45f49c57c4..b94a9aeb18 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle_Internal.h +++ b/CoreFoundation/PlugIn.subproj/CFBundle_Internal.h @@ -31,7 +31,7 @@ CF_EXTERN_C_BEGIN #endif // FHS bundles are supported on the Swift and C runtimes, except on Windows. -#if !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS +#if !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS && !DEPLOYMENT_TARGET_ANDROID #if DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD #define _CFBundleFHSSharedLibraryFilenamePrefix CFSTR("lib") @@ -43,7 +43,7 @@ CF_EXTERN_C_BEGIN #error Disable FHS bundles or specify shared library prefixes and suffixes for this platform. #endif // DEPLOYMENT_TARGET_… -#endif // !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS +#endif // !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS && !DEPLOYMENT_TARGET_ANDROID #define CFBundleExecutableNotFoundError 4 #define CFBundleExecutableNotLoadableError 3584 diff --git a/CoreFoundation/URL.subproj/CFURL.c b/CoreFoundation/URL.subproj/CFURL.c index 0696b3ea46..3e25b4f756 100644 --- a/CoreFoundation/URL.subproj/CFURL.c +++ b/CoreFoundation/URL.subproj/CFURL.c @@ -25,10 +25,10 @@ #include #include #include -#if __has_include() -#include -#elif __has_include() +#if __has_include() #include +#else +#include #endif #include #endif diff --git a/Foundation/Bundle.swift b/Foundation/Bundle.swift index 921126ad40..38b395e9cb 100644 --- a/Foundation/Bundle.swift +++ b/Foundation/Bundle.swift @@ -53,8 +53,10 @@ open class Bundle: NSObject { self.init(path: url.path) } - public init(for aClass: AnyClass) { NSUnimplemented() } - + public init(for aClass: AnyClass) { + NSUnimplemented() + } + public init?(identifier: String) { super.init() diff --git a/Foundation/FileManager.swift b/Foundation/FileManager.swift index b69c77a831..99b5a93189 100644 --- a/Foundation/FileManager.swift +++ b/Foundation/FileManager.swift @@ -375,10 +375,13 @@ open class FileManager : NSObject { This method replaces fileSystemAttributesAtPath:. */ + #if os(Android) + @available(*, unavailable, message: "Unsuppported on this platform") + open func attributesOfFileSystem(forPath path: String) throws -> [FileAttributeKey : Any] { + NSUnsupported() + } + #else open func attributesOfFileSystem(forPath path: String) throws -> [FileAttributeKey : Any] { -#if os(Android) - NSUnimplemented() -#else // statvfs(2) doesn't support 64bit inode on Darwin (apfs), fallback to statfs(2) #if os(macOS) || os(iOS) var s = statfs() @@ -407,8 +410,8 @@ open class FileManager : NSObject { result[.systemFreeNodes] = NSNumber(value: UInt64(s.f_ffree)) return result -#endif } +#endif /* createSymbolicLinkAtPath:withDestination:error: returns YES if the symbolic link that point at 'destPath' was able to be created at the location specified by 'path'. If this method returns NO, the link was unable to be created and an NSError will be returned by reference in the 'error' parameter. This method does not traverse a terminal symlink. diff --git a/Foundation/NSCFString.swift b/Foundation/NSCFString.swift index 638de7e449..a4fd04b4f4 100644 --- a/Foundation/NSCFString.swift +++ b/Foundation/NSCFString.swift @@ -71,8 +71,8 @@ internal final class _NSCFConstantString : _NSCFString { // FIXME: Split expression as a work-around for slow type // checking (tracked by SR-5322). let offTemp1 = MemoryLayout.size + MemoryLayout.size - let offTemp2 = MemoryLayout<_CFInfo>.size - return offTemp1 + offTemp2 + MemoryLayout>.size + let offset = offTemp1 + MemoryLayout<_CFInfo>.size + return offset + MemoryLayout>.size } private var _lenPtr : UnsafeMutableRawPointer { diff --git a/Foundation/NSTimeZone.swift b/Foundation/NSTimeZone.swift index 5e5b311017..61eedeb8c5 100644 --- a/Foundation/NSTimeZone.swift +++ b/Foundation/NSTimeZone.swift @@ -179,14 +179,6 @@ open class NSTimeZone : NSObject, NSCopying, NSSecureCoding, NSCoding { extension NSTimeZone { open class var system: TimeZone { -#if os(Android) - var now = time(nil), info = tm() - if localtime_r(&now, &info) != nil { - // NOTE: this is not a real time zone but a fixed offset from GMT. - // It will be incorrect outside the current daylight saving period. - return TimeZone(reference: NSTimeZone(forSecondsFromGMT: info.tm_gmtoff)) - } -#endif return CFTimeZoneCopySystem()._swiftObject } diff --git a/TestFoundation/TestFileManager.swift b/TestFoundation/TestFileManager.swift index 579d9865db..e612e7e7f1 100644 --- a/TestFoundation/TestFileManager.swift +++ b/TestFoundation/TestFileManager.swift @@ -275,6 +275,7 @@ class TestFileManager : XCTestCase { } func test_fileSystemAttributes() { +#if !os(Android) let fm = FileManager.default let path = NSTemporaryDirectory() @@ -306,6 +307,7 @@ class TestFileManager : XCTestCase { } catch let err { XCTFail("\(err)") } +#endif } func test_setFileAttributes() { diff --git a/TestFoundation/TestNSAttributedString.swift b/TestFoundation/TestNSAttributedString.swift index 308b5958dd..17a7e48662 100644 --- a/TestFoundation/TestNSAttributedString.swift +++ b/TestFoundation/TestNSAttributedString.swift @@ -192,10 +192,6 @@ class TestNSAttributedString : XCTestCase { } func test_enumerateAttributes() { -#if os(Android) - // Invalid dictionary returned by CFAttributedStringGetAttributesAndLongestEffectiveRange - XCTFail("Intermittent failures on Android") -#else let string = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus consectetur et sem vitae consectetur. Nam venenatis lectus a laoreet blandit." let attrKey1 = NSAttributedStringKey("attribute.placeholder.key1") @@ -254,7 +250,6 @@ class TestNSAttributedString : XCTestCase { } XCTAssertEqual(rangeDescriptionString, "(0,10)") XCTAssertEqual(attrsDescriptionString, "[attribute.placeholder.key1:attribute.placeholder.value1]") -#endif } func test_copy() { diff --git a/TestFoundation/TestNSNumber.swift b/TestFoundation/TestNSNumber.swift index 8dc25a0183..af19acf887 100644 --- a/TestFoundation/TestNSNumber.swift +++ b/TestFoundation/TestNSNumber.swift @@ -1083,37 +1083,40 @@ class TestNSNumber : XCTestCase { func test_stringValue() { + // The following casts on subtraction are required for an Android compile + // https://bugs.swift.org/browse/SR-7469 + if UInt.max == UInt32.max { XCTAssertEqual(NSNumber(value: UInt.min).stringValue, "0") XCTAssertEqual(NSNumber(value: UInt.min + 1).stringValue, "1") XCTAssertEqual(NSNumber(value: UInt.max).stringValue, "4294967295") - XCTAssertEqual(NSNumber(value: UInt.max - 1).stringValue, "4294967294") + XCTAssertEqual(NSNumber(value: UInt.max - 1 as UInt).stringValue, "4294967294") } else if UInt.max == UInt64.max { XCTAssertEqual(NSNumber(value: UInt.min).stringValue, "0") XCTAssertEqual(NSNumber(value: UInt.min + 1).stringValue, "1") XCTAssertEqual(NSNumber(value: UInt.max).stringValue, "18446744073709551615") - XCTAssertEqual(NSNumber(value: UInt.max - 1).stringValue, "18446744073709551614") + XCTAssertEqual(NSNumber(value: UInt.max - 1 as UInt).stringValue, "18446744073709551614") } XCTAssertEqual(NSNumber(value: UInt8.min).stringValue, "0") XCTAssertEqual(NSNumber(value: UInt8.min + 1).stringValue, "1") XCTAssertEqual(NSNumber(value: UInt8.max).stringValue, "255") - XCTAssertEqual(NSNumber(value: UInt8.max - 1).stringValue, "254") + XCTAssertEqual(NSNumber(value: UInt8.max - 1 as UInt8).stringValue, "254") XCTAssertEqual(NSNumber(value: UInt16.min).stringValue, "0") XCTAssertEqual(NSNumber(value: UInt16.min + 1).stringValue, "1") XCTAssertEqual(NSNumber(value: UInt16.max).stringValue, "65535") - XCTAssertEqual(NSNumber(value: UInt16.max - 1).stringValue, "65534") + XCTAssertEqual(NSNumber(value: UInt16.max - 1 as UInt16).stringValue, "65534") XCTAssertEqual(NSNumber(value: UInt32.min).stringValue, "0") XCTAssertEqual(NSNumber(value: UInt32.min + 1).stringValue, "1") XCTAssertEqual(NSNumber(value: UInt32.max).stringValue, "4294967295") - XCTAssertEqual(NSNumber(value: UInt32.max - 1).stringValue, "4294967294") + XCTAssertEqual(NSNumber(value: UInt32.max - 1 as UInt32).stringValue, "4294967294") XCTAssertEqual(NSNumber(value: UInt64.min).stringValue, "0") XCTAssertEqual(NSNumber(value: UInt64.min + 1).stringValue, "1") XCTAssertEqual(NSNumber(value: UInt64.max).stringValue, "18446744073709551615") - XCTAssertEqual(NSNumber(value: UInt64.max - 1).stringValue, "18446744073709551614") + XCTAssertEqual(NSNumber(value: UInt64.max - 1 as UInt64).stringValue, "18446744073709551614") if Int.max == Int32.max { XCTAssertEqual(NSNumber(value: Int.min).stringValue, "-2147483648")