@@ -31,6 +31,7 @@
Â
 #define RETURN_TYPE void *
 #define AVAILABLE(h, h_l, j, n_l) ((j) <= (h_l) - (n_l))
+#define FASTSEARCH(S,C,N) (void*) memchr ((void *)(S), (C), (N))
 #include "str-two-way.h"
Â
 #undef memmem
@@ -281,50 +281,50 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
    }
  else
    {
-Â Â Â Â Â const unsigned char *phaystack = &haystack[suffix];
+Â Â Â Â Â const unsigned char *phaystack;
      /* The comparison always starts from needle[suffix], so cache it
         and use an optimized first-character loop. */
      unsigned char needle_suffix = CANON_ELEMENT (needle[suffix]);
Â
-#if CHECK_EOL
-Â Â Â Â Â /* We start matching from the SUFFIX'th element, so make sure we
-       don't hit '\0' before that. */
-Â Â Â Â Â if (haystack_len < suffix + 1
-Â Â Â Â Â Â Â Â && !AVAILABLE (haystack, haystack_len, 0, suffix + 1))
-Â Â Â Â Â Â return NULL;
-#endif
-
      /* The two halves of needle are distinct; no extra memory is
         required, and any mismatch results in a maximal shift. */
      period = MAX (suffix, needle_len - suffix) + 1;
      j = 0;
-Â Â Â Â Â while (1
-#if !CHECK_EOL
-Â Â Â Â Â Â Â Â Â Â Â && AVAILABLE (haystack, haystack_len, j, needle_len)
-#endif
-Â Â Â Â Â Â Â Â Â Â Â )
+Â Â Â Â Â while (AVAILABLE (haystack, haystack_len, j, needle_len))
        {
          unsigned char haystack_char;
          const unsigned char *pneedle;
Â
-Â Â Â Â Â Â Â Â /* TODO: The first-character loop can be sped up by adapting
-           longword-at-a-time implementation of memchr/strchr. */
-Â Â Â Â Â Â Â Â if (needle_suffix
+Â Â Â Â Â Â Â Â phaystack = &haystack[suffix + j];
+
+#ifdef FASTSEARCH
+Â Â Â Â Â Â Â Â if (*phaystack++ != needle_suffix)
+Â Â Â Â Â Â Â Â Â Â {
+Â Â Â Â Â Â Â Â Â Â Â Â phaystack = FASTSEARCH (phaystack, needle_suffix,
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â haystack_len - needle_len - j);
+Â Â Â Â Â Â Â Â Â Â Â Â if (phaystack == NULL)
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â goto ret0;
+Â Â Â Â Â Â Â Â Â Â Â Â j = phaystack - &haystack[suffix];
+Â Â Â Â Â Â Â Â Â Â Â Â phaystack++;
+Â Â Â Â Â Â Â Â Â Â }
+#else
+Â Â Â Â Â Â Â Â while (needle_suffix
              != (haystack_char = CANON_ELEMENT (*phaystack++)))
            {
              RET0_IF_0 (haystack_char);
-#if !CHECK_EOL
+# if !CHECK_EOL
              ++j;
-#endif
-Â Â Â Â Â Â Â Â Â Â Â Â continue;
+Â Â Â Â Â Â Â Â Â Â Â Â if (!AVAILABLE (haystack, haystack_len, j, needle_len))
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â goto ret0;
+# endif
            }
Â
-#if CHECK_EOL
+# if CHECK_EOL
          /* Calculate J if it wasn't kept up-to-date in the first-character
             loop. */
          j = phaystack - &haystack[suffix] - 1;
+# endif
 #endif
-
          /* Scan for matches in right half. */
          i = suffix + 1;
          pneedle = &needle[i];
@@ -338,6 +338,11 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
                }
              ++i;
            }
+#if CHECK_EOL
+        /* Update minimal length of haystack. */
+Â Â Â Â Â Â Â Â if (phaystack > haystack + haystack_len)
+Â Â Â Â Â Â Â Â Â Â haystack_len = phaystack - haystack;
+#endif
          if (needle_len <= i)
            {
              /* Scan for matches in left half. */
@@ -360,13 +365,6 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
            }
          else
            j += i - suffix + 1;
-
-#if CHECK_EOL
-Â Â Â Â Â Â Â Â if (!AVAILABLE (haystack, haystack_len, j, needle_len))
-Â Â Â Â Â Â Â Â Â Â break;
-#endif
-
-Â Â Â Â Â Â Â Â phaystack = &haystack[suffix + j];
        }
    }
 ret0: __attribute__ ((unused))
@@ -37,8 +37,8 @@
 /* Two-Way algorithm. */
 #define RETURN_TYPE char *
 #define AVAILABLE(h, h_l, j, n_l)                      \
-Â (!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l))Â Â Â \
-Â Â && ((h_l) = (j) + (n_l)))
+Â (((j) + (n_l) <= (h_l)) || ((h_l) += strnlen ((void*)((h) + (h_l)), 512), \
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â (j) + (n_l) <= (h_l)))
 #define CHECK_EOL (1)
 #define RET0_IF_0(a) if (!a) goto ret0
 #define CANON_ELEMENT(c) TOLOWER (c)
@@ -33,10 +33,11 @@
Â
 #define RETURN_TYPE char *
 #define AVAILABLE(h, h_l, j, n_l)                      \
-Â (!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l))Â Â Â \
-Â Â && ((h_l) = (j) + (n_l)))
+Â (((j) + (n_l) <= (h_l)) || ((h_l) += strnlen ((void*)((h) + (h_l)), 512), \
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â (j) + (n_l) <= (h_l)))
 #define CHECK_EOL (1)
 #define RET0_IF_0(a) if (!a) goto ret0
+#define FASTSEARCH(S,C,N) (void*) strchr ((void*)(S), (C))
 #include "str-two-way.h"
Â
 #undef strstr