bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

mbrtowc: don't replace mbstate_t on MSVC


From: Bruno Haible
Subject: mbrtowc: don't replace mbstate_t on MSVC
Date: Thu, 02 Jan 2020 18:36:59 +0100
User-agent: KMail/5.1.3 (Linux/4.4.0-170-generic; KDE/5.18.0; x86_64; ; )

Currently, REPLACE_MBSTATE_T is set to 1 on MSVC, but not on mingw.
Why? Because mbsinit is not declared as a global function on MSVC, only as
an inline function.
This has the effect of constraining the possible implementations of mbrtowc
and mbrtoc32.

There is actually no need to set REPLACE_MBSTATE_T, because we know how
the mbsinit function works on this platform, and it's fine.

So let's set REPLACE_MBSTATE_T=0 on this platform. But we do need to override
wcrtomb, otherwise the unit test fails. Here's a small standalone test program:
============================================================
#include <locale.h>
#include <stdlib.h>
#include <wchar.h>

int
main (int argc, char *argv[])
{
  if (setlocale (LC_ALL, "French_France.65001") == NULL)
    return 1;

  wchar_t wc;
  int iret;
  size_t ret;

  wc = (wchar_t) 0xBADFACE;
  iret = mbtowc (&wc, "\303\274", 2);
  if (iret != 2)
    return 2;

  ret = wcrtomb (NULL, wc, NULL);
  if (ret != 1)
    return 3;

  return 0;
}
============================================================


2020-01-02  Bruno Haible  <address@hidden>

        mbrtowc: Don't replace mbstate_t on MSVC.
        * m4/mbrtowc.m4 (gl_MBSTATE_T_BROKEN): Require AC_CANONICAL_HOST. Ignore
        a missing mbsinit function on native Windows.
        * m4/wcrtomb.m4 (gl_FUNC_WCRTOMB): Strengthen the test, to detect an
        MSVC bug.
        * doc/posix-functions/wcrtomb.texi: Mention the MSVC bug.

diff --git a/m4/mbrtowc.m4 b/m4/mbrtowc.m4
index c747ea2..af4e25d 100644
--- a/m4/mbrtowc.m4
+++ b/m4/mbrtowc.m4
@@ -1,4 +1,4 @@
-# mbrtowc.m4 serial 34  -*- coding: utf-8 -*-
+# mbrtowc.m4 serial 35  -*- coding: utf-8 -*-
 dnl Copyright (C) 2001-2002, 2004-2005, 2008-2020 Free Software Foundation,
 dnl Inc.
 dnl This file is free software; the Free Software Foundation
@@ -97,11 +97,19 @@ dnl avoid inconsistencies.
 AC_DEFUN([gl_MBSTATE_T_BROKEN],
 [
   AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
+  AC_REQUIRE([AC_CANONICAL_HOST])
 
   AC_REQUIRE([AC_TYPE_MBSTATE_T])
   AC_CHECK_FUNCS_ONCE([mbsinit])
   AC_CHECK_FUNCS_ONCE([mbrtowc])
-  if test $ac_cv_func_mbsinit = yes && test $ac_cv_func_mbrtowc = yes; then
+  dnl On native Windows, we know exactly how mbsinit() behaves and don't need
+  dnl to override it, even if - like on MSVC - mbsinit() is only defined as
+  dnl an inline function, not as a global function.
+  if case "$host_os" in
+       mingw*) true ;;
+       *) test $ac_cv_func_mbsinit = yes ;;
+     esac \
+    && test $ac_cv_func_mbrtowc = yes; then
     gl_MBRTOWC_INCOMPLETE_STATE
     gl_MBRTOWC_SANITYCHECK
     REPLACE_MBSTATE_T=0
diff --git a/m4/wcrtomb.m4 b/m4/wcrtomb.m4
index 73c551b..64e5110 100644
--- a/m4/wcrtomb.m4
+++ b/m4/wcrtomb.m4
@@ -1,4 +1,4 @@
-# wcrtomb.m4 serial 14
+# wcrtomb.m4 serial 15
 dnl Copyright (C) 2008-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -90,12 +90,10 @@ int main ()
           dnl is present.
 changequote(,)dnl
           case "$host_os" in
-                                     # Guess no on AIX 4, OSF/1 and Solaris.
-            aix4* | osf* | solaris*) gl_cv_func_wcrtomb_retval="guessing no" ;;
-                                     # Guess yes on native Windows.
-            mingw*)                  gl_cv_func_wcrtomb_retval="guessing yes" 
;;
-                                     # Guess yes otherwise.
-            *)                       gl_cv_func_wcrtomb_retval="guessing yes" 
;;
+            # Guess no on AIX 4, OSF/1, Solaris, native Windows.
+            aix4* | osf* | solaris* | mingw*) 
gl_cv_func_wcrtomb_retval="guessing no" ;;
+            # Guess yes otherwise.
+            *)                                
gl_cv_func_wcrtomb_retval="guessing yes" ;;
           esac
 changequote([,])dnl
           if test $LOCALE_FR != none || test $LOCALE_FR_UTF8 != none || test 
$LOCALE_JA != none || test $LOCALE_ZH_CN != none; then
@@ -111,6 +109,7 @@ changequote([,])dnl
 #include <stdio.h>
 #include <time.h>
 #include <wchar.h>
+#include <stdlib.h>
 int main ()
 {
   int result = 0;
@@ -123,6 +122,12 @@ int main ()
     {
       if (wcrtomb (NULL, 0, NULL) != 1)
         result |= 2;
+      {
+        wchar_t wc = (wchar_t) 0xBADFACE;
+        if (mbtowc (&wc, "\303\274", 2) == 2)
+          if (wcrtomb (NULL, wc, NULL) != 1)
+            result |= 2;
+      }
     }
   if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
     {
diff --git a/doc/posix-functions/wcrtomb.texi b/doc/posix-functions/wcrtomb.texi
index 20902e9..232bea4 100644
--- a/doc/posix-functions/wcrtomb.texi
+++ b/doc/posix-functions/wcrtomb.texi
@@ -17,6 +17,9 @@ Android 4.3.
 @item
 This function returns 0 when the first argument is NULL in some locales on 
some platforms:
 Solaris 11.3.
+@item
+This function does not ignore the second argument when the first argument is 
NULL on some platforms:
+MSVC 14.
 @end itemize
 
 Portability problems not fixed by Gnulib:




reply via email to

[Prev in Thread] Current Thread [Next in Thread]