From Trung Nguyen <trungnt282910@xxxxxxxxx>:
Trung Nguyen has uploaded this change for review. (
https://review.haiku-os.org/c/haiku/+/5351 ;)
Change subject: libs/posix: Implemented new locale functions
......................................................................
libs/posix: Implemented new locale functions
Implemented the missing POSIX functions in <locale.h>:
newlocale, duplocale, uselocale, and freelocale, and also
provided missing type definitions for <locale.h>.
Modified LocaleBackend so that it could support thread-local
locales.
Some glibc-like locale-related variables supporting
ctype and printf family of functions have also been updated
to reflect the thread-local variables present in the latest
glibc sources.
As there have been some modifications to global symbols
from libroot, libroot_stubs.c has also been regenerated.
Change-Id: Ibf296c58c47d42d1d1dfb2ce64042442f2679431
---
M headers/posix/ctype.h
M headers/posix/locale.h
M headers/private/libroot/locale/LocaleBackend.h
M src/system/libroot/add-ons/icu/ICULocaleBackend.cpp
M src/system/libroot/add-ons/icu/ICUNumericData.cpp
M src/system/libroot/add-ons/icu/ICUTimeConversion.cpp
M src/system/libroot/posix/glibc/ctype/ctype.h
M src/system/libroot/posix/glibc/locale/Jamfile
A src/system/libroot/posix/glibc/locale/global-locale.c
M src/system/libroot/posix/glibc/locale/lc-ctype.c
M src/system/libroot/posix/glibc/locale/localeinfo.h
M src/system/libroot/posix/locale/Jamfile
M src/system/libroot/posix/locale/LocaleBackend.cpp
M src/system/libroot/posix/locale/LocaleDataBridge.cpp
A src/system/libroot/posix/locale/LocaleInternal.cpp
A src/system/libroot/posix/locale/LocaleInternal.h
M src/system/libroot/posix/locale/ctype.cpp
A src/system/libroot/posix/locale/ctype_loc.cpp
A src/system/libroot/posix/locale/ctype_loc_thread.cpp
A src/system/libroot/posix/locale/duplocale.cpp
A src/system/libroot/posix/locale/freelocale.cpp
M src/system/libroot/posix/locale/localeconv.cpp
A src/system/libroot/posix/locale/newlocale.cpp
M src/system/libroot/posix/locale/nl_langinfo.cpp
M src/system/libroot/posix/locale/setlocale.cpp
A src/system/libroot/posix/locale/uselocale.cpp
M src/system/libroot/posix/locale/wctype.cpp
M src/system/libroot/posix/string/strcoll.cpp
M src/system/libroot/posix/string/strxfrm.cpp
M src/system/libroot/posix/time/localtime.cpp
M src/system/libroot/posix/time/timelocal.cpp
M src/system/libroot/posix/wchar/mbrtowc.cpp
M src/system/libroot/posix/wchar/mbsrtowcs.cpp
M src/system/libroot/posix/wchar/wcrtomb.cpp
M src/system/libroot/posix/wchar/wcscoll.cpp
M src/system/libroot/posix/wchar/wcsrtombs.cpp
M src/system/libroot/posix/wchar/wcsxfrm.cpp
M src/system/libroot/stubbed/libroot_stubs.c
M src/system/runtime_loader/Jamfile
39 files changed, 1,063 insertions(+), 586 deletions(-)
git pull ssh://git.haiku-os.org:22/haiku refs/changes/51/5351/1
diff --git a/headers/posix/ctype.h b/headers/posix/ctype.h
index 57b2820..95d904f 100644
--- a/headers/posix/ctype.h
+++ b/headers/posix/ctype.h
@@ -48,14 +48,28 @@
extern const int *__ctype_tolower;
extern const int *__ctype_toupper;
+// The OS won't boot if __ctype_* is accessed indirectly.
+#if !defined(_BOOT_MODE) && !defined(_KERNEL_MODE)
+extern const unsigned short int **__ctype_b_loc();
+extern const int **__ctype_tolower_loc();
+extern const int **__ctype_toupper_loc();
+
+#define __isctype(c, type) \
+ ((*__ctype_b_loc())[(int)(c)] & (unsigned short int)type)
+
+#define tolower(c) ((int)(*__ctype_tolower_loc())[(int)(c)])
+#define toupper(c) ((int)(*__ctype_toupper_loc())[(int)(c)])
+#else
#define __isctype(c, type) \
(__ctype_b[(int)(c)] & (unsigned short int)type)
+#define tolower(c) ((int)__ctype_tolower[(int)(c)])
+#define toupper(c) ((int)__ctype_toupper[(int)(c)])
+#endif // !defined(_BOOT_MODE) && !defined(_KERNEL_MODE)
+
#define isascii(c) (((c) & ~0x7f) == 0) /* ASCII characters have bit 8
cleared */
#define toascii(c) ((c) & 0x7f) /* Clear higher bits */
-#define tolower(c) ((int)__ctype_tolower[(int)(c)])
-#define toupper(c) ((int)__ctype_toupper[(int)(c)])
#define _tolower(c) tolower(c)
#define _toupper(c) toupper(c)
diff --git a/headers/posix/locale.h b/headers/posix/locale.h
index 2cc8717..bc38f45 100644
--- a/headers/posix/locale.h
+++ b/headers/posix/locale.h
@@ -48,6 +48,25 @@
*/
#define LC_LAST LC_MESSAGES
+#define LC_COLLATE_MASK (1 << (LC_COLLATE - 1))
+#define LC_CTYPE_MASK (1 << (LC_CTYPE - 1))
+#define LC_MONETARY_MASK (1 << (LC_MONETARY - 1))
+#define LC_NUMERIC_MASK (1 << (LC_NUMERIC - 1))
+#define LC_TIME_MASK (1 << (LC_TIME - 1))
+#define LC_MESSAGES_MASK (1 << (LC_MESSAGES - 1))
+
+#define LC_ALL_MASK (LC_COLLATE_MASK | LC_CTYPE_MASK | \
+ LC_MONETARY_MASK |
LC_NUMERIC_MASK | \
+ LC_TIME_MASK |
LC_MESSAGES_MASK)
+
+typedef struct __locale_t {
+ int magic;
+ void* backend;
+ void* databridge;
+} *locale_t;
+
+#define LC_GLOBAL_LOCALE ((locale_t)-1)
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -55,6 +74,11 @@
extern struct lconv *localeconv(void);
extern char *setlocale(int category, const char *locale);
+extern locale_t duplocale(locale_t);
+extern void freelocale(locale_t);
+extern locale_t newlocale(int, const char *, locale_t);
+extern locale_t uselocale(locale_t);
+
#ifdef __cplusplus
}
#endif
diff --git a/headers/private/libroot/locale/LocaleBackend.h
b/headers/private/libroot/locale/LocaleBackend.h
index 38798b3..e4077af 100644
--- a/headers/private/libroot/locale/LocaleBackend.h
+++ b/headers/private/libroot/locale/LocaleBackend.h
@@ -8,11 +8,11 @@
#include <SupportDefs.h>
+#include <locale.h>
#include <time.h>
#include <wctype.h>
-struct lconv;
struct lc_time_t;
struct locale_data; // glibc
@@ -22,29 +22,33 @@
struct LocaleCtypeDataBridge {
- const unsigned short** addrOfClassInfoTable;
- const int** addrOfToLowerTable;
- const int** addrOfToUpperTable;
+ const unsigned short** addrOfClassInfoTable;
+ const int** addrOfToLowerTable;
+ const int** addrOfToUpperTable;
- const unsigned short* posixClassInfo;
- const int* posixToLowerMap;
- const int* posixToUpperMap;
+ const unsigned short* const posixClassInfo;
+ const int* const posixToLowerMap;
+ const int* const posixToUpperMap;
- LocaleCtypeDataBridge();
+ bool isGlobal;
+
+ LocaleCtypeDataBridge(bool isGlobal);
+ ~LocaleCtypeDataBridge();
void setMbCurMax(unsigned short mbCurMax);
+ void ApplyToCurrentThread();
};
struct LocaleMessagesDataBridge {
- const char** posixLanginfo;
+ const char** const posixLanginfo;
LocaleMessagesDataBridge();
};
struct LocaleMonetaryDataBridge {
- const struct lconv* posixLocaleConv;
+ const struct lconv* const posixLocaleConv;
LocaleMonetaryDataBridge();
};
@@ -73,16 +77,19 @@
locale_data* originalGlibcLocale;
public:
- const struct lconv* posixLocaleConv;
- GlibcNumericLocale glibcNumericLocale;
+ const struct lconv* const posixLocaleConv;
+ GlibcNumericLocale* glibcNumericLocale;
+ bool isGlobal;
- LocaleNumericDataBridge();
+ LocaleNumericDataBridge(bool isGlobal);
~LocaleNumericDataBridge();
+
+ void ApplyToCurrentThread();
};
struct LocaleTimeDataBridge {
- const struct lc_time_t* posixLCTimeInfo;
+ const struct lc_time_t* const posixLCTimeInfo;
LocaleTimeDataBridge();
};
@@ -92,8 +99,10 @@
int* addrOfDaylight;
long* addrOfTimezone;
char** addrOfTZName;
+ bool isGlobal;
- TimeConversionDataBridge();
+ TimeConversionDataBridge(bool isGlobal);
+ ~TimeConversionDataBridge();
};
@@ -104,9 +113,12 @@
LocaleNumericDataBridge numericDataBridge;
LocaleTimeDataBridge timeDataBridge;
TimeConversionDataBridge timeConversionDataBridge;
- const char** posixLanginfo;
+ const char** const posixLanginfo;
+ bool isGlobal;
- LocaleDataBridge();
+ LocaleDataBridge(bool isGlobal);
+
+ void ApplyToCurrentThread();
};
@@ -162,14 +174,25 @@
virtual void Initialize(LocaleDataBridge*
dataBridge) = 0;
static status_t LoadBackend();
+ static LocaleBackend* CreateBackend();
+ static void DestroyBackend(LocaleBackend*
instance);
};
-extern LocaleBackend* gLocaleBackend;
-
+extern thread_local locale_t gLocaleInfo;
+extern LocaleBackend* gGlobalLocaleBackend;
+extern LocaleDataBridge gGlobalLocaleDataBridge;
} // namespace Libroot
} // namespace BPrivate
+#define GET_LOCALE_BACKEND()
\
+ ((BPrivate::Libroot::gLocaleInfo == NULL) ? \
+ BPrivate::Libroot::gGlobalLocaleBackend :
\
+ ((BPrivate::Libroot::gLocaleInfo->backend == NULL) ? \
+ BPrivate::Libroot::gGlobalLocaleBackend :
\
+
(BPrivate::Libroot::LocaleBackend*)BPrivate::Libroot::gLocaleInfo->backend))
+
+
#endif // _LOCALE_BACKEND_H
diff --git a/src/system/libroot/add-ons/icu/ICULocaleBackend.cpp
b/src/system/libroot/add-ons/icu/ICULocaleBackend.cpp
index 5dccc60..4d9a1e8 100644
--- a/src/system/libroot/add-ons/icu/ICULocaleBackend.cpp
+++ b/src/system/libroot/add-ons/icu/ICULocaleBackend.cpp
@@ -29,6 +29,12 @@
return new(std::nothrow) ICULocaleBackend();
}
+extern "C" void
+DestroyInstance(LocaleBackend* instance)
+{
+ delete instance;
+}
+
ICULocaleBackend::ICULocaleBackend()
:
diff --git a/src/system/libroot/add-ons/icu/ICUNumericData.cpp
b/src/system/libroot/add-ons/icu/ICUNumericData.cpp
index cdde2de..733867a 100644
--- a/src/system/libroot/add-ons/icu/ICUNumericData.cpp
+++ b/src/system/libroot/add-ons/icu/ICUNumericData.cpp
@@ -34,9 +34,9 @@
void
ICUNumericData::Initialize(LocaleNumericDataBridge* dataBridge)
{
- dataBridge->glibcNumericLocale.values[0].string = fDecimalPoint;
- dataBridge->glibcNumericLocale.values[1].string = fThousandsSep;
- dataBridge->glibcNumericLocale.values[2].string = fGrouping;
+ dataBridge->glibcNumericLocale->values[0].string = fDecimalPoint;
+ dataBridge->glibcNumericLocale->values[1].string = fThousandsSep;
+ dataBridge->glibcNumericLocale->values[2].string = fGrouping;
fDataBridge = dataBridge;
}
@@ -62,13 +62,13 @@
if (result == B_OK) {
result = _SetLocaleconvEntry(formatSymbols,
fDecimalPoint,
DecimalFormatSymbols::kDecimalSeparatorSymbol);
- fDataBridge->glibcNumericLocale.values[3].word
+ fDataBridge->glibcNumericLocale->values[3].word
= (unsigned int)fDecimalPoint[0];
}
if (result == B_OK) {
result = _SetLocaleconvEntry(formatSymbols,
fThousandsSep,
DecimalFormatSymbols::kGroupingSeparatorSymbol);
- fDataBridge->glibcNumericLocale.values[4].word
+ fDataBridge->glibcNumericLocale->values[4].word
= (unsigned int)fThousandsSep[0];
}
if (result == B_OK) {
@@ -104,9 +104,9 @@
strcpy(fDecimalPoint,
fDataBridge->posixLocaleConv->decimal_point);
strcpy(fThousandsSep,
fDataBridge->posixLocaleConv->thousands_sep);
strcpy(fGrouping, fDataBridge->posixLocaleConv->grouping);
- fDataBridge->glibcNumericLocale.values[3].word
+ fDataBridge->glibcNumericLocale->values[3].word
= (unsigned int)fDecimalPoint[0];
- fDataBridge->glibcNumericLocale.values[4].word
+ fDataBridge->glibcNumericLocale->values[4].word
= (unsigned int)fThousandsSep[0];
}
diff --git a/src/system/libroot/add-ons/icu/ICUTimeConversion.cpp
b/src/system/libroot/add-ons/icu/ICUTimeConversion.cpp
index 5951b6c..6d45b71 100644
--- a/src/system/libroot/add-ons/icu/ICUTimeConversion.cpp
+++ b/src/system/libroot/add-ons/icu/ICUTimeConversion.cpp
@@ -47,6 +47,7 @@
ICUTimeConversion::TZSet(const char* timeZoneID, const char* tz)
{
bool offsetHasBeenSet = false;
+ bool timeZoneIdMatches = false;
// The given TZ environment variable's content overrides the default
// system timezone.
@@ -55,8 +56,10 @@
// value is implementation specific, we expect a full timezone
ID.
if (*tz == ':') {
// nothing to do if the given name matches the current
timezone
- if (strcasecmp(fTimeZoneID, tz + 1) == 0)
- return B_OK;
+ if (strcasecmp(fTimeZoneID, tz + 1) == 0) {
+ timeZoneIdMatches = true;
+ goto done;
+ }
strlcpy(fTimeZoneID, tz + 1, sizeof(fTimeZoneID));
} else {
@@ -64,8 +67,10 @@
strlcpy(fTimeZoneID, tz, sizeof(fTimeZoneID));
// nothing to do if the given name matches the current
timezone
- if (strcasecmp(fTimeZoneID,
fDataBridge->addrOfTZName[0]) == 0)
- return B_OK;
+ if (strcasecmp(fTimeZoneID,
fDataBridge->addrOfTZName[0]) == 0) {
+ timeZoneIdMatches = true;
+ goto done;
+ }
// parse TZ variable (only <std> and <offset> supported)
const char* tzNameEnd = tz;
@@ -88,12 +93,22 @@
}
} else {
// nothing to do if the given name matches the current timezone
- if (strcasecmp(fTimeZoneID, timeZoneID) == 0)
- return B_OK;
+ if (strcasecmp(fTimeZoneID, timeZoneID) == 0) {
+ timeZoneIdMatches = true;
+ goto done;
+ }
strlcpy(fTimeZoneID, timeZoneID, sizeof(fTimeZoneID));
}
+done:
+ // fTimeZone can still be NULL if we don't initialize it
+ // in the first TZSet, causing problems for future
+ // Localtime invocations.
+ if (fTimeZone != NULL && timeZoneIdMatches) {
+ return B_OK;
+ }
+
delete fTimeZone;
fTimeZone = TimeZone::createTimeZone(fTimeZoneID);
if (fTimeZone == NULL)
diff --git a/src/system/libroot/posix/glibc/ctype/ctype.h
b/src/system/libroot/posix/glibc/ctype/ctype.h
index adffe76..af64a50 100644
--- a/src/system/libroot/posix/glibc/ctype/ctype.h
+++ b/src/system/libroot/posix/glibc/ctype/ctype.h
@@ -64,6 +64,11 @@
/* These are defined in ctype-info.c.
The declarations here must match those in localeinfo.h.
+ In the thread-specific locale model (see `uselocale' in <locale.h>)
+ we cannot use global variables for these as was done in the past.
+ Instead, the following accessor functions return the address of
+ each variable, which is local to the current thread if multithreaded.
+
These point into arrays of 384, so they can be indexed by any `unsigned
char' value [0,255]; by EOF (-1); or by any `signed char' value
[-128,-1). ISO C requires that the ctype functions work for `unsigned
@@ -72,12 +77,12 @@
rather than `unsigned char's because tolower (EOF) must be EOF, which
doesn't fit into an `unsigned char'. But today more important is that
the arrays are also used for multi-byte character sets. */
-extern __const unsigned short int *__ctype_b; /* Characteristics. */
-extern __const __int32_t *__ctype_tolower; /* Case conversions. */
-extern __const __int32_t *__ctype_toupper; /* Case conversions. */
+extern __const unsigned short int **__ctype_b_loc (void); /* Characteristics.
*/
+extern __const __int32_t **__ctype_tolower_loc (void); /* Case conversions.
*/
+extern __const __int32_t **__ctype_toupper_loc (void); /* Case conversions.
*/
#define __isctype(c, type) \
- (__ctype_b[(int) (c)] & (unsigned short int) type)
+ ((*__ctype_b_loc())[(int) (c)] & (unsigned short int) type)
#define __isascii(c) (((c) & ~0x7f) == 0) /* If C is a 7 bit
value. */
#define __toascii(c) ((c) & 0x7f) /* Mask off high bits.
*/
@@ -167,27 +172,27 @@
__extern_inline int
tolower (int __c) __THROW
{
- return __c >= -128 && __c < 256 ? __ctype_tolower[__c] : __c;
+ return __c >= -128 && __c < 256 ? (*__ctype_tolower_loc())[__c] : __c;
}
__extern_inline int
toupper (int __c) __THROW
{
- return __c >= -128 && __c < 256 ? __ctype_toupper[__c] : __c;
+ return __c >= -128 && __c < 256 ? (*__ctype_toupper_loc())[__c] : __c;
}
# endif
# if __GNUC__ >= 2 && defined __OPTIMIZE__ && !defined __cplusplus
-# define tolower(c) __tobody (c, tolower, __ctype_tolower, (c))
-# define toupper(c) __tobody (c, toupper, __ctype_toupper, (c))
+# define tolower(c) __tobody (c, tolower, (*__ctype_tolower_loc()), (c))
+# define toupper(c) __tobody (c, toupper, (*__ctype_toupper_loc()), (c))
# endif /* Optimizing gcc */
# if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN
# define isascii(c) __isascii (c)
# define toascii(c) __toascii (c)
-# define _tolower(c) ((int) __ctype_tolower[(int) (c)])
-# define _toupper(c) ((int) __ctype_toupper[(int) (c)])
+# define _tolower(c) ((int) (*__ctype_tolower_loc())[(int) (c)])
+# define _toupper(c) ((int) (*__ctype_toupper_loc())[(int) (c)])
# endif
#endif /* Not __NO_CTYPE. */
diff --git a/src/system/libroot/posix/glibc/locale/Jamfile
b/src/system/libroot/posix/glibc/locale/Jamfile
index b3ba468..de7d9c4 100644
--- a/src/system/libroot/posix/glibc/locale/Jamfile
+++ b/src/system/libroot/posix/glibc/locale/Jamfile
@@ -24,6 +24,7 @@
C-time.c
C_name.c
coll-lookup.c
+ global-locale.c
lc-collate.c
lc-ctype.c
lc-messages.c
diff --git a/src/system/libroot/posix/glibc/locale/global-locale.c
b/src/system/libroot/posix/glibc/locale/global-locale.c
new file mode 100644
index 0000000..fa93468
--- /dev/null
+++ b/src/system/libroot/posix/glibc/locale/global-locale.c
@@ -0,0 +1,48 @@
+/* Locale object representing the global locale controlled by setlocale.
+ Copyright (C) 2002-2019 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <locale.h>
+#include "localeinfo.h"
+
+#define DEFINE_CATEGORY(category, category_name, items, a) \
+extern struct locale_data _nl_C_##category;
+#include "categories.def"
+#undef DEFINE_CATEGORY
+
+/* Defined in locale/C-ctype.c. */
+extern const char _nl_C_LC_CTYPE_class[];
+extern const char _nl_C_LC_CTYPE_toupper[];
+extern const char _nl_C_LC_CTYPE_tolower[];
+
+/* Here we define the locale object maintained by setlocale.
+ The references in the initializer are weak, so the parts of
+ the structure that are never referred to will be zero. */
+
+struct __locale_struct _nl_global_locale =
+ {
+ .__locales =
+ {
+#define DEFINE_CATEGORY(category, category_name, items, a) \
+ [category] = &_nl_C_##category,
+#include "categories.def"
+#undef DEFINE_CATEGORY
+ },
+ .__ctype_b = (const unsigned short int *) _nl_C_LC_CTYPE_class + 128,
+ .__ctype_tolower = (const int *) _nl_C_LC_CTYPE_tolower + 128,
+ .__ctype_toupper = (const int *) _nl_C_LC_CTYPE_toupper + 128
+ };
diff --git a/src/system/libroot/posix/glibc/locale/lc-ctype.c
b/src/system/libroot/posix/glibc/locale/lc-ctype.c
index 742dae4..99c0d8e 100644
--- a/src/system/libroot/posix/glibc/locale/lc-ctype.c
+++ b/src/system/libroot/posix/glibc/locale/lc-ctype.c
@@ -47,9 +47,9 @@
offset = _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_CLASS_OFFSET);
for (cnt = 0; cnt < 12; cnt++)
- __ctype32_wctype[cnt] = _nl_current_LC_CTYPE->values[offset + cnt].string;
+ __ctype32_wctype[cnt] = (*_nl_current_LC_CTYPE)->values[offset +
cnt].string;
offset = _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_OFFSET);
for (cnt = 0; cnt < 2; cnt++)
- __ctype32_wctrans[cnt] = _nl_current_LC_CTYPE->values[offset + cnt].string;
+ __ctype32_wctrans[cnt] = (*_nl_current_LC_CTYPE)->values[offset +
cnt].string;
}
diff --git a/src/system/libroot/posix/glibc/locale/localeinfo.h
b/src/system/libroot/posix/glibc/locale/localeinfo.h
index 814a273..0a89f90 100644
--- a/src/system/libroot/posix/glibc/locale/localeinfo.h
+++ b/src/system/libroot/posix/glibc/locale/localeinfo.h
@@ -27,6 +27,11 @@
#include <stdint.h>
#include <sys/types.h>
+// __locale_struct
+#include "xlocale.h"
+// LC_* values
+#include "locale.h"
+
/* This has to be changed whenever a new locale is defined. */
#define __LC_LAST 7
@@ -143,7 +148,7 @@
/* 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;
+extern __thread struct locale_data *const *_nl_current_##category;
#include "categories.def"
#undef DEFINE_CATEGORY
@@ -158,22 +163,27 @@
/* The standard codeset. */
extern const char _nl_C_codeset[];
+/* 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;
+
/* Extract the current CATEGORY locale's string for ITEM. */
#define _NL_CURRENT(category, item) \
- (_nl_current_##category->values[_NL_ITEM_INDEX (item)].string)
+ ((*_nl_current_##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_##category->values[_NL_ITEM_INDEX (item)].wstr))
+ ((wchar_t *) ((*_nl_current_##category)->values[_NL_ITEM_INDEX (item)].wstr))
/* Extract the current CATEGORY locale's word for ITEM. */
#define _NL_CURRENT_WORD(category, item) \
- (_nl_current_##category->values[_NL_ITEM_INDEX (item)].word)
+ ((*_nl_current_##category)->values[_NL_ITEM_INDEX (item)].word)
/* This is used in lc-CATEGORY.c to define _nl_current_CATEGORY. */
#define _NL_CURRENT_DEFINE(category) \
- extern struct locale_data _nl_C_##category; \
- struct locale_data *_nl_current_##category = &_nl_C_##category
+ __thread struct locale_data *const *_nl_current_##category \
+ = &_nl_global_locale.__locales[category];
/* Load the locale data for CATEGORY from the file specified by *NAME.
If *NAME is "", use environment variables as specified by POSIX,
diff --git a/src/system/libroot/posix/locale/Jamfile
b/src/system/libroot/posix/locale/Jamfile
index d2f9aef..aff1b11 100644
--- a/src/system/libroot/posix/locale/Jamfile
+++ b/src/system/libroot/posix/locale/Jamfile
@@ -12,14 +12,24 @@
local architecture = $(TARGET_PACKAGING_ARCH) ;
MergeObject <$(architecture)>posix_locale.o :
+ ctype_loc_thread.cpp
ctype.cpp
+ duplocale.cpp
+ freelocale.cpp
LocaleBackend.cpp
LocaleData.cpp
LocaleDataBridge.cpp
+ LocaleInternal.cpp
localeconv.cpp
+ newlocale.cpp
nl_langinfo.cpp
setlocale.cpp
+ uselocale.cpp
wctype.cpp
;
+
+ MergeObject <$(architecture)>ctype_loc.o :
+ ctype_loc.cpp
+ ;
}
}
diff --git a/src/system/libroot/posix/locale/LocaleBackend.cpp
b/src/system/libroot/posix/locale/LocaleBackend.cpp
index dfd1be5..154711e 100644
--- a/src/system/libroot/posix/locale/LocaleBackend.cpp
+++ b/src/system/libroot/posix/locale/LocaleBackend.cpp
@@ -15,32 +15,50 @@
namespace Libroot {
-LocaleBackend* gLocaleBackend = NULL;
+thread_local locale_t gLocaleInfo = NULL;
+LocaleBackend* gGlobalLocaleBackend = NULL;
+LocaleDataBridge gGlobalLocaleDataBridge = LocaleDataBridge(true);
-static LocaleDataBridge sLocaleDataBridge;
+static void* sImageHandle = NULL;
+typedef LocaleBackend* (*create_instance_t)();
+typedef void (*destroy_instance_t)(LocaleBackend*);
+static create_instance_t sCreateInstanceFunc = NULL;
+static destroy_instance_t sDestroyInstanceFunc = NULL;
+
+
static pthread_once_t sBackendInitOnce = PTHREAD_ONCE_INIT;
+static pthread_once_t sFunctionsInitOnce = PTHREAD_ONCE_INIT;
+
+
+static void
+LoadFunctions()
+{
+ sImageHandle = dlopen("libroot-addon-icu.so", RTLD_LAZY);
+ if (sImageHandle == NULL)
+ return;
+
+ sCreateInstanceFunc = (create_instance_t)dlsym(sImageHandle,
"CreateInstance");
+ sDestroyInstanceFunc = (destroy_instance_t)dlsym(sImageHandle,
"DestroyInstance");
+
+ if ((sCreateInstanceFunc == NULL) || (sDestroyInstanceFunc == NULL)) {
+ dlclose(sImageHandle);
+ return;
+ }
+}
static void
LoadBackend()
{
- void* imageHandle = dlopen("libroot-addon-icu.so", RTLD_LAZY);
- if (imageHandle == NULL)
- return;
-
- typedef LocaleBackend* (*symbolType)();
- symbolType createInstanceFunc
- = (symbolType)dlsym(imageHandle, "CreateInstance");
- if (createInstanceFunc == NULL) {
- dlclose(imageHandle);
- return;
+ gGlobalLocaleBackend = LocaleBackend::CreateBackend();
+ if (gGlobalLocaleBackend != NULL) {
+ gGlobalLocaleBackend->Initialize(&gGlobalLocaleDataBridge);
}
-
- gLocaleBackend = createInstanceFunc();
}
+
LocaleBackend::LocaleBackend()
{
}
@@ -54,15 +72,35 @@
status_t
LocaleBackend::LoadBackend()
{
- if (gLocaleBackend == NULL) {
+ if (gGlobalLocaleBackend == NULL) {
pthread_once(&sBackendInitOnce,
&BPrivate::Libroot::LoadBackend);
- if (gLocaleBackend != NULL)
- gLocaleBackend->Initialize(&sLocaleDataBridge);
}
- return gLocaleBackend != NULL ? B_OK : B_ERROR;
+ return gGlobalLocaleBackend != NULL ? B_OK : B_ERROR;
}
+LocaleBackend*
+LocaleBackend::CreateBackend()
+{
+ if (sCreateInstanceFunc == NULL) {
+ pthread_once(&sFunctionsInitOnce,
&BPrivate::Libroot::LoadFunctions);
+ }
+
+ if (sCreateInstanceFunc != NULL) {
+ LocaleBackend* backend = sCreateInstanceFunc();
+ return backend;
+ }
+
+ return NULL;
+}
+
+void
+LocaleBackend::DestroyBackend(LocaleBackend* instance)
+{
+ if (sDestroyInstanceFunc != NULL) {
+ sDestroyInstanceFunc(instance);
+ }
+}
} // namespace Libroot
} // namespace BPrivate
diff --git a/src/system/libroot/posix/locale/LocaleDataBridge.cpp
b/src/system/libroot/posix/locale/LocaleDataBridge.cpp
index c8f2631..eaf84fa 100644
--- a/src/system/libroot/posix/locale/LocaleDataBridge.cpp
+++ b/src/system/libroot/posix/locale/LocaleDataBridge.cpp
@@ -17,30 +17,71 @@
#include <PosixLocaleConv.h>
-extern locale_data* _nl_current_LC_NUMERIC;
+extern const unsigned short* __ctype_b;
+extern const int* __ctype_tolower;
+extern const int* __ctype_toupper;
+
+
+extern thread_local locale_data* const* _nl_current_LC_NUMERIC;
+struct __locale_struct
+{
+ locale_data *__locales[7];
+
+ const unsigned short int *__ctype_b;
+ const int *__ctype_tolower;
+ const int *__ctype_toupper;
+}; // struct from glibc xlocale.h
+extern struct __locale_struct _nl_global_locale;
+const int __LC_NUMERIC = 1; // constant from bits/locale.h
+// Convenience macro
+#define _NL_GLOBAL_LC_NUMERIC (_nl_global_locale.__locales[__LC_NUMERIC])
+
namespace BPrivate {
namespace Libroot {
-LocaleCtypeDataBridge::LocaleCtypeDataBridge()
+LocaleCtypeDataBridge::LocaleCtypeDataBridge(bool isGlobal)
:
- addrOfClassInfoTable(&__ctype_b),
- addrOfToLowerTable(&__ctype_tolower),
- addrOfToUpperTable(&__ctype_toupper),
posixClassInfo(gPosixClassInfo),
posixToLowerMap(gPosixToLowerMap),
- posixToUpperMap(gPosixToUpperMap)
+ posixToUpperMap(gPosixToUpperMap),
+ isGlobal(isGlobal)
{
+ if (isGlobal) {
+ addrOfClassInfoTable = &__ctype_b;
+ addrOfToLowerTable = &__ctype_tolower;
+ addrOfToUpperTable = &__ctype_toupper;
+ } else {
+ addrOfClassInfoTable = new const unsigned short*(__ctype_b);
+ addrOfToLowerTable = new const int*(__ctype_tolower);
+ addrOfToUpperTable = new const int*(__ctype_toupper);
+ }
}
+LocaleCtypeDataBridge::~LocaleCtypeDataBridge()
+{
+ if (!isGlobal) {
+ delete addrOfClassInfoTable;
+ delete addrOfToLowerTable;
+ delete addrOfToUpperTable;
+ }
+}
void LocaleCtypeDataBridge::setMbCurMax(unsigned short mbCurMax)
{
__ctype_mb_cur_max = mbCurMax;
}
+void
+LocaleCtypeDataBridge::ApplyToCurrentThread()
+{
+ *__ctype_b_loc() = *addrOfClassInfoTable;
+ *__ctype_tolower_loc() = *addrOfToLowerTable;
+ *__ctype_toupper_loc() = *addrOfToUpperTable;
+}
+
LocaleMessagesDataBridge::LocaleMessagesDataBridge()
:
@@ -56,20 +97,36 @@
}
-LocaleNumericDataBridge::LocaleNumericDataBridge()
+LocaleNumericDataBridge::LocaleNumericDataBridge(bool isGlobal)
:
- originalGlibcLocale(_nl_current_LC_NUMERIC),
- posixLocaleConv(&gPosixLocaleConv)
+ posixLocaleConv(&gPosixLocaleConv),
+ glibcNumericLocale(new GlibcNumericLocale)
{
- memcpy(&glibcNumericLocale, _nl_current_LC_NUMERIC,
- sizeof(glibcNumericLocale));
- _nl_current_LC_NUMERIC = (locale_data*)&glibcNumericLocale;
-}
+ memcpy(glibcNumericLocale, _NL_GLOBAL_LC_NUMERIC,
+ sizeof(GlibcNumericLocale));
+
+ if (isGlobal) {
+ originalGlibcLocale = _NL_GLOBAL_LC_NUMERIC;
+ _NL_GLOBAL_LC_NUMERIC = (locale_data*)glibcNumericLocale;
+ }
+}
LocaleNumericDataBridge::~LocaleNumericDataBridge()
{
- _nl_current_LC_NUMERIC = originalGlibcLocale;
+ if (isGlobal) {
+ _NL_GLOBAL_LC_NUMERIC = originalGlibcLocale;
+ } else if (_nl_current_LC_NUMERIC ==
(locale_data**)&glibcNumericLocale) {
+ _nl_current_LC_NUMERIC = &_NL_GLOBAL_LC_NUMERIC;
+ }
+
+ delete glibcNumericLocale;
+}
+
+void
+LocaleNumericDataBridge::ApplyToCurrentThread()
+{
+ _nl_current_LC_NUMERIC = (locale_data**)&glibcNumericLocale;
}
@@ -80,21 +137,58 @@
}
-TimeConversionDataBridge::TimeConversionDataBridge()
+TimeConversionDataBridge::TimeConversionDataBridge(bool isGlobal)
:
- addrOfDaylight(&daylight),
- addrOfTimezone(&timezone),
- addrOfTZName(tzname)
+ isGlobal(isGlobal)
{
+ if (isGlobal) {
+ addrOfDaylight = &daylight;
+ addrOfTimezone = &timezone;
+ addrOfTZName = tzname;
+ } else {
+ addrOfDaylight = new int(daylight);
+ addrOfTimezone = new long(timezone);
+ addrOfTZName = new char*[2] { new char[64], new char[64] };
+ strlcpy(addrOfTZName[0], tzname[0], 64);
+ strlcpy(addrOfTZName[1], tzname[1], 64);
+ }
+}
+
+TimeConversionDataBridge::~TimeConversionDataBridge()
+{
+ if (!isGlobal) {
+ delete addrOfDaylight;
+ delete addrOfTimezone;
+ delete [] addrOfTZName[0];
+ delete [] addrOfTZName[1];
+ delete [] addrOfTZName;
+ }
}
-LocaleDataBridge::LocaleDataBridge()
+LocaleDataBridge::LocaleDataBridge(bool isGlobal)
:
- posixLanginfo(gPosixLanginfo)
+ ctypeDataBridge(isGlobal),
+ numericDataBridge(isGlobal),
+ timeConversionDataBridge(isGlobal),
+ posixLanginfo(gPosixLanginfo),
+ isGlobal(isGlobal)
{
}
+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
+ // directly. The values are set in the bridge mostly for
+ // synchronization purposes. Therefore, don't call
+ // ApplyToCurrentThread for this object.
+}
+
} // namespace Libroot
} // namespace BPrivate
diff --git a/src/system/libroot/posix/locale/LocaleInternal.cpp
b/src/system/libroot/posix/locale/LocaleInternal.cpp
new file mode 100644
index 0000000..9c88699
--- /dev/null
+++ b/src/system/libroot/posix/locale/LocaleInternal.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2004-2007, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx
+ * Copyright 2010, Oliver Tappe, zooey@xxxxxxxxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+
+#include "LocaleInternal.h"
+
+#include <locale.h>
+#include <stdlib.h>
+#include <strings.h>
+
+
+namespace BPrivate {
+namespace Libroot {
+
+
+status_t
+GetLocalesFromEnvironment(int category, const char** locales)
+{
+ const char* locale = getenv("LC_ALL");
+ if (locale && *locale)
+ locales[category] = locale;
+ else {
+ // the order of the names must match the one specified in
locale.h
+ const char* categoryNames[] = {
+ "LC_ALL",
+ "LC_COLLATE",
+ "LC_CTYPE",
+ "LC_MONETARY",
+ "LC_NUMERIC",
+ "LC_TIME",
+ "LC_MESSAGES"
+ };
+ int from, to;
+ if (category == LC_ALL) {
+ // we need to check each real category if all of them
should be set
+ from = 1;
+ to = LC_LAST;
+ } else
+ from = to = category;
+ bool haveDifferentLocales = false;
+ locale = NULL;
+ for (int lc = from; lc <= to; lc++) {
+ const char* lastLocale = locale;
+ locale = getenv(categoryNames[lc]);
+ if (!locale || *locale == '\0')
+ locale = getenv("LANG");
+ if (!locale || *locale == '\0')
+ locale = "POSIX";
+ locales[lc] = locale;
+ if (lastLocale && strcasecmp(locale, lastLocale) != 0)
+ haveDifferentLocales = true;
+ }
+ if (!haveDifferentLocales) {
+ // we can set all locales at once
+ locales[LC_ALL] = locale;
+ }
+ }
+
+ return B_OK;
+}
+
+} // namespace Libroot
+} // namespace BPrivate
diff --git a/src/system/libroot/posix/locale/LocaleInternal.h
b/src/system/libroot/posix/locale/LocaleInternal.h
new file mode 100644
index 0000000..3041dea
--- /dev/null
+++ b/src/system/libroot/posix/locale/LocaleInternal.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2004-2007, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx
+ * Copyright 2010, Oliver Tappe, zooey@xxxxxxxxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+
+#include <SupportDefs.h>
+
+
+#define LOCALE_T_MAGIC 0x4C4F4341
+
+
+namespace BPrivate {
+namespace Libroot {
+
+
+status_t GetLocalesFromEnvironment(int category, const char** locales);
+
+} // namespace Libroot
+} // namespace BPrivate
diff --git a/src/system/libroot/posix/locale/ctype.cpp
b/src/system/libroot/posix/locale/ctype.cpp
index e558a86..20b53de 100644
--- a/src/system/libroot/posix/locale/ctype.cpp
+++ b/src/system/libroot/posix/locale/ctype.cpp
@@ -26,6 +26,13 @@
#undef toupper
+#if defined(_KERNEL_MODE)
+#define GET_CTYPE(name) (name)
+#else
+#define GET_CTYPE(name) (*name##_loc())
+#endif
+
+
extern "C"
{
@@ -44,7 +51,7 @@
isalnum(int c)
{
if (c >= -128 && c < 256)
- return __ctype_b[c] & (_ISupper | _ISlower | _ISdigit);
+ return GET_CTYPE(__ctype_b)[c] & (_ISupper | _ISlower |
_ISdigit);
return 0;
}
@@ -54,7 +61,7 @@
isalpha(int c)
{
if (c >= -128 && c < 256)
- return __ctype_b[c] & (_ISupper | _ISlower);
+ return GET_CTYPE(__ctype_b)[c] & (_ISupper | _ISlower);
return 0;
}
@@ -72,7 +79,7 @@
isblank(int c)
{
if (c >= -128 && c < 256)
- return __ctype_b[c] & _ISblank;
+ return GET_CTYPE(__ctype_b)[c] & _ISblank;
return 0;
}
@@ -82,7 +89,7 @@
iscntrl(int c)
{
if (c >= -128 && c < 256)
- return __ctype_b[c] & _IScntrl;
+ return GET_CTYPE(__ctype_b)[c] & _IScntrl;
return 0;
}
@@ -92,7 +99,7 @@
isdigit(int c)
{
if (c >= -128 && c < 256)
- return __ctype_b[c] & _ISdigit;
+ return GET_CTYPE(__ctype_b)[c] & _ISdigit;
return 0;
}
@@ -102,7 +109,7 @@
isgraph(int c)
{
if (c >= -128 && c < 256)
- return __ctype_b[c] & _ISgraph;
+ return GET_CTYPE(__ctype_b)[c] & _ISgraph;
return 0;
}
@@ -112,7 +119,7 @@
islower(int c)
{
if (c >= -128 && c < 256)
- return __ctype_b[c] & _ISlower;
+ return GET_CTYPE(__ctype_b)[c] & _ISlower;
return 0;
}
@@ -122,7 +129,7 @@
isprint(int c)
{
if (c >= -128 && c < 256)
- return __ctype_b[c] & _ISprint;
+ return GET_CTYPE(__ctype_b)[c] & _ISprint;
return 0;
}
@@ -132,7 +139,7 @@
ispunct(int c)
{
if (c >= -128 && c < 256)
- return __ctype_b[c] & _ISpunct;
+ return GET_CTYPE(__ctype_b)[c] & _ISpunct;
return 0;
}
@@ -142,7 +149,7 @@
isspace(int c)
{
if (c >= -128 && c < 256)
- return __ctype_b[c] & _ISspace;
+ return GET_CTYPE(__ctype_b)[c] & _ISspace;
return 0;
}
@@ -152,7 +159,7 @@
isupper(int c)
{
if (c >= -128 && c < 256)
- return __ctype_b[c] & _ISupper;
+ return GET_CTYPE(__ctype_b)[c] & _ISupper;
return 0;
}
@@ -162,7 +169,7 @@
isxdigit(int c)
{
if (c >= -128 && c < 256)
- return __ctype_b[c] & _ISxdigit;
+ return GET_CTYPE(__ctype_b)[c] & _ISxdigit;
return 0;
}
@@ -180,7 +187,7 @@
tolower(int c)
{
if (c >= -128 && c < 256)
- return __ctype_tolower[c];
+ return GET_CTYPE(__ctype_tolower)[c];
return c;
}
@@ -190,7 +197,7 @@
toupper(int c)
{
if (c >= -128 && c < 256)
- return __ctype_toupper[c];
+ return GET_CTYPE(__ctype_toupper)[c];
return c;
}
diff --git a/src/system/libroot/posix/locale/ctype_loc.cpp
b/src/system/libroot/posix/locale/ctype_loc.cpp
new file mode 100644
index 0000000..dabea33
--- /dev/null
+++ b/src/system/libroot/posix/locale/ctype_loc.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2022, Trung Nguyen, trungnt282910@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+
+#ifndef _KERNEL_MODE
+#include <ctype.h>
+
+
+// These functions are intended for scenarios where we cannot
+// link to the whole libroot and access pthread functions;
+// for example, when we're in the static "libruntime_loader.a"
+
+extern "C" const unsigned short**
+__ctype_b_loc()
+{
+ return &__ctype_b;
+}
+
+extern "C" const int**
+__ctype_tolower_loc()
+{
+ return &__ctype_tolower;
+}
+
+extern "C" const int**
+__ctype_toupper_loc()
+{
+ return &__ctype_toupper;
+}
+
+
+#endif //_KERNEL_MODE
diff --git a/src/system/libroot/posix/locale/ctype_loc_thread.cpp
b/src/system/libroot/posix/locale/ctype_loc_thread.cpp
new file mode 100644
index 0000000..2804444
--- /dev/null
+++ b/src/system/libroot/posix/locale/ctype_loc_thread.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2022, Trung Nguyen, trungnt282910@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+
+#ifndef _KERNEL_MODE
+#include <ctype.h>
+#include <pthread.h>
+
+
+namespace BPrivate {
+namespace Libroot {
+
+
+struct ctype_info {
+ const unsigned short* __ctype_b;
+ const int* __ctype_tolower;
+ const int* __ctype_toupper;
+};
+
+
+static pthread_key_t sCtypeInfoPthreadKey;
+static pthread_once_t sCtypeInfoPthreadKeyOnce = PTHREAD_ONCE_INIT;
+
+
+static void
+ctype_info_destroy(void* ptr)
+{
+ ctype_info* info = (ctype_info*)ptr;
+ delete info;
+}
+
+static void
+ctype_info_make_key()
+{
+ pthread_key_create(&sCtypeInfoPthreadKey, ctype_info_destroy);
+}
+
+static ctype_info*
+__ctype_info_get()
+{
+ ctype_info* ptr;
+ pthread_once(&sCtypeInfoPthreadKeyOnce, ctype_info_make_key);
+ if ((ptr = (ctype_info*)pthread_getspecific(sCtypeInfoPthreadKey)) ==
NULL) {
+ ptr = new ctype_info;
+ ptr->__ctype_b = __ctype_b;
+ ptr->__ctype_tolower = __ctype_tolower;
+ ptr->__ctype_toupper = __ctype_toupper;
+ pthread_setspecific(sCtypeInfoPthreadKey, ptr);
+ }
+ return ptr;
+}
+
+
+extern "C" const unsigned short**
+__ctype_b_loc()
+{
+ return &__ctype_info_get()->__ctype_b;
+}
+
+extern "C" const int**
+__ctype_tolower_loc()
+{
+ return &__ctype_info_get()->__ctype_tolower;
+}
+
+extern "C" const int**
+__ctype_toupper_loc()
+{
+ return &__ctype_info_get()->__ctype_toupper;
+}
+
+
+} // namespace Libroot
+} // namespace BPrivate
+
+
+#endif //
diff --git a/src/system/libroot/posix/locale/duplocale.cpp
b/src/system/libroot/posix/locale/duplocale.cpp
new file mode 100644
index 0000000..befb19a
--- /dev/null
+++ b/src/system/libroot/posix/locale/duplocale.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2022, Trung Nguyen, trungnt282910@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+
+#include <new>
+#include <errno.h>
+#include <locale.h>
+#include <strings.h>
+
+#include <ErrnoMaintainer.h>
+
+#include "LocaleBackend.h"
+
+
+using BPrivate::Libroot::gGlobalLocaleBackend;
+using BPrivate::Libroot::LocaleBackend;
+using BPrivate::Libroot::LocaleDataBridge;
+
+
+extern "C" locale_t
+duplocale(locale_t locobj)
+{
+ locale_t newObj = new (std::nothrow) __locale_t;
+ if (newObj == NULL) {
+ errno = ENOMEM;
+ return (locale_t)0;
+ }
+
+ LocaleBackend* backend = (locobj == LC_GLOBAL_LOCALE) ?
+ gGlobalLocaleBackend : (LocaleBackend*)locobj->backend;
+
+ if (backend == NULL) {
+ newObj->backend = NULL;
+ return newObj;
+ }
+
+ // Check if everything is set to "C" or "POSIX",
+ // and avoid making a backend.
+ const char* localeDescription = backend->SetLocale(LC_ALL, NULL);
+
+ if ((strcasecmp(localeDescription, "POSIX") == 0) ||
(strcasecmp(localeDescription, "C") == 0)) {
+ newObj->backend = NULL;
+ return newObj;
+ }
+
+ BPrivate::ErrnoMaintainer errnoMaintainer;
+
+ LocaleBackend*& newBackend = (LocaleBackend*&)newObj->backend;
+ LocaleDataBridge*& newDataBridge = (LocaleDataBridge*&)newObj->databridge;
+ newBackend = LocaleBackend::CreateBackend();
+
+ if (newBackend == NULL) {
+ errno = ENOMEM;
+ delete newObj;
+ return (locale_t)0;
+ }
+
+ newDataBridge = new (std::nothrow) LocaleDataBridge(false);
+
+ if (newDataBridge == NULL) {
+ errno = ENOMEM;
+ delete newBackend;
+ delete newObj;
+ return (locale_t)0;
+ }
+
+ newBackend->Initialize(newDataBridge);
+
+ // Skipping LC_ALL. Asking for LC_ALL would force the backend
+ // to query each other value once, anyway.
+ for (int lc = 1; lc <= LC_LAST; ++lc) {
+ newBackend->SetLocale(lc, backend->SetLocale(lc, NULL));
+ }
+
+ return newObj;
+}
diff --git a/src/system/libroot/posix/locale/freelocale.cpp
b/src/system/libroot/posix/locale/freelocale.cpp
new file mode 100644
index 0000000..ccc29ea
--- /dev/null
+++ b/src/system/libroot/posix/locale/freelocale.cpp
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2022, Trung Nguyen, trungnt282910@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+
+#include <locale.h>
+
+#include "LocaleBackend.h"
+
+
+using BPrivate::Libroot::LocaleBackend;
+using BPrivate::Libroot::LocaleDataBridge;
+
+
+extern "C" void
+freelocale(locale_t locobj)
+{
+ if (locobj->backend) {
+ LocaleBackend::DestroyBackend((LocaleBackend*)locobj->backend);
+ LocaleDataBridge* databridge = (LocaleDataBridge*)locobj->databridge;
+ delete databridge;
+ }
+ delete locobj;
+}
diff --git a/src/system/libroot/posix/locale/localeconv.cpp
b/src/system/libroot/posix/locale/localeconv.cpp
index 8b353cc..7c397ff 100644
--- a/src/system/libroot/posix/locale/localeconv.cpp
+++ b/src/system/libroot/posix/locale/localeconv.cpp
@@ -12,7 +12,6 @@
#ifndef _KERNEL_MODE
#include "LocaleBackend.h"
-using BPrivate::Libroot::gLocaleBackend;
#endif
@@ -20,8 +19,8 @@
localeconv(void)
{
#ifndef _KERNEL_MODE
- if (gLocaleBackend)
- return const_cast<lconv*>(gLocaleBackend->LocaleConv());
+ if (GET_LOCALE_BACKEND())
+ return const_cast<lconv*>(GET_LOCALE_BACKEND()->LocaleConv());
#endif
return &BPrivate::Libroot::gPosixLocaleConv;
diff --git a/src/system/libroot/posix/locale/newlocale.cpp
b/src/system/libroot/posix/locale/newlocale.cpp
new file mode 100644
index 0000000..fad4a9d
--- /dev/null
+++ b/src/system/libroot/posix/locale/newlocale.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2022, Trung Nguyen, trungnt282910@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+#include <new>
+#include <errno.h>
+#include <locale.h>
+#include <strings.h>
+
+#include <ErrnoMaintainer.h>
+
+#include "LocaleBackend.h"
+#include "LocaleInternal.h"
+
+
+using BPrivate::Libroot::GetLocalesFromEnvironment;
+using BPrivate::Libroot::LocaleBackend;
+using BPrivate::Libroot::LocaleDataBridge;
+
+
+extern "C" locale_t
+newlocale(int category_mask, const char* locale, locale_t base)
+{
+ if (((category_mask | LC_ALL_MASK) != LC_ALL_MASK) || (locale == NULL)) {
+ errno = EINVAL;
+ return (locale_t)0;
+ }
+
+ bool newObject = false;
+
+ if (base == NULL) {
+ base = new (std::nothrow) __locale_t;
+ if (base == NULL) {
+ errno = ENOMEM;
+ return (locale_t)0;
+ }
+ base->magic = LOCALE_T_MAGIC;
+ base->backend = NULL;
+
+ newObject = true;
+ }
+
+ LocaleBackend*& backend = (LocaleBackend*&)base->backend;
+ LocaleDataBridge*& databridge = (LocaleDataBridge*&)base->databridge;
+
+ const char* locales[LC_LAST + 1];
+ for (int lc = 0; lc <= LC_LAST; lc++)
+ locales[lc] = NULL;
+
+ if (*locale == '\0') {
+ if (category_mask == LC_ALL_MASK) {
+ GetLocalesFromEnvironment(LC_ALL, locales);
+ } else {
+ for (int lc = 1; lc <= LC_LAST; ++lc) {
+ if (category_mask & (1 << (lc - 1))) {
+ GetLocalesFromEnvironment(lc, locales);
+ }
+ }
+ }
+ } else {
+ if (category_mask == LC_ALL_MASK) {
+ locales[LC_ALL] = locale;
+ }
+ for (int lc = 1; lc <= LC_LAST; ++lc) {
+ if (category_mask & (1 << (lc - 1))) {
+ locales[lc] = locale;
+ }
+ }
+ }
+
+ if (!backend) {
+ // for any locale other than POSIX/C, we try to activate the ICU
+ // backend
+ bool needBackend = false;
+ for (int lc = 0; lc <= LC_LAST; lc++) {
+ if (locales[lc] != NULL && strcasecmp(locales[lc], "POSIX") != 0
+ && strcasecmp(locales[lc], "C") != 0) {
+ needBackend = true;
+ break;
+ }
+ }
+ if (needBackend) {
+ backend = LocaleBackend::CreateBackend();
+ if (backend == NULL) {
+ errno = ENOMEM;
+ if (newObject) {
+ delete base;
+ }
+ return (locale_t)0;
+ }
+ databridge = new (std::nothrow) LocaleDataBridge(false);
+ if (databridge == NULL) {
+ errno = ENOMEM;
+ delete backend;
+ if (newObject) {
+ delete base;
+ }
+ return (locale_t)0;
+ }
+ backend->Initialize(databridge);
+ }
+ }
+
+ BPrivate::ErrnoMaintainer errnoMaintainer;
+
+ if (backend != NULL) {
+ for (int lc = 0; lc <= LC_LAST; lc++) {
+ if (locales[lc] != NULL) {
+ locale = backend->SetLocale(lc, locales[lc]);
+ if (lc == LC_ALL) {
+ // skip the rest, LC_ALL overrides
+ break;
+ }
+ }
+ }
+ }
+
+ return base;
+}
diff --git a/src/system/libroot/posix/locale/nl_langinfo.cpp
b/src/system/libroot/posix/locale/nl_langinfo.cpp
index b48f6f5..48670f8 100644
--- a/src/system/libroot/posix/locale/nl_langinfo.cpp
+++ b/src/system/libroot/posix/locale/nl_langinfo.cpp
@@ -11,7 +11,6 @@
#include <PosixLanginfo.h>
-using BPrivate::Libroot::gLocaleBackend;
using BPrivate::Libroot::gPosixLanginfo;
@@ -21,8 +20,8 @@
if (item < 0 || item >= _NL_LANGINFO_LAST)
return const_cast<char*>("");
- if (gLocaleBackend != NULL)
- return const_cast<char*>(gLocaleBackend->GetLanginfo(item));
+ if (GET_LOCALE_BACKEND() != NULL)
+ return
const_cast<char*>(GET_LOCALE_BACKEND()->GetLanginfo(item));
return const_cast<char*>(gPosixLanginfo[item]);
}
diff --git a/src/system/libroot/posix/locale/setlocale.cpp
b/src/system/libroot/posix/locale/setlocale.cpp
index 7977780..7519e1d 100644
--- a/src/system/libroot/posix/locale/setlocale.cpp
+++ b/src/system/libroot/posix/locale/setlocale.cpp
@@ -7,65 +7,19 @@
#include <ctype.h>
#include <locale.h>
-#include <stdlib.h>
#include <strings.h>
#include <ErrnoMaintainer.h>
#include "LocaleBackend.h"
+#include "LocaleInternal.h"
-using BPrivate::Libroot::gLocaleBackend;
+using BPrivate::Libroot::gGlobalLocaleBackend;
+using BPrivate::Libroot::GetLocalesFromEnvironment;
using BPrivate::Libroot::LocaleBackend;
-static status_t
-GetLocalesFromEnvironment(int category, const char** locales)
-{
- const char* locale = getenv("LC_ALL");
- if (locale && *locale)
- locales[category] = locale;
- else {
- // the order of the names must match the one specified in
locale.h
- const char* categoryNames[] = {
- "LC_ALL",
- "LC_COLLATE",
- "LC_CTYPE",
- "LC_MONETARY",
- "LC_NUMERIC",
- "LC_TIME",
- "LC_MESSAGES"
- };
- int from, to;
- if (category == LC_ALL) {
- // we need to check each real category if all of them
should be set
- from = 1;
- to = LC_LAST;
- } else
- from = to = category;
- bool haveDifferentLocales = false;
- locale = NULL;
- for (int lc = from; lc <= to; lc++) {
- const char* lastLocale = locale;
- locale = getenv(categoryNames[lc]);
- if (!locale || *locale == '\0')
- locale = getenv("LANG");
- if (!locale || *locale == '\0')
- locale = "POSIX";
- locales[lc] = locale;
- if (lastLocale && strcasecmp(locale, lastLocale) != 0)
- haveDifferentLocales = true;
- }
- if (!haveDifferentLocales) {
- // we can set all locales at once
- locales[LC_ALL] = locale;
- }
- }
-
- return B_OK;
-}
-
-
extern "C" char*
setlocale(int category, const char* locale)
{
@@ -76,8 +30,8 @@
if (locale == NULL) {
// query the locale of the given category
- if (gLocaleBackend != NULL)
- return
const_cast<char*>(gLocaleBackend->SetLocale(category, NULL));
+ if (gGlobalLocaleBackend != NULL)
+ return
const_cast<char*>(gGlobalLocaleBackend->SetLocale(category, NULL));
else
return const_cast<char*>("POSIX");
}
@@ -93,7 +47,7 @@
else
locales[category] = locale;
- if (!gLocaleBackend) {
+ if (!gGlobalLocaleBackend) {
// for any locale other than POSIX/C, we try to activate the ICU
// backend
bool needBackend = false;
@@ -108,17 +62,17 @@
return NULL;
}
- if (gLocaleBackend != NULL) {
+ if (gGlobalLocaleBackend != NULL) {
for (int lc = 0; lc <= LC_LAST; lc++) {
if (locales[lc] != NULL) {
- locale = gLocaleBackend->SetLocale(lc,
locales[lc]);
+ locale = gGlobalLocaleBackend->SetLocale(lc,
locales[lc]);
if (lc == LC_ALL) {
// skip the rest, LC_ALL overrides
return const_cast<char*>(locale);
}
}
}
- return const_cast<char*>(gLocaleBackend->SetLocale(category,
NULL));
+ return
const_cast<char*>(gGlobalLocaleBackend->SetLocale(category, NULL));
}
return const_cast<char*>("POSIX");
diff --git a/src/system/libroot/posix/locale/uselocale.cpp
b/src/system/libroot/posix/locale/uselocale.cpp
new file mode 100644
index 0000000..c3b7c89
--- /dev/null
+++ b/src/system/libroot/posix/locale/uselocale.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2022, Trung Nguyen, trungnt282910@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+
+#include <errno.h>
+#include <locale.h>
+
+#include "LocaleBackend.h"
+#include "LocaleInternal.h"
+
+
+using BPrivate::Libroot::gGlobalLocaleDataBridge;
+using BPrivate::Libroot::gLocaleInfo;
+using BPrivate::Libroot::LocaleDataBridge;
+
+
+extern "C" locale_t
+uselocale(locale_t newLoc)
+{
+ locale_t oldLoc = gLocaleInfo;
+ if (gLocaleInfo == NULL) {
+ oldLoc = LC_GLOBAL_LOCALE;
+ }
+
+ if (newLoc != (locale_t)0) {
+ if (newLoc == LC_GLOBAL_LOCALE) {
+ gLocaleInfo = NULL;
+ } else {
+ if (newLoc->magic != LOCALE_T_MAGIC) {
+ errno = EINVAL;
+ return (locale_t)0;
+ }
+ gLocaleInfo = newLoc;
+ }
+
+ if (gLocaleInfo != NULL) {
+
((LocaleDataBridge*)gLocaleInfo->databridge)->ApplyToCurrentThread();
+ } else {
+ gGlobalLocaleDataBridge.ApplyToCurrentThread();
+ }
+ }
+
+ return oldLoc;
+}
diff --git a/src/system/libroot/posix/locale/wctype.cpp
b/src/system/libroot/posix/locale/wctype.cpp
index 4c50c5b..4b71446 100644
--- a/src/system/libroot/posix/locale/wctype.cpp
+++ b/src/system/libroot/posix/locale/wctype.cpp
@@ -13,7 +13,8 @@
#include "LocaleBackend.h"
-using BPrivate::Libroot::gLocaleBackend;
+using BPrivate::Libroot::LocaleBackend;
+
/*
* In many of the following functions, we make use of the fact that with
@@ -26,13 +27,15 @@
int
iswctype(wint_t wc, wctype_t charClass)
{
- if (gLocaleBackend == NULL) {
+ LocaleBackend* backend = GET_LOCALE_BACKEND();
+
+ if (backend == NULL) {
if (wc < 0 || wc > 127)
return 0;
return __isctype(wc, charClass);
}
- return gLocaleBackend->IsWCType(wc, charClass);
+ return backend->IsWCType(wc, charClass);
}
@@ -123,14 +126,16 @@
wint_t
towlower(wint_t wc)
{
- if (gLocaleBackend == NULL) {
+ LocaleBackend* backend = GET_LOCALE_BACKEND();
+
+ if (backend == NULL) {
if (wc < 0 || wc > 127)
return wc;
return tolower(wc);
}
wint_t result = wc;
- gLocaleBackend->ToWCTrans(wc, _ISlower, result);
+ backend->ToWCTrans(wc, _ISlower, result);
return result;
}
@@ -139,14 +144,16 @@
wint_t
towupper(wint_t wc)
{
- if (gLocaleBackend == NULL) {
+ LocaleBackend* backend = GET_LOCALE_BACKEND();
+
+ if (backend == NULL) {
if (wc < 0 || wc > 127)
return wc;
return toupper(wc);
}
wint_t result = wc;
- gLocaleBackend->ToWCTrans(wc, _ISupper, result);
+ backend->ToWCTrans(wc, _ISupper, result);
return result;
}
@@ -155,7 +162,9 @@
wint_t
towctrans(wint_t wc, wctrans_t transition)
{
- if (gLocaleBackend == NULL) {
+ LocaleBackend* backend = GET_LOCALE_BACKEND();
+
+ if (backend == NULL) {
if (transition == _ISlower)
return tolower(wc);
if (transition == _ISupper)
@@ -166,7 +175,7 @@
}
wint_t result = wc;
- status_t status = gLocaleBackend->ToWCTrans(wc, transition, result);
+ status_t status = backend->ToWCTrans(wc, transition, result);
if (status != B_OK)
__set_errno(EINVAL);
diff --git a/src/system/libroot/posix/string/strcoll.cpp
b/src/system/libroot/posix/string/strcoll.cpp
index 1a477e5..fa61d76 100644
--- a/src/system/libroot/posix/string/strcoll.cpp
+++ b/src/system/libroot/posix/string/strcoll.cpp
@@ -11,15 +11,17 @@
#include "LocaleBackend.h"
-using BPrivate::Libroot::gLocaleBackend;
+using BPrivate::Libroot::LocaleBackend;
extern "C" int
strcoll(const char *a, const char *b)
{
- if (gLocaleBackend != NULL) {
+ LocaleBackend* backend = GET_LOCALE_BACKEND();
+
+ if (backend != NULL) {
int result = 0;
- status_t status = gLocaleBackend->Strcoll(a, b, result);
+ status_t status = backend->Strcoll(a, b, result);
if (status != B_OK)
__set_errno(EINVAL);
diff --git a/src/system/libroot/posix/string/strxfrm.cpp
b/src/system/libroot/posix/string/strxfrm.cpp
index 058f3cf..fbeb1ba 100644
--- a/src/system/libroot/posix/string/strxfrm.cpp
+++ b/src/system/libroot/posix/string/strxfrm.cpp
@@ -11,15 +11,17 @@
#include "LocaleBackend.h"
-using BPrivate::Libroot::gLocaleBackend;
+using BPrivate::Libroot::LocaleBackend;
extern "C" size_t
strxfrm(char *out, const char *in, size_t size)
{
- if (gLocaleBackend != NULL) {
+ LocaleBackend* backend = GET_LOCALE_BACKEND();
+
+ if (backend != NULL) {
size_t outSize = 0;
- status_t status = gLocaleBackend->Strxfrm(out, in, size,
outSize);
+ status_t status = backend->Strxfrm(out, in, size, outSize);
if (status != B_OK)
__set_errno(EINVAL);
diff --git a/src/system/libroot/posix/time/localtime.cpp
b/src/system/libroot/posix/time/localtime.cpp
index 739712f..7923f89 100644
--- a/src/system/libroot/posix/time/localtime.cpp
+++ b/src/system/libroot/posix/time/localtime.cpp
@@ -17,7 +17,6 @@
#include "LocaleBackend.h"
-using BPrivate::Libroot::gLocaleBackend;
using BPrivate::Libroot::LocaleBackend;
@@ -43,13 +42,13 @@
extern "C" void
tzset(void)
{
- if (gLocaleBackend == NULL && LocaleBackend::LoadBackend() != B_OK)
+ if (GET_LOCALE_BACKEND() == NULL && LocaleBackend::LoadBackend() !=
B_OK)
return;
char timeZoneID[B_FILE_NAME_LENGTH] = { "GMT" };
_kern_get_timezone(NULL, timeZoneID, sizeof(timeZoneID));
- gLocaleBackend->TZSet(timeZoneID, getenv("TZ"));
+ GET_LOCALE_BACKEND()->TZSet(timeZoneID, getenv("TZ"));
}
@@ -71,8 +70,11 @@
}
tzset();
- if (gLocaleBackend != NULL) {
- status_t status = gLocaleBackend->Localtime(inTime, tmOut);
+
+ LocaleBackend* backend = GET_LOCALE_BACKEND();
+
+ if (backend != NULL) {
+ status_t status = backend->Localtime(inTime, tmOut);
if (status != B_OK)
__set_errno(EOVERFLOW);
@@ -104,8 +106,11 @@
}
tzset();
- if (gLocaleBackend != NULL) {
- status_t status = gLocaleBackend->Gmtime(inTime, tmOut);
+
+ LocaleBackend* backend = GET_LOCALE_BACKEND();
+
+ if (backend != NULL) {
+ status_t status = backend->Gmtime(inTime, tmOut);
if (status != B_OK)
__set_errno(EOVERFLOW);
@@ -128,9 +133,12 @@
}
tzset();
- if (gLocaleBackend != NULL) {
+
+ LocaleBackend* backend = GET_LOCALE_BACKEND();
+
+ if (backend != NULL) {
time_t timeOut;
- status_t status = gLocaleBackend->Mktime(inTm, timeOut);
+ status_t status = backend->Mktime(inTm, timeOut);
if (status != B_OK) {
__set_errno(EOVERFLOW);
@@ -154,9 +162,12 @@
return -1;
}
tzset();
- if (gLocaleBackend != NULL) {
+
+ LocaleBackend* backend = GET_LOCALE_BACKEND();
+
+ if (backend != NULL) {
time_t timeOut;
- status_t status = gLocaleBackend->Timegm(inTm, timeOut);
+ status_t status = backend->Timegm(inTm, timeOut);
if (status != B_OK) {
__set_errno(EOVERFLOW);
diff --git a/src/system/libroot/posix/time/timelocal.cpp
b/src/system/libroot/posix/time/timelocal.cpp
index bfa62bb..1b83bfe 100644
--- a/src/system/libroot/posix/time/timelocal.cpp
+++ b/src/system/libroot/posix/time/timelocal.cpp
@@ -12,14 +12,11 @@
#include "PosixLCTimeInfo.h"
-using BPrivate::Libroot::gLocaleBackend;
-
-
extern "C" const lc_time_t*
__get_current_time_locale(void)
{
- if (gLocaleBackend)
- return gLocaleBackend->LCTimeInfo();
+ if (GET_LOCALE_BACKEND())
+ return GET_LOCALE_BACKEND()->LCTimeInfo();
return &BPrivate::Libroot::gPosixLCTimeInfo;
}
diff --git a/src/system/libroot/posix/wchar/mbrtowc.cpp
b/src/system/libroot/posix/wchar/mbrtowc.cpp
index 38ee8a0..c2154e1 100644
--- a/src/system/libroot/posix/wchar/mbrtowc.cpp
+++ b/src/system/libroot/posix/wchar/mbrtowc.cpp
@@ -20,7 +20,7 @@
#endif
-using BPrivate::Libroot::gLocaleBackend;
+using BPrivate::Libroot::LocaleBackend;
extern "C" size_t
@@ -34,7 +34,9 @@
if (s == NULL)
return __mbrtowc(NULL, "", 1, ps);
- if (gLocaleBackend == NULL) {
+ LocaleBackend* backend = GET_LOCALE_BACKEND();
+
+ if (backend == NULL) {
if (*s == '\0') {
memset(ps, 0, sizeof(mbstate_t));
@@ -64,7 +66,7 @@
size_t lengthUsed;
status_t status
- = gLocaleBackend->MultibyteToWchar(pwc, s, n, ps, lengthUsed);
+ = backend->MultibyteToWchar(pwc, s, n, ps, lengthUsed);
if (status == B_BAD_INDEX)
return (size_t)-2;
diff --git a/src/system/libroot/posix/wchar/mbsrtowcs.cpp
b/src/system/libroot/posix/wchar/mbsrtowcs.cpp
index 7776be2..15b1d84 100644
--- a/src/system/libroot/posix/wchar/mbsrtowcs.cpp
+++ b/src/system/libroot/posix/wchar/mbsrtowcs.cpp
@@ -20,22 +20,24 @@
#endif
-using BPrivate::Libroot::gLocaleBackend;
+using BPrivate::Libroot::LocaleBackend;
extern "C" size_t
__mbsnrtowcs(wchar_t* dst, const char** src, size_t nmc, size_t len,
mbstate_t* ps)
{
+ LocaleBackend* backend = GET_LOCALE_BACKEND();
+
TRACE(("mbsnrtowcs(%p, %p, %lu, %lu) - lb:%p\n", dst, *src, nmc, len,
- gLocaleBackend));
+ backend));
if (ps == NULL) {
static mbstate_t internalMbState;
ps = &internalMbState;
}
- if (gLocaleBackend == NULL) {
+ if (backend == NULL) {
/*
* The POSIX locale is active. Since the POSIX locale only
contains
* chars 0-127 and those ASCII chars are compatible with the
UTF32
@@ -82,7 +84,7 @@
}
size_t result = 0;
- status_t status = gLocaleBackend->MultibyteStringToWchar(dst, len, src,
nmc,
+ status_t status = backend->MultibyteStringToWchar(dst, len, src, nmc,
ps, result);
if (status == B_BAD_DATA) {
@@ -112,7 +114,8 @@
ps = &internalMbState;
}
- size_t srcLen = gLocaleBackend == NULL ? strlen(*src) + 1 : (size_t)-1;
+ LocaleBackend* backend = GET_LOCALE_BACKEND();
+ size_t srcLen = backend == NULL ? strlen(*src) + 1 : (size_t)-1;
return __mbsnrtowcs(dst, src, srcLen, len, ps);
}
diff --git a/src/system/libroot/posix/wchar/wcrtomb.cpp
b/src/system/libroot/posix/wchar/wcrtomb.cpp
index 8285351..f84dfc9 100644
--- a/src/system/libroot/posix/wchar/wcrtomb.cpp
+++ b/src/system/libroot/posix/wchar/wcrtomb.cpp
@@ -20,12 +20,14 @@
#endif
-using BPrivate::Libroot::gLocaleBackend;
+using BPrivate::Libroot::LocaleBackend;
extern "C" size_t
__wcrtomb(char* s, wchar_t wc, mbstate_t* ps)
{
+ LocaleBackend* backend = GET_LOCALE_BACKEND();
+
if (ps == NULL) {
static mbstate_t internalMbState;
ps = &internalMbState;
@@ -34,7 +36,7 @@
if (s == NULL)
wc = 0;
- if (gLocaleBackend == NULL) {
+ if (backend == NULL) {
/*
* The POSIX locale is active. Since the POSIX locale only
contains
* chars 0-127 and those ASCII chars are compatible with the
UTF32
@@ -54,7 +56,7 @@
}
size_t lengthUsed;
- status_t status = gLocaleBackend->WcharToMultibyte(s, wc, ps,
lengthUsed);
+ status_t status = backend->WcharToMultibyte(s, wc, ps, lengthUsed);
if (status == B_BAD_INDEX)
return (size_t)-2;
diff --git a/src/system/libroot/posix/wchar/wcscoll.cpp
b/src/system/libroot/posix/wchar/wcscoll.cpp
index d06ffcb..e2d4e41f 100644
--- a/src/system/libroot/posix/wchar/wcscoll.cpp
+++ b/src/system/libroot/posix/wchar/wcscoll.cpp
@@ -8,15 +8,17 @@
#include <wchar_private.h>
-using BPrivate::Libroot::gLocaleBackend;
+using BPrivate::Libroot::LocaleBackend;
extern "C" int
__wcscoll(const wchar_t* wcs1, const wchar_t* wcs2)
{
- if (gLocaleBackend != NULL) {
+ LocaleBackend* backend = GET_LOCALE_BACKEND();
+
+ if (backend != NULL) {
int result = 0;
- status_t status = gLocaleBackend->Wcscoll(wcs1, wcs2, result);
+ status_t status = backend->Wcscoll(wcs1, wcs2, result);
if (status != B_OK)
__set_errno(EINVAL);
diff --git a/src/system/libroot/posix/wchar/wcsrtombs.cpp
b/src/system/libroot/posix/wchar/wcsrtombs.cpp
index 9d6b3cc..d33ab80 100644
--- a/src/system/libroot/posix/wchar/wcsrtombs.cpp
+++ b/src/system/libroot/posix/wchar/wcsrtombs.cpp
@@ -21,22 +21,24 @@
#endif
-using BPrivate::Libroot::gLocaleBackend;
+using BPrivate::Libroot::LocaleBackend;
extern "C" size_t
__wcsnrtombs(char* dst, const wchar_t** src, size_t nwc, size_t len,
mbstate_t* ps)
{
+ LocaleBackend* backend = GET_LOCALE_BACKEND();
+
TRACE(("wcsnrtombs(%p, %p, %lu, %lu) - lb:%p\n", dst, *src, nwc, len,
- gLocaleBackend));
+ backend));
if (ps == NULL) {
static mbstate_t internalMbState;
ps = &internalMbState;
}
- if (gLocaleBackend == NULL) {
+ if (backend == NULL) {
/*
* The POSIX locale is active. Since the POSIX locale only
contains
* chars 0-127 and those ASCII chars are compatible with the
UTF32
@@ -83,7 +85,7 @@
}
size_t result = 0;
- status_t status = gLocaleBackend->WcharStringToMultibyte(dst, len, src,
nwc,
+ status_t status = backend->WcharStringToMultibyte(dst, len, src, nwc,
ps, result);
if (status == B_BAD_DATA) {
diff --git a/src/system/libroot/posix/wchar/wcsxfrm.cpp
b/src/system/libroot/posix/wchar/wcsxfrm.cpp
index 4260703..fc8ebd9 100644
--- a/src/system/libroot/posix/wchar/wcsxfrm.cpp
+++ b/src/system/libroot/posix/wchar/wcsxfrm.cpp
@@ -10,15 +10,17 @@
#include <wchar_private.h>
-using BPrivate::Libroot::gLocaleBackend;
+using BPrivate::Libroot::LocaleBackend;
extern "C" size_t
__wcsxfrm(wchar_t* dest, const wchar_t* src, size_t destSize)
{
- if (gLocaleBackend != NULL) {
+ LocaleBackend* backend = GET_LOCALE_BACKEND();
+
+ if (backend != NULL) {
size_t outSize = 0;
- status_t status = gLocaleBackend->Wcsxfrm(dest, src, destSize,
outSize);
+ status_t status = backend->Wcsxfrm(dest, src, destSize,
outSize);
if (status != B_OK)
__set_errno(EINVAL);
diff --git a/src/system/libroot/stubbed/libroot_stubs.c
b/src/system/libroot/stubbed/libroot_stubs.c
index 5cd88a1..55458be 100644
--- a/src/system/libroot/stubbed/libroot_stubs.c
+++ b/src/system/libroot/stubbed/libroot_stubs.c
@@ -11,16 +11,17 @@
int _ZN8BPrivate10kGroupFileE;
int _ZN8BPrivate11kPasswdFileE;
int _ZN8BPrivate14kShadowPwdFileE;
-int _ZN8BPrivate7Libroot14gLocaleBackendE;
+int _ZN8BPrivate7Libroot11gLocaleInfoE;
int _ZN8BPrivate7Libroot14gPosixLanginfoE;
int _ZN8BPrivate7Libroot16gPosixLCTimeInfoE;
int _ZN8BPrivate7Libroot16gPosixLocaleConvE;
+int _ZN8BPrivate7Libroot20gGlobalLocaleBackendE;
+int _ZN8BPrivate7Libroot23gGlobalLocaleDataBridgeE;
int _ZN8BPrivate9hoardHeap10_sizeTableE;
int _ZN8BPrivate9hoardHeap10_thresholdE;
int _ZN8BPrivate9hoardHeap14_numProcessorsE;
int _ZN8BPrivate9hoardHeap15fMaxThreadHeapsE;
int _ZN8BPrivate9hoardHeap18_numProcessorsMaskE;
-int __bss_start;
int __ctype32_wctrans;
int __ctype32_wctype;
int __ctype_b;
@@ -28,6 +29,7 @@
int __ctype_tolower;
int __ctype_toupper;
int __gABIVersion;
+int __gAPIVersion;
int __gCPUCount;
int __gCommPageAddress;
int __gRuntimeLoader;
@@ -42,10 +44,10 @@
int __printf_arginfo_table;
int __printf_function_table;
int __progname;
+int __signgam;
+int __stack_chk_guard;
int __wcsmbs_gconv_fcts;
int _data_offset_main_;
-int _edata;
-int _end;
int _gSharedObjectHaikuABI;
int _gSharedObjectHaikuVersion;
int _nl_C_LC_COLLATE;
@@ -60,6 +62,7 @@
int _nl_current_LC_MESSAGES;
int _nl_current_LC_MONETARY;
int _nl_current_LC_NUMERIC;
+int _nl_global_locale;
int _obstack;
int _rtDebugFlag;
int _single_threaded;
@@ -79,12 +82,10 @@
int optind;
int optopt;
int re_syntax_options;
-int signgam;
int stderr;
int stdin;
int stdout;
int sys_siglist;
-int tab54;
int timezone;
int tzname;
@@ -288,6 +289,7 @@
void _Z17__init_after_forkv() {}
void _Z18HMAC_SHA256_UpdateP15HMAC_SHA256_CTXPKvm() {}
void _Z18crypto_scrypt_smixPhmmPvS0_() {}
+void _Z20__pthread_mutex_lockP14_pthread_mutexjl() {}
void _Z22internal_path_for_pathPcmPKcS1_19path_base_directoryS1_jS_m() {}
void _Z26get_driver_settings_stringPvPcPlb() {}
void
_Z36posix_spawn_file_actions_addchdir_npPP25_posix_spawn_file_actionsPKc() {}
@@ -312,7 +314,7 @@
void _ZN10__cxxabiv120__si_class_type_infoD0Ev() {}
void _ZN10__cxxabiv120__si_class_type_infoD1Ev() {}
void _ZN10__cxxabiv120__si_class_type_infoD2Ev() {}
-void _ZN11LocalRWLock15StructureUnlockEv() {}
+void _ZN11LocalRWLock5_WaitEbjl() {}
void _ZN11LocalRWLock8_UnblockEv() {}
void _ZN14parsed_element11SetCharTypeEha() {}
void _ZN14parsed_element5AdoptERK16known_identifier() {}
@@ -323,11 +325,17 @@
void
_ZN16DoublyLinkedListI15AtExitInfoBlock31DoublyLinkedListStandardGetLinkIS0_EED2Ev()
{}
void
_ZN16SinglyLinkedListI10AtExitInfo31SinglyLinkedListStandardGetLinkIS0_EED1Ev()
{}
void
_ZN16SinglyLinkedListI10AtExitInfo31SinglyLinkedListStandardGetLinkIS0_EED2Ev()
{}
+void _ZN17EnvironmentFilter5_InitEiPKcmPKS1_m() {}
+void _ZN8BPrivate10AutoLockerI11LocalRWLockNS1_7LockingEE6UnlockEv() {}
+void _ZN8BPrivate10AutoLockerI5mutex12MutexLockingE6UnlockEv() {}
+void _ZN8BPrivate10AutoLockerIiNS_16UserGroupLockingEE6UnlockEv() {}
void _ZN8BPrivate10hoardYieldEv() {}
void _ZN8BPrivate10superblock14makeSuperblockEiPNS_11processHeapE() {}
+void _ZN8BPrivate10superblock8getBlockEv() {}
void _ZN8BPrivate10superblockC1EiiPNS_9hoardHeapE() {}
void _ZN8BPrivate10superblockC2EiiPNS_9hoardHeapE() {}
void _ZN8BPrivate10threadHeap6mallocEm() {}
+void _ZN8BPrivate10threadHeap8memalignEmm() {}
void _ZN8BPrivate10threadHeapC1Ev() {}
void _ZN8BPrivate10threadHeapC2Ev() {}
void _ZN8BPrivate11hoardUnlockER5mutex() {}
@@ -370,14 +378,17 @@
void _ZN8BPrivate6SHA256D1Ev() {}
void _ZN8BPrivate6SHA256D2Ev() {}
void _ZN8BPrivate7Libroot13LocaleBackend11LoadBackendEv() {}
+void _ZN8BPrivate7Libroot13LocaleBackend13CreateBackendEv() {}
+void _ZN8BPrivate7Libroot13LocaleBackend14DestroyBackendEPS1_() {}
void _ZN8BPrivate7Libroot13LocaleBackendC1Ev() {}
void _ZN8BPrivate7Libroot13LocaleBackendC2Ev() {}
void _ZN8BPrivate7Libroot13LocaleBackendD0Ev() {}
void _ZN8BPrivate7Libroot13LocaleBackendD1Ev() {}
void _ZN8BPrivate7Libroot13LocaleBackendD2Ev() {}
void _ZN8BPrivate7Libroot15gPosixClassInfoE() {}
-void _ZN8BPrivate7Libroot16LocaleDataBridgeC1Ev() {}
-void _ZN8BPrivate7Libroot16LocaleDataBridgeC2Ev() {}
+void _ZN8BPrivate7Libroot16LocaleDataBridge20ApplyToCurrentThreadEv() {}
+void _ZN8BPrivate7Libroot16LocaleDataBridgeC1Eb() {}
+void _ZN8BPrivate7Libroot16LocaleDataBridgeC2Eb() {}
void _ZN8BPrivate7Libroot16LocaleDataBridgeD1Ev() {}
void _ZN8BPrivate7Libroot16LocaleDataBridgeD2Ev() {}
void _ZN8BPrivate7Libroot16gPosixToLowerMapE() {}
@@ -385,18 +396,25 @@
void _ZN8BPrivate7Libroot20LocaleTimeDataBridgeC1Ev() {}
void _ZN8BPrivate7Libroot20LocaleTimeDataBridgeC2Ev() {}
void _ZN8BPrivate7Libroot21LocaleCtypeDataBridge11setMbCurMaxEt() {}
-void _ZN8BPrivate7Libroot21LocaleCtypeDataBridgeC1Ev() {}
-void _ZN8BPrivate7Libroot21LocaleCtypeDataBridgeC2Ev() {}
-void _ZN8BPrivate7Libroot23LocaleNumericDataBridgeC1Ev() {}
-void _ZN8BPrivate7Libroot23LocaleNumericDataBridgeC2Ev() {}
+void _ZN8BPrivate7Libroot21LocaleCtypeDataBridge20ApplyToCurrentThreadEv() {}
+void _ZN8BPrivate7Libroot21LocaleCtypeDataBridgeC1Eb() {}
+void _ZN8BPrivate7Libroot21LocaleCtypeDataBridgeC2Eb() {}
+void _ZN8BPrivate7Libroot21LocaleCtypeDataBridgeD1Ev() {}
+void _ZN8BPrivate7Libroot21LocaleCtypeDataBridgeD2Ev() {}
+void _ZN8BPrivate7Libroot23LocaleNumericDataBridge20ApplyToCurrentThreadEv() {}
+void _ZN8BPrivate7Libroot23LocaleNumericDataBridgeC1Eb() {}
+void _ZN8BPrivate7Libroot23LocaleNumericDataBridgeC2Eb() {}
void _ZN8BPrivate7Libroot23LocaleNumericDataBridgeD1Ev() {}
void _ZN8BPrivate7Libroot23LocaleNumericDataBridgeD2Ev() {}
void _ZN8BPrivate7Libroot24LocaleMessagesDataBridgeC1Ev() {}
void _ZN8BPrivate7Libroot24LocaleMessagesDataBridgeC2Ev() {}
void _ZN8BPrivate7Libroot24LocaleMonetaryDataBridgeC1Ev() {}
void _ZN8BPrivate7Libroot24LocaleMonetaryDataBridgeC2Ev() {}
-void _ZN8BPrivate7Libroot24TimeConversionDataBridgeC1Ev() {}
-void _ZN8BPrivate7Libroot24TimeConversionDataBridgeC2Ev() {}
+void _ZN8BPrivate7Libroot24TimeConversionDataBridgeC1Eb() {}
+void _ZN8BPrivate7Libroot24TimeConversionDataBridgeC2Eb() {}
+void _ZN8BPrivate7Libroot24TimeConversionDataBridgeD1Ev() {}
+void _ZN8BPrivate7Libroot24TimeConversionDataBridgeD2Ev() {}
+void _ZN8BPrivate7Libroot25GetLocalesFromEnvironmentEiPPKc() {}
void _ZN8BPrivate8KMessage11ReceiveFromEilP17port_message_info() {}
void _ZN8BPrivate8KMessage11_InitBufferEj() {}
void _ZN8BPrivate8KMessage12_CapacityForEi() {}
@@ -431,7 +449,10 @@
void
_ZN8BPrivate9hoardHeap16insertSuperblockEiPNS_10superblockEPNS_11processHeapE()
{}
void _ZN8BPrivate9hoardHeap16removeSuperblockEPNS_10superblockEi() {}
void _ZN8BPrivate9hoardHeap19removeMaxSuperblockEi() {}
+void
_ZN8BPrivate9hoardHeap23findAvailableSuperblockEiRPNS_5blockEPNS_11processHeapE()
{}
void _ZN8BPrivate9hoardHeap5reuseEi() {}
+void _ZN8BPrivate9hoardHeap7recycleEPNS_10superblockE() {}
+void _ZN8BPrivate9hoardHeap8decStatsEiii() {}
void
_ZN8BPrivate9hoardHeap9freeBlockERPNS_5blockERPNS_10superblockEiPNS_11processHeapE()
{}
void _ZN8BPrivate9hoardHeapC1Ev() {}
void _ZN8BPrivate9hoardHeapC2Ev() {}
@@ -439,6 +460,8 @@
void _ZN8BPrivate9hoardSbrkEl() {}
void _ZN8DateMask10IsCompleteEv() {}
void _ZN8DateMask7HasTimeEv() {}
+void _ZN9__gnu_cxx20recursive_init_errorC1Ev() {}
+void _ZN9__gnu_cxx20recursive_init_errorC2Ev() {}
void _ZN9__gnu_cxx20recursive_init_errorD0Ev() {}
void _ZN9__gnu_cxx20recursive_init_errorD1Ev() {}
void _ZN9__gnu_cxx20recursive_init_errorD2Ev() {}
@@ -456,6 +479,7 @@
void _ZN9__gnu_cxx29__concurrence_broadcast_errorD1Ev() {}
void _ZN9__gnu_cxx29__concurrence_broadcast_errorD2Ev() {}
void _ZN9__gnu_cxx30__throw_concurrence_lock_errorEv() {}
+void _ZN9__gnu_cxx32__throw_concurrence_unlock_errorEv() {}
void _ZN9__gnu_cxx35__throw_concurrence_broadcast_errorEv() {}
void _ZN9__gnu_cxx9__freeresEv() {}
void _ZNK10__cxxabiv117__class_type_info10__do_catchEPKSt9type_infoPPvj() {}
@@ -494,7 +518,6 @@
void _ZNK8BPrivate8KMessage9FindFieldEPKcPNS_13KMessageFieldE() {}
void _ZNK8BPrivate8KMessage9FindFieldEPKcjPNS_13KMessageFieldE() {}
void _ZNK8BPrivate8KMessage9ReplyPortEv() {}
-void _ZNK8BPrivate8KMessage9_FindTypeIiEEiPKcjiPT_() {}
void _ZNK9__gnu_cxx24__concurrence_lock_error4whatEv() {}
void _ZNK9__gnu_cxx24__concurrence_wait_error4whatEv() {}
void _ZNK9__gnu_cxx26__concurrence_unlock_error4whatEv() {}
@@ -531,7 +554,6 @@
void _ZNSt9type_infoD1Ev() {}
void _ZNSt9type_infoD2Ev() {}
void _ZSt10unexpectedv() {}
-void
_ZSt13__adjust_heapIPN17EnvironmentFilter5EntryElS1_N9__gnu_cxx5__ops15_Iter_less_iterEEvT_T0_S7_T1_T2_()
{}
void _ZSt13get_terminatev() {}
void _ZSt13set_terminatePFvvE() {}
void _ZSt14get_unexpectedv() {}
@@ -597,40 +619,18 @@
void _ZdlPv() {}
void _ZdlPvRKSt9nothrow_t() {}
void _ZdlPvm() {}
+void _Znam() {}
void _ZnamRKSt9nothrow_t() {}
+void _Znwm() {}
void _ZnwmRKSt9nothrow_t() {}
-void __acos() {}
-void __acosf() {}
-void __acosh() {}
-void __acoshf() {}
-void __acoshl() {}
-void __acosl() {}
-void __acr() {}
-void __add() {}
void __allocate_pthread() {}
void __arch_get_stack_trace() {}
void __arch_get_system_time_offset() {}
void __arch_init_time() {}
-void __asin() {}
-void __asinf() {}
-void __asinh() {}
-void __asinhf() {}
-void __asinhl() {}
-void __asinl() {}
void __asprintf() {}
void __assert_fail() {}
void __assert_perror_fail() {}
-void __atan2() {}
-void __atan2f() {}
-void __atan2l() {}
-void __atanf() {}
-void __atanh() {}
-void __atanhf() {}
-void __atanhl() {}
-void __atanl() {}
-void __branred() {}
void __btowc() {}
-void __c32() {}
void __cabs() {}
void __cabsf() {}
void __cabsl() {}
@@ -655,18 +655,12 @@
void __catanhf() {}
void __catanhl() {}
void __catanl() {}
-void __cbrt() {}
-void __cbrtf() {}
-void __cbrtl() {}
void __ccos() {}
void __ccosf() {}
void __ccosh() {}
void __ccoshf() {}
void __ccoshl() {}
void __ccosl() {}
-void __ceil() {}
-void __ceilf() {}
-void __ceill() {}
void __cexp() {}
void __cexpf() {}
void __cexpl() {}
@@ -686,25 +680,12 @@
void __conj() {}
void __conjf() {}
void __conjl() {}
-void __copysign() {}
-void __copysignf() {}
-void __copysignl() {}
-void __cos() {}
-void __cos32() {}
-void __cosf() {}
-void __cosh() {}
-void __coshf() {}
-void __coshl() {}
-void __cosl() {}
void __cpow() {}
void __cpowf() {}
void __cpowl() {}
void __cproj() {}
void __cprojf() {}
void __cprojl() {}
-void __cpy() {}
-void __cpymn() {}
-void __cr() {}
void __creal() {}
void __crealf() {}
void __creall() {}
@@ -724,7 +705,10 @@
void __ctanhf() {}
void __ctanhl() {}
void __ctanl() {}
+void __ctype_b_loc() {}
void __ctype_get_mb_cur_max() {}
+void __ctype_tolower_loc() {}
+void __ctype_toupper_loc() {}
void __cxa_allocate_dependent_exception() {}
void __cxa_allocate_exception() {}
void __cxa_atexit() {}
@@ -734,7 +718,6 @@
void __cxa_call_terminate() {}
void __cxa_call_unexpected() {}
void __cxa_current_exception_type() {}
-void __cxa_deleted_virtual() {}
void __cxa_demangle() {}
void __cxa_end_catch() {}
void __cxa_finalize() {}
@@ -747,50 +730,12 @@
void __cxa_guard_acquire() {}
void __cxa_guard_release() {}
void __cxa_init_primary_exception() {}
-void __cxa_pure_virtual() {}
void __cxa_rethrow() {}
void __cxa_throw() {}
void __cxa_throw_bad_array_new_length() {}
-void __dbl_mp() {}
-void __doasin() {}
-void __docos() {}
void __drand48_iterate() {}
-void __drem() {}
-void __dremf() {}
-void __dreml() {}
-void __dubcos() {}
-void __dubsin() {}
-void __dvd() {}
void __erand48_r() {}
-void __erf() {}
-void __erfc() {}
-void __erfcf() {}
-void __erfcl() {}
-void __erff() {}
-void __erfl() {}
-void __exp() {}
-void __exp1() {}
-void __exp10() {}
-void __exp10f() {}
-void __exp10l() {}
-void __exp2() {}
-void __exp2f() {}
-void __exp2l() {}
-void __exp_atable() {}
-void __exp_deltatable() {}
-void __expf() {}
-void __expl() {}
-void __expl_finite() {}
-void __expm1() {}
-void __expm1f() {}
-void __expm1l() {}
-void __fabs() {}
-void __fabsf() {}
-void __fabsl() {}
void __fcloseall() {}
-void __fdim() {}
-void __fdimf() {}
-void __fdiml() {}
void __fe_dfl_env() {}
void __fedisableexcept() {}
void __feenableexcept() {}
@@ -806,21 +751,6 @@
void __finitef() {}
void __finitel() {}
void __flatten_process_args() {}
-void __floor() {}
-void __floorf() {}
-void __floorl() {}
-void __fma() {}
-void __fmaf() {}
-void __fmal() {}
-void __fmax() {}
-void __fmaxf() {}
-void __fmaxl() {}
-void __fmin() {}
-void __fminf() {}
-void __fminl() {}
-void __fmod() {}
-void __fmodf() {}
-void __fmodl() {}
void __fopen_internal() {}
void __fopen_maybe_mmap() {}
void __fpclassify() {}
@@ -828,9 +758,6 @@
void __fpclassifyl() {}
void __fpurge() {}
void __freading() {}
-void __frexp() {}
-void __frexpf() {}
-void __frexpl() {}
void __fsetlocking() {}
void __fts_children() {}
void __fts_close() {}
@@ -841,9 +768,6 @@
void __fts_set() {}
void __fts_set_clientptr() {}
void __fwprintf() {}
-void __gamma() {}
-void __gammaf() {}
-void __gammal() {}
void __gcclibcxx_demangle_callback() {}
void __gconv_get_builtin_trans() {}
void __gconv_transform_ascii_internal() {}
@@ -873,113 +797,22 @@
void __guess_grouping() {}
void __guess_secondary_architecture_from_path() {}
void __gxx_personality_v0() {}
-void __halfulp() {}
-void __hdestroy() {}
void __heap_after_fork_child() {}
void __heap_after_fork_parent() {}
void __heap_before_fork() {}
void __heap_terminate_after() {}
void __heap_thread_exit() {}
void __heap_thread_init() {}
-void __hypot() {}
-void __hypotf() {}
-void __hypotl() {}
-void __ieee754_acos() {}
-void __ieee754_acosf() {}
-void __ieee754_acosh() {}
-void __ieee754_acoshf() {}
-void __ieee754_acoshl() {}
-void __ieee754_acosl() {}
-void __ieee754_asin() {}
-void __ieee754_asinf() {}
-void __ieee754_asinl() {}
-void __ieee754_atan2() {}
-void __ieee754_atan2f() {}
-void __ieee754_atan2l() {}
-void __ieee754_atanh() {}
-void __ieee754_atanhf() {}
-void __ieee754_atanhl() {}
-void __ieee754_cosh() {}
-void __ieee754_coshf() {}
-void __ieee754_coshl() {}
-void __ieee754_exp() {}
-void __ieee754_exp10() {}
-void __ieee754_exp10f() {}
-void __ieee754_exp10l() {}
-void __ieee754_exp2() {}
-void __ieee754_exp2f() {}
-void __ieee754_exp2l() {}
-void __ieee754_expf() {}
-void __ieee754_expl() {}
-void __ieee754_fmod() {}
-void __ieee754_fmodf() {}
-void __ieee754_fmodl() {}
-void __ieee754_gamma_r() {}
-void __ieee754_gammaf_r() {}
-void __ieee754_gammal_r() {}
-void __ieee754_hypot() {}
-void __ieee754_hypotf() {}
-void __ieee754_hypotl() {}
-void __ieee754_ilogbl() {}
-void __ieee754_j0() {}
-void __ieee754_j0f() {}
-void __ieee754_j0l() {}
-void __ieee754_j1() {}
-void __ieee754_j1f() {}
-void __ieee754_j1l() {}
-void __ieee754_jn() {}
-void __ieee754_jnf() {}
-void __ieee754_jnl() {}
-void __ieee754_lgamma_r() {}
-void __ieee754_lgammaf_r() {}
-void __ieee754_lgammal_r() {}
-void __ieee754_log() {}
-void __ieee754_log10() {}
-void __ieee754_log10f() {}
-void __ieee754_log10l() {}
-void __ieee754_log2() {}
-void __ieee754_log2f() {}
-void __ieee754_log2l() {}
-void __ieee754_logf() {}
-void __ieee754_logl() {}
-void __ieee754_pow() {}
-void __ieee754_powf() {}
-void __ieee754_powl() {}
-void __ieee754_rem_pio2() {}
-void __ieee754_rem_pio2f() {}
-void __ieee754_remainder() {}
-void __ieee754_remainderf() {}
-void __ieee754_remainderl() {}
-void __ieee754_scalb() {}
-void __ieee754_scalbf() {}
-void __ieee754_scalbl() {}
-void __ieee754_sinh() {}
-void __ieee754_sinhf() {}
-void __ieee754_sinhl() {}
-void __ieee754_sqrt() {}
-void __ieee754_sqrtf() {}
-void __ieee754_sqrtl() {}
-void __ieee754_y0() {}
-void __ieee754_y0f() {}
-void __ieee754_y0l() {}
-void __ieee754_y1() {}
-void __ieee754_y1f() {}
-void __ieee754_y1l() {}
-void __ieee754_yn() {}
-void __ieee754_ynf() {}
-void __ieee754_ynl() {}
-void __ilogb() {}
-void __ilogbf() {}
-void __ilogbl() {}
void __init_env() {}
void __init_env_post_heap() {}
void __init_heap() {}
void __init_once() {}
void __init_pthread() {}
void __init_pwd_backend() {}
+void __init_stack_protector() {}
void __init_time() {}
void __initstate_r() {}
-void __inv() {}
+void __ioctl() {}
void __isinf() {}
void __isinff() {}
void __isinfl() {}
@@ -990,56 +823,15 @@
void __kernel_casinh() {}
void __kernel_casinhf() {}
void __kernel_casinhl() {}
-void __kernel_cosf() {}
-void __kernel_rem_pio2() {}
-void __kernel_rem_pio2f() {}
-void __kernel_sinf() {}
-void __kernel_tan() {}
-void __kernel_tanf() {}
void __lcong48_r() {}
-void __ldexp() {}
-void __ldexpf() {}
-void __ldexpl() {}
-void __lgamma() {}
-void __lgamma_r() {}
-void __lgammaf() {}
-void __lgammaf_r() {}
-void __lgammal() {}
void __lgammal_r() {}
void __libc_dlclose() {}
void __libc_dlopen() {}
void __libc_dlsym() {}
void __libc_use_alloca() {}
-void __llrint() {}
-void __llrintf() {}
-void __llrintl() {}
-void __llround() {}
-void __llroundf() {}
-void __llroundl() {}
-void __log() {}
-void __log10() {}
-void __log10f() {}
-void __log10l() {}
-void __log1p() {}
-void __log1pf() {}
-void __log1pl() {}
-void __log2() {}
-void __log2f() {}
-void __log2l() {}
-void __logb() {}
-void __logbf() {}
-void __logbl() {}
-void __logf() {}
-void __logf_finite() {}
-void __logl() {}
+void __load_image_at_path() {}
void __longjmp_return() {}
-void __lrint() {}
-void __lrintf() {}
-void __lrintl() {}
-void __lround() {}
-void __lroundf() {}
-void __lroundl() {}
-void __matherr() {}
+void __look_up_in_path() {}
void __mblen() {}
void __mbrlen() {}
void __mbrtowc() {}
@@ -1050,16 +842,6 @@
void __mbtowc() {}
void __memrchr() {}
void __mktime_fallback() {}
-void __modf() {}
-void __modff() {}
-void __modfl() {}
-void __mp_dbl() {}
-void __mpatan() {}
-void __mpatan2() {}
-void __mpcos() {}
-void __mpcos1() {}
-void __mpexp() {}
-void __mplog() {}
void __mpn_add() {}
void __mpn_add_1() {}
void __mpn_add_n() {}
@@ -1084,23 +866,11 @@
void __mpn_sub_1() {}
void __mpn_sub_n() {}
void __mpn_submul_1() {}
-void __mpranred() {}
-void __mpsin() {}
-void __mpsin1() {}
-void __mpsqrt() {}
-void __mptan() {}
-void __mul() {}
void __mutex_destroy() {}
void __mutex_init() {}
void __mutex_init_etc() {}
void __mutex_lock() {}
void __mutex_unlock() {}
-void __nan() {}
-void __nanf() {}
-void __nanl() {}
-void __nearbyint() {}
-void __nearbyintf() {}
-void __nearbyintl() {}
void __new_fclose() {}
void __new_fdopen() {}
void __new_fgetpos() {}
@@ -1109,26 +879,16 @@
void __new_pclose() {}
void __new_popen() {}
void __new_tmpfile() {}
-void __nextafter() {}
-void __nextafterf() {}
-void __nextafterl() {}
-void __nexttoward() {}
-void __nexttowardf() {}
-void __nexttowardl() {}
void __nrand48_r() {}
void __overflow() {}
void __parse_invoke_line() {}
void __path_search() {}
-void __pow() {}
-void __pow10() {}
-void __pow10f() {}
-void __pow10l() {}
-void __powf() {}
-void __powl() {}
+void __ppoll() {}
void __printf_fp() {}
void __printf_fphex() {}
void __pselect() {}
void __pselect_beos() {}
+void __pthread_attr_get_np() {}
void __pthread_cleanup_pop_handler() {}
void __pthread_cleanup_push_handler() {}
void __pthread_destroy_thread() {}
@@ -1150,18 +910,6 @@
void __register_atfork() {}
void __register_printf_function() {}
void __reinit_pwd_backend_after_fork() {}
-void __remainder() {}
-void __remainderf() {}
-void __remainderl() {}
-void __remquo() {}
-void __remquof() {}
-void __remquol() {}
-void __rint() {}
-void __rintf() {}
-void __rintl() {}
-void __round() {}
-void __roundf() {}
-void __roundl() {}
void __rw_lock_destroy() {}
void __rw_lock_init() {}
void __rw_lock_init_etc() {}
@@ -1169,15 +917,6 @@
void __rw_lock_read_unlock() {}
void __rw_lock_write_lock() {}
void __rw_lock_write_unlock() {}
-void __scalb() {}
-void __scalbf() {}
-void __scalbl() {}
-void __scalbln() {}
-void __scalblnf() {}
-void __scalblnl() {}
-void __scalbn() {}
-void __scalbnf() {}
-void __scalbnl() {}
void __seed48_r() {}
void __set_scheduler_mode() {}
void __set_stack_protection() {}
@@ -1201,7 +940,6 @@
void __siginterrupt_beos() {}
void __sigismember() {}
void __sigismember_beos() {}
-void __signArctan() {}
void __signal() {}
void __signal_beos() {}
void __signal_get_sigrtmax() {}
@@ -1209,9 +947,6 @@
void __signbit() {}
void __signbitf() {}
void __signbitl() {}
-void __significand() {}
-void __significandf() {}
-void __significandl() {}
void __sigpause() {}
void __sigpause_beos() {}
void __sigpending() {}
@@ -1227,24 +962,11 @@
void __sigsuspend_beos() {}
void __sigwait() {}
void __sigwait_beos() {}
-void __sin() {}
-void __sin32() {}
-void __sincos() {}
-void __sincosf() {}
-void __sincosl() {}
-void __sinf() {}
-void __sinh() {}
-void __sinhf() {}
-void __sinhl() {}
-void __sinl() {}
-void __slowexp() {}
-void __slowpow() {}
void __snprintf() {}
-void __sqrt() {}
-void __sqrtf() {}
-void __sqrtl() {}
void __srand48_r() {}
void __srandom_r() {}
+void __stack_chk_fail() {}
+void __stack_chk_fail_local() {}
void __start_watching_system() {}
void __stop_watching_system() {}
void __strtod_internal() {}
@@ -1254,7 +976,6 @@
void __strtoll_internal() {}
void __strtoul_internal() {}
void __strtoull_internal() {}
-void __sub() {}
void __swap_double() {}
void __swap_float() {}
void __swap_int16() {}
@@ -1262,28 +983,12 @@
void __swap_int64() {}
void __sysconf() {}
void __sysconf_beos() {}
-void __tanf() {}
-void __tanh() {}
-void __tanhf() {}
-void __tanhl() {}
-void __tanl() {}
-void __tdelete() {}
-void __tdestroy() {}
void __tens() {}
void __test_executable() {}
-void __tfind() {}
-void __tgamma() {}
-void __tgammaf() {}
-void __tgammal() {}
+void __timegm_fallback() {}
void __times() {}
void __times_beos() {}
void __tls_get_addr() {}
-void ___tls_get_addr() {}
-void __trunc() {}
-void __truncf() {}
-void __truncl() {}
-void __tsearch() {}
-void __twalk() {}
void __uflow() {}
void __underflow() {}
void __vfscanf() {}
@@ -1356,6 +1061,7 @@
void _fstat_beos() {}
void _fstat_current() {}
void _get_area_info() {}
+void _get_cpu_info_etc() {}
void _get_image_info() {}
void _get_next_area_info() {}
void _get_next_image_info() {}
@@ -1370,6 +1076,8 @@
void _get_team_usage_info() {}
void _get_thread_info() {}
void _getopt_internal() {}
+void _getrusage_base() {}
+void _getrusage_current() {}
void _init() {}
void _init_c_library_() {}
void _itoa() {}
@@ -1498,8 +1206,10 @@
void _kern_lock_node() {}
void _kern_map_file() {}
void _kern_memory_advice() {}
+void _kern_mlock() {}
void _kern_mount() {}
void _kern_move_partition() {}
+void _kern_munlock() {}
void _kern_mutex_lock() {}
void _kern_mutex_sem_acquire() {}
void _kern_mutex_sem_release() {}
@@ -1519,6 +1229,7 @@
void _kern_poll() {}
void _kern_port_buffer_size_etc() {}
void _kern_port_count() {}
+void _kern_preallocate() {}
void _kern_process_info() {}
void _kern_read() {}
void _kern_read_attr() {}
@@ -1642,6 +1353,7 @@
void _kern_wait_for_objects() {}
void _kern_wait_for_team() {}
void _kern_wait_for_thread() {}
+void _kern_wait_for_thread_etc() {}
void _kern_write() {}
void _kern_write_attr() {}
void _kern_write_fs_info() {}
@@ -1715,6 +1427,7 @@
void acquire_sem() {}
void acquire_sem_etc() {}
void alarm() {}
+void aligned_alloc() {}
void alphasort() {}
void area_for() {}
void asctime() {}
@@ -1895,6 +1608,7 @@
void debug_vprintf() {}
void debugger() {}
void delete_area() {}
+void delete_driver_settings() {}
void delete_port() {}
void delete_sem() {}
void dev_for_path() {}
@@ -1908,19 +1622,21 @@
void dlerror() {}
void dlopen() {}
void dlsym() {}
+void dprintf() {}
void drand48() {}
void drand48_r() {}
void drem() {}
void dremf() {}
-void dreml() {}
void dup() {}
void dup2() {}
+void duplocale() {}
void ecvt() {}
void ecvt_r() {}
void encrypt() {}
void endgrent() {}
void endpwent() {}
void endspent() {}
+void endutxent() {}
void erand48() {}
void erand48_r() {}
void erf() {}
@@ -1955,7 +1671,6 @@
void fabsf() {}
void fabsl() {}
void faccessat() {}
-void fastiroot() {}
void fchdir() {}
void fchmod() {}
void fchmodat() {}
@@ -1974,16 +1689,13 @@
void fedisableexcept() {}
void feenableexcept() {}
void fegetenv() {}
-void fegetround() {}
void feholdexcept() {}
void feof() {}
void feof_unlocked() {}
void feraiseexcept() {}
void ferror() {}
void ferror_unlocked() {}
-void fesetenv() {}
void fesetexceptflag() {}
-void fesetround() {}
void feupdateenv() {}
void fflush() {}
void fflush_unlocked() {}
@@ -2048,6 +1760,7 @@
void fread() {}
void fread_unlocked() {}
void free() {}
+void freelocale() {}
void freopen() {}
void frexp() {}
void frexpf() {}
@@ -2108,9 +1821,6 @@
void fwrite() {}
void fwrite_unlocked() {}
void fwscanf() {}
-void gamma() {}
-void gammaf() {}
-void gammal() {}
void gcvt() {}
void get_architecture() {}
void get_architectures() {}
@@ -2175,7 +1885,6 @@
void getpwuid() {}
void getpwuid_r() {}
void getrlimit() {}
-void getrusage() {}
void gets() {}
void getsid() {}
void getspent() {}
@@ -2185,6 +1894,9 @@
void getsubopt() {}
void gettimeofday() {}
void getuid() {}
+void getutxent() {}
+void getutxid() {}
+void getutxline() {}
void getw() {}
void getwc() {}
void getwc_unlocked() {}
@@ -2258,13 +1970,10 @@
void isxdigit() {}
void j0() {}
void j0f() {}
-void j0l() {}
void j1() {}
void j1f() {}
-void j1l() {}
void jn() {}
void jnf() {}
-void jnl() {}
void jrand48() {}
void jrand48_r() {}
void kill() {}
@@ -2338,7 +2047,6 @@
void madvise() {}
void malloc() {}
void malloc_usable_size() {}
-void matherr() {}
void mblen() {}
void mbrlen() {}
void mbrtowc() {}
@@ -2367,6 +2075,7 @@
void mkstemps() {}
void mktemp() {}
void mktime() {}
+void mlock() {}
void mmap() {}
void modf() {}
void modff() {}
@@ -2380,6 +2089,7 @@
void msgsnd() {}
void mstats() {}
void msync() {}
+void munlock() {}
void munmap() {}
void nan() {}
void nanf() {}
@@ -2388,6 +2098,7 @@
void nearbyint() {}
void nearbyintf() {}
void nearbyintl() {}
+void newlocale() {}
void next_dev() {}
void nextafter() {}
void nextafterf() {}
@@ -2451,6 +2162,7 @@
void pow10l() {}
void powf() {}
void powl() {}
+void ppoll() {}
void pread() {}
void printf() {}
void printf_size() {}
@@ -2482,6 +2194,7 @@
void pthread_barrierattr_setpshared() {}
void pthread_cancel() {}
void pthread_cond_broadcast() {}
+void pthread_cond_clockwait() {}
void pthread_cond_destroy() {}
void pthread_cond_init() {}
void pthread_cond_signal() {}
@@ -2505,6 +2218,7 @@
void pthread_key_create() {}
void pthread_key_delete() {}
void pthread_kill() {}
+void pthread_mutex_clocklock() {}
void pthread_mutex_destroy() {}
void pthread_mutex_getprioceiling() {}
void pthread_mutex_init() {}
@@ -2524,6 +2238,8 @@
void pthread_mutexattr_setpshared() {}
void pthread_mutexattr_settype() {}
void pthread_once() {}
+void pthread_rwlock_clockrdlock() {}
+void pthread_rwlock_clockwrlock() {}
void pthread_rwlock_destroy() {}
void pthread_rwlock_init() {}
void pthread_rwlock_rdlock() {}
@@ -2556,6 +2272,7 @@
void putchar_unlocked() {}
void putenv() {}
void puts() {}
+void pututxline() {}
void putw() {}
void putwc() {}
void putwc_unlocked() {}
@@ -2628,7 +2345,6 @@
void sbrk() {}
void scalb() {}
void scalbf() {}
-void scalbl() {}
void scalbln() {}
void scalblnf() {}
void scalblnl() {}
@@ -2644,6 +2360,7 @@
void seed48_r() {}
void seekdir() {}
void select() {}
+void sem_clockwait() {}
void sem_close() {}
void sem_destroy() {}
void sem_getvalue() {}
@@ -2670,7 +2387,6 @@
void set_sem_owner() {}
void set_signal_stack() {}
void set_thread_priority() {}
-void set_timezone() {}
void setbuf() {}
void setbuffer() {}
void setegid() {}
@@ -2700,6 +2416,7 @@
void setstate() {}
void setstate_r() {}
void setuid() {}
+void setutxent() {}
void setvbuf() {}
void sgetspent() {}
void sgetspent_r() {}
@@ -2707,9 +2424,9 @@
void shm_unlink() {}
void sigaltstack() {}
void siglongjmp() {}
+void signgam() {}
void significand() {}
void significandf() {}
-void significandl() {}
void sigqueue() {}
void sigsetjmp() {}
void sigtimedwait() {}
@@ -2739,8 +2456,6 @@
void srand48_r() {}
void srandom() {}
void srandom_r() {}
-void __stack_chk_fail() {}
-void __stack_chk_fail_local() {}
void sscanf() {}
void statvfs() {}
void stime() {}
@@ -2813,9 +2528,11 @@
void tcflush() {}
void tcgetattr() {}
void tcgetpgrp() {}
+void tcgetsid() {}
void tcsendbreak() {}
void tcsetattr() {}
void tcsetpgrp() {}
+void tcsetsid() {}
void tdelete() {}
void tdestroy() {}
void telldir() {}
@@ -2825,6 +2542,14 @@
void tgamma() {}
void tgammaf() {}
void tgammal() {}
+void thrd_create() {}
+void thrd_current() {}
+void thrd_detach() {}
+void thrd_equal() {}
+void thrd_exit() {}
+void thrd_join() {}
+void thrd_sleep() {}
+void thrd_yield() {}
void time() {}
void timegm() {}
void timer_create() {}
@@ -2832,6 +2557,7 @@
void timer_getoverrun() {}
void timer_gettime() {}
void timer_settime() {}
+void timespec_get() {}
void tls_address() {}
void tls_allocate() {}
void tls_get() {}
@@ -2867,6 +2593,7 @@
void unload_driver_settings() {}
void unlockpt() {}
void unsetenv() {}
+void uselocale() {}
void usleep() {}
void utime() {}
void utimensat() {}
@@ -2959,13 +2686,10 @@
void wscanf() {}
void y0() {}
void y0f() {}
-void y0l() {}
void y1() {}
void y1f() {}
-void y1l() {}
void yn() {}
void ynf() {}
-void ynl() {}
#include <symbol_versioning.h>
@@ -2975,6 +2699,8 @@
DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("__find_directory_alpha4",
"find_directory@", "BASE");
DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("_fstat_current", "fstat@@", "1_ALPHA1");
DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("_fstat_beos", "fstat@", "BASE");
+DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("_getrusage_current", "getrusage@@",
"1_BETA3");
+DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("_getrusage_base", "getrusage@", "BASE");
DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("_lstat_current", "lstat@@", "1_ALPHA1");
DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("_lstat_beos", "lstat@", "BASE");
DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("__pselect", "pselect@@", "1_ALPHA4");
diff --git a/src/system/runtime_loader/Jamfile
b/src/system/runtime_loader/Jamfile
index 99b87e6..372e9e3 100644
--- a/src/system/runtime_loader/Jamfile
+++ b/src/system/runtime_loader/Jamfile
@@ -51,6 +51,7 @@
<src!system!libroot!posix!$(architecture)>fcntl.o
<src!system!libroot!posix!locale!$(architecture)>ctype.o
+
<src!system!libroot!posix!locale!$(architecture)>ctype_loc.o
<src!system!libroot!posix!locale!$(architecture)>LocaleData.o
<src!system!libroot!posix!string!$(architecture)>memchr.o
--
To view, visit https://review.haiku-os.org/c/haiku/+/5351
To unsubscribe, or for help writing mail filters, visit
https://review.haiku-os.org/settings
Gerrit-Project: haiku
Gerrit-Branch: master
Gerrit-Change-Id: Ibf296c58c47d42d1d1dfb2ce64042442f2679431
Gerrit-Change-Number: 5351
Gerrit-PatchSet: 1
Gerrit-Owner: Trung Nguyen <trungnt282910@xxxxxxxxx>
Gerrit-MessageType: newchange