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; }