* Similar to standard strstr() but we ignore case in this version. * Based on the strstr() implementation further below. */
| 287 | * Based on the strstr() implementation further below. |
| 288 | */ |
| 289 | AP_DECLARE(char *) ap_strcasestr(const char *s1, const char *s2) |
| 290 | { |
| 291 | char *p1, *p2; |
| 292 | if (*s2 == '\0') { |
| 293 | /* an empty s2 */ |
| 294 | return((char *)s1); |
| 295 | } |
| 296 | while(1) { |
| 297 | for ( ; (*s1 != '\0') && (apr_tolower(*s1) != apr_tolower(*s2)); s1++); |
| 298 | if (*s1 == '\0') { |
| 299 | return(NULL); |
| 300 | } |
| 301 | /* found first character of s2, see if the rest matches */ |
| 302 | p1 = (char *)s1; |
| 303 | p2 = (char *)s2; |
| 304 | for (++p1, ++p2; apr_tolower(*p1) == apr_tolower(*p2); ++p1, ++p2) { |
| 305 | if (*p1 == '\0') { |
| 306 | /* both strings ended together */ |
| 307 | return((char *)s1); |
| 308 | } |
| 309 | } |
| 310 | if (*p2 == '\0') { |
| 311 | /* second string ended, a match */ |
| 312 | break; |
| 313 | } |
| 314 | /* didn't find a match here, try starting at next character in s1 */ |
| 315 | s1++; |
| 316 | } |
| 317 | return((char *)s1); |
| 318 | } |
| 319 | |
| 320 | /* |
| 321 | * Returns an offsetted pointer in bigstring immediately after |
no outgoing calls
no test coverage detected