Implement mingw-w64 emulation of fgetws() via fwscanf() with "%l[^\n]"
format to have C95+ compatibility.

Note that scanf format does not support specifying length of the string
buffer via additional argument (like printf format "*"), so specify length
of the buffer directly in the format generated by swprintf function.
Function fgetws() has to return also the trailing newline if there is a
place for it in buffer, so read it by additional fwscanf() call.
---
 mingw-w64-crt/Makefile.am    |  2 ++
 mingw-w64-crt/stdio/fgetws.c | 59 ++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+)
 create mode 100644 mingw-w64-crt/stdio/fgetws.c

diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index 69d86460a16e..37fad69169db 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -751,6 +751,7 @@ src_crtdll=\
   stdio/_vscprintf.c \
   stdio/_vscwprintf.c \
   stdio/atoll.c \
+  stdio/fgetws.c \
   stdio/fputws.c \
   stdio/fgetpos.c \
   stdio/fsetpos.c \
@@ -821,6 +822,7 @@ src_msvcrt10=\
   stdio/_vscprintf.c \
   stdio/_vscwprintf.c \
   stdio/atoll.c \
+  stdio/fgetws.c \
   stdio/fputws.c \
   stdio/fgetpos.c \
   stdio/fsetpos.c \
diff --git a/mingw-w64-crt/stdio/fgetws.c b/mingw-w64-crt/stdio/fgetws.c
new file mode 100644
index 000000000000..df2ee3a9e8dd
--- /dev/null
+++ b/mingw-w64-crt/stdio/fgetws.c
@@ -0,0 +1,59 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+
+wchar_t *__cdecl fgetws(wchar_t * __restrict__ _Dst, int _SizeInWords, FILE * 
__restrict__ _File)
+{
+    wchar_t format[19];
+    int count;
+    int ret;
+
+    if (_Dst == NULL || _SizeInWords <= 0)
+    {
+        errno = EINVAL;
+        return NULL;
+    }
+
+    if (_SizeInWords == 1)
+    {
+        _Dst[0] = L'\0';
+        return _Dst;
+    }
+
+    /* _SizeInWords-1 must be positive as it is maximum width for %l[ format */
+    if (_swprintf(format, L"%%%dl[^\n]%%n", _SizeInWords-1) < 0)
+    {
+        return NULL;
+    }
+
+    ret = __ms_fwscanf(_File, format, _Dst, &count);
+
+    /* fwscanf() returns zero if the format "%l[^\n]" does not match any 
character
+     * which means that the first character in _File has to be new line */
+    if (ret == 0)
+    {
+        _Dst[0] = L'\0';
+        count = 0;
+        ret = 2;
+    }
+
+    if (ret < 2)
+    {
+        return NULL;
+    }
+
+    if (count < _SizeInWords-1)
+    {
+        if (__ms_fwscanf(_File, L"%1l[\n]", &_Dst[count]) == 1)
+        {
+            count++;
+        }
+    }
+
+    return _Dst;
+}
-- 
2.20.1



_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to