mirror of
https://git.savannah.gnu.org/git/gnulib.git
synced 2026-10-24 00:48:56 +03:00
wcrtomb: Make consistent with mbrtowc (regression 2016-04-09).
* m4/wcrtomb.m4 (gl_FUNC_WCRTOMB): Require gl_MBRTOWC_C_LOCALE and, if needed, set REPLACE_WCRTOMB and define MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ. * lib/mbrtowc.c (rpl_mbrtowc) [MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ]: In the C locale, map 0x80..0xFF to 0xDF80..0xDFFF instead of 0x0080..0x00FF. * lib/wcrtomb.c: Include hard-locale.h, <locale.h>. (wcrtomb) [MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ]: In the C locale, map 0xDF80..0xDFFF to 0x80..0xFF. * modules/wcrtomb (Depends-on): Add hard-locale. * tests/test-wcrtomb.c (main): Check that wcrtomb does the inverse of mbrtowc in the C locale.
This commit is contained in:
14
ChangeLog
14
ChangeLog
@@ -1,3 +1,17 @@
|
||||
2026-09-20 Bruno Haible <bruno@clisp.org>
|
||||
|
||||
wcrtomb: Make consistent with mbrtowc (regression 2016-04-09).
|
||||
* m4/wcrtomb.m4 (gl_FUNC_WCRTOMB): Require gl_MBRTOWC_C_LOCALE and, if
|
||||
needed, set REPLACE_WCRTOMB and define MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ.
|
||||
* lib/mbrtowc.c (rpl_mbrtowc) [MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ]: In the
|
||||
C locale, map 0x80..0xFF to 0xDF80..0xDFFF instead of 0x0080..0x00FF.
|
||||
* lib/wcrtomb.c: Include hard-locale.h, <locale.h>.
|
||||
(wcrtomb) [MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ]: In the C locale, map
|
||||
0xDF80..0xDFFF to 0x80..0xFF.
|
||||
* modules/wcrtomb (Depends-on): Add hard-locale.
|
||||
* tests/test-wcrtomb.c (main): Check that wcrtomb does the inverse of
|
||||
mbrtowc in the C locale.
|
||||
|
||||
2026-09-19 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Pacify -Waddress on MS-Windows
|
||||
|
||||
@@ -78,7 +78,7 @@ mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
|
||||
# include "localcharset.h"
|
||||
# include "streq-opt.h"
|
||||
|
||||
# if MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ
|
||||
# if MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ /* glibc, Cygwin < 3.5 */
|
||||
# include "hard-locale.h"
|
||||
# include <locale.h>
|
||||
# endif
|
||||
@@ -342,11 +342,12 @@ rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
|
||||
return 0;
|
||||
# endif
|
||||
|
||||
# if MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ
|
||||
# if MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ /* glibc, Cygwin < 3.5 */
|
||||
/* In the C locale, map 0x80..0xFF to 0xDF80..0xDFFF. */
|
||||
if ((size_t) -2 <= ret && n != 0 && ! hard_locale (LC_CTYPE))
|
||||
{
|
||||
unsigned char uc = *s;
|
||||
*pwc = uc;
|
||||
*pwc = 0xDF00 + uc;
|
||||
return 1;
|
||||
}
|
||||
# endif
|
||||
|
||||
@@ -23,6 +23,11 @@
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ
|
||||
# include "hard-locale.h"
|
||||
# include <locale.h>
|
||||
#endif
|
||||
|
||||
|
||||
size_t
|
||||
wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
|
||||
@@ -38,7 +43,8 @@ wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
|
||||
|
||||
#if !HAVE_WCRTOMB /* HP-UX 11.00, mingw */ \
|
||||
|| WCRTOMB_RETVAL_BUG /* Solaris 11.3, MSVC */ \
|
||||
|| WCRTOMB_C_LOCALE_BUG /* Android */
|
||||
|| WCRTOMB_C_LOCALE_BUG /* Android */ \
|
||||
|| MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ /* glibc, Cygwin < 3.5 */
|
||||
if (s == NULL)
|
||||
/* We know the NUL wide character corresponds to the NUL character. */
|
||||
return 1;
|
||||
@@ -60,6 +66,15 @@ wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
|
||||
return (size_t)(-1);
|
||||
}
|
||||
# else
|
||||
# if MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ /* glibc, Cygwin < 3.5 */
|
||||
/* Implement consistently with mbrtowc(): through a 1:1 correspondence,
|
||||
mapping 0xDF80..0xDFFF back to 0x80..0xFF. */
|
||||
if (wc >= 0xDF80 && wc <= 0xDFFF && ! hard_locale (LC_CTYPE))
|
||||
{
|
||||
*s = (unsigned char) (wc - 0xDF00);
|
||||
return 1;
|
||||
}
|
||||
# endif
|
||||
return wcrtomb (s, wc, ps);
|
||||
# endif
|
||||
#else /* HP-UX 11.00, mingw */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# wcrtomb.m4
|
||||
# serial 24
|
||||
# serial 25
|
||||
dnl Copyright (C) 2008-2026 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
@@ -145,6 +145,15 @@ int main ()
|
||||
REPLACE_WCRTOMB=1 ;;
|
||||
esac
|
||||
fi
|
||||
dnl When we adjust mbrtowc in the C locale, we need to adjust wcrtomb as well, for consistency.
|
||||
AC_REQUIRE([gl_MBRTOWC_C_LOCALE])
|
||||
case "$gl_cv_func_mbrtowc_C_locale_sans_EILSEQ" in
|
||||
*yes) ;;
|
||||
*) AC_DEFINE([MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ], [1],
|
||||
[Define if the mbrtowc function may signal encoding errors in the C locale.])
|
||||
REPLACE_WCRTOMB=1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ m4/codeset.m4
|
||||
Depends-on:
|
||||
wchar-h
|
||||
extensions
|
||||
hard-locale [test $HAVE_WCRTOMB = 0 || test $REPLACE_WCRTOMB = 1]
|
||||
mbsinit [test $HAVE_WCRTOMB = 0 || test $REPLACE_WCRTOMB = 1]
|
||||
|
||||
configure.ac:
|
||||
|
||||
@@ -114,6 +114,23 @@ main (int argc, char *argv[])
|
||||
{
|
||||
case '1':
|
||||
/* C locale; tested above. */
|
||||
#if !defined __ANDROID__
|
||||
/* On Android ≥ 5.0, the default locale is the "C.UTF-8" locale, not the
|
||||
"C" locale. Furthermore, when you attempt to set the "C" or "POSIX"
|
||||
locale via setlocale(), what you get is a "C" locale with UTF-8
|
||||
encoding, that is, effectively the "C.UTF-8" locale. */
|
||||
/* Check that wcrtomb does the inverse of mbrtowc, in the C locale.
|
||||
Recall that POSIX:2024 says about mbrtowc:
|
||||
"In the POSIX locale an [EILSEQ] error cannot occur since all
|
||||
byte values are valid characters."
|
||||
Above we have only tested the ISO C "basic character set". */
|
||||
for (int c = 0; c < 0x100; c++)
|
||||
{
|
||||
ret = wcrtomb (buf, btowc (c), NULL);
|
||||
ASSERT (ret == 1);
|
||||
ASSERT (buf[0] == (char) c);
|
||||
}
|
||||
#endif
|
||||
return test_exit_status;
|
||||
|
||||
case '2':
|
||||
|
||||
Reference in New Issue
Block a user