6192: Allow translations to reorder string substitutions r=Robyt3 a=heinrich5991

This is supported on Windows
(https://docs.microsoft.com/en-us/cpp/c-runtime-library/printf-p-positional-parameters) and on POSIX, so basically everywhere.

Add some tests to verify that the target system does indeed support these positional parameters.

(cherry picked from commit ddd2b93190)

## Checklist

- [ ] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


Co-authored-by: heinrich5991 <heinrich5991@gmail.com>
This commit is contained in:
bors[bot] 2022-12-25 22:03:08 +00:00 committed by GitHub
commit 4f02f6da97
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 2 deletions

View file

@ -116,7 +116,7 @@ void log_log_impl(LEVEL level, bool have_color, LOG_COLOR color, const char *sys
#pragma GCC diagnostic ignored "-Wformat-nonliteral" #pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif #endif
#if defined(CONF_FAMILY_WINDOWS) #if defined(CONF_FAMILY_WINDOWS)
_vsnprintf(pMessage, MessageSize, fmt, args); _vsprintf_p(pMessage, MessageSize, fmt, args);
#else #else
vsnprintf(pMessage, MessageSize, fmt, args); vsnprintf(pMessage, MessageSize, fmt, args);
#endif #endif

View file

@ -2657,7 +2657,7 @@ int str_format(char *buffer, int buffer_size, const char *format, ...)
#if defined(CONF_FAMILY_WINDOWS) #if defined(CONF_FAMILY_WINDOWS)
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
_vsnprintf(buffer, buffer_size, format, ap); _vsprintf_p(buffer, buffer_size, format, ap);
va_end(ap); va_end(ap);
buffer[buffer_size - 1] = 0; /* assure null termination */ buffer[buffer_size - 1] = 0; /* assure null termination */

View file

@ -217,6 +217,27 @@ TEST(Str, Endswith)
str_length(ABCDEFG) - str_length(DEFG)); str_length(ABCDEFG) - str_length(DEFG));
} }
TEST(StrFormat, Positional)
{
char aBuf[256];
// normal
str_format(aBuf, sizeof(aBuf), "%s %s", "first", "second");
EXPECT_STREQ(aBuf, "first second");
// normal with positional arguments
str_format(aBuf, sizeof(aBuf), "%1$s %2$s", "first", "second");
EXPECT_STREQ(aBuf, "first second");
// reverse
str_format(aBuf, sizeof(aBuf), "%2$s %1$s", "first", "second");
EXPECT_STREQ(aBuf, "second first");
// duplicate
str_format(aBuf, sizeof(aBuf), "%1$s %1$s %2$d %1$s %2$d", "str", 1);
EXPECT_STREQ(aBuf, "str str 1 str 1");
}
TEST(Str, EndswithNocase) TEST(Str, EndswithNocase)
{ {
EXPECT_TRUE(str_endswith_nocase("abcdef", "deF")); EXPECT_TRUE(str_endswith_nocase("abcdef", "deF"));