diff --git a/include/string.h b/include/string.h index abaf80e7d..b19f44e31 100644 --- a/include/string.h +++ b/include/string.h @@ -81,6 +81,7 @@ void __fastcall__ bzero (void* ptr, size_t n); /* BSD */ char* __fastcall__ strdup (const char* s); /* SYSV/BSD */ int __fastcall__ stricmp (const char* s1, const char* s2); /* DOS/Windows */ int __fastcall__ strcasecmp (const char* s1, const char* s2); /* Same for Unix */ +char* __fastcall__ strcasestr (const char* str, const char* substr); int __fastcall__ strnicmp (const char* s1, const char* s2, size_t count); /* DOS/Windows */ int __fastcall__ strncasecmp (const char* s1, const char* s2, size_t count); /* Same for Unix */ size_t __fastcall__ strnlen (const char* s, size_t maxlen); /* POSIX.1-2008 */ diff --git a/libsrc/common/strcasestr.c b/libsrc/common/strcasestr.c new file mode 100644 index 000000000..693b43a37 --- /dev/null +++ b/libsrc/common/strcasestr.c @@ -0,0 +1,36 @@ +/* +** strcasestr.c +** +** Colin Leroy-Mira, 2024 +*/ + + + +#include +#include +#include + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +char* __fastcall__ strcasestr(const char *str, const char *substr) { + size_t len_a = strlen(str); + size_t len_b = strlen(substr); + const char *end_str; + + if (len_a < len_b) + return NULL; + + len_a -= len_b; + + for (end_str = str + len_a + 1; str < end_str; str++) { + if (!strncasecmp(str, substr, len_b)) + return (char *)str; + } + return NULL; +} diff --git a/test/val/strstr-test.c b/test/val/strstr-test.c new file mode 100644 index 000000000..5c8a147b0 --- /dev/null +++ b/test/val/strstr-test.c @@ -0,0 +1,41 @@ +#include +#include +#include + +int fails = 0; + +#define STRSTR_TEST(needle,expected) \ + if (strstr(haystack, (needle)) != (expected)) { \ + printf("strstr failure: expected %p for \"%s\", " \ + "got %p\n", \ + expected, needle, strstr(haystack, (needle)));\ + fails++; \ + } + +#define STRCASESTR_TEST(needle,expected) \ + if (strcasestr(haystack, (needle)) != (expected)) { \ + printf("strcasestr failure: expected %p for \"%s\", " \ + "got %p\n", \ + expected, needle, strcasestr(haystack, (needle)));\ + fails++; \ + } + +int main (void) +{ + const char *haystack = "This is a string to search in"; + + STRSTR_TEST("This is", haystack + 0); + STRSTR_TEST("a string", haystack + 8); + STRSTR_TEST("This is a string to search in", haystack); + STRSTR_TEST("search in", haystack + 20); + STRSTR_TEST("This is a string to search in with extra chars", NULL); + STRSTR_TEST("nowhere", NULL); + + STRCASESTR_TEST("this is", haystack + 0); + STRCASESTR_TEST("a STRING", haystack + 8); + STRCASESTR_TEST("this is a string TO search in", haystack); + STRCASESTR_TEST("This is a string to search in with extra chars", NULL); + STRCASESTR_TEST("search IN", haystack + 20); + + return fails; +}