mirror of
https://github.com/Ryujinx/SDL.git
synced 2025-05-10 23:12:17 +00:00
Added support for "%[]" sscanf syntax
Fixes https://github.com/libsdl-org/SDL/issues/8423 (cherry picked from commit 39a961ba41430788774f1b8c0e6d63f7308116e7)
This commit is contained in:
parent
3823ba1ded
commit
4194a902e8
|
@ -1114,6 +1114,39 @@ int SDL_vsscanf(const char *text, const char *fmt, va_list ap)
|
||||||
return vsscanf(text, fmt, ap);
|
return vsscanf(text, fmt, ap);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
static SDL_bool CharacterMatchesSet(char c, const char *set, size_t set_len)
|
||||||
|
{
|
||||||
|
SDL_bool invert = SDL_FALSE;
|
||||||
|
SDL_bool result = SDL_FALSE;
|
||||||
|
|
||||||
|
if (*set == '^') {
|
||||||
|
invert = SDL_TRUE;
|
||||||
|
++set;
|
||||||
|
--set_len;
|
||||||
|
}
|
||||||
|
while (set_len > 0 && !result) {
|
||||||
|
if (set_len >= 3 && set[1] == '-') {
|
||||||
|
char low_char = SDL_min(set[0], set[2]);
|
||||||
|
char high_char = SDL_max(set[0], set[2]);
|
||||||
|
if (c >= low_char && c <= high_char) {
|
||||||
|
result = SDL_TRUE;
|
||||||
|
}
|
||||||
|
set += 3;
|
||||||
|
set_len -= 3;
|
||||||
|
} else {
|
||||||
|
if (c == *set) {
|
||||||
|
result = SDL_TRUE;
|
||||||
|
}
|
||||||
|
++set;
|
||||||
|
--set_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (invert) {
|
||||||
|
result = result ? SDL_FALSE : SDL_TRUE;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* NOLINTNEXTLINE(readability-non-const-parameter) */
|
/* NOLINTNEXTLINE(readability-non-const-parameter) */
|
||||||
int SDL_vsscanf(const char *text, const char *fmt, va_list ap)
|
int SDL_vsscanf(const char *text, const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
|
@ -1387,6 +1420,44 @@ int SDL_vsscanf(const char *text, const char *fmt, va_list ap)
|
||||||
}
|
}
|
||||||
done = SDL_TRUE;
|
done = SDL_TRUE;
|
||||||
break;
|
break;
|
||||||
|
case '[':
|
||||||
|
{
|
||||||
|
const char *set = fmt + 1;
|
||||||
|
while (*fmt && *fmt != ']') {
|
||||||
|
++fmt;
|
||||||
|
}
|
||||||
|
if (*fmt) {
|
||||||
|
size_t set_len = (fmt - set);
|
||||||
|
if (suppress) {
|
||||||
|
while (CharacterMatchesSet(*text, set, set_len)) {
|
||||||
|
++text;
|
||||||
|
if (count) {
|
||||||
|
if (--count == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SDL_bool had_match = SDL_FALSE;
|
||||||
|
char *valuep = va_arg(ap, char *);
|
||||||
|
while (CharacterMatchesSet(*text, set, set_len)) {
|
||||||
|
had_match = SDL_TRUE;
|
||||||
|
*valuep++ = *text++;
|
||||||
|
if (count) {
|
||||||
|
if (--count == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*valuep = '\0';
|
||||||
|
if (had_match) {
|
||||||
|
++retval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
done = SDL_TRUE;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
done = SDL_TRUE;
|
done = SDL_TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -351,7 +351,7 @@ int stdlib_sscanf(void *arg)
|
||||||
long long_output, expected_long_output;
|
long long_output, expected_long_output;
|
||||||
long long long_long_output, expected_long_long_output;
|
long long long_long_output, expected_long_long_output;
|
||||||
size_t size_output, expected_size_output;
|
size_t size_output, expected_size_output;
|
||||||
char text[128];
|
char text[128], text2[128];
|
||||||
|
|
||||||
expected_output = output = 123;
|
expected_output = output = 123;
|
||||||
expected_result = -1;
|
expected_result = -1;
|
||||||
|
@ -415,6 +415,82 @@ int stdlib_sscanf(void *arg)
|
||||||
SDLTest_AssertCheck(expected_size_output == size_output, "Check output, expected: %zu, got: %zu", expected_size_output, size_output);
|
SDLTest_AssertCheck(expected_size_output == size_output, "Check output, expected: %zu, got: %zu", expected_size_output, size_output);
|
||||||
SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
|
SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
|
||||||
|
|
||||||
|
expected_result = 1;
|
||||||
|
text[0] = '\0';
|
||||||
|
result = SDL_sscanf("abc def", "%s", text);
|
||||||
|
SDLTest_AssertPass("Call to SDL_sscanf(\"abc def\", \"%%s\", text)");
|
||||||
|
SDLTest_AssertCheck(SDL_strcmp(text, "abc") == 0, "Check output, expected: \"abc\", got: \"%s\"", text);
|
||||||
|
SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
|
||||||
|
|
||||||
|
expected_result = 1;
|
||||||
|
text[0] = '\0';
|
||||||
|
result = SDL_sscanf("abc,def", "%s", text);
|
||||||
|
SDLTest_AssertPass("Call to SDL_sscanf(\"abc,def\", \"%%s\", text)");
|
||||||
|
SDLTest_AssertCheck(SDL_strcmp(text, "abc,def") == 0, "Check output, expected: \"abc\", got: \"%s\"", text);
|
||||||
|
SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
|
||||||
|
|
||||||
|
expected_result = 1;
|
||||||
|
text[0] = '\0';
|
||||||
|
result = SDL_sscanf("abc,def", "%[cba]", text);
|
||||||
|
SDLTest_AssertPass("Call to SDL_sscanf(\"abc,def\", \"%%[cba]\", text)");
|
||||||
|
SDLTest_AssertCheck(SDL_strcmp(text, "abc") == 0, "Check output, expected: \"abc\", got: \"%s\"", text);
|
||||||
|
SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
|
||||||
|
|
||||||
|
expected_result = 1;
|
||||||
|
text[0] = '\0';
|
||||||
|
result = SDL_sscanf("abc,def", "%[a-z]", text);
|
||||||
|
SDLTest_AssertPass("Call to SDL_sscanf(\"abc,def\", \"%%[z-a]\", text)");
|
||||||
|
SDLTest_AssertCheck(SDL_strcmp(text, "abc") == 0, "Check output, expected: \"abc\", got: \"%s\"", text);
|
||||||
|
SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
|
||||||
|
|
||||||
|
expected_result = 1;
|
||||||
|
text[0] = '\0';
|
||||||
|
result = SDL_sscanf("abc,def", "%[^,]", text);
|
||||||
|
SDLTest_AssertPass("Call to SDL_sscanf(\"abc,def\", \"%%[^,]\", text)");
|
||||||
|
SDLTest_AssertCheck(SDL_strcmp(text, "abc") == 0, "Check output, expected: \"abc\", got: \"%s\"", text);
|
||||||
|
SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
|
||||||
|
|
||||||
|
expected_result = 0;
|
||||||
|
text[0] = '\0';
|
||||||
|
result = SDL_sscanf("abc,def", "%[A-Z]", text);
|
||||||
|
SDLTest_AssertPass("Call to SDL_sscanf(\"abc,def\", \"%%[A-Z]\", text)");
|
||||||
|
SDLTest_AssertCheck(SDL_strcmp(text, "") == 0, "Check output, expected: \"\", got: \"%s\"", text);
|
||||||
|
SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
|
||||||
|
|
||||||
|
expected_result = 2;
|
||||||
|
text[0] = '\0';
|
||||||
|
text2[0] = '\0';
|
||||||
|
result = SDL_sscanf("abc,def", "%[abc],%[def]", text, text2);
|
||||||
|
SDLTest_AssertPass("Call to SDL_sscanf(\"abc,def\", \"%%[abc],%%[def]\", text)");
|
||||||
|
SDLTest_AssertCheck(SDL_strcmp(text, "abc") == 0, "Check output, expected: \"abc\", got: \"%s\"", text);
|
||||||
|
SDLTest_AssertCheck(SDL_strcmp(text2, "def") == 0, "Check output, expected: \"def\", got: \"%s\"", text2);
|
||||||
|
SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
|
||||||
|
|
||||||
|
expected_result = 2;
|
||||||
|
text[0] = '\0';
|
||||||
|
text2[0] = '\0';
|
||||||
|
result = SDL_sscanf("abc,def", "%[abc]%*[,]%[def]", text, text2);
|
||||||
|
SDLTest_AssertPass("Call to SDL_sscanf(\"abc,def\", \"%%[abc]%%*[,]%%[def]\", text)");
|
||||||
|
SDLTest_AssertCheck(SDL_strcmp(text, "abc") == 0, "Check output, expected: \"abc\", got: \"%s\"", text);
|
||||||
|
SDLTest_AssertCheck(SDL_strcmp(text2, "def") == 0, "Check output, expected: \"def\", got: \"%s\"", text2);
|
||||||
|
SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
|
||||||
|
|
||||||
|
expected_result = 2;
|
||||||
|
text[0] = '\0';
|
||||||
|
text2[0] = '\0';
|
||||||
|
result = SDL_sscanf("abc def", "%[abc] %[def]", text, text2);
|
||||||
|
SDLTest_AssertPass("Call to SDL_sscanf(\"abc def\", \"%%[abc] %%[def]\", text)");
|
||||||
|
SDLTest_AssertCheck(SDL_strcmp(text, "abc") == 0, "Check output, expected: \"abc\", got: \"%s\"", text);
|
||||||
|
SDLTest_AssertCheck(SDL_strcmp(text2, "def") == 0, "Check output, expected: \"def\", got: \"%s\"", text2);
|
||||||
|
SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
|
||||||
|
|
||||||
|
expected_result = 1;
|
||||||
|
text[0] = '\0';
|
||||||
|
result = SDL_sscanf("abc123XYZ", "%[a-zA-Z0-9]", text);
|
||||||
|
SDLTest_AssertPass("Call to SDL_sscanf(\"abc123XYZ\", \"%%[a-zA-Z0-9]\", text)");
|
||||||
|
SDLTest_AssertCheck(SDL_strcmp(text, "abc123XYZ") == 0, "Check output, expected: \"abc123XYZ\", got: \"%s\"", text);
|
||||||
|
SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
|
||||||
|
|
||||||
return TEST_COMPLETED;
|
return TEST_COMPLETED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue