SDL: introduce new printf format macros SDL_PRISZu, SDL_PRISZx and SDL_PRISZX

From a6c294410e331b7248e110184764fcf5baeebb64 Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Mon, 13 Jul 2026 21:05:50 +0300
Subject: [PATCH] introduce new printf format macros SDL_PRISZu, SDL_PRISZx and
 SDL_PRISZX

---
 include/SDL3/SDL_stdinc.h                   | 74 +++++++++++++++++++++
 src/joystick/hidapi/SDL_report_descriptor.c |  2 +-
 test/testautomation_stdlib.c                | 38 ++++-------
 3 files changed, 89 insertions(+), 25 deletions(-)

diff --git a/include/SDL3/SDL_stdinc.h b/include/SDL3/SDL_stdinc.h
index a79074f69794d..22dbafb5669a6 100644
--- a/include/SDL3/SDL_stdinc.h
+++ b/include/SDL3/SDL_stdinc.h
@@ -734,6 +734,61 @@ typedef Sint64 SDL_Time;
  * \since This macro is available since SDL 3.2.0.
  */
 #define SDL_PRILLX SDL_PRILL_PREFIX "X"
+
+/**
+ * A printf-formatting string prefix for a `size_t` value.
+ *
+ * This is just the prefix! You probably actually want SDL_PRISZu, SDL_PRISZx,
+ * or SDL_PRISZX instead.
+ *
+ * Use it like this:
+ *
+ * ```c
+ * SDL_Log("There are %" SDL_PRISZ_PREFIX "u bottles of beer on the wall.", bottles);
+ * ```
+ *
+ * \since This macro is available since SDL 3.6.0.
+ */
+#define SDL_PRISZ_PREFIX "z"
+
+/**
+ * A printf-formatting string for a `size_t` value.
+ *
+ * Use it like this:
+ *
+ * ```c
+ * SDL_Log("There are %" SDL_PRISZu " bottles of beer on the wall.", bottles);
+ * ```
+ *
+ * \since This macro is available since SDL 3.6.0.
+ */
+#define SDL_PRISZu SDL_PRISZ_PREFIX "u"
+
+/**
+ * A printf-formatting string for an `size_t` value as lower-case hexadecimal.
+ *
+ * Use it like this:
+ *
+ * ```c
+ * SDL_Log("There are %" SDL_PRISZx " bottles of beer on the wall.", bottles);
+ * ```
+ *
+ * \since This macro is available since SDL 3.6.0.
+ */
+#define SDL_PRISZx SDL_PRISZ_PREFIX "x"
+
+/**
+ * A printf-formatting string for an `size_t` value as upper-case hexadecimal.
+ *
+ * Use it like this:
+ *
+ * ```c
+ * SDL_Log("There are %" SDL_PRISZX " bottles of beer on the wall.", bottles);
+ * ```
+ *
+ * \since This macro is available since SDL 3.6.0.
+ */
+#define SDL_PRISZX SDL_PRISZ_PREFIX "X"
 #endif /* SDL_WIKI_DOCUMENTATION_SECTION */
 
 /* Make sure we have macros for printing width-based integers.
@@ -832,6 +887,25 @@ SDL_COMPILE_TIME_ASSERT(longlong_size64, sizeof(long long) == 8); /* using I64 f
 #ifndef SDL_PRILLX
 #define SDL_PRILLX SDL_PRILL_PREFIX "X"
 #endif
+/* Specifically for `size_t` -- SDL-specific. */
+#if defined(SDL_PLATFORM_CYGWIN)
+#define SDL_PRISZ_PREFIX "z"
+#elif defined(_WIN64)
+#define SDL_PRISZ_PREFIX "I64"
+#elif defined(SDL_PLATFORM_WIN32)
+#define SDL_PRISZ_PREFIX "I32"
+#else
+#define SDL_PRISZ_PREFIX "z"
+#endif
+#ifndef SDL_PRISZu
+#define SDL_PRISZu SDL_PRISZ_PREFIX "u"
+#endif
+#ifndef SDL_PRISZx
+#define SDL_PRISZx SDL_PRISZ_PREFIX "x"
+#endif
+#ifndef SDL_PRISZX
+#define SDL_PRISZX SDL_PRISZ_PREFIX "X"
+#endif
 
 /* Annotations to help code analysis tools */
 #ifdef SDL_WIKI_DOCUMENTATION_SECTION
diff --git a/src/joystick/hidapi/SDL_report_descriptor.c b/src/joystick/hidapi/SDL_report_descriptor.c
index 801c027e039db..56cbe4a03bd2c 100644
--- a/src/joystick/hidapi/SDL_report_descriptor.c
+++ b/src/joystick/hidapi/SDL_report_descriptor.c
@@ -480,7 +480,7 @@ static bool ParseDescriptor(DescriptorContext *ctx, const Uint8 *descriptor, siz
         }
 
 #ifdef DEBUG_DESCRIPTOR
-        SDL_Log("Data: 0x%.2x, size: %d, type: %d, tag: %d", data, (int)size, type, tag);
+        SDL_Log("Data: 0x%.2x, size: %" SDL_PRISZu ", type: %d, tag: %d", data, size, type, tag);
 #endif
         switch (type) {
         case DescriptorItemTypeMain:
diff --git a/test/testautomation_stdlib.c b/test/testautomation_stdlib.c
index ad4e7f969f3bc..fd222183be5fa 100644
--- a/test/testautomation_stdlib.c
+++ b/test/testautomation_stdlib.c
@@ -934,16 +934,6 @@ static int SDLCALL stdlib_sscanf(void *arg)
 #pragma GCC diagnostic pop
 #endif
 
-#if defined(SDL_PLATFORM_CYGWIN)
-#define SIZE_FORMAT "zu"
-#elif defined(_WIN64)
-#define SIZE_FORMAT "I64u"
-#elif defined(SDL_PLATFORM_WIN32)
-#define SIZE_FORMAT "I32u"
-#else
-#define SIZE_FORMAT "zu"
-#endif
-
 /**
  * Call to SDL_aligned_alloc
  */
@@ -953,7 +943,7 @@ static int SDLCALL stdlib_aligned_alloc(void *arg)
     void *ptr;
 
     for (i = 0; i < 2*sizeof(void *); ++i) {
-        SDLTest_AssertPass("Call to SDL_aligned_alloc(%"SIZE_FORMAT")", i);
+        SDLTest_AssertPass("Call to SDL_aligned_alloc(%" SDL_PRISZu ")", i);
         ptr = SDL_aligned_alloc(i, 1);
         if (i < sizeof(void *)) {
             alignment = sizeof(void *);
@@ -961,7 +951,7 @@ static int SDLCALL stdlib_aligned_alloc(void *arg)
             alignment = i;
         }
         SDLTest_AssertCheck(ptr != NULL, "Check output, expected non-NULL, got: %p", ptr);
-        SDLTest_AssertCheck((((size_t)ptr) % alignment) == 0, "Check output, expected aligned pointer, actual offset: %"SIZE_FORMAT, (((size_t)ptr) % alignment));
+        SDLTest_AssertCheck((((size_t)ptr) % alignment) == 0, "Check output, expected aligned pointer, actual offset: %" SDL_PRISZu, (((size_t)ptr) % alignment));
         if (ptr != NULL) {
             SDLTest_AssertPass("Filling memory to alignment value");
             SDL_memset(ptr, 0xAA, alignment);
@@ -1033,14 +1023,14 @@ stdlib_overflow(void *arg)
 
             if (t->status) {
                 SDLTest_AssertCheck(status,
-                                    "(%" SIZE_FORMAT " * %" SIZE_FORMAT ") should succeed",
+                                    "(%" SDL_PRISZu " * %" SDL_PRISZu ") should succeed",
                                     t->a, t->b);
                 SDLTest_AssertCheck(result == t->result,
-                                    "(%" SIZE_FORMAT " * %" SIZE_FORMAT "): expected %" SIZE_FORMAT ", got %" SIZE_FORMAT,
+                                    "(%" SDL_PRISZu " * %" SDL_PRISZu "): expected %" SDL_PRISZu ", got %" SDL_PRISZu,
                                     t->a, t->b, t->result, result);
             } else {
                 SDLTest_AssertCheck(!status,
-                                    "(%" SIZE_FORMAT " * %" SIZE_FORMAT ") should fail",
+                                    "(%" SDL_PRISZu " * %" SDL_PRISZu ") should fail",
                                     t->a, t->b);
             }
 
@@ -1058,14 +1048,14 @@ stdlib_overflow(void *arg)
 
             if (t->status) {
                 SDLTest_AssertCheck(status,
-                                    "(%" SIZE_FORMAT " * %" SIZE_FORMAT ") should succeed",
+                                    "(%" SDL_PRISZu " * %" SDL_PRISZu ") should succeed",
                                     t->b, t->a);
                 SDLTest_AssertCheck(result == t->result,
-                                    "(%" SIZE_FORMAT " * %" SIZE_FORMAT "): expected %" SIZE_FORMAT ", got %" SIZE_FORMAT,
+                                    "(%" SDL_PRISZu " * %" SDL_PRISZu "): expected %" SDL_PRISZu ", got %" SDL_PRISZu,
                                     t->b, t->a, t->result, result);
             } else {
                 SDLTest_AssertCheck(!status,
-                                    "(%" SIZE_FORMAT " * %" SIZE_FORMAT ") should fail",
+                                    "(%" SDL_PRISZu " * %" SDL_PRISZu ") should fail",
                                     t->b, t->a);
             }
         }
@@ -1083,14 +1073,14 @@ stdlib_overflow(void *arg)
 
             if (t->status) {
                 SDLTest_AssertCheck(status,
-                                    "(%" SIZE_FORMAT " + %" SIZE_FORMAT ") should succeed",
+                                    "(%" SDL_PRISZu " + %" SDL_PRISZu ") should succeed",
                                     t->a, t->b);
                 SDLTest_AssertCheck(result == t->result,
-                                    "(%" SIZE_FORMAT " + %" SIZE_FORMAT "): expected %" SIZE_FORMAT ", got %" SIZE_FORMAT,
+                                    "(%" SDL_PRISZu " + %" SDL_PRISZu "): expected %" SDL_PRISZu ", got %" SDL_PRISZu,
                                     t->a, t->b, t->result, result);
             } else {
                 SDLTest_AssertCheck(!status,
-                                    "(%" SIZE_FORMAT " + %" SIZE_FORMAT ") should fail",
+                                    "(%" SDL_PRISZu " + %" SDL_PRISZu ") should fail",
                                     t->a, t->b);
             }
 
@@ -1108,14 +1098,14 @@ stdlib_overflow(void *arg)
 
             if (t->status) {
                 SDLTest_AssertCheck(status,
-                                    "(%" SIZE_FORMAT " + %" SIZE_FORMAT ") should succeed",
+                                    "(%" SDL_PRISZu " + %" SDL_PRISZu ") should succeed",
                                     t->b, t->a);
                 SDLTest_AssertCheck(result == t->result,
-                                    "(%" SIZE_FORMAT " + %" SIZE_FORMAT "): expected %" SIZE_FORMAT ", got %" SIZE_FORMAT,
+                                    "(%" SDL_PRISZu " + %" SDL_PRISZu "): expected %" SDL_PRISZu ", got %" SDL_PRISZu,
                                     t->b, t->a, t->result, result);
             } else {
                 SDLTest_AssertCheck(!status,
-                                    "(%" SIZE_FORMAT " + %" SIZE_FORMAT ") should fail",
+                                    "(%" SDL_PRISZu " + %" SDL_PRISZu ") should fail",
                                     t->b, t->a);
             }
         }