2007-01-03 Ulrich Drepper <drepper@redhat.com> * string/Makefile (tst-strxfrm2-ENV): Define. 2006-11-10 Jakub Jelinek <jakub@redhat.com> * string/strxfrm_l.c (STRXFRM): Fix trailing \1 optimization if N is one bigger than return value. * string/tst-strxfrm2.c (do_test): Also test strxfrm with l1 + 1 and l1 last arguments, if buf is defined, verify the return value equals to strlen (buf) and verify no byte beyond passed length is modified. 2006-11-09 Ulrich Drepper <drepper@redhat.com> * string/Makefile (tests): Add tst-strxfrm2. * string/tst-strxfrm2.c: New file. 2006-11-08 Jakub Jelinek <jakub@redhat.com> * string/strxfrm_l.c (STRXFRM): Do the trailing \1 removal optimization even if needed > n. --- libc/string/Makefile 4 Jun 2006 16:35:25 -0000 1.69 +++ libc/string/Makefile 9 Nov 2006 20:19:24 -0000 1.71 @@ -54,7 +54,7 @@ tests := tester inl-tester noinl-tester bug-strncat1 bug-strspn1 bug-strpbrk1 tst-bswap \ tst-strtok tst-strxfrm bug-strcoll1 tst-strfry \ bug-strtok1 $(addprefix test-,$(strop-tests)) \ - bug-envz1 + bug-envz1 tst-strxfrm2 distribute := memcopy.h pagecopy.h tst-svc.expect test-string.h @@ -64,6 +64,7 @@ tester-ENV = LANGUAGE=C inl-tester-ENV = LANGUAGE=C noinl-tester-ENV = LANGUAGE=C tst-strxfrm-ENV = LOCPATH=$(common-objpfx)localedata +tst-strxfrm2-ENV = LOCPATH=$(common-objpfx)localedata bug-strcoll1-ENV = LOCPATH=$(common-objpfx)localedata CFLAGS-inl-tester.c = -fno-builtin CFLAGS-noinl-tester.c = -fno-builtin --- libc/string/strxfrm_l.c 15 Oct 2005 20:49:18 -0000 1.5 +++ libc/string/strxfrm_l.c 10 Nov 2006 15:18:46 -0000 1.7 @@ -96,6 +97,7 @@ STRXFRM (STRING_TYPE *dest, const STRING const int32_t *indirect; uint_fast32_t pass; size_t needed; + size_t last_needed; const USTRING_TYPE *usrc; size_t srclen = STRLEN (src); int32_t *idxarr; @@ -197,6 +199,7 @@ STRXFRM (STRING_TYPE *dest, const STRING this is true for all of them. */ int position = rule & sort_position; + last_needed = needed; if (position == 0) { for (idxcnt = 0; idxcnt < idxmax; ++idxcnt) @@ -426,11 +429,11 @@ STRXFRM (STRING_TYPE *dest, const STRING a `position' rule at the end and if no non-ignored character is found the last \1 byte is immediately followed by a \0 byte signalling this. We can avoid the \1 byte(s). */ - if (needed <= n && needed > 2 && dest[needed - 2] == L('\1')) + if (needed > 2 && needed == last_needed + 1) { /* Remove the \1 byte. */ - --needed; - dest[needed - 1] = L('\0'); + if (--needed <= n) + dest[needed - 1] = L('\0'); } /* Free the memory if needed. */ --- libc/string/tst-strxfrm2.c 1 Jan 1970 00:00:00 -0000 +++ libc/string/tst-strxfrm2.c 10 Nov 2006 15:20:23 -0000 1.2 @@ -0,0 +1,83 @@ +#include <locale.h> +#include <stdio.h> +#include <string.h> + +static int +do_test (void) +{ + int res = 0; + + char buf[20]; + size_t l1 = strxfrm (NULL, "ab", 0); + size_t l2 = strxfrm (buf, "ab", 1); + size_t l3 = strxfrm (buf, "ab", sizeof (buf)); + if (l3 < sizeof (buf) && strlen (buf) != l3) + { + puts ("C locale l3 test failed"); + res = 1; + } + + size_t l4 = strxfrm (buf, "ab", l1 + 1); + if (l4 < l1 + 1 && strlen (buf) != l4) + { + puts ("C locale l4 test failed"); + res = 1; + } + + buf[l1] = 'Z'; + size_t l5 = strxfrm (buf, "ab", l1); + if (buf[l1] != 'Z') + { + puts ("C locale l5 test failed"); + res = 1; + } + + if (l1 != l2 || l1 != l3 || l1 != l4 || l1 != l5) + { + puts ("C locale retval test failed"); + res = 1; + } + + if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL) + { + puts ("setlocale failed"); + res = 1; + } + else + { + l1 = strxfrm (NULL, "ab", 0); + l2 = strxfrm (buf, "ab", 1); + l3 = strxfrm (buf, "ab", sizeof (buf)); + if (l3 < sizeof (buf) && strlen (buf) != l3) + { + puts ("UTF-8 locale l3 test failed"); + res = 1; + } + + l4 = strxfrm (buf, "ab", l1 + 1); + if (l4 < l1 + 1 && strlen (buf) != l4) + { + puts ("UTF-8 locale l4 test failed"); + res = 1; + } + + buf[l1] = 'Z'; + l5 = strxfrm (buf, "ab", l1); + if (buf[l1] != 'Z') + { + puts ("UTF-8 locale l5 test failed"); + res = 1; + } + + if (l1 != l2 || l1 != l3 || l1 != l4 || l1 != l5) + { + puts ("UTF-8 locale retval test failed"); + res = 1; + } + } + + return res; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c"