SDL: Implemented left-justification in SDL_PrintString()

From f59d66f4b1f99ae61a3e776933eda7ccdbc1ab0a Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 4 Aug 2024 19:21:06 -0700
Subject: [PATCH] Implemented left-justification in SDL_PrintString()

Fixes https://github.com/libsdl-org/SDL/issues/10310
---
 src/stdlib/SDL_string.c      | 26 +++++++++++++++++---------
 test/testautomation_stdlib.c | 12 ++++++++++++
 2 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c
index cd6cd1868c04c..b477979a5db60 100644
--- a/src/stdlib/SDL_string.c
+++ b/src/stdlib/SDL_string.c
@@ -1796,7 +1796,7 @@ typedef enum
 
 typedef struct
 {
-    SDL_bool left_justify; /* for now: ignored. */
+    SDL_bool left_justify;
     SDL_bool force_sign;
     SDL_bool force_type; /* for now: used only by float printer, ignored otherwise. */
     SDL_bool pad_zeroes;
@@ -1808,6 +1808,9 @@ typedef struct
 
 static size_t SDL_PrintString(char *text, size_t maxlen, SDL_FormatInfo *info, const char *string)
 {
+    const char fill = (info && info->pad_zeroes) ? '0' : ' ';
+    size_t width = 0;
+    size_t filllen = 0;
     size_t length = 0;
     size_t slen, sz;
 
@@ -1817,24 +1820,29 @@ static size_t SDL_PrintString(char *text, size_t maxlen, SDL_FormatInfo *info, c
 
     sz = SDL_strlen(string);
     if (info && info->width > 0 && (size_t)info->width > sz) {
-        const char fill = info->pad_zeroes ? '0' : ' ';
-        size_t width = info->width - sz;
-        size_t filllen;
-
+        width = info->width - sz;
         if (info->precision >= 0 && (size_t)info->precision < sz) {
             width += sz - (size_t)info->precision;
         }
 
         filllen = SDL_min(width, maxlen);
-        SDL_memset(text, fill, filllen);
-        text += filllen;
-        maxlen -= filllen;
-        length += width;
+        if (!info->left_justify) {
+            SDL_memset(text, fill, filllen);
+            text += filllen;
+            maxlen -= filllen;
+            length += width;
+            filllen = 0;
+        }
     }
 
     SDL_strlcpy(text, string, maxlen);
     length += sz;
 
+    if (filllen > 0) {
+        SDL_memset(text + sz, fill, filllen);
+        length += width;
+    }
+
     if (info) {
         if (info->precision >= 0 && (size_t)info->precision < sz) {
             slen = (size_t)info->precision;
diff --git a/test/testautomation_stdlib.c b/test/testautomation_stdlib.c
index d7072f03c6c0d..44a0907264019 100644
--- a/test/testautomation_stdlib.c
+++ b/test/testautomation_stdlib.c
@@ -150,6 +150,18 @@ static int stdlib_snprintf(void *arg)
     SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text);
     SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int)SDL_strlen(text), result);
 
+    result = SDL_snprintf(text, sizeof(text), "%10sA", "foo");
+    expected = "       fooA";
+    SDLTest_AssertPass("Call to SDL_snprintf(\"%%10sA\", \"foo\")");
+    SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text);
+    SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int)SDL_strlen(text), result);
+
+    result = SDL_snprintf(text, sizeof(text), "%-10sA", "foo");
+    expected = "foo       A";
+    SDLTest_AssertPass("Call to SDL_snprintf(\"%%-10sA\", \"foo\")");
+    SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text);
+    SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int)SDL_strlen(text), result);
+
     result = SDL_snprintf(text, sizeof(text), "%S", L"foo");
     expected = "foo";
     SDLTest_AssertPass("Call to SDL_snprintf(\"%%S\", \"foo\")");