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
|
__BEGIN_DECLS
|
||||||
|
|
||||||
#ifndef __locale_t_defined
|
typedef enum { __ENC_ASCII, __ENC_UTF8 } __encoding_e;
|
||||||
#define __locale_t_defined 1
|
struct __locale_t
|
||||||
typedef enum { LOCALE_INVALID, LOCALE_POSIX, LOCALE_UTF8 } locale_t;
|
{
|
||||||
#endif
|
const char* name;
|
||||||
|
__encoding_e encoding;
|
||||||
|
};
|
||||||
|
typedef struct __locale_t* locale_t;
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
|||||||
@@ -8,11 +8,10 @@ static const char* nl_langinfo_impl(nl_item item)
|
|||||||
// only codeset is affected by current locales
|
// only codeset is affected by current locales
|
||||||
if (item == CODESET)
|
if (item == CODESET)
|
||||||
{
|
{
|
||||||
switch (__getlocale(LC_CTYPE))
|
switch (__getlocale(LC_CTYPE)->encoding)
|
||||||
{
|
{
|
||||||
case LOCALE_INVALID: ASSERT_NOT_REACHED();
|
case __ENC_ASCII: return "ANSI_X3.4-1968";
|
||||||
case LOCALE_UTF8: return "UTF-8";
|
case __ENC_UTF8: return "UTF-8";
|
||||||
case LOCALE_POSIX: return "ANSI_X3.4-1968";
|
|
||||||
}
|
}
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,35 +5,37 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.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] {
|
static locale_t s_current_locales[LC_ALL] {
|
||||||
LOCALE_POSIX,
|
&s_locale_posix,
|
||||||
LOCALE_POSIX,
|
&s_locale_posix,
|
||||||
LOCALE_POSIX,
|
&s_locale_posix,
|
||||||
LOCALE_POSIX,
|
&s_locale_posix,
|
||||||
LOCALE_POSIX,
|
&s_locale_posix,
|
||||||
LOCALE_POSIX,
|
&s_locale_posix,
|
||||||
};
|
};
|
||||||
static_assert(LC_ALL == 6);
|
static_assert(LC_ALL == 6);
|
||||||
|
|
||||||
static locale_t str_to_locale(const char* locale)
|
static locale_t str_to_locale(const char* locale)
|
||||||
{
|
{
|
||||||
if (*locale == '\0')
|
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)
|
if (strcmp(locale, "C.UTF-8") == 0)
|
||||||
return LOCALE_UTF8;
|
return &s_locale_utf8;
|
||||||
return LOCALE_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char* locale_to_str(locale_t locale)
|
return nullptr;
|
||||||
{
|
|
||||||
if (locale == LOCALE_POSIX)
|
|
||||||
return "C";
|
|
||||||
if (locale == LOCALE_UTF8)
|
|
||||||
return "C.UTF-8";
|
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct lconv* localeconv(void)
|
struct lconv* localeconv(void)
|
||||||
@@ -80,17 +82,18 @@ char* setlocale(int category, const char* locale_str)
|
|||||||
case LC_MONETARY:
|
case LC_MONETARY:
|
||||||
case LC_NUMERIC:
|
case LC_NUMERIC:
|
||||||
case LC_TIME:
|
case LC_TIME:
|
||||||
strcpy(s_locale_buffer, locale_to_str(s_current_locales[category]));
|
strcpy(s_locale_buffer, s_current_locales[category]->name);
|
||||||
break;
|
break;
|
||||||
case LC_ALL:
|
case LC_ALL:
|
||||||
sprintf(s_locale_buffer, "%s;%s;%s;%s;%s;%s",
|
sprintf(s_locale_buffer, "%s;%s;%s;%s;%s;%s",
|
||||||
locale_to_str(s_current_locales[0]),
|
s_current_locales[0]->name,
|
||||||
locale_to_str(s_current_locales[1]),
|
s_current_locales[1]->name,
|
||||||
locale_to_str(s_current_locales[2]),
|
s_current_locales[2]->name,
|
||||||
locale_to_str(s_current_locales[3]),
|
s_current_locales[3]->name,
|
||||||
locale_to_str(s_current_locales[4]),
|
s_current_locales[4]->name,
|
||||||
locale_to_str(s_current_locales[5])
|
s_current_locales[5]->name
|
||||||
);
|
);
|
||||||
|
static_assert(LC_ALL == 6);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -100,7 +103,7 @@ char* setlocale(int category, const char* locale_str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
locale_t locale = str_to_locale(locale_str);
|
locale_t locale = str_to_locale(locale_str);
|
||||||
if (locale == LOCALE_INVALID)
|
if (locale == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
switch (category)
|
switch (category)
|
||||||
@@ -121,7 +124,7 @@ char* setlocale(int category, const char* locale_str)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(s_locale_buffer, locale_to_str(locale));
|
strcpy(s_locale_buffer, locale->name);
|
||||||
return s_locale_buffer;
|
return s_locale_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,6 +140,30 @@ locale_t __getlocale(int category)
|
|||||||
case LC_TIME:
|
case LC_TIME:
|
||||||
return s_current_locales[category];
|
return s_current_locales[category];
|
||||||
default:
|
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;
|
return 0;
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
return -1;
|
return -1;
|
||||||
switch (__getlocale(LC_CTYPE))
|
|
||||||
|
switch (__getlocale(LC_CTYPE)->encoding)
|
||||||
{
|
{
|
||||||
case LOCALE_INVALID:
|
case __ENC_ASCII:
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
case LOCALE_POSIX:
|
|
||||||
return 1;
|
return 1;
|
||||||
case LOCALE_UTF8:
|
case __ENC_UTF8:
|
||||||
const auto bytes = BAN::UTF8::byte_length(*s);
|
const auto bytes = BAN::UTF8::byte_length(*s);
|
||||||
if (bytes == BAN::UTF8::invalid)
|
if (bytes == BAN::UTF8::invalid)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -369,6 +368,7 @@ int mblen(const char* s, size_t n)
|
|||||||
return -1;
|
return -1;
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,15 +378,13 @@ int mbtowc(wchar_t* __restrict pwc, const char* __restrict s, size_t n)
|
|||||||
if (s == nullptr)
|
if (s == nullptr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
switch (__getlocale(LC_CTYPE))
|
switch (__getlocale(LC_CTYPE)->encoding)
|
||||||
{
|
{
|
||||||
case LOCALE_INVALID:
|
case __ENC_ASCII:
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
case LOCALE_POSIX:
|
|
||||||
if (pwc != nullptr)
|
if (pwc != nullptr)
|
||||||
*pwc = *s;
|
*pwc = *s;
|
||||||
return *s ? 1 : 0;
|
return *s ? 1 : 0;
|
||||||
case LOCALE_UTF8:
|
case __ENC_UTF8:
|
||||||
const auto* us = reinterpret_cast<const unsigned char*>(s);
|
const auto* us = reinterpret_cast<const unsigned char*>(s);
|
||||||
|
|
||||||
const uint32_t length = BAN::UTF8::byte_length(*us);
|
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;
|
size_t written = 0;
|
||||||
|
|
||||||
switch (__getlocale(LC_CTYPE))
|
switch (__getlocale(LC_CTYPE)->encoding)
|
||||||
{
|
{
|
||||||
case LOCALE_INVALID:
|
case __ENC_ASCII:
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
case LOCALE_POSIX:
|
|
||||||
if (pwcs == nullptr)
|
if (pwcs == nullptr)
|
||||||
written = strlen(s);
|
written = strlen(s);
|
||||||
else for (; s[written] && written < n; written++)
|
else for (; s[written] && written < n; written++)
|
||||||
pwcs[written] = s[written];
|
pwcs[written] = s[written];
|
||||||
break;
|
break;
|
||||||
case LOCALE_UTF8:
|
case __ENC_UTF8:
|
||||||
|
{
|
||||||
const auto* us = reinterpret_cast<const unsigned char*>(s);
|
const auto* us = reinterpret_cast<const unsigned char*>(s);
|
||||||
for (; *us && (pwcs == nullptr || written < n); written++)
|
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);
|
us += BAN::UTF8::byte_length(*us);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pwcs != nullptr && written < n)
|
if (pwcs != nullptr && written < n)
|
||||||
@@ -454,14 +454,12 @@ int wctomb(char* s, wchar_t wchar)
|
|||||||
if (s == nullptr)
|
if (s == nullptr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
switch (__getlocale(LC_CTYPE))
|
switch (__getlocale(LC_CTYPE)->encoding)
|
||||||
{
|
{
|
||||||
case locale_t::LOCALE_INVALID:
|
case __ENC_ASCII:
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
case locale_t::LOCALE_POSIX:
|
|
||||||
*s = wchar;
|
*s = wchar;
|
||||||
return wchar ? 1 : 0;
|
return wchar ? 1 : 0;
|
||||||
case locale_t::LOCALE_UTF8:
|
case __ENC_UTF8:
|
||||||
char buffer[5];
|
char buffer[5];
|
||||||
if (!BAN::UTF8::from_codepoints(&wchar, 1, buffer))
|
if (!BAN::UTF8::from_codepoints(&wchar, 1, buffer))
|
||||||
return -1;
|
return -1;
|
||||||
@@ -477,11 +475,9 @@ size_t wcstombs(char* __restrict s, const wchar_t* __restrict pwcs, size_t n)
|
|||||||
{
|
{
|
||||||
size_t written = 0;
|
size_t written = 0;
|
||||||
|
|
||||||
switch (__getlocale(LC_CTYPE))
|
switch (__getlocale(LC_CTYPE)->encoding)
|
||||||
{
|
{
|
||||||
case locale_t::LOCALE_INVALID:
|
case __ENC_ASCII:
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
case locale_t::LOCALE_POSIX:
|
|
||||||
for (size_t i = 0; pwcs[i] && (s == nullptr || written < n); i++)
|
for (size_t i = 0; pwcs[i] && (s == nullptr || written < n); i++)
|
||||||
{
|
{
|
||||||
if (pwcs[i] > 0xFF)
|
if (pwcs[i] > 0xFF)
|
||||||
@@ -491,7 +487,7 @@ size_t wcstombs(char* __restrict s, const wchar_t* __restrict pwcs, size_t n)
|
|||||||
written++;
|
written++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case locale_t::LOCALE_UTF8:
|
case __ENC_UTF8:
|
||||||
for (size_t i = 0; pwcs[i] && (s == nullptr || written < n); i++)
|
for (size_t i = 0; pwcs[i] && (s == nullptr || written < n); i++)
|
||||||
{
|
{
|
||||||
char buffer[5];
|
char buffer[5];
|
||||||
@@ -507,6 +503,8 @@ size_t wcstombs(char* __restrict s, const wchar_t* __restrict pwcs, size_t n)
|
|||||||
written += len;
|
written += len;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s && written < n)
|
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)
|
int strcoll_l(const char *s1, const char *s2, locale_t locale)
|
||||||
{
|
{
|
||||||
switch (locale)
|
switch (locale->encoding)
|
||||||
{
|
{
|
||||||
case LOCALE_INVALID:
|
case __ENC_ASCII:
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
case LOCALE_POSIX:
|
|
||||||
return strcmp(s1, s2);
|
return strcmp(s1, s2);
|
||||||
case LOCALE_UTF8:
|
case __ENC_UTF8:
|
||||||
{
|
{
|
||||||
const unsigned char* u1 = (unsigned char*)s1;
|
const unsigned char* u1 = (unsigned char*)s1;
|
||||||
const unsigned char* u2 = (unsigned char*)s2;
|
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;
|
return wc1 - wc2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,19 +45,19 @@ size_t wcrtomb(char* __restrict s, wchar_t ws, mbstate_t* __restrict ps)
|
|||||||
if (s == nullptr)
|
if (s == nullptr)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
switch (__getlocale(LC_CTYPE))
|
switch (__getlocale(LC_CTYPE)->encoding)
|
||||||
{
|
{
|
||||||
case locale_t::LOCALE_INVALID:
|
case __ENC_ASCII:
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
case locale_t::LOCALE_POSIX:
|
|
||||||
if (ws > 0x7F)
|
if (ws > 0x7F)
|
||||||
break;
|
break;
|
||||||
*s = ws;
|
*s = ws;
|
||||||
return 1;
|
return 1;
|
||||||
case locale_t::LOCALE_UTF8:
|
case __ENC_UTF8:
|
||||||
if (!BAN::UTF8::from_codepoints(&ws, 1, s))
|
if (!BAN::UTF8::from_codepoints(&ws, 1, s))
|
||||||
break;
|
break;
|
||||||
return BAN::UTF8::byte_length(s[0]);
|
return BAN::UTF8::byte_length(s[0]);
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = EILSEQ;
|
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);
|
const auto locale = __getlocale(LC_CTYPE);
|
||||||
|
|
||||||
size_t bytes = -1;
|
size_t bytes = -1;
|
||||||
switch (locale)
|
switch (locale->encoding)
|
||||||
{
|
{
|
||||||
case locale_t::LOCALE_INVALID:
|
case __ENC_ASCII:
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
case locale_t::LOCALE_POSIX:
|
|
||||||
bytes = 1;
|
bytes = 1;
|
||||||
break;
|
break;
|
||||||
case locale_t::LOCALE_UTF8:
|
case __ENC_UTF8:
|
||||||
if (auto b = BAN::UTF8::byte_length(s[0]); b != BAN::UTF8::invalid)
|
if (auto b = BAN::UTF8::byte_length(s[0]); b != BAN::UTF8::invalid)
|
||||||
bytes = b;
|
bytes = b;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes == static_cast<size_t>(-1))
|
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;
|
return -1;
|
||||||
|
|
||||||
wchar_t codepoint = WEOF;
|
wchar_t codepoint = WEOF;
|
||||||
switch (locale)
|
switch (locale->encoding)
|
||||||
{
|
{
|
||||||
case locale_t::LOCALE_INVALID:
|
case __ENC_ASCII:
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
case locale_t::LOCALE_POSIX:
|
|
||||||
codepoint = s[0];
|
codepoint = s[0];
|
||||||
break;
|
break;
|
||||||
case locale_t::LOCALE_UTF8:
|
case __ENC_UTF8:
|
||||||
if (auto cp = BAN::UTF8::to_codepoint(s); cp != BAN::UTF8::invalid)
|
if (auto cp = BAN::UTF8::to_codepoint(s); cp != BAN::UTF8::invalid)
|
||||||
codepoint = cp;
|
codepoint = cp;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codepoint == WEOF)
|
if (codepoint == WEOF)
|
||||||
|
|||||||
Reference in New Issue
Block a user