LibC: Define locale_t as an poiter
A lot of ports seem to depend on this casting nullptr into locale_t
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -5,35 +5,37 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
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 <BAN/Debug.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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<const unsigned char*>(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<const unsigned char*>(s);
|
||||
for (; *us && (pwcs == nullptr || written < n); written++)
|
||||
{
|
||||
@@ -442,6 +439,9 @@ size_t mbstowcs(wchar_t* __restrict pwcs, const char* __restrict s, size_t n)
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
if (pwcs != nullptr && written < n)
|
||||
pwcs[written] = L'\0';
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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<size_t>(-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)
|
||||
|
||||
Reference in New Issue
Block a user