+ /* A LocaleGuard object ensures that the
+ * LC_NUMERIC/std::locale::numeric aspect of the C and C++ locales are
+ * set to "C" during its lifetime, so that printf/iostreams use a
+ * portable format for numeric output (i.e. 1234.5 is always 1234.5 and
+ * not sometimes 1234,5, as it would be in fr or de locales)
+ */
+
+ char const * const current_c_locale = setlocale (LC_NUMERIC, 0);
+
+ if (strcmp ("C", current_c_locale) != 0) {
+
+ old_c_locale = strdup (current_c_locale);
+
+ try {
+ /* set the C++ global/default locale to whatever we are using
+ * now, but with "C" numeric handling.
+ *
+ * this also sets the C locale, so no additional call to setlocale() is required.
+ */
+
+ std::locale::global (std::locale (old_cpp_locale, "C", std::locale::numeric));
+ pre_cpp_locale = std::locale();
+ DEBUG_TRACE (DEBUG::Locale, string_compose ("LG: change C & C++ locale from '%1' => %2\n", old_cpp_locale.name(), pre_cpp_locale.name()));
+
+ } catch (...) {
+ /* Apple in particular have historically done a
+ * terrible job supporting setlocale and even more so
+ * with the C++ API. Using any locale other than "C" or
+ * "POSIX" will fail, and in the case of the C++ API,
+ * will throw an exception. In that case, just try to
+ * use setlocale() to reset *only* the numeric aspect
+ * of the current locale settings back to "C", which is
+ * likely to work everywhere.
+ */
+
+ setlocale (LC_NUMERIC, "C");
+ pre_cpp_locale = std::locale();
+ DEBUG_TRACE (DEBUG::Locale, string_compose ("LG: C++ locale API failed, change just C locale from '%1' => 'C' (C++ locale is %2)\n", old_c_locale, pre_cpp_locale.name()));
+ }
+
+ }