Skip to content

Commit

Permalink
Added SDL_strnstr()
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed Dec 3, 2023
1 parent 7c71e72 commit 81cec43
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 9 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1065,7 +1065,7 @@ if(SDL_LIBC)
realloc rindex round roundf
scalbn scalbnf setenv sin sinf sqr sqrt sqrtf sscanf strchr
strcmp strlcat strlcpy strlen strncmp strnlen
strrchr strstr strtod strtok_r strtol strtoll strtoul strtoull
strrchr strnstr strstr strtod strtok_r strtol strtoll strtoul strtoull
tan tanf trunc truncf
unsetenv
vsnprintf vsscanf
Expand Down
1 change: 1 addition & 0 deletions include/SDL3/SDL_stdinc.h
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,7 @@ extern DECLSPEC char *SDLCALL SDL_strupr(char *str);
extern DECLSPEC char *SDLCALL SDL_strlwr(char *str);
extern DECLSPEC char *SDLCALL SDL_strchr(const char *str, int c);
extern DECLSPEC char *SDLCALL SDL_strrchr(const char *str, int c);
extern DECLSPEC char *SDLCALL SDL_strnstr(const char *haystack, const char *needle, size_t maxlen);
extern DECLSPEC char *SDLCALL SDL_strstr(const char *haystack, const char *needle);
extern DECLSPEC char *SDLCALL SDL_strcasestr(const char *haystack, const char *needle);
extern DECLSPEC char *SDLCALL SDL_strtok_r(char *s1, const char *s2, char **saveptr);
Expand Down
1 change: 1 addition & 0 deletions include/build_config/SDL_build_config.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
#cmakedefine HAVE_RINDEX 1
#cmakedefine HAVE_STRCHR 1
#cmakedefine HAVE_STRRCHR 1
#cmakedefine HAVE_STRNSTR 1
#cmakedefine HAVE_STRSTR 1
#cmakedefine HAVE_STRTOK_R 1
#cmakedefine HAVE_ITOA 1
Expand Down
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi.sym
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,7 @@ SDL3_0.0.0 {
SDL_GetGamepadMappings;
SDL_GetTouchDevices;
SDL_GetTouchDeviceName;
SDL_strnstr;
# extra symbols go here (don't modify this line)
local: *;
};
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi_overrides.h
Original file line number Diff line number Diff line change
Expand Up @@ -985,3 +985,4 @@
#define SDL_GetGamepadMappings SDL_GetGamepadMappings_REAL
#define SDL_GetTouchDevices SDL_GetTouchDevices_REAL
#define SDL_GetTouchDeviceName SDL_GetTouchDeviceName_REAL
#define SDL_strnstr SDL_strnstr_REAL
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi_procs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1010,3 +1010,4 @@ SDL_DYNAPI_PROC(SDL_Renderer*,SDL_CreateRendererWithProperties,(SDL_PropertiesID
SDL_DYNAPI_PROC(char**,SDL_GetGamepadMappings,(int *a),(a),return)
SDL_DYNAPI_PROC(SDL_TouchID*,SDL_GetTouchDevices,(int *a),(a),return)
SDL_DYNAPI_PROC(const char*,SDL_GetTouchDeviceName,(SDL_TouchID a),(a),return)
SDL_DYNAPI_PROC(char*,SDL_strnstr,(const char *a, const char *b, size_t c),(a,b,c),return)
21 changes: 17 additions & 4 deletions src/stdlib/SDL_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -821,22 +821,35 @@ char *SDL_strrchr(const char *string, int c)
#endif /* HAVE_STRRCHR */
}

char *SDL_strstr(const char *haystack, const char *needle)
char *SDL_strnstr(const char *haystack, const char *needle, size_t maxlen)
{
#ifdef HAVE_STRSTR
return SDL_const_cast(char *, strstr(haystack, needle));
#ifdef HAVE_STRNSTR
return SDL_const_cast(char *, strnstr(haystack, needle, maxlen));
#else
size_t length = SDL_strlen(needle);
while (*haystack) {
if (length == 0) {
return (char *)haystack;
}
while (maxlen >= length && *haystack) {
if (SDL_strncmp(haystack, needle, length) == 0) {
return (char *)haystack;
}
++haystack;
--maxlen;
}
return NULL;
#endif /* HAVE_STRSTR */
}

char *SDL_strstr(const char *haystack, const char *needle)
{
#ifdef HAVE_STRSTR
return SDL_const_cast(char *, strstr(haystack, needle));
#else
return SDL_strnstr(haystack, needle, SDL_strlen(haystack));
#endif /* HAVE_STRSTR */
}

char *SDL_strcasestr(const char *haystack, const char *needle)
{
#ifdef HAVE_STRCASESTR
Expand Down
75 changes: 71 additions & 4 deletions test/testautomation_stdlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,68 @@ static int stdlib_strlcpy(void *arg)
return TEST_COMPLETED;
}

/**
* Call to SDL_strstr
*/
static int stdlib_strstr(void *arg)
{
char *result;
const char *text = "abcdef";
const char *expected;

result = SDL_strstr(text, "");
expected = text;
SDLTest_AssertPass("Call to SDL_strstr(text, \"\")");
SDLTest_AssertCheck(result == expected, "Check result, expected: %s, got: %s", expected, result);

result = SDL_strstr(text, "abc");
expected = text;
SDLTest_AssertPass("Call to SDL_strstr(text, \"abc\")");
SDLTest_AssertCheck(result == expected, "Check result, expected: %s, got: %s", expected, result);

result = SDL_strstr(text, "bcd");
expected = text+1;
SDLTest_AssertPass("Call to SDL_strstr(text, \"bcd\")");
SDLTest_AssertCheck(result == expected, "Check result, expected: %s, got: %s", expected, result);

result = SDL_strstr(text, "xyz");
expected = NULL;
SDLTest_AssertPass("Call to SDL_strstr(text, \"xyz\")");
SDLTest_AssertCheck(result == expected, "Check result, expected: (null), got: %s", result);

result = SDL_strnstr(text, "", SDL_strlen(text));
expected = text;
SDLTest_AssertPass("Call to SDL_strnstr(text, \"\", SDL_strlen(text))");
SDLTest_AssertCheck(result == expected, "Check result, expected: %s, got: %s", expected, result);

result = SDL_strnstr(text, "abc", SDL_strlen(text));
expected = text;
SDLTest_AssertPass("Call to SDL_strnstr(text, \"abc\", SDL_strlen(text))");
SDLTest_AssertCheck(result == expected, "Check result, expected: %s, got: %s", expected, result);

result = SDL_strnstr(text, "bcd", SDL_strlen(text));
expected = text+1;
SDLTest_AssertPass("Call to SDL_strnstr(text, \"bcd\", SDL_strlen(text))");
SDLTest_AssertCheck(result == expected, "Check result, expected: %s, got: %s", expected, result);

result = SDL_strnstr(text, "bcd", 3);
expected = NULL;
SDLTest_AssertPass("Call to SDL_strnstr(text, \"bcd\", 3)");
SDLTest_AssertCheck(result == expected, "Check result, expected: (null), got: %s", result);

result = SDL_strnstr(text, "xyz", 3);
expected = NULL;
SDLTest_AssertPass("Call to SDL_strnstr(text, \"xyz\", 3)");
SDLTest_AssertCheck(result == expected, "Check result, expected: (null), got: %s", result);

result = SDL_strnstr(text, "xyz", SDL_strlen(text)*100000);
expected = NULL;
SDLTest_AssertPass("Call to SDL_strnstr(text, \"xyz\", SDL_strlen(text)*100000)");
SDLTest_AssertCheck(result == expected, "Check result, expected: (null), got: %s", result);

return TEST_COMPLETED;
}

#if defined(HAVE_WFORMAT) || defined(HAVE_WFORMAT_EXTRA_ARGS)
#pragma GCC diagnostic push
#ifdef HAVE_WFORMAT
Expand Down Expand Up @@ -930,22 +992,26 @@ static const SDLTest_TestCaseReference stdlibTest2 = {
};

static const SDLTest_TestCaseReference stdlibTest3 = {
stdlib_snprintf, "stdlib_snprintf", "Call to SDL_snprintf", TEST_ENABLED
stdlib_strstr, "stdlib_strstr", "Call to SDL_strstr", TEST_ENABLED
};

static const SDLTest_TestCaseReference stdlibTest4 = {
stdlib_swprintf, "stdlib_swprintf", "Call to SDL_swprintf", TEST_ENABLED
stdlib_snprintf, "stdlib_snprintf", "Call to SDL_snprintf", TEST_ENABLED
};

static const SDLTest_TestCaseReference stdlibTest5 = {
stdlib_getsetenv, "stdlib_getsetenv", "Call to SDL_getenv and SDL_setenv", TEST_ENABLED
stdlib_swprintf, "stdlib_swprintf", "Call to SDL_swprintf", TEST_ENABLED
};

static const SDLTest_TestCaseReference stdlibTest6 = {
stdlib_sscanf, "stdlib_sscanf", "Call to SDL_sscanf", TEST_ENABLED
stdlib_getsetenv, "stdlib_getsetenv", "Call to SDL_getenv and SDL_setenv", TEST_ENABLED
};

static const SDLTest_TestCaseReference stdlibTest7 = {
stdlib_sscanf, "stdlib_sscanf", "Call to SDL_sscanf", TEST_ENABLED
};

static const SDLTest_TestCaseReference stdlibTest8 = {
stdlib_aligned_alloc, "stdlib_aligned_alloc", "Call to SDL_aligned_alloc", TEST_ENABLED
};

Expand All @@ -962,6 +1028,7 @@ static const SDLTest_TestCaseReference *stdlibTests[] = {
&stdlibTest5,
&stdlibTest6,
&stdlibTest7,
&stdlibTest8,
&stdlibTestOverflow,
NULL
};
Expand Down

0 comments on commit 81cec43

Please sign in to comment.