20320 STRPBRK
20330 STRCSPN
20340 STRSPN
+ 20350 STRCASESTR
*/
#endif
+/*---------------------- strcasestr ----------------------*/
+
+#define STRCASESTR(soname, fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
+ (void* haystack, void* needle); \
+ void* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
+ (void* haystack, void* needle) \
+ { \
+ extern int tolower(int); \
+ UChar* h = (UChar*)haystack; \
+ UChar* n = (UChar*)needle; \
+ \
+ /* find the length of n, not including terminating zero */ \
+ UWord nlen = 0; \
+ while (n[nlen]) nlen++; \
+ \
+ /* if n is the empty string, match immediately. */ \
+ if (nlen == 0) return h; \
+ \
+ /* assert(nlen >= 1); */ \
+ UChar n0 = tolower(n[0]); \
+ \
+ while (1) { \
+ UChar hh = tolower(*h); \
+ if (hh == 0) return NULL; \
+ if (hh != n0) { h++; continue; } \
+ \
+ UWord i; \
+ for (i = 0; i < nlen; i++) { \
+ if (tolower(n[i]) != tolower(h[i])) \
+ break; \
+ } \
+ /* assert(i >= 0 && i <= nlen); */ \
+ if (i == nlen) \
+ return h; \
+ \
+ h++; \
+ } \
+ }
+
+#if defined(VGO_linux)
+ STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
+
+#elif defined(VGO_darwin)
+
+#endif
+
+
/*------------------------------------------------------------*/
/*--- Improve definedness checking of process environment ---*/
/*------------------------------------------------------------*/
check(strncasecmp("ADC", "abcd", 2) > 0, 20);
}
+static void
+test_strcasestr (void)
+{
+ it = "strcasestr";
+ check(strcasestr("abCd", "z") == NULL, 1); /* Not found. */
+ check(strcasestr("AbcD", "abX") == NULL, 2); /* Dead end. */
+ (void) strcpy(one, "abCd");
+ check(strcasestr(one, "c") == one+2, 3); /* Basic test. */
+ check(strcasestr(one, "Bc") == one+1, 4); /* Multichar. */
+ check(strcasestr(one, "d") == one+3, 5); /* End of string. */
+ check(strcasestr(one, "Cd") == one+2, 6); /* Tail of string. */
+ check(strcasestr(one, "aBc") == one, 7); /* Beginning. */
+ check(strcasestr(one, "aBcd") == one, 8); /* Exact match. */
+ check(strcasestr(one, "AbcDe") == NULL, 9); /* Too long. */
+ check(strcasestr(one, "dE") == NULL, 10); /* Past end. */
+ check(strcasestr(one, "") == one, 11); /* Finding empty. */
+ (void) strcpy(one, "abAba");
+ check(strcasestr(one, "Ba") == one+1, 12); /* Finding first. */
+ (void) strcpy(one, "");
+ check(strcasestr(one, "b") == NULL, 13); /* Empty string. */
+ check(strcasestr(one, "") == one, 14); /* Empty in empty string. */
+ (void) strcpy(one, "BcbCa");
+ check(strcasestr(one, "bCa") == one+2, 15); /* False start. */
+ (void) strcpy(one, "bbBcaBbcA");
+ check(strcasestr(one, "bbCa") == one+1, 16); /* With overlap. */
+}
+
int
main (void)
{
/* strncasecmp. Without locale dependencies. */
test_strncasecmp ();
+ test_strcasestr ();
+
if (errors == 0)
{
status = EXIT_SUCCESS;