- needle++;
- for (;; haystack++)
- {
- if (*haystack == '\0')
- /* No match. */
- return NULL;
-
- /* See whether it's advisable to use an asymptotically faster
- algorithm. */
- if (try_kmp
- && outer_loop_count >= 10
- && comparison_count >= 5 * outer_loop_count)
- {
- /* See if needle + comparison_count now reaches the end of
- needle. */
- if (needle_last_ccount != NULL)
- {
- needle_last_ccount +=
- strnlen (needle_last_ccount, comparison_count - last_ccount);
- if (*needle_last_ccount == '\0')
- needle_last_ccount = NULL;
- last_ccount = comparison_count;
- }
- if (needle_last_ccount == NULL)
- {
- /* Try the Knuth-Morris-Pratt algorithm. */
- const char *result;
- bool success =
- knuth_morris_pratt_unibyte (haystack, needle - 1, &result);
- if (success)
- return (char *) result;
- try_kmp = false;
- }
- }
-
- outer_loop_count++;
- comparison_count++;
- if (c_tolower ((unsigned char) *haystack) == b)
- /* The first character matches. */
- {
- const char *rhaystack = haystack + 1;
- const char *rneedle = needle;
-
- for (;; rhaystack++, rneedle++)
- {
- if (*rneedle == '\0')
- /* Found a match. */
- return (char *) haystack;
- if (*rhaystack == '\0')
- /* No match. */
- return NULL;
- comparison_count++;
- if (c_tolower ((unsigned char) *rhaystack)
- != c_tolower ((unsigned char) *rneedle))
- /* Nothing in this round. */
- break;
- }
- }
- }
- }
- else
- return (char *) haystack;
+ /* Perform the search. Abstract memory is considered to be an array
+ of 'unsigned char' values, not an array of 'char' values. See
+ ISO C 99 section 6.2.6.1. */
+ if (needle_len < LONG_NEEDLE_THRESHOLD)
+ return two_way_short_needle ((const unsigned char *) haystack,
+ haystack_len,
+ (const unsigned char *) needle_start,
+ needle_len);
+ return two_way_long_needle ((const unsigned char *) haystack, haystack_len,
+ (const unsigned char *) needle_start,
+ needle_len);