Add rudimentary locale module
This commit is contained in:
parent
837e389b4c
commit
47500c833f
99
src/modules/module_locale.c
Normal file
99
src/modules/module_locale.c
Normal file
@ -0,0 +1,99 @@
|
||||
#include <limits.h>
|
||||
#include <locale.h>
|
||||
|
||||
#include <kuroko/vm.h>
|
||||
#include <kuroko/util.h>
|
||||
|
||||
KRK_Function(setlocale) {
|
||||
int category;
|
||||
const char * locale = NULL;
|
||||
if (!krk_parseArgs("i|z",(const char*[]){"category","locale"}, &category, &locale)) return NONE_VAL();
|
||||
char * result = setlocale(category, locale);
|
||||
if (!result) {
|
||||
return krk_runtimeError(vm.exceptions->valueError, "unsupported locale setting or query failed");
|
||||
}
|
||||
return OBJECT_VAL(krk_copyString(result,strlen(result)));
|
||||
}
|
||||
|
||||
static void do_grouping(KrkValue result, const char * keyname, const char * grouping) {
|
||||
KrkValue out = krk_list_of(0,NULL,0);
|
||||
krk_push(out);
|
||||
|
||||
const char * c = grouping;
|
||||
|
||||
/* If there is nothing here, return an empty list, otherwise return all
|
||||
* entries including either a terminating NUL or a terminating CHAR_MAX */
|
||||
if (*c) {
|
||||
do {
|
||||
krk_writeValueArray(AS_LIST(out), INTEGER_VAL(*c));
|
||||
if (!*c || *c == CHAR_MAX) break;
|
||||
c++;
|
||||
} while (1);
|
||||
}
|
||||
|
||||
krk_attachNamedValue(AS_DICT(result), keyname, out);
|
||||
krk_pop();
|
||||
}
|
||||
|
||||
KRK_Function(localeconv) {
|
||||
FUNCTION_TAKES_NONE();
|
||||
|
||||
struct lconv * lc = localeconv();
|
||||
|
||||
/* localeconv is defined to never fail... */
|
||||
|
||||
KrkValue result = krk_dict_of(0,NULL,0);
|
||||
krk_push(result);
|
||||
|
||||
#define DO_DICT_STR(key) krk_attachNamedObject(AS_DICT(result), #key, (KrkObj*)krk_copyString(lc-> key, strlen(lc-> key)))
|
||||
#define DO_DICT_INT(key) krk_attachNamedValue(AS_DICT(result), #key, INTEGER_VAL(lc-> key))
|
||||
|
||||
DO_DICT_STR(decimal_point);
|
||||
DO_DICT_STR(thousands_sep);
|
||||
DO_DICT_STR(int_curr_symbol);
|
||||
DO_DICT_STR(currency_symbol);
|
||||
DO_DICT_STR(mon_decimal_point);
|
||||
DO_DICT_STR(mon_thousands_sep);
|
||||
DO_DICT_STR(positive_sign);
|
||||
DO_DICT_STR(negative_sign);
|
||||
|
||||
DO_DICT_INT(int_frac_digits);
|
||||
DO_DICT_INT(frac_digits);
|
||||
DO_DICT_INT(p_cs_precedes);
|
||||
DO_DICT_INT(p_sep_by_space);
|
||||
DO_DICT_INT(n_cs_precedes);
|
||||
DO_DICT_INT(n_sep_by_space);
|
||||
DO_DICT_INT(p_sign_posn);
|
||||
DO_DICT_INT(n_sign_posn);
|
||||
|
||||
/* 'grouping' and 'mon_grouping' aren't real strings */
|
||||
do_grouping(result, "grouping", lc->grouping);
|
||||
do_grouping(result, "mon_grouping", lc->mon_grouping);
|
||||
|
||||
#undef DO_DICT_STR
|
||||
#undef DO_DICT_INT
|
||||
|
||||
return krk_pop();
|
||||
}
|
||||
|
||||
KRK_Module(locale) {
|
||||
KRK_DOC(module, "@brief Bindings for C locale functions");
|
||||
|
||||
KRK_DOC(BIND_FUNC(module,setlocale),
|
||||
"@brief Set or query the C locale\n"
|
||||
"@arguments category,locale=None\n\n"
|
||||
"Set the locale used by various C functions.");
|
||||
BIND_FUNC(module,localeconv);
|
||||
|
||||
#define DO_INT(name) krk_attachNamedValue(&module->fields, #name, INTEGER_VAL(name))
|
||||
DO_INT(LC_ALL);
|
||||
DO_INT(LC_COLLATE);
|
||||
DO_INT(LC_CTYPE);
|
||||
DO_INT(LC_MONETARY);
|
||||
DO_INT(LC_NUMERIC);
|
||||
DO_INT(LC_TIME);
|
||||
/* LC_MESSAGES ? */
|
||||
DO_INT(CHAR_MAX); /* Needed to understand grouping */
|
||||
#undef DO_INT
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user