Index: lib/libc/locale/rune.c =================================================================== RCS file: /cvsroot/src/lib/libc/locale/rune.c,v retrieving revision 1.29 diff -u -r1.29 rune.c --- lib/libc/locale/rune.c 19 Mar 2006 02:54:38 -0000 1.29 +++ lib/libc/locale/rune.c 27 Sep 2007 10:16:56 -0000 @@ -339,6 +339,9 @@ free(__UNCONST(rl->rl_codeset)); if (rl->rl_citrus_ctype) _citrus_ctype_close(rl->rl_citrus_ctype); + free(__UNCONST(rl->rl_ctype_tab)); + free(__UNCONST(rl->rl_tolower_tab)); + free(__UNCONST(rl->rl_toupper_tab)); free(rl); } } @@ -472,7 +475,7 @@ /* * __runetable_to_netbsd_ctype() will be called from - * setlocale.c:loadlocale(), and fill old ctype table. + * setrunelocale.c:_newrunelocale(), and fill old ctype table. */ free(new_ctype); Index: lib/libc/locale/rune_local.h =================================================================== RCS file: /cvsroot/src/lib/libc/locale/rune_local.h,v retrieving revision 1.8 diff -u -r1.8 rune_local.h --- lib/libc/locale/rune_local.h 29 Nov 2005 03:11:59 -0000 1.8 +++ lib/libc/locale/rune_local.h 27 Sep 2007 10:16:56 -0000 @@ -40,7 +40,7 @@ extern int _newrunelocale __P((char *)); /* runeglue.c */ -extern int __runetable_to_netbsd_ctype __P((const char *)); +extern int __runetable_to_netbsd_ctype __P((_RuneLocale *)); /* ___runetype_mb.c */ extern _RuneType ___runetype_mb __P((wint_t)); Index: lib/libc/locale/runeglue.c =================================================================== RCS file: /cvsroot/src/lib/libc/locale/runeglue.c,v retrieving revision 1.11 diff -u -r1.11 runeglue.c --- lib/libc/locale/runeglue.c 29 Nov 2005 03:11:59 -0000 1.11 +++ lib/libc/locale/runeglue.c 27 Sep 2007 10:16:56 -0000 @@ -47,6 +47,8 @@ #include #include #include +#include "citrus/citrus_module.h" +#include "citrus/citrus_ctype.h" #include "rune.h" #include "rune_local.h" @@ -58,32 +60,15 @@ #endif int -__runetable_to_netbsd_ctype(locale) - const char *locale; +__runetable_to_netbsd_ctype(rl) + _RuneLocale *rl; { - int i; + int i, ch; unsigned char *new_ctype; short *new_toupper, *new_tolower; _DIAGASSERT(locale != NULL); - /* set to C locale, to ease failure case handling */ - if (_ctype_ != _C_ctype_) { - free(__UNCONST(_ctype_)); - _ctype_ = _C_ctype_; - } - if (_toupper_tab_ != _C_toupper_) { - free(__UNCONST(_toupper_tab_)); - _toupper_tab_ = _C_toupper_; - } - if (_tolower_tab_ != _C_tolower_) { - free(__UNCONST(_tolower_tab_)); - _tolower_tab_ = _C_tolower_; - } - - if (!strcmp(locale, "C") || !strcmp(locale, "POSIX")) - return 0; - new_ctype = malloc(sizeof(*new_ctype) * (1 + _CTYPE_NUM_CHARS)); if (!new_ctype) return -1; @@ -107,20 +92,36 @@ new_toupper[0] = EOF; new_tolower[0] = EOF; for (i = 0; i < _CTYPE_NUM_CHARS; i++) { - new_ctype[i + 1]=0; - if (_CurrentRuneLocale->rl_runetype[i] & _CTYPE_U) + new_ctype[i + 1] = 0; + new_toupper[i + 1] = i; + new_tolower[i + 1] = i; + + /* XXX: FIXME + * expected 'x' == L'x', see defect report #279 + * http://www.open-std.org/JTC1/SC22/WG14/www/docs/dr_279.htm + */ + if (_citrus_ctype_wctob(rl->rl_citrus_ctype, (wint_t)i, &ch)) { + free(new_ctype); + free(new_toupper); + free(new_tolower); + return -1; + } + if (ch == EOF) + continue; + + if (rl->rl_runetype[i] & _CTYPE_U) new_ctype[i + 1] |= _U; - if (_CurrentRuneLocale->rl_runetype[i] & _CTYPE_L) + if (rl->rl_runetype[i] & _CTYPE_L) new_ctype[i + 1] |= _L; - if (_CurrentRuneLocale->rl_runetype[i] & _CTYPE_D) + if (rl->rl_runetype[i] & _CTYPE_D) new_ctype[i + 1] |= _N; - if (_CurrentRuneLocale->rl_runetype[i] & _CTYPE_S) + if (rl->rl_runetype[i] & _CTYPE_S) new_ctype[i + 1] |= _S; - if (_CurrentRuneLocale->rl_runetype[i] & _CTYPE_P) + if (rl->rl_runetype[i] & _CTYPE_P) new_ctype[i + 1] |= _P; - if (_CurrentRuneLocale->rl_runetype[i] & _CTYPE_C) + if (rl->rl_runetype[i] & _CTYPE_C) new_ctype[i + 1] |= _C; - if (_CurrentRuneLocale->rl_runetype[i] & _CTYPE_X) + if (rl->rl_runetype[i] & _CTYPE_X) new_ctype[i + 1] |= _X; /* * TWEAK! _B has been used incorrectly (or with older @@ -130,23 +131,22 @@ * function (i.e. isblank() is inherently locale unfriendly). */ #if 1 - if ((_CurrentRuneLocale->rl_runetype[i] & (_CTYPE_R | _CTYPE_G)) - == _CTYPE_R) + if ((rl->rl_runetype[i] & (_CTYPE_R | _CTYPE_G)) == _CTYPE_R) new_ctype[i + 1] |= _B; #else - if (_CurrentRuneLocale->rl_runetype[i] & _CTYPE_B) + if (rl->rl_runetype[i] & _CTYPE_B) new_ctype[i + 1] |= _B; #endif - new_toupper[i + 1] = (short)_CurrentRuneLocale->rl_mapupper[i]; - new_tolower[i + 1] = (short)_CurrentRuneLocale->rl_maplower[i]; + new_toupper[i + 1] = (short)rl->rl_mapupper[i]; + new_tolower[i + 1] = (short)rl->rl_maplower[i]; } /* LINTED const cast */ - _ctype_ = (const unsigned char *)new_ctype; + rl->rl_ctype_tab = (const unsigned char *)new_ctype; /* LINTED const cast */ - _toupper_tab_ = (const short *)new_toupper; + rl->rl_toupper_tab = (const short *)new_toupper; /* LINTED const cast */ - _tolower_tab_ = (const short *)new_tolower; + rl->rl_tolower_tab = (const short *)new_tolower; return 0; } Index: lib/libc/locale/runetable.c =================================================================== RCS file: /cvsroot/src/lib/libc/locale/runetable.c,v retrieving revision 1.14 diff -u -r1.14 runetable.c --- lib/libc/locale/runetable.c 17 Jan 2007 23:24:22 -0000 1.14 +++ lib/libc/locale/runetable.c 27 Sep 2007 10:16:56 -0000 @@ -44,6 +44,7 @@ #endif /* LIBC_SCCS and not lint */ #include +#define _CTYPE_PRIVATE #include #include #include @@ -276,7 +277,10 @@ { "space", _CTYPE_S }, { "upper", _CTYPE_U }, { "xdigit", _CTYPE_X }, - } + }, + _C_ctype_, + _C_tolower_, + _C_toupper_ }; _RuneLocale *_CurrentRuneLocale = &_DefaultRuneLocale; Index: lib/libc/locale/runetype.h =================================================================== RCS file: /cvsroot/src/lib/libc/locale/runetype.h,v retrieving revision 1.19 diff -u -r1.19 runetype.h --- lib/libc/locale/runetype.h 29 Nov 2005 03:11:59 -0000 1.19 +++ lib/libc/locale/runetype.h 27 Sep 2007 10:16:56 -0000 @@ -89,14 +89,14 @@ int32_t fre_map; /* What first maps to in maps */ uint32_t fre_pad1; /* backward compatibility */ __runepad_t fre_pad2; /* backward compatibility */ -} __attribute__((__packed__)) _FileRuneEntry; +} __packed _FileRuneEntry; typedef struct { uint32_t frr_nranges; /* Number of ranges stored */ uint32_t frr_pad1; /* backward compatibility */ __runepad_t frr_pad2; /* backward compatibility */ -} __attribute__((__packed__)) _FileRuneRange; +} __packed _FileRuneRange; typedef struct { @@ -126,7 +126,7 @@ uint32_t frl_pad5; /* backward compatibility */ /* variable size data follows */ -} __attribute__((__packed__)) _FileRuneLocale; +} __packed _FileRuneLocale; /* @@ -207,6 +207,10 @@ struct _citrus_ctype_rec *rl_citrus_ctype; _WCTransEntry rl_wctrans[_WCTRANS_NINDEXES]; _WCTypeEntry rl_wctype[_WCTYPE_NINDEXES]; + + const unsigned char *rl_ctype_tab; + const short *rl_tolower_tab; + const short *rl_toupper_tab; } _NBRuneLocale; Index: lib/libc/locale/setlocale.c =================================================================== RCS file: /cvsroot/src/lib/libc/locale/setlocale.c,v retrieving revision 1.51 diff -u -r1.51 setlocale.c --- lib/libc/locale/setlocale.c 28 Mar 2007 19:05:53 -0000 1.51 +++ lib/libc/locale/setlocale.c 27 Sep 2007 10:16:57 -0000 @@ -245,7 +245,6 @@ case LC_CTYPE: #ifdef WITH_RUNE (void)_xpg4_setrunelocale("C"); - (void)__runetable_to_netbsd_ctype("C"); #else if (_ctype_ != _C_ctype_) { /* LINTED const castaway */ @@ -318,11 +317,6 @@ #ifdef WITH_RUNE if (_xpg4_setrunelocale(__UNCONST(locname))) return -1; - if (__runetable_to_netbsd_ctype(locname)) { - /* very unfortunate, but need to go to "C" locale */ - revert_to_default(category); - return -1; - } #else if (!__loadctype(name)) return -1; Index: lib/libc/locale/setrunelocale.c =================================================================== RCS file: /cvsroot/src/lib/libc/locale/setrunelocale.c,v retrieving revision 1.16 diff -u -r1.16 setrunelocale.c --- lib/libc/locale/setrunelocale.c 29 Nov 2005 03:11:59 -0000 1.16 +++ lib/libc/locale/setrunelocale.c 27 Sep 2007 10:16:57 -0000 @@ -103,6 +103,7 @@ #include "rune.h" #include +#include #include #include #include @@ -176,6 +177,8 @@ ret = _citrus_ctype_open(&rl->rl_citrus_ctype, rl->rl_encoding, rl->rl_variable, rl->rl_variable_len, _PRIVSIZE); + if (!ret) + ret = __runetable_to_netbsd_ctype(rl); if (ret) { _NukeRune(rl); return ret; @@ -260,6 +263,9 @@ return ENOENT; found: + _ctype_ = rl->rl_ctype_tab; + _tolower_tab_ = rl->rl_tolower_tab; + _toupper_tab_ = rl->rl_toupper_tab; _CurrentRuneLocale = rl; __mb_cur_max = _citrus_ctype_get_mb_cur_max(rl->rl_citrus_ctype);