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).