const char * orig_NUMERIC_locale = NULL;
if (which_mask & INDEX_TO_BIT(LC_NUMERIC_INDEX_)) {
LC_NUMERIC_LOCK(0);
+
+# if defined(WIN32)
+
+ /* There is a bug in Windows in which setting LC_CTYPE after the others
+ * doesn't actually take effect for localeconv(). See the commit
+ * message for this commit for details. Thus we have to make sure that
+ * the locale we want is set after LC_CTYPE. We unconditionally toggle
+ * away from and back to the current locale prior to calling
+ * localeconv().
+ *
+ * This code will have no effect if we already are in C, but khw
+ * hasn't seen any cases where this causes problems when we are in the
+ * C locale. */
+ orig_NUMERIC_locale = toggle_locale_i(LC_NUMERIC_INDEX_, "C");
+ toggle_locale_i(LC_NUMERIC_INDEX_, locale);
+
+# else
+
+ /* No need for the extra toggle when not on Windows */
orig_NUMERIC_locale = toggle_locale_i(LC_NUMERIC_INDEX_, locale);
- }
# endif
+ }
+
+# endif
+# if defined(USE_LOCALE_MONETARY) && defined(WIN32)
+
+ /* Same Windows bug as described just above for NUMERIC. Otherwise, no
+ * need to toggle LC_MONETARY, as it is kept in the underlying locale */
+ const char * orig_MONETARY_locale = NULL;
+ if (which_mask & INDEX_TO_BIT(LC_MONETARY_INDEX_)) {
+ orig_MONETARY_locale = toggle_locale_i(LC_MONETARY_INDEX_, "C");
+ toggle_locale_i(LC_MONETARY_INDEX_, locale);
+ }
+
+# endif
+
/* Finally ready to do the actual localeconv(). Lock to prevent other
* accesses until we have made a copy of its returned static buffer */
gwLOCALE_LOCK;
gwLOCALE_UNLOCK; /* Finished with the critical section of a
globally-accessible buffer */
+# if defined(USE_LOCALE_MONETARY) && defined(WIN32)
+
+ restore_toggled_locale_i(LC_MONETARY_INDEX_, orig_MONETARY_locale);
+
+# endif
# ifdef USE_LOCALE_NUMERIC
restore_toggled_locale_i(LC_NUMERIC_INDEX_, orig_NUMERIC_locale);