module_locale.c
1 #include <limits.h>
2 #include <locale.h>
3 
4 #include <kuroko/vm.h>
5 #include <kuroko/util.h>
6 
7 KRK_Function(setlocale) {
8  int category;
9  const char * locale = NULL;
10  if (!krk_parseArgs("i|z",(const char*[]){"category","locale"}, &category, &locale)) return NONE_VAL();
11  char * result = setlocale(category, locale);
12  if (!result) {
13  return krk_runtimeError(vm.exceptions->valueError, "unsupported locale setting or query failed");
14  }
15  return OBJECT_VAL(krk_copyString(result,strlen(result)));
16 }
17 
18 static void do_grouping(KrkValue result, const char * keyname, const char * grouping) {
19  KrkValue out = krk_list_of(0,NULL,0);
20  krk_push(out);
21 
22  const char * c = grouping;
23 
24  /* If there is nothing here, return an empty list, otherwise return all
25  * entries including either a terminating NUL or a terminating CHAR_MAX */
26  if (*c) {
27  do {
28  krk_writeValueArray(AS_LIST(out), INTEGER_VAL(*c));
29  if (!*c || *c == CHAR_MAX) break;
30  c++;
31  } while (1);
32  }
33 
34  krk_attachNamedValue(AS_DICT(result), keyname, out);
35  krk_pop();
36 }
37 
38 KRK_Function(localeconv) {
39  FUNCTION_TAKES_NONE();
40 
41  struct lconv * lc = localeconv();
42 
43  /* localeconv is defined to never fail... */
44 
45  KrkValue result = krk_dict_of(0,NULL,0);
46  krk_push(result);
47 
48 #define DO_DICT_STR(key) krk_attachNamedObject(AS_DICT(result), #key, (KrkObj*)krk_copyString(lc-> key, strlen(lc-> key)))
49 #define DO_DICT_INT(key) krk_attachNamedValue(AS_DICT(result), #key, INTEGER_VAL(lc-> key))
50 
51  DO_DICT_STR(decimal_point);
52  DO_DICT_STR(thousands_sep);
53  DO_DICT_STR(int_curr_symbol);
54  DO_DICT_STR(currency_symbol);
55  DO_DICT_STR(mon_decimal_point);
56  DO_DICT_STR(mon_thousands_sep);
57  DO_DICT_STR(positive_sign);
58  DO_DICT_STR(negative_sign);
59 
60  DO_DICT_INT(int_frac_digits);
61  DO_DICT_INT(frac_digits);
62  DO_DICT_INT(p_cs_precedes);
63  DO_DICT_INT(p_sep_by_space);
64  DO_DICT_INT(n_cs_precedes);
65  DO_DICT_INT(n_sep_by_space);
66  DO_DICT_INT(p_sign_posn);
67  DO_DICT_INT(n_sign_posn);
68 
69  /* 'grouping' and 'mon_grouping' aren't real strings */
70  do_grouping(result, "grouping", lc->grouping);
71  do_grouping(result, "mon_grouping", lc->mon_grouping);
72 
73 #undef DO_DICT_STR
74 #undef DO_DICT_INT
75 
76  return krk_pop();
77 }
78 
79 KRK_Module(locale) {
80  KRK_DOC(module, "@brief Bindings for C locale functions");
81 
82  KRK_DOC(BIND_FUNC(module,setlocale),
83  "@brief Set or query the C locale\n"
84  "@arguments category,locale=None\n\n"
85  "Set the locale used by various C functions.");
86  BIND_FUNC(module,localeconv);
87 
88 #define DO_INT(name) krk_attachNamedValue(&module->fields, #name, INTEGER_VAL(name))
89  DO_INT(LC_ALL);
90  DO_INT(LC_COLLATE);
91  DO_INT(LC_CTYPE);
92  DO_INT(LC_MONETARY);
93  DO_INT(LC_NUMERIC);
94  DO_INT(LC_TIME);
95  /* LC_MESSAGES ? */
96  DO_INT(CHAR_MAX); /* Needed to understand grouping */
97 #undef DO_INT
98 
99 }
KrkValue krk_runtimeError(KrkClass *type, const char *fmt,...)
Produce and raise an exception with a formatted message.
Definition: exceptions.c:460
KRK_Module(socket)
KrkValue krk_dict_of(int argc, const KrkValue argv[], int hasKw)
Create a dict object.
Definition: obj_dict.c:19
KrkValue krk_list_of(int argc, const KrkValue argv[], int hasKw)
Create a list object.
Definition: obj_list.c:30
KrkString * krk_copyString(const char *chars, size_t length)
Obtain a string object representation of the given C string.
Definition: object.c:224
void krk_attachNamedValue(KrkTable *table, const char name[], KrkValue obj)
Attach a value to an attribute table.
Definition: vm.c:794
void krk_writeValueArray(KrkValueArray *array, KrkValue value)
Add a value to a value array.
Definition: value.c:17
Stack reference or primative value.
Utilities for creating native bindings.
#define krk_parseArgs(f, n,...)
Parse arguments to a function while accepting keyword arguments.
Definition: util.h:360
#define KRK_DOC(thing, text)
Attach documentation to a thing of various types.
Definition: util.h:304
Core API for the bytecode virtual machine.
#define vm
Convenience macro for namespacing.
Definition: vm.h:257
KrkValue krk_pop(void)
Pop the top of the stack.
Definition: vm.c:131
void krk_push(KrkValue value)
Push a stack value.
Definition: vm.c:118