public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/iains/heads/d-for-darwin)] libphobos: Move getdelim declaration to druntime, fix stdio logic, add ucontext_t
@ 2020-12-21 20:36 Iain D Sandoe
0 siblings, 0 replies; 2+ messages in thread
From: Iain D Sandoe @ 2020-12-21 20:36 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:cb227eb0d06ef529489f45656022badce54ae52c
commit cb227eb0d06ef529489f45656022badce54ae52c
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Thu Dec 3 23:51:01 2020 +0100
libphobos: Move getdelim declaration to druntime, fix stdio logic, add ucontext_t
Diff:
---
libphobos/libdruntime/core/sys/posix/stdio.d | 194 +++++---
libphobos/libdruntime/core/sys/posix/ucontext.d | 25 +
libphobos/src/std/stdio.d | 582 ++++++++++++------------
3 files changed, 458 insertions(+), 343 deletions(-)
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index bc2329e6bf8..a47aec525e8 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -249,64 +249,72 @@ else version (Solaris)
/*
L_ctermid
-char* ctermid(char*);
-FILE* fdopen(int, in char*);
-int fileno(FILE*);
-int fseeko(FILE*, off_t, int);
-off_t ftello(FILE*);
-char* gets(char*);
-int pclose(FILE*);
-FILE* popen(in char*, in char*);
+char* ctermid(char*);
+FILE* fdopen(int, const scope char*);
+int fileno(FILE*);
+int fseeko(FILE*, off_t, int);
+off_t ftello(FILE*);
+ssize_t getdelim(char**, size_t*, int, FILE*);
+ssize_t getline(char**, size_t*, FILE*);
+char* gets(char*);
+int pclose(FILE*);
+FILE* popen(const scope char*, const scope char*);
*/
version (CRuntime_Glibc)
{
enum L_ctermid = 9;
- static if ( __USE_FILE_OFFSET64 )
- {
- int fseeko64(FILE*, off_t, int);
- alias fseeko64 fseeko;
- }
- else
- {
- int fseeko(FILE*, off_t, int);
- }
-
- static if ( __USE_FILE_OFFSET64 )
- {
- off_t ftello64(FILE*);
- alias ftello64 ftello;
- }
- else
- {
- off_t ftello(FILE*);
- }
+ static if ( __USE_FILE_OFFSET64 )
+ {
+ int fseeko64(FILE*, off_t, int);
+ alias fseeko64 fseeko;
+ }
+ else
+ {
+ int fseeko(FILE*, off_t, int);
+ }
+
+ static if ( __USE_FILE_OFFSET64 )
+ {
+ off_t ftello64(FILE*);
+ alias ftello64 ftello;
+ }
+ else
+ {
+ off_t ftello(FILE*);
+ }
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
}
else version (CRuntime_UClibc)
{
enum L_ctermid = 9;
enum L_cuserid = 9;
- static if ( __USE_FILE_OFFSET64 )
- {
- int fseeko64(FILE*, off_t, int);
- alias fseeko64 fseeko;
- }
- else
- {
- int fseeko(FILE*, off_t, int);
- }
-
- static if ( __USE_FILE_OFFSET64 )
- {
- off_t ftello64(FILE*);
- alias ftello64 ftello;
- }
- else
- {
- off_t ftello(FILE*);
- }
+ static if ( __USE_FILE_OFFSET64 )
+ {
+ int fseeko64(FILE*, off_t, int);
+ alias fseeko64 fseeko;
+ }
+ else
+ {
+ int fseeko(FILE*, off_t, int);
+ }
+
+ static if ( __USE_FILE_OFFSET64 )
+ {
+ off_t ftello64(FILE*);
+ alias ftello64 ftello;
+ }
+ else
+ {
+ off_t ftello(FILE*);
+ }
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
}
else version (CRuntime_Musl)
{
@@ -331,6 +339,91 @@ else version (CRuntime_Musl)
{
off_t ftello(FILE*);
}
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
+}
+else version (CRuntime_Bionic)
+{
+ enum L_ctermid = 1024;
+
+ static if ( __USE_FILE_OFFSET64 )
+ {
+ int fseeko64(FILE*, off_t, int);
+ alias fseeko64 fseeko;
+ }
+ else
+ {
+ int fseeko(FILE*, off_t, int);
+ }
+
+ static if ( __USE_FILE_OFFSET64 )
+ {
+ off_t ftello64(FILE*);
+ alias ftello64 ftello;
+ }
+ else
+ {
+ off_t ftello(FILE*);
+ }
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
+}
+else version (Darwin)
+{
+ enum L_ctermid = 1024;
+
+ int fseeko(FILE*, off_t, int);
+ off_t ftello(FILE*);
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
+}
+else version (FreeBSD)
+{
+ import core.sys.freebsd.config;
+
+ enum L_ctermid = 1024;
+
+ int fseeko(FILE*, off_t, int);
+ off_t ftello(FILE*);
+
+ static if (__FreeBSD_version >= 800000)
+ {
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
+ }
+}
+else version (NetBSD)
+{
+ enum L_ctermid = 1024;
+
+ int fseeko(FILE*, off_t, int);
+ off_t ftello(FILE*);
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
+}
+else version (OpenBSD)
+{
+ enum L_ctermid = 1024;
+
+ int fseeko(FILE*, off_t, int);
+ off_t ftello(FILE*);
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
+}
+else version (DragonFlyBSD)
+{
+ enum L_ctermid = 1024;
+
+ int fseeko(FILE*, off_t, int);
+ off_t ftello(FILE*);
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
}
else version (Solaris)
{
@@ -356,6 +449,9 @@ else version (Solaris)
{
off_t ftello(FILE*);
}
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
}
else version (Posix)
{
@@ -366,8 +462,6 @@ else version (Posix)
char* ctermid(char*);
FILE* fdopen(int, in char*);
int fileno(FILE*);
-//int fseeko(FILE*, off_t, int);
-//off_t ftello(FILE*);
char* gets(char*);
int pclose(FILE*);
FILE* popen(in char*, in char*);
@@ -546,7 +640,3 @@ unittest
assert(memcmp(ptr, testdata.ptr, testdata.length*wchar_t.sizeof) == 0);
assert(fclose(f) == 0);
}
-
-
-ssize_t getdelim (char** lineptr, size_t* n, int delimiter, FILE* stream);
-ssize_t getline (char** lineptr, size_t* n, FILE* stream);
diff --git a/libphobos/libdruntime/core/sys/posix/ucontext.d b/libphobos/libdruntime/core/sys/posix/ucontext.d
index 2e518aefa84..ef74771a50d 100644
--- a/libphobos/libdruntime/core/sys/posix/ucontext.d
+++ b/libphobos/libdruntime/core/sys/posix/ucontext.d
@@ -23,6 +23,15 @@ extern (C):
nothrow:
@nogc:
+version (OSX)
+ version = Darwin;
+else version (iOS)
+ version = Darwin;
+else version (TVOS)
+ version = Darwin;
+else version (WatchOS)
+ version = Darwin;
+
version (MIPS32) version = MIPS_Any;
version (MIPS64) version = MIPS_Any;
version (PPC) version = PPC_Any;
@@ -909,6 +918,22 @@ else version (CRuntime_Musl)
else
static assert(0, "unimplemented");
}
+else version (Darwin)
+{
+ alias mcontext_t = void;
+
+ struct ucontext
+ {
+ int uc_onstack;
+ sigset_t uc_sigmask;
+ stack_t uc_stack;
+ ucontext* uc_link;
+ size_t uc_mcsize;
+ mcontext_t* uc_mcontext;
+ }
+
+ alias ucontext_t = ucontext;
+}
else version (FreeBSD)
{
// <machine/ucontext.h>
diff --git a/libphobos/src/std/stdio.d b/libphobos/src/std/stdio.d
index 4c1ad0baa15..9265cc05170 100644
--- a/libphobos/src/std/stdio.d
+++ b/libphobos/src/std/stdio.d
@@ -42,43 +42,34 @@ version (CRuntime_Glibc)
{
// Specific to the way Gnu C does stdio
version = GCC_IO;
- version = HAS_GETDELIM;
}
else version (CRuntime_Bionic)
{
version = GENERIC_IO;
- version = HAS_GETDELIM;
}
else version (CRuntime_Musl)
{
version = GENERIC_IO;
- version = HAS_GETDELIM;
}
-
-version (OSX)
+else version (OSX)
{
version = GENERIC_IO;
- version = HAS_GETDELIM;
}
else version (FreeBSD)
{
version = GENERIC_IO;
- version = HAS_GETDELIM;
}
else version (NetBSD)
{
version = GENERIC_IO;
- version = HAS_GETDELIM;
}
else version (DragonFlyBSD)
{
version = GENERIC_IO;
- version = HAS_GETDELIM;
}
else version (Solaris)
{
version = GENERIC_IO;
- version = NO_GETDELIM;
}
// Character type used for operating system filesystem APIs
@@ -105,6 +96,11 @@ version (Windows)
import core.sys.windows.windows : HANDLE;
}
+version (Posix)
+{
+ static import core.sys.posix.stdio; // getdelim
+}
+
version (DIGITAL_MARS_STDIO)
{
extern (C)
@@ -244,11 +240,19 @@ else
static assert(0, "unsupported C I/O system");
}
-version (HAS_GETDELIM) extern(C) nothrow @nogc
+static if (__traits(compiles, core.sys.posix.stdio.getdelim))
{
- ptrdiff_t getdelim(char**, size_t*, int, FILE*);
- // getline() always comes together with getdelim()
- ptrdiff_t getline(char**, size_t*, FILE*);
+ extern(C) nothrow @nogc
+ {
+ // @@@DEPRECATED_2.104@@@
+ deprecated("To be removed after 2.104. Use core.sys.posix.stdio.getdelim instead.")
+ ptrdiff_t getdelim(char**, size_t*, int, FILE*);
+
+ // @@@DEPRECATED_2.104@@@
+ // getline() always comes together with getdelim()
+ deprecated("To be removed after 2.104. Use core.sys.posix.stdio.getline instead.")
+ ptrdiff_t getline(char**, size_t*, FILE*);
+ }
}
//------------------------------------------------------------------------------
@@ -4718,59 +4722,142 @@ private struct ReadlnAppender
}
// Private implementation of readln
-version (DIGITAL_MARS_STDIO)
-private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation /*ignored*/)
+private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation orientation)
{
- FLOCK(fps);
- scope(exit) FUNLOCK(fps);
+ version (DIGITAL_MARS_STDIO)
+ {
+ FLOCK(fps);
+ scope(exit) FUNLOCK(fps);
- /* Since fps is now locked, we can create an "unshared" version
- * of fp.
- */
- auto fp = cast(_iobuf*) fps;
+ /* Since fps is now locked, we can create an "unshared" version
+ * of fp.
+ */
+ auto fp = cast(_iobuf*) fps;
- ReadlnAppender app;
- app.initialize(buf);
+ ReadlnAppender app;
+ app.initialize(buf);
- if (__fhnd_info[fp._file] & FHND_WCHAR)
- { /* Stream is in wide characters.
- * Read them and convert to chars.
- */
- static assert(wchar_t.sizeof == 2);
- for (int c = void; (c = FGETWC(fp)) != -1; )
+ if (__fhnd_info[fp._file] & FHND_WCHAR)
+ { /* Stream is in wide characters.
+ * Read them and convert to chars.
+ */
+ static assert(wchar_t.sizeof == 2);
+ for (int c = void; (c = FGETWC(fp)) != -1; )
+ {
+ if ((c & ~0x7F) == 0)
+ {
+ app.putchar(cast(char) c);
+ if (c == terminator)
+ break;
+ }
+ else
+ {
+ if (c >= 0xD800 && c <= 0xDBFF)
+ {
+ int c2 = void;
+ if ((c2 = FGETWC(fp)) != -1 ||
+ c2 < 0xDC00 && c2 > 0xDFFF)
+ {
+ StdioException("unpaired UTF-16 surrogate");
+ }
+ c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
+ }
+ app.putdchar(cast(dchar) c);
+ }
+ }
+ if (ferror(fps))
+ StdioException();
+ }
+
+ else if (fp._flag & _IONBF)
{
- if ((c & ~0x7F) == 0)
+ /* Use this for unbuffered I/O, when running
+ * across buffer boundaries, or for any but the common
+ * cases.
+ */
+ L1:
+ int c;
+ while ((c = FGETC(fp)) != -1)
{
app.putchar(cast(char) c);
if (c == terminator)
- break;
+ {
+ buf = app.data;
+ return buf.length;
+ }
+
}
- else
- {
- if (c >= 0xD800 && c <= 0xDBFF)
+
+ if (ferror(fps))
+ StdioException();
+ }
+ else
+ {
+ int u = fp._cnt;
+ char* p = fp._ptr;
+ int i;
+ if (fp._flag & _IOTRAN)
+ { /* Translated mode ignores \r and treats ^Z as end-of-file
+ */
+ char c;
+ while (1)
{
- int c2 = void;
- if ((c2 = FGETWC(fp)) != -1 ||
- c2 < 0xDC00 && c2 > 0xDFFF)
+ if (i == u) // if end of buffer
+ goto L1; // give up
+ c = p[i];
+ i++;
+ if (c != '\r')
{
- StdioException("unpaired UTF-16 surrogate");
+ if (c == terminator)
+ break;
+ if (c != 0x1A)
+ continue;
+ goto L1;
+ }
+ else
+ { if (i != u && p[i] == terminator)
+ break;
+ goto L1;
}
- c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
}
- app.putdchar(cast(dchar) c);
+ app.putonly(p[0 .. i]);
+ app.buf[i - 1] = cast(char) terminator;
+ if (terminator == '\n' && c == '\r')
+ i++;
+ }
+ else
+ {
+ while (1)
+ {
+ if (i == u) // if end of buffer
+ goto L1; // give up
+ auto c = p[i];
+ i++;
+ if (c == terminator)
+ break;
+ }
+ app.putonly(p[0 .. i]);
}
+ fp._cnt -= i;
+ fp._ptr += i;
}
- if (ferror(fps))
- StdioException();
- }
- else if (fp._flag & _IONBF)
+ buf = app.data;
+ return buf.length;
+ }
+ else version (MICROSOFT_STDIO)
{
- /* Use this for unbuffered I/O, when running
- * across buffer boundaries, or for any but the common
- * cases.
+ FLOCK(fps);
+ scope(exit) FUNLOCK(fps);
+
+ /* Since fps is now locked, we can create an "unshared" version
+ * of fp.
*/
- L1:
+ auto fp = cast(_iobuf*) fps;
+
+ ReadlnAppender app;
+ app.initialize(buf);
+
int c;
while ((c = FGETC(fp)) != -1)
{
@@ -4785,295 +4872,208 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
if (ferror(fps))
StdioException();
+ buf = app.data;
+ return buf.length;
}
- else
+ else static if (__traits(compiles, core.sys.posix.stdio.getdelim))
{
- int u = fp._cnt;
- char* p = fp._ptr;
- int i;
- if (fp._flag & _IOTRAN)
- { /* Translated mode ignores \r and treats ^Z as end-of-file
+ import core.stdc.stdlib : free;
+ import core.stdc.wchar_ : fwide;
+
+ if (orientation == File.Orientation.wide)
+ {
+ /* Stream is in wide characters.
+ * Read them and convert to chars.
*/
- char c;
- while (1)
+ FLOCK(fps);
+ scope(exit) FUNLOCK(fps);
+ auto fp = cast(_iobuf*) fps;
+ version (Windows)
{
- if (i == u) // if end of buffer
- goto L1; // give up
- c = p[i];
- i++;
- if (c != '\r')
+ buf.length = 0;
+ for (int c = void; (c = FGETWC(fp)) != -1; )
{
- if (c == terminator)
- break;
- if (c != 0x1A)
- continue;
- goto L1;
+ if ((c & ~0x7F) == 0)
+ { buf ~= c;
+ if (c == terminator)
+ break;
+ }
+ else
+ {
+ if (c >= 0xD800 && c <= 0xDBFF)
+ {
+ int c2 = void;
+ if ((c2 = FGETWC(fp)) != -1 ||
+ c2 < 0xDC00 && c2 > 0xDFFF)
+ {
+ StdioException("unpaired UTF-16 surrogate");
+ }
+ c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
+ }
+ import std.utf : encode;
+ encode(buf, c);
+ }
}
- else
- { if (i != u && p[i] == terminator)
+ if (ferror(fp))
+ StdioException();
+ return buf.length;
+ }
+ else version (Posix)
+ {
+ buf.length = 0;
+ for (int c; (c = FGETWC(fp)) != -1; )
+ {
+ import std.utf : encode;
+
+ if ((c & ~0x7F) == 0)
+ buf ~= cast(char) c;
+ else
+ encode(buf, cast(dchar) c);
+ if (c == terminator)
break;
- goto L1;
}
+ if (ferror(fps))
+ StdioException();
+ return buf.length;
+ }
+ else
+ {
+ static assert(0);
}
- app.putonly(p[0 .. i]);
- app.buf[i - 1] = cast(char) terminator;
- if (terminator == '\n' && c == '\r')
- i++;
}
- else
+
+ static char *lineptr = null;
+ static size_t n = 0;
+ scope(exit)
{
- while (1)
+ if (n > 128 * 1024)
{
- if (i == u) // if end of buffer
- goto L1; // give up
- auto c = p[i];
- i++;
- if (c == terminator)
- break;
+ // Bound memory used by readln
+ free(lineptr);
+ lineptr = null;
+ n = 0;
}
- app.putonly(p[0 .. i]);
}
- fp._cnt -= i;
- fp._ptr += i;
- }
-
- buf = app.data;
- return buf.length;
-}
-
-version (MICROSOFT_STDIO)
-private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation /*ignored*/)
-{
- FLOCK(fps);
- scope(exit) FUNLOCK(fps);
- /* Since fps is now locked, we can create an "unshared" version
- * of fp.
- */
- auto fp = cast(_iobuf*) fps;
-
- ReadlnAppender app;
- app.initialize(buf);
-
- int c;
- while ((c = FGETC(fp)) != -1)
- {
- app.putchar(cast(char) c);
- if (c == terminator)
+ auto s = core.sys.posix.stdio.getdelim(&lineptr, &n, terminator, fps);
+ if (s < 0)
{
- buf = app.data;
- return buf.length;
+ if (ferror(fps))
+ StdioException();
+ buf.length = 0; // end of file
+ return 0;
}
+ if (s <= buf.length)
+ {
+ buf = buf[0 .. s];
+ buf[] = lineptr[0 .. s];
+ }
+ else
+ {
+ buf = lineptr[0 .. s].dup;
+ }
+ return s;
}
-
- if (ferror(fps))
- StdioException();
- buf = app.data;
- return buf.length;
-}
-
-version (HAS_GETDELIM)
-private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation orientation)
-{
- import core.stdc.stdlib : free;
- import core.stdc.wchar_ : fwide;
-
- if (orientation == File.Orientation.wide)
+ else // version (NO_GETDELIM)
{
- /* Stream is in wide characters.
- * Read them and convert to chars.
- */
+ import core.stdc.wchar_ : fwide;
+
FLOCK(fps);
scope(exit) FUNLOCK(fps);
auto fp = cast(_iobuf*) fps;
- version (Windows)
+ if (orientation == File.Orientation.wide)
{
- buf.length = 0;
- for (int c = void; (c = FGETWC(fp)) != -1; )
+ /* Stream is in wide characters.
+ * Read them and convert to chars.
+ */
+ version (Windows)
{
- if ((c & ~0x7F) == 0)
- { buf ~= c;
- if (c == terminator)
- break;
- }
- else
+ buf.length = 0;
+ for (int c; (c = FGETWC(fp)) != -1; )
{
- if (c >= 0xD800 && c <= 0xDBFF)
+ if ((c & ~0x7F) == 0)
+ { buf ~= c;
+ if (c == terminator)
+ break;
+ }
+ else
{
- int c2 = void;
- if ((c2 = FGETWC(fp)) != -1 ||
- c2 < 0xDC00 && c2 > 0xDFFF)
+ if (c >= 0xD800 && c <= 0xDBFF)
{
- StdioException("unpaired UTF-16 surrogate");
+ int c2 = void;
+ if ((c2 = FGETWC(fp)) != -1 ||
+ c2 < 0xDC00 && c2 > 0xDFFF)
+ {
+ StdioException("unpaired UTF-16 surrogate");
+ }
+ c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
}
- c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
+ import std.utf : encode;
+ encode(buf, c);
}
- import std.utf : encode;
- encode(buf, c);
}
+ if (ferror(fp))
+ StdioException();
+ return buf.length;
}
- if (ferror(fp))
- StdioException();
- return buf.length;
- }
- else version (Posix)
- {
- buf.length = 0;
- for (int c; (c = FGETWC(fp)) != -1; )
+ else version (Posix)
{
import std.utf : encode;
-
- if ((c & ~0x7F) == 0)
- buf ~= cast(char) c;
- else
- encode(buf, cast(dchar) c);
- if (c == terminator)
- break;
- }
- if (ferror(fps))
- StdioException();
- return buf.length;
- }
- else
- {
- static assert(0);
- }
- }
-
- static char *lineptr = null;
- static size_t n = 0;
- scope(exit)
- {
- if (n > 128 * 1024)
- {
- // Bound memory used by readln
- free(lineptr);
- lineptr = null;
- n = 0;
- }
- }
-
- auto s = getdelim(&lineptr, &n, terminator, fps);
- if (s < 0)
- {
- if (ferror(fps))
- StdioException();
- buf.length = 0; // end of file
- return 0;
- }
-
- if (s <= buf.length)
- {
- buf = buf[0 .. s];
- buf[] = lineptr[0 .. s];
- }
- else
- {
- buf = lineptr[0 .. s].dup;
- }
- return s;
-}
-
-version (NO_GETDELIM)
-private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation orientation)
-{
- import core.stdc.wchar_ : fwide;
-
- FLOCK(fps);
- scope(exit) FUNLOCK(fps);
- auto fp = cast(_iobuf*) fps;
- if (orientation == File.Orientation.wide)
- {
- /* Stream is in wide characters.
- * Read them and convert to chars.
- */
- version (Windows)
- {
- buf.length = 0;
- for (int c; (c = FGETWC(fp)) != -1; )
- {
- if ((c & ~0x7F) == 0)
- { buf ~= c;
+ buf.length = 0;
+ for (int c; (c = FGETWC(fp)) != -1; )
+ {
+ if ((c & ~0x7F) == 0)
+ buf ~= cast(char) c;
+ else
+ encode(buf, cast(dchar) c);
if (c == terminator)
break;
}
- else
- {
- if (c >= 0xD800 && c <= 0xDBFF)
- {
- int c2 = void;
- if ((c2 = FGETWC(fp)) != -1 ||
- c2 < 0xDC00 && c2 > 0xDFFF)
- {
- StdioException("unpaired UTF-16 surrogate");
- }
- c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
- }
- import std.utf : encode;
- encode(buf, c);
- }
+ if (ferror(fps))
+ StdioException();
+ return buf.length;
}
- if (ferror(fp))
- StdioException();
- return buf.length;
- }
- else version (Posix)
- {
- import std.utf : encode;
- buf.length = 0;
- for (int c; (c = FGETWC(fp)) != -1; )
+ else
{
- if ((c & ~0x7F) == 0)
- buf ~= cast(char) c;
- else
- encode(buf, cast(dchar) c);
- if (c == terminator)
- break;
+ static assert(0);
}
- if (ferror(fps))
- StdioException();
- return buf.length;
- }
- else
- {
- static assert(0);
}
- }
- // Narrow stream
- // First, fill the existing buffer
- for (size_t bufPos = 0; bufPos < buf.length; )
- {
- immutable c = FGETC(fp);
- if (c == -1)
+ // Narrow stream
+ // First, fill the existing buffer
+ for (size_t bufPos = 0; bufPos < buf.length; )
{
- buf.length = bufPos;
- goto endGame;
- }
- buf[bufPos++] = cast(char) c;
- if (c == terminator)
- {
- // No need to test for errors in file
- buf.length = bufPos;
- return bufPos;
+ immutable c = FGETC(fp);
+ if (c == -1)
+ {
+ buf.length = bufPos;
+ goto endGame;
+ }
+ buf[bufPos++] = cast(char) c;
+ if (c == terminator)
+ {
+ // No need to test for errors in file
+ buf.length = bufPos;
+ return bufPos;
+ }
}
- }
- // Then, append to it
- for (int c; (c = FGETC(fp)) != -1; )
- {
- buf ~= cast(char) c;
- if (c == terminator)
+ // Then, append to it
+ for (int c; (c = FGETC(fp)) != -1; )
{
- // No need to test for errors in file
- return buf.length;
+ buf ~= cast(char) c;
+ if (c == terminator)
+ {
+ // No need to test for errors in file
+ return buf.length;
+ }
}
- }
- endGame:
- if (ferror(fps))
- StdioException();
- return buf.length;
+ endGame:
+ if (ferror(fps))
+ StdioException();
+ return buf.length;
+ }
}
@system unittest
^ permalink raw reply [flat|nested] 2+ messages in thread
* [gcc(refs/users/iains/heads/d-for-darwin)] libphobos: Move getdelim declaration to druntime, fix stdio logic, add ucontext_t
@ 2020-12-13 17:42 Iain D Sandoe
0 siblings, 0 replies; 2+ messages in thread
From: Iain D Sandoe @ 2020-12-13 17:42 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:d1e20aff423befc98eaba68e19e147f05d98e36b
commit d1e20aff423befc98eaba68e19e147f05d98e36b
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Thu Dec 3 23:51:01 2020 +0100
libphobos: Move getdelim declaration to druntime, fix stdio logic, add ucontext_t
Diff:
---
libphobos/libdruntime/core/sys/posix/stdio.d | 194 +++++---
libphobos/libdruntime/core/sys/posix/ucontext.d | 25 +
libphobos/src/std/stdio.d | 582 ++++++++++++------------
3 files changed, 458 insertions(+), 343 deletions(-)
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index bc2329e6bf8..a47aec525e8 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -249,64 +249,72 @@ else version (Solaris)
/*
L_ctermid
-char* ctermid(char*);
-FILE* fdopen(int, in char*);
-int fileno(FILE*);
-int fseeko(FILE*, off_t, int);
-off_t ftello(FILE*);
-char* gets(char*);
-int pclose(FILE*);
-FILE* popen(in char*, in char*);
+char* ctermid(char*);
+FILE* fdopen(int, const scope char*);
+int fileno(FILE*);
+int fseeko(FILE*, off_t, int);
+off_t ftello(FILE*);
+ssize_t getdelim(char**, size_t*, int, FILE*);
+ssize_t getline(char**, size_t*, FILE*);
+char* gets(char*);
+int pclose(FILE*);
+FILE* popen(const scope char*, const scope char*);
*/
version (CRuntime_Glibc)
{
enum L_ctermid = 9;
- static if ( __USE_FILE_OFFSET64 )
- {
- int fseeko64(FILE*, off_t, int);
- alias fseeko64 fseeko;
- }
- else
- {
- int fseeko(FILE*, off_t, int);
- }
-
- static if ( __USE_FILE_OFFSET64 )
- {
- off_t ftello64(FILE*);
- alias ftello64 ftello;
- }
- else
- {
- off_t ftello(FILE*);
- }
+ static if ( __USE_FILE_OFFSET64 )
+ {
+ int fseeko64(FILE*, off_t, int);
+ alias fseeko64 fseeko;
+ }
+ else
+ {
+ int fseeko(FILE*, off_t, int);
+ }
+
+ static if ( __USE_FILE_OFFSET64 )
+ {
+ off_t ftello64(FILE*);
+ alias ftello64 ftello;
+ }
+ else
+ {
+ off_t ftello(FILE*);
+ }
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
}
else version (CRuntime_UClibc)
{
enum L_ctermid = 9;
enum L_cuserid = 9;
- static if ( __USE_FILE_OFFSET64 )
- {
- int fseeko64(FILE*, off_t, int);
- alias fseeko64 fseeko;
- }
- else
- {
- int fseeko(FILE*, off_t, int);
- }
-
- static if ( __USE_FILE_OFFSET64 )
- {
- off_t ftello64(FILE*);
- alias ftello64 ftello;
- }
- else
- {
- off_t ftello(FILE*);
- }
+ static if ( __USE_FILE_OFFSET64 )
+ {
+ int fseeko64(FILE*, off_t, int);
+ alias fseeko64 fseeko;
+ }
+ else
+ {
+ int fseeko(FILE*, off_t, int);
+ }
+
+ static if ( __USE_FILE_OFFSET64 )
+ {
+ off_t ftello64(FILE*);
+ alias ftello64 ftello;
+ }
+ else
+ {
+ off_t ftello(FILE*);
+ }
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
}
else version (CRuntime_Musl)
{
@@ -331,6 +339,91 @@ else version (CRuntime_Musl)
{
off_t ftello(FILE*);
}
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
+}
+else version (CRuntime_Bionic)
+{
+ enum L_ctermid = 1024;
+
+ static if ( __USE_FILE_OFFSET64 )
+ {
+ int fseeko64(FILE*, off_t, int);
+ alias fseeko64 fseeko;
+ }
+ else
+ {
+ int fseeko(FILE*, off_t, int);
+ }
+
+ static if ( __USE_FILE_OFFSET64 )
+ {
+ off_t ftello64(FILE*);
+ alias ftello64 ftello;
+ }
+ else
+ {
+ off_t ftello(FILE*);
+ }
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
+}
+else version (Darwin)
+{
+ enum L_ctermid = 1024;
+
+ int fseeko(FILE*, off_t, int);
+ off_t ftello(FILE*);
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
+}
+else version (FreeBSD)
+{
+ import core.sys.freebsd.config;
+
+ enum L_ctermid = 1024;
+
+ int fseeko(FILE*, off_t, int);
+ off_t ftello(FILE*);
+
+ static if (__FreeBSD_version >= 800000)
+ {
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
+ }
+}
+else version (NetBSD)
+{
+ enum L_ctermid = 1024;
+
+ int fseeko(FILE*, off_t, int);
+ off_t ftello(FILE*);
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
+}
+else version (OpenBSD)
+{
+ enum L_ctermid = 1024;
+
+ int fseeko(FILE*, off_t, int);
+ off_t ftello(FILE*);
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
+}
+else version (DragonFlyBSD)
+{
+ enum L_ctermid = 1024;
+
+ int fseeko(FILE*, off_t, int);
+ off_t ftello(FILE*);
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
}
else version (Solaris)
{
@@ -356,6 +449,9 @@ else version (Solaris)
{
off_t ftello(FILE*);
}
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
}
else version (Posix)
{
@@ -366,8 +462,6 @@ else version (Posix)
char* ctermid(char*);
FILE* fdopen(int, in char*);
int fileno(FILE*);
-//int fseeko(FILE*, off_t, int);
-//off_t ftello(FILE*);
char* gets(char*);
int pclose(FILE*);
FILE* popen(in char*, in char*);
@@ -546,7 +640,3 @@ unittest
assert(memcmp(ptr, testdata.ptr, testdata.length*wchar_t.sizeof) == 0);
assert(fclose(f) == 0);
}
-
-
-ssize_t getdelim (char** lineptr, size_t* n, int delimiter, FILE* stream);
-ssize_t getline (char** lineptr, size_t* n, FILE* stream);
diff --git a/libphobos/libdruntime/core/sys/posix/ucontext.d b/libphobos/libdruntime/core/sys/posix/ucontext.d
index 2e518aefa84..ef74771a50d 100644
--- a/libphobos/libdruntime/core/sys/posix/ucontext.d
+++ b/libphobos/libdruntime/core/sys/posix/ucontext.d
@@ -23,6 +23,15 @@ extern (C):
nothrow:
@nogc:
+version (OSX)
+ version = Darwin;
+else version (iOS)
+ version = Darwin;
+else version (TVOS)
+ version = Darwin;
+else version (WatchOS)
+ version = Darwin;
+
version (MIPS32) version = MIPS_Any;
version (MIPS64) version = MIPS_Any;
version (PPC) version = PPC_Any;
@@ -909,6 +918,22 @@ else version (CRuntime_Musl)
else
static assert(0, "unimplemented");
}
+else version (Darwin)
+{
+ alias mcontext_t = void;
+
+ struct ucontext
+ {
+ int uc_onstack;
+ sigset_t uc_sigmask;
+ stack_t uc_stack;
+ ucontext* uc_link;
+ size_t uc_mcsize;
+ mcontext_t* uc_mcontext;
+ }
+
+ alias ucontext_t = ucontext;
+}
else version (FreeBSD)
{
// <machine/ucontext.h>
diff --git a/libphobos/src/std/stdio.d b/libphobos/src/std/stdio.d
index 4c1ad0baa15..9265cc05170 100644
--- a/libphobos/src/std/stdio.d
+++ b/libphobos/src/std/stdio.d
@@ -42,43 +42,34 @@ version (CRuntime_Glibc)
{
// Specific to the way Gnu C does stdio
version = GCC_IO;
- version = HAS_GETDELIM;
}
else version (CRuntime_Bionic)
{
version = GENERIC_IO;
- version = HAS_GETDELIM;
}
else version (CRuntime_Musl)
{
version = GENERIC_IO;
- version = HAS_GETDELIM;
}
-
-version (OSX)
+else version (OSX)
{
version = GENERIC_IO;
- version = HAS_GETDELIM;
}
else version (FreeBSD)
{
version = GENERIC_IO;
- version = HAS_GETDELIM;
}
else version (NetBSD)
{
version = GENERIC_IO;
- version = HAS_GETDELIM;
}
else version (DragonFlyBSD)
{
version = GENERIC_IO;
- version = HAS_GETDELIM;
}
else version (Solaris)
{
version = GENERIC_IO;
- version = NO_GETDELIM;
}
// Character type used for operating system filesystem APIs
@@ -105,6 +96,11 @@ version (Windows)
import core.sys.windows.windows : HANDLE;
}
+version (Posix)
+{
+ static import core.sys.posix.stdio; // getdelim
+}
+
version (DIGITAL_MARS_STDIO)
{
extern (C)
@@ -244,11 +240,19 @@ else
static assert(0, "unsupported C I/O system");
}
-version (HAS_GETDELIM) extern(C) nothrow @nogc
+static if (__traits(compiles, core.sys.posix.stdio.getdelim))
{
- ptrdiff_t getdelim(char**, size_t*, int, FILE*);
- // getline() always comes together with getdelim()
- ptrdiff_t getline(char**, size_t*, FILE*);
+ extern(C) nothrow @nogc
+ {
+ // @@@DEPRECATED_2.104@@@
+ deprecated("To be removed after 2.104. Use core.sys.posix.stdio.getdelim instead.")
+ ptrdiff_t getdelim(char**, size_t*, int, FILE*);
+
+ // @@@DEPRECATED_2.104@@@
+ // getline() always comes together with getdelim()
+ deprecated("To be removed after 2.104. Use core.sys.posix.stdio.getline instead.")
+ ptrdiff_t getline(char**, size_t*, FILE*);
+ }
}
//------------------------------------------------------------------------------
@@ -4718,59 +4722,142 @@ private struct ReadlnAppender
}
// Private implementation of readln
-version (DIGITAL_MARS_STDIO)
-private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation /*ignored*/)
+private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation orientation)
{
- FLOCK(fps);
- scope(exit) FUNLOCK(fps);
+ version (DIGITAL_MARS_STDIO)
+ {
+ FLOCK(fps);
+ scope(exit) FUNLOCK(fps);
- /* Since fps is now locked, we can create an "unshared" version
- * of fp.
- */
- auto fp = cast(_iobuf*) fps;
+ /* Since fps is now locked, we can create an "unshared" version
+ * of fp.
+ */
+ auto fp = cast(_iobuf*) fps;
- ReadlnAppender app;
- app.initialize(buf);
+ ReadlnAppender app;
+ app.initialize(buf);
- if (__fhnd_info[fp._file] & FHND_WCHAR)
- { /* Stream is in wide characters.
- * Read them and convert to chars.
- */
- static assert(wchar_t.sizeof == 2);
- for (int c = void; (c = FGETWC(fp)) != -1; )
+ if (__fhnd_info[fp._file] & FHND_WCHAR)
+ { /* Stream is in wide characters.
+ * Read them and convert to chars.
+ */
+ static assert(wchar_t.sizeof == 2);
+ for (int c = void; (c = FGETWC(fp)) != -1; )
+ {
+ if ((c & ~0x7F) == 0)
+ {
+ app.putchar(cast(char) c);
+ if (c == terminator)
+ break;
+ }
+ else
+ {
+ if (c >= 0xD800 && c <= 0xDBFF)
+ {
+ int c2 = void;
+ if ((c2 = FGETWC(fp)) != -1 ||
+ c2 < 0xDC00 && c2 > 0xDFFF)
+ {
+ StdioException("unpaired UTF-16 surrogate");
+ }
+ c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
+ }
+ app.putdchar(cast(dchar) c);
+ }
+ }
+ if (ferror(fps))
+ StdioException();
+ }
+
+ else if (fp._flag & _IONBF)
{
- if ((c & ~0x7F) == 0)
+ /* Use this for unbuffered I/O, when running
+ * across buffer boundaries, or for any but the common
+ * cases.
+ */
+ L1:
+ int c;
+ while ((c = FGETC(fp)) != -1)
{
app.putchar(cast(char) c);
if (c == terminator)
- break;
+ {
+ buf = app.data;
+ return buf.length;
+ }
+
}
- else
- {
- if (c >= 0xD800 && c <= 0xDBFF)
+
+ if (ferror(fps))
+ StdioException();
+ }
+ else
+ {
+ int u = fp._cnt;
+ char* p = fp._ptr;
+ int i;
+ if (fp._flag & _IOTRAN)
+ { /* Translated mode ignores \r and treats ^Z as end-of-file
+ */
+ char c;
+ while (1)
{
- int c2 = void;
- if ((c2 = FGETWC(fp)) != -1 ||
- c2 < 0xDC00 && c2 > 0xDFFF)
+ if (i == u) // if end of buffer
+ goto L1; // give up
+ c = p[i];
+ i++;
+ if (c != '\r')
{
- StdioException("unpaired UTF-16 surrogate");
+ if (c == terminator)
+ break;
+ if (c != 0x1A)
+ continue;
+ goto L1;
+ }
+ else
+ { if (i != u && p[i] == terminator)
+ break;
+ goto L1;
}
- c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
}
- app.putdchar(cast(dchar) c);
+ app.putonly(p[0 .. i]);
+ app.buf[i - 1] = cast(char) terminator;
+ if (terminator == '\n' && c == '\r')
+ i++;
+ }
+ else
+ {
+ while (1)
+ {
+ if (i == u) // if end of buffer
+ goto L1; // give up
+ auto c = p[i];
+ i++;
+ if (c == terminator)
+ break;
+ }
+ app.putonly(p[0 .. i]);
}
+ fp._cnt -= i;
+ fp._ptr += i;
}
- if (ferror(fps))
- StdioException();
- }
- else if (fp._flag & _IONBF)
+ buf = app.data;
+ return buf.length;
+ }
+ else version (MICROSOFT_STDIO)
{
- /* Use this for unbuffered I/O, when running
- * across buffer boundaries, or for any but the common
- * cases.
+ FLOCK(fps);
+ scope(exit) FUNLOCK(fps);
+
+ /* Since fps is now locked, we can create an "unshared" version
+ * of fp.
*/
- L1:
+ auto fp = cast(_iobuf*) fps;
+
+ ReadlnAppender app;
+ app.initialize(buf);
+
int c;
while ((c = FGETC(fp)) != -1)
{
@@ -4785,295 +4872,208 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
if (ferror(fps))
StdioException();
+ buf = app.data;
+ return buf.length;
}
- else
+ else static if (__traits(compiles, core.sys.posix.stdio.getdelim))
{
- int u = fp._cnt;
- char* p = fp._ptr;
- int i;
- if (fp._flag & _IOTRAN)
- { /* Translated mode ignores \r and treats ^Z as end-of-file
+ import core.stdc.stdlib : free;
+ import core.stdc.wchar_ : fwide;
+
+ if (orientation == File.Orientation.wide)
+ {
+ /* Stream is in wide characters.
+ * Read them and convert to chars.
*/
- char c;
- while (1)
+ FLOCK(fps);
+ scope(exit) FUNLOCK(fps);
+ auto fp = cast(_iobuf*) fps;
+ version (Windows)
{
- if (i == u) // if end of buffer
- goto L1; // give up
- c = p[i];
- i++;
- if (c != '\r')
+ buf.length = 0;
+ for (int c = void; (c = FGETWC(fp)) != -1; )
{
- if (c == terminator)
- break;
- if (c != 0x1A)
- continue;
- goto L1;
+ if ((c & ~0x7F) == 0)
+ { buf ~= c;
+ if (c == terminator)
+ break;
+ }
+ else
+ {
+ if (c >= 0xD800 && c <= 0xDBFF)
+ {
+ int c2 = void;
+ if ((c2 = FGETWC(fp)) != -1 ||
+ c2 < 0xDC00 && c2 > 0xDFFF)
+ {
+ StdioException("unpaired UTF-16 surrogate");
+ }
+ c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
+ }
+ import std.utf : encode;
+ encode(buf, c);
+ }
}
- else
- { if (i != u && p[i] == terminator)
+ if (ferror(fp))
+ StdioException();
+ return buf.length;
+ }
+ else version (Posix)
+ {
+ buf.length = 0;
+ for (int c; (c = FGETWC(fp)) != -1; )
+ {
+ import std.utf : encode;
+
+ if ((c & ~0x7F) == 0)
+ buf ~= cast(char) c;
+ else
+ encode(buf, cast(dchar) c);
+ if (c == terminator)
break;
- goto L1;
}
+ if (ferror(fps))
+ StdioException();
+ return buf.length;
+ }
+ else
+ {
+ static assert(0);
}
- app.putonly(p[0 .. i]);
- app.buf[i - 1] = cast(char) terminator;
- if (terminator == '\n' && c == '\r')
- i++;
}
- else
+
+ static char *lineptr = null;
+ static size_t n = 0;
+ scope(exit)
{
- while (1)
+ if (n > 128 * 1024)
{
- if (i == u) // if end of buffer
- goto L1; // give up
- auto c = p[i];
- i++;
- if (c == terminator)
- break;
+ // Bound memory used by readln
+ free(lineptr);
+ lineptr = null;
+ n = 0;
}
- app.putonly(p[0 .. i]);
}
- fp._cnt -= i;
- fp._ptr += i;
- }
-
- buf = app.data;
- return buf.length;
-}
-
-version (MICROSOFT_STDIO)
-private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation /*ignored*/)
-{
- FLOCK(fps);
- scope(exit) FUNLOCK(fps);
- /* Since fps is now locked, we can create an "unshared" version
- * of fp.
- */
- auto fp = cast(_iobuf*) fps;
-
- ReadlnAppender app;
- app.initialize(buf);
-
- int c;
- while ((c = FGETC(fp)) != -1)
- {
- app.putchar(cast(char) c);
- if (c == terminator)
+ auto s = core.sys.posix.stdio.getdelim(&lineptr, &n, terminator, fps);
+ if (s < 0)
{
- buf = app.data;
- return buf.length;
+ if (ferror(fps))
+ StdioException();
+ buf.length = 0; // end of file
+ return 0;
}
+ if (s <= buf.length)
+ {
+ buf = buf[0 .. s];
+ buf[] = lineptr[0 .. s];
+ }
+ else
+ {
+ buf = lineptr[0 .. s].dup;
+ }
+ return s;
}
-
- if (ferror(fps))
- StdioException();
- buf = app.data;
- return buf.length;
-}
-
-version (HAS_GETDELIM)
-private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation orientation)
-{
- import core.stdc.stdlib : free;
- import core.stdc.wchar_ : fwide;
-
- if (orientation == File.Orientation.wide)
+ else // version (NO_GETDELIM)
{
- /* Stream is in wide characters.
- * Read them and convert to chars.
- */
+ import core.stdc.wchar_ : fwide;
+
FLOCK(fps);
scope(exit) FUNLOCK(fps);
auto fp = cast(_iobuf*) fps;
- version (Windows)
+ if (orientation == File.Orientation.wide)
{
- buf.length = 0;
- for (int c = void; (c = FGETWC(fp)) != -1; )
+ /* Stream is in wide characters.
+ * Read them and convert to chars.
+ */
+ version (Windows)
{
- if ((c & ~0x7F) == 0)
- { buf ~= c;
- if (c == terminator)
- break;
- }
- else
+ buf.length = 0;
+ for (int c; (c = FGETWC(fp)) != -1; )
{
- if (c >= 0xD800 && c <= 0xDBFF)
+ if ((c & ~0x7F) == 0)
+ { buf ~= c;
+ if (c == terminator)
+ break;
+ }
+ else
{
- int c2 = void;
- if ((c2 = FGETWC(fp)) != -1 ||
- c2 < 0xDC00 && c2 > 0xDFFF)
+ if (c >= 0xD800 && c <= 0xDBFF)
{
- StdioException("unpaired UTF-16 surrogate");
+ int c2 = void;
+ if ((c2 = FGETWC(fp)) != -1 ||
+ c2 < 0xDC00 && c2 > 0xDFFF)
+ {
+ StdioException("unpaired UTF-16 surrogate");
+ }
+ c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
}
- c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
+ import std.utf : encode;
+ encode(buf, c);
}
- import std.utf : encode;
- encode(buf, c);
}
+ if (ferror(fp))
+ StdioException();
+ return buf.length;
}
- if (ferror(fp))
- StdioException();
- return buf.length;
- }
- else version (Posix)
- {
- buf.length = 0;
- for (int c; (c = FGETWC(fp)) != -1; )
+ else version (Posix)
{
import std.utf : encode;
-
- if ((c & ~0x7F) == 0)
- buf ~= cast(char) c;
- else
- encode(buf, cast(dchar) c);
- if (c == terminator)
- break;
- }
- if (ferror(fps))
- StdioException();
- return buf.length;
- }
- else
- {
- static assert(0);
- }
- }
-
- static char *lineptr = null;
- static size_t n = 0;
- scope(exit)
- {
- if (n > 128 * 1024)
- {
- // Bound memory used by readln
- free(lineptr);
- lineptr = null;
- n = 0;
- }
- }
-
- auto s = getdelim(&lineptr, &n, terminator, fps);
- if (s < 0)
- {
- if (ferror(fps))
- StdioException();
- buf.length = 0; // end of file
- return 0;
- }
-
- if (s <= buf.length)
- {
- buf = buf[0 .. s];
- buf[] = lineptr[0 .. s];
- }
- else
- {
- buf = lineptr[0 .. s].dup;
- }
- return s;
-}
-
-version (NO_GETDELIM)
-private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation orientation)
-{
- import core.stdc.wchar_ : fwide;
-
- FLOCK(fps);
- scope(exit) FUNLOCK(fps);
- auto fp = cast(_iobuf*) fps;
- if (orientation == File.Orientation.wide)
- {
- /* Stream is in wide characters.
- * Read them and convert to chars.
- */
- version (Windows)
- {
- buf.length = 0;
- for (int c; (c = FGETWC(fp)) != -1; )
- {
- if ((c & ~0x7F) == 0)
- { buf ~= c;
+ buf.length = 0;
+ for (int c; (c = FGETWC(fp)) != -1; )
+ {
+ if ((c & ~0x7F) == 0)
+ buf ~= cast(char) c;
+ else
+ encode(buf, cast(dchar) c);
if (c == terminator)
break;
}
- else
- {
- if (c >= 0xD800 && c <= 0xDBFF)
- {
- int c2 = void;
- if ((c2 = FGETWC(fp)) != -1 ||
- c2 < 0xDC00 && c2 > 0xDFFF)
- {
- StdioException("unpaired UTF-16 surrogate");
- }
- c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
- }
- import std.utf : encode;
- encode(buf, c);
- }
+ if (ferror(fps))
+ StdioException();
+ return buf.length;
}
- if (ferror(fp))
- StdioException();
- return buf.length;
- }
- else version (Posix)
- {
- import std.utf : encode;
- buf.length = 0;
- for (int c; (c = FGETWC(fp)) != -1; )
+ else
{
- if ((c & ~0x7F) == 0)
- buf ~= cast(char) c;
- else
- encode(buf, cast(dchar) c);
- if (c == terminator)
- break;
+ static assert(0);
}
- if (ferror(fps))
- StdioException();
- return buf.length;
- }
- else
- {
- static assert(0);
}
- }
- // Narrow stream
- // First, fill the existing buffer
- for (size_t bufPos = 0; bufPos < buf.length; )
- {
- immutable c = FGETC(fp);
- if (c == -1)
+ // Narrow stream
+ // First, fill the existing buffer
+ for (size_t bufPos = 0; bufPos < buf.length; )
{
- buf.length = bufPos;
- goto endGame;
- }
- buf[bufPos++] = cast(char) c;
- if (c == terminator)
- {
- // No need to test for errors in file
- buf.length = bufPos;
- return bufPos;
+ immutable c = FGETC(fp);
+ if (c == -1)
+ {
+ buf.length = bufPos;
+ goto endGame;
+ }
+ buf[bufPos++] = cast(char) c;
+ if (c == terminator)
+ {
+ // No need to test for errors in file
+ buf.length = bufPos;
+ return bufPos;
+ }
}
- }
- // Then, append to it
- for (int c; (c = FGETC(fp)) != -1; )
- {
- buf ~= cast(char) c;
- if (c == terminator)
+ // Then, append to it
+ for (int c; (c = FGETC(fp)) != -1; )
{
- // No need to test for errors in file
- return buf.length;
+ buf ~= cast(char) c;
+ if (c == terminator)
+ {
+ // No need to test for errors in file
+ return buf.length;
+ }
}
- }
- endGame:
- if (ferror(fps))
- StdioException();
- return buf.length;
+ endGame:
+ if (ferror(fps))
+ StdioException();
+ return buf.length;
+ }
}
@system unittest
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2020-12-21 20:36 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-21 20:36 [gcc(refs/users/iains/heads/d-for-darwin)] libphobos: Move getdelim declaration to druntime, fix stdio logic, add ucontext_t Iain D Sandoe
-- strict thread matches above, loose matches on Subject: below --
2020-12-13 17:42 Iain D Sandoe
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).