1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00

New comprehensive test for wcscmp

This commit is contained in:
Liubov Dmitrieva
2011-08-04 16:04:15 -04:00
committed by Ulrich Drepper
parent 9be9bfcc9d
commit cff8293390
4 changed files with 169 additions and 24 deletions

View File

@ -1,3 +1,12 @@
2011-07-22 Liubov Dmitrieva <liubov.dmitrieva@gmail.com>
* string/Makefile: Update.
(strop-tests): Append strncat.
* string/test-wcscmp.c: New file.
New comprehensive test for wcscmp.
* string/test-strcmp.c: Update.
(WIDE): New define.
2011-07-22 Andreas Schwab <schwab@redhat.com> 2011-07-22 Andreas Schwab <schwab@redhat.com>
* resolv/res_init.c (__res_vinit): Properly tokenize nameserver * resolv/res_init.c (__res_vinit): Properly tokenize nameserver

View File

@ -46,7 +46,7 @@ routines := strcat strchr strcmp strcoll strcpy strcspn \
# for -fbounded-pointer compiles. Glibc uses memchr for explicit checks. # for -fbounded-pointer compiles. Glibc uses memchr for explicit checks.
o-objects.ob := memcpy.o memset.o memchr.o o-objects.ob := memcpy.o memset.o memchr.o
strop-tests := memchr memcmp memcpy memmove mempcpy memset memccpy \ strop-tests := wcscmp memchr memcmp memcpy memmove mempcpy memset memccpy \
stpcpy stpncpy strcat strchr strcmp strcpy strcspn \ stpcpy stpncpy strcat strchr strcmp strcpy strcspn \
strlen strncmp strncpy strpbrk strrchr strspn memmem \ strlen strncmp strncpy strpbrk strrchr strspn memmem \
strstr strcasestr strnlen strcasecmp strncasecmp \ strstr strcasestr strnlen strcasecmp strncasecmp \

View File

@ -1,7 +1,8 @@
/* Test and measure strcmp functions. /* Test and measure STRCMP functions.
Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc. Copyright (C) 1999, 2002, 2003, 2005, 2011 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999. Written by Jakub Jelinek <jakub@redhat.com>, 1999.
Added wcscmp support by Liubov Dmitrieva <liubov.dmitrieva@gmail.com>, 2011.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -21,39 +22,63 @@
#define TEST_MAIN #define TEST_MAIN
#include "test-string.h" #include "test-string.h"
typedef int (*proto_t) (const char *, const char *); #ifdef WIDE
int simple_strcmp (const char *, const char *); # include <inttypes.h>
int stupid_strcmp (const char *, const char *); # include <wchar.h>
#endif
IMPL (stupid_strcmp, 0) #ifdef WIDE
IMPL (simple_strcmp, 0) # define L(str) L##str
IMPL (strcmp, 1) # define STRCMP wcscmp
# define STRCPY wcscpy
# define STRLEN wcslen
# define SIMPLE_STRCMP simple_wcscmp
# define STUPID_STRCMP stupid_wcscmp
typedef uint32_t unsigned_element_type;
typedef uint32_t element_type;
typedef int (*proto_t) (const uint32_t *, const uint32_t *);
#else
# define L(str) str
# define STRCMP strcmp
# define STRCPY strcpy
# define STRLEN strlen
# define SIMPLE_STRCMP simple_strcmp
# define STUPID_STRCMP stupid_strcmp
typedef unsigned char unsigned_element_type;
typedef char element_type;
typedef int (*proto_t) (const char *, const char *);
#endif
int int
simple_strcmp (const char *s1, const char *s2) SIMPLE_STRCMP (const unsigned_element_type *s1, const unsigned_element_type *s2)
{ {
int ret; int ret;
while ((ret = *(unsigned char *) s1 - *(unsigned char *) s2++) == 0 while ((ret = *s1 - *s2++) == 0 && *s1++);
&& *s1++);
return ret; return ret;
} }
int int
stupid_strcmp (const char *s1, const char *s2) STUPID_STRCMP (const unsigned_element_type *s1, const unsigned_element_type *s2)
{ {
size_t ns1 = strlen (s1) + 1, ns2 = strlen (s2) + 1; size_t ns1 = STRLEN (s1) + 1, ns2 = STRLEN (s2) + 1;
size_t n = ns1 < ns2 ? ns1 : ns2; size_t n = ns1 < ns2 ? ns1 : ns2;
int ret = 0; int ret = 0;
while (n--) while (n--)
if ((ret = *(unsigned char *) s1++ - *(unsigned char *) s2++) != 0) if ((ret = *s1++ - *s2++) != 0)
break; break;
return ret; return ret;
} }
static void IMPL (STUPID_STRCMP, 1)
do_one_test (impl_t *impl, const char *s1, const char *s2, int exp_result) IMPL (SIMPLE_STRCMP, 1)
IMPL (STRCMP, 1)
static int
check_result (impl_t *impl,
const element_type *s1, const element_type *s2,
int exp_result)
{ {
int result = CALL (impl, s1, s2); int result = CALL (impl, s1, s2);
if ((exp_result == 0 && result != 0) if ((exp_result == 0 && result != 0)
@ -63,9 +88,20 @@ do_one_test (impl_t *impl, const char *s1, const char *s2, int exp_result)
error (0, 0, "Wrong result in function %s %d %d", impl->name, error (0, 0, "Wrong result in function %s %d %d", impl->name,
result, exp_result); result, exp_result);
ret = 1; ret = 1;
return; return -1;
} }
return 0;
}
static void
do_one_test (impl_t *impl,
const element_type *s1, const element_type *s2,
int exp_result)
{
if (check_result (impl, s1, s2, exp_result) < 0)
return;
if (HP_TIMING_AVAIL) if (HP_TIMING_AVAIL)
{ {
hp_timing_t start __attribute ((unused)); hp_timing_t start __attribute ((unused));
@ -90,11 +126,13 @@ do_test (size_t align1, size_t align2, size_t len, int max_char,
int exp_result) int exp_result)
{ {
size_t i; size_t i;
char *s1, *s2;
element_type *s1, *s2;
if (len == 0) if (len == 0)
return; return;
#ifndef WIDE
align1 &= 7; align1 &= 7;
if (align1 + len + 1 >= page_size) if (align1 + len + 1 >= page_size)
return; return;
@ -106,8 +144,29 @@ do_test (size_t align1, size_t align2, size_t len, int max_char,
s1 = (char *) (buf1 + align1); s1 = (char *) (buf1 + align1);
s2 = (char *) (buf2 + align2); s2 = (char *) (buf2 + align2);
#else
align1 &= 63;
if (align1 + len * 4 + 4 >= page_size)
return;
align2 &= 63;
if (align2 + len * 4 + 4 >= page_size)
return;
/* Put them close to the end of page. */
i = align1 + 4 * len + 8;
s1 = (uint32_t *) (buf1 + ((page_size - i) / 16 * 16) + align1);
i = align2 + 4 * len + 8;
s2 = (uint32_t *) (buf2 + ((page_size - i) / 16 * 16) + align2);
#endif
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
#ifndef WIDE
s1[i] = s2[i] = 1 + 23 * i % max_char; s1[i] = s2[i] = 1 + 23 * i % max_char;
#else
s1[i] = s2[i] = 1 + 1023 * i % max_char;
#endif
s1[len] = s2[len] = 0; s1[len] = s2[len] = 0;
s1[len + 1] = 23; s1[len + 1] = 23;
@ -129,11 +188,21 @@ do_random_tests (void)
{ {
size_t i, j, n, align1, align2, pos, len1, len2; size_t i, j, n, align1, align2, pos, len1, len2;
int result; int result;
long r; int r;
#ifndef WIDE
unsigned char *p1 = buf1 + page_size - 512; unsigned char *p1 = buf1 + page_size - 512;
unsigned char *p2 = buf2 + page_size - 512; unsigned char *p2 = buf2 + page_size - 512;
for (n = 0; n < ITERATIONS; n++) for (n = 0; n < ITERATIONS; n++)
#else
for (size_t a = 0; a < 4; a++)
for (size_t b = 0; b < 4; b++)
{
uint32_t *p1 = (uint32_t *) (buf1 + page_size - 512 * 4 - a);
uint32_t *p2 = (uint32_t *) (buf2 + page_size - 512 * 4 - b);
for (n = 0; n < ITERATIONS / 2; n++)
#endif
{ {
align1 = random () & 31; align1 = random () & 31;
if (random () & 1) if (random () & 1)
@ -178,7 +247,11 @@ do_random_tests (void)
} }
result = 0; result = 0;
#ifndef WIDE
memcpy (p2 + align2, p1 + align1, pos); memcpy (p2 + align2, p1 + align1, pos);
#else
memcpy (p2 + align2, p1 + align1, 4 * pos);
#endif
if (pos < len1) if (pos < len1)
{ {
if (p2[align2 + pos] == p1[align1 + pos]) if (p2[align2 + pos] == p1[align1 + pos])
@ -198,7 +271,7 @@ do_random_tests (void)
FOR_EACH_IMPL (impl, 1) FOR_EACH_IMPL (impl, 1)
{ {
r = CALL (impl, (char *) (p1 + align1), (char *) (p2 + align2)); r = CALL (impl, p1 + align1, p2 + align2);
/* Test whether on 64-bit architectures where ABI requires /* Test whether on 64-bit architectures where ABI requires
callee to promote has the promotion been done. */ callee to promote has the promotion been done. */
asm ("" : "=g" (r) : "0" (r)); asm ("" : "=g" (r) : "0" (r));
@ -206,26 +279,55 @@ do_random_tests (void)
|| (r < 0 && result >= 0) || (r < 0 && result >= 0)
|| (r > 0 && result <= 0)) || (r > 0 && result <= 0))
{ {
error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd, %zd, %zd) %ld != %d, p1 %p p2 %p", error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd, %zd, %zd) %d != %d, p1 %p p2 %p",
n, impl->name, align1, align2, len1, len2, pos, r, result, p1, p2); n, impl->name, (size_t) (p1 + align1) & 63, (size_t) (p1 + align2) & 63, len1, len2, pos, r, result, p1, p2);
ret = 1; ret = 1;
} }
} }
} }
#ifdef WIDE
}
#endif
} }
static void
check (void)
{
const element_type *s1 = (element_type *) (buf1 + 0xb2c);
const element_type *s2 = (element_type *) (buf1 + 0xfd8);
size_t i1, i2, l1, l2;
int exp_result;
STRCPY(s1, L"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs");
STRCPY(s2, L"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkLMNOPQRSTUV");
l1 = STRLEN (s1);
l2 = STRLEN (s2);
for (i1 = 0; i1 < l1; i1++)
for (i2 = 0; i2 < l2; i2++)
{
exp_result = SIMPLE_STRCMP (s1 + i1, s2 + i2);
FOR_EACH_IMPL (impl, 0)
check_result (impl, s1 + i1, s2 + i2, exp_result);
}
}
int int
test_main (void) test_main (void)
{ {
size_t i; size_t i;
test_init (); test_init ();
check();
printf ("%23s", ""); printf ("%23s", "");
FOR_EACH_IMPL (impl, 0) FOR_EACH_IMPL (impl, 0)
printf ("\t%s", impl->name); printf ("\t%s", impl->name);
putchar ('\n'); putchar ('\n');
#ifndef WIDE
for (i = 1; i < 16; ++i) for (i = 1; i < 16; ++i)
{ {
do_test (i, i, i, 127, 0); do_test (i, i, i, 127, 0);
@ -253,6 +355,38 @@ test_main (void)
do_test (2 * i, i, 8 << i, 254, -1); do_test (2 * i, i, 8 << i, 254, -1);
} }
#else
for (i = 1; i < 32; ++i)
{
do_test (i, i, i, 127, 0);
do_test (i, i, i, 127, 1);
do_test (i, i, i, 127, -1);
}
for (i = 1; i < 12; ++i)
{
do_test (0, 0, 2 << i, 127, 0);
do_test (0, 0, 2 << i, 10000, 0);
do_test (0, 0, 2 << i, 127, 1);
do_test (0, 0, 2 << i, 10000, 1);
do_test (0, 0, 2 << i, 127, -1);
do_test (0, 0, 2 << i, 10000, -1);
do_test (0, 4 * i, 2 << i, 127, 1);
do_test (4 * i, 4 * i + 4, 2 << i, 10000, 1);
}
for (i = 1; i < 9; ++i)
{
do_test (i, 2 * i, 8 << i, 10000, 0);
do_test (8 * i, 4 * i, 8 << i, 20000, 0);
do_test (i, 2 * i, 8 << i, 30000, 1);
do_test (2 * i, i, 8 << i, 10000, 1);
do_test (4 * i, 4 * i + 4, 8 << i, 20000, -1);
do_test (2 * i, i, 8 << i, 30000, -1);
do_test (4 * i + 4, 4 * i, 8 << i, 10000, 1);
}
#endif
do_random_tests (); do_random_tests ();
return ret; return ret;
} }

2
string/test-wcscmp.c Normal file
View File

@ -0,0 +1,2 @@
#define WIDE 1
#include "test-strcmp.c"