Blob Blame History Raw
diff -Nrup a/NEWS b/NEWS
--- a/NEWS	2012-09-14 14:31:29.000000000 -0600
+++ b/NEWS	2012-09-20 15:43:07.883932826 -0600
@@ -27,9 +27,6 @@ Version 2.17
 * SystemTap static probes have been added into the dynamic linker.
   Implemented by Gary Benson.
 
-* Optimizations of string functions strstr, strcasestr and memmem.
-  Implemented by Maxim Kuvyrkov.
-
 * The minimum Linux kernel version that this version of the GNU C Library
   can be used with is 2.6.16.
 
diff -Nrup a/string/Makefile b/string/Makefile
--- a/string/Makefile	2012-09-14 14:31:29.000000000 -0600
+++ b/string/Makefile	2012-09-20 15:42:02.189221257 -0600
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-2002, 2005-2011, 2012 Free Software Foundation, Inc.
+# Copyright (C) 1991-2002, 2005-2010, 2011 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 
 # The GNU C Library is free software; you can redistribute it and/or
@@ -56,7 +56,9 @@ tests		:= tester inl-tester noinl-tester
 		   tst-strtok tst-strxfrm bug-strcoll1 tst-strfry	\
 		   bug-strtok1 $(addprefix test-,$(strop-tests))	\
 		   bug-envz1 tst-strxfrm2 tst-endian tst-svc2		\
-		   bug-strstr1 bug-strcasestr1 bug-strchr1 tst-strtok_r
+		   bug-strstr1 bug-strchr1
+distribute	:= memcopy.h pagecopy.h tst-svc.expect test-string.h	\
+		   str-two-way.h
 
 
 include ../Rules
@@ -74,7 +76,6 @@ CFLAGS-stratcliff.c = -fno-builtin
 CFLAGS-test-ffs.c = -fno-builtin
 CFLAGS-tst-inlcall.c = -fno-builtin
 CFLAGS-bug-strstr1.c = -fno-builtin
-CFLAGS-bug-strcasestr1.c = -fno-builtin
 
 ifeq ($(cross-compiling),no)
 tests: $(objpfx)tst-svc.out
diff -Nrup a/string/bug-strcasestr1.c b/string/bug-strcasestr1.c
--- a/string/bug-strcasestr1.c	2012-09-14 14:31:29.000000000 -0600
+++ b/string/bug-strcasestr1.c	1969-12-31 17:00:00.000000000 -0700
@@ -1,39 +0,0 @@
-/* Test for non-submitted strcasestr bug.
-   Copyright (C) 2012 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <stdio.h>
-#include <string.h>
-
-#define TEST_FUNCTION do_test ()
-static int
-do_test (void)
-{
-  const char haystack[] = "AOKB";
-  const char needle[] = "OK";
-  const char *sub = strcasestr (haystack, needle);
-
-  if (sub == NULL)
-    {
-      fprintf (stderr, "BUG: didn't find \"%s\" in \"%s\"\n", needle, haystack);
-      return 1;
-    }
-
-  return 0;
-}
-
-#include "../test-skeleton.c"
diff -Nrup a/string/str-two-way.h b/string/str-two-way.h
--- a/string/str-two-way.h	2012-09-14 14:31:29.000000000 -0600
+++ b/string/str-two-way.h	2012-09-20 15:41:31.478356212 -0600
@@ -1,5 +1,5 @@
 /* Byte-wise substring search, using the Two-Way algorithm.
-   Copyright (C) 2008-2012 Free Software Foundation, Inc.
+   Copyright (C) 2008, 2010 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Eric Blake <ebb9@byu.net>, 2008.
 
@@ -43,7 +43,6 @@
 
 #include <limits.h>
 #include <stdint.h>
-#include <sys/param.h>                  /* Defines MAX.  */
 
 /* We use the Two-Way string matching algorithm, which guarantees
    linear complexity with constant space.  Additionally, for long
@@ -68,6 +67,10 @@
 # define LONG_NEEDLE_THRESHOLD SIZE_MAX
 #endif
 
+#ifndef MAX
+# define MAX(a, b) ((a < b) ? (b) : (a))
+#endif
+
 #ifndef CANON_ELEMENT
 # define CANON_ELEMENT(c) c
 #endif
@@ -75,19 +78,6 @@
 # define CMP_FUNC memcmp
 #endif
 
-#ifndef AVAILABLE1
-# define AVAILABLE1(h, h_l, j, n_l) AVAILABLE (h, h_l, j, n_l)
-#endif
-#ifndef AVAILABLE2
-# define AVAILABLE2(h, h_l, j, n_l) (1)
-#endif
-#ifndef RET0_IF_0
-# define RET0_IF_0(a) /* nothing */
-#endif
-#ifndef AVAILABLE1_USES_J
-# define AVAILABLE1_USES_J (1)
-#endif
-
 /* Perform a critical factorization of NEEDLE, of length NEEDLE_LEN.
    Return the index of the first byte in the right half, and set
    *PERIOD to the global period of the right half.
@@ -243,24 +233,17 @@ two_way_short_needle (const unsigned cha
       j = 0;
       while (AVAILABLE (haystack, haystack_len, j, needle_len))
 	{
-	  const unsigned char *pneedle;
-	  const unsigned char *phaystack;
-
 	  /* Scan for matches in right half.  */
 	  i = MAX (suffix, memory);
-	  pneedle = &needle[i];
-	  phaystack = &haystack[i + j];
-	  while (i < needle_len && (CANON_ELEMENT (*pneedle++)
-				    == CANON_ELEMENT (*phaystack++)))
+	  while (i < needle_len && (CANON_ELEMENT (needle[i])
+				    == CANON_ELEMENT (haystack[i + j])))
 	    ++i;
 	  if (needle_len <= i)
 	    {
 	      /* Scan for matches in left half.  */
 	      i = suffix - 1;
-	      pneedle = &needle[i];
-	      phaystack = &haystack[i + j];
-	      while (memory < i + 1 && (CANON_ELEMENT (*pneedle--)
-					== CANON_ELEMENT (*phaystack--)))
+	      while (memory < i + 1 && (CANON_ELEMENT (needle[i])
+					== CANON_ELEMENT (haystack[i + j])))
 		--i;
 	      if (i + 1 < memory + 1)
 		return (RETURN_TYPE) (haystack + j);
@@ -278,81 +261,32 @@ two_way_short_needle (const unsigned cha
     }
   else
     {
-      const unsigned char *phaystack = &haystack[suffix];
-      /* 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]);
-
       /* 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 (AVAILABLE1 (haystack, haystack_len, j, needle_len))
+      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
-	      != (haystack_char = CANON_ELEMENT (*phaystack++)))
-	    {
-	      RET0_IF_0 (haystack_char);
-#if AVAILABLE1_USES_J
-	      ++j;
-#endif
-	      continue;
-	    }
-
-#if !AVAILABLE1_USES_J
-	  /* Calculate J if it wasn't kept up-to-date in the first-character
-	     loop.  */
-	  j = phaystack - &haystack[suffix] - 1;
-#endif
-
 	  /* Scan for matches in right half.  */
-	  i = suffix + 1;
-	  pneedle = &needle[i];
-	  while (i < needle_len)
-	    {
-	      if (CANON_ELEMENT (*pneedle++)
-		  != (haystack_char = CANON_ELEMENT (*phaystack++)))
-		{
-		  RET0_IF_0 (haystack_char);
-		  break;
-		}
-	      ++i;
-	    }
+	  i = suffix;
+	  while (i < needle_len && (CANON_ELEMENT (needle[i])
+				    == CANON_ELEMENT (haystack[i + j])))
+	    ++i;
 	  if (needle_len <= i)
 	    {
 	      /* Scan for matches in left half.  */
 	      i = suffix - 1;
-	      pneedle = &needle[i];
-	      phaystack = &haystack[i + j];
-	      while (i != SIZE_MAX)
-		{
-		  if (CANON_ELEMENT (*pneedle--)
-		      != (haystack_char = CANON_ELEMENT (*phaystack--)))
-		    {
-		      RET0_IF_0 (haystack_char);
-		      break;
-		    }
-		  --i;
-		}
+	      while (i != SIZE_MAX && (CANON_ELEMENT (needle[i])
+				       == CANON_ELEMENT (haystack[i + j])))
+		--i;
 	      if (i == SIZE_MAX)
 		return (RETURN_TYPE) (haystack + j);
 	      j += period;
 	    }
 	  else
 	    j += i - suffix + 1;
-
-	  if (!AVAILABLE2 (haystack, haystack_len, j, needle_len))
-	    break;
-
-	  phaystack = &haystack[suffix + j];
 	}
     }
- ret0: __attribute__ ((unused))
   return NULL;
 }
 
@@ -404,9 +338,6 @@ two_way_long_needle (const unsigned char
       j = 0;
       while (AVAILABLE (haystack, haystack_len, j, needle_len))
 	{
-	  const unsigned char *pneedle;
-	  const unsigned char *phaystack;
-
 	  /* Check the last byte first; if it does not match, then
 	     shift to the next possible match location.  */
 	  shift = shift_table[CANON_ELEMENT (haystack[j + needle_len - 1])];
@@ -426,19 +357,15 @@ two_way_long_needle (const unsigned char
 	  /* Scan for matches in right half.  The last byte has
 	     already been matched, by virtue of the shift table.  */
 	  i = MAX (suffix, memory);
-	  pneedle = &needle[i];
-	  phaystack = &haystack[i + j];
-	  while (i < needle_len - 1 && (CANON_ELEMENT (*pneedle++)
-					== CANON_ELEMENT (*phaystack++)))
+	  while (i < needle_len - 1 && (CANON_ELEMENT (needle[i])
+					== CANON_ELEMENT (haystack[i + j])))
 	    ++i;
 	  if (needle_len - 1 <= i)
 	    {
 	      /* Scan for matches in left half.  */
 	      i = suffix - 1;
-	      pneedle = &needle[i];
-	      phaystack = &haystack[i + j];
-	      while (memory < i + 1 && (CANON_ELEMENT (*pneedle--)
-					== CANON_ELEMENT (*phaystack--)))
+	      while (memory < i + 1 && (CANON_ELEMENT (needle[i])
+					== CANON_ELEMENT (haystack[i + j])))
 		--i;
 	      if (i + 1 < memory + 1)
 		return (RETURN_TYPE) (haystack + j);
@@ -463,9 +390,6 @@ two_way_long_needle (const unsigned char
       j = 0;
       while (AVAILABLE (haystack, haystack_len, j, needle_len))
 	{
-	  const unsigned char *pneedle;
-	  const unsigned char *phaystack;
-
 	  /* Check the last byte first; if it does not match, then
 	     shift to the next possible match location.  */
 	  shift = shift_table[CANON_ELEMENT (haystack[j + needle_len - 1])];
@@ -477,19 +401,15 @@ two_way_long_needle (const unsigned char
 	  /* Scan for matches in right half.  The last byte has
 	     already been matched, by virtue of the shift table.  */
 	  i = suffix;
-	  pneedle = &needle[i];
-	  phaystack = &haystack[i + j];
-	  while (i < needle_len - 1 && (CANON_ELEMENT (*pneedle++)
-					== CANON_ELEMENT (*phaystack++)))
+	  while (i < needle_len - 1 && (CANON_ELEMENT (needle[i])
+					== CANON_ELEMENT (haystack[i + j])))
 	    ++i;
 	  if (needle_len - 1 <= i)
 	    {
 	      /* Scan for matches in left half.  */
 	      i = suffix - 1;
-	      pneedle = &needle[i];
-	      phaystack = &haystack[i + j];
-	      while (i != SIZE_MAX && (CANON_ELEMENT (*pneedle--)
-				       == CANON_ELEMENT (*phaystack--)))
+	      while (i != SIZE_MAX && (CANON_ELEMENT (needle[i])
+				       == CANON_ELEMENT (haystack[i + j])))
 		--i;
 	      if (i == SIZE_MAX)
 		return (RETURN_TYPE) (haystack + j);
@@ -503,10 +423,6 @@ two_way_long_needle (const unsigned char
 }
 
 #undef AVAILABLE
-#undef AVAILABLE1
-#undef AVAILABLE2
-#undef AVAILABLE1_USES_J
 #undef CANON_ELEMENT
 #undef CMP_FUNC
-#undef RET0_IF_0
 #undef RETURN_TYPE
diff -Nrup a/string/strcasestr.c b/string/strcasestr.c
--- a/string/strcasestr.c	2012-09-14 14:31:29.000000000 -0600
+++ b/string/strcasestr.c	2012-09-20 15:41:41.709311245 -0600
@@ -1,5 +1,6 @@
 /* Return the offset of one string within another.
-   Copyright (C) 1994-2012 Free Software Foundation, Inc.
+   Copyright (C) 1994, 1996-2000, 2004, 2008, 2009, 2010
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -36,17 +37,13 @@
 #include <stdbool.h>
 #include <strings.h>
 
-#define TOLOWER(Ch) tolower (Ch)
+#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
 
 /* 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)))
-#define AVAILABLE1(h, h_l, j, n_l) (true)
-#define AVAILABLE2(h, h_l, j, n_l) AVAILABLE (h, h_l, j, n_l)
-#define RET0_IF_0(a) if (!a) goto ret0
-#define AVAILABLE1_USES_J (0)
 #define CANON_ELEMENT(c) TOLOWER (c)
 #define CMP_FUNC(p1, p2, l)				\
   __strncasecmp ((const char *) (p1), (const char *) (p2), l)
diff -Nrup a/string/strstr.c b/string/strstr.c
--- a/string/strstr.c	2012-09-14 14:31:29.000000000 -0600
+++ b/string/strstr.c	2012-09-20 15:42:15.661162080 -0600
@@ -1,5 +1,6 @@
 /* Return the offset of one string within another.
-   Copyright (C) 1994-2012 Free Software Foundation, Inc.
+   Copyright (C) 1994,1996,1997,2000,2001,2003,2008,2009
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -35,10 +36,6 @@
 #define AVAILABLE(h, h_l, j, n_l)			\
   (!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l))	\
    && ((h_l) = (j) + (n_l)))
-#define AVAILABLE1(h, h_l, j, n_l) (true)
-#define AVAILABLE2(h, h_l, j, n_l) AVAILABLE (h, h_l, j, n_l)
-#define RET0_IF_0(a) if (!a) goto ret0
-#define AVAILABLE1_USES_J (0)
 #include "str-two-way.h"
 
 #undef strstr