Update.
authorUlrich Drepper <drepper@redhat.com>
Mon, 4 Oct 1999 07:30:05 +0000 (07:30 +0000)
committerUlrich Drepper <drepper@redhat.com>
Mon, 4 Oct 1999 07:30:05 +0000 (07:30 +0000)
1999-10-04  Ulrich Drepper  <drepper@cygnus.com>

* include/string.h: Add __memrchr declaration.

* string/string.h: Moce __memrchr declaration to include/string.h.

1999-10-03  Ulrich Drepper  <drepper@cygnus.com>

* string/Makefile (routines): Add memrchr.

* sysdeps/generic/memrchr.c: Don't undef memchr, undef memrchr.
Correct order of tests for matching bytes.

* string/tester.c: Add tests for memrchr.

* sysdeps/i386/i486/bits/string.h (__memrchr): Correct implementation.
Start from the last character and take decrement not increment
into account for correction in return line.  Add memrchr alias.
* sysdeps/i386/bits/string.h: Likewise.

ChangeLog
include/string.h
string/string.h
string/tester.c
sysdeps/generic/memrchr.c
sysdeps/i386/bits/string.h
sysdeps/i386/i486/bits/string.h

index a1a27fb..bd320a2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+1999-10-04  Ulrich Drepper  <drepper@cygnus.com>
+
+       * include/string.h: Add __memrchr declaration.
+
+       * string/string.h: Moce __memrchr declaration to include/string.h.
+
+1999-10-03  Ulrich Drepper  <drepper@cygnus.com>
+
+       * string/Makefile (routines): Add memrchr.
+
+       * sysdeps/generic/memrchr.c: Don't undef memchr, undef memrchr.
+       Correct order of tests for matching bytes.
+
+       * string/tester.c: Add tests for memrchr.
+
+       * sysdeps/i386/i486/bits/string.h (__memrchr): Correct implementation.
+       Start from the last character and take decrement not increment
+       into account for correction in return line.  Add memrchr alias.
+       * sysdeps/i386/bits/string.h: Likewise.
+
 1999-10-04  Roland McGrath  <roland@baalperazim.frob.com>
 
        * stdlib/stdlib.h [__USE_BSD]: Declare getloadavg.
index 4d610ba..4cd64fb 100644 (file)
@@ -20,4 +20,6 @@ extern __ptr_t __rawmemchr __P ((__const __ptr_t __s, int __c));
 
 extern char *__strchrnul __P ((__const char *__s, int __c));
 
+extern __ptr_t __memrchr __P ((__const __ptr_t __s, int __c, size_t __n));
+
 #endif
index 03cf103..a09d42a 100644 (file)
@@ -66,7 +66,6 @@ extern __ptr_t memchr __P ((__const __ptr_t __s, int __c, size_t __n));
 extern __ptr_t rawmemchr __P ((__const __ptr_t __s, int __c));
 
 /* Search N bytes of S for the final occurrence of C.  */
-extern __ptr_t __memrchr __P ((__const __ptr_t __s, int __c, size_t __n));
 extern __ptr_t memrchr __P ((__const __ptr_t __s, int __c, size_t __n));
 #endif
 
index 5105e4e..4fed10e 100644 (file)
@@ -564,6 +564,52 @@ test_strrchr (void)
 }
 
 void
+test_memrchr (void)
+{
+  size_t l;
+  it = "memrchr";
+  check (memrchr ("abcd", 'z', 5) == NULL, 1); /* Not found. */
+  (void) strcpy (one, "abcd");
+  l = strlen (one) + 1;
+  check (memrchr (one, 'c', l) == one+2, 2);   /* Basic test. */
+  check (memrchr (one, 'd', l) == one+3, 3);   /* End of string. */
+  check (memrchr (one, 'a', l) == one, 4);             /* Beginning. */
+  check (memrchr (one, '\0', l) == one+4, 5);  /* Finding NUL. */
+  (void) strcpy (one, "ababa");
+  l = strlen (one) + 1;
+  check (memrchr (one, 'b', l) == one+3, 6);   /* Finding last. */
+  (void) strcpy (one, "");
+  l = strlen (one) + 1;
+  check (memrchr (one, 'b', l) == NULL, 7);    /* Empty string. */
+  check (memrchr (one, '\0', l) == one, 8);    /* NUL in empty string. */
+
+  /* now test all possible alignment and length combinations to catch
+     bugs due to unrolled loops (assuming unrolling is limited to no
+     more than 128 byte chunks: */
+  {
+    char buf[128 + sizeof(long)];
+    long align, len, i, pos;
+
+    for (align = 0; align < (long) sizeof(long); ++align) {
+      for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
+       for (i = 0; i < len; ++i)
+         buf[align + i] = 'x';         /* don't depend on memset... */
+
+       for (pos = len - 1; pos >= 0; --pos) {
+#if 0
+         printf("align %d, len %d, pos %d\n", align, len, pos);
+#endif
+         check(memrchr(buf + align, 'x', len) == buf + align + pos, 9);
+         check(memrchr(buf + align + pos + 1, 'x', len - (pos + 1)) == NULL,
+               10);
+         buf[align + pos] = '-';
+       }
+      }
+    }
+  }
+}
+
+void
 test_rindex (void)
 {
   it = "rindex";
@@ -1183,6 +1229,9 @@ main (void)
   /* strrchr.  */
   test_strrchr ();
 
+  /* memrchr.  */
+  test_memrchr ();
+
   /* rindex - just like strrchr.  */
   test_rindex ();
 
index c866257..874caf1 100644 (file)
@@ -51,6 +51,8 @@
 
 #include <sys/types.h>
 
+#undef memrchr
+
 
 /* Search no more than N bytes of S for C.  */
 __ptr_t
@@ -163,24 +165,24 @@ __memrchr (s, c_in, n)
 
          const unsigned char *cp = (const unsigned char *) longword_ptr;
 
-         if (cp[0] == c)
-           return (__ptr_t) cp;
-         if (cp[1] == c)
-           return (__ptr_t) &cp[1];
-         if (cp[2] == c)
-           return (__ptr_t) &cp[2];
-         if (cp[3] == c)
-           return (__ptr_t) &cp[3];
 #if LONG_MAX > 2147483647
-         if (cp[4] == c)
-           return (__ptr_t) &cp[4];
-         if (cp[5] == c)
-           return (__ptr_t) &cp[5];
-         if (cp[6] == c)
-           return (__ptr_t) &cp[6];
          if (cp[7] == c)
            return (__ptr_t) &cp[7];
+         if (cp[6] == c)
+           return (__ptr_t) &cp[6];
+         if (cp[5] == c)
+           return (__ptr_t) &cp[5];
+         if (cp[4] == c)
+           return (__ptr_t) &cp[4];
 #endif
+         if (cp[3] == c)
+           return (__ptr_t) &cp[3];
+         if (cp[2] == c)
+           return (__ptr_t) &cp[2];
+         if (cp[1] == c)
+           return (__ptr_t) &cp[1];
+         if (cp[0] == c)
+           return (__ptr_t) cp;
        }
 
       n -= sizeof (longword);
index 01c17db..b727e2b 100644 (file)
@@ -319,13 +319,16 @@ __memrchr (__const void *__s, int __c, size_t __n)
     ("std\n\t"
      "repne; scasb\n\t"
      "je 1f\n\t"
-     "movl $1,%0\n"
+     "orl $-1,%0\n"
      "1:\tcld"
      : "=D" (__res), "=&c" (__d0)
-     : "a" (__c), "0" (__s), "1" (__n)
+     : "a" (__c), "0" (__s + __n - 1), "1" (__n)
      : "cc");
-  return __res - 1;
+  return __res + 1;
 }
+# ifdef __USE_GNU
+#  define memrchr(s, c, n) __memrchr (s, c, n)
+# endif
 #endif
 
 /* Return the length of S.  */
index 9b37f58..54e5ac4 100644 (file)
@@ -452,34 +452,37 @@ __STRING_INLINE void *
 __memrchr (__const void *__s, int __c, size_t __n)
 {
   register unsigned long int __d0;
-#ifdef __i686__
+# ifdef __i686__
   register unsigned long int __d1;
-#endif
+# endif
   register void *__res;
   if (__n == 0)
     return NULL;
-#ifdef __i686__
+# ifdef __i686__
   __asm__ __volatile__
     ("std\n\t"
      "repne; scasb\n\t"
      "cmovne %2,%0\n\t"
      "cld"
      : "=D" (__res), "=&c" (__d0), "=&r" (__d1)
-     : "a" (__c), "0" (__s), "1" (__n), "2" (1)
+     : "a" (__c), "0" (__s + __n - 1), "1" (__n), "2" (-1)
      : "cc");
-#else
+# else
   __asm__ __volatile__
     ("std\n\t"
      "repne; scasb\n\t"
      "je 1f\n\t"
-     "movl $1,%0\n"
+     "orl $-1,%0\n"
      "1:\tcld"
      : "=D" (__res), "=&c" (__d0)
-     : "a" (__c), "0" (__s), "1" (__n)
+     : "a" (__c), "0" (__s + __n - 1), "1" (__n)
      : "cc");
-#endif
-  return __res - 1;
+# endif
+  return __res + 1;
 }
+# ifdef __USE_GNU
+#  define memrchr(s, c, n) __memrchr (s, c, n)
+# endif
 #endif
 
 /* Return pointer to C in S.  */