feat(dlog): support binary unsigned integer format specifiers

Binary format specifiers for unsigned integers (`%b` and `%B`) are added
in C23, so we might as well support them as well for completeness.

Change-Id: I5bf0ecb4c1be6549194cb0c67bf3985ecd026c59
Signed-off-by: Karl Meakin <karl.meakin@arm.com>
diff --git a/src/dlog.c b/src/dlog.c
index ac4445b..5a12327 100644
--- a/src/dlog.c
+++ b/src/dlog.c
@@ -32,6 +32,7 @@
 /* clang-format on */
 
 enum format_base {
+	base2 = 2,
 	base8 = 8,
 	base10 = 10,
 	base16 = 16,
@@ -180,8 +181,8 @@
 static size_t print_int(size_t value, enum format_base base, size_t min_width,
 			struct format_flags flags)
 {
-	static const char *digits_lower = "0123456789abcdefx";
-	static const char *digits_upper = "0123456789ABCDEFX";
+	static const char *digits_lower = "0123456789abcdefxb";
+	static const char *digits_upper = "0123456789ABCDEFXB";
 	const char *digits = flags.upper ? digits_upper : digits_lower;
 	char buf[DLOG_MAX_STRING_LENGTH];
 	char *ptr = &buf[sizeof(buf) - 1];
@@ -205,6 +206,12 @@
 			ptr[1] = digits[16];
 			break;
 
+		case base2:
+			ptr -= 2;
+			ptr[0] = '0';
+			ptr[1] = digits[17];
+			break;
+
 		case base8:
 			ptr--;
 			*ptr = '0';
@@ -464,6 +471,25 @@
 				break;
 			}
 
+			case 'b':
+				fmt++;
+				value = va_arg(args, uint64_t);
+				value = reinterpret_unsigned_int(length, value);
+
+				chars_written += print_int(value, base2,
+							   min_width, flags);
+				break;
+
+			case 'B':
+				fmt++;
+				flags.upper = true;
+				value = va_arg(args, uint64_t);
+				value = reinterpret_unsigned_int(length, value);
+
+				chars_written += print_int(value, base2,
+							   min_width, flags);
+				break;
+
 			case 'o':
 				fmt++;
 				value = va_arg(args, uint64_t);