Skip to content

[libc++] Add more missing bits to the locale base API #122531

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions libcxx/include/__locale
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ public:

static const category // values assigned here are for exposition only
none = 0,
collate = LC_COLLATE_MASK, ctype = LC_CTYPE_MASK, monetary = LC_MONETARY_MASK, numeric = LC_NUMERIC_MASK,
time = LC_TIME_MASK, messages = LC_MESSAGES_MASK, all = collate | ctype | monetary | numeric | time | messages;
collate = _LIBCPP_COLLATE_MASK, ctype = _LIBCPP_CTYPE_MASK, monetary = _LIBCPP_MONETARY_MASK,
numeric = _LIBCPP_NUMERIC_MASK, time = _LIBCPP_TIME_MASK, messages = _LIBCPP_MESSAGES_MASK,
all = collate | ctype | monetary | numeric | time | messages;

// construct/copy/destroy:
locale() _NOEXCEPT;
Expand Down
29 changes: 27 additions & 2 deletions libcxx/include/__locale_dir/locale_base_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,22 @@
// -----------------
// namespace __locale {
// using __locale_t = implementation-defined;
// using __lconv_t = implementation-defined;
// __locale_t __newlocale(int, const char*, __locale_t);
// void __freelocale(__locale_t);
// lconv* __localeconv(__locale_t&);
// char* __setlocale(int, const char*);
// __lconv_t* __localeconv(__locale_t&);
// }
//
// #define _LIBCPP_COLLATE_MASK /* implementation-defined */
// #define _LIBCPP_CTYPE_MASK /* implementation-defined */
// #define _LIBCPP_MONETARY_MASK /* implementation-defined */
// #define _LIBCPP_NUMERIC_MASK /* implementation-defined */
// #define _LIBCPP_TIME_MASK /* implementation-defined */
// #define _LIBCPP_MESSAGES_MASK /* implementation-defined */
// #define _LIBCPP_ALL_MASK /* implementation-defined */
// #define _LIBCPP_LC_ALL /* implementation-defined */
//
// Strtonum functions
// ------------------
// namespace __locale {
Expand Down Expand Up @@ -133,14 +144,28 @@ namespace __locale {
// Locale management
//
using __locale_t _LIBCPP_NODEBUG = locale_t;
using __lconv_t _LIBCPP_NODEBUG = lconv;

inline _LIBCPP_HIDE_FROM_ABI __locale_t __newlocale(int __category_mask, const char* __name, __locale_t __loc) {
return newlocale(__category_mask, __name, __loc);
}

inline _LIBCPP_HIDE_FROM_ABI char* __setlocale(int __category, char const* __locale) {
return ::setlocale(__category, __locale);
}

inline _LIBCPP_HIDE_FROM_ABI void __freelocale(__locale_t __loc) { freelocale(__loc); }

inline _LIBCPP_HIDE_FROM_ABI lconv* __localeconv(__locale_t& __loc) { return __libcpp_localeconv_l(__loc); }
inline _LIBCPP_HIDE_FROM_ABI __lconv_t* __localeconv(__locale_t& __loc) { return __libcpp_localeconv_l(__loc); }

# define _LIBCPP_COLLATE_MASK LC_COLLATE_MASK
# define _LIBCPP_CTYPE_MASK LC_CTYPE_MASK
# define _LIBCPP_MONETARY_MASK LC_MONETARY_MASK
# define _LIBCPP_NUMERIC_MASK LC_NUMERIC_MASK
# define _LIBCPP_TIME_MASK LC_TIME_MASK
# define _LIBCPP_MESSAGES_MASK LC_MESSAGES_MASK
# define _LIBCPP_ALL_MASK LC_ALL_MASK
# define _LIBCPP_LC_ALL LC_ALL

//
// Strtonum functions
Expand Down
16 changes: 15 additions & 1 deletion libcxx/include/__locale_dir/support/bsd_like.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,29 @@ namespace __locale {
//
// Locale management
//
#define _LIBCPP_COLLATE_MASK LC_COLLATE_MASK
#define _LIBCPP_CTYPE_MASK LC_CTYPE_MASK
#define _LIBCPP_MONETARY_MASK LC_MONETARY_MASK
#define _LIBCPP_NUMERIC_MASK LC_NUMERIC_MASK
#define _LIBCPP_TIME_MASK LC_TIME_MASK
#define _LIBCPP_MESSAGES_MASK LC_MESSAGES_MASK
#define _LIBCPP_ALL_MASK LC_ALL_MASK
#define _LIBCPP_LC_ALL LC_ALL

using __locale_t = ::locale_t;
using __lconv_t = std::lconv;

inline _LIBCPP_HIDE_FROM_ABI __locale_t __newlocale(int __category_mask, const char* __locale, __locale_t __base) {
return ::newlocale(__category_mask, __locale, __base);
}

inline _LIBCPP_HIDE_FROM_ABI void __freelocale(__locale_t __loc) { ::freelocale(__loc); }

inline _LIBCPP_HIDE_FROM_ABI lconv* __localeconv(__locale_t& __loc) { return ::localeconv_l(__loc); }
inline _LIBCPP_HIDE_FROM_ABI char* __setlocale(int __category, char const* __locale) {
return ::setlocale(__category, __locale);
}

inline _LIBCPP_HIDE_FROM_ABI __lconv_t* __localeconv(__locale_t& __loc) { return ::localeconv_l(__loc); }

//
// Strtonum functions
Expand Down
16 changes: 15 additions & 1 deletion libcxx/include/__locale_dir/support/fuchsia.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,29 @@ struct __locale_guard {
//
// Locale management
//
#define _LIBCPP_COLLATE_MASK LC_COLLATE_MASK
#define _LIBCPP_CTYPE_MASK LC_CTYPE_MASK
#define _LIBCPP_MONETARY_MASK LC_MONETARY_MASK
#define _LIBCPP_NUMERIC_MASK LC_NUMERIC_MASK
#define _LIBCPP_TIME_MASK LC_TIME_MASK
#define _LIBCPP_MESSAGES_MASK LC_MESSAGES_MASK
#define _LIBCPP_ALL_MASK LC_ALL_MASK
#define _LIBCPP_LC_ALL LC_ALL

using __locale_t = locale_t;
using __lconv_t = std::lconv;

inline _LIBCPP_HIDE_FROM_ABI __locale_t __newlocale(int __category_mask, const char* __name, __locale_t __loc) {
return ::newlocale(__category_mask, __name, __loc);
}

inline _LIBCPP_HIDE_FROM_ABI void __freelocale(__locale_t __loc) { ::freelocale(__loc); }

inline _LIBCPP_HIDE_FROM_ABI lconv* __localeconv(__locale_t& __loc) {
inline _LIBCPP_HIDE_FROM_ABI char* __setlocale(int __category, char const* __locale) {
return ::setlocale(__category, __locale);
}

inline _LIBCPP_HIDE_FROM_ABI __lconv_t* __localeconv(__locale_t& __loc) {
__locale_guard __current(__loc);
return std::localeconv();
}
Expand Down
52 changes: 28 additions & 24 deletions libcxx/include/__locale_dir/support/windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,14 @@
# pragma GCC system_header
#endif

#define _CATMASK(n) ((1 << (n)) >> 1)
#define LC_COLLATE_MASK _CATMASK(LC_COLLATE)
#define LC_CTYPE_MASK _CATMASK(LC_CTYPE)
#define LC_MONETARY_MASK _CATMASK(LC_MONETARY)
#define LC_NUMERIC_MASK _CATMASK(LC_NUMERIC)
#define LC_TIME_MASK _CATMASK(LC_TIME)
#define LC_MESSAGES_MASK _CATMASK(6)
#define LC_ALL_MASK \
(LC_COLLATE_MASK | LC_CTYPE_MASK | LC_MESSAGES_MASK | LC_MONETARY_MASK | LC_NUMERIC_MASK | LC_TIME_MASK)

_LIBCPP_BEGIN_NAMESPACE_STD
namespace __locale {

using __lconv_t = std::lconv;

class __lconv_storage {
public:
__lconv_storage(const lconv* __lc_input) {
__lconv_storage(const __lconv_t* __lc_input) {
__lc_ = *__lc_input;

__decimal_point_ = __lc_input->decimal_point;
Expand All @@ -67,10 +59,10 @@ class __lconv_storage {
__lc_.negative_sign = const_cast<char*>(__negative_sign_.c_str());
}

std::lconv* __get() { return &__lc_; }
__lconv_t* __get() { return &__lc_; }

private:
std::lconv __lc_;
__lconv_t __lc_;
std::string __decimal_point_;
std::string __thousands_sep_;
std::string __grouping_;
Expand All @@ -86,6 +78,18 @@ class __lconv_storage {
//
// Locale management
//
#define _CATMASK(n) ((1 << (n)) >> 1)
#define _LIBCPP_COLLATE_MASK _CATMASK(LC_COLLATE)
#define _LIBCPP_CTYPE_MASK _CATMASK(LC_CTYPE)
#define _LIBCPP_MONETARY_MASK _CATMASK(LC_MONETARY)
#define _LIBCPP_NUMERIC_MASK _CATMASK(LC_NUMERIC)
#define _LIBCPP_TIME_MASK _CATMASK(LC_TIME)
#define _LIBCPP_MESSAGES_MASK _CATMASK(6)
#define _LIBCPP_ALL_MASK \
(_LIBCPP_COLLATE_MASK | _LIBCPP_CTYPE_MASK | _LIBCPP_MESSAGES_MASK | _LIBCPP_MONETARY_MASK | _LIBCPP_NUMERIC_MASK | \
_LIBCPP_TIME_MASK)
#define _LIBCPP_LC_ALL LC_ALL

class __locale_t {
public:
__locale_t() : __locale_(nullptr), __locale_str_(nullptr), __lc_(nullptr) {}
Expand Down Expand Up @@ -137,7 +141,7 @@ class __locale_t {

operator ::_locale_t() const { return __locale_; }

std::lconv* __store_lconv(const std::lconv* __input_lc) {
__lconv_t* __store_lconv(const __lconv_t* __input_lc) {
delete __lc_;
__lc_ = new __lconv_storage(__input_lc);
return __lc_->__get();
Expand All @@ -151,7 +155,13 @@ class __locale_t {

_LIBCPP_EXPORTED_FROM_ABI __locale_t __newlocale(int __mask, const char* __locale, __locale_t __base);
inline _LIBCPP_HIDE_FROM_ABI void __freelocale(__locale_t __loc) { ::_free_locale(__loc); }
_LIBCPP_EXPORTED_FROM_ABI lconv* __localeconv(__locale_t& __loc);
inline _LIBCPP_HIDE_FROM_ABI char* __setlocale(int __category, const char* __locale) {
char* __new_locale = ::setlocale(__category, __locale);
if (__new_locale == nullptr)
std::__throw_bad_alloc();
return __new_locale;
}
_LIBCPP_EXPORTED_FROM_ABI __lconv_t* __localeconv(__locale_t& __loc);

//
// Strtonum functions
Expand Down Expand Up @@ -292,7 +302,7 @@ struct __locale_guard {
// Setting the locale can be expensive even when the locale given is
// already the current locale, so do an explicit check to see if the
// current locale is already the one we want.
const char* __lc = __setlocale(nullptr);
const char* __lc = __locale::__setlocale(LC_ALL, nullptr);
// If every category is the same, the locale string will simply be the
// locale name, otherwise it will be a semicolon-separated string listing
// each category. In the second case, we know at least one category won't
Expand All @@ -301,7 +311,7 @@ struct __locale_guard {
__locale_all = _strdup(__lc);
if (__locale_all == nullptr)
__throw_bad_alloc();
__setlocale(__l.__get_locale());
__locale::__setlocale(LC_ALL, __l.__get_locale());
}
}
_LIBCPP_HIDE_FROM_ABI ~__locale_guard() {
Expand All @@ -310,17 +320,11 @@ struct __locale_guard {
// for the different categories in the same format as returned by
// setlocale(LC_ALL, nullptr).
if (__locale_all != nullptr) {
__setlocale(__locale_all);
__locale::__setlocale(LC_ALL, __locale_all);
free(__locale_all);
}
_configthreadlocale(__status);
}
_LIBCPP_HIDE_FROM_ABI static const char* __setlocale(const char* __locale) {
const char* __new_locale = setlocale(LC_ALL, __locale);
if (__new_locale == nullptr)
__throw_bad_alloc();
return __new_locale;
}
int __status;
char* __locale_all = nullptr;
};
Expand Down
2 changes: 1 addition & 1 deletion libcxx/src/iostream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ alignas(wostream) _LIBCPP_EXPORTED_FROM_ABI char wclog[sizeof(wostream)]
static void force_locale_initialization() {
#if defined(_LIBCPP_MSVCRT_LIKE)
static bool once = []() {
auto loc = __locale::__newlocale(LC_ALL_MASK, "C", 0);
auto loc = __locale::__newlocale(_LIBCPP_ALL_MASK, "C", 0);
{
__locale::__locale_guard g(loc); // forces initialization of locale TLS
((void)g);
Expand Down
Loading
Loading