From 843c97b01ffdff290d34649ec3c6bc0db091d476 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Thu, 20 Mar 2025 16:13:59 -0400 Subject: [PATCH] libroot: Make glibc use the native Haiku locale structs. It accesses values through macros, so just write functions that fetch the appropriate value from Haiku's structures. Note that the values for multibyte digit characters are hardcoded. As far as I can tell, we never set or updated these in glibc's locale structures, so it always just used the default, so this should not be a behavioral change from before. --- .../private/libroot/locale/LocaleBackend.h | 26 --- headers/private/libroot/locale/ThreadLocale.h | 36 +-- src/system/libroot/Jamfile | 2 - .../libroot/add-ons/icu/ICUNumericData.cpp | 11 - src/system/libroot/posix/glibc/Jamfile | 2 - .../libroot/posix/glibc/include/langinfo.h | 1 - .../libroot/posix/glibc/include/locale.h | 10 - .../libroot/posix/glibc/include/xlocale.h | 2 +- .../libroot/posix/glibc/locale/locale.h | 157 ------------- .../libroot/posix/glibc/locale/localeinfo.h | 214 +++++++++++------- .../libroot/posix/locale/LocaleDataBridge.cpp | 30 --- .../libroot/posix/locale/ThreadLocale.cpp | 25 +- 12 files changed, 142 insertions(+), 374 deletions(-) delete mode 100644 src/system/libroot/posix/glibc/include/langinfo.h delete mode 100644 src/system/libroot/posix/glibc/include/locale.h delete mode 100644 src/system/libroot/posix/glibc/locale/locale.h diff --git a/headers/private/libroot/locale/LocaleBackend.h b/headers/private/libroot/locale/LocaleBackend.h index 20c06ec0d3..ce2d982f99 100644 --- a/headers/private/libroot/locale/LocaleBackend.h +++ b/headers/private/libroot/locale/LocaleBackend.h @@ -14,7 +14,6 @@ struct lc_time_t; -struct locale_data; // glibc namespace BPrivate { @@ -60,37 +59,12 @@ struct LocaleMonetaryDataBridge { struct LocaleNumericDataBridge { -private: - // struct used by glibc to store numeric locale data - struct GlibcNumericLocale { - const char* name; - const char* filedata; - off_t filesize; - int mmaped; - unsigned int usage_count; - int use_translit; - const char *options; - unsigned int nstrings; - union locale_data_value - { - const uint32_t* wstr; - const char* string; - unsigned int word; - } - values[6]; - }; - locale_data* originalGlibcLocale; - GlibcNumericLocale glibcNumericLocaleData; - public: const struct lconv* const posixLocaleConv; - GlibcNumericLocale* glibcNumericLocale; bool isGlobal; LocaleNumericDataBridge(bool isGlobal); ~LocaleNumericDataBridge(); - - void ApplyToCurrentThread(); }; diff --git a/headers/private/libroot/locale/ThreadLocale.h b/headers/private/libroot/locale/ThreadLocale.h index 99dd64ef32..57b3cb51d5 100644 --- a/headers/private/libroot/locale/ThreadLocale.h +++ b/headers/private/libroot/locale/ThreadLocale.h @@ -3,7 +3,6 @@ * All rights reserved. Distributed under the terms of the MIT License. */ - #ifndef _THREAD_LOCALE_H #define _THREAD_LOCALE_H @@ -15,38 +14,13 @@ namespace BPrivate { namespace Libroot { -// This struct is taken from glibc's __locale_struct -// from xlocale.h. -// It will also be used by glibc so it should have the same -// layout. -struct GlibcLocaleStruct { - void *__locales[7]; /* 7 = __LC_LAST. */ - - const unsigned short int *__ctype_b; - const int *__ctype_tolower; - const int *__ctype_toupper; -}; - - -// Taken from glibc's bits/locale.h -// glibc uses different codes from our the native locale.h. -// This should be the values used for the indexes -// in GlibcLocaleStruct. -enum { - GLIBC_LC_CTYPE = 0, - GLIBC_LC_NUMERIC = 1, - GLIBC_LC_TIME = 2, - GLIBC_LC_COLLATE = 3, - GLIBC_LC_MONETARY = 4, - GLIBC_LC_MESSAGES = 5, - GLIBC_LC_ALL = 6, -}; - - // The pointer in the TLS will point to this struct. struct ThreadLocale { - GlibcLocaleStruct glibcLocaleStruct; - LocaleBackendData* threadLocaleInfo; + LocaleBackendData* threadLocaleInfo; + + const unsigned short int* ctype_b; + const int* ctype_tolower; + const int* ctype_toupper; }; diff --git a/src/system/libroot/Jamfile b/src/system/libroot/Jamfile index 81411a3a5d..012ae9f7f5 100644 --- a/src/system/libroot/Jamfile +++ b/src/system/libroot/Jamfile @@ -37,11 +37,9 @@ for architectureObject in [ MultiArchSubDirSetup ] { posix_stdio.o posix_musl.o posix_gnu_arch_$(TARGET_ARCH).o - posix_gnu_ctype.o posix_gnu_ext.o posix_gnu_iconv.o posix_gnu_libio.o - posix_gnu_locale.o posix_gnu_regex.o posix_gnu_stdio.o posix_gnu_stdlib.o diff --git a/src/system/libroot/add-ons/icu/ICUNumericData.cpp b/src/system/libroot/add-ons/icu/ICUNumericData.cpp index 733867ab90..f498f14795 100644 --- a/src/system/libroot/add-ons/icu/ICUNumericData.cpp +++ b/src/system/libroot/add-ons/icu/ICUNumericData.cpp @@ -34,9 +34,6 @@ ICUNumericData::ICUNumericData(pthread_key_t tlsKey, struct lconv& localeConv) void ICUNumericData::Initialize(LocaleNumericDataBridge* dataBridge) { - dataBridge->glibcNumericLocale->values[0].string = fDecimalPoint; - dataBridge->glibcNumericLocale->values[1].string = fThousandsSep; - dataBridge->glibcNumericLocale->values[2].string = fGrouping; fDataBridge = dataBridge; } @@ -62,14 +59,10 @@ ICUNumericData::SetTo(const Locale& locale, const char* posixLocaleName) if (result == B_OK) { result = _SetLocaleconvEntry(formatSymbols, fDecimalPoint, DecimalFormatSymbols::kDecimalSeparatorSymbol); - fDataBridge->glibcNumericLocale->values[3].word - = (unsigned int)fDecimalPoint[0]; } if (result == B_OK) { result = _SetLocaleconvEntry(formatSymbols, fThousandsSep, DecimalFormatSymbols::kGroupingSeparatorSymbol); - fDataBridge->glibcNumericLocale->values[4].word - = (unsigned int)fThousandsSep[0]; } if (result == B_OK) { int32 groupingSize = numberFormat->getGroupingSize(); @@ -104,10 +97,6 @@ ICUNumericData::SetToPosix() strcpy(fDecimalPoint, fDataBridge->posixLocaleConv->decimal_point); strcpy(fThousandsSep, fDataBridge->posixLocaleConv->thousands_sep); strcpy(fGrouping, fDataBridge->posixLocaleConv->grouping); - fDataBridge->glibcNumericLocale->values[3].word - = (unsigned int)fDecimalPoint[0]; - fDataBridge->glibcNumericLocale->values[4].word - = (unsigned int)fThousandsSep[0]; } return result; diff --git a/src/system/libroot/posix/glibc/Jamfile b/src/system/libroot/posix/glibc/Jamfile index f35be1c6cc..e634d9b6e5 100644 --- a/src/system/libroot/posix/glibc/Jamfile +++ b/src/system/libroot/posix/glibc/Jamfile @@ -5,11 +5,9 @@ for arch in $(TARGET_ARCHS) { HaikuSubInclude arch $(arch) ; } -SubInclude HAIKU_TOP src system libroot posix glibc ctype ; SubInclude HAIKU_TOP src system libroot posix glibc extensions ; SubInclude HAIKU_TOP src system libroot posix glibc iconv ; SubInclude HAIKU_TOP src system libroot posix glibc libio ; -SubInclude HAIKU_TOP src system libroot posix glibc locale ; SubInclude HAIKU_TOP src system libroot posix glibc regex ; SubInclude HAIKU_TOP src system libroot posix glibc stdio-common ; SubInclude HAIKU_TOP src system libroot posix glibc stdlib ; diff --git a/src/system/libroot/posix/glibc/include/langinfo.h b/src/system/libroot/posix/glibc/include/langinfo.h deleted file mode 100644 index 2a81c6ddaf..0000000000 --- a/src/system/libroot/posix/glibc/include/langinfo.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/src/system/libroot/posix/glibc/include/locale.h b/src/system/libroot/posix/glibc/include/locale.h deleted file mode 100644 index 4374792d14..0000000000 --- a/src/system/libroot/posix/glibc/include/locale.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _LOCALE_H -#include - -/* Locale object for C locale. */ -extern struct __locale_struct _nl_C_locobj; - -/* Now define the internal interfaces. */ -extern struct lconv *__localeconv (void); - -#endif diff --git a/src/system/libroot/posix/glibc/include/xlocale.h b/src/system/libroot/posix/glibc/include/xlocale.h index 5280ef0bc4..567ee86463 100644 --- a/src/system/libroot/posix/glibc/include/xlocale.h +++ b/src/system/libroot/posix/glibc/include/xlocale.h @@ -1 +1 @@ -#include +/* Nothing here. */ diff --git a/src/system/libroot/posix/glibc/locale/locale.h b/src/system/libroot/posix/glibc/locale/locale.h deleted file mode 100644 index 2770798b6f..0000000000 --- a/src/system/libroot/posix/glibc/locale/locale.h +++ /dev/null @@ -1,157 +0,0 @@ -/* Copyright (C) 1991,92,1995-1999,2000,2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* - * ISO C99 Standard: 7.11 Localization - */ - -#ifndef _LOCALE_H -#define _LOCALE_H 1 - -#include - -#define __need_NULL -#include -#include - -__BEGIN_DECLS - -/* These are the possibilities for the first argument to setlocale. - The code assumes that the lowest LC_* symbol has the value zero. */ -#define LC_CTYPE __LC_CTYPE -#define LC_NUMERIC __LC_NUMERIC -#define LC_TIME __LC_TIME -#define LC_COLLATE __LC_COLLATE -#define LC_MONETARY __LC_MONETARY -#define LC_MESSAGES __LC_MESSAGES -#define LC_ALL __LC_ALL - - -/* Structure giving information about numeric and monetary notation. */ -struct lconv -{ - /* Numeric (non-monetary) information. */ - - char *decimal_point; /* Decimal point character. */ - char *thousands_sep; /* Thousands separator. */ - /* Each element is the number of digits in each group; - elements with higher indices are farther left. - An element with value CHAR_MAX means that no further grouping is done. - An element with value 0 means that the previous element is used - for all groups farther left. */ - char *grouping; - - /* Monetary information. */ - - /* First three chars are a currency symbol from ISO 4217. - Fourth char is the separator. Fifth char is '\0'. */ - char *int_curr_symbol; - char *currency_symbol; /* Local currency symbol. */ - char *mon_decimal_point; /* Decimal point character. */ - char *mon_thousands_sep; /* Thousands separator. */ - char *mon_grouping; /* Like `grouping' element (above). */ - char *positive_sign; /* Sign for positive values. */ - char *negative_sign; /* Sign for negative values. */ - char int_frac_digits; /* Int'l fractional digits. */ - char frac_digits; /* Local fractional digits. */ - /* 1 if currency_symbol precedes a positive value, 0 if succeeds. */ - char p_cs_precedes; - /* 1 iff a space separates currency_symbol from a positive value. */ - char p_sep_by_space; - /* 1 if currency_symbol precedes a negative value, 0 if succeeds. */ - char n_cs_precedes; - /* 1 iff a space separates currency_symbol from a negative value. */ - char n_sep_by_space; - /* Positive and negative sign positions: - 0 Parentheses surround the quantity and currency_symbol. - 1 The sign string precedes the quantity and currency_symbol. - 2 The sign string follows the quantity and currency_symbol. - 3 The sign string immediately precedes the currency_symbol. - 4 The sign string immediately follows the currency_symbol. */ - char p_sign_posn; - char n_sign_posn; -#ifdef __USE_ISOC99 - /* 1 if int_curr_symbol precedes a positive value, 0 if succeeds. */ - char int_p_cs_precedes; - /* 1 iff a space separates int_curr_symbol from a positive value. */ - char int_p_sep_by_space; - /* 1 if int_curr_symbol precedes a negative value, 0 if succeeds. */ - char int_n_cs_precedes; - /* 1 iff a space separates int_curr_symbol from a negative value. */ - char int_n_sep_by_space; - /* Positive and negative sign positions: - 0 Parentheses surround the quantity and int_curr_symbol. - 1 The sign string precedes the quantity and int_curr_symbol. - 2 The sign string follows the quantity and int_curr_symbol. - 3 The sign string immediately precedes the int_curr_symbol. - 4 The sign string immediately follows the int_curr_symbol. */ - char int_p_sign_posn; - char int_n_sign_posn; -#else - char __int_p_cs_precedes; - char __int_p_sep_by_space; - char __int_n_cs_precedes; - char __int_n_sep_by_space; - char __int_p_sign_posn; - char __int_n_sign_posn; -#endif -}; - - -/* Set and/or return the current locale. */ -extern char *setlocale (int __category, __const char *__locale) __THROW; - -/* Return the numeric/monetary information for the current locale. */ -extern struct lconv *localeconv (void) __THROW; - -#ifdef __USE_GNU -/* The concept of one static locale per category is not very well - thought out. Many applications will need to process its data using - information from several different locales. Another application is - the implementation of the internationalization handling in the - upcoming ISO C++ standard library. To support this another set of - the functions using locale data exist which have an additional - argument. - - Attention: all these functions are *not* standardized in any form. - This is a proof-of-concept implementation. */ - -/* Get locale datatype definition. */ -# include - -/* Return a reference to a data structure representing a set of locale - datasets. Unlike for the CATEGORY parameter for `setlocale' the - CATEGORY_MASK parameter here uses a single bit for each category. - I.e., 1 << LC_CTYPE means to load data for this category. If - BASE is non-null the appropriate category information in the BASE - record is replaced. */ -extern __locale_t __newlocale (int __category_mask, __const char *__locale, - __locale_t __base) __THROW; - -/* Return a duplicate of the set of locale in DATASET. All usage - counters are increased if necessary. */ -extern __locale_t __duplocale (__locale_t __dataset) __THROW; - -/* Free the data associated with a locale dataset previously returned - by a call to `setlocale_r'. */ -extern void __freelocale (__locale_t __dataset) __THROW; -#endif - -__END_DECLS - -#endif /* locale.h */ diff --git a/src/system/libroot/posix/glibc/locale/localeinfo.h b/src/system/libroot/posix/glibc/locale/localeinfo.h index def5e06979..5e477b6fcd 100644 --- a/src/system/libroot/posix/glibc/locale/localeinfo.h +++ b/src/system/libroot/posix/glibc/locale/localeinfo.h @@ -1,109 +1,149 @@ -/* Declarations for internal libc locale interfaces - Copyright (C) 1995, 96, 97, 98, 99,2000,2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - +/* + * Copyright 2025, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ #ifndef _LOCALEINFO_H -#define _LOCALEINFO_H 1 +#define _LOCALEINFO_H -#include -#include -#include -#include -#include -#include -// __locale_struct -#include -// LC_* values +#include #include +#include -/* This has to be changed whenever a new locale is defined. */ -#define __LC_LAST 7 -/* We use a special value for the usage counter in `locale_data' to - signal that this data must never be removed anymore. */ -#define MAX_USAGE_COUNT (UINT_MAX - 1) -#define UNDELETABLE UINT_MAX +enum { + LC_CTYPE__NL_CTYPE_OUTDIGITS_MB_LEN = 0, + LC_CTYPE__NL_CTYPE_OUTDIGIT0_MB, + LC_CTYPE__NL_CTYPE_OUTDIGIT1_MB, + LC_CTYPE__NL_CTYPE_OUTDIGIT2_MB, + LC_CTYPE__NL_CTYPE_OUTDIGIT3_MB, + LC_CTYPE__NL_CTYPE_OUTDIGIT4_MB, + LC_CTYPE__NL_CTYPE_OUTDIGIT5_MB, + LC_CTYPE__NL_CTYPE_OUTDIGIT6_MB, + LC_CTYPE__NL_CTYPE_OUTDIGIT7_MB, + LC_CTYPE__NL_CTYPE_OUTDIGIT8_MB, + LC_CTYPE__NL_CTYPE_OUTDIGIT9_MB, + LC_CTYPE__NL_CTYPE_MB_CUR_MAX, -/* Structure describing locale data in core for a category. */ -struct locale_data -{ - const char *name; - const char *filedata; /* Region mapping the file data. */ - off_t filesize; /* Size of the file (and the region). */ - int mmaped; /* If nonzero the data is mmaped. */ +#define LC_CTYPE__NL_CTYPE_INDIGITS_MB_LEN LC_CTYPE__NL_CTYPE_OUTDIGITS_MB_LEN +#define LC_CTYPE__NL_CTYPE_INDIGITS0_MB LC_CTYPE__NL_CTYPE_OUTDIGIT0_MB - unsigned int usage_count; /* Counter for users. */ +#define LC_CTYPE__NL_CTYPE_OUTDIGITS_WC_LEN LC_CTYPE__NL_CTYPE_OUTDIGITS_MB_LEN +#define LC_CTYPE__NL_CTYPE_OUTDIGIT0_WC LC_CTYPE__NL_CTYPE_OUTDIGIT0_MB +#define LC_CTYPE__NL_CTYPE_INDIGITS_WC_LEN LC_CTYPE__NL_CTYPE_INDIGITS_MB_LEN +#define LC_CTYPE__NL_CTYPE_INDIGITS0_WC LC_CTYPE__NL_CTYPE_INDIGITS0_MB - int use_translit; /* Nonzero if the mb*towv*() and wc*tomb() - functions should use transliteration. */ - const char *options; /* Extra options from the locale name, - not used in the path to the locale data. */ + LC_MONETARY_MON_DECIMAL_POINT, + LC_MONETARY_MON_THOUSANDS_SEP, + LC_MONETARY_MON_GROUPING, - unsigned int nstrings; /* Number of strings below. */ - union locale_data_value - { - const uint32_t *wstr; - const char *string; - unsigned int word; - } - values __flexarr; /* Items, usually pointers into `filedata'. */ +#define LC_MONETARY__NL_MONETARY_DECIMAL_POINT_WC LC_MONETARY_MON_DECIMAL_POINT +#define LC_MONETARY__NL_MONETARY_THOUSANDS_SEP_WC LC_MONETARY_MON_THOUSANDS_SEP + + LC_NUMERIC_DECIMAL_POINT, + LC_NUMERIC_THOUSANDS_SEP, + LC_NUMERIC_GROUPING, + +#define LC_NUMERIC__NL_NUMERIC_DECIMAL_POINT_WC LC_NUMERIC_DECIMAL_POINT +#define LC_NUMERIC__NL_NUMERIC_THOUSANDS_SEP_WC LC_NUMERIC_THOUSANDS_SEP }; +static inline const char* +_nl_current(int value) +{ + struct lconv* lconv = localeconv(); + switch (value) { + // TODO: Not correct for non-ASCII/UTF-8 multibyte locales! + // (perhaps via alloca+wcrtomb? or do we need new localeinfo?) +#define DIGIT(D) case LC_CTYPE__NL_CTYPE_OUTDIGIT##D##_MB: return #D + DIGIT(0); + DIGIT(1); + DIGIT(2); + DIGIT(3); + DIGIT(4); + DIGIT(5); + DIGIT(6); + DIGIT(7); + DIGIT(8); + DIGIT(9); +#undef DIGIT -/* Name of the standard locales. */ -extern const char _nl_C_name[]; -extern const char _nl_POSIX_name[]; + case LC_MONETARY_MON_DECIMAL_POINT: + return lconv->mon_decimal_point; + case LC_MONETARY_MON_THOUSANDS_SEP: + return lconv->mon_thousands_sep; + case LC_MONETARY_MON_GROUPING: + return lconv->mon_grouping; -/* The standard codeset. */ -extern const char _nl_C_codeset[]; + case LC_NUMERIC_DECIMAL_POINT: + return lconv->decimal_point; + case LC_NUMERIC_THOUSANDS_SEP: + return lconv->thousands_sep; + case LC_NUMERIC_GROUPING: + return lconv->grouping; + } + return NULL; +} -/* This is the internal locale_t object that holds the global locale - controlled by calls to setlocale. A thread's TSD locale pointer - points to this when `uselocale (LC_GLOBAL_LOCALE)' is in effect. */ -extern struct __locale_struct _nl_global_locale; +static inline const wchar_t +_nl_current_word(int value) +{ + struct lconv* lconv = NULL; + mbstate_t temp; + const char* str = NULL; + wchar_t out = 0; -extern struct __locale_struct* _nl_current_locale(); -#define _NL_CURRENT_LOCALE (_nl_current_locale()) + switch (value) { + case LC_CTYPE__NL_CTYPE_OUTDIGITS_WC_LEN: + return 1; + + /* We always use UTF-32 in wchar_t. */ +#define DIGIT(D) case LC_CTYPE__NL_CTYPE_OUTDIGIT##D##_MB: return 0x0030 + D + DIGIT(0); + DIGIT(1); + DIGIT(2); + DIGIT(3); + DIGIT(4); + DIGIT(5); + DIGIT(6); + DIGIT(7); + DIGIT(8); + DIGIT(9); +#undef DIGIT + + case LC_CTYPE__NL_CTYPE_MB_CUR_MAX: + return __ctype_get_mb_cur_max(); + + case LC_MONETARY_MON_DECIMAL_POINT: + lconv = localeconv(); + str = lconv->mon_decimal_point; + break; + case LC_MONETARY_MON_THOUSANDS_SEP: + lconv = localeconv(); + str = lconv->mon_thousands_sep; + break; + + case LC_NUMERIC_DECIMAL_POINT: + lconv = localeconv(); + str = lconv->decimal_point; + break; + case LC_NUMERIC_THOUSANDS_SEP: + lconv = localeconv(); + str = lconv->thousands_sep; + break; + } + if (str == NULL) + return out; + + mbrtowc(&out, str, 1, &temp); + return out; +} -/* Return a pointer to the current `struct __locale_data' for CATEGORY. */ -#define _NL_CURRENT_DATA(category) \ - (_NL_CURRENT_LOCALE->__locales[category]) -/* Extract the current CATEGORY locale's string for ITEM. */ #define _NL_CURRENT(category, item) \ - (_NL_CURRENT_DATA (category)->values[_NL_ITEM_INDEX (item)].string) - -/* Extract the current CATEGORY locale's string for ITEM. */ -#define _NL_CURRENT_WSTR(category, item) \ - ((wchar_t *) _NL_CURRENT_DATA (category)->values[_NL_ITEM_INDEX (item)].wstr) - -/* Extract the current CATEGORY locale's word for ITEM. */ + _nl_current(category##_##item) #define _NL_CURRENT_WORD(category, item) \ - ((uint32_t) _NL_CURRENT_DATA (category)->values[_NL_ITEM_INDEX (item)].word) - -/* This is used in lc-CATEGORY.c to define _nl_current_CATEGORY. */ -#define _NL_CURRENT_DEFINE(category) \ - /* No per-category variable here. */ - -/* Postload processing. */ -extern void _nl_postload_ctype (void); -extern void _nl_postload_time (void); + _nl_current_word(category##_##item) -#endif /* localeinfo.h */ +#endif /* _LOCALEINFO_H */ diff --git a/src/system/libroot/posix/locale/LocaleDataBridge.cpp b/src/system/libroot/posix/locale/LocaleDataBridge.cpp index 306a5dd54c..3581612a67 100644 --- a/src/system/libroot/posix/locale/LocaleDataBridge.cpp +++ b/src/system/libroot/posix/locale/LocaleDataBridge.cpp @@ -27,14 +27,6 @@ namespace BPrivate { namespace Libroot { -extern "C" GlibcLocaleStruct* _nl_current_locale(); -extern "C" GlibcLocaleStruct _nl_global_locale; -#define _NL_CURRENT_DATA(category) \ - ((locale_data*&)(_nl_current_locale()->__locales[category])) -#define _NL_GLOBAL_DATA(category) \ - ((locale_data*&)(_nl_global_locale.__locales[category])) - - LocaleCtypeDataBridge::LocaleCtypeDataBridge(bool isGlobal) : localClassInfoTable(__ctype_b), @@ -89,34 +81,13 @@ LocaleMonetaryDataBridge::LocaleMonetaryDataBridge() LocaleNumericDataBridge::LocaleNumericDataBridge(bool isGlobal) : posixLocaleConv(&gPosixLocaleConv), - glibcNumericLocale(&glibcNumericLocaleData), isGlobal(isGlobal) { - - memcpy(glibcNumericLocale, _NL_GLOBAL_DATA(GLIBC_LC_NUMERIC), - sizeof(GlibcNumericLocale)); - - if (isGlobal) { - originalGlibcLocale = _NL_GLOBAL_DATA(GLIBC_LC_NUMERIC); - _NL_GLOBAL_DATA(GLIBC_LC_NUMERIC) = (locale_data*)glibcNumericLocale; - } } LocaleNumericDataBridge::~LocaleNumericDataBridge() { - if (isGlobal) { - _NL_GLOBAL_DATA(GLIBC_LC_NUMERIC) = originalGlibcLocale; - } else if (_NL_CURRENT_DATA(GLIBC_LC_NUMERIC) == (locale_data*)glibcNumericLocale) { - _NL_CURRENT_DATA(GLIBC_LC_NUMERIC) = _NL_GLOBAL_DATA(GLIBC_LC_NUMERIC); - } -} - - -void -LocaleNumericDataBridge::ApplyToCurrentThread() -{ - _NL_CURRENT_DATA(GLIBC_LC_NUMERIC) = (locale_data*)glibcNumericLocale; } @@ -164,7 +135,6 @@ void LocaleDataBridge::ApplyToCurrentThread() { ctypeDataBridge.ApplyToCurrentThread(); - numericDataBridge.ApplyToCurrentThread(); // While timeConverstionDataBridge stores read-write variables, // these variables are global (by POSIX definition). Furthermore, // none of the backends seem to access these variables diff --git a/src/system/libroot/posix/locale/ThreadLocale.cpp b/src/system/libroot/posix/locale/ThreadLocale.cpp index 512612856a..3ce6ad84ba 100644 --- a/src/system/libroot/posix/locale/ThreadLocale.cpp +++ b/src/system/libroot/posix/locale/ThreadLocale.cpp @@ -11,15 +11,13 @@ #include -// From glibc's localeinfo.h -extern BPrivate::Libroot::GlibcLocaleStruct _nl_global_locale; - namespace BPrivate { namespace Libroot { -static void DestroyThreadLocale(void* ptr) +static void +DestroyThreadLocale(void* ptr) { ThreadLocale* threadLocale = (ThreadLocale*)ptr; delete threadLocale; @@ -32,8 +30,11 @@ GetCurrentThreadLocale() ThreadLocale* threadLocale = (ThreadLocale*)tls_get(TLS_LOCALE_SLOT); if (threadLocale == NULL) { threadLocale = new ThreadLocale(); - threadLocale->glibcLocaleStruct = _nl_global_locale; threadLocale->threadLocaleInfo = NULL; + threadLocale->ctype_b = __ctype_b; + threadLocale->ctype_tolower = __ctype_tolower; + threadLocale->ctype_toupper = __ctype_toupper; + on_exit_thread(DestroyThreadLocale, threadLocale); tls_set(TLS_LOCALE_SLOT, threadLocale); } @@ -41,32 +42,24 @@ GetCurrentThreadLocale() } -// Exported so that glibc could also use. -extern "C" GlibcLocaleStruct* -_nl_current_locale() -{ - return &GetCurrentThreadLocale()->glibcLocaleStruct; -} - - extern "C" const unsigned short** __ctype_b_loc() { - return &GetCurrentThreadLocale()->glibcLocaleStruct.__ctype_b; + return &GetCurrentThreadLocale()->ctype_b; } extern "C" const int** __ctype_tolower_loc() { - return &GetCurrentThreadLocale()->glibcLocaleStruct.__ctype_tolower; + return &GetCurrentThreadLocale()->ctype_tolower; } extern "C" const int** __ctype_toupper_loc() { - return &GetCurrentThreadLocale()->glibcLocaleStruct.__ctype_toupper; + return &GetCurrentThreadLocale()->ctype_toupper; }