Import from Linux support for printing buffers as a hex string
with a certain separator. For larger buffers consider using
print_hex_dump(). Examples:

  %*ph  00 01 02  ...  3f
  %*phC 00:01:02: ... :3f
  %*phD 00-01-02- ... -3f
  %*phN 000102 ... 3f

Signed-off-by: Ahmad Fatoum <[email protected]>
---
 lib/Kconfig    |  3 +++
 lib/vsprintf.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)

diff --git a/lib/Kconfig b/lib/Kconfig
index 718033e56e64..27e7bea6852f 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -166,6 +166,9 @@ config PRINTF_UUID
 config PRINTF_WCHAR
        bool
 
+config PRINTF_HEXSTR
+       bool
+
 config GENERIC_LIB_ASHLDI3
        bool
 
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 85147e8d2e25..ce92787c58ef 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -320,6 +320,52 @@ char *uuid_string(char *buf, const char *end, const u8 
*addr, int field_width,
        return string(buf, end, uuid, field_width, precision, flags);
 }
 
+static noinline_for_stack
+char *hex_string(char *buf, const char *end, const u8 *addr, int field_width,
+                int precision, int flags, const char *fmt)
+{
+       char separator;
+       int i, len;
+
+       if (field_width == 0)
+               /* nothing to print */
+               return buf;
+
+       switch (fmt[1]) {
+       case 'C':
+               separator = ':';
+               break;
+       case 'D':
+               separator = '-';
+               break;
+       case 'N':
+               separator = 0;
+               break;
+       default:
+               separator = ' ';
+               break;
+       }
+
+       len = field_width > 0 ? field_width : 1;
+
+       for (i = 0; i < len; ++i) {
+               if (buf < end)
+                       *buf = hex_asc_hi(addr[i]);
+               ++buf;
+               if (buf < end)
+                       *buf = hex_asc_lo(addr[i]);
+               ++buf;
+
+               if (separator && i != len - 1) {
+                       if (buf < end)
+                               *buf = separator;
+                       ++buf;
+               }
+       }
+
+       return buf;
+}
+
 static noinline_for_stack
 char *address_val(char *buf, const char *end, const void *addr,
                  int field_width, int precision, int flags, const char *fmt)
@@ -406,6 +452,10 @@ static char *pointer(const char *fmt, char *buf, const 
char *end, const void *pt
                break;
        case 'e':
                return error_string(buf, end, ptr, field_width, precision, 
flags, fmt);
+       case 'h':
+               if (IS_ENABLED(CONFIG_PRINTF_HEXSTR))
+                       return hex_string(buf, end, ptr, field_width, 
precision, flags, fmt);
+               break;
        }
 
        return raw_pointer(buf, end, ptr, field_width, precision, flags);
-- 
2.30.2


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox

Reply via email to