Created
May 7, 2015 15:46
-
-
Save joakim-noah/07ed7ab1e5732ab91126 to your computer and use it in GitHub Desktop.
Phobos patch for Android with ldc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/std/conv.d b/std/conv.d | |
index 8ce8ad6..3a91e85 100644 | |
--- a/std/conv.d | |
+++ b/std/conv.d | |
@@ -2885,6 +2885,8 @@ unittest | |
x = *cast(longdouble *)&ld; | |
version (Win64) | |
ld1 = 0x1.FFFFFFFFFFFFFFFEp-16382L; // strtold currently mapped to strtod | |
+ else version (Android) | |
+ ld1 = 0x1.FFFFFFFFFFFFFFFEp-16382L; // strtold currently mapped to strtod | |
else | |
ld1 = strtold(s.ptr, null); | |
x1 = *cast(longdouble *)&ld1; | |
diff --git a/std/datetime.d b/std/datetime.d | |
index 1b079a4..89fd4b0 100644 | |
--- a/std/datetime.d | |
+++ b/std/datetime.d | |
@@ -26024,6 +26024,7 @@ auto tz = TimeZone.getTimeZone("America/Los_Angeles"); | |
version(FreeBSD) enum utcZone = "Etc/UTC"; | |
version(linux) enum utcZone = "UTC"; | |
version(OSX) enum utcZone = "UTC"; | |
+ version(Android) enum utcZone = "UTC"; | |
auto tzs = [testTZ("America/Los_Angeles", "PST", "PDT", dur!"hours"(-8), dur!"hours"(1)), | |
testTZ("America/New_York", "EST", "EDT", dur!"hours"(-5), dur!"hours"(1)), | |
diff --git a/std/file.d b/std/file.d | |
index de08c25..6393d6f 100644 | |
--- a/std/file.d | |
+++ b/std/file.d | |
@@ -55,6 +55,17 @@ version (unittest) | |
return _deleteme; | |
} | |
+ | |
+ version(Android) | |
+ { | |
+ enum system_directory = "/system/etc"; | |
+ enum system_file = "/system/etc/hosts"; | |
+ } | |
+ else version(Posix) | |
+ { | |
+ enum system_directory = "/usr/include"; | |
+ enum system_file = "/usr/include/assert.h"; | |
+ } | |
} | |
@@ -718,7 +729,8 @@ void setTimes(in char[] name, | |
unittest | |
{ | |
- string dir = deleteme ~ r".dir/a/b/c"; | |
+ string newdir = deleteme ~ r".dir"; | |
+ string dir = newdir ~ r"/a/b/c"; | |
string file = dir ~ "/file"; | |
if (!exists(dir)) mkdirRecurse(dir); | |
@@ -737,7 +749,7 @@ unittest | |
assert(mtime == mtime_res); | |
} | |
- rmdirRecurse(dir); | |
+ rmdirRecurse(newdir); | |
} | |
/++ | |
@@ -1021,11 +1033,11 @@ unittest | |
} | |
else version(Posix) | |
{ | |
- if("/usr/include".exists) | |
- assert("/usr/include".isDir); | |
+ if(system_directory.exists) | |
+ assert(system_directory.isDir); | |
- if("/usr/include/assert.h".exists) | |
- assert(!"/usr/include/assert.h".isDir); | |
+ if(system_file.exists) | |
+ assert(!system_file.isDir); | |
} | |
} | |
@@ -1072,16 +1084,16 @@ unittest | |
} | |
else version(Posix) | |
{ | |
- if("/usr/include".exists) | |
+ if(system_directory.exists) | |
{ | |
- assert(attrIsDir(getAttributes("/usr/include"))); | |
- assert(attrIsDir(getLinkAttributes("/usr/include"))); | |
+ assert(attrIsDir(getAttributes(system_directory))); | |
+ assert(attrIsDir(getLinkAttributes(system_directory))); | |
} | |
- if("/usr/include/assert.h".exists) | |
+ if(system_file.exists) | |
{ | |
- assert(!attrIsDir(getAttributes("/usr/include/assert.h"))); | |
- assert(!attrIsDir(getLinkAttributes("/usr/include/assert.h"))); | |
+ assert(!attrIsDir(getAttributes(system_file))); | |
+ assert(!attrIsDir(getLinkAttributes(system_file))); | |
} | |
} | |
} | |
@@ -1134,11 +1146,11 @@ unittest | |
} | |
else version(Posix) | |
{ | |
- if("/usr/include".exists) | |
- assert(!"/usr/include".isFile); | |
+ if(system_directory.exists) | |
+ assert(!system_directory.isFile); | |
- if("/usr/include/assert.h".exists) | |
- assert("/usr/include/assert.h".isFile); | |
+ if(system_file.exists) | |
+ assert(system_file.isFile); | |
} | |
} | |
@@ -1196,16 +1208,16 @@ unittest | |
} | |
else version(Posix) | |
{ | |
- if("/usr/include".exists) | |
+ if(system_directory.exists) | |
{ | |
- assert(!attrIsFile(getAttributes("/usr/include"))); | |
- assert(!attrIsFile(getLinkAttributes("/usr/include"))); | |
+ assert(!attrIsFile(getAttributes(system_directory))); | |
+ assert(!attrIsFile(getLinkAttributes(system_directory))); | |
} | |
- if("/usr/include/assert.h".exists) | |
+ if(system_file.exists) | |
{ | |
- assert(attrIsFile(getAttributes("/usr/include/assert.h"))); | |
- assert(attrIsFile(getLinkAttributes("/usr/include/assert.h"))); | |
+ assert(attrIsFile(getAttributes(system_file))); | |
+ assert(attrIsFile(getLinkAttributes(system_file))); | |
} | |
} | |
} | |
@@ -1260,14 +1272,14 @@ unittest | |
} | |
else version(Posix) | |
{ | |
- if("/usr/include".exists) | |
+ if(system_directory.exists) | |
{ | |
- assert(!"/usr/include".isSymlink); | |
+ assert(!system_directory.isSymlink); | |
immutable symfile = deleteme ~ "_slink\0"; | |
scope(exit) if(symfile.exists) symfile.remove(); | |
- core.sys.posix.unistd.symlink("/usr/include", symfile.ptr); | |
+ core.sys.posix.unistd.symlink(system_directory, symfile.ptr); | |
assert(symfile.isSymlink); | |
assert(!attrIsSymlink(getAttributes(symfile))); | |
@@ -1280,14 +1292,14 @@ unittest | |
assert(!attrIsFile(getLinkAttributes(symfile))); | |
} | |
- if("/usr/include/assert.h".exists) | |
+ if(system_file.exists) | |
{ | |
- assert(!"/usr/include/assert.h".isSymlink); | |
+ assert(!system_file.isSymlink); | |
immutable symfile = deleteme ~ "_slink\0"; | |
scope(exit) if(symfile.exists) symfile.remove(); | |
- core.sys.posix.unistd.symlink("/usr/include/assert.h", symfile.ptr); | |
+ core.sys.posix.unistd.symlink(system_file, symfile.ptr); | |
assert(symfile.isSymlink); | |
assert(!attrIsSymlink(getAttributes(symfile))); | |
@@ -1496,12 +1508,12 @@ else version(Posix) void symlink(C1, C2)(const(C1)[] original, const(C2)[] link) | |
version(Posix) unittest | |
{ | |
- if("/usr/include".exists) | |
+ if(system_directory.exists) | |
{ | |
immutable symfile = deleteme ~ "_slink\0"; | |
scope(exit) if(symfile.exists) symfile.remove(); | |
- symlink("/usr/include", symfile); | |
+ symlink(system_directory, symfile); | |
assert(symfile.exists); | |
assert(symfile.isSymlink); | |
@@ -1515,14 +1527,14 @@ version(Posix) unittest | |
assert(!attrIsFile(getLinkAttributes(symfile))); | |
} | |
- if("/usr/include/assert.h".exists) | |
+ if(system_file.exists) | |
{ | |
- assert(!"/usr/include/assert.h".isSymlink); | |
+ assert(!system_file.isSymlink); | |
immutable symfile = deleteme ~ "_slink\0"; | |
scope(exit) if(symfile.exists) symfile.remove(); | |
- symlink("/usr/include/assert.h", symfile); | |
+ symlink(system_file, symfile); | |
assert(symfile.exists); | |
assert(symfile.isSymlink); | |
@@ -1587,7 +1599,7 @@ else version(Posix) string readLink(C)(const(C)[] link) | |
version(Posix) unittest | |
{ | |
- foreach(file; ["/usr/include", "/usr/include/assert.h"]) | |
+ foreach(file; [system_directory, system_file]) | |
{ | |
if(file.exists) | |
{ | |
@@ -1721,6 +1733,10 @@ else version (FreeBSD) | |
return buffer.assumeUnique; | |
} | |
+ else version (Android) | |
+ { | |
+ return readLink("/proc/self/exe"); | |
+ } | |
else version (Solaris) | |
{ | |
import core.sys.posix.unistd : getpid; | |
@@ -2231,10 +2247,10 @@ unittest | |
} | |
else version(Posix) | |
{ | |
- if("/usr/include".exists) | |
+ if(system_directory.exists) | |
{ | |
{ | |
- auto de = DirEntry("/usr/include"); | |
+ auto de = DirEntry(system_directory); | |
assert(!de.isFile); | |
assert(de.isDir); | |
assert(!de.isSymlink); | |
@@ -2243,7 +2259,7 @@ unittest | |
immutable symfile = deleteme ~ "_slink\0"; | |
scope(exit) if(symfile.exists) symfile.remove(); | |
- core.sys.posix.unistd.symlink("/usr/include", symfile.ptr); | |
+ core.sys.posix.unistd.symlink(system_directory, symfile.ptr); | |
{ | |
auto de = DirEntry(symfile); | |
@@ -2273,9 +2289,9 @@ unittest | |
} | |
} | |
- if("/usr/include/assert.h".exists) | |
+ if(system_file.exists) | |
{ | |
- auto de = DirEntry("/usr/include/assert.h"); | |
+ auto de = DirEntry(system_file); | |
assert(de.isFile); | |
assert(!de.isDir); | |
assert(!de.isSymlink); | |
@@ -2440,7 +2456,9 @@ version(Posix) unittest | |
d = deleteme~"/a/b/c/d/e/f/g"; | |
mkdirRecurse(d); | |
- std.process.system("ln -sf "~deleteme~"/a/b/c "~deleteme~"/link"); | |
+ version(Android) string link_cmd = "ln -s "; | |
+ else string link_cmd = "ln -sf "; | |
+ std.process.system(link_cmd~deleteme~"/a/b/c "~deleteme~"/link"); | |
rmdirRecurse(deleteme); | |
enforce(!exists(deleteme)); | |
} | |
@@ -3154,7 +3172,7 @@ string tempDir() @trusted | |
} | |
else static assert (false, "Unsupported platform"); | |
- if (cache is null) cache = "."; | |
+ if (cache is null) cache = getcwd(); | |
} | |
return cache; | |
} | |
diff --git a/std/format.d b/std/format.d | |
index b8c43d1..8f9d0bf 100644 | |
--- a/std/format.d | |
+++ b/std/format.d | |
@@ -1675,7 +1675,9 @@ if (is(FloatingPointTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) | |
formatTest( to!( const T)(5.5), "5.5" ); | |
formatTest( to!(immutable T)(5.5), "5.5" ); | |
- formatTest( T.nan, "nan" ); | |
+ // bionic doesn't support lower-case string formatting of nan yet | |
+ version(Android) { formatTest( T.nan, "NaN" ); } | |
+ else { formatTest( T.nan, "nan" ); } | |
} | |
} | |
@@ -3426,6 +3428,13 @@ unittest | |
assert(stream.data == "1.67 -0X1.47AE14P+0 nan", | |
stream.data); | |
} | |
+ else version (Android) | |
+ { | |
+ // bionic doesn't support hex formatting of floating point numbers | |
+ // or lower-case string formatting of nan yet, but it was committed | |
+ // recently (April 2014): | |
+ // https://code.google.com/p/android/issues/detail?id=64886 | |
+ } | |
else | |
{ | |
assert(stream.data == "1.67 -0X1.47AE147AE147BP+0 nan", | |
@@ -3454,6 +3463,12 @@ unittest | |
version (MinGW) { /+ LDC_FIXME: GitHub #383 +/ } else | |
version (Win64) | |
assert(stream.data == "0x1.51eb85p+0 0X1.B1EB86P+2"); | |
+ else version (Android) | |
+ { | |
+ // bionic doesn't support hex formatting of floating point numbers, | |
+ // but it was committed recently (April 2014): | |
+ // https://code.google.com/p/android/issues/detail?id=64886 | |
+ } | |
else | |
assert(stream.data == "0x1.51eb851eb851fp+0 0X1.B1EB86P+2"); | |
stream.clear(); | |
@@ -5974,6 +5989,13 @@ unittest | |
assert(s == "1.67 -0XA.3D70A3D70A3D8P-3 nan", s); | |
else version (Win64) | |
assert(s == "1.67 -0X1.47AE14P+0 nan", s); | |
+ else version (Android) | |
+ { | |
+ // bionic doesn't support hex formatting of floating point numbers | |
+ // or lower-case string formatting of nan yet, but it was committed | |
+ // recently (April 2014): | |
+ // https://code.google.com/p/android/issues/detail?id=64886 | |
+ } | |
else | |
assert(s == "1.67 -0X1.47AE147AE147BP+0 nan", s); | |
diff --git a/std/math.d b/std/math.d | |
index 948d6c2..7d2bf76 100644 | |
--- a/std/math.d | |
+++ b/std/math.d | |
@@ -538,7 +538,7 @@ unittest | |
version(LDC) | |
{ | |
- real cos(real x) @safe pure nothrow @nogc { return llvm_cos(x); } | |
+ real cos(real x) @safe pure nothrow @nogc { return cos(x); } | |
} | |
else | |
{ | |
@@ -561,7 +561,7 @@ real cos(real x) @safe pure nothrow @nogc; /* intrinsic */ | |
*/ | |
version(LDC) | |
{ | |
- real sin(real x) @safe pure nothrow @nogc { return llvm_sin(x); } | |
+ real sin(real x) @safe pure nothrow @nogc { return sin(x); } | |
} | |
else | |
{ | |
@@ -636,7 +636,7 @@ unittest | |
real tan(real x) @trusted pure nothrow @nogc | |
{ | |
- version (LDC) | |
+ version (LDCN) | |
{ | |
return core.stdc.math.tanl(x); | |
} | |
@@ -2464,7 +2464,7 @@ version(LDC) | |
real ldexp(real n, int exp) @nogc @trusted pure nothrow | |
{ | |
- return core.stdc.math.ldexpl(n, exp); | |
+ return core.stdc.math.ldexp(n, exp); | |
} | |
} | |
@@ -2554,7 +2554,7 @@ unittest | |
*/ | |
version(LDC) | |
{ | |
- real log(real x) @safe pure nothrow @nogc { return llvm_log(x); } | |
+ real log(real x) @safe pure nothrow @nogc { return log(x); } | |
} | |
else | |
{ | |
@@ -2689,7 +2689,7 @@ unittest | |
*/ | |
static if (__traits(compiles, llvm_log10(3.14L))) | |
{ | |
- real log10(real x) @safe pure nothrow @nogc { return llvm_log10(x); } | |
+ real log10(real x) @safe pure nothrow @nogc { return log10(x); } | |
} | |
else | |
{ | |
@@ -2869,7 +2869,7 @@ real log1p(real x) @safe pure nothrow @nogc | |
*/ | |
static if (__traits(compiles, llvm_log2(3.14L))) | |
{ | |
- real log2(real x) @safe pure nothrow @nogc { return llvm_log2(x); } | |
+ real log2(real x) @safe pure nothrow @nogc { return log2(x); } | |
} | |
else | |
{ | |
@@ -3105,7 +3105,7 @@ real scalbn(real x, int n) @trusted nothrow @nogc | |
} | |
else | |
{*/ | |
- return core.stdc.math.scalbnl(x, n); | |
+ return core.stdc.math.scalbn(x, n); | |
/*}*/ | |
} | |
@@ -3538,7 +3538,7 @@ version(LDC) | |
{ | |
static if (__traits(compiles, llvm_rint(3.14L))) | |
{ | |
- real rint(real x) @safe pure nothrow @nogc { return llvm_rint(x); } | |
+ real rint(real x) @safe pure nothrow @nogc { return rint(x); } | |
} | |
else | |
{ | |
@@ -5645,7 +5645,7 @@ real fmin(real x, real y) @safe pure nothrow @nogc { return x < y ? x : y; } | |
*/ | |
version(LDC) | |
{ | |
- real fma(real x, real y, real z) @safe pure nothrow @nogc { return llvm_fma(x, y, z); } | |
+ real fma(real x, real y, real z) @safe pure nothrow @nogc { return fma(x, y, z); } | |
} | |
else | |
{ | |
@@ -6578,6 +6578,34 @@ body | |
; | |
} | |
} | |
+ else version (Android) | |
+ { | |
+ asm // assembler by W. Bright | |
+ { | |
+ // EDX = (A.length - 1) * real.sizeof | |
+ mov ECX,A[EBP] ; // ECX = A.length | |
+ dec ECX ; | |
+ lea EDX,[ECX*8] ; | |
+ lea EDX,[EDX][ECX*4] ; | |
+ add EDX,A+4[EBP] ; | |
+ fld real ptr [EDX] ; // ST0 = coeff[ECX] | |
+ jecxz return_ST ; | |
+ fld x[EBP] ; // ST0 = x | |
+ fxch ST(1) ; // ST1 = x, ST0 = r | |
+ align 4 ; | |
+ L2: fmul ST,ST(1) ; // r *= x | |
+ fld real ptr -12[EDX] ; | |
+ sub EDX,12 ; // deg-- | |
+ faddp ST(1),ST ; | |
+ dec ECX ; | |
+ jne L2 ; | |
+ fxch ST(1) ; // ST1 = r, ST0 = x | |
+ fstp ST(0) ; // dump x | |
+ align 4 ; | |
+ return_ST: ; | |
+ ; | |
+ } | |
+ } | |
else | |
{ | |
static assert(0); | |
diff --git a/std/path.d b/std/path.d | |
index 93c34f8..b97afec 100644 | |
--- a/std/path.d | |
+++ b/std/path.d | |
@@ -2894,68 +2894,77 @@ string expandTilde(string inputPath) | |
// Replaces the tilde from path with the path from the user database. | |
static string expandFromDatabase(string path) | |
{ | |
- assert(path.length > 2 || (path.length == 2 && !isDirSeparator(path[1]))); | |
- assert(path[0] == '~'); | |
- | |
- // Extract username, searching for path separator. | |
- string username; | |
- auto last_char = std.string.indexOf(path, dirSeparator[0]); | |
- | |
- if (last_char == -1) | |
+ // Android doesn't really support this, as getpwnam_r | |
+ // isn't provided and getpwnam is basically just a stub | |
+ version(Android) | |
{ | |
- username = path[1 .. $] ~ '\0'; | |
- last_char = username.length + 1; | |
+ return path; | |
} | |
else | |
{ | |
- username = path[1 .. last_char] ~ '\0'; | |
- } | |
- assert(last_char > 1); | |
+ assert(path.length > 2 || (path.length == 2 && !isDirSeparator(path[1]))); | |
+ assert(path[0] == '~'); | |
- // Reserve C memory for the getpwnam_r() function. | |
- passwd result; | |
- int extra_memory_size = 5 * 1024; | |
- void* extra_memory; | |
+ // Extract username, searching for path separator. | |
+ string username; | |
+ auto last_char = std.string.indexOf(path, dirSeparator[0]); | |
- while (1) | |
- { | |
- extra_memory = core.stdc.stdlib.malloc(extra_memory_size); | |
- if (extra_memory == null) | |
- goto Lerror; | |
- | |
- // Obtain info from database. | |
- passwd *verify; | |
- errno = 0; | |
- if (getpwnam_r(cast(char*) username.ptr, &result, cast(char*) extra_memory, extra_memory_size, | |
- &verify) == 0) | |
+ if (last_char == -1) | |
{ | |
- // Failure if verify doesn't point at result. | |
- if (verify != &result) | |
- // username is not found, so return path[] | |
- goto Lnotfound; | |
- break; | |
+ username = path[1 .. $] ~ '\0'; | |
+ last_char = username.length + 1; | |
+ } | |
+ else | |
+ { | |
+ username = path[1 .. last_char] ~ '\0'; | |
} | |
+ assert(last_char > 1); | |
- if (errno != ERANGE) | |
- goto Lerror; | |
+ // Reserve C memory for the getpwnam_r() function. | |
+ passwd result; | |
+ int extra_memory_size = 5 * 1024; | |
+ void* extra_memory; | |
- // extra_memory isn't large enough | |
- core.stdc.stdlib.free(extra_memory); | |
- extra_memory_size *= 2; | |
- } | |
+ while (1) | |
+ { | |
+ extra_memory = core.stdc.stdlib.malloc(extra_memory_size); | |
+ if (extra_memory == null) | |
+ goto Lerror; | |
+ | |
+ // Obtain info from database. | |
+ passwd *verify; | |
+ errno = 0; | |
+ if (getpwnam_r(cast(char*) username.ptr, &result, cast(char*) extra_memory, extra_memory_size, | |
+ &verify) == 0) | |
+ { | |
+ // Failure if verify doesn't point at result. | |
+ if (verify != &result) | |
+ // username is not found, so return path[] | |
+ goto Lnotfound; | |
+ break; | |
+ } | |
+ | |
+ if (errno != ERANGE) | |
+ goto Lerror; | |
- path = combineCPathWithDPath(result.pw_dir, path, last_char); | |
+ // extra_memory isn't large enough | |
+ core.stdc.stdlib.free(extra_memory); | |
+ extra_memory_size *= 2; | |
+ } | |
- Lnotfound: | |
- core.stdc.stdlib.free(extra_memory); | |
- return path; | |
+ path = combineCPathWithDPath(result.pw_dir, path, last_char); | |
- Lerror: | |
- // Errors are going to be caused by running out of memory | |
- if (extra_memory) | |
+ Lnotfound: | |
core.stdc.stdlib.free(extra_memory); | |
- onOutOfMemoryError(); | |
- return null; | |
+ return path; | |
+ | |
+ Lerror: | |
+ // Errors are going to be caused by running out of memory | |
+ if (extra_memory) | |
+ core.stdc.stdlib.free(extra_memory); | |
+ onOutOfMemoryError(); | |
+ return null; | |
+ } | |
} | |
// Return early if there is no tilde in path. | |
@@ -3006,15 +3015,20 @@ unittest | |
if (oldHome !is null) environment["HOME"] = oldHome; | |
else environment.remove("HOME"); | |
- // Test user expansion for root. Are there unices without /root? | |
+ // Test user expansion for root, no /root on Android | |
version (OSX) | |
+ { | |
assert(expandTilde("~root") == "/var/root", expandTilde("~root")); | |
- else | |
- assert(expandTilde("~root") == "/root", expandTilde("~root")); | |
- version (OSX) | |
assert(expandTilde("~root/") == "/var/root/", expandTilde("~root/")); | |
+ } | |
+ else version (Android) | |
+ { | |
+ } | |
else | |
+ { | |
+ assert(expandTilde("~root") == "/root", expandTilde("~root")); | |
assert(expandTilde("~root/") == "/root/", expandTilde("~root/")); | |
+ } | |
assert(expandTilde("~Idontexist/hey") == "~Idontexist/hey"); | |
} | |
} | |
diff --git a/std/process.d b/std/process.d | |
index 1dc42e0..a422525 100644 | |
--- a/std/process.d | |
+++ b/std/process.d | |
@@ -2159,7 +2159,8 @@ private struct TestScript | |
else version (Posix) | |
{ | |
auto ext = ""; | |
- auto firstLine = "#!/bin/sh"; | |
+ version(Android) auto firstLine = "#!" ~ userShell; | |
+ else auto firstLine = "#!/bin/sh"; | |
} | |
path = uniqueTempPath()~ext; | |
std.file.write(path, firstLine~std.ascii.newline~code~std.ascii.newline); | |
diff --git a/std/range.d b/std/range.d | |
index 6bda764..621ff9f 100644 | |
--- a/std/range.d | |
+++ b/std/range.d | |
@@ -8906,9 +8906,11 @@ unittest | |
// Test on an input range | |
unittest | |
{ | |
- import std.stdio, std.file, std.path, std.conv; | |
- auto name = buildPath(tempDir(), "test.std.range." ~ text(__LINE__)); | |
+ import std.stdio, std.file, std.path, std.conv, std.uuid; | |
+ auto name = buildPath(tempDir(), "test.std.range.line-" ~ text(__LINE__) ~ | |
+ "." ~ randomUUID().toString()); | |
auto f = File(name, "w"); | |
+ scope(exit) if (exists(name)) remove(name); | |
// write a sorted range of lines to the file | |
f.write("abc\ndef\nghi\njkl"); | |
f.close(); | |
@@ -8916,6 +8918,7 @@ unittest | |
auto r = assumeSorted(f.byLine()); | |
auto r1 = r.upperBound!(SearchPolicy.linear)("def"); | |
assert(r1.front == "ghi", r1.front); | |
+ f.close(); | |
} | |
/** | |
diff --git a/std/socket.d b/std/socket.d | |
index d7468e2..03dda13 100644 | |
--- a/std/socket.d | |
+++ b/std/socket.d | |
@@ -98,6 +98,14 @@ else version(Posix) | |
private enum SD_SEND = SHUT_WR; | |
private enum SD_BOTH = SHUT_RDWR; | |
} | |
+ else version(Android) | |
+ { | |
+ import core.sys.posix.sys.socket; | |
+ import core.sys.posix.sys.select; | |
+ private enum SD_RECEIVE = SHUT_RD; | |
+ private enum SD_SEND = SHUT_WR; | |
+ private enum SD_BOTH = SHUT_RDWR; | |
+ } | |
else | |
static assert(false); | |
@@ -205,6 +213,14 @@ string formatSocketError(int err) | |
else | |
return "Socket error " ~ to!string(err); | |
} | |
+ else version (Android) | |
+ { | |
+ auto errs = strerror_r(err, buf.ptr, buf.length); | |
+ if (errs == 0) | |
+ cs = buf.ptr; | |
+ else | |
+ return "Socket error " ~ to!string(err); | |
+ } | |
else | |
static assert(0); | |
@@ -399,18 +415,37 @@ enum SocketType: int | |
/** | |
* Protocol | |
*/ | |
-enum ProtocolType: int | |
+version(Android) | |
+{ | |
+ // no GGP on Android | |
+ enum ProtocolType: int | |
+ { | |
+ IP = IPPROTO_IP, /// Internet Protocol version 4 | |
+ ICMP = IPPROTO_ICMP, /// Internet Control Message Protocol | |
+ IGMP = IPPROTO_IGMP, /// Internet Group Management Protocol | |
+ TCP = IPPROTO_TCP, /// Transmission Control Protocol | |
+ PUP = IPPROTO_PUP, /// PARC Universal Packet Protocol | |
+ UDP = IPPROTO_UDP, /// User Datagram Protocol | |
+ IDP = IPPROTO_IDP, /// Xerox NS protocol | |
+ RAW = IPPROTO_RAW, /// Raw IP packets | |
+ IPV6 = IPPROTO_IPV6, /// Internet Protocol version 6 | |
+ } | |
+} | |
+else | |
{ | |
- IP = IPPROTO_IP, /// Internet Protocol version 4 | |
- ICMP = IPPROTO_ICMP, /// Internet Control Message Protocol | |
- IGMP = IPPROTO_IGMP, /// Internet Group Management Protocol | |
- GGP = IPPROTO_GGP, /// Gateway to Gateway Protocol | |
- TCP = IPPROTO_TCP, /// Transmission Control Protocol | |
- PUP = IPPROTO_PUP, /// PARC Universal Packet Protocol | |
- UDP = IPPROTO_UDP, /// User Datagram Protocol | |
- IDP = IPPROTO_IDP, /// Xerox NS protocol | |
- RAW = IPPROTO_RAW, /// Raw IP packets | |
- IPV6 = IPPROTO_IPV6, /// Internet Protocol version 6 | |
+ enum ProtocolType: int | |
+ { | |
+ IP = IPPROTO_IP, /// Internet Protocol version 4 | |
+ ICMP = IPPROTO_ICMP, /// Internet Control Message Protocol | |
+ IGMP = IPPROTO_IGMP, /// Internet Group Management Protocol | |
+ GGP = IPPROTO_GGP, /// Gateway to Gateway Protocol | |
+ TCP = IPPROTO_TCP, /// Transmission Control Protocol | |
+ PUP = IPPROTO_PUP, /// PARC Universal Packet Protocol | |
+ UDP = IPPROTO_UDP, /// User Datagram Protocol | |
+ IDP = IPPROTO_IDP, /// Xerox NS protocol | |
+ RAW = IPPROTO_RAW, /// Raw IP packets | |
+ IPV6 = IPPROTO_IPV6, /// Internet Protocol version 6 | |
+ } | |
} | |
@@ -494,6 +529,7 @@ class Protocol | |
unittest | |
{ | |
+ // getprotobyname,number are unimplemented on Android | |
softUnittest({ | |
Protocol proto = new Protocol; | |
assert(proto.getProtocolByType(ProtocolType.TCP)); | |
@@ -2388,19 +2424,39 @@ unittest | |
} | |
/// The level at which a socket option is defined: | |
-enum SocketOptionLevel: int | |
-{ | |
- SOCKET = SOL_SOCKET, /// Socket level | |
- IP = ProtocolType.IP, /// Internet Protocol version 4 level | |
- ICMP = ProtocolType.ICMP, /// Internet Control Message Protocol level | |
- IGMP = ProtocolType.IGMP, /// Internet Group Management Protocol level | |
- GGP = ProtocolType.GGP, /// Gateway to Gateway Protocol level | |
- TCP = ProtocolType.TCP, /// Transmission Control Protocol level | |
- PUP = ProtocolType.PUP, /// PARC Universal Packet Protocol level | |
- UDP = ProtocolType.UDP, /// User Datagram Protocol level | |
- IDP = ProtocolType.IDP, /// Xerox NS protocol level | |
- RAW = ProtocolType.RAW, /// Raw IP packet level | |
- IPV6 = ProtocolType.IPV6, /// Internet Protocol version 6 level | |
+version(Android) | |
+{ | |
+ // no GGP on Android | |
+ enum SocketOptionLevel: int | |
+ { | |
+ SOCKET = SOL_SOCKET, /// Socket level | |
+ IP = ProtocolType.IP, /// Internet Protocol version 4 level | |
+ ICMP = ProtocolType.ICMP, /// Internet Control Message Protocol level | |
+ IGMP = ProtocolType.IGMP, /// Internet Group Management Protocol level | |
+ TCP = ProtocolType.TCP, /// Transmission Control Protocol level | |
+ PUP = ProtocolType.PUP, /// PARC Universal Packet Protocol level | |
+ UDP = ProtocolType.UDP, /// User Datagram Protocol level | |
+ IDP = ProtocolType.IDP, /// Xerox NS protocol level | |
+ RAW = ProtocolType.RAW, /// Raw IP packet level | |
+ IPV6 = ProtocolType.IPV6, /// Internet Protocol version 6 level | |
+ } | |
+} | |
+else | |
+{ | |
+ enum SocketOptionLevel: int | |
+ { | |
+ SOCKET = SOL_SOCKET, /// Socket level | |
+ IP = ProtocolType.IP, /// Internet Protocol version 4 level | |
+ ICMP = ProtocolType.ICMP, /// Internet Control Message Protocol level | |
+ IGMP = ProtocolType.IGMP, /// Internet Group Management Protocol level | |
+ GGP = ProtocolType.GGP, /// Gateway to Gateway Protocol level | |
+ TCP = ProtocolType.TCP, /// Transmission Control Protocol level | |
+ PUP = ProtocolType.PUP, /// PARC Universal Packet Protocol level | |
+ UDP = ProtocolType.UDP, /// User Datagram Protocol level | |
+ IDP = ProtocolType.IDP, /// Xerox NS protocol level | |
+ RAW = ProtocolType.RAW, /// Raw IP packet level | |
+ IPV6 = ProtocolType.IPV6, /// Internet Protocol version 6 level | |
+ } | |
} | |
/// _Linger information for use with SocketOption.LINGER. | |
diff --git a/std/stdio.d b/std/stdio.d | |
index 5db3f45..3194538 100644 | |
--- a/std/stdio.d | |
+++ b/std/stdio.d | |
@@ -919,7 +919,7 @@ Throws: $(D Exception) if the file is not opened. | |
else | |
{ | |
//static assert(off_t.sizeof == 8); | |
- errnoEnforce(fseeko(_p.handle, offset, origin) == 0, | |
+ errnoEnforce(fseeko(_p.handle, cast(off_t) offset, origin) == 0, | |
"Could not seek in file `"~_name~"'"); | |
} | |
} | |
@@ -942,7 +942,10 @@ Throws: $(D Exception) if the file is not opened. | |
{ | |
import std.conv : text; | |
- auto bigOffset = cast(ulong) int.max + 100; | |
+ version (Android) | |
+ auto bigOffset = int.max - 100; | |
+ else | |
+ auto bigOffset = cast(ulong) int.max + 100; | |
f.seek(bigOffset); | |
assert(f.tell == bigOffset, text(f.tell)); | |
// Uncomment the tests below only if you want to wait for | |
diff --git a/std/system.d b/std/system.d | |
index 9bb4d51..d4b47fe 100644 | |
--- a/std/system.d | |
+++ b/std/system.d | |
@@ -35,6 +35,7 @@ immutable | |
osx, /// Mac OS X | |
freeBSD, /// FreeBSD | |
solaris, /// Solaris | |
+ android, /// Android | |
otherPosix /// Other Posix Systems | |
} | |
@@ -44,6 +45,7 @@ immutable | |
else version(linux) OS os = OS.linux; | |
else version(OSX) OS os = OS.osx; | |
else version(FreeBSD) OS os = OS.freeBSD; | |
+ else version(Android) OS os = OS.android; | |
else version(Posix) OS os = OS.otherPosix; | |
else static assert(0, "Unknown OS."); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment