SDL: Added SDL_strcasestr() for a case insensitive version of SDL_strstr()

From 297ecb706d89a78448ebd07f813ebbfa94aae556 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 5 Nov 2022 15:58:30 -0700
Subject: [PATCH] Added SDL_strcasestr() for a case insensitive version of
 SDL_strstr()

---
 include/SDL_stdinc.h              |  1 +
 src/dynapi/SDL2.exports           |  1 +
 src/dynapi/SDL_dynapi_overrides.h |  1 +
 src/dynapi/SDL_dynapi_procs.h     |  1 +
 src/stdlib/SDL_string.c           | 17 +++++++++++++++++
 5 files changed, 21 insertions(+)

diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h
index 06233c013fa0..70dba7db6950 100644
--- a/include/SDL_stdinc.h
+++ b/include/SDL_stdinc.h
@@ -583,6 +583,7 @@ 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_strstr(const char *haystack, const char *needle);
+extern DECLSPEC char *SDLCALL SDL_strcasestr(const char *haystack, const char *needle);
 extern DECLSPEC char *SDLCALL SDL_strtokr(char *s1, const char *s2, char **saveptr);
 extern DECLSPEC size_t SDLCALL SDL_utf8strlen(const char *str);
 extern DECLSPEC size_t SDLCALL SDL_utf8strnlen(const char *str, size_t bytes);
diff --git a/src/dynapi/SDL2.exports b/src/dynapi/SDL2.exports
index 8cc0c617bb61..5085bffd9451 100644
--- a/src/dynapi/SDL2.exports
+++ b/src/dynapi/SDL2.exports
@@ -866,3 +866,4 @@
 ++'_SDL_GameControllerGetSensorDataWithTimestamp'.'SDL2.dll'.'SDL_GameControllerGetSensorDataWithTimestamp'
 ++'_SDL_SensorGetDataWithTimestamp'.'SDL2.dll'.'SDL_SensorGetDataWithTimestamp'
 ++'_SDL_ResetHints'.'SDL2.dll'.'SDL_ResetHints'
+++'_SDL_strcasestr'.'SDL2.dll'.'SDL_strcasestr'
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index d5d782f34192..586465276208 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -892,3 +892,4 @@
 #define SDL_GameControllerGetSensorDataWithTimestamp SDL_GameControllerGetSensorDataWithTimestamp_REAL
 #define SDL_SensorGetDataWithTimestamp SDL_SensorGetDataWithTimestamp_REAL
 #define SDL_ResetHints SDL_ResetHints_REAL
+#define SDL_strcasestr SDL_strcasestr_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index 435ccb46a012..7b3e02da11d9 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -975,3 +975,4 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_HasPrimarySelectionText,(void),(),return)
 SDL_DYNAPI_PROC(int,SDL_GameControllerGetSensorDataWithTimestamp,(SDL_GameController *a, SDL_SensorType b, Uint64 *c, float *d, int e),(a,b,c,d,e),return)
 SDL_DYNAPI_PROC(int,SDL_SensorGetDataWithTimestamp,(SDL_Sensor *a, Uint64 *b, float *c, int d),(a,b,c,d),return)
 SDL_DYNAPI_PROC(void,SDL_ResetHints,(void),(),)
+SDL_DYNAPI_PROC(char*,SDL_strcasestr,(const char *a, const char *b),(a,b),return)
diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c
index 06ff885474d3..ec632b7a6b28 100644
--- a/src/stdlib/SDL_string.c
+++ b/src/stdlib/SDL_string.c
@@ -761,6 +761,23 @@ SDL_strstr(const char *haystack, const char *needle)
 #endif /* HAVE_STRSTR */
 }
 
+char *
+SDL_strcasestr(const char *haystack, const char *needle)
+{
+#if defined(HAVE_STRCASESTR)
+    return SDL_const_cast(char*,strcasestr(haystack, needle));
+#else
+    size_t length = SDL_strlen(needle);
+    while (*haystack) {
+        if (SDL_strncasecmp(haystack, needle, length) == 0) {
+            return (char *) haystack;
+        }
+        ++haystack;
+    }
+    return NULL;
+#endif /* HAVE_STRCASESTR */
+}
+
 #if !defined(HAVE__LTOA) || !defined(HAVE__I64TOA) || \
     !defined(HAVE__ULTOA) || !defined(HAVE__UI64TOA)
 static const char ntoa_table[] = {