summaryrefslogtreecommitdiffstats
path: root/lib.h
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-03-04 01:10:01 -0800
committerKaz Kylheku <kaz@kylheku.com>2021-03-04 01:10:01 -0800
commitb111bddfcc737b7f4ab854ce823094bcc8a9de48 (patch)
treefd2fe324b8623a0b803736e2fc8dc30e32ba174b /lib.h
parentcf126a147c108497ef8a387dc869a4c24a9622ed (diff)
downloadtxr-b111bddfcc737b7f4ab854ce823094bcc8a9de48.tar.gz
txr-b111bddfcc737b7f4ab854ce823094bcc8a9de48.tar.bz2
txr-b111bddfcc737b7f4ab854ce823094bcc8a9de48.zip
lib: defend against locale-specific wcstod.
The wcstod function has locale-specific behavior. It uses a locale-specific decimal separator character, which may not be the period. Though in TXR we never call setlocale in order to activate localization, it is a good idea to put in code to defend against this. If locale is ever unleashed on the code, it really botches our floating-point handling. However, let's keep that defensive logic disabled for now using the preprocessor. The strategy is to inquire about the locale's decimal character at startup. Then, in the flo_str function, we preprocess the input by converting the decimal period to the locale-specific character before calling wcstod. On the output side, we also deal with it in the format function; we call sprintf, and then convert the locale-specific characer to period. I tested all this by temporarily introducing the setlocale call, and switching to a locale with a comma as the separator, geting make tests to pass, and doing some interactive testing. This is not going to receive coverage in the test suite. * lib.c (dec_point): New global variable. (flo_str): If dec_point isn't '.', we must copy the string into a local buffer, which we get from alloca, and edit any '.' that it contains to dec_point. (locale_init): New function; initializes dec_point. (init): Call locale_init. * lib.h (dec_point): Declared. * stream.c (formatv): Don't look for a '.' in the result of printing a double using %e; look for dec_point. Post-process floating-point sprinf by substituting occurrences of dec_point with the period.
Diffstat (limited to 'lib.h')
-rw-r--r--lib.h2
1 files changed, 2 insertions, 0 deletions
diff --git a/lib.h b/lib.h
index e9c1bd16..3a519905 100644
--- a/lib.h
+++ b/lib.h
@@ -538,6 +538,8 @@ extern val list_f, less_f, greater_f;
extern val prog_string;
+extern char dec_point;
+
#if HAVE_ULONGLONG_T
typedef ulonglong_t alloc_bytes_t;
#define SIZEOF_ALLOC_BYTES_T SIZEOF_LONGLONG_T