Update.
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.
This commit is contained in:
parent
ba60c6d921
commit
fbda91b119
20
ChangeLog
20
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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -563,6 +563,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)
|
||||
{
|
||||
@ -1183,6 +1229,9 @@ main (void)
|
||||
/* strrchr. */
|
||||
test_strrchr ();
|
||||
|
||||
/* memrchr. */
|
||||
test_memrchr ();
|
||||
|
||||
/* rindex - just like strrchr. */
|
||||
test_rindex ();
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user