public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 2/3]: C++20 P0482R6 and C2X N2653: Implement mbrtoc8, c8rtomb,  char8_t
@ 2022-02-27 16:53 Tom Honermann
  2022-02-28 23:01 ` Joseph Myers
  0 siblings, 1 reply; 27+ messages in thread
From: Tom Honermann @ 2022-02-27 16:53 UTC (permalink / raw)
  To: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 905 bytes --]

This patch provides implementations for the mbrtoc8 and c8rtomb 
functions adopted for C++20 via WG21 P0482R6 [1] and for C2X via WG14 
N2653 [2]. It also provides the char8_t typedef adopted for C2X via WG14 
N2653 [2].

The mbrtoc8 and c8rtomb functions are declared in uchar.h in C2X mode or 
when the _GNU_SOURCE macro or C++20 __cpp_char8_t feature test macro is 
defined.

The char8_t typedef is declared in uchar.h in C2X mode or when the 
_GNU_SOURCE macro is defined and the C++20 __cpp_char8_t feature test 
macro is not defined (if __cpp_char8_t is defined, then char8_t is a 
builtin type).

Tested on Linux x86_64.

Tom.

[1]: WG21 P0482R6
      "char8_t: A type for UTF-8 characters and strings (Revision 6)"
      https://wg21.link/p0482r6

[2]: WG14 N2653
      "char8_t: A type for UTF-8 characters and strings (Revision 1)"
      http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2653.htm

[-- Attachment #2: n2653-2.patch --]
[-- Type: text/x-patch, Size: 29192 bytes --]

commit d29ff21403913f7014fe3deebe65c9294e6c1d44
Author: Tom Honermann <tom@honermann.net>
Date:   Sun Feb 27 10:28:58 2022 -0500

    Implement mbrtoc8(), c8rtomb(), and the char8_t typedef.
    
    This change provides implementations for the mbrtoc8 and c8rtomb
    functions adopted for C++20 via WG21 P0482R6 and for C2X via WG14
    N2653.  It also provides the char8_t typedef from WG14 N2653.
    
    The mbrtoc8 and c8rtomb functions are declared in uchar.h in C2X
    mode or when the _GNU_SOURCE macro or C++20 __cpp_char8_t feature
    test macro is defined.
    
    The char8_t typedef is declared in uchar.h in C2X mode or when the
    _GNU_SOURCE macro is defined and the C++20 __cpp_char8_t feature
    test macro is not defined (if __cpp_char8_t is defined, then char8_t
    is a builtin type).

diff --git a/NEWS b/NEWS
index 626eeabf5d..3c4b597ab3 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,15 @@ Version 2.36
 
 Major new features:
 
+* Support for the mbrtoc8 and c8rtomb multibyte/UTF-8 character conversion
+  functions has been added per the ISO C2X N2653 and C++20 P0482R6 proposals.
+  Support for the char8_t typedef has been added per the ISO C2X N2653
+  proposal. The functions are declared in uchar.h in C2X mode or when the
+  _GNU_SOURCE macro or C++20 __cpp_char8_t feature test macro is defined.
+  The char8_t typedef is declared in uchar.h in C2X mode or when the
+  _GNU_SOURCE macro is defined and the C++20 __cpp_char8_t feature test macro
+  is not defined (if __cpp_char8_t is defined, then char8_t is a builtin type).
+
   [Add new features here]
 
 Deprecated and removed features, and other changes affecting compatibility:
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index 4dc87e9061..66fb0e28fa 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2289,6 +2289,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 close_range F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 1b63d9e447..82dfae3421 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2616,3 +2616,5 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index e7e4cf7d2a..56d9094a58 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2713,6 +2713,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index bc3d228e31..fb7fc117f3 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -2377,3 +2377,5 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index db7039c4ab..f7c3b87bc0 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -496,6 +496,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index d2add4fb49..19f44510ee 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -493,6 +493,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 355d72a30c..fce3ee63ea 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2652,3 +2652,5 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 3df39bb28c..307b77c25b 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2601,6 +2601,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index c4da358f80..99f3b0dde1 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2785,6 +2785,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 241bac70ea..3fe18c1bea 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2551,6 +2551,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 78bf372b72..aee8cb576b 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -497,6 +497,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0x98
 GLIBC_2.4 _IO_2_1_stdin_ D 0x98
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 00df5c901f..9b204c5cf9 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2728,6 +2728,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index e8118569c3..6ec81952e1 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2701,3 +2701,5 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index c0d2373e64..7b484a8419 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2698,3 +2698,5 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 2d0fd04f54..26e4321f80 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2693,6 +2693,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index e39ccfb312..2c5e66e2c0 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2691,6 +2691,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 1e900f86e4..f2e0a4818a 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2699,6 +2699,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 9145ba7931..e0505441f6 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2602,6 +2602,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index e95d60d926..d0260261e2 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2740,3 +2740,5 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist
index ca934e374b..506853ee25 100644
--- a/sysdeps/unix/sysv/linux/or1k/libc.abilist
+++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist
@@ -2123,3 +2123,5 @@ GLIBC_2.35 wprintf F
 GLIBC_2.35 write F
 GLIBC_2.35 writev F
 GLIBC_2.35 wscanf F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 3820b9f235..0096aa7a97 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2755,6 +2755,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index 464dc27fcd..5869941ec6 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2788,6 +2788,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index 2f7e58747f..dc6277f1d8 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2510,6 +2510,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 4f3043d913..fd8adceee6 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2812,3 +2812,5 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index 84b6ac815a..2f0b08fe30 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -2379,3 +2379,5 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index 4d5c19c56a..ad49621c76 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2579,3 +2579,5 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index 7c5ee8d569..ab25e964f1 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2753,6 +2753,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 50de0b46cf..3851645690 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2547,6 +2547,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 66fba013ca..b606bad5dc 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2608,6 +2608,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index 38703f8aa0..9b7e03a290 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2605,6 +2605,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 6df55eb765..04651211d7 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2748,6 +2748,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index b90569d881..5ce2c90903 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2574,6 +2574,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index e88b0f101f..85a7fb3152 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2525,6 +2525,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index e0755272eb..975e78eaa5 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2631,3 +2631,5 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
index df9a85f4a9..bda281ad70 100644
--- a/wcsmbs/Makefile
+++ b/wcsmbs/Makefile
@@ -42,7 +42,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
 	    wcsmbsload mbsrtowcs_l \
 	    isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf \
 	    isoc99_swscanf isoc99_vswscanf \
-	    mbrtoc16 c16rtomb mbrtoc32 c32rtomb
+	    mbrtoc8 c8rtomb mbrtoc16 c16rtomb mbrtoc32 c32rtomb
 
 strop-tests :=  wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \
 		wcpcpy wcsncpy wcpncpy wcscat wcsncat wcschrnul wcsspn wcspbrk \
diff --git a/wcsmbs/Versions b/wcsmbs/Versions
index 0b31c1b940..ec28acfb73 100644
--- a/wcsmbs/Versions
+++ b/wcsmbs/Versions
@@ -49,4 +49,7 @@ libc {
     wcstof32; wcstof64; wcstof32x;
     wcstof32_l; wcstof64_l; wcstof32x_l;
   }
+  GLIBC_2.36 {
+    c8rtomb; mbrtoc8;
+  }
 }
diff --git a/wcsmbs/c8rtomb.c b/wcsmbs/c8rtomb.c
new file mode 100644
index 0000000000..8a5ffeab23
--- /dev/null
+++ b/wcsmbs/c8rtomb.c
@@ -0,0 +1,132 @@
+/* UTF-8 to multibyte conversion.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <uchar.h>
+#include <wchar.h>
+
+
+/* This is the private state used if PS is NULL.  */
+static mbstate_t state;
+
+size_t
+c8rtomb (char *s, char8_t c8, mbstate_t *ps)
+{
+  /* This implementation depends on the converter invoked by wcrtomb not
+     needing to retain state in either the top most bit of ps->__count or
+     in ps->__value between invocations.  This implementation uses the
+     top most bit of ps->__count to indicate that trailing code units are
+     expected and uses ps->__value to store previously seen code units.  */
+
+  wchar_t wc;
+
+  if (ps == NULL)
+    ps = &state;
+
+  if (s == NULL)
+    {
+      /* if 's' is a null pointer, behave as if u8'\0' was passed as 'c8'.  If
+         this occurs for an incomplete code unit sequence, then an error will
+         be reported below.  */
+      c8 = u8""[0];
+    }
+
+  if (! (ps->__count & 0x80000000))
+    {
+      /* Initial state.  */
+      if ((c8 >= 0x80 && c8 <= 0xC1) || c8 >= 0xF5)
+	{
+	  /* An invalid lead code unit.  */
+	  __set_errno (EILSEQ);
+	  return -1;
+	}
+      if (c8 >= 0xC2)
+	{
+	  /* A valid lead code unit.  */
+	  ps->__count |= 0x80000000;
+	  ps->__value.__wchb[0] = c8;
+          ps->__value.__wchb[3] = 1;
+	  return 0;
+	}
+      /* A single byte (ASCII) code unit.  */
+      wc = c8;
+    }
+  else
+    {
+      char8_t cu1 = ps->__value.__wchb[0];
+      if (ps->__value.__wchb[3] == 1)
+	{
+	  /* A single lead code unit was previously seen.  */
+	  if ((c8 < 0x80 || c8 > 0xBF) ||
+               (cu1 == 0xE0 && c8 < 0xA0) ||
+               (cu1 == 0xED && c8 > 0x9F) ||
+               (cu1 == 0xF0 && c8 < 0x90) ||
+               (cu1 == 0xF4 && c8 > 0x8F))
+	    {
+	      /* An invalid second code unit.  */
+	      __set_errno (EILSEQ);
+	      return -1;
+	    }
+	  if (cu1 >= 0xE0)
+	    {
+	      /* A three or four code unit sequence.  */
+	      ps->__value.__wchb[1] = c8;
+	      ++ps->__value.__wchb[3];
+	      return 0;
+	    }
+	  wc = ((cu1 & 0x1F) << 6) +
+	       (c8 & 0x3F);
+	}
+      else
+	{
+	  char8_t cu2 = ps->__value.__wchb[1];
+	  /* A three or four byte code unit sequence.  */
+	  if (c8 < 0x80 || c8 > 0xBF)
+	    {
+	      /* An invalid third or fourth code unit.  */
+	      __set_errno (EILSEQ);
+	      return -1;
+	    }
+	  if (ps->__value.__wchb[3] == 2 && cu1 >= 0xF0)
+	    {
+	      /* A four code unit sequence.  */
+	      ps->__value.__wchb[2] = c8;
+	      ++ps->__value.__wchb[3];
+	      return 0;
+	    }
+	  if (cu1 < 0xF0)
+	    {
+	      wc = ((cu1 & 0x0F) << 12) +
+		   ((cu2 & 0x3F) << 6) +
+		   (c8 & 0x3F);
+	    }
+	  else
+	    {
+	      char8_t cu3 = ps->__value.__wchb[2];
+	      wc = ((cu1 & 0x07) << 18) +
+		   ((cu2 & 0x3F) << 12) +
+		   ((cu3 & 0x3F) << 6) +
+		   (c8 & 0x3F);
+	    }
+	}
+      ps->__count &= 0x7fffffff;
+      ps->__value.__wch = 0;
+    }
+
+  return wcrtomb (s, wc, ps);
+}
diff --git a/wcsmbs/mbrtoc8.c b/wcsmbs/mbrtoc8.c
new file mode 100644
index 0000000000..8ca457088d
--- /dev/null
+++ b/wcsmbs/mbrtoc8.c
@@ -0,0 +1,126 @@
+/* Multibyte to UTF-8 conversion.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <gconv.h>
+#include <uchar.h>
+#include <wcsmbsload.h>
+
+#include <sysdep.h>
+
+#ifndef EILSEQ
+# define EILSEQ EINVAL
+#endif
+
+
+/* This is the private state used if PS is NULL.  */
+static mbstate_t state;
+
+size_t
+mbrtoc8 (char8_t *pc8, const char *s, size_t n, mbstate_t *ps)
+{
+  /* This implementation depends on the converter invoked by mbrtowc() not
+     needing to retain state in either the top most bit of ps->__count or
+     in ps->__value between invocations.  This implementation uses the
+     top most bit of ps->__count to indicate that trailing code units are
+     yet to be written and uses ps->__value to store those code units.  */
+
+  if (ps == NULL)
+    ps = &state;
+
+  /* If state indicates that trailing code units are yet to be written, write
+     those first regardless of whether 's' is a null pointer.  */
+  if (ps->__count & 0x80000000)
+    {
+      /* ps->__value.__wchb[3] stores the index of the next code unit to
+         write.  Code units are stored in reverse order.  */
+      size_t i = ps->__value.__wchb[3];
+      if (pc8 != NULL)
+	{
+	  *pc8 = ps->__value.__wchb[i];
+	}
+      if (i == 0)
+	{
+	  ps->__count &= 0x7fffffff;
+	  ps->__value.__wch = 0;
+	}
+      else
+	--ps->__value.__wchb[3];
+      return -3;
+    }
+
+  if (s == NULL)
+    {
+      /* if 's' is a null pointer, behave as if a null pointer was passed for
+         'pc8', an empty string was passed for 's', and 1 passed for 'n'.  */
+      pc8 = NULL;
+      s = "";
+      n = 1;
+    }
+
+  wchar_t wc;
+  size_t result;
+
+  result = mbrtowc(&wc, s, n, ps);
+  if (result <= n)
+    {
+      if (wc <= 0x7F)
+	{
+	  if (pc8 != NULL)
+	    *pc8 = wc;
+	}
+      else if (wc <= 0x7FF)
+	{
+	  if (pc8 != NULL)
+	    *pc8 = 0xC0 + ((wc >> 6) & 0x1F);
+	  ps->__value.__wchb[0] = 0x80 + (wc & 0x3F);
+	  ps->__value.__wchb[3] = 0;
+	  ps->__count |= 0x80000000;
+	}
+      else if (wc <= 0xFFFF)
+	{
+	  if (pc8 != NULL)
+	    *pc8 = 0xE0 + ((wc >> 12) & 0x0F);
+	  ps->__value.__wchb[1] = 0x80 + ((wc >> 6) & 0x3F);
+	  ps->__value.__wchb[0] = 0x80 + (wc & 0x3F);
+	  ps->__value.__wchb[3] = 1;
+	  ps->__count |= 0x80000000;
+	}
+      else if (wc <= 0x10FFFF)
+	{
+	  if (pc8 != NULL)
+	    *pc8 = 0xF0 + ((wc >> 18) & 0x07);
+	  ps->__value.__wchb[2] = 0x80 + ((wc >> 12) & 0x3F);
+	  ps->__value.__wchb[1] = 0x80 + ((wc >> 6) & 0x3F);
+	  ps->__value.__wchb[0] = 0x80 + (wc & 0x3F);
+	  ps->__value.__wchb[3] = 2;
+	  ps->__count |= 0x80000000;
+	}
+    }
+  if (result == 0 && wc != 0)
+    {
+      /* mbrtowc() never returns -3.  When a MB sequence converts to multiple
+         WCs, no input is consumed when writing the subsequent WCs resulting
+         in a result of 0 even if a null character wasn't written.  */
+      result = -3;
+    }
+
+  return result;
+}
diff --git a/wcsmbs/uchar.h b/wcsmbs/uchar.h
index 051cdcbeb5..01aaf9c94b 100644
--- a/wcsmbs/uchar.h
+++ b/wcsmbs/uchar.h
@@ -31,6 +31,13 @@
 #include <bits/types.h>
 #include <bits/types/mbstate_t.h>
 
+/* Declare the C2x char8_t typedef in _GNU_SOURCE and C2x modes, but only
+   if the C++ __cpp_char8_t feature test macro is not defined.  */
+#if (defined __USE_GNU || __GLIBC_USE (ISOC2X)) && !defined __cpp_char8_t
+/* Define the 8-bit character type.  */
+typedef unsigned char char8_t;
+#endif
+
 #ifndef __USE_ISOCXX11
 /* Define the 16-bit and 32-bit character types.  */
 typedef __uint_least16_t char16_t;
@@ -40,6 +47,20 @@ typedef __uint_least32_t char32_t;
 
 __BEGIN_DECLS
 
+/* Declare the C2x mbrtoc8() and c8rtomb() functions in _GNU_SOURCE and C2x
+   modes or if the C++ __cpp_char8_t feature test macro is defined.  */
+#if defined __USE_GNU || __GLIBC_USE (ISOC2X) || defined __cpp_char8_t
+/* Write char8_t representation of multibyte character pointed
+   to by S to PC8.  */
+extern size_t mbrtoc8  (char8_t *__restrict __pc8,
+			const char *__restrict __s, size_t __n,
+			mbstate_t *__restrict __p) __THROW;
+
+/* Write multibyte representation of char8_t C8 to S.  */
+extern size_t c8rtomb  (char *__restrict __s, char8_t __c8,
+			mbstate_t *__restrict __ps) __THROW;
+#endif
+
 /* Write char16_t representation of multibyte character pointed
    to by S to PC16.  */
 extern size_t mbrtoc16 (char16_t *__restrict __pc16,

^ permalink raw reply	[flat|nested] 27+ messages in thread
* [PATCH 2/3]: C++20 P0482R6 and C2X N2653: Implement mbrtoc8, c8rtomb,  char8_t
@ 2022-01-08  0:39 Tom Honermann
  2022-01-11  0:53 ` Joseph Myers
  0 siblings, 1 reply; 27+ messages in thread
From: Tom Honermann @ 2022-01-08  0:39 UTC (permalink / raw)
  To: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 831 bytes --]

This patch provides implementations for the mbrtoc8 and c8rtomb 
functions adopted for C++20 via WG21 P0482R6 [1] and proposed for C2X 
via WG14 N2653 [2]. It also provides the char8_t typedef from WG14 N2653 
[2].

The mbrtoc8 and c8rtomb functions are declared in uchar.h if either of 
the C++20 __cpp_char8_t or _GNU_SOURCE feature test macros are defined.

The char8_t typedef is declared in uchar.h if _GNU_SOURCE is defined and 
__cpp_char8_t is not defined (if __cpp_char8_t is defined, then char8_t 
is a builtin type).

Tested on Linux x86_64.

Tom.

[1]: WG21 P0482R6
      "char8_t: A type for UTF-8 characters and strings (Revision 6)"
      https://wg21.link/p0482r6

[2]: WG14 N2653
      "char8_t: A type for UTF-8 characters and strings (Revision 1)"
      http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2653.htm

[-- Attachment #2: n2653-2.patch --]
[-- Type: text/x-patch, Size: 27563 bytes --]

commit 0710b1004c1eb151d739c73090c4eab81e454eb1
Author: Tom Honermann <tom@honermann.net>
Date:   Wed Jan 5 18:42:03 2022 -0500

    Implement mbrtoc8(), c8rtomb(), and the char8_t typedef.
    
    This change provides implementations for the mbrtoc8 and c8rtomb
    functions adopted for C++20 via WG21 P0482R6 and proposed for C2X
    via WG14 N2653.  It also provides the char8_t typedef from N2653.
    
    The mbrtoc8 and c8rtomb functions are declared in uchar.h if
    either of the C++20 __cpp_char8_t feature test macro or the
    _GNU_SOURCE macro are defined.
    
    The char8_t typedef is declared in uchar.h if _GNU_SOURCE is
    defined and __cpp_char8_t is not defined (if __cpp_char8_t is
    defined, then char8_t is a builtin type).

diff --git a/NEWS b/NEWS
index 4762bfcc4e..ccb22553f2 100644
--- a/NEWS
+++ b/NEWS
@@ -237,6 +237,14 @@ Major new features:
 * The audit libraries will avoid unnecessary slowdown if it is not required
   PLT tracking (by not implementing the la_pltenter or la_pltexit callbacks).
 
+* The mbrtoc8 and c8rtomb functions are added for implementation of the
+  C++20 P0482R6 and C2X N2653 proposals.  These functions perform conversions
+  between multibyte sequences and the UTF-8 character encoding.  A char8_t
+  typedef is added for the C2X N2653 proposal.  The functions are declared
+  in uchar.h if the C++20 __cpp_char8_t feature test macro or _GNU_SOURCE
+  macro is defined.  The char8_t typedef is declared in uchar.h if _GNU_SOURCE
+  is defined and __cpp_char8_t is not defined.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
 * The function pthread_mutex_consistent_np has been deprecated; programs
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index ecf8c0992e..d1188a83a5 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2287,7 +2287,9 @@ GLIBC_2.34 shm_unlink F
 GLIBC_2.34 timespec_getres F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
 GLIBC_2.35 close_range F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index fed942ed4b..35586c023f 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2613,4 +2613,6 @@ GLIBC_2.34 tss_delete F
 GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
+GLIBC_2.35 c8rtomb F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 mbrtoc8 F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 2867932704..4969c57a37 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2711,6 +2711,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index 239db7bab0..fccd1f8662 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -2375,3 +2375,5 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index bc79dcfe8a..1cb2d4fd66 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -493,6 +493,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index 614607fd6b..b36859f8e1 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -490,6 +490,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 2b61543f0d..4f7828d822 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2649,3 +2649,5 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 6b3cb1adb4..d59accc822 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2598,6 +2598,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 7f608c1b64..37a065f555 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2782,6 +2782,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 865deec43f..69839c86fd 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2549,6 +2549,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index a172d74632..b8418d612c 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -494,6 +494,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0x98
 GLIBC_2.4 _IO_2_1_stdin_ D 0x98
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 174e9c7739..8cfbb5f235 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2725,6 +2725,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index d042be1369..0d729329aa 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2698,3 +2698,5 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 332da62de2..3980c6df0d 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2695,3 +2695,5 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 2d6ec0d0e8..f8c2087559 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2690,6 +2690,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 6c5befa72b..ce87791286 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2688,6 +2688,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 5fb24c97e1..ee547ceb78 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2696,6 +2696,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index f4f29fc15e..4c558a283e 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2600,6 +2600,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 2e7300cd05..234ab84125 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2737,3 +2737,5 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 129a2f16a7..e383bac9bd 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2752,6 +2752,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index 7e23226779..ddbcb3e085 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2785,6 +2785,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index 6f97392b70..daaa374fa0 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2508,6 +2508,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 29058a041a..a24f6b4751 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2810,3 +2810,5 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index d2924766d2..3dc0e04f64 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -2377,3 +2377,5 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index b770e05da3..af3bbfc83b 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2577,3 +2577,5 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index bed3433a2b..4025a7f913 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2750,6 +2750,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 4f1a143da5..55febf9508 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2545,6 +2545,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 92c8dec8ec..cc37920ee2 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2605,6 +2605,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index 263da58cb7..298654b119 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2602,6 +2602,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 0171efe7db..ed214429f0 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2745,6 +2745,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 7f8d45f362..0dcc3674eb 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2572,6 +2572,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index c2f1a8ecc6..ec4e0b73e4 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2523,6 +2523,8 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 8b43acf100..b60cd45821 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2629,3 +2629,5 @@ GLIBC_2.34 tss_get F
 GLIBC_2.34 tss_set F
 GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
+GLIBC_2.35 c8rtomb F
+GLIBC_2.35 mbrtoc8 F
diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
index 3a3be9cd95..390d94bbb2 100644
--- a/wcsmbs/Makefile
+++ b/wcsmbs/Makefile
@@ -42,7 +42,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
 	    wcsmbsload mbsrtowcs_l \
 	    isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf \
 	    isoc99_swscanf isoc99_vswscanf \
-	    mbrtoc16 c16rtomb mbrtoc32 c32rtomb
+	    mbrtoc8 c8rtomb mbrtoc16 c16rtomb mbrtoc32 c32rtomb
 
 strop-tests :=  wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \
 		wcpcpy wcsncpy wcpncpy wcscat wcsncat wcschrnul wcsspn wcspbrk \
diff --git a/wcsmbs/Versions b/wcsmbs/Versions
index 0b31c1b940..d578518fad 100644
--- a/wcsmbs/Versions
+++ b/wcsmbs/Versions
@@ -49,4 +49,7 @@ libc {
     wcstof32; wcstof64; wcstof32x;
     wcstof32_l; wcstof64_l; wcstof32x_l;
   }
+  GLIBC_2.35 {
+    c8rtomb; mbrtoc8;
+  }
 }
diff --git a/wcsmbs/c8rtomb.c b/wcsmbs/c8rtomb.c
new file mode 100644
index 0000000000..8a5ffeab23
--- /dev/null
+++ b/wcsmbs/c8rtomb.c
@@ -0,0 +1,132 @@
+/* UTF-8 to multibyte conversion.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <uchar.h>
+#include <wchar.h>
+
+
+/* This is the private state used if PS is NULL.  */
+static mbstate_t state;
+
+size_t
+c8rtomb (char *s, char8_t c8, mbstate_t *ps)
+{
+  /* This implementation depends on the converter invoked by wcrtomb not
+     needing to retain state in either the top most bit of ps->__count or
+     in ps->__value between invocations.  This implementation uses the
+     top most bit of ps->__count to indicate that trailing code units are
+     expected and uses ps->__value to store previously seen code units.  */
+
+  wchar_t wc;
+
+  if (ps == NULL)
+    ps = &state;
+
+  if (s == NULL)
+    {
+      /* if 's' is a null pointer, behave as if u8'\0' was passed as 'c8'.  If
+         this occurs for an incomplete code unit sequence, then an error will
+         be reported below.  */
+      c8 = u8""[0];
+    }
+
+  if (! (ps->__count & 0x80000000))
+    {
+      /* Initial state.  */
+      if ((c8 >= 0x80 && c8 <= 0xC1) || c8 >= 0xF5)
+	{
+	  /* An invalid lead code unit.  */
+	  __set_errno (EILSEQ);
+	  return -1;
+	}
+      if (c8 >= 0xC2)
+	{
+	  /* A valid lead code unit.  */
+	  ps->__count |= 0x80000000;
+	  ps->__value.__wchb[0] = c8;
+          ps->__value.__wchb[3] = 1;
+	  return 0;
+	}
+      /* A single byte (ASCII) code unit.  */
+      wc = c8;
+    }
+  else
+    {
+      char8_t cu1 = ps->__value.__wchb[0];
+      if (ps->__value.__wchb[3] == 1)
+	{
+	  /* A single lead code unit was previously seen.  */
+	  if ((c8 < 0x80 || c8 > 0xBF) ||
+               (cu1 == 0xE0 && c8 < 0xA0) ||
+               (cu1 == 0xED && c8 > 0x9F) ||
+               (cu1 == 0xF0 && c8 < 0x90) ||
+               (cu1 == 0xF4 && c8 > 0x8F))
+	    {
+	      /* An invalid second code unit.  */
+	      __set_errno (EILSEQ);
+	      return -1;
+	    }
+	  if (cu1 >= 0xE0)
+	    {
+	      /* A three or four code unit sequence.  */
+	      ps->__value.__wchb[1] = c8;
+	      ++ps->__value.__wchb[3];
+	      return 0;
+	    }
+	  wc = ((cu1 & 0x1F) << 6) +
+	       (c8 & 0x3F);
+	}
+      else
+	{
+	  char8_t cu2 = ps->__value.__wchb[1];
+	  /* A three or four byte code unit sequence.  */
+	  if (c8 < 0x80 || c8 > 0xBF)
+	    {
+	      /* An invalid third or fourth code unit.  */
+	      __set_errno (EILSEQ);
+	      return -1;
+	    }
+	  if (ps->__value.__wchb[3] == 2 && cu1 >= 0xF0)
+	    {
+	      /* A four code unit sequence.  */
+	      ps->__value.__wchb[2] = c8;
+	      ++ps->__value.__wchb[3];
+	      return 0;
+	    }
+	  if (cu1 < 0xF0)
+	    {
+	      wc = ((cu1 & 0x0F) << 12) +
+		   ((cu2 & 0x3F) << 6) +
+		   (c8 & 0x3F);
+	    }
+	  else
+	    {
+	      char8_t cu3 = ps->__value.__wchb[2];
+	      wc = ((cu1 & 0x07) << 18) +
+		   ((cu2 & 0x3F) << 12) +
+		   ((cu3 & 0x3F) << 6) +
+		   (c8 & 0x3F);
+	    }
+	}
+      ps->__count &= 0x7fffffff;
+      ps->__value.__wch = 0;
+    }
+
+  return wcrtomb (s, wc, ps);
+}
diff --git a/wcsmbs/mbrtoc8.c b/wcsmbs/mbrtoc8.c
new file mode 100644
index 0000000000..8ca457088d
--- /dev/null
+++ b/wcsmbs/mbrtoc8.c
@@ -0,0 +1,126 @@
+/* Multibyte to UTF-8 conversion.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <gconv.h>
+#include <uchar.h>
+#include <wcsmbsload.h>
+
+#include <sysdep.h>
+
+#ifndef EILSEQ
+# define EILSEQ EINVAL
+#endif
+
+
+/* This is the private state used if PS is NULL.  */
+static mbstate_t state;
+
+size_t
+mbrtoc8 (char8_t *pc8, const char *s, size_t n, mbstate_t *ps)
+{
+  /* This implementation depends on the converter invoked by mbrtowc() not
+     needing to retain state in either the top most bit of ps->__count or
+     in ps->__value between invocations.  This implementation uses the
+     top most bit of ps->__count to indicate that trailing code units are
+     yet to be written and uses ps->__value to store those code units.  */
+
+  if (ps == NULL)
+    ps = &state;
+
+  /* If state indicates that trailing code units are yet to be written, write
+     those first regardless of whether 's' is a null pointer.  */
+  if (ps->__count & 0x80000000)
+    {
+      /* ps->__value.__wchb[3] stores the index of the next code unit to
+         write.  Code units are stored in reverse order.  */
+      size_t i = ps->__value.__wchb[3];
+      if (pc8 != NULL)
+	{
+	  *pc8 = ps->__value.__wchb[i];
+	}
+      if (i == 0)
+	{
+	  ps->__count &= 0x7fffffff;
+	  ps->__value.__wch = 0;
+	}
+      else
+	--ps->__value.__wchb[3];
+      return -3;
+    }
+
+  if (s == NULL)
+    {
+      /* if 's' is a null pointer, behave as if a null pointer was passed for
+         'pc8', an empty string was passed for 's', and 1 passed for 'n'.  */
+      pc8 = NULL;
+      s = "";
+      n = 1;
+    }
+
+  wchar_t wc;
+  size_t result;
+
+  result = mbrtowc(&wc, s, n, ps);
+  if (result <= n)
+    {
+      if (wc <= 0x7F)
+	{
+	  if (pc8 != NULL)
+	    *pc8 = wc;
+	}
+      else if (wc <= 0x7FF)
+	{
+	  if (pc8 != NULL)
+	    *pc8 = 0xC0 + ((wc >> 6) & 0x1F);
+	  ps->__value.__wchb[0] = 0x80 + (wc & 0x3F);
+	  ps->__value.__wchb[3] = 0;
+	  ps->__count |= 0x80000000;
+	}
+      else if (wc <= 0xFFFF)
+	{
+	  if (pc8 != NULL)
+	    *pc8 = 0xE0 + ((wc >> 12) & 0x0F);
+	  ps->__value.__wchb[1] = 0x80 + ((wc >> 6) & 0x3F);
+	  ps->__value.__wchb[0] = 0x80 + (wc & 0x3F);
+	  ps->__value.__wchb[3] = 1;
+	  ps->__count |= 0x80000000;
+	}
+      else if (wc <= 0x10FFFF)
+	{
+	  if (pc8 != NULL)
+	    *pc8 = 0xF0 + ((wc >> 18) & 0x07);
+	  ps->__value.__wchb[2] = 0x80 + ((wc >> 12) & 0x3F);
+	  ps->__value.__wchb[1] = 0x80 + ((wc >> 6) & 0x3F);
+	  ps->__value.__wchb[0] = 0x80 + (wc & 0x3F);
+	  ps->__value.__wchb[3] = 2;
+	  ps->__count |= 0x80000000;
+	}
+    }
+  if (result == 0 && wc != 0)
+    {
+      /* mbrtowc() never returns -3.  When a MB sequence converts to multiple
+         WCs, no input is consumed when writing the subsequent WCs resulting
+         in a result of 0 even if a null character wasn't written.  */
+      result = -3;
+    }
+
+  return result;
+}
diff --git a/wcsmbs/uchar.h b/wcsmbs/uchar.h
index 6020f66cf6..2f15c6f74d 100644
--- a/wcsmbs/uchar.h
+++ b/wcsmbs/uchar.h
@@ -31,6 +31,13 @@
 #include <bits/types.h>
 #include <bits/types/mbstate_t.h>
 
+/* Declare the char8_t typedef in _GNU_SOURCE mode, but only if the C++
+   __cpp_char8_t feature test macro is not defined.  */
+#if defined __USE_GNU && !defined __cpp_char8_t
+/* Define the 8-bit character type.  */
+typedef unsigned char char8_t;
+#endif
+
 #ifndef __USE_ISOCXX11
 /* Define the 16-bit and 32-bit character types.  */
 typedef __uint_least16_t char16_t;
@@ -40,6 +47,20 @@ typedef __uint_least32_t char32_t;
 
 __BEGIN_DECLS
 
+/* Declare mbrtoc8() and c8rtomb() in _GNU_SOURCE mode or if the C++
+   __cpp_char8_t feature test macro is defined.  */
+#if defined __USE_GNU || defined __cpp_char8_t
+/* Write char8_t representation of multibyte character pointed
+   to by S to PC8.  */
+extern size_t mbrtoc8  (char8_t *__restrict __pc8,
+			const char *__restrict __s, size_t __n,
+			mbstate_t *__restrict __p) __THROW;
+
+/* Write multibyte representation of char8_t C8 to S.  */
+extern size_t c8rtomb  (char *__restrict __s, char8_t __c8,
+			mbstate_t *__restrict __ps) __THROW;
+#endif
+
 /* Write char16_t representation of multibyte character pointed
    to by S to PC16.  */
 extern size_t mbrtoc16 (char16_t *__restrict __pc16,

^ permalink raw reply	[flat|nested] 27+ messages in thread
* [PATCH 2/3]: C++20 P0482R6 and C2X N2653: Implement mbrtoc8, c8rtomb,  char8_t
@ 2021-06-07  2:08 Tom Honermann
  2021-06-07 18:53 ` Joseph Myers
  0 siblings, 1 reply; 27+ messages in thread
From: Tom Honermann @ 2021-06-07  2:08 UTC (permalink / raw)
  To: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 1105 bytes --]

This patch provides implementations for the mbrtoc8 and c8rtomb 
functions adopted for C++20 via WG21 P0482R6 [1] and proposed for C2X 
via WG14 N2653 [2].  It also provides the char8_t typedef from WG14 
N2653 [2] and introduces a _CHAR8_T_SOURCE feature test macro to opt-in 
to the new declarations.

The mbrtoc8 and c8rtomb functions are declared in uchar.h if either the 
C++20 __cpp_char8_t feature test macro or the _CHAR8_T_SOURCE feature 
test macro are defined.

The char8_t typedef is declared in uchar.h if _CHAR8_T_SOURCE is defined 
and __cpp_char8_t is not defined (if __cpp_char8_t is defined, then 
char8_t is a builtin type).

Additionally, in features.h, missing comments for the 
__GLIBC_USE_ISOC2X, __GLIBC_USE_DEPRECATED_GETS, and 
__GLIBC_USE_DEPRECATED_SCANF macros are added.

Tested on Linux x86_64.

Tom.

[1]: WG21 P0482R6
      "char8_t: A type for UTF-8 characters and strings (Revision 6)"
      https://wg21.link/p0482r6

[2]: WG14 N2653
      "char8_t: A type for UTF-8 characters and strings (Revision 1)"
      http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2653.htm


[-- Attachment #2: n2653-2.patch --]
[-- Type: text/x-patch, Size: 39183 bytes --]

commit 9b79320a42146cda02338941606cbf4ee0ca0db8
Author: Tom Honermann <tom@honermann.net>
Date:   Fri Feb 12 22:00:26 2021 -0500

    Implement mbrtoc8(), c8rtomb(), and the char8_t typedef.
    
    This change provides implementations for the mbrtoc8 and c8rtomb
    functions adopted for C++20 via WG21 P0482R6 and proposed for C2X
    via WG14 N2653.  It also provides the char8_t typedef from N2653
    and introduces a _CHAR8_T_SOURCE feature test macro to opt-in to
    the new declarations.
    
    The mbrtoc8 and c8rtomb functions are declared in uchar.h if
    either the C++20 __cpp_char8_t feature test macro or the
    _CHAR8_T_SOURCE feature test macro are defined.
    
    The char8_t typedef is declared in uchar.h if _CHAR8_T_SOURCE is
    defined and __cpp_char8_t is not defined (if __cpp_char8_t is
    defined, then char8_t is a builtin type).
    
    In features.h, missing comments for the __GLIBC_USE_ISOC2X,
    __GLIBC_USE_DEPRECATED_GETS, and __GLIBC_USE_DEPRECATED_SCANF
    macros are added.

diff --git a/NEWS b/NEWS
index 266837bf2d..67793fc324 100644
--- a/NEWS
+++ b/NEWS
@@ -25,6 +25,15 @@ Major new features:
 
 * The ISO C2X function timespec_getres has been added.
 
+* The mbrtoc8 and c8rtomb functions are added for implementation of the
+  C++20 P0482R6 and C2X N2653 proposals.  These functions perform conversions
+  between multibyte sequences and the UTF-8 character encoding.  A char8_t
+  typedef is added for the C2X N2653 proposal.  The functions are declared
+  in uchar.h if the C++20 __cpp_char8_t feature test macro or the
+  _CHAR8_T_SOURCE feature test macro is defined.  The char8_t typedef is
+  declared in uchar.h if _CHAR8_T_SOURCE is defined and __cpp_char8_t is
+  not defined.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
 * The function pthread_mutex_consistent_np has been deprecated; programs
diff --git a/include/features.h b/include/features.h
index eb97470afa..9437f0f0b8 100644
--- a/include/features.h
+++ b/include/features.h
@@ -60,6 +60,8 @@
    _REENTRANT, _THREAD_SAFE
 			Obsolete; equivalent to _POSIX_C_SOURCE=199506L.
 
+   _CHAR8_T_SOURCE	Extensions for char8_t as specified in WG14 N2231.
+
    The `-ansi' switch to the GNU C compiler, and standards conformance
    options such as `-std=c99', define __STRICT_ANSI__.  If none of
    these are defined, or if _DEFAULT_SOURCE is defined, the default is
@@ -100,6 +102,12 @@
 			MINSIGSTKSZ and SIGSTKSZ.
    __USE_GNU		Define GNU extensions.
    __USE_FORTIFY_LEVEL	Additional security measures used, according to level.
+   __GLIBC_USE_ISOC2X	Define ISO C2X things.
+   __GLIBC_USE_DEPRECATED_GETS
+			Define deprecated gets()
+   __GLIBC_USE_DEPRECATED_SCANF
+			Define deprecated scanf()
+   __GLIBC_USE_CHAR8_T	Define extensions for char8_t as specified in WG14 N2231.
 
    The macros `__GNU_LIBRARY__', `__GLIBC__', and `__GLIBC_MINOR__' are
    defined by this file unconditionally.  `__GNU_LIBRARY__' is provided
@@ -148,6 +156,7 @@
 #undef	__GLIBC_USE_ISOC2X
 #undef	__GLIBC_USE_DEPRECATED_GETS
 #undef	__GLIBC_USE_DEPRECATED_SCANF
+#undef	__GLIBC_USE_CHAR8_T
 
 /* Suppress kernel-name space pollution unless user expressedly asks
    for it.  */
@@ -457,6 +466,16 @@
 # define __GLIBC_USE_DEPRECATED_SCANF 0
 #endif
 
+/* The char8_t related c8rtomb and mbrtoc8 functions are declared if the
+   C++ __cpp_char8_t feature test macro is defined or if _CHAR8_T_SOURCE
+   is defined.  The char8_t typedef is declared if _CHAR8_T_SOURCE is
+   defined and the C++ __cpp_char8_t feature test macro is not defined.  */
+#if defined _CHAR8_T_SOURCE || defined __cpp_char8_t
+# define __GLIBC_USE_CHAR8_T   1
+#else
+# define __GLIBC_USE_CHAR8_T   0
+#endif
+
 /* Get definitions of __STDC_* predefined macros, if the compiler has
    not preincluded this header automatically.  */
 #include <stdc-predef.h>
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index 49aa809366..f536073108 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2207,7 +2207,9 @@ GLIBC_2.33 stat64 F
 GLIBC_2.34 __isnanf128 F
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 _hurd_libc_proc_init F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 timespec_getres F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index d22c7da7ef..54eb6473ff 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2335,6 +2335,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2343,6 +2344,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index cefff3bf36..288ed25ab1 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2427,6 +2427,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2435,6 +2436,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index 91a90f8ca4..3ef5eaf40f 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -2094,6 +2094,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2102,6 +2103,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index 120288d766..5553b89bc1 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -200,6 +200,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -208,6 +209,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index be987da77e..9813f6ca87 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -197,6 +197,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -205,6 +206,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index adb4e15cb8..d457c6e42a 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2278,6 +2278,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2286,6 +2287,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index bd022276e8..23ea3705ba 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2231,6 +2231,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2239,6 +2240,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 9e37e1cb38..39f6611ee0 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2415,6 +2415,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2423,6 +2424,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index b8089b0b0c..4bb6092441 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2267,6 +2267,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2275,6 +2276,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 093854ad85..63a8877c38 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -201,6 +201,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -209,6 +210,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 87554f1468..f3c8644e51 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2358,6 +2358,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2366,6 +2367,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index e9340671c5..5897810a1f 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2329,6 +2329,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2337,6 +2338,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 6ddc0e90cf..7d1672eb0d 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2326,6 +2326,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2334,6 +2335,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 8582c9c371..4a4a43aad7 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2323,6 +2323,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2331,6 +2332,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index b0849bec98..fa33fc92d1 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2321,6 +2321,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2329,6 +2330,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 386660a5a1..3dcdfa2b39 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2329,6 +2329,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2337,6 +2338,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 4d05128f21..e4685a7e10 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2323,6 +2323,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2331,6 +2332,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index bd305f440f..3204a54838 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2368,6 +2368,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2376,6 +2377,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index c2665624aa..b0122085c9 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2385,6 +2385,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2393,6 +2394,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index 13ef6ef39e..c7e4209cf5 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2418,6 +2418,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2426,6 +2427,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index b21072e313..0e14ea72ca 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2232,6 +2232,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2240,6 +2241,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 62af65536c..2ff5fbc8a5 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2531,6 +2531,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2539,6 +2540,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index a63aec3379..dbe5fcf2ae 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -2096,6 +2096,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2104,6 +2105,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index b52efaf5ee..9b9afda286 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2296,6 +2296,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2304,6 +2305,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index b699dedcc1..1ca55714a6 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2383,6 +2383,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2391,6 +2392,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 94209858b1..7348c3aa2a 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2269,6 +2269,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2277,6 +2278,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 0fab90e1e3..279f3388ac 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2238,6 +2238,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2246,6 +2247,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index 2f3a64b580..cce9c390da 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2235,6 +2235,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2243,6 +2244,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index e6fe453f50..54e64f4654 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2376,6 +2376,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2384,6 +2385,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 4327cf5eb3..11f9bc8db2 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2288,6 +2288,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2296,6 +2297,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 318a6d50f9..b9cae9f7ab 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2247,6 +2247,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2255,6 +2256,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 0bcf898d4d..cf633eefa4 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2350,6 +2350,7 @@ GLIBC_2.34 __pthread_register_cancel_defer F
 GLIBC_2.34 __pthread_unregister_cancel F
 GLIBC_2.34 __pthread_unregister_cancel_restore F
 GLIBC_2.34 __pthread_unwind_next F
+GLIBC_2.34 c8rtomb F
 GLIBC_2.34 call_once F
 GLIBC_2.34 cnd_broadcast F
 GLIBC_2.34 cnd_destroy F
@@ -2358,6 +2359,7 @@ GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
 GLIBC_2.34 execveat F
+GLIBC_2.34 mbrtoc8 F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
 GLIBC_2.34 mtx_lock F
diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
index f38eb5cfe1..e0c8acf591 100644
--- a/wcsmbs/Makefile
+++ b/wcsmbs/Makefile
@@ -42,7 +42,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
 	    wcsmbsload mbsrtowcs_l \
 	    isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf \
 	    isoc99_swscanf isoc99_vswscanf \
-	    mbrtoc16 c16rtomb mbrtoc32 c32rtomb
+	    mbrtoc8 c8rtomb mbrtoc16 c16rtomb mbrtoc32 c32rtomb
 
 strop-tests :=  wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \
 		wcpcpy wcsncpy wcpncpy wcscat wcsncat wcschrnul wcsspn wcspbrk \
diff --git a/wcsmbs/Versions b/wcsmbs/Versions
index 0b31c1b940..acf6c3b705 100644
--- a/wcsmbs/Versions
+++ b/wcsmbs/Versions
@@ -49,4 +49,7 @@ libc {
     wcstof32; wcstof64; wcstof32x;
     wcstof32_l; wcstof64_l; wcstof32x_l;
   }
+  GLIBC_2.34 {
+    c8rtomb; mbrtoc8;
+  }
 }
diff --git a/wcsmbs/c8rtomb.c b/wcsmbs/c8rtomb.c
new file mode 100644
index 0000000000..ebb1e73e5c
--- /dev/null
+++ b/wcsmbs/c8rtomb.c
@@ -0,0 +1,137 @@
+/* Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Tom Honermann <tom@honermann.net>, 2020.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* Ensure that char8_t support is enabled so that the char8_t typedef is
+   declared.  */
+#define _CHAR8_T_SOURCE
+
+#include <features.h>
+#include <errno.h>
+#include <uchar.h>
+#include <wchar.h>
+
+
+/* This is the private state used if PS is NULL.  */
+static mbstate_t state;
+
+size_t
+c8rtomb (char *s, char8_t c8, mbstate_t *ps)
+{
+  /* This implementation depends on the converter invoked by wcrtomb not
+     needing to retain state in either the top most bit of ps->__count or
+     in ps->__value between invocations.  This implementation uses the
+     top most bit of ps->__count to indicate that trailing code units are
+     expected and uses ps->__value to store previously seen code units.  */
+
+  wchar_t wc;
+
+  if (ps == NULL)
+    ps = &state;
+
+  if (s == NULL)
+    {
+      /* if 's' is a null pointer, behave as if u8'\0' was passed as 'c8'.  If
+         this occurs for an incomplete code unit sequence, then an error will
+         be reported below.  */
+      c8 = u8""[0];
+    }
+
+  if (! (ps->__count & 0x80000000))
+    {
+      /* Initial state.  */
+      if ((c8 >= 0x80 && c8 <= 0xC1) || c8 >= 0xF5)
+	{
+	  /* An invalid lead code unit.  */
+	  __set_errno (EILSEQ);
+	  return -1;
+	}
+      if (c8 >= 0xC2)
+	{
+	  /* A valid lead code unit.  */
+	  ps->__count |= 0x80000000;
+	  ps->__value.__wchb[0] = c8;
+          ps->__value.__wchb[3] = 1;
+	  return 0;
+	}
+      /* A single byte (ASCII) code unit.  */
+      wc = c8;
+    }
+  else
+    {
+      char8_t cu1 = ps->__value.__wchb[0];
+      if (ps->__value.__wchb[3] == 1)
+	{
+	  /* A single lead code unit was previously seen.  */
+	  if ((c8 < 0x80 || c8 > 0xBF) ||
+               (cu1 == 0xE0 && c8 < 0xA0) ||
+               (cu1 == 0xED && c8 > 0x9F) ||
+               (cu1 == 0xF0 && c8 < 0x90) ||
+               (cu1 == 0xF4 && c8 > 0x8F))
+	    {
+	      /* An invalid second code unit.  */
+	      __set_errno (EILSEQ);
+	      return -1;
+	    }
+	  if (cu1 >= 0xE0)
+	    {
+	      /* A three or four code unit sequence.  */
+	      ps->__value.__wchb[1] = c8;
+	      ++ps->__value.__wchb[3];
+	      return 0;
+	    }
+	  wc = ((cu1 & 0x1F) << 6) +
+	       (c8 & 0x3F);
+	}
+      else
+	{
+	  char8_t cu2 = ps->__value.__wchb[1];
+	  /* A three or four byte code unit sequence.  */
+	  if (c8 < 0x80 || c8 > 0xBF)
+	    {
+	      /* An invalid third or fourth code unit.  */
+	      __set_errno (EILSEQ);
+	      return -1;
+	    }
+	  if (ps->__value.__wchb[3] == 2 && cu1 >= 0xF0)
+	    {
+	      /* A four code unit sequence.  */
+	      ps->__value.__wchb[2] = c8;
+	      ++ps->__value.__wchb[3];
+	      return 0;
+	    }
+	  if (cu1 < 0xF0)
+	    {
+	      wc = ((cu1 & 0x0F) << 12) +
+		   ((cu2 & 0x3F) << 6) +
+		   (c8 & 0x3F);
+	    }
+	  else
+	    {
+	      char8_t cu3 = ps->__value.__wchb[2];
+	      wc = ((cu1 & 0x07) << 18) +
+		   ((cu2 & 0x3F) << 12) +
+		   ((cu3 & 0x3F) << 6) +
+		   (c8 & 0x3F);
+	    }
+	}
+      ps->__count &= 0x7fffffff;
+      ps->__value.__wch = 0;
+    }
+
+  return wcrtomb (s, wc, ps);
+}
diff --git a/wcsmbs/mbrtoc8.c b/wcsmbs/mbrtoc8.c
new file mode 100644
index 0000000000..c112216de5
--- /dev/null
+++ b/wcsmbs/mbrtoc8.c
@@ -0,0 +1,131 @@
+/* Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Tom Honermann <tom@honermann.net>, 2020.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* Ensure that char8_t support is enabled so that the char8_t typedef is
+   declared.  */
+#define _CHAR8_T_SOURCE
+
+#include <features.h>
+#include <assert.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <gconv.h>
+#include <uchar.h>
+#include <wcsmbsload.h>
+
+#include <sysdep.h>
+
+#ifndef EILSEQ
+# define EILSEQ EINVAL
+#endif
+
+
+/* This is the private state used if PS is NULL.  */
+static mbstate_t state;
+
+size_t
+mbrtoc8 (char8_t *pc8, const char *s, size_t n, mbstate_t *ps)
+{
+  /* This implementation depends on the converter invoked by mbrtowc() not
+     needing to retain state in either the top most bit of ps->__count or
+     in ps->__value between invocations.  This implementation uses the
+     top most bit of ps->__count to indicate that trailing code units are
+     yet to be written and uses ps->__value to store those code units.  */
+
+  if (ps == NULL)
+    ps = &state;
+
+  /* If state indicates that trailing code units are yet to be written, write
+     those first regardless of whether 's' is a null pointer.  */
+  if (ps->__count & 0x80000000)
+    {
+      /* ps->__value.__wchb[3] stores the index of the next code unit to
+         write.  Code units are stored in reverse order.  */
+      size_t i = ps->__value.__wchb[3];
+      if (pc8 != NULL)
+	{
+	  *pc8 = ps->__value.__wchb[i];
+	}
+      if (i == 0)
+	{
+	  ps->__count &= 0x7fffffff;
+	  ps->__value.__wch = 0;
+	}
+      else
+	--ps->__value.__wchb[3];
+      return -3;
+    }
+
+  if (s == NULL)
+    {
+      /* if 's' is a null pointer, behave as if a null pointer was passed for
+         'pc8', an empty string was passed for 's', and 1 passed for 'n'.  */
+      pc8 = NULL;
+      s = "";
+      n = 1;
+    }
+
+  wchar_t wc;
+  size_t result;
+
+  result = mbrtowc(&wc, s, n, ps);
+  if (result <= n)
+    {
+      if (wc <= 0x7F)
+	{
+	  if (pc8 != NULL)
+	    *pc8 = wc;
+	}
+      else if (wc <= 0x7FF)
+	{
+	  if (pc8 != NULL)
+	    *pc8 = 0xC0 + ((wc >> 6) & 0x1F);
+	  ps->__value.__wchb[0] = 0x80 + (wc & 0x3F);
+	  ps->__value.__wchb[3] = 0;
+	  ps->__count |= 0x80000000;
+	}
+      else if (wc <= 0xFFFF)
+	{
+	  if (pc8 != NULL)
+	    *pc8 = 0xE0 + ((wc >> 12) & 0x0F);
+	  ps->__value.__wchb[1] = 0x80 + ((wc >> 6) & 0x3F);
+	  ps->__value.__wchb[0] = 0x80 + (wc & 0x3F);
+	  ps->__value.__wchb[3] = 1;
+	  ps->__count |= 0x80000000;
+	}
+      else if (wc <= 0x10FFFF)
+	{
+	  if (pc8 != NULL)
+	    *pc8 = 0xF0 + ((wc >> 18) & 0x07);
+	  ps->__value.__wchb[2] = 0x80 + ((wc >> 12) & 0x3F);
+	  ps->__value.__wchb[1] = 0x80 + ((wc >> 6) & 0x3F);
+	  ps->__value.__wchb[0] = 0x80 + (wc & 0x3F);
+	  ps->__value.__wchb[3] = 2;
+	  ps->__count |= 0x80000000;
+	}
+    }
+  if (result == 0 && wc != 0)
+    {
+      /* mbrtowc() never returns -3.  When a MB sequence converts to multiple
+         WCs, no input is consumed when writing the subsequent WCs resulting
+         in a result of 0 even if a null character wasn't written.  */
+      result = -3;
+    }
+
+  return result;
+}
diff --git a/wcsmbs/uchar.h b/wcsmbs/uchar.h
index 6020f66cf6..b23ff1a5ac 100644
--- a/wcsmbs/uchar.h
+++ b/wcsmbs/uchar.h
@@ -31,6 +31,14 @@
 #include <bits/types.h>
 #include <bits/types/mbstate_t.h>
 
+/* Define the char8_t typedef if support is enabled, but only if the C++
+   predefined feature test macro that indicates char8_t is a builtin type
+   is not defined.  */
+#if __GLIBC_USE (CHAR8_T) && !defined __cpp_char8_t
+/* Define the 8-bit character type.  */
+typedef unsigned char char8_t;
+#endif
+
 #ifndef __USE_ISOCXX11
 /* Define the 16-bit and 32-bit character types.  */
 typedef __uint_least16_t char16_t;
@@ -40,6 +48,18 @@ typedef __uint_least32_t char32_t;
 
 __BEGIN_DECLS
 
+#if __GLIBC_USE (CHAR8_T)
+/* Write char8_t representation of multibyte character pointed
+   to by S to PC8.  */
+extern size_t mbrtoc8  (char8_t *__restrict __pc8,
+			const char *__restrict __s, size_t __n,
+			mbstate_t *__restrict __p) __THROW;
+
+/* Write multibyte representation of char8_t C8 to S.  */
+extern size_t c8rtomb  (char *__restrict __s, char8_t __c8,
+			mbstate_t *__restrict __ps) __THROW;
+#endif
+
 /* Write char16_t representation of multibyte character pointed
    to by S to PC16.  */
 extern size_t mbrtoc16 (char16_t *__restrict __pc16,



^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2022-05-18 17:57 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-27 16:53 [PATCH 2/3]: C++20 P0482R6 and C2X N2653: Implement mbrtoc8, c8rtomb, char8_t Tom Honermann
2022-02-28 23:01 ` Joseph Myers
2022-03-01  3:40   ` Tom Honermann
2022-05-17 15:57     ` Carlos O'Donell
2022-05-17 18:05     ` Adhemerval Zanella
2022-05-17 18:12       ` Joseph Myers
2022-05-17 18:17         ` Adhemerval Zanella
2022-05-17 21:33           ` Florian Weimer
2022-05-18 15:32             ` Tom Honermann
2022-05-18 16:17               ` Adhemerval Zanella
2022-05-18 17:26                 ` Tom Honermann
2022-05-18 17:39                   ` Adhemerval Zanella
2022-05-18 17:40                 ` Florian Weimer
2022-05-18 17:57                   ` Adhemerval Zanella
  -- strict thread matches above, loose matches on Subject: below --
2022-01-08  0:39 Tom Honermann
2022-01-11  0:53 ` Joseph Myers
2022-01-11 19:23   ` Tom Honermann
2022-01-20 23:17     ` Tom Honermann
2022-01-21 20:01       ` Adhemerval Zanella
2022-01-22 12:24         ` Tom Honermann
2022-02-16 18:29           ` Joseph Myers
2022-02-16 19:14             ` tom
2021-06-07  2:08 Tom Honermann
2021-06-07 18:53 ` Joseph Myers
2021-06-11 11:25   ` Tom Honermann
2021-06-11 16:28     ` Joseph Myers
2021-06-13 15:35       ` Tom Honermann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).