Extend the printf format specifier for pointers (%p) to accept a suffix specifier G to print GUIDs: %pG can be used to print grub_guid structs. This does not interfere with the -Wformat checking of gcc. Note that the data type is not checked though (%p accepts void*).
Signed-off-by: Oliver Steffen <ostef...@redhat.com> --- grub-core/kern/misc.c | 81 ++++++++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 21 deletions(-) diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index dfae4f9d7..eadb46988 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -24,6 +24,7 @@ #include <grub/term.h> #include <grub/env.h> #include <grub/i18n.h> +#include <grub/types.h> union printf_arg { @@ -34,7 +35,8 @@ union printf_arg { INT, LONG, LONGLONG, UNSIGNED_INT = 3, UNSIGNED_LONG, UNSIGNED_LONGLONG, - STRING + STRING, + GUID } type; long long ll; }; @@ -772,6 +774,9 @@ parse_printf_arg_fmt (const char *fmt0, struct printf_args *args, switch (c) { case 'p': + if (*(fmt) == 'G') + ++fmt; + /* Fall through. */ case 'x': case 'X': case 'u': @@ -885,6 +890,10 @@ parse_printf_arg_fmt (const char *fmt0, struct printf_args *args, args->ptr[curn].type = UNSIGNED_LONGLONG; else args->ptr[curn].type = UNSIGNED_INT; + if (*(fmt) == 'G') { + args->ptr[curn].type = GUID; + ++fmt; + } break; case 's': args->ptr[curn].type = STRING; @@ -926,6 +935,7 @@ parse_printf_args (const char *fmt0, struct printf_args *args, va_list args_in) args->ptr[n].ll = va_arg (args_in, long long); break; case STRING: + case GUID: if (sizeof (void *) == sizeof (long long)) args->ptr[n].ll = va_arg (args_in, long long); else @@ -943,6 +953,27 @@ write_char (char *str, grub_size_t *count, grub_size_t max_len, unsigned char ch (*count)++; } +static void +write_number (char *str, grub_size_t *count, grub_size_t max_len, grub_size_t format1, + char rightfill, char zerofill, char c, long long value) +{ + char tmp[32]; + const char *p = tmp; + grub_size_t len; + grub_size_t fill; + + len = grub_lltoa (tmp, c, value) - tmp; + fill = len < format1 ? format1 - len : 0; + if (! rightfill) + while (fill--) + write_char (str, count, max_len, zerofill); + while (*p) + write_char (str, count, max_len, *p++); + if (rightfill) + while (fill--) + write_char (str, count, max_len, zerofill); +} + static int grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, struct printf_args *args) @@ -1025,31 +1056,39 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, switch (c) { case 'p': - write_char (str, &count, max_len, '0'); - write_char (str, &count, max_len, 'x'); - c = 'x'; + if (*(fmt) == 'G') + { + ++fmt; + grub_guid_t *guid = (grub_guid_t *) curarg; + write_number (str, &count, max_len, 8, 0, '0', 'x', grub_le_to_cpu32 (guid->data1)); + write_char (str, &count, max_len, '-'); + write_number (str, &count, max_len, 4, 0, '0', 'x', grub_le_to_cpu16 (guid->data2)); + write_char (str, &count, max_len, '-'); + write_number (str, &count, max_len, 4, 0, '0', 'x', grub_le_to_cpu16 (guid->data3)); + write_char (str, &count, max_len, '-'); + write_number (str, &count, max_len, 2, 0, '0', 'x', guid->data4[0]); + write_number (str, &count, max_len, 2, 0, '0', 'x', guid->data4[1]); + write_char (str, &count, max_len, '-'); + write_number (str, &count, max_len, 2, 0, '0', 'x', guid->data4[2]); + write_number (str, &count, max_len, 2, 0, '0', 'x', guid->data4[3]); + write_number (str, &count, max_len, 2, 0, '0', 'x', guid->data4[4]); + write_number (str, &count, max_len, 2, 0, '0', 'x', guid->data4[5]); + write_number (str, &count, max_len, 2, 0, '0', 'x', guid->data4[6]); + write_number (str, &count, max_len, 2, 0, '0', 'x', guid->data4[7]); + break; + } + else + { + write_char (str, &count, max_len, '0'); + write_char (str, &count, max_len, 'x'); + c = 'x'; + } /* Fall through. */ case 'x': case 'X': case 'u': case 'd': - { - char tmp[32]; - const char *p = tmp; - grub_size_t len; - grub_size_t fill; - - len = grub_lltoa (tmp, c, curarg) - tmp; - fill = len < format1 ? format1 - len : 0; - if (! rightfill) - while (fill--) - write_char (str, &count, max_len, zerofill); - while (*p) - write_char (str, &count, max_len, *p++); - if (rightfill) - while (fill--) - write_char (str, &count, max_len, zerofill); - } + write_number (str, &count, max_len, format1, rightfill, zerofill, c, curarg); break; case 'c': -- 2.40.1 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel