kern/misc: Add the "z" length modifier support

Add support for the "z" length modifier in the printf code. This allows
printing of size_t and ssize_t values using %zu, %zd and related
formats. The parser maps "z" to the correct integer width based on
sizeof(size_t).

Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Neal Gompa <ngompa13@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
Michael Chang 2025-10-17 17:01:32 +08:00 committed by Daniel Kiper
parent 91ddada642
commit 3c9762b12f

View File

@ -26,6 +26,7 @@
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/types.h> #include <grub/types.h>
#include <grub/charset.h> #include <grub/charset.h>
#include <stddef.h>
union printf_arg union printf_arg
{ {
@ -832,6 +833,9 @@ parse_printf_arg_fmt (const char *fmt0, struct printf_args *args,
COMPILE_TIME_ASSERT (sizeof (long) <= sizeof (long long)); COMPILE_TIME_ASSERT (sizeof (long) <= sizeof (long long));
COMPILE_TIME_ASSERT (sizeof (long long) == sizeof (void *) COMPILE_TIME_ASSERT (sizeof (long long) == sizeof (void *)
|| sizeof (int) == sizeof (void *)); || sizeof (int) == sizeof (void *));
COMPILE_TIME_ASSERT (sizeof (size_t) == sizeof (unsigned)
|| sizeof (size_t) == sizeof (unsigned long)
|| sizeof (size_t) == sizeof (unsigned long long));
fmt = fmt0; fmt = fmt0;
while ((c = *fmt++) != 0) while ((c = *fmt++) != 0)
@ -866,11 +870,17 @@ parse_printf_arg_fmt (const char *fmt0, struct printf_args *args,
fmt++; fmt++;
c = *fmt++; c = *fmt++;
if (c == 'z')
{
c = *fmt++;
goto do_count;
}
if (c == 'l') if (c == 'l')
c = *fmt++; c = *fmt++;
if (c == 'l') if (c == 'l')
c = *fmt++; c = *fmt++;
do_count:
switch (c) switch (c)
{ {
case 'p': case 'p':
@ -967,6 +977,14 @@ parse_printf_arg_fmt (const char *fmt0, struct printf_args *args,
continue; continue;
} }
if (c == 'z')
{
c = *fmt++;
if (sizeof (size_t) == sizeof (unsigned long))
longfmt = 1;
else if (sizeof (size_t) == sizeof (unsigned long long))
longfmt = 2;
}
if (c == 'l') if (c == 'l')
{ {
c = *fmt++; c = *fmt++;
@ -1143,6 +1161,8 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0,
} }
c = *fmt++; c = *fmt++;
if (c == 'z')
c = *fmt++;
if (c == 'l') if (c == 'l')
c = *fmt++; c = *fmt++;
if (c == 'l') if (c == 'l')