From 511ab7e99cd983152b498b88970ae0f281faf175 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Fri, 10 Jul 2026 00:23:56 +0300 Subject: [PATCH] LibC: Define locale_t as an poiter A lot of ports seem to depend on this casting nullptr into locale_t --- .../LibC/include/bits/types/locale_t.h | 11 ++- userspace/libraries/LibC/langinfo.cpp | 7 +- userspace/libraries/LibC/locale.cpp | 85 ++++++++++++------- userspace/libraries/LibC/stdlib.cpp | 48 +++++------ userspace/libraries/LibC/string.cpp | 9 +- userspace/libraries/LibC/wchar.cpp | 30 +++---- 6 files changed, 108 insertions(+), 82 deletions(-) diff --git a/userspace/libraries/LibC/include/bits/types/locale_t.h b/userspace/libraries/LibC/include/bits/types/locale_t.h index 1adfe749..d5d254b5 100644 --- a/userspace/libraries/LibC/include/bits/types/locale_t.h +++ b/userspace/libraries/LibC/include/bits/types/locale_t.h @@ -7,10 +7,13 @@ __BEGIN_DECLS -#ifndef __locale_t_defined - #define __locale_t_defined 1 - typedef enum { LOCALE_INVALID, LOCALE_POSIX, LOCALE_UTF8 } locale_t; -#endif +typedef enum { __ENC_ASCII, __ENC_UTF8 } __encoding_e; +struct __locale_t +{ + const char* name; + __encoding_e encoding; +}; +typedef struct __locale_t* locale_t; __END_DECLS diff --git a/userspace/libraries/LibC/langinfo.cpp b/userspace/libraries/LibC/langinfo.cpp index ce6dbbdd..71757bbc 100644 --- a/userspace/libraries/LibC/langinfo.cpp +++ b/userspace/libraries/LibC/langinfo.cpp @@ -8,11 +8,10 @@ static const char* nl_langinfo_impl(nl_item item) // only codeset is affected by current locales if (item == CODESET) { - switch (__getlocale(LC_CTYPE)) + switch (__getlocale(LC_CTYPE)->encoding) { - case LOCALE_INVALID: ASSERT_NOT_REACHED(); - case LOCALE_UTF8: return "UTF-8"; - case LOCALE_POSIX: return "ANSI_X3.4-1968"; + case __ENC_ASCII: return "ANSI_X3.4-1968"; + case __ENC_UTF8: return "UTF-8"; } ASSERT_NOT_REACHED(); } diff --git a/userspace/libraries/LibC/locale.cpp b/userspace/libraries/LibC/locale.cpp index ab0b4dbe..387f1626 100644 --- a/userspace/libraries/LibC/locale.cpp +++ b/userspace/libraries/LibC/locale.cpp @@ -5,35 +5,37 @@ #include #include +static __locale_t s_locale_posix { + .name = "C", + .encoding = __ENC_ASCII, +}; +static __locale_t s_locale_utf8 { + .name = "C.UTF-8", + .encoding = __ENC_UTF8, +}; + static locale_t s_current_locales[LC_ALL] { - LOCALE_POSIX, - LOCALE_POSIX, - LOCALE_POSIX, - LOCALE_POSIX, - LOCALE_POSIX, - LOCALE_POSIX, + &s_locale_posix, + &s_locale_posix, + &s_locale_posix, + &s_locale_posix, + &s_locale_posix, + &s_locale_posix, }; static_assert(LC_ALL == 6); static locale_t str_to_locale(const char* locale) { if (*locale == '\0') - return LOCALE_UTF8; + return &s_locale_utf8; + + if (strcmp(locale, "C") == 0 || strcmp(locale, "POSIX") == 0) + return &s_locale_posix; - if (strcmp(locale, "C") == 0 || strcmp(locale, "LOCALE_POSIX") == 0) - return LOCALE_POSIX; if (strcmp(locale, "C.UTF-8") == 0) - return LOCALE_UTF8; - return LOCALE_INVALID; -} + return &s_locale_utf8; -static const char* locale_to_str(locale_t locale) -{ - if (locale == LOCALE_POSIX) - return "C"; - if (locale == LOCALE_UTF8) - return "C.UTF-8"; - ASSERT_NOT_REACHED(); + return nullptr; } struct lconv* localeconv(void) @@ -80,17 +82,18 @@ char* setlocale(int category, const char* locale_str) case LC_MONETARY: case LC_NUMERIC: case LC_TIME: - strcpy(s_locale_buffer, locale_to_str(s_current_locales[category])); + strcpy(s_locale_buffer, s_current_locales[category]->name); break; case LC_ALL: sprintf(s_locale_buffer, "%s;%s;%s;%s;%s;%s", - locale_to_str(s_current_locales[0]), - locale_to_str(s_current_locales[1]), - locale_to_str(s_current_locales[2]), - locale_to_str(s_current_locales[3]), - locale_to_str(s_current_locales[4]), - locale_to_str(s_current_locales[5]) + s_current_locales[0]->name, + s_current_locales[1]->name, + s_current_locales[2]->name, + s_current_locales[3]->name, + s_current_locales[4]->name, + s_current_locales[5]->name ); + static_assert(LC_ALL == 6); break; default: return nullptr; @@ -100,7 +103,7 @@ char* setlocale(int category, const char* locale_str) } locale_t locale = str_to_locale(locale_str); - if (locale == LOCALE_INVALID) + if (locale == nullptr) return nullptr; switch (category) @@ -121,7 +124,7 @@ char* setlocale(int category, const char* locale_str) return nullptr; } - strcpy(s_locale_buffer, locale_to_str(locale)); + strcpy(s_locale_buffer, locale->name); return s_locale_buffer; } @@ -137,6 +140,30 @@ locale_t __getlocale(int category) case LC_TIME: return s_current_locales[category]; default: - return LOCALE_INVALID; + return nullptr; } } + +#include + +locale_t newlocale(int category_mask, const char* locale, locale_t base) +{ + (void)category_mask; + (void)locale; + (void)base; + dwarnln("TODO: newlocale"); + return nullptr; +} + +void freelocale(locale_t locobj) +{ + (void)locobj; + dwarnln("TODO: freelocale"); +} + +locale_t uselocale(locale_t newloc) +{ + (void)newloc; + dwarnln("TODO: uselocale"); + return nullptr; +} diff --git a/userspace/libraries/LibC/stdlib.cpp b/userspace/libraries/LibC/stdlib.cpp index aa8658aa..8ecac808 100644 --- a/userspace/libraries/LibC/stdlib.cpp +++ b/userspace/libraries/LibC/stdlib.cpp @@ -355,13 +355,12 @@ int mblen(const char* s, size_t n) return 0; if (n == 0) return -1; - switch (__getlocale(LC_CTYPE)) + + switch (__getlocale(LC_CTYPE)->encoding) { - case LOCALE_INVALID: - ASSERT_NOT_REACHED(); - case LOCALE_POSIX: + case __ENC_ASCII: return 1; - case LOCALE_UTF8: + case __ENC_UTF8: const auto bytes = BAN::UTF8::byte_length(*s); if (bytes == BAN::UTF8::invalid) return -1; @@ -369,6 +368,7 @@ int mblen(const char* s, size_t n) return -1; return bytes; } + ASSERT_NOT_REACHED(); } @@ -378,15 +378,13 @@ int mbtowc(wchar_t* __restrict pwc, const char* __restrict s, size_t n) if (s == nullptr) return 0; - switch (__getlocale(LC_CTYPE)) + switch (__getlocale(LC_CTYPE)->encoding) { - case LOCALE_INVALID: - ASSERT_NOT_REACHED(); - case LOCALE_POSIX: + case __ENC_ASCII: if (pwc != nullptr) *pwc = *s; return *s ? 1 : 0; - case LOCALE_UTF8: + case __ENC_UTF8: const auto* us = reinterpret_cast(s); const uint32_t length = BAN::UTF8::byte_length(*us); @@ -416,17 +414,16 @@ size_t mbstowcs(wchar_t* __restrict pwcs, const char* __restrict s, size_t n) { size_t written = 0; - switch (__getlocale(LC_CTYPE)) + switch (__getlocale(LC_CTYPE)->encoding) { - case LOCALE_INVALID: - ASSERT_NOT_REACHED(); - case LOCALE_POSIX: + case __ENC_ASCII: if (pwcs == nullptr) written = strlen(s); else for (; s[written] && written < n; written++) pwcs[written] = s[written]; break; - case LOCALE_UTF8: + case __ENC_UTF8: + { const auto* us = reinterpret_cast(s); for (; *us && (pwcs == nullptr || written < n); written++) { @@ -441,6 +438,9 @@ size_t mbstowcs(wchar_t* __restrict pwcs, const char* __restrict s, size_t n) us += BAN::UTF8::byte_length(*us); } break; + } + default: + ASSERT_NOT_REACHED(); } if (pwcs != nullptr && written < n) @@ -454,14 +454,12 @@ int wctomb(char* s, wchar_t wchar) if (s == nullptr) return 0; - switch (__getlocale(LC_CTYPE)) + switch (__getlocale(LC_CTYPE)->encoding) { - case locale_t::LOCALE_INVALID: - ASSERT_NOT_REACHED(); - case locale_t::LOCALE_POSIX: + case __ENC_ASCII: *s = wchar; return wchar ? 1 : 0; - case locale_t::LOCALE_UTF8: + case __ENC_UTF8: char buffer[5]; if (!BAN::UTF8::from_codepoints(&wchar, 1, buffer)) return -1; @@ -477,11 +475,9 @@ size_t wcstombs(char* __restrict s, const wchar_t* __restrict pwcs, size_t n) { size_t written = 0; - switch (__getlocale(LC_CTYPE)) + switch (__getlocale(LC_CTYPE)->encoding) { - case locale_t::LOCALE_INVALID: - ASSERT_NOT_REACHED(); - case locale_t::LOCALE_POSIX: + case __ENC_ASCII: for (size_t i = 0; pwcs[i] && (s == nullptr || written < n); i++) { if (pwcs[i] > 0xFF) @@ -491,7 +487,7 @@ size_t wcstombs(char* __restrict s, const wchar_t* __restrict pwcs, size_t n) written++; } break; - case locale_t::LOCALE_UTF8: + case __ENC_UTF8: for (size_t i = 0; pwcs[i] && (s == nullptr || written < n); i++) { char buffer[5]; @@ -507,6 +503,8 @@ size_t wcstombs(char* __restrict s, const wchar_t* __restrict pwcs, size_t n) written += len; } break; + default: + ASSERT_NOT_REACHED(); } if (s && written < n) diff --git a/userspace/libraries/LibC/string.cpp b/userspace/libraries/LibC/string.cpp index 164183cb..0d22fef2 100644 --- a/userspace/libraries/LibC/string.cpp +++ b/userspace/libraries/LibC/string.cpp @@ -162,13 +162,11 @@ int strcoll(const char* s1, const char* s2) int strcoll_l(const char *s1, const char *s2, locale_t locale) { - switch (locale) + switch (locale->encoding) { - case LOCALE_INVALID: - ASSERT_NOT_REACHED(); - case LOCALE_POSIX: + case __ENC_ASCII: return strcmp(s1, s2); - case LOCALE_UTF8: + case __ENC_UTF8: { const unsigned char* u1 = (unsigned char*)s1; const unsigned char* u2 = (unsigned char*)s2; @@ -195,6 +193,7 @@ int strcoll_l(const char *s1, const char *s2, locale_t locale) return wc1 - wc2; } } + ASSERT_NOT_REACHED(); } diff --git a/userspace/libraries/LibC/wchar.cpp b/userspace/libraries/LibC/wchar.cpp index 88722355..534bb581 100644 --- a/userspace/libraries/LibC/wchar.cpp +++ b/userspace/libraries/LibC/wchar.cpp @@ -45,19 +45,19 @@ size_t wcrtomb(char* __restrict s, wchar_t ws, mbstate_t* __restrict ps) if (s == nullptr) return 1; - switch (__getlocale(LC_CTYPE)) + switch (__getlocale(LC_CTYPE)->encoding) { - case locale_t::LOCALE_INVALID: - ASSERT_NOT_REACHED(); - case locale_t::LOCALE_POSIX: + case __ENC_ASCII: if (ws > 0x7F) break; *s = ws; return 1; - case locale_t::LOCALE_UTF8: + case __ENC_UTF8: if (!BAN::UTF8::from_codepoints(&ws, 1, s)) break; return BAN::UTF8::byte_length(s[0]); + default: + ASSERT_NOT_REACHED(); } errno = EILSEQ; @@ -74,17 +74,17 @@ size_t mbrtowc(wchar_t* __restrict pwc, const char* __restrict s, size_t n, mbst const auto locale = __getlocale(LC_CTYPE); size_t bytes = -1; - switch (locale) + switch (locale->encoding) { - case locale_t::LOCALE_INVALID: - ASSERT_NOT_REACHED(); - case locale_t::LOCALE_POSIX: + case __ENC_ASCII: bytes = 1; break; - case locale_t::LOCALE_UTF8: + case __ENC_UTF8: if (auto b = BAN::UTF8::byte_length(s[0]); b != BAN::UTF8::invalid) bytes = b; break; + default: + ASSERT_NOT_REACHED(); } if (bytes == static_cast(-1)) @@ -97,17 +97,17 @@ size_t mbrtowc(wchar_t* __restrict pwc, const char* __restrict s, size_t n, mbst return -1; wchar_t codepoint = WEOF; - switch (locale) + switch (locale->encoding) { - case locale_t::LOCALE_INVALID: - ASSERT_NOT_REACHED(); - case locale_t::LOCALE_POSIX: + case __ENC_ASCII: codepoint = s[0]; break; - case locale_t::LOCALE_UTF8: + case __ENC_UTF8: if (auto cp = BAN::UTF8::to_codepoint(s); cp != BAN::UTF8::invalid) codepoint = cp; break; + default: + ASSERT_NOT_REACHED(); } if (codepoint == WEOF)