Discussion:
fix mbsinit for MSVC
(too old to reply)
Bruno Haible
2017-04-21 14:43:27 UTC
Permalink
Raw Message
On MSVC 14, test-mbrtowc-w32-3.sh fails, because at
test-mbrtowc-w32.c:301 the state is { 0x00, 0x96, 0x00, 0x00 },
which is the initial state, but mbsinit does not recognize it,
because it's not in sync with the definition of mbrtowc.
This fixes it.

Note that on MSVC, GNULIB_defined_mbstate_t is defined, because
HAVE_MBSINIT = 0 and REPLACE_MBSTATE_T = 1. configure determines these
values, because mbsinit() is defined as an inline function. Maybe we
could make use of the native mbsinit and mbrtowc. Don't know...


2017-04-21 Bruno Haible <***@clisp.org>

mbsinit: Fix for MSVC 14.
* lib/mbsinit.c (mbsinit): If GNULIB_defined_mbstate_t, provide an
implementation that is in sync with mbrtowc.c. On other platforms, use
an adequate ad-hoc implementation.

diff --git a/lib/mbsinit.c b/lib/mbsinit.c
index 58e0441..7580126 100644
--- a/lib/mbsinit.c
+++ b/lib/mbsinit.c
@@ -22,17 +22,7 @@

#include "verify.h"

-#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
-
-/* On native Windows, 'mbstate_t' is defined as 'int'. */
-
-int
-mbsinit (const mbstate_t *ps)
-{
- return ps == NULL || *ps == 0;
-}
-
-#else
+#if GNULIB_defined_mbstate_t

/* Platforms that lack mbsinit() also lack mbrlen(), mbrtowc(), mbsrtowcs()
and wcrtomb(), wcsrtombs().
@@ -45,6 +35,7 @@ mbsinit (const mbstate_t *ps)
We define the meaning of mbstate_t as follows:
- In mb -> wc direction, mbstate_t's first byte contains the number of
buffered bytes (in the range 0..3), followed by up to 3 buffered bytes.
+ See mbrtowc.c.
- In wc -> mb direction, mbstate_t contains no information. In other
words, it is always in the initial state. */

@@ -58,4 +49,25 @@ mbsinit (const mbstate_t *ps)
return pstate == NULL || pstate[0] == 0;
}

+#else
+
+int
+mbsinit (const mbstate_t *ps)
+{
+# if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
+ /* Native Windows. */
+# ifdef __MINGW32__
+ /* On mingw, 'mbstate_t' is defined as 'int'. */
+ return ps == NULL || *ps == 0;
+# else
+ /* MSVC defines 'mbstate_t' as an 8-byte struct; the first 4-bytes matter. */
+ return ps == NULL || *(const unsigned int *)ps == 0;
+# endif
+# else
+ /* Minix, HP-UX 11.00, Solaris 2.6, Interix, ... */
+ /* Maybe this definition works, maybe not... */
+ return ps == NULL || *(const char *)ps == 0;
+# endif
+}
+
#endif

Loading...