[prev in list] [next in list] [prev in thread] [next in thread] 

List:       grub-devel
Subject:    [PATCH v8 03/10] kern/misc: Add a format specifier GUIDs
From:       Oliver Steffen <osteffen () redhat ! com>
Date:       2023-05-24 14:55:51
Message-ID: 20230524145558.2219878-4-osteffen () redhat ! com
[Download RAW message or body]

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 <osteffen@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..22b7dca42 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 *)(grub_addr_t) curarg;
+	      write_number (str, &count, max_len, 8, 0, '0', 'x', guid->data1);
+	      write_char (str, &count, max_len, '-');
+	      write_number (str, &count, max_len, 4, 0, '0', 'x', guid->data2);
+	      write_char (str, &count, max_len, '-');
+	      write_number (str, &count, max_len, 4, 0, '0', 'x', 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

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic