From 5d481c259b4f6c3b9ca83f977693ab0146b09b4b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 13 Mar 2011 07:59:16 -0600 Subject: [PATCH] fix inexact number printing when LC_NUMERIC locale is not "C" Relevant to PR 11802 --- src/racket/src/numstr.c | 3 +++ src/racket/src/schpriv.h | 3 +++ src/racket/src/string.c | 20 ++++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/src/racket/src/numstr.c b/src/racket/src/numstr.c index b83136e990..ee4d39b9d9 100644 --- a/src/racket/src/numstr.c +++ b/src/racket/src/numstr.c @@ -1569,7 +1569,9 @@ static char *double_to_string (double d, int alloc, int was_single) /* Initial count for significant digits is 14. That's big enough to get most right, small enough to avoid nonsense digits. But we'll loop in case it's not precise enough to get read-write invariance: */ + GC_CAN_IGNORE char *loc; digits = 14; + loc = scheme_push_c_numeric_locale(); while (digits < 30) { double check; GC_CAN_IGNORE char *ptr; @@ -1583,6 +1585,7 @@ static char *double_to_string (double d, int alloc, int was_single) digits++; } + scheme_pop_c_numeric_locale(loc); l = strlen(buffer); for (i = 0; i < l; i++) { diff --git a/src/racket/src/schpriv.h b/src/racket/src/schpriv.h index c5edabe0de..700786a933 100644 --- a/src/racket/src/schpriv.h +++ b/src/racket/src/schpriv.h @@ -1693,6 +1693,9 @@ void scheme_clear_bignum_cache(void); intptr_t scheme_integer_length(Scheme_Object *n); +char *scheme_push_c_numeric_locale(); +void scheme_pop_c_numeric_locale(char *prev); + /****** Rational numbers *******/ typedef struct { diff --git a/src/racket/src/string.c b/src/racket/src/string.c index 32de924fc5..7020b54e2f 100644 --- a/src/racket/src/string.c +++ b/src/racket/src/string.c @@ -3508,6 +3508,26 @@ static void reset_locale(void) } } +char *scheme_push_c_numeric_locale() +{ +#ifndef DONT_USE_LOCALE + GC_CAN_IGNORE char *prev; + prev = setlocale(LC_NUMERIC, NULL); + if (!strcmp(prev, "C")) + return NULL; + else + return setlocale(LC_NUMERIC, "C"); +#endif +} + +void scheme_pop_c_numeric_locale(char *prev) +{ +#ifndef DONT_USE_LOCALE + if (prev) + setlocale(LC_NUMERIC, prev); +#endif +} + static int find_special_casing(int ch) { /* Binary search */