/* This function is equivalent to strcasestr() for multibyte strings, * except in that it scans the string in reverse, starting at rev_start. */ char *mbrevstrcasestr(const char *haystack, const char *needle, const char *rev_start) { #ifdef ENABLE_UTF8 if (use_utf8) { size_t rev_start_len, needle_len; if (*needle == '\0') return (char *)rev_start; needle_len = mbstrlen(needle); if (mbstrlen(haystack) < needle_len) return NULL; rev_start_len = mbstrlen(rev_start); while (TRUE) { if (rev_start_len >= needle_len && mbstrncasecmp(rev_start, needle, needle_len) == 0) return (char *)rev_start; /* If we've reached the head of the haystack, we found nothing. */ if (rev_start == haystack) return NULL; rev_start = haystack + move_mbleft(haystack, rev_start - haystack); rev_start_len++; } } else #endif return revstrcasestr(haystack, needle, rev_start); }
/* This function is equivalent to strcasestr() for multibyte strings, * except in that it scans the string in reverse, starting at * rev_start. */ char *mbrevstrcasestr(const char *haystack, const char *needle, const char *rev_start) { #ifdef ENABLE_UTF8 if (use_utf8) { bool begin_line = FALSE; size_t rev_start_len, needle_len; assert(haystack != NULL && needle != NULL && rev_start != NULL); if (*needle == '\0') return (char *)rev_start; needle_len = mbstrlen(needle); if (mbstrlen(haystack) < needle_len) return NULL; rev_start_len = mbstrlen(rev_start); while (!begin_line) { if (rev_start_len >= needle_len && mbstrncasecmp(rev_start, needle, needle_len) == 0 && mblen(rev_start, MB_CUR_MAX) > 0) return (char *)rev_start; if (rev_start == haystack) begin_line = TRUE; else { rev_start = haystack + move_mbleft(haystack, rev_start - haystack); rev_start_len++; } } return NULL; } else #endif return revstrcasestr(haystack, needle, rev_start); }