Skip to content

Port of Foundation to Android #622

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Sep 22, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
fc14279
Port of Foundation to Android
johnno1962 Sep 6, 2016
80f82ae
Port of Foundation to Android
johnno1962 Sep 6, 2016
bbd66a4
Missing -lcurl for Linux builds of Foundation
johnno1962 Sep 6, 2016
21457d1
README and script tidy-up
johnno1962 Sep 6, 2016
6c904b9
Response to comments
johnno1962 Sep 7, 2016
9237e8d
NSGeonetry, Operation queues fixed
johnno1962 Sep 8, 2016
0fdf620
More reponses to comments
johnno1962 Sep 9, 2016
4fa36dd
NSLog now working
johnno1962 Sep 9, 2016
23ad327
Update README
johnno1962 Sep 10, 2016
83e5800
Update README
johnno1962 Sep 12, 2016
2e25c71
CGFloat.swift problems resolved, NSGeometry, NSScanner.swift updated
johnno1962 Sep 13, 2016
8e24456
Glibc is already an @_exported import in NSSwiftRuntime.swift
johnno1962 Sep 14, 2016
a0457a5
Glibc is already an @_exported import in NSSwiftRuntime.swift
johnno1962 Sep 14, 2016
604718e
#import <stdarg.h> problem went away with rebuild
johnno1962 Sep 14, 2016
9bc98b0
Update scripts
johnno1962 Sep 15, 2016
546cad2
move to SEEK_* macros
johnno1962 Sep 15, 2016
60e6b73
Better logging and restructuring
johnno1962 Sep 15, 2016
6213cba
CONST_STRING_DECL() problem resolved
johnno1962 Sep 16, 2016
bc4cabb
Jira for CFStringGetCString() crash with zero length strings
johnno1962 Sep 16, 2016
5fe1c8c
Only use heap if required in logging
johnno1962 Sep 16, 2016
6858ae8
Reinstate fix for SR-2666
johnno1962 Sep 16, 2016
e15e240
Reinstate fix for SR-2666
johnno1962 Sep 16, 2016
759eca6
Ensure NSUnimplemented() functions logged
johnno1962 Sep 16, 2016
ffe852b
one true brace style
johnno1962 Sep 17, 2016
a82e390
Final tweaks?
johnno1962 Sep 19, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CoreFoundation/Base.subproj/CFInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,16 @@ CF_PRIVATE Boolean __CFProcessIsRestricted();
#define STACK_BUFFER_DECL(T, N, C) T N[C]
#endif

#ifdef __ANDROID__
// Avoids crashes on Android
// https://bugs.swift.org/browse/SR-2587
// https://bugs.swift.org/browse/SR-2588
// Seemed to be a linker/relocation? problem.
// CFStrings using CONST_STRING_DECL() were not working
// Applies reference to _NSCFConstantString's isa here
// rather than using a linker option to create an alias.
#define __CFConstantStringClassReference _TMC10Foundation19_NSCFConstantString
#endif

CF_EXPORT void * __CFConstantStringClassReferencePtr;
#if defined(__CONSTANT_CFSTRINGS__)
Expand Down
4 changes: 4 additions & 0 deletions CoreFoundation/Base.subproj/CFPlatform.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,11 @@ const char *_CFProcessPath(void) {

#if DEPLOYMENT_TARGET_LINUX
#include <unistd.h>
#if __has_include(<syscall.h>)
#include <syscall.h>
#else
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the previous header does not exist what is to say the sys/syscall version exists? Perhaps that should be gated as well and #error'd on the else claiming that syscall.h is required

Copy link
Contributor Author

@johnno1962 johnno1962 Sep 7, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

won’t it error anyway? It doesn’t fail silently or anything anti-social. This just improves the odds. I can gate it if you want.

#include <sys/syscall.h>
#endif

Boolean _CFIsMainThread(void) {
return syscall(SYS_gettid) == getpid();
Expand Down
43 changes: 42 additions & 1 deletion CoreFoundation/Base.subproj/CFUtilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#if DEPLOYMENT_TARGET_WINDOWS
#include <process.h>
#endif
#ifdef __ANDROID__
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@parkera should we perhaps instead of using macros defined by the compiler use a DEPLOYMENT_TARGET_ANDROID for these?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can change it back if you like.

#include <android/log.h>
#endif
#include <math.h>
#include <string.h>
#include <stdio.h>
Expand Down Expand Up @@ -764,7 +767,45 @@ void CFLog(CFLogLevel lev, CFStringRef format, ...) {
#if DEPLOYMENT_RUNTIME_SWIFT
// Temporary as Swift cannot import varag C functions
void CFLog1(CFLogLevel lev, CFStringRef message) {
#ifdef __ANDROID__
android_LogPriority priority = ANDROID_LOG_UNKNOWN;
switch (lev) {
case kCFLogLevelEmergency: priority = ANDROID_LOG_FATAL; break;
case kCFLogLevelAlert: priority = ANDROID_LOG_ERROR; break;
case kCFLogLevelCritical: priority = ANDROID_LOG_ERROR; break;
case kCFLogLevelError: priority = ANDROID_LOG_ERROR; break;
case kCFLogLevelWarning: priority = ANDROID_LOG_WARN; break;
case kCFLogLevelNotice: priority = ANDROID_LOG_WARN; break;
case kCFLogLevelInfo: priority = ANDROID_LOG_INFO; break;
case kCFLogLevelDebug: priority = ANDROID_LOG_DEBUG; break;
}

if (message == NULL) message = CFSTR("NULL");

char stack_buffer[1024] = { 0 };
char *buffer = &stack_buffer[0];
CFStringEncoding encoding = kCFStringEncodingUTF8;
CFIndex maxLength = CFStringGetMaximumSizeForEncoding(CFStringGetLength(message), encoding) + 1;

if (maxLength > sizeof(stack_buffer) / sizeof(stack_buffer[0])) {
buffer = calloc(sizeof(char), maxLength);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should check calloc() return value

Copy link
Contributor Author

@johnno1962 johnno1962 Sep 23, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too late now...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not too late - open up another PR. =)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright already, new PR #655

}

if (maxLength == 1) {
// was crashing with zero length strings
// https://bugs.swift.org/browse/SR-2666
strcpy(buffer, " "); // log empty string
}
else
CFStringGetCString(message, buffer, maxLength, encoding);

const char *tag = "Swift"; // process name not available from NDK
__android_log_print(priority, tag, "%s", buffer);

if (buffer != &stack_buffer[0]) free(buffer);
#else
CFLog(lev, CFSTR("%@"), message);
#endif
}
#endif

Expand Down Expand Up @@ -1265,7 +1306,7 @@ CFDictionaryRef __CFGetEnvironment() {
extern char **environ;
char **envp = environ;
#elif DEPLOYMENT_TARGET_LINUX
#ifndef environ
#if !defined(environ) && !defined(__ANDROID__)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this right? Do you really intend to leave environ undefined on Android?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe environ is already defined on Android: https://github.com/apple/swift/blob/e6dec58cc5e08a59028310aac14d1e8fbc46c2d4/stdlib/private/SwiftPrivateLibcExtras/Subprocess.swift#L292

So in theory this additional !defined(__ANDROID__) check may not be necessary at all...?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

environ is already defined on Android. No need to redefine it to __environ.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this change can be reverted, yes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m saying it’s needed, honest! Full code is:

#elif DEPLOYMENT_TARGET_LINUX
#if !defined(environ) && !defined(ANDROID)
#define environ __environ
#endif
char **envp = environ;
#endif

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused, if environ is already defined in Android, then the second half of your #if is never evaluated; if environ is undefined in Android, then what is envp on Android?

Am I missing something?

Copy link
Contributor Author

@johnno1962 johnno1962 Sep 14, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

envrion is a C symbol on Android not a #define for the preprocessor so you can’t test for whether it exists with a #ifdef. It must be a #define on some other architectures.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it.

#define environ __environ
#endif
char **envp = environ;
Expand Down
6 changes: 6 additions & 0 deletions CoreFoundation/Base.subproj/CoreFoundation_Prefix.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,11 @@ typedef int boolean_t;

#include <pthread.h>

#ifdef __ANDROID__
typedef unsigned long fd_mask;
#endif

#ifndef __ANDROID__
CF_INLINE size_t
strlcpy(char * dst, const char * src, size_t maxlen) {
const size_t srclen = strlen(src);
Expand All @@ -203,6 +208,7 @@ strlcat(char * dst, const char * src, size_t maxlen) {
}
return dstlen + srclen;
}
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is fd_mask defined in an else clause with definitions of strlcpy/strlcat? Are the two related in some way that I am missing?

Copy link
Contributor Author

@johnno1962 johnno1962 Sep 7, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m just saving a line. I’ll separate them.


#define issetugid() 0

Expand Down
4 changes: 4 additions & 0 deletions CoreFoundation/Base.subproj/SwiftRuntime/CoreFoundation.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
#include <string.h>
#include <time.h>

#if __has_include(<netdb.h>)
#include <netdb.h> // for NSHost.swift
#endif

#if defined(__STDC_VERSION__) && (199901L <= __STDC_VERSION__)

#include <inttypes.h>
Expand Down
4 changes: 4 additions & 0 deletions CoreFoundation/NumberDate.subproj/CFTimeZone.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
#include <dirent.h>
#include <unistd.h>
#if __has_include(<sys/fcntl.h>)
#include <sys/fcntl.h>
#else
#include <fcntl.h>
#endif
#endif
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
#include <tzfile.h>
Expand Down
2 changes: 2 additions & 0 deletions CoreFoundation/PlugIn.subproj/CFBundle_InfoPlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@

#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_FREEBSD
#include <dirent.h>
#if __has_include(<sys/sysctl.h>)
#include <sys/sysctl.h>
#endif
#include <sys/mman.h>
#endif

Expand Down
2 changes: 2 additions & 0 deletions CoreFoundation/PlugIn.subproj/CFBundle_Resources.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@

#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
#include <unistd.h>
#if __has_include(<sys/sysctl.h>)
#include <sys/sysctl.h>
#endif
#include <sys/stat.h>
#include <dirent.h>
#endif
Expand Down
4 changes: 4 additions & 0 deletions CoreFoundation/URL.subproj/CFURL.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#if __has_include(<sys/syslog.h>)
#include <sys/syslog.h>
#else
#include <syslog.h>
#endif
#include <CoreFoundation/CFURLPriv.h>
#endif

Expand Down
4 changes: 2 additions & 2 deletions Foundation/NSData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
repeat {
#if os(OSX) || os(iOS)
bytesWritten = Darwin.write(fd, buf.advanced(by: length - bytesRemaining), bytesRemaining)
#elseif os(Linux)
#elseif os(Linux) || os(Android)
bytesWritten = Glibc.write(fd, buf.advanced(by: length - bytesRemaining), bytesRemaining)
#endif
} while (bytesWritten < 0 && errno == EINTR)
Expand All @@ -444,7 +444,7 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
// Preserve permissions.
var info = stat()
if lstat(path, &info) == 0 {
mode = info.st_mode
mode = mode_t(info.st_mode)
} else if errno != ENOENT && errno != ENAMETOOLONG {
throw _NSErrorWithErrno(errno, reading: false, path: path)
}
Expand Down
12 changes: 6 additions & 6 deletions Foundation/NSFileHandle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ open class FileHandle : NSObject, NSSecureCoding {
}
}
} else {
let offset = lseek(_fd, 0, L_INCR)
let offset = lseek(_fd, 0, SEEK_CUR)
if offset < 0 {
fatalError("Unable to fetch current file offset")
}
if statbuf.st_size > offset {
if off_t(statbuf.st_size) > offset {
var remaining = size_t(statbuf.st_size - offset)
remaining = min(remaining, size_t(length))

Expand Down Expand Up @@ -128,19 +128,19 @@ open class FileHandle : NSObject, NSSecureCoding {
// TODO: Error handling.

open var offsetInFile: UInt64 {
return UInt64(lseek(_fd, 0, L_INCR))
return UInt64(lseek(_fd, 0, SEEK_CUR))
}

open func seekToEndOfFile() -> UInt64 {
return UInt64(lseek(_fd, 0, L_XTND))
return UInt64(lseek(_fd, 0, SEEK_END))
}

open func seek(toFileOffset offset: UInt64) {
lseek(_fd, off_t(offset), L_SET)
lseek(_fd, off_t(offset), SEEK_SET)
}

open func truncateFile(atOffset offset: UInt64) {
if lseek(_fd, off_t(offset), L_SET) == 0 {
if lseek(_fd, off_t(offset), SEEK_SET) == 0 {
ftruncate(_fd, off_t(offset))
}
}
Expand Down
18 changes: 13 additions & 5 deletions Foundation/NSFileManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
import Glibc
#endif

#if os(Android) // struct stat.st_mode is UInt32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here too, does this also apply to Linux?

Copy link
Contributor Author

@johnno1962 johnno1962 Sep 14, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to be an Android NDK specific thing

internal func &(left: UInt32, right: mode_t) -> mode_t {
return mode_t(left) & right
}
#endif

import CoreFoundation

open class FileManager : NSObject {
Expand Down Expand Up @@ -123,10 +129,10 @@ open class FileManager : NSObject {
}
#if os(OSX) || os(iOS)
let modeT = number.uint16Value
#elseif os(Linux)
#elseif os(Linux) || os(Android)
let modeT = number.uint32Value
#endif
if chmod(path, modeT) != 0 {
if chmod(path, mode_t(modeT)) != 0 {
fatalError("errno \(errno)")
}
} else {
Expand Down Expand Up @@ -246,11 +252,11 @@ open class FileManager : NSObject {
}
#if os(OSX) || os(iOS)
let tempEntryType = entryType
#elseif os(Linux)
#elseif os(Linux) || os(Android)
let tempEntryType = Int(entryType)
#endif

if tempEntryType == DT_DIR {
if tempEntryType == Int(DT_DIR) {
let subPath: String = path + "/" + entryName

let entries = try subpathsOfDirectory(atPath: subPath)
Expand Down Expand Up @@ -279,6 +285,8 @@ open class FileManager : NSObject {

#if os(OSX) || os(iOS)
let ti = (TimeInterval(s.st_mtimespec.tv_sec) - kCFAbsoluteTimeIntervalSince1970) + (1.0e-9 * TimeInterval(s.st_mtimespec.tv_nsec))
#elseif os(Android)
let ti = (TimeInterval(s.st_mtime) - kCFAbsoluteTimeIntervalSince1970) + (1.0e-9 * TimeInterval(s.st_mtime_nsec))
#else
let ti = (TimeInterval(s.st_mtim.tv_sec) - kCFAbsoluteTimeIntervalSince1970) + (1.0e-9 * TimeInterval(s.st_mtim.tv_nsec))
#endif
Expand Down Expand Up @@ -361,7 +369,7 @@ open class FileManager : NSObject {
throw _NSErrorWithErrno(errno, reading: true, path: path)
}

return self.string(withFileSystemRepresentation: buf, length: len)
return self.string(withFileSystemRepresentation: buf, length: Int(len))
}

open func copyItem(atPath srcPath: String, toPath dstPath: String) throws {
Expand Down
2 changes: 1 addition & 1 deletion Foundation/NSLocale.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ open class NSLocale: NSObject, NSCopying, NSSecureCoding {
private var _prefs: UnsafeMutableRawPointer? = nil
#if os(OSX) || os(iOS)
private var _lock = pthread_mutex_t()
#elseif os(Linux)
#elseif os(Linux) || os(Android)
private var _lock = Int32(0)
#endif
private var _nullLocale = false
Expand Down
3 changes: 3 additions & 0 deletions Foundation/NSObjCRuntime.swift
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,9 @@ internal func NSRequiresConcreteImplementation(_ fn: String = #function, file: S
}

internal func NSUnimplemented(_ fn: String = #function, file: StaticString = #file, line: UInt = #line) -> Never {
#if os(Android)
NSLog("\(fn) is not yet implemented. \(file):\(line)")
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did we add an NSLog here?

Copy link
Contributor Author

@johnno1962 johnno1962 Sep 22, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fatalError() doesn’t print anything on Android (asserts do). Just giving people a pointer.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't fatalError call __android_log_print on android?

Copy link
Contributor Author

@johnno1962 johnno1962 Sep 22, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should but this is a Foundation PR. I’ll take a look. Annoyingly, using __android_log_print requires a -llog when you link so it wouldn’t be a trivial change. Looks like a change to https://github.com/apple/swift/blob/master/stdlib/public/runtime/Errors.cpp#L204

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fatalError("\(fn) is not yet implemented", file: file, line: line)
}

Expand Down
2 changes: 1 addition & 1 deletion Foundation/NSOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

#if DEPLOYMENT_ENABLE_LIBDISPATCH
import Dispatch
#if os(Linux)
#if os(Linux) || os(Android)
import CoreFoundation
private func pthread_main_np() -> Int32 {
return _CFIsMainThread() ? 1 : 0
Expand Down
8 changes: 7 additions & 1 deletion Foundation/NSSwiftRuntime.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,16 @@ import CoreFoundation
// This mimics the behavior of the swift sdk overlay on Darwin
#if os(OSX) || os(iOS)
@_exported import Darwin
#elseif os(Linux)
#elseif os(Linux) || os(Android)
@_exported import Glibc
#endif

#if os(Android) // shim required for bzero
@_transparent func bzero(_ ptr: UnsafeMutableRawPointer, _ size: size_t) {
memset(ptr, 0, size)
}
#endif

public typealias ObjCBool = Bool

internal class __NSCFType : NSObject {
Expand Down
2 changes: 2 additions & 0 deletions Foundation/NSTask.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//

#if !os(Android) // not available
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still not happy about this.

Is there a way, instead, to mark the class as unavailable on the Android platform?

Copy link
Contributor Author

@johnno1962 johnno1962 Sep 12, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you tell me the syntax to specify a NSTask unavailable for android please. I’ll make the class unavailable and #if !os(Android) out it’s methods or would they not try to compile if marked unavailable.

Copy link
Contributor Author

@johnno1962 johnno1962 Sep 12, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had a quick look at removing the #if !os(Android), got the following:

Foundation/NSTask.swift:95:2: warning: unknown platform 'Android' for attribute 'available'
@available(Android, unavailable)
^

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does it take to add Android as a platform for the compiler to understand here? That may be a prereq to anyone doing anything meaningful on Android in the first place.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you tell me the syntax to specify a NSTask unavailable for android please.

I think this means adding Android to the list of platforms that the Swift compiler knows about. Adding that (and maybe some other tweaks) should allow us to write @available(Android, unavailable). Does that sound right to you, @parkera?

Copy link
Contributor Author

@johnno1962 johnno1962 Sep 13, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s odd. The compiler knows about #if os(Android) giving an error if you mistype it but not @available(Android, unavailable). Can it be the list you mention as Linux is not on it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's a good point. I'm not 100% sure -- I just grepped around, found that spot, and thought it looked interesting. :)

If adding Android to that list is indeed what @parkera had in mind, we could email the swift-dev mailing list to learn more about it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@parkera is having @available(Android, unavailable) a blocker for this PR? IMHO it would be the ideal solution here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jira https://bugs.swift.org/browse/SR-2670 has a response - currently not implemented.

import CoreFoundation

#if os(OSX) || os(iOS)
Expand Down Expand Up @@ -455,3 +456,4 @@ private func posix(_ code: Int32) {
default: fatalError("POSIX command failed with error: \(code)")
}
}
#endif
2 changes: 1 addition & 1 deletion Foundation/NSThread.swift
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ open class Thread : NSObject {
internal var _main: (Void) -> Void = {}
#if os(OSX) || os(iOS)
private var _thread: pthread_t? = nil
#elseif os(Linux)
#elseif os(Linux) || os(Android)
private var _thread = pthread_t()
#endif
internal var _attr = pthread_attr_t()
Expand Down
2 changes: 1 addition & 1 deletion Foundation/NSURL.swift
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {

open var password: String? {
let absoluteURL = CFURLCopyAbsoluteURL(_cfObject)
#if os(Linux)
#if os(Linux) || os(Android)
let passwordRange = CFURLGetByteRangeForComponent(absoluteURL, kCFURLComponentPassword, nil)
#else
let passwordRange = CFURLGetByteRangeForComponent(absoluteURL, .password, nil)
Expand Down
2 changes: 1 addition & 1 deletion Foundation/NSXMLNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ open class XMLNode: NSObject, NSCopying {
public static let nodePromoteSignificantWhitespace = Options(rawValue: 1 << 28)
public static let nodePreserveEmptyElements = Options([.nodeExpandEmptyElement, .nodeCompactEmptyElement])
public static let nodePreserveQuotes = Options([.nodeUseSingleQuotes, .nodeUseDoubleQuotes])
public static let nodePreserveAll = Options(rawValue: Options([.nodePreserveNamespaceOrder, .nodePreserveAttributeOrder, .nodePreserveEntities, .nodePreservePrefixes, .nodePreserveCDATA, .nodePreserveEmptyElements, .nodePreserveQuotes, .nodePreserveWhitespace, .nodePreserveDTD, .nodePreserveCharacterReferences]).rawValue | UInt(bitPattern: 0xFFF00000))
public static let nodePreserveAll = Options(rawValue: 0xFFF00000).union([.nodePreserveNamespaceOrder, .nodePreserveAttributeOrder, .nodePreserveEntities, .nodePreservePrefixes, .nodePreserveCDATA, .nodePreserveEmptyElements, .nodePreserveQuotes, .nodePreserveWhitespace, .nodePreserveDTD, .nodePreserveCharacterReferences])
}

open override func copy() -> Any {
Expand Down
Loading