From fdf32aeb9743b1b405aa1acac2961d9b74a53106 Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Sun, 16 May 2021 18:08:05 +0200 Subject: [PATCH] locale: add a stub that supports only the "C" locale (TEST) This is enough to support the standard and likely the C++ library and external programs to port, but also the most we can do without a proper locale data storage and more target-specific developments that aren't a priority right now. --- CMakeLists.txt | 2 ++ include/locale.h | 43 ++++++++++++++++++++++++++++++++++++ src/libc/locale/localeconv.c | 34 ++++++++++++++++++++++++++++ src/libc/locale/setlocale.c | 18 +++++++++++++++ 4 files changed, 97 insertions(+) create mode 100644 include/locale.h create mode 100644 src/libc/locale/localeconv.c create mode 100644 src/libc/locale/setlocale.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 032f57e..1d1caf8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,6 +59,8 @@ endif() set(SOURCES src/libc/assert/assert.c + src/libc/locale/setlocale.c + src/libc/locale/localeconv.c src/libc/stdio/vsnprintf.c src/libc/stdio/sprintf.c src/libc/stdio/dprintf.c diff --git a/include/locale.h b/include/locale.h new file mode 100644 index 0000000..9b2f760 --- /dev/null +++ b/include/locale.h @@ -0,0 +1,43 @@ +#ifndef __LOCALE_H__ +# define __LOCALE_H__ + +#include + +struct lconv { + char *decimal_point; + char *thousands_sep; + char *grouping; + char *mon_decimal_point; + char *mon_thousands_sep; + char *mon_grouping; + char *positive_sign; + char *negative_sign; + char *currency_symbol; + char frac_digits; + char p_cs_precedes; + char n_cs_precedes; + char p_sep_by_space; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; + char *int_curr_symbol; + char int_frac_digits; + char int_p_cs_precedes; + char int_n_cs_precedes; + char int_p_sep_by_space; + char int_n_sep_by_space; + char int_p_sign_posn; + char int_n_sign_posn; +}; + +#define LC_COLLATE 0 +#define LC_CTYPE 1 +#define LC_MONETARY 2 +#define LC_NUMERIC 3 +#define LC_TIME 4 +#define LC_ALL 5 + +extern char *setlocale(int __category, char const *__locale); +extern struct lconv *localeconv(void); + +#endif /*__LOCALE_H__*/ diff --git a/src/libc/locale/localeconv.c b/src/libc/locale/localeconv.c new file mode 100644 index 0000000..e266e7d --- /dev/null +++ b/src/libc/locale/localeconv.c @@ -0,0 +1,34 @@ +#include +#include + +static struct lconv lconv_c = { + .decimal_point = ".", + .thousands_sep = "", + .grouping = "", + .mon_decimal_point = "", + .mon_thousands_sep = "", + .mon_grouping = "", + .positive_sign = "", + .negative_sign = "", + .currency_symbol = "", + .frac_digits = CHAR_MAX, + .p_cs_precedes = CHAR_MAX, + .n_cs_precedes = CHAR_MAX, + .p_sep_by_space = CHAR_MAX, + .n_sep_by_space = CHAR_MAX, + .p_sign_posn = CHAR_MAX, + .n_sign_posn = CHAR_MAX, + .int_curr_symbol = "", + .int_frac_digits = CHAR_MAX, + .int_p_cs_precedes = CHAR_MAX, + .int_n_cs_precedes = CHAR_MAX, + .int_p_sep_by_space = CHAR_MAX, + .int_n_sep_by_space = CHAR_MAX, + .int_p_sign_posn = CHAR_MAX, + .int_n_sign_posn = CHAR_MAX, +}; + +struct lconv *localeconv(void) +{ + return &lconv_c; +} diff --git a/src/libc/locale/setlocale.c b/src/libc/locale/setlocale.c new file mode 100644 index 0000000..3a91428 --- /dev/null +++ b/src/libc/locale/setlocale.c @@ -0,0 +1,18 @@ +#include + +/* +** This stub locale implementation only supports the "C" locale. For several +** targets there is no filesystem/LOCPATH/database of locale values, so this is +** the only setting that can always be supported. It is also sufficient to +** support when porting Linux programs because Linux does not guarantee that +** other locales will be available. +*/ + +char *setlocale(__attribute__((unused)) int category, char const *locale) +{ + if(locale) { + if(locale[0] == 0) locale = "C"; + if(locale[0] != 'C' || locale[1] != 0) return NULL; + } + return "C"; +}