bug in towctrans in C locale
Bruno Haible
haible@ilog.fr
Fri Jul 28 06:45:00 GMT 2000
In the C locale, towctrans("tolower") returns the toupper table, and vice
versa. It surprised me that this is not caught by the test suite. So here
is a patch which
- adds a test to the testsuite that detects the bug,
- fixes the C locale,
- introduces symbolic names for the indices of the two tables, in
order to avoid similar bugs in the future.
localedata/ChangeLog:
2000-07-27 Bruno Haible <haible@clisp.cons.org>
* tests-mbwc/tgn_locdef.h (TST_LOC_C): New macro.
* tests-mbwc/dat_towctrans.c: Apply the en_US test also to the C
locale.
main ChangeLog:
2000-07-27 Bruno Haible <haible@clisp.cons.org>
* locale/C-ctype.c (_nl_C_LC_CTYPE): Swap the two names in
_NL_CTYPE_MAP_NAMES.
* locale/localeinfo.h (__TOW_toupper, __TOW_tolower): New enum values.
* wctype/wcfuncs.c (towlower, towupper): Use them.
* wctype/wcfuncs_l.c (__towlower_l, __towupper_l): Likewise.
* wctype/wctrans.c (wctrans): Likewise.
* wctype/wctrans_l.c (__wctrans_l): Likewise.
*** glibc-20000724/localedata/tests-mbwc/tgn_locdef.h.bak Wed Jun 28 10:24:36 2000
--- glibc-20000724/localedata/tests-mbwc/tgn_locdef.h Fri Jul 28 03:20:57 2000
***************
*** 3,8 ****
--- 3,11 ----
/* Defines for all locales used in the suite. */
+ /* POSIX C locale. */
+ #define TST_LOC_C "C"
+
/* German locale with ISO-8859-1. */
#define TST_LOC_de "de_DE.ISO-8859-1"
*** glibc-20000724/localedata/tests-mbwc/dat_towctrans.c.bak Wed Jun 28 06:11:54 2000
--- glibc-20000724/localedata/tests-mbwc/dat_towctrans.c Fri Jul 28 03:21:58 2000
***************
*** 36,41 ****
--- 36,55 ----
TST_TOWCTRANS tst_towctrans_loc [] = {
{
+ { Ttowctrans, TST_LOC_C },
+ {
+ #ifdef SHOJI_IS_RIGHT
+ { { 0x0010, "xxxxxxx" }, { 1,EINVAL,1,0x0010 } },
+ #else
+ { { 0x0010, "xxxxxxx" }, { 1,0, 1,0x0010 } },
+ #endif
+ { { 0x007F, "tolower" }, { 1,0, 1,0x007F } },
+ { { 0x0061, "toupper" }, { 1,0, 1,0x0041 } },
+ { { 0x0041, "tolower" }, { 1,0, 1,0x0061 } },
+ { is_last: 1 }
+ }
+ },
+ {
{ Ttowctrans, TST_LOC_de },
{
#ifdef SHOJI_IS_RIGHT
*** glibc-20000724/locale/C-ctype.c.bak Tue Jul 25 00:07:59 2000
--- glibc-20000724/locale/C-ctype.c Fri Jul 28 03:42:43 2000
***************
*** 370,376 ****
"vowel_connect\0"
#endif
},
! { string: "tolower\0" "toupper\0"
#ifdef PREDEFINED_CLASSES
"tosymmetric\0"
#endif
--- 370,376 ----
"vowel_connect\0"
#endif
},
! { string: "toupper\0" "tolower\0"
#ifdef PREDEFINED_CLASSES
"tosymmetric\0"
#endif
*** glibc-20000724/locale/localeinfo.h.bak Mon Jul 3 16:39:31 2000
--- glibc-20000724/locale/localeinfo.h Fri Jul 28 01:00:21 2000
***************
*** 129,134 ****
--- 129,143 ----
(((((const uint32_t *) (desc)) - 8)[(c) >> 5] >> ((c) & 0x1f)) & 1)
+ /* LC_CTYPE specific:
+ Hardwired indices for standard wide character translation mappings. */
+ enum
+ {
+ __TOW_toupper = 0,
+ __TOW_tolower = 1
+ };
+
+
/* For each category declare the variable for the current locale data. */
#define DEFINE_CATEGORY(category, category_name, items, a) \
extern struct locale_data *_nl_current_##category;
*** glibc-20000724/wctype/wcfuncs.c.bak Tue Jul 25 00:08:37 2000
--- glibc-20000724/wctype/wcfuncs.c Thu Jul 27 13:37:10 2000
***************
*** 100,106 ****
else
{
/* New locale format. */
! return wctrans_table_lookup (__ctype32_wctrans[1], wc);
}
}
--- 100,106 ----
else
{
/* New locale format. */
! return wctrans_table_lookup (__ctype32_wctrans[__TOW_tolower], wc);
}
}
***************
*** 123,128 ****
else
{
/* New locale format. */
! return wctrans_table_lookup (__ctype32_wctrans[0], wc);
}
}
--- 123,128 ----
else
{
/* New locale format. */
! return wctrans_table_lookup (__ctype32_wctrans[__TOW_toupper], wc);
}
}
*** glibc-20000724/wctype/wcfuncs_l.c.bak Tue Jul 25 00:08:37 2000
--- glibc-20000724/wctype/wcfuncs_l.c Thu Jul 27 13:36:13 2000
***************
*** 86,92 ****
else
{
/* New locale format. */
! size_t i = locale->__locales[LC_CTYPE]->values[_NL_ITEM_INDEX (_NL_CTYPE_MAP_OFFSET)].word + 1;
const char *desc = locale->__locales[LC_CTYPE]->values[i].string;
return wctrans_table_lookup (desc, wc);
}
--- 86,92 ----
else
{
/* New locale format. */
! size_t i = locale->__locales[LC_CTYPE]->values[_NL_ITEM_INDEX (_NL_CTYPE_MAP_OFFSET)].word + __TOW_tolower;
const char *desc = locale->__locales[LC_CTYPE]->values[i].string;
return wctrans_table_lookup (desc, wc);
}
***************
*** 113,119 ****
else
{
/* New locale format. */
! size_t i = locale->__locales[LC_CTYPE]->values[_NL_ITEM_INDEX (_NL_CTYPE_MAP_OFFSET)].word + 0;
const char *desc = locale->__locales[LC_CTYPE]->values[i].string;
return wctrans_table_lookup (desc, wc);
}
--- 113,119 ----
else
{
/* New locale format. */
! size_t i = locale->__locales[LC_CTYPE]->values[_NL_ITEM_INDEX (_NL_CTYPE_MAP_OFFSET)].word + __TOW_toupper;
const char *desc = locale->__locales[LC_CTYPE]->values[i].string;
return wctrans_table_lookup (desc, wc);
}
*** glibc-20000724/wctype/wctrans.c.bak Tue Jul 25 00:08:37 2000
--- glibc-20000724/wctype/wctrans.c Thu Jul 27 13:35:25 2000
***************
*** 50,58 ****
if (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_HASH_SIZE) != 0)
{
/* Old locale format. */
! if (cnt == 0)
return (wctrans_t) __ctype32_toupper;
! else if (cnt == 1)
return (wctrans_t) __ctype32_tolower;
/* We have to search the table. */
--- 50,58 ----
if (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_HASH_SIZE) != 0)
{
/* Old locale format. */
! if (cnt == __TOW_toupper)
return (wctrans_t) __ctype32_toupper;
! else if (cnt == __TOW_tolower)
return (wctrans_t) __ctype32_tolower;
/* We have to search the table. */
*** glibc-20000724/wctype/wctrans_l.c.bak Tue Jul 25 00:08:37 2000
--- glibc-20000724/wctype/wctrans_l.c Thu Jul 27 13:35:05 2000
***************
*** 43,51 ****
if (locale->__locales[LC_CTYPE]->values[_NL_ITEM_INDEX (_NL_CTYPE_HASH_SIZE)].word == 0)
{
/* Old locale format. */
! if (cnt == 0)
return (wctrans_t) locale->__locales[LC_CTYPE]->values[_NL_ITEM_INDEX (_NL_CTYPE_TOUPPER32)].string;
! else if (cnt == 1)
return (wctrans_t) locale->__locales[LC_CTYPE]->values[_NL_ITEM_INDEX (_NL_CTYPE_TOLOWER32)].string;
/* We have to search the table. */
--- 43,51 ----
if (locale->__locales[LC_CTYPE]->values[_NL_ITEM_INDEX (_NL_CTYPE_HASH_SIZE)].word == 0)
{
/* Old locale format. */
! if (cnt == __TOW_toupper)
return (wctrans_t) locale->__locales[LC_CTYPE]->values[_NL_ITEM_INDEX (_NL_CTYPE_TOUPPER32)].string;
! else if (cnt == __TOW_tolower)
return (wctrans_t) locale->__locales[LC_CTYPE]->values[_NL_ITEM_INDEX (_NL_CTYPE_TOLOWER32)].string;
/* We have to search the table. */
More information about the Libc-alpha
mailing list