+2023-07-10 Bruno Haible <bruno@clisp.org>
+
+ mbrtoc32-regular: New module.
+ * modules/mbrtoc32-regular: New file.
+ * lib/mbrtoc32.c (mbrtoc32): If the module 'mbrtoc32-regular' is present
+ and the system's mbrtoc32 returned a char32_t, clear the mbstate_t.
+ * doc/posix-functions/mbrtoc32.texi: Mention the new module.
+
2023-07-10 Bruno Haible <bruno@clisp.org>
Apply the last change to all locale-*.m4 files.
@section @code{mbrtoc32}
@findex mbrtoc32
-Gnulib module: mbrtoc32
+Gnulib module: mbrtoc32 or mbrtoc32-regular
-Portability problems fixed by Gnulib:
+Portability problems fixed by either Gnulib module @code{mbrtoc32} or @code{mbrtoc32-regular}:
@itemize
@item
This function is missing on most non-glibc platforms:
@c See https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/mbrtoc16-mbrtoc323
@end itemize
-Portability problems not fixed by Gnulib:
+Portability problems fixed by Gnulib module @code{mbrtoc32-regular}:
@itemize
@item
+This function can map some multibyte characters to a sequence of two or more
+Unicode characters, and may thus return @code{(size_t) -3}.
+No known implementation currently (2023) behaves that way, but it may
+theoretically happen.
+With the @code{mbrtoc32-regular} module, you have the guarantee that the
+Gnulib-provided @code{mbrtoc32} function maps each multibyte character to
+exactly one Unicode character and thus never returns @code{(size_t) -3}.
+@item
This function behaves incorrectly when converting precomposed characters
from the BIG5-HKSCS encoding:
@c https://sourceware.org/bugzilla/show_bug.cgi?id=30611
glibc 2.36.
-@item
-Although ISO C says this function can return @code{(size_t) -3},
-no known implementation behaves that way,
-and if it were to happen it would break common uses.
-If dealing with @code{(size_t) -3} would complicate your code significantly,
-it is probably better not to bother.
+@end itemize
+
+Portability problems not fixed by Gnulib:
+@itemize
@item
This function is only defined as an inline function on some platforms:
Haiku 2020.
size_t ret = mbrtoc32 (pwc, s, n, ps);
# endif
+# if GNULIB_MBRTOC32_REGULAR
+ /* Verify that mbrtoc32 is regular. */
+ if (ret < (size_t) -3 && ! mbsinit (ps))
+ /* This occurs on glibc 2.36. */
+ memset (ps, '\0', sizeof (mbstate_t));
+ if (ret == (size_t) -3)
+ abort ();
+# endif
+
# if MBRTOC32_IN_C_LOCALE_MAYBE_EILSEQ
if ((size_t) -2 <= ret && n != 0 && ! hard_locale (LC_CTYPE))
{
--- /dev/null
+Description:
+mbrtoc32() function that maps each multibyte character to exactly one Unicode
+character and thus never returns (size_t)(-3).
+
+Files:
+
+Depends-on:
+mbrtoc32
+
+configure.ac:
+gl_MODULE_INDICATOR([mbrtoc32-regular])
+
+Makefile.am:
+
+Include:
+<uchar.h>
+
+Link:
+$(LTLIBUNISTRING) when linking with libtool, $(LIBUNISTRING) otherwise
+$(MBRTOWC_LIB)
+$(LTLIBC32CONV) when linking with libtool, $(LIBC32CONV) otherwise
+
+License:
+LGPLv2+
+
+Maintainer:
+Bruno Haible