feat(string): add GNU strcasestr at level 3
Case-insensitive ASCII-fold substring search, locale-free, no allocation. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <[email protected]>
This commit is contained in:
@@ -0,0 +1,59 @@
|
|||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fold an ASCII uppercase letter to lowercase; every other character
|
||||||
|
* (including NUL) passes through unchanged. Kept local and locale-free:
|
||||||
|
* strcasestr must never depend on ctype tables or the active locale.
|
||||||
|
*/
|
||||||
|
static inline char
|
||||||
|
fold_ascii(char c)
|
||||||
|
{
|
||||||
|
if (c >= 'A' && c <= 'Z')
|
||||||
|
{
|
||||||
|
return (char)(c + ('a' - 'A'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a pointer to the first case-insensitive (ASCII fold) occurrence of
|
||||||
|
* needle in haystack, or NULL if absent. An empty needle matches haystack.
|
||||||
|
*
|
||||||
|
* Naive two-pointer scan: for each position in haystack, compare folded
|
||||||
|
* characters until the needle is exhausted (match) or a mismatch occurs
|
||||||
|
* (advance). The inner loop stops at the NUL terminator of either string,
|
||||||
|
* so the comparison never reads past the end of haystack when needle is
|
||||||
|
* longer than the remaining tail.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
strcasestr(const char *haystack, const char *needle) // NOLINT(bugprone-easily-swappable-parameters)
|
||||||
|
{
|
||||||
|
if (*needle == '\0')
|
||||||
|
{
|
||||||
|
return (char *)haystack;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; *haystack != '\0'; haystack++)
|
||||||
|
{
|
||||||
|
const char *h = haystack;
|
||||||
|
const char *n = needle;
|
||||||
|
|
||||||
|
while (*n != '\0' && fold_ascii(*h) == fold_ascii(*n))
|
||||||
|
{
|
||||||
|
h++;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*n == '\0')
|
||||||
|
{
|
||||||
|
return (char *)haystack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user