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>
#include <grub/i18n.h>
#include <grub/types.h>
#include <grub/charset.h>
+#include <stddef.h>
union printf_arg
{
COMPILE_TIME_ASSERT (sizeof (long) <= sizeof (long long));
COMPILE_TIME_ASSERT (sizeof (long long) == 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;
while ((c = *fmt++) != 0)
fmt++;
c = *fmt++;
+ if (c == 'z')
+ {
+ c = *fmt++;
+ goto do_count;
+ }
if (c == 'l')
c = *fmt++;
if (c == 'l')
c = *fmt++;
+ do_count:
switch (c)
{
case 'p':
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')
{
c = *fmt++;
}
c = *fmt++;
+ if (c == 'z')
+ c = *fmt++;
if (c == 'l')
c = *fmt++;
if (c == 'l')