summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/lib.c b/lib.c
index f6c57552..338ff9fc 100644
--- a/lib.c
+++ b/lib.c
@@ -37,6 +37,7 @@
#include <math.h>
#include <signal.h>
#include <assert.h>
+#include <locale.h>
#include "config.h"
#include "alloca.h"
#if HAVE_GETENVIRONMENTSTRINGS
@@ -130,6 +131,10 @@ val list_f, less_f, greater_f;
val prog_string;
+#if CONFIG_LOCALE_TOLERANCE
+char dec_point = '.';
+#endif
+
static val recycled_conses;
const seq_kind_t seq_kind_tab[MAXTYPE+1] = {
@@ -5402,9 +5407,21 @@ val flo_str(val str)
{
const wchar_t *wcs = c_str(str);
wchar_t *ptr;
+ double value;
+
+#if CONFIG_LOCALE_TOLERANCE
+ if (dec_point != '.') {
+ size_t size = c_unum(length_str(str), lit("flot-str")) + 1;
+ wchar_t *wcopy = alloca(sizeof *wcopy * size), *dot = wcopy;
+ wmemcpy(wcopy, wcs, size);
+ wcs = wcopy;
+ while ((dot = wcschr(dot, '.')) != 0)
+ *dot++ = dec_point;
+ }
+#endif
+
+ value = wcstod(wcs, &ptr);
- /* TODO: detect if we have wcstod */
- double value = wcstod(wcs, &ptr);
if (value == 0 && ptr == wcs)
return nil;
if ((value == HUGE_VAL || value == -HUGE_VAL) && errno == ERANGE)
@@ -11888,6 +11905,16 @@ val in_range_star(val range, val num)
}
}
+#if CONFIG_LOCALE_TOLERANCE
+
+static void locale_init(void)
+{
+ struct lconv *lc = localeconv();
+ dec_point = *lc->decimal_point;
+}
+
+#endif
+
static void obj_init(void)
{
/*
@@ -12970,6 +12997,9 @@ void init(val *stack_bottom)
t = one;
gc_init(stack_bottom);
+#if CONFIG_LOCALE_TOLERANCE
+ locale_init();
+#endif
obj_init();
uw_init();
eval_init();