bug-gnulib
[Top][All Lists]
Advanced

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

*printf-posix: ISO C 23: Support size specifiers 'wN' and 'wfN'


From: Bruno Haible
Subject: *printf-posix: ISO C 23: Support size specifiers 'wN' and 'wfN'
Date: Fri, 24 Mar 2023 22:26:03 +0100

ISO C 23 introduced new size specifiers (a.k.a. "length modifiers") in
format directives for *printf format strings. They are w8, w16, w32, w64,
wf8, wf16, wf32, wf64. This patch adds support for them.

Other wN and wfN values may exist, if <stdint.h> defines uintN_t or
uint_leastN_t or uint_fastN_t types. I'm not adding support for these
to Gnulib, because
  - only few platforms will ever define them.
  - As a consequence, their use will not be portable.

The motivation of these size specifiers is to make the PRI* macros from
<inttypes.h> obsolete. For example,
   "%" PRId64
is equivalent to
   "%w64d"

GNU gettext has specific support for the PRI* macros, which added complexity
to the message catalog loading code in glibc and libintl. No such complexity
is needed for the wN and wfN size specifiers.


2023-03-24  Bruno Haible  <bruno@clisp.org>

        *printf-posix: ISO C 23: Support size specifiers 'wN' and 'wfN'.
        * lib/printf-args.h: Include <stdint.h>.
        (arg_type): Add TYPE_[U]INT8_T, ..., TYPE_[U]INT_FAST64_T and
        TYPE_COUNT_INT8_T_POINTER, ..., TYPE_COUNT_INT_FAST64_T_POINTER.
        (argument): Add the union members a_[u]int8_t, ..., a_[u]int_fast64_t
        and a_count_int8_t_pointer, ..., a_count_int_fast64_t_pointer.
        * lib/printf-args.c: Include <limits.h>.
        (PRINTF_FETCHARGS): Handle TYPE_[U]INT8_T, ..., TYPE_[U]INT_FAST64_T and
        TYPE_COUNT_INT8_T_POINTER, ..., TYPE_COUNT_INT_FAST64_T_POINTER.
        * lib/printf-parse.c (PRINTF_PARSE): Accept only one size specifier, not
        a sequence of size specifiers. Accept "wN" and "wfN", where N = 8, 16,
        32, 64.
        * lib/vasnprintf.c (MAX_ROOM_NEEDED, VASNPRINTF): Handle the new TYPE_*
        values as well.
        * m4/printf.m4 (gl_PRINTF_SIZES_C23): New macro.
        * m4/vasnprintf-posix.m4 (gl_FUNC_VASNPRINTF_IS_POSIX): Require
        gl_PRINTF_SIZES_C23. Test gl_cv_func_printf_sizes_c23.
        * m4/dprintf-posix.m4 (gl_FUNC_DPRINTF_IS_POSIX): Likewise.
        * m4/fprintf-posix.m4 (gl_FUNC_FPRINTF_IS_POSIX): Likewise.
        * m4/obstack-printf-posix.m4 (gl_FUNC_OBSTACK_PRINTF_IS_POSIX):
        Likewise.
        * m4/snprintf-posix.m4 (gl_FUNC_SNPRINTF_IS_POSIX): Likewise.
        * m4/sprintf-posix.m4 (gl_FUNC_SPRINTF_IS_POSIX): Likewise.
        * m4/vasprintf-posix.m4 (gl_FUNC_VASPRINTF_IS_POSIX): Likewise.
        * m4/vdprintf-posix.m4 (gl_FUNC_VDPRINTF_IS_POSIX): Likewise.
        * m4/vfprintf-posix.m4 (gl_FUNC_VFPRINTF_IS_POSIX): Likewise.
        * m4/vsnprintf-posix.m4 (gl_FUNC_VSNPRINTF_IS_POSIX): Likewise.
        * m4/vsprintf-posix.m4 (gl_FUNC_VSPRINTF_IS_POSIX): Likewise.
        * tests/test-vasnprintf-posix.c (test_function): Add tests for size
        specifiers with %d, %u, %b, %o, %x.
        * tests/test-snprintf-posix.h (test_function): Likewise.
        * tests/test-sprintf-posix.h (test_function): Likewise.
        * tests/test-vasnwprintf-posix.c (test_function): Likewise.
        * tests/test-vasprintf-posix.c (test_function): Likewise.
        * modules/vasnprintf (Depends-on): Add limits-h.
        * modules/vasnwprintf (Depends-on): Add limits-h.
        * modules/c-vasnprintf (Depends-on): Add limits-h, stdint.
        * modules/unistdio/u-printf-args (Depends-on): Add stdint, limits-h.
        * doc/posix-functions/dprintf.texi: Mention the ISO C 23 size
        specifiers.
        * doc/posix-functions/fprintf.texi: Likewise.
        * doc/posix-functions/fwprintf.texi: Likewise.
        * doc/posix-functions/printf.texi: Likewise.
        * doc/posix-functions/snprintf.texi: Likewise.
        * doc/posix-functions/sprintf.texi: Likewise.
        * doc/posix-functions/swprintf.texi: Likewise.
        * doc/posix-functions/vdprintf.texi: Likewise.
        * doc/posix-functions/vfprintf.texi: Likewise.
        * doc/posix-functions/vfwprintf.texi: Likewise.
        * doc/posix-functions/vprintf.texi: Likewise.
        * doc/posix-functions/vsnprintf.texi: Likewise.
        * doc/posix-functions/vsprintf.texi: Likewise.
        * doc/posix-functions/vswprintf.texi: Likewise.
        * doc/posix-functions/vwprintf.texi: Likewise.
        * doc/posix-functions/wprintf.texi: Likewise.

diff --git a/doc/posix-functions/dprintf.texi b/doc/posix-functions/dprintf.texi
index 54953d04a3..2f90377590 100644
--- a/doc/posix-functions/dprintf.texi
+++ b/doc/posix-functions/dprintf.texi
@@ -16,6 +16,12 @@
 Portability problems fixed by either Gnulib module @code{dprintf-posix} or 
@code{dprintf-gnu}:
 @itemize
 @item
+This function does not support size specifiers as in C23 (@code{w8},
+@code{w16}, @code{w32}, @code{w64}, @code{wf8}, @code{wf16}, @code{wf32},
+@code{wf64}) on some platforms:
+glibc, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, Solaris 11.4, Cygwin 2.9.0.
+@item
 printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an
 incorrect result on some platforms:
 Solaris 11.4.
diff --git a/doc/posix-functions/fprintf.texi b/doc/posix-functions/fprintf.texi
index 3ee74b41ae..7e1d2254ca 100644
--- a/doc/posix-functions/fprintf.texi
+++ b/doc/posix-functions/fprintf.texi
@@ -13,6 +13,12 @@
 @code{j}, @code{t}, @code{z}) on some platforms:
 AIX 5.1, HP-UX 11.23, IRIX 6.5, Solaris 9, Cygwin 1.5.24, mingw, MSVC 14.
 @item
+This function does not support size specifiers as in C23 (@code{w8},
+@code{w16}, @code{w32}, @code{w64}, @code{wf8}, @code{wf16}, @code{wf32},
+@code{wf64}) on some platforms:
+glibc, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
 printf of @samp{long double} numbers is unsupported on some platforms:
 mingw, MSVC 14.
 @item
diff --git a/doc/posix-functions/fwprintf.texi 
b/doc/posix-functions/fwprintf.texi
index b9ce2eb024..2b4600de11 100644
--- a/doc/posix-functions/fwprintf.texi
+++ b/doc/posix-functions/fwprintf.texi
@@ -19,6 +19,12 @@
 On Windows and 32-bit AIX platforms, @code{wchar_t} is a 16-bit type and 
therefore cannot
 accommodate all Unicode characters.
 @item
+This function does not support size specifiers as in C23 (@code{w8},
+@code{w16}, @code{w32}, @code{w64}, @code{wf8}, @code{wf16}, @code{wf32},
+@code{wf64}) on some platforms:
+glibc, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
 This function does not support the @samp{b} directive, required by ISO C23,
 on some platforms:
 glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
diff --git a/doc/posix-functions/printf.texi b/doc/posix-functions/printf.texi
index 382873e9e0..e8fafa4bdb 100644
--- a/doc/posix-functions/printf.texi
+++ b/doc/posix-functions/printf.texi
@@ -13,6 +13,12 @@
 @code{j}, @code{t}, @code{z}) on some platforms:
 AIX 5.1, HP-UX 11.23, IRIX 6.5, Solaris 9, Cygwin 1.5.24, mingw, MSVC 14.
 @item
+This function does not support size specifiers as in C23 (@code{w8},
+@code{w16}, @code{w32}, @code{w64}, @code{wf8}, @code{wf16}, @code{wf32},
+@code{wf64}) on some platforms:
+glibc, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
 printf of @samp{long double} numbers is unsupported on some platforms:
 mingw, MSVC 14.
 @item
diff --git a/doc/posix-functions/snprintf.texi 
b/doc/posix-functions/snprintf.texi
index a5a7550c7d..032c6ff023 100644
--- a/doc/posix-functions/snprintf.texi
+++ b/doc/posix-functions/snprintf.texi
@@ -28,6 +28,12 @@
 @code{j}, @code{t}, @code{z}) on some platforms:
 AIX 5.1, HP-UX 11.23, IRIX 6.5, Solaris 9, Cygwin 1.5.24, mingw, MSVC 14.
 @item
+This function does not support size specifiers as in C23 (@code{w8},
+@code{w16}, @code{w32}, @code{w64}, @code{wf8}, @code{wf16}, @code{wf32},
+@code{wf64}) on some platforms:
+glibc, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9.0, mingw.
+@item
 printf of @samp{long double} numbers is unsupported on some platforms:
 mingw, MSVC 14.
 @item
diff --git a/doc/posix-functions/sprintf.texi b/doc/posix-functions/sprintf.texi
index 54816f26ab..5d88d38c3f 100644
--- a/doc/posix-functions/sprintf.texi
+++ b/doc/posix-functions/sprintf.texi
@@ -13,6 +13,12 @@
 @code{j}, @code{t}, @code{z}) on some platforms:
 AIX 5.1, HP-UX 11.23, IRIX 6.5, Solaris 9, Cygwin 1.5.24, mingw, MSVC 14.
 @item
+This function does not support size specifiers as in C23 (@code{w8},
+@code{w16}, @code{w32}, @code{w64}, @code{wf8}, @code{wf16}, @code{wf32},
+@code{wf64}) on some platforms:
+glibc, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
 printf of @samp{long double} numbers is unsupported on some platforms:
 mingw, MSVC 14.
 @item
diff --git a/doc/posix-functions/swprintf.texi 
b/doc/posix-functions/swprintf.texi
index 357cfc1ad4..b53c96c6d7 100644
--- a/doc/posix-functions/swprintf.texi
+++ b/doc/posix-functions/swprintf.texi
@@ -36,6 +36,12 @@
 @item
 On Windows, this function does not take a buffer size as second argument.
 @item
+This function does not support size specifiers as in C23 (@code{w8},
+@code{w16}, @code{w32}, @code{w64}, @code{wf8}, @code{wf16}, @code{wf32},
+@code{wf64}) on some platforms:
+glibc, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
 This function ignores the minimum field width in the @samp{lc} directive
 on some platforms:
 @c https://www.openwall.com/lists/musl/2023/03/20/1
diff --git a/doc/posix-functions/vdprintf.texi 
b/doc/posix-functions/vdprintf.texi
index 59138d5d15..f21172c441 100644
--- a/doc/posix-functions/vdprintf.texi
+++ b/doc/posix-functions/vdprintf.texi
@@ -16,6 +16,12 @@
 Portability problems fixed by either Gnulib module @code{vdprintf-posix} or 
@code{vdprintf-gnu}:
 @itemize
 @item
+This function does not support size specifiers as in C23 (@code{w8},
+@code{w16}, @code{w32}, @code{w64}, @code{wf8}, @code{wf16}, @code{wf32},
+@code{wf64}) on some platforms:
+glibc, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, Solaris 11.4, Cygwin 2.9.0.
+@item
 printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an
 incorrect result on some platforms:
 Solaris 11.4.
diff --git a/doc/posix-functions/vfprintf.texi 
b/doc/posix-functions/vfprintf.texi
index 719bba0698..b4ae2cc733 100644
--- a/doc/posix-functions/vfprintf.texi
+++ b/doc/posix-functions/vfprintf.texi
@@ -13,6 +13,12 @@
 @code{j}, @code{t}, @code{z}) on some platforms:
 AIX 5.1, HP-UX 11.23, IRIX 6.5, Solaris 9, Cygwin 1.5.24, mingw, MSVC 14.
 @item
+This function does not support size specifiers as in C23 (@code{w8},
+@code{w16}, @code{w32}, @code{w64}, @code{wf8}, @code{wf16}, @code{wf32},
+@code{wf64}) on some platforms:
+glibc, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
 printf of @samp{long double} numbers is unsupported on some platforms:
 mingw, MSVC 14.
 @item
diff --git a/doc/posix-functions/vfwprintf.texi 
b/doc/posix-functions/vfwprintf.texi
index f6e136b0b1..22e4a59212 100644
--- a/doc/posix-functions/vfwprintf.texi
+++ b/doc/posix-functions/vfwprintf.texi
@@ -19,6 +19,12 @@
 On Windows and 32-bit AIX platforms, @code{wchar_t} is a 16-bit type and 
therefore cannot
 accommodate all Unicode characters.
 @item
+This function does not support size specifiers as in C23 (@code{w8},
+@code{w16}, @code{w32}, @code{w64}, @code{wf8}, @code{wf16}, @code{wf32},
+@code{wf64}) on some platforms:
+glibc, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
 This function does not support the @samp{b} directive, required by ISO C23,
 on some platforms:
 glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
diff --git a/doc/posix-functions/vprintf.texi b/doc/posix-functions/vprintf.texi
index 051aef880d..a69eb467cd 100644
--- a/doc/posix-functions/vprintf.texi
+++ b/doc/posix-functions/vprintf.texi
@@ -13,6 +13,12 @@
 @code{j}, @code{t}, @code{z}) on some platforms:
 AIX 5.1, HP-UX 11.23, IRIX 6.5, Solaris 9, Cygwin 1.5.24, mingw, MSVC 14.
 @item
+This function does not support size specifiers as in C23 (@code{w8},
+@code{w16}, @code{w32}, @code{w64}, @code{wf8}, @code{wf16}, @code{wf32},
+@code{wf64}) on some platforms:
+glibc, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
 printf of @samp{long double} numbers is unsupported on some platforms:
 mingw, MSVC 14.
 @item
diff --git a/doc/posix-functions/vsnprintf.texi 
b/doc/posix-functions/vsnprintf.texi
index e99292f178..90613a95ef 100644
--- a/doc/posix-functions/vsnprintf.texi
+++ b/doc/posix-functions/vsnprintf.texi
@@ -25,6 +25,12 @@
 @code{j}, @code{t}, @code{z}) on some platforms:
 AIX 5.1, HP-UX 11.23, IRIX 6.5, Solaris 9, Cygwin 1.5.24, mingw, MSVC 14.
 @item
+This function does not support size specifiers as in C23 (@code{w8},
+@code{w16}, @code{w32}, @code{w64}, @code{wf8}, @code{wf16}, @code{wf32},
+@code{wf64}) on some platforms:
+glibc, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
 printf of @samp{long double} numbers is unsupported on some platforms:
 mingw, MSVC 14.
 @item
diff --git a/doc/posix-functions/vsprintf.texi 
b/doc/posix-functions/vsprintf.texi
index 5ae3644e00..e75af4fb3b 100644
--- a/doc/posix-functions/vsprintf.texi
+++ b/doc/posix-functions/vsprintf.texi
@@ -13,6 +13,12 @@
 @code{j}, @code{t}, @code{z}) on some platforms:
 AIX 5.1, HP-UX 11.23, IRIX 6.5, Solaris 9, Cygwin 1.5.24, mingw, MSVC 14.
 @item
+This function does not support size specifiers as in C23 (@code{w8},
+@code{w16}, @code{w32}, @code{w64}, @code{wf8}, @code{wf16}, @code{wf32},
+@code{wf64}) on some platforms:
+glibc, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
 printf of @samp{long double} numbers is unsupported on some platforms:
 mingw, MSVC 14.
 @item
diff --git a/doc/posix-functions/vswprintf.texi 
b/doc/posix-functions/vswprintf.texi
index 62a644fb6d..4083cfd2a1 100644
--- a/doc/posix-functions/vswprintf.texi
+++ b/doc/posix-functions/vswprintf.texi
@@ -21,6 +21,12 @@
 @item
 On Windows, this function does not take a buffer size as second argument.
 @item
+This function does not support size specifiers as in C23 (@code{w8},
+@code{w16}, @code{w32}, @code{w64}, @code{wf8}, @code{wf16}, @code{wf32},
+@code{wf64}) on some platforms:
+glibc, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
 This function does not support the @samp{b} directive, required by ISO C23,
 on some platforms:
 glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
diff --git a/doc/posix-functions/vwprintf.texi 
b/doc/posix-functions/vwprintf.texi
index 80c8646663..7b029c9ceb 100644
--- a/doc/posix-functions/vwprintf.texi
+++ b/doc/posix-functions/vwprintf.texi
@@ -22,6 +22,12 @@
 On Windows and 32-bit AIX platforms, @code{wchar_t} is a 16-bit type and 
therefore cannot
 accommodate all Unicode characters.
 @item
+This function does not support size specifiers as in C23 (@code{w8},
+@code{w16}, @code{w32}, @code{w64}, @code{wf8}, @code{wf16}, @code{wf32},
+@code{wf64}) on some platforms:
+glibc, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
 This function does not support the @samp{b} directive, required by ISO C23,
 on some platforms:
 glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
diff --git a/doc/posix-functions/wprintf.texi b/doc/posix-functions/wprintf.texi
index 1c3b99b281..56106b309e 100644
--- a/doc/posix-functions/wprintf.texi
+++ b/doc/posix-functions/wprintf.texi
@@ -22,6 +22,12 @@
 On Windows and 32-bit AIX platforms, @code{wchar_t} is a 16-bit type and 
therefore cannot
 accommodate all Unicode characters.
 @item
+This function does not support size specifiers as in C23 (@code{w8},
+@code{w16}, @code{w32}, @code{w64}, @code{wf8}, @code{wf16}, @code{wf32},
+@code{wf64}) on some platforms:
+glibc, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
 This function does not support the @samp{b} directive, required by ISO C23,
 on some platforms:
 glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
diff --git a/lib/printf-args.c b/lib/printf-args.c
index 5e14f65479..b2b21aeec1 100644
--- a/lib/printf-args.c
+++ b/lib/printf-args.c
@@ -29,6 +29,9 @@
 # include "printf-args.h"
 #endif
 
+/* Get INT_WIDTH.  */
+#include <limits.h>
+
 #ifdef STATIC
 STATIC
 #endif
@@ -71,6 +74,102 @@ PRINTF_FETCHARGS (va_list args, arguments *a)
       case TYPE_ULONGLONGINT:
         ap->a.a_ulonglongint = va_arg (args, unsigned long long int);
         break;
+      case TYPE_INT8_T:
+        #if INT8_WIDTH < INT_WIDTH
+        ap->a.a_int8_t = va_arg (args, /* int8_t */ int);
+        #else
+        ap->a.a_int8_t = va_arg (args, int8_t);
+        #endif
+        break;
+      case TYPE_UINT8_T:
+        #if UINT8_WIDTH < INT_WIDTH
+        ap->a.a_uint8_t = va_arg (args, /* uint8_t */ int);
+        #else
+        ap->a.a_uint8_t = va_arg (args, uint8_t);
+        #endif
+        break;
+      case TYPE_INT16_T:
+        #if INT16_WIDTH < INT_WIDTH
+        ap->a.a_int16_t = va_arg (args, /* int16_t */ int);
+        #else
+        ap->a.a_int16_t = va_arg (args, int16_t);
+        #endif
+        break;
+      case TYPE_UINT16_T:
+        #if UINT16_WIDTH < INT_WIDTH
+        ap->a.a_uint16_t = va_arg (args, /* uint16_t */ int);
+        #else
+        ap->a.a_uint16_t = va_arg (args, uint16_t);
+        #endif
+        break;
+      case TYPE_INT32_T:
+        #if INT32_WIDTH < INT_WIDTH
+        ap->a.a_int32_t = va_arg (args, /* int32_t */ int);
+        #else
+        ap->a.a_int32_t = va_arg (args, int32_t);
+        #endif
+        break;
+      case TYPE_UINT32_T:
+        #if UINT32_WIDTH < INT_WIDTH
+        ap->a.a_uint32_t = va_arg (args, /* uint32_t */ int);
+        #else
+        ap->a.a_uint32_t = va_arg (args, uint32_t);
+        #endif
+        break;
+      case TYPE_INT64_T:
+        ap->a.a_int64_t = va_arg (args, int64_t);
+        break;
+      case TYPE_UINT64_T:
+        ap->a.a_uint64_t = va_arg (args, uint64_t);
+        break;
+      case TYPE_INT_FAST8_T:
+        #if INT_FAST8_WIDTH < INT_WIDTH
+        ap->a.a_int_fast8_t = va_arg (args, /* int_fast8_t */ int);
+        #else
+        ap->a.a_int_fast8_t = va_arg (args, int_fast8_t);
+        #endif
+        break;
+      case TYPE_UINT_FAST8_T:
+        #if UINT_FAST8_WIDTH < INT_WIDTH
+        ap->a.a_uint_fast8_t = va_arg (args, /* uint_fast8_t */ int);
+        #else
+        ap->a.a_uint_fast8_t = va_arg (args, uint_fast8_t);
+        #endif
+        break;
+      case TYPE_INT_FAST16_T:
+        #if INT_FAST16_WIDTH < INT_WIDTH
+        ap->a.a_int_fast16_t = va_arg (args, /* int_fast16_t */ int);
+        #else
+        ap->a.a_int_fast16_t = va_arg (args, int_fast16_t);
+        #endif
+        break;
+      case TYPE_UINT_FAST16_T:
+        #if UINT_FAST16_WIDTH < INT_WIDTH
+        ap->a.a_uint_fast16_t = va_arg (args, /* uint_fast16_t */ int);
+        #else
+        ap->a.a_uint_fast16_t = va_arg (args, uint_fast16_t);
+        #endif
+        break;
+      case TYPE_INT_FAST32_T:
+        #if INT_FAST32_WIDTH < INT_WIDTH
+        ap->a.a_int_fast32_t = va_arg (args, /* int_fast32_t */ int);
+        #else
+        ap->a.a_int_fast32_t = va_arg (args, int_fast32_t);
+        #endif
+        break;
+      case TYPE_UINT_FAST32_T:
+        #if UINT_FAST32_WIDTH < INT_WIDTH
+        ap->a.a_uint_fast32_t = va_arg (args, /* uint_fast32_t */ int);
+        #else
+        ap->a.a_uint_fast32_t = va_arg (args, uint_fast32_t);
+        #endif
+        break;
+      case TYPE_INT_FAST64_T:
+        ap->a.a_int_fast64_t = va_arg (args, int_fast64_t);
+        break;
+      case TYPE_UINT_FAST64_T:
+        ap->a.a_uint_fast64_t = va_arg (args, uint_fast64_t);
+        break;
       case TYPE_DOUBLE:
         ap->a.a_double = va_arg (args, double);
         break;
@@ -136,6 +235,30 @@ PRINTF_FETCHARGS (va_list args, arguments *a)
       case TYPE_COUNT_LONGLONGINT_POINTER:
         ap->a.a_count_longlongint_pointer = va_arg (args, long long int *);
         break;
+      case TYPE_COUNT_INT8_T_POINTER:
+        ap->a.a_count_int8_t_pointer = va_arg (args, int8_t *);
+        break;
+      case TYPE_COUNT_INT16_T_POINTER:
+        ap->a.a_count_int16_t_pointer = va_arg (args, int16_t *);
+        break;
+      case TYPE_COUNT_INT32_T_POINTER:
+        ap->a.a_count_int32_t_pointer = va_arg (args, int32_t *);
+        break;
+      case TYPE_COUNT_INT64_T_POINTER:
+        ap->a.a_count_int64_t_pointer = va_arg (args, int64_t *);
+        break;
+      case TYPE_COUNT_INT_FAST8_T_POINTER:
+        ap->a.a_count_int_fast8_t_pointer = va_arg (args, int_fast8_t *);
+        break;
+      case TYPE_COUNT_INT_FAST16_T_POINTER:
+        ap->a.a_count_int_fast16_t_pointer = va_arg (args, int_fast16_t *);
+        break;
+      case TYPE_COUNT_INT_FAST32_T_POINTER:
+        ap->a.a_count_int_fast32_t_pointer = va_arg (args, int_fast32_t *);
+        break;
+      case TYPE_COUNT_INT_FAST64_T_POINTER:
+        ap->a.a_count_int_fast64_t_pointer = va_arg (args, int_fast64_t *);
+        break;
 #if ENABLE_UNISTDIO
       /* The unistdio extensions.  */
       case TYPE_U8_STRING:
diff --git a/lib/printf-args.h b/lib/printf-args.h
index f303cb19e9..1101610282 100644
--- a/lib/printf-args.h
+++ b/lib/printf-args.h
@@ -41,6 +41,9 @@
 # include <wchar.h>
 #endif
 
+/* Get intN_t, uintN_t, intN_fast_t, uintN_fast_t.  */
+#include <stdint.h>
+
 /* Get va_list.  */
 #include <stdarg.h>
 
@@ -59,6 +62,26 @@ typedef enum
   TYPE_ULONGINT,
   TYPE_LONGLONGINT,
   TYPE_ULONGLONGINT,
+  /* According to ISO C 23 ยง 7.23.6.1, "all exact-width integer types",
+     "all minimum-width integer types", and "all fastest minimum-width integer
+     types" defined in <stdint.h> should be supported.  But for portability
+     between platforms, we support only those with N = 8, 16, 32, 64.  */
+  TYPE_INT8_T,
+  TYPE_UINT8_T,
+  TYPE_INT16_T,
+  TYPE_UINT16_T,
+  TYPE_INT32_T,
+  TYPE_UINT32_T,
+  TYPE_INT64_T,
+  TYPE_UINT64_T,
+  TYPE_INT_FAST8_T,
+  TYPE_UINT_FAST8_T,
+  TYPE_INT_FAST16_T,
+  TYPE_UINT_FAST16_T,
+  TYPE_INT_FAST32_T,
+  TYPE_UINT_FAST32_T,
+  TYPE_INT_FAST64_T,
+  TYPE_UINT_FAST64_T,
   TYPE_DOUBLE,
   TYPE_LONGDOUBLE,
   TYPE_CHAR,
@@ -74,7 +97,15 @@ typedef enum
   TYPE_COUNT_SHORT_POINTER,
   TYPE_COUNT_INT_POINTER,
   TYPE_COUNT_LONGINT_POINTER,
-  TYPE_COUNT_LONGLONGINT_POINTER
+  TYPE_COUNT_LONGLONGINT_POINTER,
+  TYPE_COUNT_INT8_T_POINTER,
+  TYPE_COUNT_INT16_T_POINTER,
+  TYPE_COUNT_INT32_T_POINTER,
+  TYPE_COUNT_INT64_T_POINTER,
+  TYPE_COUNT_INT_FAST8_T_POINTER,
+  TYPE_COUNT_INT_FAST16_T_POINTER,
+  TYPE_COUNT_INT_FAST32_T_POINTER,
+  TYPE_COUNT_INT_FAST64_T_POINTER
 #if ENABLE_UNISTDIO
   /* The unistdio extensions.  */
 , TYPE_U8_STRING
@@ -99,7 +130,23 @@ typedef struct
     unsigned long int           a_ulongint;
     long long int               a_longlongint;
     unsigned long long int      a_ulonglongint;
-    float                       a_float;
+    int8_t                      a_int8_t;
+    uint8_t                     a_uint8_t;
+    int16_t                     a_int16_t;
+    uint16_t                    a_uint16_t;
+    int32_t                     a_int32_t;
+    uint32_t                    a_uint32_t;
+    int64_t                     a_int64_t;
+    uint64_t                    a_uint64_t;
+    int_fast8_t                 a_int_fast8_t;
+    uint_fast8_t                a_uint_fast8_t;
+    int_fast16_t                a_int_fast16_t;
+    uint_fast16_t               a_uint_fast16_t;
+    int_fast32_t                a_int_fast32_t;
+    uint_fast32_t               a_uint_fast32_t;
+    int_fast64_t                a_int_fast64_t;
+    uint_fast64_t               a_uint_fast64_t;
+    float                       a_float;                     /* unused */
     double                      a_double;
     long double                 a_longdouble;
     int                         a_char;
@@ -116,6 +163,14 @@ typedef struct
     int *                       a_count_int_pointer;
     long int *                  a_count_longint_pointer;
     long long int *             a_count_longlongint_pointer;
+    int8_t *                    a_count_int8_t_pointer;
+    int16_t *                   a_count_int16_t_pointer;
+    int32_t *                   a_count_int32_t_pointer;
+    int64_t *                   a_count_int64_t_pointer;
+    int_fast8_t *               a_count_int_fast8_t_pointer;
+    int_fast16_t *              a_count_int_fast16_t_pointer;
+    int_fast32_t *              a_count_int_fast32_t_pointer;
+    int_fast64_t *              a_count_int_fast64_t_pointer;
 #if ENABLE_UNISTDIO
     /* The unistdio extensions.  */
     const uint8_t *             a_u8_string;
diff --git a/lib/printf-parse.c b/lib/printf-parse.c
index 7fbd1d4b53..d3f2c3cb5d 100644
--- a/lib/printf-parse.c
+++ b/lib/printf-parse.c
@@ -326,230 +326,317 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, 
arguments *a)
             arg_type type;
 
             /* Parse argument type/size specifiers.  */
-            {
-              int flags = 0;
-
-              for (;;)
-                {
-                  if (*cp == 'h')
-                    {
-                      flags |= (1 << (flags & 1));
-                      cp++;
-                    }
-                  else if (*cp == 'L')
-                    {
-                      flags |= 4;
-                      cp++;
-                    }
-                  else if (*cp == 'l')
-                    {
-                      flags += 8;
-                      cp++;
-                    }
-                  else if (*cp == 'j')
-                    {
-                      if (sizeof (intmax_t) > sizeof (long))
-                        {
-                          /* intmax_t = long long */
-                          flags += 16;
-                        }
-                      else if (sizeof (intmax_t) > sizeof (int))
-                        {
-                          /* intmax_t = long */
-                          flags += 8;
-                        }
-                      cp++;
-                    }
-                  else if (*cp == 'z' || *cp == 'Z')
-                    {
-                      /* 'z' is standardized in ISO C 99, but glibc uses 'Z'
-                         because the warning facility in gcc-2.95.2 understands
-                         only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784).  */
-                      if (sizeof (size_t) > sizeof (long))
-                        {
-                          /* size_t = long long */
-                          flags += 16;
-                        }
-                      else if (sizeof (size_t) > sizeof (int))
-                        {
-                          /* size_t = long */
-                          flags += 8;
-                        }
-                      cp++;
-                    }
-                  else if (*cp == 't')
-                    {
-                      if (sizeof (ptrdiff_t) > sizeof (long))
-                        {
-                          /* ptrdiff_t = long long */
-                          flags += 16;
-                        }
-                      else if (sizeof (ptrdiff_t) > sizeof (int))
-                        {
-                          /* ptrdiff_t = long */
-                          flags += 8;
-                        }
-                      cp++;
-                    }
+            /* Relevant for the conversion characters d, i.  */
+            arg_type signed_type = TYPE_INT;
+            /* Relevant for the conversion characters b, o, u, x, X.  */
+            arg_type unsigned_type = TYPE_UINT;
+            /* Relevant for the conversion characters n.  */
+            arg_type pointer_type = TYPE_COUNT_INT_POINTER;
+            /* Relevant for the conversion characters a, A, e, E, f, F, g, G.  
*/
+            arg_type floatingpoint_type = TYPE_DOUBLE;
+
+            if (*cp == 'h')
+              {
+                if (cp[1] == 'h')
+                  {
+                    signed_type = TYPE_SCHAR;
+                    unsigned_type = TYPE_UCHAR;
+                    pointer_type = TYPE_COUNT_SCHAR_POINTER;
+                    cp += 2;
+                  }
+                else
+                  {
+                    signed_type = TYPE_SHORT;
+                    unsigned_type = TYPE_USHORT;
+                    pointer_type = TYPE_COUNT_SHORT_POINTER;
+                    cp++;
+                  }
+              }
+            else if (*cp == 'l')
+              {
+                if (cp[1] == 'l')
+                  {
+                    signed_type = TYPE_LONGLONGINT;
+                    unsigned_type = TYPE_ULONGLONGINT;
+                    pointer_type = TYPE_COUNT_LONGLONGINT_POINTER;
+                    /* For backward compatibility only.  */
+                    floatingpoint_type = TYPE_LONGDOUBLE;
+                    cp += 2;
+                  }
+                else
+                  {
+                    signed_type = TYPE_LONGINT;
+                    unsigned_type = TYPE_ULONGINT;
+                    pointer_type = TYPE_COUNT_LONGINT_POINTER;
+                    cp++;
+                  }
+              }
+            else if (*cp == 'j')
+              {
+                if (sizeof (intmax_t) > sizeof (long))
+                  {
+                    /* intmax_t = long long */
+                    signed_type = TYPE_LONGLONGINT;
+                    unsigned_type = TYPE_ULONGLONGINT;
+                    pointer_type = TYPE_COUNT_LONGLONGINT_POINTER;
+                    /* For backward compatibility only.  */
+                    floatingpoint_type = TYPE_LONGDOUBLE;
+                  }
+                else if (sizeof (intmax_t) > sizeof (int))
+                  {
+                    /* intmax_t = long */
+                    signed_type = TYPE_LONGINT;
+                    unsigned_type = TYPE_ULONGINT;
+                    pointer_type = TYPE_COUNT_LONGINT_POINTER;
+                  }
+                cp++;
+              }
+            else if (*cp == 'z' || *cp == 'Z')
+              {
+                /* 'z' is standardized in ISO C 99, but glibc uses 'Z'
+                   because the warning facility in gcc-2.95.2 understands
+                   only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784).  */
+                if (sizeof (size_t) > sizeof (long))
+                  {
+                    /* size_t = unsigned long long */
+                    signed_type = TYPE_LONGLONGINT;
+                    unsigned_type = TYPE_ULONGLONGINT;
+                    pointer_type = TYPE_COUNT_LONGLONGINT_POINTER;
+                    /* For backward compatibility only.  */
+                    floatingpoint_type = TYPE_LONGDOUBLE;
+                  }
+                else if (sizeof (size_t) > sizeof (int))
+                  {
+                    /* size_t = unsigned long */
+                    signed_type = TYPE_LONGINT;
+                    unsigned_type = TYPE_ULONGINT;
+                    pointer_type = TYPE_COUNT_LONGINT_POINTER;
+                  }
+                cp++;
+              }
+            else if (*cp == 't')
+              {
+                if (sizeof (ptrdiff_t) > sizeof (long))
+                  {
+                    /* ptrdiff_t = long long */
+                    signed_type = TYPE_LONGLONGINT;
+                    unsigned_type = TYPE_ULONGLONGINT;
+                    pointer_type = TYPE_COUNT_LONGLONGINT_POINTER;
+                    /* For backward compatibility only.  */
+                    floatingpoint_type = TYPE_LONGDOUBLE;
+                  }
+                else if (sizeof (ptrdiff_t) > sizeof (int))
+                  {
+                    /* ptrdiff_t = long */
+                    signed_type = TYPE_LONGINT;
+                    unsigned_type = TYPE_ULONGINT;
+                    pointer_type = TYPE_COUNT_LONGINT_POINTER;
+                  }
+                cp++;
+              }
+            else if (*cp == 'w')
+              {
+                /* wN and wfN are standardized in ISO C 23.  */
+                if (cp[1] == 'f')
+                  {
+                    if (cp[2] == '8')
+                      {
+                        signed_type = TYPE_INT_FAST8_T;
+                        unsigned_type = TYPE_UINT_FAST8_T;
+                        pointer_type = TYPE_COUNT_INT_FAST8_T_POINTER;
+                        cp += 3;
+                      }
+                    else if (cp[2] == '1' && cp[3] == '6')
+                      {
+                        signed_type = TYPE_INT_FAST16_T;
+                        unsigned_type = TYPE_UINT_FAST16_T;
+                        pointer_type = TYPE_COUNT_INT_FAST16_T_POINTER;
+                        cp += 4;
+                      }
+                    else if (cp[2] == '3' && cp[3] == '2')
+                      {
+                        signed_type = TYPE_INT_FAST32_T;
+                        unsigned_type = TYPE_UINT_FAST32_T;
+                        pointer_type = TYPE_COUNT_INT_FAST32_T_POINTER;
+                        cp += 4;
+                      }
+                    else if (cp[2] == '6' && cp[3] == '4')
+                      {
+                        signed_type = TYPE_INT_FAST64_T;
+                        unsigned_type = TYPE_UINT_FAST64_T;
+                        pointer_type = TYPE_COUNT_INT_FAST64_T_POINTER;
+                        cp += 4;
+                      }
+                  }
+                else
+                  {
+                    if (cp[1] == '8')
+                      {
+                        signed_type = TYPE_INT8_T;
+                        unsigned_type = TYPE_UINT8_T;
+                        pointer_type = TYPE_COUNT_INT8_T_POINTER;
+                        cp += 2;
+                      }
+                    else if (cp[1] == '1' && cp[2] == '6')
+                      {
+                        signed_type = TYPE_INT16_T;
+                        unsigned_type = TYPE_UINT16_T;
+                        pointer_type = TYPE_COUNT_INT16_T_POINTER;
+                        cp += 3;
+                      }
+                    else if (cp[1] == '3' && cp[2] == '2')
+                      {
+                        signed_type = TYPE_INT32_T;
+                        unsigned_type = TYPE_UINT32_T;
+                        pointer_type = TYPE_COUNT_INT32_T_POINTER;
+                        cp += 3;
+                      }
+                    else if (cp[1] == '6' && cp[2] == '4')
+                      {
+                        signed_type = TYPE_INT64_T;
+                        unsigned_type = TYPE_UINT64_T;
+                        pointer_type = TYPE_COUNT_INT64_T_POINTER;
+                        cp += 3;
+                      }
+                  }
+              }
+            else if (*cp == 'L')
+              {
+                signed_type = TYPE_LONGLONGINT;
+                unsigned_type = TYPE_ULONGLONGINT;
+                pointer_type = TYPE_COUNT_LONGLONGINT_POINTER;
+                floatingpoint_type = TYPE_LONGDOUBLE;
+                cp++;
+              }
 #if defined __APPLE__ && defined __MACH__
-                  /* On Mac OS X 10.3, PRIdMAX is defined as "qd".
-                     We cannot change it to "lld" because PRIdMAX must also
-                     be understood by the system's printf routines.  */
-                  else if (*cp == 'q')
-                    {
-                      if (64 / 8 > sizeof (long))
-                        {
-                          /* int64_t = long long */
-                          flags += 16;
-                        }
-                      else
-                        {
-                          /* int64_t = long */
-                          flags += 8;
-                        }
-                      cp++;
-                    }
+            /* On Mac OS X 10.3, PRIdMAX is defined as "qd".
+               We cannot change it to "lld" because PRIdMAX must also
+               be understood by the system's printf routines.  */
+            else if (*cp == 'q')
+              {
+                if (64 / 8 > sizeof (long))
+                  {
+                    /* int64_t = long long */
+                    signed_type = TYPE_LONGLONGINT;
+                    unsigned_type = TYPE_ULONGLONGINT;
+                    pointer_type = TYPE_COUNT_LONGLONGINT_POINTER;
+                    /* For backward compatibility only.  */
+                    floatingpoint_type = TYPE_LONGDOUBLE;
+                  }
+                else
+                  {
+                    /* int64_t = long */
+                    signed_type = TYPE_LONGINT;
+                    unsigned_type = TYPE_ULONGINT;
+                    pointer_type = TYPE_COUNT_LONGINT_POINTER;
+                  }
+                cp++;
+              }
 #endif
 #if defined _WIN32 && ! defined __CYGWIN__
-                  /* On native Windows, PRIdMAX is defined as "I64d".
-                     We cannot change it to "lld" because PRIdMAX must also
-                     be understood by the system's printf routines.  */
-                  else if (*cp == 'I' && cp[1] == '6' && cp[2] == '4')
-                    {
-                      if (64 / 8 > sizeof (long))
-                        {
-                          /* __int64 = long long */
-                          flags += 16;
-                        }
-                      else
-                        {
-                          /* __int64 = long */
-                          flags += 8;
-                        }
-                      cp += 3;
-                    }
+            /* On native Windows, PRIdMAX is defined as "I64d".
+               We cannot change it to "lld" because PRIdMAX must also
+               be understood by the system's printf routines.  */
+            else if (*cp == 'I' && cp[1] == '6' && cp[2] == '4')
+              {
+                if (64 / 8 > sizeof (long))
+                  {
+                    /* __int64_t = long long */
+                    signed_type = TYPE_LONGLONGINT;
+                    unsigned_type = TYPE_ULONGLONGINT;
+                    pointer_type = TYPE_COUNT_LONGLONGINT_POINTER;
+                    /* For backward compatibility only.  */
+                    floatingpoint_type = TYPE_LONGDOUBLE;
+                  }
+                else
+                  {
+                    /* __int64_t = long */
+                    signed_type = TYPE_LONGINT;
+                    unsigned_type = TYPE_ULONGINT;
+                    pointer_type = TYPE_COUNT_LONGINT_POINTER;
+                  }
+                cp++;
+              }
 #endif
-                  else
-                    break;
-                }
 
-              /* Read the conversion character.  */
-              c = *cp++;
-              switch (c)
-                {
-                case 'd': case 'i':
-                  /* If 'long long' is larger than 'long':  */
-                  if (flags >= 16 || (flags & 4))
-                    type = TYPE_LONGLONGINT;
-                  else
-                  /* If 'long long' is the same as 'long', we parse "lld" into
-                     TYPE_LONGINT.  */
-                  if (flags >= 8)
-                    type = TYPE_LONGINT;
-                  else if (flags & 2)
-                    type = TYPE_SCHAR;
-                  else if (flags & 1)
-                    type = TYPE_SHORT;
-                  else
-                    type = TYPE_INT;
-                  break;
-                case 'b': case 'o': case 'u': case 'x': case 'X':
-                #if SUPPORT_GNU_PRINTF_DIRECTIVES \
-                    || (__GLIBC__ + (__GLIBC_MINOR__ >= 35) > 2)
-                case 'B':
-                #endif
-                  /* If 'unsigned long long' is larger than 'unsigned long':  
*/
-                  if (flags >= 16 || (flags & 4))
-                    type = TYPE_ULONGLONGINT;
-                  else
-                  /* If 'unsigned long long' is the same as 'unsigned long', we
-                     parse "llu" into TYPE_ULONGINT.  */
-                  if (flags >= 8)
-                    type = TYPE_ULONGINT;
-                  else if (flags & 2)
-                    type = TYPE_UCHAR;
-                  else if (flags & 1)
-                    type = TYPE_USHORT;
-                  else
-                    type = TYPE_UINT;
-                  break;
-                case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
-                case 'a': case 'A':
-                  if (flags >= 16 || (flags & 4))
-                    type = TYPE_LONGDOUBLE;
-                  else
-                    type = TYPE_DOUBLE;
-                  break;
-                case 'c':
-                  if (flags >= 8)
+            /* Read the conversion character.  */
+            c = *cp++;
+            switch (c)
+              {
+              case 'd': case 'i':
+                type = signed_type;
+                break;
+              case 'b': case 'o': case 'u': case 'x': case 'X':
+              #if SUPPORT_GNU_PRINTF_DIRECTIVES \
+                  || (__GLIBC__ + (__GLIBC_MINOR__ >= 35) > 2)
+              case 'B':
+              #endif
+                type = unsigned_type;
+                break;
+              case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
+              case 'a': case 'A':
+                type = floatingpoint_type;
+                break;
+              case 'c':
+                if (signed_type == TYPE_LONGINT
+                    /* For backward compatibility only.  */
+                    || signed_type == TYPE_LONGLONGINT)
 #if HAVE_WINT_T
-                    type = TYPE_WIDE_CHAR;
+                  type = TYPE_WIDE_CHAR;
 #else
-                    goto error;
+                  goto error;
 #endif
-                  else
-                    type = TYPE_CHAR;
-                  break;
+                else
+                  type = TYPE_CHAR;
+                break;
 #if HAVE_WINT_T
-                case 'C':
-                  type = TYPE_WIDE_CHAR;
-                  c = 'c';
-                  break;
+              case 'C':
+                type = TYPE_WIDE_CHAR;
+                c = 'c';
+                break;
 #endif
-                case 's':
-                  if (flags >= 8)
+              case 's':
+                if (signed_type == TYPE_LONGINT
+                    /* For backward compatibility only.  */
+                    || signed_type == TYPE_LONGLONGINT)
 #if HAVE_WCHAR_T
-                    type = TYPE_WIDE_STRING;
+                  type = TYPE_WIDE_STRING;
 #else
-                    goto error;
+                  goto error;
 #endif
-                  else
-                    type = TYPE_STRING;
-                  break;
+                else
+                  type = TYPE_STRING;
+                break;
 #if HAVE_WCHAR_T
-                case 'S':
-                  type = TYPE_WIDE_STRING;
-                  c = 's';
-                  break;
+              case 'S':
+                type = TYPE_WIDE_STRING;
+                c = 's';
+                break;
 #endif
-                case 'p':
-                  type = TYPE_POINTER;
-                  break;
-                case 'n':
-                  /* If 'long long' is larger than 'long':  */
-                  if (flags >= 16 || (flags & 4))
-                    type = TYPE_COUNT_LONGLONGINT_POINTER;
-                  else
-                  /* If 'long long' is the same as 'long', we parse "lln" into
-                     TYPE_COUNT_LONGINT_POINTER.  */
-                  if (flags >= 8)
-                    type = TYPE_COUNT_LONGINT_POINTER;
-                  else if (flags & 2)
-                    type = TYPE_COUNT_SCHAR_POINTER;
-                  else if (flags & 1)
-                    type = TYPE_COUNT_SHORT_POINTER;
-                  else
-                    type = TYPE_COUNT_INT_POINTER;
-                  break;
+              case 'p':
+                type = TYPE_POINTER;
+                break;
+              case 'n':
+                type = pointer_type;
+                break;
 #if ENABLE_UNISTDIO
-                /* The unistdio extensions.  */
-                case 'U':
-                  if (flags >= 16)
-                    type = TYPE_U32_STRING;
-                  else if (flags >= 8)
-                    type = TYPE_U16_STRING;
-                  else
-                    type = TYPE_U8_STRING;
-                  break;
+              /* The unistdio extensions.  */
+              case 'U':
+                if (signed_type == TYPE_LONGLONGINT)
+                  type = TYPE_U32_STRING;
+                else if (signed_type == TYPE_LONGINT)
+                  type = TYPE_U16_STRING;
+                else
+                  type = TYPE_U8_STRING;
+                break;
 #endif
-                case '%':
-                  type = TYPE_NONE;
-                  break;
-                default:
-                  /* Unknown conversion character.  */
-                  goto error;
-                }
-            }
+              case '%':
+                type = TYPE_NONE;
+                break;
+              default:
+                /* Unknown conversion character.  */
+                goto error;
+              }
 
             if (type != TYPE_NONE)
               {
diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c
index bb7d0aec25..83128fd1ea 100644
--- a/lib/vasnprintf.c
+++ b/lib/vasnprintf.c
@@ -85,7 +85,7 @@
 #include <string.h>     /* memcpy(), strlen() */
 #include <wchar.h>      /* mbstate_t, mbrtowc(), mbrlen(), wcrtomb() */
 #include <errno.h>      /* errno */
-#include <limits.h>     /* CHAR_BIT */
+#include <limits.h>     /* CHAR_BIT, INT_WIDTH, LONG_WIDTH */
 #include <float.h>      /* DBL_MAX_EXP, LDBL_MAX_EXP */
 #if HAVE_NL_LANGINFO
 # include <langinfo.h>
@@ -1633,24 +1633,155 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t 
arg_index, FCHAR_T conversion,
   switch (conversion)
     {
     case 'd': case 'i': case 'u':
-      if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
-        tmp_length =
-          (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
-                          * 0.30103 /* binary -> decimal */
-                         )
-          + 1; /* turn floor into ceil */
-      else if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
-        tmp_length =
-          (unsigned int) (sizeof (unsigned long) * CHAR_BIT
-                          * 0.30103 /* binary -> decimal */
-                         )
-          + 1; /* turn floor into ceil */
-      else
-        tmp_length =
-          (unsigned int) (sizeof (unsigned int) * CHAR_BIT
-                          * 0.30103 /* binary -> decimal */
-                         )
-          + 1; /* turn floor into ceil */
+      switch (type)
+        {
+        default:
+          tmp_length =
+            (unsigned int) (sizeof (unsigned int) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+        case TYPE_LONGINT:
+          tmp_length =
+            (unsigned int) (sizeof (long int) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_ULONGINT:
+          tmp_length =
+            (unsigned int) (sizeof (unsigned long int) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_LONGLONGINT:
+          tmp_length =
+            (unsigned int) (sizeof (long long int) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_ULONGLONGINT:
+          tmp_length =
+            (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_INT8_T:
+          tmp_length =
+            (unsigned int) (sizeof (int8_t) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT8_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint8_t) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_INT16_T:
+          tmp_length =
+            (unsigned int) (sizeof (int16_t) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT16_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint16_t) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_INT32_T:
+          tmp_length =
+            (unsigned int) (sizeof (int32_t) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT32_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint32_t) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_INT64_T:
+          tmp_length =
+            (unsigned int) (sizeof (int64_t) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT64_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint64_t) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_INT_FAST8_T:
+          tmp_length =
+            (unsigned int) (sizeof (int_fast8_t) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT_FAST8_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_INT_FAST16_T:
+          tmp_length =
+            (unsigned int) (sizeof (int_fast16_t) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT_FAST16_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_INT_FAST32_T:
+          tmp_length =
+            (unsigned int) (sizeof (int_fast32_t) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT_FAST32_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_INT_FAST64_T:
+          tmp_length =
+            (unsigned int) (sizeof (int_fast64_t) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT_FAST64_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT
+                            * 0.30103 /* binary -> decimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        }
       if (tmp_length < precision)
         tmp_length = precision;
       /* Multiply by 2, as an estimate for FLAG_GROUP.  */
@@ -1664,18 +1795,64 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, 
FCHAR_T conversion,
         || (__GLIBC__ + (__GLIBC_MINOR__ >= 35) > 2)
     case 'B':
     #endif
-      if (type == TYPE_ULONGLONGINT)
-        tmp_length =
-          (unsigned int) (sizeof (unsigned long long) * CHAR_BIT)
-          + 1; /* turn floor into ceil */
-      else if (type == TYPE_ULONGINT)
-        tmp_length =
-          (unsigned int) (sizeof (unsigned long) * CHAR_BIT)
-          + 1; /* turn floor into ceil */
-      else
-        tmp_length =
-          (unsigned int) (sizeof (unsigned int) * CHAR_BIT)
-          + 1; /* turn floor into ceil */
+      switch (type)
+        {
+        default:
+          tmp_length =
+            (unsigned int) (sizeof (unsigned int) * CHAR_BIT)
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_ULONGINT:
+          tmp_length =
+            (unsigned int) (sizeof (unsigned long int) * CHAR_BIT)
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_ULONGLONGINT:
+          tmp_length =
+            (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT)
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT8_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint8_t) * CHAR_BIT)
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT16_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint16_t) * CHAR_BIT)
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT32_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint32_t) * CHAR_BIT)
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT64_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint64_t) * CHAR_BIT)
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT_FAST8_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT)
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT_FAST16_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT)
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT_FAST32_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT)
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT_FAST64_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT)
+            + 1; /* turn floor into ceil */
+          break;
+        }
       if (tmp_length < precision)
         tmp_length = precision;
       /* Add 2, to account for a prefix from the alternate form.  */
@@ -1683,24 +1860,86 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, 
FCHAR_T conversion,
       break;
 
     case 'o':
-      if (type == TYPE_ULONGLONGINT)
-        tmp_length =
-          (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
-                          * 0.333334 /* binary -> octal */
-                         )
-          + 1; /* turn floor into ceil */
-      else if (type == TYPE_ULONGINT)
-        tmp_length =
-          (unsigned int) (sizeof (unsigned long) * CHAR_BIT
-                          * 0.333334 /* binary -> octal */
-                         )
-          + 1; /* turn floor into ceil */
-      else
-        tmp_length =
-          (unsigned int) (sizeof (unsigned int) * CHAR_BIT
-                          * 0.333334 /* binary -> octal */
-                         )
-          + 1; /* turn floor into ceil */
+      switch (type)
+        {
+        default:
+          tmp_length =
+            (unsigned int) (sizeof (unsigned int) * CHAR_BIT
+                            * 0.333334 /* binary -> octal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_ULONGINT:
+          tmp_length =
+            (unsigned int) (sizeof (unsigned long int) * CHAR_BIT
+                            * 0.333334 /* binary -> octal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_ULONGLONGINT:
+          tmp_length =
+            (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT
+                            * 0.333334 /* binary -> octal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT8_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint8_t) * CHAR_BIT
+                            * 0.333334 /* binary -> octal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT16_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint16_t) * CHAR_BIT
+                            * 0.333334 /* binary -> octal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT32_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint32_t) * CHAR_BIT
+                            * 0.333334 /* binary -> octal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT64_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint64_t) * CHAR_BIT
+                            * 0.333334 /* binary -> octal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT_FAST8_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT
+                            * 0.333334 /* binary -> octal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT_FAST16_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT
+                            * 0.333334 /* binary -> octal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT_FAST32_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT
+                            * 0.333334 /* binary -> octal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT_FAST64_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT
+                            * 0.333334 /* binary -> octal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        }
       if (tmp_length < precision)
         tmp_length = precision;
       /* Add 1, to account for a leading sign.  */
@@ -1708,24 +1947,86 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, 
FCHAR_T conversion,
       break;
 
     case 'x': case 'X':
-      if (type == TYPE_ULONGLONGINT)
-        tmp_length =
-          (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
-                          * 0.25 /* binary -> hexadecimal */
-                         )
-          + 1; /* turn floor into ceil */
-      else if (type == TYPE_ULONGINT)
-        tmp_length =
-          (unsigned int) (sizeof (unsigned long) * CHAR_BIT
-                          * 0.25 /* binary -> hexadecimal */
-                         )
-          + 1; /* turn floor into ceil */
-      else
-        tmp_length =
-          (unsigned int) (sizeof (unsigned int) * CHAR_BIT
-                          * 0.25 /* binary -> hexadecimal */
-                         )
-          + 1; /* turn floor into ceil */
+      switch (type)
+        {
+        default:
+          tmp_length =
+            (unsigned int) (sizeof (unsigned int) * CHAR_BIT
+                            * 0.25 /* binary -> hexadecimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_ULONGINT:
+          tmp_length =
+            (unsigned int) (sizeof (unsigned long int) * CHAR_BIT
+                            * 0.25 /* binary -> hexadecimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_ULONGLONGINT:
+          tmp_length =
+            (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT
+                            * 0.25 /* binary -> hexadecimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT8_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint8_t) * CHAR_BIT
+                            * 0.25 /* binary -> hexadecimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT16_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint16_t) * CHAR_BIT
+                            * 0.25 /* binary -> hexadecimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT32_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint32_t) * CHAR_BIT
+                            * 0.25 /* binary -> hexadecimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT64_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint64_t) * CHAR_BIT
+                            * 0.25 /* binary -> hexadecimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT_FAST8_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT
+                            * 0.25 /* binary -> hexadecimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT_FAST16_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT
+                            * 0.25 /* binary -> hexadecimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT_FAST32_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT
+                            * 0.25 /* binary -> hexadecimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        case TYPE_UINT_FAST64_T:
+          tmp_length =
+            (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT
+                            * 0.25 /* binary -> hexadecimal */
+                           )
+            + 1; /* turn floor into ceil */
+          break;
+        }
       if (tmp_length < precision)
         tmp_length = precision;
       /* Add 2, to account for a prefix from the alternate form.  */
@@ -2034,6 +2335,30 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                   case TYPE_COUNT_LONGLONGINT_POINTER:
                     *a.arg[dp->arg_index].a.a_count_longlongint_pointer = 
length;
                     break;
+                  case TYPE_COUNT_INT8_T_POINTER:
+                    *a.arg[dp->arg_index].a.a_count_int8_t_pointer = length;
+                    break;
+                  case TYPE_COUNT_INT16_T_POINTER:
+                    *a.arg[dp->arg_index].a.a_count_int16_t_pointer = length;
+                    break;
+                  case TYPE_COUNT_INT32_T_POINTER:
+                    *a.arg[dp->arg_index].a.a_count_int32_t_pointer = length;
+                    break;
+                  case TYPE_COUNT_INT64_T_POINTER:
+                    *a.arg[dp->arg_index].a.a_count_int64_t_pointer = length;
+                    break;
+                  case TYPE_COUNT_INT_FAST8_T_POINTER:
+                    *a.arg[dp->arg_index].a.a_count_int_fast8_t_pointer = 
length;
+                    break;
+                  case TYPE_COUNT_INT_FAST16_T_POINTER:
+                    *a.arg[dp->arg_index].a.a_count_int_fast16_t_pointer = 
length;
+                    break;
+                  case TYPE_COUNT_INT_FAST32_T_POINTER:
+                    *a.arg[dp->arg_index].a.a_count_int_fast32_t_pointer = 
length;
+                    break;
+                  case TYPE_COUNT_INT_FAST64_T_POINTER:
+                    *a.arg[dp->arg_index].a.a_count_int_fast64_t_pointer = 
length;
+                    break;
                   default:
                     abort ();
                   }
@@ -3303,18 +3628,64 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                   }
 
                 /* Allocate a temporary buffer of sufficient size.  */
-                if (type == TYPE_ULONGLONGINT)
-                  tmp_length =
-                    (unsigned int) (sizeof (unsigned long long) * CHAR_BIT)
-                    + 1; /* turn floor into ceil */
-                else if (type == TYPE_ULONGINT)
-                  tmp_length =
-                    (unsigned int) (sizeof (unsigned long) * CHAR_BIT)
-                    + 1; /* turn floor into ceil */
-                else
-                  tmp_length =
-                    (unsigned int) (sizeof (unsigned int) * CHAR_BIT)
-                    + 1; /* turn floor into ceil */
+                switch (type)
+                  {
+                  default:
+                    tmp_length =
+                      (unsigned int) (sizeof (unsigned int) * CHAR_BIT)
+                      + 1; /* turn floor into ceil */
+                    break;
+                  case TYPE_ULONGINT:
+                    tmp_length =
+                      (unsigned int) (sizeof (unsigned long int) * CHAR_BIT)
+                      + 1; /* turn floor into ceil */
+                    break;
+                  case TYPE_ULONGLONGINT:
+                    tmp_length =
+                      (unsigned int) (sizeof (unsigned long long int) * 
CHAR_BIT)
+                      + 1; /* turn floor into ceil */
+                    break;
+                  case TYPE_UINT8_T:
+                    tmp_length =
+                      (unsigned int) (sizeof (uint8_t) * CHAR_BIT)
+                      + 1; /* turn floor into ceil */
+                    break;
+                  case TYPE_UINT16_T:
+                    tmp_length =
+                      (unsigned int) (sizeof (uint16_t) * CHAR_BIT)
+                      + 1; /* turn floor into ceil */
+                    break;
+                  case TYPE_UINT32_T:
+                    tmp_length =
+                      (unsigned int) (sizeof (uint32_t) * CHAR_BIT)
+                      + 1; /* turn floor into ceil */
+                    break;
+                  case TYPE_UINT64_T:
+                    tmp_length =
+                      (unsigned int) (sizeof (uint64_t) * CHAR_BIT)
+                      + 1; /* turn floor into ceil */
+                    break;
+                  case TYPE_UINT_FAST8_T:
+                    tmp_length =
+                      (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT)
+                      + 1; /* turn floor into ceil */
+                    break;
+                  case TYPE_UINT_FAST16_T:
+                    tmp_length =
+                      (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT)
+                      + 1; /* turn floor into ceil */
+                    break;
+                  case TYPE_UINT_FAST32_T:
+                    tmp_length =
+                      (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT)
+                      + 1; /* turn floor into ceil */
+                    break;
+                  case TYPE_UINT_FAST64_T:
+                    tmp_length =
+                      (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT)
+                      + 1; /* turn floor into ceil */
+                    break;
+                  }
                 if (tmp_length < precision)
                   tmp_length = precision;
                 /* Add 2, to account for a prefix from the alternate form.  */
@@ -3340,10 +3711,51 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 
                 tmp_end = tmp + tmp_length;
 
-                unsigned long long arg =
-                  (type == TYPE_ULONGLONGINT ? 
a.arg[dp->arg_index].a.a_ulonglongint :
-                   type == TYPE_ULONGINT ? a.arg[dp->arg_index].a.a_ulongint :
-                   a.arg[dp->arg_index].a.a_uint);
+                unsigned long long arg;
+                switch (type)
+                  {
+                  case TYPE_UCHAR:
+                    arg = a.arg[dp->arg_index].a.a_uchar;
+                    break;
+                  case TYPE_USHORT:
+                    arg = a.arg[dp->arg_index].a.a_ushort;
+                    break;
+                  case TYPE_UINT:
+                    arg = a.arg[dp->arg_index].a.a_uint;
+                    break;
+                  case TYPE_ULONGINT:
+                    arg = a.arg[dp->arg_index].a.a_ulongint;
+                    break;
+                  case TYPE_ULONGLONGINT:
+                    arg = a.arg[dp->arg_index].a.a_ulonglongint;
+                    break;
+                  case TYPE_UINT8_T:
+                    arg = a.arg[dp->arg_index].a.a_uint8_t;
+                    break;
+                  case TYPE_UINT16_T:
+                    arg = a.arg[dp->arg_index].a.a_uint16_t;
+                    break;
+                  case TYPE_UINT32_T:
+                    arg = a.arg[dp->arg_index].a.a_uint32_t;
+                    break;
+                  case TYPE_UINT64_T:
+                    arg = a.arg[dp->arg_index].a.a_uint64_t;
+                    break;
+                  case TYPE_UINT_FAST8_T:
+                    arg = a.arg[dp->arg_index].a.a_uint_fast8_t;
+                    break;
+                  case TYPE_UINT_FAST16_T:
+                    arg = a.arg[dp->arg_index].a.a_uint_fast16_t;
+                    break;
+                  case TYPE_UINT_FAST32_T:
+                    arg = a.arg[dp->arg_index].a.a_uint_fast32_t;
+                    break;
+                  case TYPE_UINT_FAST64_T:
+                    arg = a.arg[dp->arg_index].a.a_uint_fast64_t;
+                    break;
+                  default:
+                    abort ();
+                  }
                 int need_prefix = ((flags & FLAG_ALT) && arg != 0);
 
                 p = tmp_end;
@@ -5361,6 +5773,54 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                   {
                   case TYPE_LONGLONGINT:
                   case TYPE_ULONGLONGINT:
+                  #if INT8_WIDTH > LONG_WIDTH
+                  case TYPE_INT8_T:
+                  #endif
+                  #if UINT8_WIDTH > LONG_WIDTH
+                  case TYPE_UINT8_T:
+                  #endif
+                  #if INT16_WIDTH > LONG_WIDTH
+                  case TYPE_INT16_T:
+                  #endif
+                  #if UINT16_WIDTH > LONG_WIDTH
+                  case TYPE_UINT16_T:
+                  #endif
+                  #if INT32_WIDTH > LONG_WIDTH
+                  case TYPE_INT32_T:
+                  #endif
+                  #if UINT32_WIDTH > LONG_WIDTH
+                  case TYPE_UINT32_T:
+                  #endif
+                  #if INT64_WIDTH > LONG_WIDTH
+                  case TYPE_INT64_T:
+                  #endif
+                  #if UINT64_WIDTH > LONG_WIDTH
+                  case TYPE_UINT64_T:
+                  #endif
+                  #if INT_FAST8_WIDTH > LONG_WIDTH
+                  case TYPE_INT_FAST8_T:
+                  #endif
+                  #if UINT_FAST8_WIDTH > LONG_WIDTH
+                  case TYPE_UINT_FAST8_T:
+                  #endif
+                  #if INT_FAST16_WIDTH > LONG_WIDTH
+                  case TYPE_INT_FAST16_T:
+                  #endif
+                  #if UINT_FAST16_WIDTH > LONG_WIDTH
+                  case TYPE_UINT_FAST16_T:
+                  #endif
+                  #if INT_FAST32_WIDTH > LONG_WIDTH
+                  case TYPE_INT3_FAST2_T:
+                  #endif
+                  #if UINT_FAST32_WIDTH > LONG_WIDTH
+                  case TYPE_UINT_FAST32_T:
+                  #endif
+                  #if INT_FAST64_WIDTH > LONG_WIDTH
+                  case TYPE_INT_FAST64_T:
+                  #endif
+                  #if UINT_FAST64_WIDTH > LONG_WIDTH
+                  case TYPE_UINT_FAST64_T:
+                  #endif
 #if defined _WIN32 && ! defined __CYGWIN__
                     *fbp++ = 'I';
                     *fbp++ = '6';
@@ -5372,12 +5832,60 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                     FALLTHROUGH;
                   case TYPE_LONGINT:
                   case TYPE_ULONGINT:
-#if HAVE_WINT_T
+                  #if INT8_WIDTH > INT_WIDTH && INT8_WIDTH <= LONG_WIDTH
+                  case TYPE_INT8_T:
+                  #endif
+                  #if UINT8_WIDTH > INT_WIDTH && UINT8_WIDTH <= LONG_WIDTH
+                  case TYPE_UINT8_T:
+                  #endif
+                  #if INT16_WIDTH > INT_WIDTH && INT16_WIDTH <= LONG_WIDTH
+                  case TYPE_INT16_T:
+                  #endif
+                  #if UINT16_WIDTH > INT_WIDTH && UINT16_WIDTH <= LONG_WIDTH
+                  case TYPE_UINT16_T:
+                  #endif
+                  #if INT32_WIDTH > INT_WIDTH && INT32_WIDTH <= LONG_WIDTH
+                  case TYPE_INT32_T:
+                  #endif
+                  #if UINT32_WIDTH > INT_WIDTH && UINT32_WIDTH <= LONG_WIDTH
+                  case TYPE_UINT32_T:
+                  #endif
+                  #if INT64_WIDTH > INT_WIDTH && INT64_WIDTH <= LONG_WIDTH
+                  case TYPE_INT64_T:
+                  #endif
+                  #if UINT64_WIDTH > INT_WIDTH && UINT64_WIDTH <= LONG_WIDTH
+                  case TYPE_UINT64_T:
+                  #endif
+                  #if INT_FAST8_WIDTH > INT_WIDTH && INT_FAST8_WIDTH <= 
LONG_WIDTH
+                  case TYPE_INT_FAST8_T:
+                  #endif
+                  #if UINT_FAST8_WIDTH > INT_WIDTH && UINT_FAST8_WIDTH <= 
LONG_WIDTH
+                  case TYPE_UINT_FAST8_T:
+                  #endif
+                  #if INT_FAST16_WIDTH > INT_WIDTH && INT_FAST16_WIDTH <= 
LONG_WIDTH
+                  case TYPE_INT_FAST16_T:
+                  #endif
+                  #if UINT_FAST16_WIDTH > INT_WIDTH && UINT_FAST16_WIDTH <= 
LONG_WIDTH
+                  case TYPE_UINT_FAST16_T:
+                  #endif
+                  #if INT_FAST32_WIDTH > INT_WIDTH && INT_FAST32_WIDTH <= 
LONG_WIDTH
+                  case TYPE_INT_FAST32_T:
+                  #endif
+                  #if UINT_FAST32_WIDTH > INT_WIDTH && UINT_FAST32_WIDTH <= 
LONG_WIDTH
+                  case TYPE_UINT_FAST32_T:
+                  #endif
+                  #if INT_FAST64_WIDTH > INT_WIDTH && INT_FAST64_WIDTH <= 
LONG_WIDTH
+                  case TYPE_INT_FAST64_T:
+                  #endif
+                  #if UINT_FAST64_WIDTH > INT_WIDTH && UINT_FAST64_WIDTH <= 
LONG_WIDTH
+                  case TYPE_UINT_FAST64_T:
+                  #endif
+                  #if HAVE_WINT_T
                   case TYPE_WIDE_CHAR:
-#endif
-#if HAVE_WCHAR_T
+                  #endif
+                  #if HAVE_WCHAR_T
                   case TYPE_WIDE_STRING:
-#endif
+                  #endif
                     *fbp++ = 'l';
                     break;
                   case TYPE_LONGDOUBLE:
@@ -5621,6 +6129,102 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                           SNPRINTF_BUF (arg);
                         }
                         break;
+                      case TYPE_INT8_T:
+                        {
+                          int8_t arg = a.arg[dp->arg_index].a.a_int8_t;
+                          SNPRINTF_BUF (arg);
+                        }
+                        break;
+                      case TYPE_UINT8_T:
+                        {
+                          uint8_t arg = a.arg[dp->arg_index].a.a_uint8_t;
+                          SNPRINTF_BUF (arg);
+                        }
+                        break;
+                      case TYPE_INT16_T:
+                        {
+                          int16_t arg = a.arg[dp->arg_index].a.a_int16_t;
+                          SNPRINTF_BUF (arg);
+                        }
+                        break;
+                      case TYPE_UINT16_T:
+                        {
+                          uint16_t arg = a.arg[dp->arg_index].a.a_uint16_t;
+                          SNPRINTF_BUF (arg);
+                        }
+                        break;
+                      case TYPE_INT32_T:
+                        {
+                          int32_t arg = a.arg[dp->arg_index].a.a_int32_t;
+                          SNPRINTF_BUF (arg);
+                        }
+                        break;
+                      case TYPE_UINT32_T:
+                        {
+                          uint32_t arg = a.arg[dp->arg_index].a.a_uint32_t;
+                          SNPRINTF_BUF (arg);
+                        }
+                        break;
+                      case TYPE_INT64_T:
+                        {
+                          int64_t arg = a.arg[dp->arg_index].a.a_int64_t;
+                          SNPRINTF_BUF (arg);
+                        }
+                        break;
+                      case TYPE_UINT64_T:
+                        {
+                          uint64_t arg = a.arg[dp->arg_index].a.a_uint64_t;
+                          SNPRINTF_BUF (arg);
+                        }
+                        break;
+                      case TYPE_INT_FAST8_T:
+                        {
+                          int_fast8_t arg = 
a.arg[dp->arg_index].a.a_int_fast8_t;
+                          SNPRINTF_BUF (arg);
+                        }
+                        break;
+                      case TYPE_UINT_FAST8_T:
+                        {
+                          uint_fast8_t arg = 
a.arg[dp->arg_index].a.a_uint_fast8_t;
+                          SNPRINTF_BUF (arg);
+                        }
+                        break;
+                      case TYPE_INT_FAST16_T:
+                        {
+                          int_fast16_t arg = 
a.arg[dp->arg_index].a.a_int_fast16_t;
+                          SNPRINTF_BUF (arg);
+                        }
+                        break;
+                      case TYPE_UINT_FAST16_T:
+                        {
+                          uint_fast16_t arg = 
a.arg[dp->arg_index].a.a_uint_fast16_t;
+                          SNPRINTF_BUF (arg);
+                        }
+                        break;
+                      case TYPE_INT_FAST32_T:
+                        {
+                          int_fast32_t arg = 
a.arg[dp->arg_index].a.a_int_fast32_t;
+                          SNPRINTF_BUF (arg);
+                        }
+                        break;
+                      case TYPE_UINT_FAST32_T:
+                        {
+                          uint_fast32_t arg = 
a.arg[dp->arg_index].a.a_uint_fast32_t;
+                          SNPRINTF_BUF (arg);
+                        }
+                        break;
+                      case TYPE_INT_FAST64_T:
+                        {
+                          int_fast64_t arg = 
a.arg[dp->arg_index].a.a_int_fast64_t;
+                          SNPRINTF_BUF (arg);
+                        }
+                        break;
+                      case TYPE_UINT_FAST64_T:
+                        {
+                          uint_fast64_t arg = 
a.arg[dp->arg_index].a.a_uint_fast64_t;
+                          SNPRINTF_BUF (arg);
+                        }
+                        break;
                       case TYPE_DOUBLE:
                         {
                           double arg = a.arg[dp->arg_index].a.a_double;
diff --git a/m4/dprintf-posix.m4 b/m4/dprintf-posix.m4
index 8759beaa22..3d964a6dce 100644
--- a/m4/dprintf-posix.m4
+++ b/m4/dprintf-posix.m4
@@ -1,4 +1,4 @@
-# dprintf-posix.m4 serial 6
+# dprintf-posix.m4 serial 7
 dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -19,6 +19,7 @@ AC_DEFUN([gl_FUNC_DPRINTF_POSIX]
 AC_DEFUN([gl_FUNC_DPRINTF_IS_POSIX],
 [
   AC_REQUIRE([gl_PRINTF_SIZES_C99])
+  AC_REQUIRE([gl_PRINTF_SIZES_C23])
   AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
   AC_REQUIRE([gl_PRINTF_INFINITE])
   AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
@@ -39,39 +40,43 @@ AC_DEFUN([gl_FUNC_DPRINTF_IS_POSIX]
   if test $ac_cv_func_dprintf = yes; then
     case "$gl_cv_func_printf_sizes_c99" in
       *yes)
-        case "$gl_cv_func_printf_long_double" in
+        case "$gl_cv_func_printf_sizes_c23" in
           *yes)
-            case "$gl_cv_func_printf_infinite" in
+            case "$gl_cv_func_printf_long_double" in
               *yes)
-                case "$gl_cv_func_printf_infinite_long_double" in
+                case "$gl_cv_func_printf_infinite" in
                   *yes)
-                    case "$gl_cv_func_printf_directive_a" in
+                    case "$gl_cv_func_printf_infinite_long_double" in
                       *yes)
-                        case "$gl_cv_func_printf_directive_b" in
+                        case "$gl_cv_func_printf_directive_a" in
                           *yes)
-                            case "$gl_cv_func_printf_directive_f" in
+                            case "$gl_cv_func_printf_directive_b" in
                               *yes)
-                                case "$gl_cv_func_printf_directive_n" in
+                                case "$gl_cv_func_printf_directive_f" in
                                   *yes)
-                                    case "$gl_cv_func_printf_directive_ls" in
+                                    case "$gl_cv_func_printf_directive_n" in
                                       *yes)
-                                        case "$gl_cv_func_printf_directive_lc" 
in
+                                        case "$gl_cv_func_printf_directive_ls" 
in
                                           *yes)
-                                            case 
"$gl_cv_func_printf_positions" in
+                                            case 
"$gl_cv_func_printf_directive_lc" in
                                               *yes)
-                                                case 
"$gl_cv_func_printf_flag_grouping" in
+                                                case 
"$gl_cv_func_printf_positions" in
                                                   *yes)
-                                                    case 
"$gl_cv_func_printf_flag_leftadjust" in
+                                                    case 
"$gl_cv_func_printf_flag_grouping" in
                                                       *yes)
-                                                        case 
"$gl_cv_func_printf_flag_zero" in
+                                                        case 
"$gl_cv_func_printf_flag_leftadjust" in
                                                           *yes)
-                                                            case 
"$gl_cv_func_printf_precision" in
+                                                            case 
"$gl_cv_func_printf_flag_zero" in
                                                               *yes)
-                                                                case 
"$gl_cv_func_printf_enomem" in
+                                                                case 
"$gl_cv_func_printf_precision" in
                                                                   *yes)
-                                                                    # dprintf 
exists and is
-                                                                    # already 
POSIX compliant.
-                                                                    
gl_cv_func_dprintf_posix=yes
+                                                                    case 
"$gl_cv_func_printf_enomem" in
+                                                                      *yes)
+                                                                        # 
dprintf exists and is
+                                                                        # 
already POSIX compliant.
+                                                                        
gl_cv_func_dprintf_posix=yes
+                                                                        ;;
+                                                                    esac
                                                                     ;;
                                                                 esac
                                                                 ;;
diff --git a/m4/fprintf-posix.m4 b/m4/fprintf-posix.m4
index 4d016c4fc5..67ecbf353b 100644
--- a/m4/fprintf-posix.m4
+++ b/m4/fprintf-posix.m4
@@ -1,4 +1,4 @@
-# fprintf-posix.m4 serial 17
+# fprintf-posix.m4 serial 18
 dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -19,6 +19,7 @@ AC_DEFUN([gl_FUNC_FPRINTF_POSIX]
 AC_DEFUN([gl_FUNC_FPRINTF_IS_POSIX],
 [
   AC_REQUIRE([gl_PRINTF_SIZES_C99])
+  AC_REQUIRE([gl_PRINTF_SIZES_C23])
   AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
   AC_REQUIRE([gl_PRINTF_INFINITE])
   AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
@@ -37,39 +38,43 @@ AC_DEFUN([gl_FUNC_FPRINTF_IS_POSIX]
   gl_cv_func_fprintf_posix=no
   case "$gl_cv_func_printf_sizes_c99" in
     *yes)
-      case "$gl_cv_func_printf_long_double" in
+      case "$gl_cv_func_printf_sizes_c23" in
         *yes)
-          case "$gl_cv_func_printf_infinite" in
+          case "$gl_cv_func_printf_long_double" in
             *yes)
-              case "$gl_cv_func_printf_infinite_long_double" in
+              case "$gl_cv_func_printf_infinite" in
                 *yes)
-                  case "$gl_cv_func_printf_directive_a" in
+                  case "$gl_cv_func_printf_infinite_long_double" in
                     *yes)
-                      case "$gl_cv_func_printf_directive_b" in
+                      case "$gl_cv_func_printf_directive_a" in
                         *yes)
-                          case "$gl_cv_func_printf_directive_f" in
+                          case "$gl_cv_func_printf_directive_b" in
                             *yes)
-                              case "$gl_cv_func_printf_directive_n" in
+                              case "$gl_cv_func_printf_directive_f" in
                                 *yes)
-                                  case "$gl_cv_func_printf_directive_ls" in
+                                  case "$gl_cv_func_printf_directive_n" in
                                     *yes)
-                                      case "$gl_cv_func_printf_directive_lc" in
+                                      case "$gl_cv_func_printf_directive_ls" in
                                         *yes)
-                                          case "$gl_cv_func_printf_positions" 
in
+                                          case 
"$gl_cv_func_printf_directive_lc" in
                                             *yes)
-                                              case 
"$gl_cv_func_printf_flag_grouping" in
+                                              case 
"$gl_cv_func_printf_positions" in
                                                 *yes)
-                                                  case 
"$gl_cv_func_printf_flag_leftadjust" in
+                                                  case 
"$gl_cv_func_printf_flag_grouping" in
                                                     *yes)
-                                                      case 
"$gl_cv_func_printf_flag_zero" in
+                                                      case 
"$gl_cv_func_printf_flag_leftadjust" in
                                                         *yes)
-                                                          case 
"$gl_cv_func_printf_precision" in
+                                                          case 
"$gl_cv_func_printf_flag_zero" in
                                                             *yes)
-                                                              case 
"$gl_cv_func_printf_enomem" in
+                                                              case 
"$gl_cv_func_printf_precision" in
                                                                 *yes)
-                                                                  # fprintf 
exists and is
-                                                                  # already 
POSIX compliant.
-                                                                  
gl_cv_func_fprintf_posix=yes
+                                                                  case 
"$gl_cv_func_printf_enomem" in
+                                                                    *yes)
+                                                                      # 
fprintf exists and is
+                                                                      # 
already POSIX compliant.
+                                                                      
gl_cv_func_fprintf_posix=yes
+                                                                      ;;
+                                                                  esac
                                                                   ;;
                                                               esac
                                                               ;;
diff --git a/m4/obstack-printf-posix.m4 b/m4/obstack-printf-posix.m4
index 751d6759cf..d306b8426d 100644
--- a/m4/obstack-printf-posix.m4
+++ b/m4/obstack-printf-posix.m4
@@ -1,4 +1,4 @@
-# obstack-printf-posix.m4 serial 7
+# obstack-printf-posix.m4 serial 8
 dnl Copyright (C) 2008-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -23,6 +23,7 @@ AC_DEFUN([gl_FUNC_OBSTACK_PRINTF_IS_POSIX]
   AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
 
   AC_REQUIRE([gl_PRINTF_SIZES_C99])
+  AC_REQUIRE([gl_PRINTF_SIZES_C23])
   AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
   AC_REQUIRE([gl_PRINTF_INFINITE])
   AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
@@ -43,39 +44,43 @@ AC_DEFUN([gl_FUNC_OBSTACK_PRINTF_IS_POSIX]
   if test $ac_cv_func_obstack_printf = yes ; then
     case "$gl_cv_func_printf_sizes_c99" in
       *yes)
-        case "$gl_cv_func_printf_long_double" in
+        case "$gl_cv_func_printf_sizes_c23" in
           *yes)
-            case "$gl_cv_func_printf_infinite" in
+            case "$gl_cv_func_printf_long_double" in
               *yes)
-                case "$gl_cv_func_printf_infinite_long_double" in
+                case "$gl_cv_func_printf_infinite" in
                   *yes)
-                    case "$gl_cv_func_printf_directive_a" in
+                    case "$gl_cv_func_printf_infinite_long_double" in
                       *yes)
-                        case "$gl_cv_func_printf_directive_b" in
+                        case "$gl_cv_func_printf_directive_a" in
                           *yes)
-                            case "$gl_cv_func_printf_directive_f" in
+                            case "$gl_cv_func_printf_directive_b" in
                               *yes)
-                                case "$gl_cv_func_printf_directive_n" in
+                                case "$gl_cv_func_printf_directive_f" in
                                   *yes)
-                                    case "$gl_cv_func_printf_directive_ls" in
+                                    case "$gl_cv_func_printf_directive_n" in
                                       *yes)
-                                        case "$gl_cv_func_printf_directive_lc" 
in
+                                        case "$gl_cv_func_printf_directive_ls" 
in
                                           *yes)
-                                            case 
"$gl_cv_func_printf_positions" in
+                                            case 
"$gl_cv_func_printf_directive_lc" in
                                               *yes)
-                                                case 
"$gl_cv_func_printf_flag_grouping" in
+                                                case 
"$gl_cv_func_printf_positions" in
                                                   *yes)
-                                                    case 
"$gl_cv_func_printf_flag_leftadjust" in
+                                                    case 
"$gl_cv_func_printf_flag_grouping" in
                                                       *yes)
-                                                        case 
"$gl_cv_func_printf_flag_zero" in
+                                                        case 
"$gl_cv_func_printf_flag_leftadjust" in
                                                           *yes)
-                                                            case 
"$gl_cv_func_printf_precision" in
+                                                            case 
"$gl_cv_func_printf_flag_zero" in
                                                               *yes)
-                                                                case 
"$gl_cv_func_printf_enomem" in
+                                                                case 
"$gl_cv_func_printf_precision" in
                                                                   *yes)
-                                                                    # 
obstack_printf exists and is
-                                                                    # already 
POSIX compliant.
-                                                                    
gl_cv_func_obstack_printf_posix=yes
+                                                                    case 
"$gl_cv_func_printf_enomem" in
+                                                                      *yes)
+                                                                        # 
obstack_printf exists and is
+                                                                        # 
already POSIX compliant.
+                                                                        
gl_cv_func_obstack_printf_posix=yes
+                                                                        ;;
+                                                                    esac
                                                                     ;;
                                                                 esac
                                                                 ;;
diff --git a/m4/printf.m4 b/m4/printf.m4
index 2f15df1e76..7178533a88 100644
--- a/m4/printf.m4
+++ b/m4/printf.m4
@@ -1,4 +1,4 @@
-# printf.m4 serial 78
+# printf.m4 serial 79
 dnl Copyright (C) 2003, 2007-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -101,6 +101,92 @@ AC_DEFUN([gl_PRINTF_SIZES_C99]
     ])
 ])
 
+dnl Test whether the *printf family of functions supports the 'w8', 'w16',
+dnl 'w32', 'w64', 'wf8', 'wf16', 'wf32', 'wf64' size specifiers. (ISO C23)
+dnl Result is gl_cv_func_printf_sizes_c23.
+
+AC_DEFUN([gl_PRINTF_SIZES_C23],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([gl_AC_HEADER_STDINT_H])
+  AC_REQUIRE([gl_AC_HEADER_INTTYPES_H])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether printf supports size specifiers as in C23],
+    [gl_cv_func_printf_sizes_c23],
+    [
+      AC_RUN_IFELSE(
+        [AC_LANG_SOURCE([[
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#if HAVE_STDINT_H_WITH_UINTMAX
+# include <stdint.h>
+#endif
+#if HAVE_INTTYPES_H_WITH_UINTMAX
+# include <inttypes.h>
+#endif
+static char buf[100];
+int main ()
+{
+  int result = 0;
+  buf[0] = '\0';
+  if (sprintf (buf, "%w8u %d", (uint8_t) 123, 33, 44, 55) < 0
+      || strcmp (buf, "123 33") != 0)
+    result |= 1;
+  buf[0] = '\0';
+  if (sprintf (buf, "%wf8u %d", (uint_fast8_t) 123, 33, 44, 55) < 0
+      || strcmp (buf, "123 33") != 0)
+    result |= 1;
+  buf[0] = '\0';
+  if (sprintf (buf, "%w16u %d", (uint16_t) 12345, 33, 44, 55) < 0
+      || strcmp (buf, "12345 33") != 0)
+    result |= 2;
+  buf[0] = '\0';
+  if (sprintf (buf, "%wf16u %d", (uint_fast16_t) 12345, 33, 44, 55) < 0
+      || strcmp (buf, "12345 33") != 0)
+    result |= 2;
+  buf[0] = '\0';
+  if (sprintf (buf, "%w32u %d", (uint32_t) 12345671, 33, 44, 55) < 0
+      || strcmp (buf, "12345671 33") != 0)
+    result |= 4;
+  buf[0] = '\0';
+  if (sprintf (buf, "%wf32u %d", (uint_fast32_t) 12345671, 33, 44, 55) < 0
+      || strcmp (buf, "12345671 33") != 0)
+    result |= 4;
+#if HAVE_STDINT_H_WITH_UINTMAX || HAVE_INTTYPES_H_WITH_UINTMAX
+  buf[0] = '\0';
+  if (sprintf (buf, "%w64u %d", (uint64_t) 12345671, 33, 44, 55) < 0
+      || strcmp (buf, "12345671 33") != 0)
+    result |= 8;
+  buf[0] = '\0';
+  if (sprintf (buf, "%wf64u %d", (uint_fast64_t) 12345671, 33, 44, 55) < 0
+      || strcmp (buf, "12345671 33") != 0)
+    result |= 8;
+#else
+  result |= 8;
+#endif
+  return result;
+}]])],
+        [gl_cv_func_printf_sizes_c23=yes],
+        [gl_cv_func_printf_sizes_c23=no],
+        [
+         case "$host_os" in
+                               # Guess no on glibc systems.
+           *-gnu* | gnu*)      gl_cv_func_printf_sizes_c23="guessing no";;
+                               # Guess no on musl systems.
+           *-musl* | midipix*) gl_cv_func_printf_sizes_c23="guessing no";;
+                               # Guess no on Android.
+           linux*-android*)    gl_cv_func_printf_sizes_c23="guessing no";;
+                               # Guess no on native Windows.
+           mingw*)             gl_cv_func_printf_sizes_c23="guessing no";;
+                               # If we don't know, obey --enable-cross-guesses.
+           *)                  
gl_cv_func_printf_sizes_c23="$gl_cross_guess_normal";;
+         esac
+        ])
+    ])
+])
+
 dnl Test whether the *printf family of functions supports 'long double'
 dnl arguments together with the 'L' size specifier. (ISO C99, POSIX:2001)
 dnl Result is gl_cv_func_printf_long_double.
@@ -1867,95 +1953,97 @@ AC_DEFUN([gl_SWPRINTF_WORKS]
 dnl The results of these tests on various platforms are:
 dnl
 dnl 1 = gl_PRINTF_SIZES_C99
-dnl 2 = gl_PRINTF_LONG_DOUBLE
-dnl 3 = gl_PRINTF_INFINITE
-dnl 4 = gl_PRINTF_INFINITE_LONG_DOUBLE
-dnl 5 = gl_PRINTF_DIRECTIVE_A
-dnl 6 = gl_PRINTF_DIRECTIVE_B
-dnl 7 = gl_PRINTF_DIRECTIVE_UPPERCASE_B
-dnl 8 = gl_PRINTF_DIRECTIVE_F
-dnl 9 = gl_PRINTF_DIRECTIVE_N
-dnl 10 = gl_PRINTF_DIRECTIVE_LS
-dnl 11 = gl_PRINTF_DIRECTIVE_LC
-dnl 12 = gl_PRINTF_POSITIONS
-dnl 13 = gl_PRINTF_FLAG_GROUPING
-dnl 14 = gl_PRINTF_FLAG_LEFTADJUST
-dnl 15 = gl_PRINTF_FLAG_ZERO
-dnl 16 = gl_PRINTF_PRECISION
-dnl 17 = gl_PRINTF_ENOMEM
-dnl 18 = gl_SNPRINTF_PRESENCE
-dnl 19 = gl_SNPRINTF_TRUNCATION_C99
-dnl 20 = gl_SNPRINTF_RETVAL_C99
-dnl 21 = gl_SNPRINTF_DIRECTIVE_N
-dnl 22 = gl_SNPRINTF_SIZE1
-dnl 23 = gl_VSNPRINTF_ZEROSIZE_C99
-dnl 24 = gl_SWPRINTF_WORKS
+dnl 2 = gl_PRINTF_SIZES_C23
+dnl 3 = gl_PRINTF_LONG_DOUBLE
+dnl 4 = gl_PRINTF_INFINITE
+dnl 5 = gl_PRINTF_INFINITE_LONG_DOUBLE
+dnl 6 = gl_PRINTF_DIRECTIVE_A
+dnl 7 = gl_PRINTF_DIRECTIVE_B
+dnl 8 = gl_PRINTF_DIRECTIVE_UPPERCASE_B
+dnl 9 = gl_PRINTF_DIRECTIVE_F
+dnl 10 = gl_PRINTF_DIRECTIVE_N
+dnl 11 = gl_PRINTF_DIRECTIVE_LS
+dnl 12 = gl_PRINTF_DIRECTIVE_LC
+dnl 13 = gl_PRINTF_POSITIONS
+dnl 14 = gl_PRINTF_FLAG_GROUPING
+dnl 15 = gl_PRINTF_FLAG_LEFTADJUST
+dnl 16 = gl_PRINTF_FLAG_ZERO
+dnl 17 = gl_PRINTF_PRECISION
+dnl 18 = gl_PRINTF_ENOMEM
+dnl 19 = gl_SNPRINTF_PRESENCE
+dnl 20 = gl_SNPRINTF_TRUNCATION_C99
+dnl 21 = gl_SNPRINTF_RETVAL_C99
+dnl 22 = gl_SNPRINTF_DIRECTIVE_N
+dnl 23 = gl_SNPRINTF_SIZE1
+dnl 24 = gl_VSNPRINTF_ZEROSIZE_C99
+dnl 25 = gl_SWPRINTF_WORKS
 dnl
 dnl 1 = checking whether printf supports size specifiers as in C99...
-dnl 2 = checking whether printf supports 'long double' arguments...
-dnl 3 = checking whether printf supports infinite 'double' arguments...
-dnl 4 = checking whether printf supports infinite 'long double' arguments...
-dnl 5 = checking whether printf supports the 'a' and 'A' directives...
-dnl 6 = checking whether printf supports the 'b' directive...
-dnl 7 = checking whether printf supports the 'B' directive...
-dnl 8 = checking whether printf supports the 'F' directive...
-dnl 9 = checking whether printf supports the 'n' directive...
-dnl 10 = checking whether printf supports the 'ls' directive...
-dnl 11 = checking whether printf supports the 'lc' directive correctly...
-dnl 12 = checking whether printf supports POSIX/XSI format strings with 
positions...
-dnl 13 = checking whether printf supports the grouping flag...
-dnl 14 = checking whether printf supports the left-adjust flag correctly...
-dnl 15 = checking whether printf supports the zero flag correctly...
-dnl 16 = checking whether printf supports large precisions...
-dnl 17 = checking whether printf survives out-of-memory conditions...
-dnl 18 = checking for snprintf...
-dnl 19 = checking whether snprintf truncates the result as in C99...
-dnl 20 = checking whether snprintf returns a byte count as in C99...
-dnl 21 = checking whether snprintf fully supports the 'n' directive...
-dnl 22 = checking whether snprintf respects a size of 1...
-dnl 23 = checking whether vsnprintf respects a zero size as in C99...
-dnl 24 = checking whether swprintf works...
+dnl 2 = checking whether printf supports size specifiers as in C23...
+dnl 3 = checking whether printf supports 'long double' arguments...
+dnl 4 = checking whether printf supports infinite 'double' arguments...
+dnl 5 = checking whether printf supports infinite 'long double' arguments...
+dnl 6 = checking whether printf supports the 'a' and 'A' directives...
+dnl 7 = checking whether printf supports the 'b' directive...
+dnl 8 = checking whether printf supports the 'B' directive...
+dnl 9 = checking whether printf supports the 'F' directive...
+dnl 10 = checking whether printf supports the 'n' directive...
+dnl 11 = checking whether printf supports the 'ls' directive...
+dnl 12 = checking whether printf supports the 'lc' directive correctly...
+dnl 13 = checking whether printf supports POSIX/XSI format strings with 
positions...
+dnl 14 = checking whether printf supports the grouping flag...
+dnl 15 = checking whether printf supports the left-adjust flag correctly...
+dnl 16 = checking whether printf supports the zero flag correctly...
+dnl 17 = checking whether printf supports large precisions...
+dnl 18 = checking whether printf survives out-of-memory conditions...
+dnl 19 = checking for snprintf...
+dnl 20 = checking whether snprintf truncates the result as in C99...
+dnl 21 = checking whether snprintf returns a byte count as in C99...
+dnl 22 = checking whether snprintf fully supports the 'n' directive...
+dnl 23 = checking whether snprintf respects a size of 1...
+dnl 24 = checking whether vsnprintf respects a zero size as in C99...
+dnl 25 = checking whether swprintf works...
 dnl
 dnl . = yes, # = no.
 dnl
-dnl                                  1  2  3  4  5  6  7  8  9 10 11 12 13 14 
15 16 17 18 19 20 21 22 23 24
-dnl   musl libc 1.2.3                .  .  .  .  .  #  #  .  .  .  .  .  .  .  
.  .  .  .  .  .  .  .  .  #
-dnl   glibc 2.35                     .  .  .  .  .  .  .  .  .  .  #  .  .  .  
.  .  .  .  .  .  .  .  .  .
-dnl   glibc 2.5                      .  .  .  .  .  #  #  .  .  .  #  .  .  .  
.  .  .  .  .  .  .  .  .  ?
-dnl   glibc 2.3.6                    .  .  .  .  #  #  #  .  .  .  #  .  .  .  
.  .  .  .  .  .  .  .  .  ?
-dnl   FreeBSD 13.0                   .  .  .  .  #  #  #  .  .  .  #  .  .  .  
.  .  #  .  .  .  .  .  .  #
-dnl   FreeBSD 5.4, 6.1               .  .  .  .  #  #  #  .  .  .  #  .  .  .  
#  .  #  .  .  .  .  .  .  #
-dnl   Mac OS X 10.13.5               .  .  .  #  #  #  #  .  #  .  #  .  .  .  
.  .  .  .  .  .  #  .  .  #
-dnl   Mac OS X 10.5.8                .  .  .  #  #  #  #  .  .  .  #  .  .  .  
#  .  .  .  .  .  .  .  .  #
-dnl   Mac OS X 10.3.9                .  .  .  .  #  #  #  .  .  .  #  .  .  .  
#  .  #  .  .  .  .  .  .  #
-dnl   OpenBSD 6.0, 6.7               .  .  .  .  #  #  #  .  .  .  #  .  .  .  
.  .  #  .  .  .  .  .  .  #
-dnl   OpenBSD 3.9, 4.0               .  .  #  #  #  #  #  #  .  #  #  .  #  .  
#  .  #  .  .  .  .  .  .  #
-dnl   Cygwin 1.7.0 (2009)            .  .  .  #  .  #  #  .  .  ?  ?  .  .  .  
.  .  ?  .  .  .  .  .  .  ?
-dnl   Cygwin 1.5.25 (2008)           .  .  .  #  #  #  #  .  .  #  ?  .  .  .  
.  .  #  .  .  .  .  .  .  ?
-dnl   Cygwin 1.5.19 (2006)           #  .  .  #  #  #  #  #  .  #  ?  .  #  .  
#  #  #  .  .  .  .  .  .  ?
-dnl   Solaris 11.4                   .  .  #  #  #  #  #  .  .  #  #  .  .  .  
#  .  .  .  .  .  .  .  .  .
-dnl   Solaris 11.3                   .  .  .  .  #  #  #  .  .  #  #  .  .  .  
.  .  .  .  .  .  .  .  .  .
-dnl   Solaris 11.0                   .  .  #  #  #  #  #  .  .  #  #  .  .  .  
#  .  .  .  .  .  .  .  .  ?
-dnl   Solaris 10                     .  .  #  #  #  #  #  .  .  #  #  .  .  .  
#  #  .  .  .  .  .  .  .  ?
-dnl   Solaris 2.6 ... 9              #  .  #  #  #  #  #  #  .  #  #  .  .  .  
#  #  .  .  .  #  .  .  .  ?
-dnl   Solaris 2.5.1                  #  .  #  #  #  #  #  #  .  #  #  .  .  .  
#  .  .  #  #  #  #  #  #  ?
-dnl   AIX 7.1                        .  .  #  #  #  #  #  .  .  .  #  .  .  .  
#  #  .  .  .  .  .  .  .  #
-dnl   AIX 5.2                        .  .  #  #  #  #  #  .  .  .  #  .  .  .  
#  .  .  .  .  .  .  .  .  #
-dnl   AIX 4.3.2, 5.1                 #  .  #  #  #  #  #  #  .  .  #  .  .  .  
#  .  .  .  .  #  .  .  .  #
-dnl   HP-UX 11.31                    .  .  .  .  #  #  #  .  .  .  ?  .  .  .  
#  .  .  .  .  #  #  .  .  ?
-dnl   HP-UX 11.{00,11,23}            #  .  .  .  #  #  #  #  .  .  ?  .  .  .  
#  .  .  .  .  #  #  .  #  ?
-dnl   HP-UX 10.20                    #  .  #  .  #  #  #  #  .  ?  ?  .  .  #  
#  .  .  .  .  #  #  ?  #  ?
-dnl   IRIX 6.5                       #  .  #  #  #  #  #  #  .  #  #  .  .  .  
#  .  .  .  .  #  .  .  .  #
-dnl   OSF/1 5.1                      #  .  #  #  #  #  #  #  .  .  ?  .  .  .  
#  .  .  .  .  #  .  .  #  ?
-dnl   OSF/1 4.0d                     #  .  #  #  #  #  #  #  .  .  ?  .  .  .  
#  .  .  #  #  #  #  #  #  ?
-dnl   NetBSD 9.0                     .  .  .  .  #  #  #  .  .  .  #  .  .  .  
.  .  .  .  .  .  .  .  .  #
-dnl   NetBSD 5.0                     .  .  .  #  #  #  #  .  .  .  #  .  .  .  
#  .  #  .  .  .  .  .  .  #
-dnl   NetBSD 4.0                     .  ?  ?  ?  ?  #  #  ?  .  ?  #  .  ?  ?  
?  ?  ?  .  .  .  ?  ?  ?  #
-dnl   NetBSD 3.0                     .  .  .  .  #  #  #  #  .  ?  #  #  #  ?  
#  .  #  .  .  .  .  .  .  #
-dnl   Haiku                          .  .  .  #  #  #  #  #  .  #  ?  .  .  .  
.  .  ?  .  .  ?  .  .  .  ?
-dnl   BeOS                           #  #  .  #  #  #  #  #  .  ?  ?  #  .  ?  
.  #  ?  .  .  ?  .  .  .  ?
-dnl   Android 4.3                    .  .  #  #  #  #  #  #  #  #  ?  .  #  .  
#  .  #  .  .  .  #  .  .  ?
-dnl   old mingw / msvcrt             #  #  #  #  #  #  #  #  .  .  ?  #  #  .  
#  #  ?  .  #  #  #  .  .  #
-dnl   MSVC 9                         #  #  #  #  #  #  #  #  #  .  ?  #  #  .  
#  #  ?  #  #  #  #  .  .  #
-dnl   mingw 2009-2011                .  #  .  #  .  #  #  .  .  .  ?  #  #  .  
.  .  ?  .  .  .  .  .  .  #
-dnl   mingw-w64 2011                 #  #  #  #  #  #  #  #  .  .  ?  #  #  .  
#  #  ?  .  #  #  #  .  .  #
+dnl                                  1  2  3  4  5  6  7  8  9 10 11 12 13 14 
15 16 17 18 19 20 21 22 23 24 25
+dnl   musl libc 1.2.3                .  #  .  .  .  .  #  #  .  .  .  .  .  .  
.  .  .  .  .  .  .  .  .  .  #
+dnl   glibc 2.35                     .  #  .  .  .  .  .  .  .  .  .  #  .  .  
.  .  .  .  .  .  .  .  .  .  .
+dnl   glibc 2.5                      .  #  .  .  .  .  #  #  .  .  .  #  .  .  
.  .  .  .  .  .  .  .  .  .  ?
+dnl   glibc 2.3.6                    .  #  .  .  .  #  #  #  .  .  .  #  .  .  
.  .  .  .  .  .  .  .  .  .  ?
+dnl   FreeBSD 13.0                   .  #  .  .  .  #  #  #  .  .  .  #  .  .  
.  .  .  #  .  .  .  .  .  .  #
+dnl   FreeBSD 5.4, 6.1               .  #  .  .  .  #  #  #  .  .  .  #  .  .  
.  #  .  #  .  .  .  .  .  .  #
+dnl   Mac OS X 10.13.5               .  #  .  .  #  #  #  #  .  #  .  #  .  .  
.  .  .  .  .  .  .  #  .  .  #
+dnl   Mac OS X 10.5.8                .  #  .  .  #  #  #  #  .  .  .  #  .  .  
.  #  .  .  .  .  .  .  .  .  #
+dnl   Mac OS X 10.3.9                .  #  .  .  .  #  #  #  .  .  .  #  .  .  
.  #  .  #  .  .  .  .  .  .  #
+dnl   OpenBSD 6.0, 6.7               .  #  .  .  .  #  #  #  .  .  .  #  .  .  
.  .  .  #  .  .  .  .  .  .  #
+dnl   OpenBSD 3.9, 4.0               .  #  .  #  #  #  #  #  #  .  #  #  .  #  
.  #  .  #  .  .  .  .  .  .  #
+dnl   Cygwin 1.7.0 (2009)            .  #  .  .  #  .  #  #  .  .  ?  ?  .  .  
.  .  .  ?  .  .  .  .  .  .  ?
+dnl   Cygwin 1.5.25 (2008)           .  #  .  .  #  #  #  #  .  .  #  ?  .  .  
.  .  .  #  .  .  .  .  .  .  ?
+dnl   Cygwin 1.5.19 (2006)           #  #  .  .  #  #  #  #  #  .  #  ?  .  #  
.  #  #  #  .  .  .  .  .  .  ?
+dnl   Solaris 11.4                   .  #  .  #  #  #  #  #  .  .  #  #  .  .  
.  #  .  .  .  .  .  .  .  .  .
+dnl   Solaris 11.3                   .  #  .  .  .  #  #  #  .  .  #  #  .  .  
.  .  .  .  .  .  .  .  .  .  .
+dnl   Solaris 11.0                   .  #  .  #  #  #  #  #  .  .  #  #  .  .  
.  #  .  .  .  .  .  .  .  .  ?
+dnl   Solaris 10                     .  #  .  #  #  #  #  #  .  .  #  #  .  .  
.  #  #  .  .  .  .  .  .  .  ?
+dnl   Solaris 2.6 ... 9              #  #  .  #  #  #  #  #  #  .  #  #  .  .  
.  #  #  .  .  .  #  .  .  .  ?
+dnl   Solaris 2.5.1                  #  #  .  #  #  #  #  #  #  .  #  #  .  .  
.  #  .  .  #  #  #  #  #  #  ?
+dnl   AIX 7.1                        .  #  .  #  #  #  #  #  .  .  .  #  .  .  
.  #  #  .  .  .  .  .  .  .  #
+dnl   AIX 5.2                        .  #  .  #  #  #  #  #  .  .  .  #  .  .  
.  #  .  .  .  .  .  .  .  .  #
+dnl   AIX 4.3.2, 5.1                 #  #  .  #  #  #  #  #  #  .  .  #  .  .  
.  #  .  .  .  .  #  .  .  .  #
+dnl   HP-UX 11.31                    .  #  .  .  .  #  #  #  .  .  .  ?  .  .  
.  #  .  .  .  .  #  #  .  .  ?
+dnl   HP-UX 11.{00,11,23}            #  #  .  .  .  #  #  #  #  .  .  ?  .  .  
.  #  .  .  .  .  #  #  .  #  ?
+dnl   HP-UX 10.20                    #  #  .  #  .  #  #  #  #  .  ?  ?  .  .  
#  #  .  .  .  .  #  #  ?  #  ?
+dnl   IRIX 6.5                       #  #  .  #  #  #  #  #  #  .  #  #  .  .  
.  #  .  .  .  .  #  .  .  .  #
+dnl   OSF/1 5.1                      #  #  .  #  #  #  #  #  #  .  .  ?  .  .  
.  #  .  .  .  .  #  .  .  #  ?
+dnl   OSF/1 4.0d                     #  #  .  #  #  #  #  #  #  .  .  ?  .  .  
.  #  .  .  #  #  #  #  #  #  ?
+dnl   NetBSD 9.0                     .  #  .  .  .  #  #  #  .  .  .  #  .  .  
.  .  .  .  .  .  .  .  .  .  #
+dnl   NetBSD 5.0                     .  #  .  .  #  #  #  #  .  .  .  #  .  .  
.  #  .  #  .  .  .  .  .  .  #
+dnl   NetBSD 4.0                     .  #  ?  ?  ?  ?  #  #  ?  .  ?  #  .  ?  
?  ?  ?  ?  .  .  .  ?  ?  ?  #
+dnl   NetBSD 3.0                     .  #  .  .  .  #  #  #  #  .  ?  #  #  #  
?  #  .  #  .  .  .  .  .  .  #
+dnl   Haiku                          .  #  .  .  #  #  #  #  #  .  #  ?  .  .  
.  .  .  ?  .  .  ?  .  .  .  ?
+dnl   BeOS                           #  #  #  .  #  #  #  #  #  .  ?  ?  #  .  
?  .  #  ?  .  .  ?  .  .  .  ?
+dnl   Android 4.3                    .  #  .  #  #  #  #  #  #  #  #  ?  .  #  
.  #  .  #  .  .  .  #  .  .  ?
+dnl   old mingw / msvcrt             #  #  #  #  #  #  #  #  #  .  .  ?  #  #  
.  #  #  ?  .  #  #  #  .  .  #
+dnl   MSVC 9                         #  #  #  #  #  #  #  #  #  #  .  ?  #  #  
.  #  #  ?  #  #  #  #  .  .  #
+dnl   mingw 2009-2011                .  #  #  .  #  .  #  #  .  .  .  ?  #  #  
.  .  .  ?  .  .  .  .  .  .  #
+dnl   mingw-w64 2011                 #  #  #  #  #  #  #  #  #  .  .  ?  #  #  
.  #  #  ?  .  #  #  #  .  .  #
diff --git a/m4/snprintf-posix.m4 b/m4/snprintf-posix.m4
index 303db27a84..010ca5aea2 100644
--- a/m4/snprintf-posix.m4
+++ b/m4/snprintf-posix.m4
@@ -1,4 +1,4 @@
-# snprintf-posix.m4 serial 17
+# snprintf-posix.m4 serial 18
 dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -19,6 +19,7 @@ AC_DEFUN([gl_FUNC_SNPRINTF_POSIX]
 AC_DEFUN([gl_FUNC_SNPRINTF_IS_POSIX],
 [
   AC_REQUIRE([gl_PRINTF_SIZES_C99])
+  AC_REQUIRE([gl_PRINTF_SIZES_C23])
   AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
   AC_REQUIRE([gl_PRINTF_INFINITE])
   AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
@@ -44,49 +45,53 @@ AC_DEFUN([gl_FUNC_SNPRINTF_IS_POSIX]
     gl_VSNPRINTF_ZEROSIZE_C99
     case "$gl_cv_func_printf_sizes_c99" in
       *yes)
-        case "$gl_cv_func_printf_long_double" in
+        case "$gl_cv_func_printf_sizes_c23" in
           *yes)
-            case "$gl_cv_func_printf_infinite" in
+            case "$gl_cv_func_printf_long_double" in
               *yes)
-                case "$gl_cv_func_printf_infinite_long_double" in
+                case "$gl_cv_func_printf_infinite" in
                   *yes)
-                    case "$gl_cv_func_printf_directive_a" in
+                    case "$gl_cv_func_printf_infinite_long_double" in
                       *yes)
-                        case "$gl_cv_func_printf_directive_b" in
+                        case "$gl_cv_func_printf_directive_a" in
                           *yes)
-                            case "$gl_cv_func_printf_directive_f" in
+                            case "$gl_cv_func_printf_directive_b" in
                               *yes)
-                                case "$gl_cv_func_printf_directive_n" in
+                                case "$gl_cv_func_printf_directive_f" in
                                   *yes)
-                                    case "$gl_cv_func_printf_directive_ls" in
+                                    case "$gl_cv_func_printf_directive_n" in
                                       *yes)
-                                        case "$gl_cv_func_printf_directive_lc" 
in
+                                        case "$gl_cv_func_printf_directive_ls" 
in
                                           *yes)
-                                            case 
"$gl_cv_func_printf_positions" in
+                                            case 
"$gl_cv_func_printf_directive_lc" in
                                               *yes)
-                                                case 
"$gl_cv_func_printf_flag_grouping" in
+                                                case 
"$gl_cv_func_printf_positions" in
                                                   *yes)
-                                                    case 
"$gl_cv_func_printf_flag_leftadjust" in
+                                                    case 
"$gl_cv_func_printf_flag_grouping" in
                                                       *yes)
-                                                        case 
"$gl_cv_func_printf_flag_zero" in
+                                                        case 
"$gl_cv_func_printf_flag_leftadjust" in
                                                           *yes)
-                                                            case 
"$gl_cv_func_printf_precision" in
+                                                            case 
"$gl_cv_func_printf_flag_zero" in
                                                               *yes)
-                                                                case 
"$gl_cv_func_printf_enomem" in
+                                                                case 
"$gl_cv_func_printf_precision" in
                                                                   *yes)
-                                                                    case 
"$gl_cv_func_snprintf_truncation_c99" in
+                                                                    case 
"$gl_cv_func_printf_enomem" in
                                                                       *yes)
-                                                                        case 
"$gl_cv_func_snprintf_retval_c99" in
+                                                                        case 
"$gl_cv_func_snprintf_truncation_c99" in
                                                                           *yes)
-                                                                            
case "$gl_cv_func_snprintf_directive_n" in
+                                                                            
case "$gl_cv_func_snprintf_retval_c99" in
                                                                               
*yes)
-                                                                               
 case "$gl_cv_func_snprintf_size1" in
+                                                                               
 case "$gl_cv_func_snprintf_directive_n" in
                                                                                
   *yes)
-                                                                               
     case "$gl_cv_func_vsnprintf_zerosize_c99" in
+                                                                               
     case "$gl_cv_func_snprintf_size1" in
                                                                                
       *yes)
-                                                                               
         # snprintf exists and is
-                                                                               
         # already POSIX compliant.
-                                                                               
         gl_cv_func_snprintf_posix=yes
+                                                                               
         case "$gl_cv_func_vsnprintf_zerosize_c99" in
+                                                                               
           *yes)
+                                                                               
             # snprintf exists and is
+                                                                               
             # already POSIX compliant.
+                                                                               
             gl_cv_func_snprintf_posix=yes
+                                                                               
             ;;
+                                                                               
         esac
                                                                                
         ;;
                                                                                
     esac
                                                                                
     ;;
diff --git a/m4/sprintf-posix.m4 b/m4/sprintf-posix.m4
index fe152d4eff..09a4ec8e57 100644
--- a/m4/sprintf-posix.m4
+++ b/m4/sprintf-posix.m4
@@ -1,4 +1,4 @@
-# sprintf-posix.m4 serial 15
+# sprintf-posix.m4 serial 16
 dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -19,6 +19,7 @@ AC_DEFUN([gl_FUNC_SPRINTF_POSIX]
 AC_DEFUN([gl_FUNC_SPRINTF_IS_POSIX],
 [
   AC_REQUIRE([gl_PRINTF_SIZES_C99])
+  AC_REQUIRE([gl_PRINTF_SIZES_C23])
   AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
   AC_REQUIRE([gl_PRINTF_INFINITE])
   AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
@@ -37,39 +38,43 @@ AC_DEFUN([gl_FUNC_SPRINTF_IS_POSIX]
   gl_cv_func_sprintf_posix=no
   case "$gl_cv_func_printf_sizes_c99" in
     *yes)
-      case "$gl_cv_func_printf_long_double" in
+      case "$gl_cv_func_printf_sizes_c23" in
         *yes)
-          case "$gl_cv_func_printf_infinite" in
+          case "$gl_cv_func_printf_long_double" in
             *yes)
-              case "$gl_cv_func_printf_infinite_long_double" in
+              case "$gl_cv_func_printf_infinite" in
                 *yes)
-                  case "$gl_cv_func_printf_directive_a" in
+                  case "$gl_cv_func_printf_infinite_long_double" in
                     *yes)
-                      case "$gl_cv_func_printf_directive_b" in
+                      case "$gl_cv_func_printf_directive_a" in
                         *yes)
-                          case "$gl_cv_func_printf_directive_f" in
+                          case "$gl_cv_func_printf_directive_b" in
                             *yes)
-                              case "$gl_cv_func_printf_directive_n" in
+                              case "$gl_cv_func_printf_directive_f" in
                                 *yes)
-                                  case "$gl_cv_func_printf_directive_ls" in
+                                  case "$gl_cv_func_printf_directive_n" in
                                     *yes)
-                                      case "$gl_cv_func_printf_directive_lc" in
+                                      case "$gl_cv_func_printf_directive_ls" in
                                         *yes)
-                                          case "$gl_cv_func_printf_positions" 
in
+                                          case 
"$gl_cv_func_printf_directive_lc" in
                                             *yes)
-                                              case 
"$gl_cv_func_printf_flag_grouping" in
+                                              case 
"$gl_cv_func_printf_positions" in
                                                 *yes)
-                                                  case 
"$gl_cv_func_printf_flag_leftadjust" in
+                                                  case 
"$gl_cv_func_printf_flag_grouping" in
                                                     *yes)
-                                                      case 
"$gl_cv_func_printf_flag_zero" in
+                                                      case 
"$gl_cv_func_printf_flag_leftadjust" in
                                                         *yes)
-                                                          case 
"$gl_cv_func_printf_precision" in
+                                                          case 
"$gl_cv_func_printf_flag_zero" in
                                                             *yes)
-                                                              case 
"$gl_cv_func_printf_enomem" in
+                                                              case 
"$gl_cv_func_printf_precision" in
                                                                 *yes)
-                                                                  # sprintf 
exists and is
-                                                                  # already 
POSIX compliant.
-                                                                  
gl_cv_func_sprintf_posix=yes
+                                                                  case 
"$gl_cv_func_printf_enomem" in
+                                                                    *yes)
+                                                                      # 
sprintf exists and is
+                                                                      # 
already POSIX compliant.
+                                                                      
gl_cv_func_sprintf_posix=yes
+                                                                      ;;
+                                                                  esac
                                                                   ;;
                                                               esac
                                                               ;;
diff --git a/m4/vasnprintf-posix.m4 b/m4/vasnprintf-posix.m4
index b4d1e3d0aa..f72fb51094 100644
--- a/m4/vasnprintf-posix.m4
+++ b/m4/vasnprintf-posix.m4
@@ -1,4 +1,4 @@
-# vasnprintf-posix.m4 serial 16
+# vasnprintf-posix.m4 serial 17
 dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -18,6 +18,7 @@ AC_DEFUN([gl_FUNC_VASNPRINTF_POSIX]
 AC_DEFUN_ONCE([gl_FUNC_VASNPRINTF_IS_POSIX],
 [
   AC_REQUIRE([gl_PRINTF_SIZES_C99])
+  AC_REQUIRE([gl_PRINTF_SIZES_C23])
   AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
   AC_REQUIRE([gl_PRINTF_INFINITE])
   AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
@@ -37,41 +38,45 @@ AC_DEFUN_ONCE([gl_FUNC_VASNPRINTF_IS_POSIX]
   AC_CHECK_FUNCS_ONCE([vasnprintf])
   case "$gl_cv_func_printf_sizes_c99" in
     *yes)
-      case "$gl_cv_func_printf_long_double" in
+      case "$gl_cv_func_printf_sizes_c23" in
         *yes)
-          case "$gl_cv_func_printf_infinite" in
+          case "$gl_cv_func_printf_long_double" in
             *yes)
-              case "$gl_cv_func_printf_infinite_long_double" in
+              case "$gl_cv_func_printf_infinite" in
                 *yes)
-                  case "$gl_cv_func_printf_directive_a" in
+                  case "$gl_cv_func_printf_infinite_long_double" in
                     *yes)
-                      case "$gl_cv_func_printf_directive_b" in
+                      case "$gl_cv_func_printf_directive_a" in
                         *yes)
-                          case "$gl_cv_func_printf_directive_f" in
+                          case "$gl_cv_func_printf_directive_b" in
                             *yes)
-                              case "$gl_cv_func_printf_directive_n" in
+                              case "$gl_cv_func_printf_directive_f" in
                                 *yes)
-                                  case "$gl_cv_func_printf_directive_ls" in
+                                  case "$gl_cv_func_printf_directive_n" in
                                     *yes)
-                                      case "$gl_cv_func_printf_directive_lc" in
+                                      case "$gl_cv_func_printf_directive_ls" in
                                         *yes)
-                                          case "$gl_cv_func_printf_positions" 
in
+                                          case 
"$gl_cv_func_printf_directive_lc" in
                                             *yes)
-                                              case 
"$gl_cv_func_printf_flag_grouping" in
+                                              case 
"$gl_cv_func_printf_positions" in
                                                 *yes)
-                                                  case 
"$gl_cv_func_printf_flag_leftadjust" in
+                                                  case 
"$gl_cv_func_printf_flag_grouping" in
                                                     *yes)
-                                                      case 
"$gl_cv_func_printf_flag_zero" in
+                                                      case 
"$gl_cv_func_printf_flag_leftadjust" in
                                                         *yes)
-                                                          case 
"$gl_cv_func_printf_precision" in
+                                                          case 
"$gl_cv_func_printf_flag_zero" in
                                                             *yes)
-                                                              case 
"$gl_cv_func_printf_enomem" in
+                                                              case 
"$gl_cv_func_printf_precision" in
                                                                 *yes)
-                                                                  if test 
$ac_cv_func_vasnprintf = yes; then
-                                                                    # 
vasnprintf exists and is
-                                                                    # already 
POSIX compliant.
-                                                                    
gl_cv_func_vasnprintf_posix=yes
-                                                                  fi
+                                                                  case 
"$gl_cv_func_printf_enomem" in
+                                                                    *yes)
+                                                                      if test 
$ac_cv_func_vasnprintf = yes; then
+                                                                        # 
vasnprintf exists and is
+                                                                        # 
already POSIX compliant.
+                                                                        
gl_cv_func_vasnprintf_posix=yes
+                                                                      fi
+                                                                      ;;
+                                                                  esac
                                                                   ;;
                                                               esac
                                                               ;;
diff --git a/m4/vasprintf-posix.m4 b/m4/vasprintf-posix.m4
index 1be95c2f22..3c7a6540bd 100644
--- a/m4/vasprintf-posix.m4
+++ b/m4/vasprintf-posix.m4
@@ -1,4 +1,4 @@
-# vasprintf-posix.m4 serial 16
+# vasprintf-posix.m4 serial 17
 dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -19,6 +19,7 @@ AC_DEFUN([gl_FUNC_VASPRINTF_POSIX]
 AC_DEFUN([gl_FUNC_VASPRINTF_IS_POSIX],
 [
   AC_REQUIRE([gl_PRINTF_SIZES_C99])
+  AC_REQUIRE([gl_PRINTF_SIZES_C23])
   AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
   AC_REQUIRE([gl_PRINTF_INFINITE])
   AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
@@ -38,41 +39,45 @@ AC_DEFUN([gl_FUNC_VASPRINTF_IS_POSIX]
   AC_CHECK_FUNCS([vasprintf])
   case "$gl_cv_func_printf_sizes_c99" in
     *yes)
-      case "$gl_cv_func_printf_long_double" in
+      case "$gl_cv_func_printf_sizes_c23" in
         *yes)
-          case "$gl_cv_func_printf_infinite" in
+          case "$gl_cv_func_printf_long_double" in
             *yes)
-              case "$gl_cv_func_printf_infinite_long_double" in
+              case "$gl_cv_func_printf_infinite" in
                 *yes)
-                  case "$gl_cv_func_printf_directive_a" in
+                  case "$gl_cv_func_printf_infinite_long_double" in
                     *yes)
-                      case "$gl_cv_func_printf_directive_b" in
+                      case "$gl_cv_func_printf_directive_a" in
                         *yes)
-                          case "$gl_cv_func_printf_directive_f" in
+                          case "$gl_cv_func_printf_directive_b" in
                             *yes)
-                              case "$gl_cv_func_printf_directive_n" in
+                              case "$gl_cv_func_printf_directive_f" in
                                 *yes)
-                                  case "$gl_cv_func_printf_directive_ls" in
+                                  case "$gl_cv_func_printf_directive_n" in
                                     *yes)
-                                      case "$gl_cv_func_printf_directive_lc" in
+                                      case "$gl_cv_func_printf_directive_ls" in
                                         *yes)
-                                          case "$gl_cv_func_printf_positions" 
in
+                                          case 
"$gl_cv_func_printf_directive_lc" in
                                             *yes)
-                                              case 
"$gl_cv_func_printf_flag_grouping" in
+                                              case 
"$gl_cv_func_printf_positions" in
                                                 *yes)
-                                                  case 
"$gl_cv_func_printf_flag_leftadjust" in
+                                                  case 
"$gl_cv_func_printf_flag_grouping" in
                                                     *yes)
-                                                      case 
"$gl_cv_func_printf_flag_zero" in
+                                                      case 
"$gl_cv_func_printf_flag_leftadjust" in
                                                         *yes)
-                                                          case 
"$gl_cv_func_printf_precision" in
+                                                          case 
"$gl_cv_func_printf_flag_zero" in
                                                             *yes)
-                                                              case 
"$gl_cv_func_printf_enomem" in
+                                                              case 
"$gl_cv_func_printf_precision" in
                                                                 *yes)
-                                                                  if test 
$ac_cv_func_vasprintf = yes; then
-                                                                    # 
vasprintf exists and is
-                                                                    # already 
POSIX compliant.
-                                                                    
gl_cv_func_vasprintf_posix=yes
-                                                                  fi
+                                                                  case 
"$gl_cv_func_printf_enomem" in
+                                                                    *yes)
+                                                                      if test 
$ac_cv_func_vasprintf = yes; then
+                                                                        # 
vasprintf exists and is
+                                                                        # 
already POSIX compliant.
+                                                                        
gl_cv_func_vasprintf_posix=yes
+                                                                      fi
+                                                                      ;;
+                                                                  esac
                                                                   ;;
                                                               esac
                                                               ;;
diff --git a/m4/vdprintf-posix.m4 b/m4/vdprintf-posix.m4
index 01664d4a52..e4b57924cd 100644
--- a/m4/vdprintf-posix.m4
+++ b/m4/vdprintf-posix.m4
@@ -1,4 +1,4 @@
-# vdprintf-posix.m4 serial 6
+# vdprintf-posix.m4 serial 7
 dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -19,6 +19,7 @@ AC_DEFUN([gl_FUNC_VDPRINTF_POSIX]
 AC_DEFUN([gl_FUNC_VDPRINTF_IS_POSIX],
 [
   AC_REQUIRE([gl_PRINTF_SIZES_C99])
+  AC_REQUIRE([gl_PRINTF_SIZES_C23])
   AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
   AC_REQUIRE([gl_PRINTF_INFINITE])
   AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
@@ -39,39 +40,43 @@ AC_DEFUN([gl_FUNC_VDPRINTF_IS_POSIX]
   if test $ac_cv_func_vdprintf = yes; then
     case "$gl_cv_func_printf_sizes_c99" in
       *yes)
-        case "$gl_cv_func_printf_long_double" in
+        case "$gl_cv_func_printf_sizes_c23" in
           *yes)
-            case "$gl_cv_func_printf_infinite" in
+            case "$gl_cv_func_printf_long_double" in
               *yes)
-                case "$gl_cv_func_printf_infinite_long_double" in
+                case "$gl_cv_func_printf_infinite" in
                   *yes)
-                    case "$gl_cv_func_printf_directive_a" in
+                    case "$gl_cv_func_printf_infinite_long_double" in
                       *yes)
-                        case "$gl_cv_func_printf_directive_b" in
+                        case "$gl_cv_func_printf_directive_a" in
                           *yes)
-                            case "$gl_cv_func_printf_directive_f" in
+                            case "$gl_cv_func_printf_directive_b" in
                               *yes)
-                                case "$gl_cv_func_printf_directive_n" in
+                                case "$gl_cv_func_printf_directive_f" in
                                   *yes)
-                                    case "$gl_cv_func_printf_directive_ls" in
+                                    case "$gl_cv_func_printf_directive_n" in
                                       *yes)
-                                        case "$gl_cv_func_printf_directive_lc" 
in
+                                        case "$gl_cv_func_printf_directive_ls" 
in
                                           *yes)
-                                            case 
"$gl_cv_func_printf_positions" in
+                                            case 
"$gl_cv_func_printf_directive_lc" in
                                               *yes)
-                                                case 
"$gl_cv_func_printf_flag_grouping" in
+                                                case 
"$gl_cv_func_printf_positions" in
                                                   *yes)
-                                                    case 
"$gl_cv_func_printf_flag_leftadjust" in
+                                                    case 
"$gl_cv_func_printf_flag_grouping" in
                                                       *yes)
-                                                        case 
"$gl_cv_func_printf_flag_zero" in
+                                                        case 
"$gl_cv_func_printf_flag_leftadjust" in
                                                           *yes)
-                                                            case 
"$gl_cv_func_printf_precision" in
+                                                            case 
"$gl_cv_func_printf_flag_zero" in
                                                               *yes)
-                                                                case 
"$gl_cv_func_printf_enomem" in
+                                                                case 
"$gl_cv_func_printf_precision" in
                                                                   *yes)
-                                                                    # vdprintf 
exists and is
-                                                                    # already 
POSIX compliant.
-                                                                    
gl_cv_func_vdprintf_posix=yes
+                                                                    case 
"$gl_cv_func_printf_enomem" in
+                                                                      *yes)
+                                                                        # 
vdprintf exists and is
+                                                                        # 
already POSIX compliant.
+                                                                        
gl_cv_func_vdprintf_posix=yes
+                                                                        ;;
+                                                                    esac
                                                                     ;;
                                                                 esac
                                                                 ;;
diff --git a/m4/vfprintf-posix.m4 b/m4/vfprintf-posix.m4
index f7e97a862a..6b51c50ada 100644
--- a/m4/vfprintf-posix.m4
+++ b/m4/vfprintf-posix.m4
@@ -1,4 +1,4 @@
-# vfprintf-posix.m4 serial 17
+# vfprintf-posix.m4 serial 18
 dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -19,6 +19,7 @@ AC_DEFUN([gl_FUNC_VFPRINTF_POSIX]
 AC_DEFUN([gl_FUNC_VFPRINTF_IS_POSIX],
 [
   AC_REQUIRE([gl_PRINTF_SIZES_C99])
+  AC_REQUIRE([gl_PRINTF_SIZES_C23])
   AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
   AC_REQUIRE([gl_PRINTF_INFINITE])
   AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
@@ -37,39 +38,43 @@ AC_DEFUN([gl_FUNC_VFPRINTF_IS_POSIX]
   gl_cv_func_vfprintf_posix=no
   case "$gl_cv_func_printf_sizes_c99" in
     *yes)
-      case "$gl_cv_func_printf_long_double" in
+      case "$gl_cv_func_printf_sizes_c23" in
         *yes)
-          case "$gl_cv_func_printf_infinite" in
+          case "$gl_cv_func_printf_long_double" in
             *yes)
-              case "$gl_cv_func_printf_infinite_long_double" in
+              case "$gl_cv_func_printf_infinite" in
                 *yes)
-                  case "$gl_cv_func_printf_directive_a" in
+                  case "$gl_cv_func_printf_infinite_long_double" in
                     *yes)
-                      case "$gl_cv_func_printf_directive_b" in
+                      case "$gl_cv_func_printf_directive_a" in
                         *yes)
-                          case "$gl_cv_func_printf_directive_f" in
+                          case "$gl_cv_func_printf_directive_b" in
                             *yes)
-                              case "$gl_cv_func_printf_directive_n" in
+                              case "$gl_cv_func_printf_directive_f" in
                                 *yes)
-                                  case "$gl_cv_func_printf_directive_ls" in
+                                  case "$gl_cv_func_printf_directive_n" in
                                     *yes)
-                                      case "$gl_cv_func_printf_directive_lc" in
+                                      case "$gl_cv_func_printf_directive_ls" in
                                         *yes)
-                                          case "$gl_cv_func_printf_positions" 
in
+                                          case 
"$gl_cv_func_printf_directive_lc" in
                                             *yes)
-                                              case 
"$gl_cv_func_printf_flag_grouping" in
+                                              case 
"$gl_cv_func_printf_positions" in
                                                 *yes)
-                                                  case 
"$gl_cv_func_printf_flag_leftadjust" in
+                                                  case 
"$gl_cv_func_printf_flag_grouping" in
                                                     *yes)
-                                                      case 
"$gl_cv_func_printf_flag_zero" in
+                                                      case 
"$gl_cv_func_printf_flag_leftadjust" in
                                                         *yes)
-                                                          case 
"$gl_cv_func_printf_precision" in
+                                                          case 
"$gl_cv_func_printf_flag_zero" in
                                                             *yes)
-                                                              case 
"$gl_cv_func_printf_enomem" in
+                                                              case 
"$gl_cv_func_printf_precision" in
                                                                 *yes)
-                                                                  # vfprintf 
exists and is
-                                                                  # already 
POSIX compliant.
-                                                                  
gl_cv_func_vfprintf_posix=yes
+                                                                  case 
"$gl_cv_func_printf_enomem" in
+                                                                    *yes)
+                                                                      # 
vfprintf exists and is
+                                                                      # 
already POSIX compliant.
+                                                                      
gl_cv_func_vfprintf_posix=yes
+                                                                      ;;
+                                                                  esac
                                                                   ;;
                                                               esac
                                                               ;;
diff --git a/m4/vsnprintf-posix.m4 b/m4/vsnprintf-posix.m4
index d65ca929a3..b47715c472 100644
--- a/m4/vsnprintf-posix.m4
+++ b/m4/vsnprintf-posix.m4
@@ -1,4 +1,4 @@
-# vsnprintf-posix.m4 serial 18
+# vsnprintf-posix.m4 serial 19
 dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -19,6 +19,7 @@ AC_DEFUN([gl_FUNC_VSNPRINTF_POSIX]
 AC_DEFUN([gl_FUNC_VSNPRINTF_IS_POSIX],
 [
   AC_REQUIRE([gl_PRINTF_SIZES_C99])
+  AC_REQUIRE([gl_PRINTF_SIZES_C23])
   AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
   AC_REQUIRE([gl_PRINTF_INFINITE])
   AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
@@ -45,49 +46,53 @@ AC_DEFUN([gl_FUNC_VSNPRINTF_IS_POSIX]
     gl_VSNPRINTF_ZEROSIZE_C99
     case "$gl_cv_func_printf_sizes_c99" in
       *yes)
-        case "$gl_cv_func_printf_long_double" in
+        case "$gl_cv_func_printf_sizes_c23" in
           *yes)
-            case "$gl_cv_func_printf_infinite" in
+            case "$gl_cv_func_printf_long_double" in
               *yes)
-                case "$gl_cv_func_printf_infinite_long_double" in
+                case "$gl_cv_func_printf_infinite" in
                   *yes)
-                    case "$gl_cv_func_printf_directive_a" in
+                    case "$gl_cv_func_printf_infinite_long_double" in
                       *yes)
-                        case "$gl_cv_func_printf_directive_b" in
+                        case "$gl_cv_func_printf_directive_a" in
                           *yes)
-                            case "$gl_cv_func_printf_directive_f" in
+                            case "$gl_cv_func_printf_directive_b" in
                               *yes)
-                                case "$gl_cv_func_printf_directive_n" in
+                                case "$gl_cv_func_printf_directive_f" in
                                   *yes)
-                                    case "$gl_cv_func_printf_directive_ls" in
+                                    case "$gl_cv_func_printf_directive_n" in
                                       *yes)
-                                        case "$gl_cv_func_printf_directive_lc" 
in
+                                        case "$gl_cv_func_printf_directive_ls" 
in
                                           *yes)
-                                            case 
"$gl_cv_func_printf_positions" in
+                                            case 
"$gl_cv_func_printf_directive_lc" in
                                               *yes)
-                                                case 
"$gl_cv_func_printf_flag_grouping" in
+                                                case 
"$gl_cv_func_printf_positions" in
                                                   *yes)
-                                                    case 
"$gl_cv_func_printf_flag_leftadjust" in
+                                                    case 
"$gl_cv_func_printf_flag_grouping" in
                                                       *yes)
-                                                        case 
"$gl_cv_func_printf_flag_zero" in
+                                                        case 
"$gl_cv_func_printf_flag_leftadjust" in
                                                           *yes)
-                                                            case 
"$gl_cv_func_printf_precision" in
+                                                            case 
"$gl_cv_func_printf_flag_zero" in
                                                               *yes)
-                                                                case 
"$gl_cv_func_printf_enomem" in
+                                                                case 
"$gl_cv_func_printf_precision" in
                                                                   *yes)
-                                                                    case 
"$gl_cv_func_snprintf_truncation_c99" in
+                                                                    case 
"$gl_cv_func_printf_enomem" in
                                                                       *yes)
-                                                                        case 
"$gl_cv_func_snprintf_retval_c99" in
+                                                                        case 
"$gl_cv_func_snprintf_truncation_c99" in
                                                                           *yes)
-                                                                            
case "$gl_cv_func_snprintf_directive_n" in
+                                                                            
case "$gl_cv_func_snprintf_retval_c99" in
                                                                               
*yes)
-                                                                               
 case "$gl_cv_func_snprintf_size1" in
+                                                                               
 case "$gl_cv_func_snprintf_directive_n" in
                                                                                
   *yes)
-                                                                               
     case "$gl_cv_func_vsnprintf_zerosize_c99" in
+                                                                               
     case "$gl_cv_func_snprintf_size1" in
                                                                                
       *yes)
-                                                                               
         # vsnprintf exists and is
-                                                                               
         # already POSIX compliant.
-                                                                               
         gl_cv_func_vsnprintf_posix=yes
+                                                                               
         case "$gl_cv_func_vsnprintf_zerosize_c99" in
+                                                                               
           *yes)
+                                                                               
             # vsnprintf exists and is
+                                                                               
             # already POSIX compliant.
+                                                                               
             gl_cv_func_vsnprintf_posix=yes
+                                                                               
             ;;
+                                                                               
         esac
                                                                                
         ;;
                                                                                
     esac
                                                                                
     ;;
diff --git a/m4/vsprintf-posix.m4 b/m4/vsprintf-posix.m4
index bc9e19f99a..57c3dd98f8 100644
--- a/m4/vsprintf-posix.m4
+++ b/m4/vsprintf-posix.m4
@@ -1,4 +1,4 @@
-# vsprintf-posix.m4 serial 15
+# vsprintf-posix.m4 serial 16
 dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -19,6 +19,7 @@ AC_DEFUN([gl_FUNC_VSPRINTF_POSIX]
 AC_DEFUN([gl_FUNC_VSPRINTF_IS_POSIX],
 [
   AC_REQUIRE([gl_PRINTF_SIZES_C99])
+  AC_REQUIRE([gl_PRINTF_SIZES_C23])
   AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
   AC_REQUIRE([gl_PRINTF_INFINITE])
   AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
@@ -37,39 +38,43 @@ AC_DEFUN([gl_FUNC_VSPRINTF_IS_POSIX]
   gl_cv_func_vsprintf_posix=no
   case "$gl_cv_func_printf_sizes_c99" in
     *yes)
-      case "$gl_cv_func_printf_long_double" in
+      case "$gl_cv_func_printf_sizes_c23" in
         *yes)
-          case "$gl_cv_func_printf_infinite" in
+          case "$gl_cv_func_printf_long_double" in
             *yes)
-              case "$gl_cv_func_printf_infinite_long_double" in
+              case "$gl_cv_func_printf_infinite" in
                 *yes)
-                  case "$gl_cv_func_printf_directive_a" in
+                  case "$gl_cv_func_printf_infinite_long_double" in
                     *yes)
-                      case "$gl_cv_func_printf_directive_b" in
+                      case "$gl_cv_func_printf_directive_a" in
                         *yes)
-                          case "$gl_cv_func_printf_directive_f" in
+                          case "$gl_cv_func_printf_directive_b" in
                             *yes)
-                              case "$gl_cv_func_printf_directive_n" in
+                              case "$gl_cv_func_printf_directive_f" in
                                 *yes)
-                                  case "$gl_cv_func_printf_directive_ls" in
+                                  case "$gl_cv_func_printf_directive_n" in
                                     *yes)
-                                      case "$gl_cv_func_printf_directive_lc" in
+                                      case "$gl_cv_func_printf_directive_ls" in
                                         *yes)
-                                          case "$gl_cv_func_printf_positions" 
in
+                                          case 
"$gl_cv_func_printf_directive_lc" in
                                             *yes)
-                                              case 
"$gl_cv_func_printf_flag_grouping" in
+                                              case 
"$gl_cv_func_printf_positions" in
                                                 *yes)
-                                                  case 
"$gl_cv_func_printf_flag_leftadjust" in
+                                                  case 
"$gl_cv_func_printf_flag_grouping" in
                                                     *yes)
-                                                      case 
"$gl_cv_func_printf_flag_zero" in
+                                                      case 
"$gl_cv_func_printf_flag_leftadjust" in
                                                         *yes)
-                                                          case 
"$gl_cv_func_printf_precision" in
+                                                          case 
"$gl_cv_func_printf_flag_zero" in
                                                             *yes)
-                                                              case 
"$gl_cv_func_printf_enomem" in
+                                                              case 
"$gl_cv_func_printf_precision" in
                                                                 *yes)
-                                                                  # vsprintf 
exists and is
-                                                                  # already 
POSIX compliant.
-                                                                  
gl_cv_func_vsprintf_posix=yes
+                                                                  case 
"$gl_cv_func_printf_enomem" in
+                                                                    *yes)
+                                                                      # 
vsprintf exists and is
+                                                                      # 
already POSIX compliant.
+                                                                      
gl_cv_func_vsprintf_posix=yes
+                                                                      ;;
+                                                                  esac
                                                                   ;;
                                                               esac
                                                               ;;
diff --git a/modules/c-vasnprintf b/modules/c-vasnprintf
index 35adfbbbdf..7ccd83c82e 100644
--- a/modules/c-vasnprintf
+++ b/modules/c-vasnprintf
@@ -24,6 +24,8 @@ m4/exponentd.m4
 Depends-on:
 assert-h
 attribute
+limits-h
+stdint
 stdio
 isnand-nolibm
 isnanl-nolibm
diff --git a/modules/unistdio/u-printf-args b/modules/unistdio/u-printf-args
index 79b4142d19..f10761f54b 100644
--- a/modules/unistdio/u-printf-args
+++ b/modules/unistdio/u-printf-args
@@ -12,6 +12,8 @@ m4/stdint_h.m4
 m4/inttypes_h.m4
 
 Depends-on:
+stdint
+limits-h
 unitypes
 wchar
 
diff --git a/modules/vasnprintf b/modules/vasnprintf
index 7d40973cdb..c87fe7a106 100644
--- a/modules/vasnprintf
+++ b/modules/vasnprintf
@@ -26,6 +26,7 @@ alloca-opt
 attribute
 float
 free-posix
+limits-h
 stdint
 xsize
 errno
diff --git a/modules/vasnwprintf b/modules/vasnwprintf
index 82eb83675f..82d4aa4668 100644
--- a/modules/vasnwprintf
+++ b/modules/vasnwprintf
@@ -29,6 +29,7 @@ alloca-opt
 attribute
 float
 free-posix
+limits-h
 stdint
 xsize
 errno
diff --git a/tests/test-snprintf-posix.h b/tests/test-snprintf-posix.h
index a8993f947a..bfc8b9914e 100644
--- a/tests/test-snprintf-posix.h
+++ b/tests/test-snprintf-posix.h
@@ -3426,4 +3426,539 @@ test_function (int (*my_snprintf) (char *, size_t, 
const char *, ...))
     ASSERT (strcmp (result, " 33") == 0);
     ASSERT (retval == strlen (result));
   }
+
+  /* Test the support of argument type/size specifiers for signed integer
+     conversions.  */
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%hhd %d", (signed char) -42, 33, 44, 55);
+    ASSERT (strcmp (result, "-42 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%hd %d", (short) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%d %d", -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%ld %d", (long int) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%lld %d", (long long int) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%w8d %d", (int8_t) -42, 33, 44, 55);
+    ASSERT (strcmp (result, "-42 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%w16d %d", (int16_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%w32d %d", (int32_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%w64d %d", (int64_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%wf8d %d", (int_fast8_t) -42, 33, 44, 55);
+    ASSERT (strcmp (result, "-42 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%wf16d %d", (int_fast16_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%wf32d %d", (int_fast32_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%wf64d %d", (int_fast64_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  /* Test the support of argument type/size specifiers for unsigned integer
+     conversions: %u  */
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%hhu %d", (unsigned char) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "42 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%hu %d", (unsigned short) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%u %d", (unsigned int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%lu %d", (unsigned long int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%llu %d", (unsigned long long int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%w8u %d", (uint8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "42 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%w16u %d", (uint16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%w32u %d", (uint32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%w64u %d", (uint64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%wf8u %d", (uint_fast8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "42 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%wf16u %d", (uint_fast16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%wf32u %d", (uint_fast32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%wf64u %d", (uint_fast64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  /* Test the support of argument type/size specifiers for unsigned integer
+     conversions: %b  */
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%hhb %d", (unsigned char) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "101010 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%hb %d", (unsigned short) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%b %d", (unsigned int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%lb %d", (unsigned long int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%llb %d", (unsigned long long int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%w8b %d", (uint8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "101010 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%w16b %d", (uint16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%w32b %d", (uint32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%w64b %d", (uint64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%wf8b %d", (uint_fast8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "101010 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%wf16b %d", (uint_fast16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%wf32b %d", (uint_fast32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%wf64b %d", (uint_fast64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  /* Test the support of argument type/size specifiers for unsigned integer
+     conversions: %o  */
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%hho %d", (unsigned char) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "52 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%ho %d", (unsigned short) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%o %d", (unsigned int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%lo %d", (unsigned long int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%llo %d", (unsigned long long int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%w8o %d", (uint8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "52 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%w16o %d", (uint16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%w32o %d", (uint32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%w64o %d", (uint64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%wf8o %d", (uint_fast8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "52 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%wf16o %d", (uint_fast16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%wf32o %d", (uint_fast32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%wf64o %d", (uint_fast64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  /* Test the support of argument type/size specifiers for unsigned integer
+     conversions: %x  */
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%hhX %d", (unsigned char) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "2A 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%hX %d", (unsigned short) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%X %d", (unsigned int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%lX %d", (unsigned long int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%llX %d", (unsigned long long int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%w8X %d", (uint8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "2A 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%w16X %d", (uint16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%w32X %d", (uint32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%w64X %d", (uint64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%wf8X %d", (uint_fast8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "2A 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%wf16X %d", (uint_fast16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%wf32X %d", (uint_fast32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%wf64X %d", (uint_fast64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
 }
diff --git a/tests/test-sprintf-posix.h b/tests/test-sprintf-posix.h
index 7f280d3c32..d2f0e579ea 100644
--- a/tests/test-sprintf-posix.h
+++ b/tests/test-sprintf-posix.h
@@ -3404,4 +3404,474 @@ test_function (int (*my_sprintf) (char *, const char *, 
...))
     ASSERT (strcmp (result, " 33") == 0);
     ASSERT (retval == strlen (result));
   }
+
+  /* Test the support of argument type/size specifiers for signed integer
+     conversions.  */
+
+  {
+    int retval =
+      my_sprintf (result, "%hhd %d", (signed char) -42, 33, 44, 55);
+    ASSERT (strcmp (result, "-42 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%hd %d", (short) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%d %d", -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%ld %d", (long int) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%lld %d", (long long int) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%w8d %d", (int8_t) -42, 33, 44, 55);
+    ASSERT (strcmp (result, "-42 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%w16d %d", (int16_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%w32d %d", (int32_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%w64d %d", (int64_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%wf8d %d", (int_fast8_t) -42, 33, 44, 55);
+    ASSERT (strcmp (result, "-42 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%wf16d %d", (int_fast16_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%wf32d %d", (int_fast32_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%wf64d %d", (int_fast64_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  /* Test the support of argument type/size specifiers for unsigned integer
+     conversions: %u  */
+
+  {
+    int retval =
+      my_sprintf (result, "%hhu %d", (unsigned char) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "42 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%hu %d", (unsigned short) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%u %d", (unsigned int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%lu %d", (unsigned long int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%llu %d", (unsigned long long int) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%w8u %d", (uint8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "42 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%w16u %d", (uint16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%w32u %d", (uint32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%w64u %d", (uint64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%wf8u %d", (uint_fast8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "42 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%wf16u %d", (uint_fast16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%wf32u %d", (uint_fast32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%wf64u %d", (uint_fast64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  /* Test the support of argument type/size specifiers for unsigned integer
+     conversions: %b  */
+
+  {
+    int retval =
+      my_sprintf (result, "%hhb %d", (unsigned char) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "101010 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%hb %d", (unsigned short) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%b %d", (unsigned int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%lb %d", (unsigned long int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%llb %d", (unsigned long long int) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%w8b %d", (uint8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "101010 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%w16b %d", (uint16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%w32b %d", (uint32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%w64b %d", (uint64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%wf8b %d", (uint_fast8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "101010 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%wf16b %d", (uint_fast16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%wf32b %d", (uint_fast32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%wf64b %d", (uint_fast64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  /* Test the support of argument type/size specifiers for unsigned integer
+     conversions: %o  */
+
+  {
+    int retval =
+      my_sprintf (result, "%hho %d", (unsigned char) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "52 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%ho %d", (unsigned short) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%o %d", (unsigned int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%lo %d", (unsigned long int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%llo %d", (unsigned long long int) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%w8o %d", (uint8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "52 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%w16o %d", (uint16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%w32o %d", (uint32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%w64o %d", (uint64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%wf8o %d", (uint_fast8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "52 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%wf16o %d", (uint_fast16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%wf32o %d", (uint_fast32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%wf64o %d", (uint_fast64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  /* Test the support of argument type/size specifiers for unsigned integer
+     conversions: %x  */
+
+  {
+    int retval =
+      my_sprintf (result, "%hhX %d", (unsigned char) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "2A 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%hX %d", (unsigned short) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%X %d", (unsigned int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%lX %d", (unsigned long int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%llX %d", (unsigned long long int) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%w8X %d", (uint8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "2A 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%w16X %d", (uint16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%w32X %d", (uint32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%w64X %d", (uint64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%wf8X %d", (uint_fast8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "2A 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%wf16X %d", (uint_fast16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%wf32X %d", (uint_fast32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  {
+    int retval =
+      my_sprintf (result, "%wf64X %d", (uint_fast64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
 }
diff --git a/tests/test-vasnprintf-posix.c b/tests/test-vasnprintf-posix.c
index 87f4fc290b..bc71e02156 100644
--- a/tests/test-vasnprintf-posix.c
+++ b/tests/test-vasnprintf-posix.c
@@ -4482,6 +4482,606 @@ test_function (char * (*my_asnprintf) (char *, size_t 
*, const char *, ...))
     free (result);
   }
 
+  /* Test the support of argument type/size specifiers for signed integer
+     conversions.  */
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%hhd %d", (signed char) -42, 33, 44, 55);
+    ASSERT (strcmp (result, "-42 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%hd %d", (short) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%d %d", -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%ld %d", (long int) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%lld %d", (long long int) -12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%w8d %d", (int8_t) -42, 33, 44, 55);
+    ASSERT (strcmp (result, "-42 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%w16d %d", (int16_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%w32d %d", (int32_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%w64d %d", (int64_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%wf8d %d", (int_fast8_t) -42, 33, 44, 55);
+    ASSERT (strcmp (result, "-42 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%wf16d %d", (int_fast16_t) -12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%wf32d %d", (int_fast32_t) -12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%wf64d %d", (int_fast64_t) -12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  /* Test the support of argument type/size specifiers for unsigned integer
+     conversions: %u  */
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%hhu %d", (unsigned char) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "42 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%hu %d", (unsigned short) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%u %d", (unsigned int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%lu %d", (unsigned long int) 12345, 33, 
44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%llu %d", (unsigned long long int) 12345, 
33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%w8u %d", (uint8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "42 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%w16u %d", (uint16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%w32u %d", (uint32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%w64u %d", (uint64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%wf8u %d", (uint_fast8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "42 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%wf16u %d", (uint_fast16_t) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%wf32u %d", (uint_fast32_t) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%wf64u %d", (uint_fast64_t) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  /* Test the support of argument type/size specifiers for unsigned integer
+     conversions: %b  */
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%hhb %d", (unsigned char) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "101010 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%hb %d", (unsigned short) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%b %d", (unsigned int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%lb %d", (unsigned long int) 12345, 33, 
44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%llb %d", (unsigned long long int) 12345, 
33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%w8b %d", (uint8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "101010 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%w16b %d", (uint16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%w32b %d", (uint32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%w64b %d", (uint64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%wf8b %d", (uint_fast8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "101010 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%wf16b %d", (uint_fast16_t) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%wf32b %d", (uint_fast32_t) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%wf64b %d", (uint_fast64_t) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  /* Test the support of argument type/size specifiers for unsigned integer
+     conversions: %o  */
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%hho %d", (unsigned char) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "52 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%ho %d", (unsigned short) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%o %d", (unsigned int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%lo %d", (unsigned long int) 12345, 33, 
44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%llo %d", (unsigned long long int) 12345, 
33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%w8o %d", (uint8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "52 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%w16o %d", (uint16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%w32o %d", (uint32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%w64o %d", (uint64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%wf8o %d", (uint_fast8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "52 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%wf16o %d", (uint_fast16_t) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%wf32o %d", (uint_fast32_t) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%wf64o %d", (uint_fast64_t) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  /* Test the support of argument type/size specifiers for unsigned integer
+     conversions: %x  */
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%hhX %d", (unsigned char) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "2A 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%hX %d", (unsigned short) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%X %d", (unsigned int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%lX %d", (unsigned long int) 12345, 33, 
44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%llX %d", (unsigned long long int) 12345, 
33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%w8X %d", (uint8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "2A 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%w16X %d", (uint16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%w32X %d", (uint32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%w64X %d", (uint64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%wf8X %d", (uint_fast8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "2A 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%wf16X %d", (uint_fast16_t) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%wf32X %d", (uint_fast32_t) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%wf64X %d", (uint_fast64_t) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
 #if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined 
__UCLIBC__
   /* Test that the 'I' flag is supported.  */
   {
diff --git a/tests/test-vasnwprintf-posix.c b/tests/test-vasnwprintf-posix.c
index 49f5f91ebe..f0ecfb082a 100644
--- a/tests/test-vasnwprintf-posix.c
+++ b/tests/test-vasnwprintf-posix.c
@@ -4487,6 +4487,606 @@ test_function (wchar_t * (*my_asnwprintf) (wchar_t *, 
size_t *, const wchar_t *,
     free (result);
   }
 
+  /* Test the support of argument type/size specifiers for signed integer
+     conversions.  */
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%hhd %d", (signed char) -42, 33, 44, 55);
+    ASSERT (wcscmp (result, L"-42 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%hd %d", (short) -12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"-12345 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%d %d", -12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"-12345 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%ld %d", (long int) -12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"-12345 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%lld %d", (long long int) -12345, 33, 
44, 55);
+    ASSERT (wcscmp (result, L"-12345 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%w8d %d", (int8_t) -42, 33, 44, 55);
+    ASSERT (wcscmp (result, L"-42 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%w16d %d", (int16_t) -12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"-12345 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%w32d %d", (int32_t) -12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"-12345 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%w64d %d", (int64_t) -12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"-12345 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%wf8d %d", (int_fast8_t) -42, 33, 44, 
55);
+    ASSERT (wcscmp (result, L"-42 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%wf16d %d", (int_fast16_t) -12345, 33, 
44, 55);
+    ASSERT (wcscmp (result, L"-12345 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%wf32d %d", (int_fast32_t) -12345, 33, 
44, 55);
+    ASSERT (wcscmp (result, L"-12345 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%wf64d %d", (int_fast64_t) -12345, 33, 
44, 55);
+    ASSERT (wcscmp (result, L"-12345 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  /* Test the support of argument type/size specifiers for unsigned integer
+     conversions: %u  */
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%hhu %d", (unsigned char) 42, 33, 44, 
55);
+    ASSERT (wcscmp (result, L"42 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%hu %d", (unsigned short) 12345, 33, 44, 
55);
+    ASSERT (wcscmp (result, L"12345 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%u %d", (unsigned int) 12345, 33, 44, 
55);
+    ASSERT (wcscmp (result, L"12345 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%lu %d", (unsigned long int) 12345, 33, 
44, 55);
+    ASSERT (wcscmp (result, L"12345 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%llu %d", (unsigned long long int) 
12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"12345 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%w8u %d", (uint8_t) 42, 33, 44, 55);
+    ASSERT (wcscmp (result, L"42 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%w16u %d", (uint16_t) 12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"12345 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%w32u %d", (uint32_t) 12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"12345 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%w64u %d", (uint64_t) 12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"12345 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%wf8u %d", (uint_fast8_t) 42, 33, 44, 
55);
+    ASSERT (wcscmp (result, L"42 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%wf16u %d", (uint_fast16_t) 12345, 33, 
44, 55);
+    ASSERT (wcscmp (result, L"12345 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%wf32u %d", (uint_fast32_t) 12345, 33, 
44, 55);
+    ASSERT (wcscmp (result, L"12345 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%wf64u %d", (uint_fast64_t) 12345, 33, 
44, 55);
+    ASSERT (wcscmp (result, L"12345 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  /* Test the support of argument type/size specifiers for unsigned integer
+     conversions: %b  */
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%hhb %d", (unsigned char) 42, 33, 44, 
55);
+    ASSERT (wcscmp (result, L"101010 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%hb %d", (unsigned short) 12345, 33, 44, 
55);
+    ASSERT (wcscmp (result, L"11000000111001 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%b %d", (unsigned int) 12345, 33, 44, 
55);
+    ASSERT (wcscmp (result, L"11000000111001 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%lb %d", (unsigned long int) 12345, 33, 
44, 55);
+    ASSERT (wcscmp (result, L"11000000111001 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%llb %d", (unsigned long long int) 
12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"11000000111001 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%w8b %d", (uint8_t) 42, 33, 44, 55);
+    ASSERT (wcscmp (result, L"101010 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%w16b %d", (uint16_t) 12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"11000000111001 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%w32b %d", (uint32_t) 12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"11000000111001 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%w64b %d", (uint64_t) 12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"11000000111001 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%wf8b %d", (uint_fast8_t) 42, 33, 44, 
55);
+    ASSERT (wcscmp (result, L"101010 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%wf16b %d", (uint_fast16_t) 12345, 33, 
44, 55);
+    ASSERT (wcscmp (result, L"11000000111001 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%wf32b %d", (uint_fast32_t) 12345, 33, 
44, 55);
+    ASSERT (wcscmp (result, L"11000000111001 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%wf64b %d", (uint_fast64_t) 12345, 33, 
44, 55);
+    ASSERT (wcscmp (result, L"11000000111001 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  /* Test the support of argument type/size specifiers for unsigned integer
+     conversions: %o  */
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%hho %d", (unsigned char) 42, 33, 44, 
55);
+    ASSERT (wcscmp (result, L"52 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%ho %d", (unsigned short) 12345, 33, 44, 
55);
+    ASSERT (wcscmp (result, L"30071 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%o %d", (unsigned int) 12345, 33, 44, 
55);
+    ASSERT (wcscmp (result, L"30071 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%lo %d", (unsigned long int) 12345, 33, 
44, 55);
+    ASSERT (wcscmp (result, L"30071 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%llo %d", (unsigned long long int) 
12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"30071 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%w8o %d", (uint8_t) 42, 33, 44, 55);
+    ASSERT (wcscmp (result, L"52 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%w16o %d", (uint16_t) 12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"30071 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%w32o %d", (uint32_t) 12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"30071 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%w64o %d", (uint64_t) 12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"30071 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%wf8o %d", (uint_fast8_t) 42, 33, 44, 
55);
+    ASSERT (wcscmp (result, L"52 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%wf16o %d", (uint_fast16_t) 12345, 33, 
44, 55);
+    ASSERT (wcscmp (result, L"30071 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%wf32o %d", (uint_fast32_t) 12345, 33, 
44, 55);
+    ASSERT (wcscmp (result, L"30071 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%wf64o %d", (uint_fast64_t) 12345, 33, 
44, 55);
+    ASSERT (wcscmp (result, L"30071 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  /* Test the support of argument type/size specifiers for unsigned integer
+     conversions: %x  */
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%hhX %d", (unsigned char) 42, 33, 44, 
55);
+    ASSERT (wcscmp (result, L"2A 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%hX %d", (unsigned short) 12345, 33, 44, 
55);
+    ASSERT (wcscmp (result, L"3039 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%X %d", (unsigned int) 12345, 33, 44, 
55);
+    ASSERT (wcscmp (result, L"3039 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%lX %d", (unsigned long int) 12345, 33, 
44, 55);
+    ASSERT (wcscmp (result, L"3039 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%llX %d", (unsigned long long int) 
12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"3039 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%w8X %d", (uint8_t) 42, 33, 44, 55);
+    ASSERT (wcscmp (result, L"2A 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%w16X %d", (uint16_t) 12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"3039 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%w32X %d", (uint32_t) 12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"3039 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%w64X %d", (uint64_t) 12345, 33, 44, 55);
+    ASSERT (wcscmp (result, L"3039 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%wf8X %d", (uint_fast8_t) 42, 33, 44, 
55);
+    ASSERT (wcscmp (result, L"2A 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%wf16X %d", (uint_fast16_t) 12345, 33, 
44, 55);
+    ASSERT (wcscmp (result, L"3039 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%wf32X %d", (uint_fast32_t) 12345, 33, 
44, 55);
+    ASSERT (wcscmp (result, L"3039 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  {
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%wf64X %d", (uint_fast64_t) 12345, 33, 
44, 55);
+    ASSERT (wcscmp (result, L"3039 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
 #if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined 
__UCLIBC__
   /* Test that the 'I' flag is supported.  */
   {
diff --git a/tests/test-vasprintf-posix.c b/tests/test-vasprintf-posix.c
index 0da0c7441b..6a18413abb 100644
--- a/tests/test-vasprintf-posix.c
+++ b/tests/test-vasprintf-posix.c
@@ -4420,6 +4420,606 @@ test_function (int (*my_asprintf) (char **, const char 
*, ...))
     ASSERT (retval == strlen (result));
     free (result);
   }
+
+  /* Test the support of argument type/size specifiers for signed integer
+     conversions.  */
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%hhd %d", (signed char) -42, 33, 44, 55);
+    ASSERT (strcmp (result, "-42 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%hd %d", (short) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%d %d", -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%ld %d", (long int) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%lld %d", (long long int) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%w8d %d", (int8_t) -42, 33, 44, 55);
+    ASSERT (strcmp (result, "-42 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%w16d %d", (int16_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%w32d %d", (int32_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%w64d %d", (int64_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%wf8d %d", (int_fast8_t) -42, 33, 44, 55);
+    ASSERT (strcmp (result, "-42 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%wf16d %d", (int_fast16_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%wf32d %d", (int_fast32_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%wf64d %d", (int_fast64_t) -12345, 33, 44, 55);
+    ASSERT (strcmp (result, "-12345 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  /* Test the support of argument type/size specifiers for unsigned integer
+     conversions: %u  */
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%hhu %d", (unsigned char) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "42 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%hu %d", (unsigned short) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%u %d", (unsigned int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%lu %d", (unsigned long int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%llu %d", (unsigned long long int) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%w8u %d", (uint8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "42 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%w16u %d", (uint16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%w32u %d", (uint32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%w64u %d", (uint64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%wf8u %d", (uint_fast8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "42 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%wf16u %d", (uint_fast16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%wf32u %d", (uint_fast32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%wf64u %d", (uint_fast64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "12345 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  /* Test the support of argument type/size specifiers for unsigned integer
+     conversions: %b  */
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%hhb %d", (unsigned char) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "101010 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%hb %d", (unsigned short) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%b %d", (unsigned int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%lb %d", (unsigned long int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%llb %d", (unsigned long long int) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%w8b %d", (uint8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "101010 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%w16b %d", (uint16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%w32b %d", (uint32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%w64b %d", (uint64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%wf8b %d", (uint_fast8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "101010 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%wf16b %d", (uint_fast16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%wf32b %d", (uint_fast32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%wf64b %d", (uint_fast64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  /* Test the support of argument type/size specifiers for unsigned integer
+     conversions: %o  */
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%hho %d", (unsigned char) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "52 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%ho %d", (unsigned short) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%o %d", (unsigned int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%lo %d", (unsigned long int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%llo %d", (unsigned long long int) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%w8o %d", (uint8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "52 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%w16o %d", (uint16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%w32o %d", (uint32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%w64o %d", (uint64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%wf8o %d", (uint_fast8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "52 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%wf16o %d", (uint_fast16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%wf32o %d", (uint_fast32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%wf64o %d", (uint_fast64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "30071 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  /* Test the support of argument type/size specifiers for unsigned integer
+     conversions: %x  */
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%hhX %d", (unsigned char) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "2A 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%hX %d", (unsigned short) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%X %d", (unsigned int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%lX %d", (unsigned long int) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%llX %d", (unsigned long long int) 12345, 33, 44, 
55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%w8X %d", (uint8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "2A 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%w16X %d", (uint16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%w32X %d", (uint32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%w64X %d", (uint64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%wf8X %d", (uint_fast8_t) 42, 33, 44, 55);
+    ASSERT (strcmp (result, "2A 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%wf16X %d", (uint_fast16_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%wf32X %d", (uint_fast32_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  {
+    char *result;
+    int retval =
+      my_asprintf (&result, "%wf64X %d", (uint_fast64_t) 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "3039 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
 }
 
 static int






reply via email to

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