[glibmm] Glib::init(): Set the global locale
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glibmm] Glib::init(): Set the global locale
- Date: Wed, 14 Dec 2016 08:53:53 +0000 (UTC)
commit d27f6f0c715b226e6a9dc67cd05b4dc860d2271b
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date: Wed Dec 14 09:49:55 2016 +0100
Glib::init(): Set the global locale
* glib/glibmm/init.[cc|h]: Add set/get_init_to_users_preferred_locale().
Let Glib::init() set the C andC++ global locale to the user's preferred locale,
or (if Glib::set_init_to_users_preferred_locale(false) has been called) set
the C++ locale to be equal to the C locale.
* glib/glibmm/ustring.h: Add to the documentation that Glib::init() sets the
global locale. Bug 661588
glib/glibmm/init.cc | 56 +++++++++++++++++++++++++++++++++++++++++++++++-
glib/glibmm/init.h | 47 +++++++++++++++++++++++++++++++++++-----
glib/glibmm/ustring.h | 4 ++-
3 files changed, 98 insertions(+), 9 deletions(-)
---
diff --git a/glib/glibmm/init.cc b/glib/glibmm/init.cc
index cc3b84c..f42cdf5 100644
--- a/glib/glibmm/init.cc
+++ b/glib/glibmm/init.cc
@@ -17,15 +17,67 @@
#include <glibmm/init.h>
#include <glibmm/error.h>
+#include <locale>
+#include <clocale>
+#include <stdexcept>
+
+namespace
+{
+ bool init_to_users_preferred_locale = true;
+
+} // anonymous namespace
namespace Glib
{
+void set_init_to_users_preferred_locale(bool state)
+{
+ init_to_users_preferred_locale = state;
+}
+
+bool get_init_to_users_preferred_locale()
+{
+ return init_to_users_preferred_locale;
+}
-void
-init()
+void init()
{
+ static bool is_initialized = false;
+
+ if (is_initialized)
+ return;
+
+ if (init_to_users_preferred_locale)
+ {
+ try
+ {
+ // Set the global locale for C++ functions and the locale for C functions
+ // to the user-preferred locale.
+ std::locale::global(std::locale(""));
+ }
+ catch (const std::runtime_error& ex)
+ {
+ g_warning("Can't set the global locale to the user's preferred locale.\n"
+ " %s\n The environment variable LANG may be wrong.\n", ex.what());
+ }
+ }
+ else
+ {
+ try
+ {
+ // Make the C++ locale equal to the C locale.
+ std::locale::global(std::locale(std::setlocale(LC_ALL, nullptr)));
+ }
+ catch (const std::runtime_error& ex)
+ {
+ g_warning("Can't make the global C++ locale equal to the C locale.\n"
+ " %s\n C locale = %s\n", ex.what(), std::setlocale(LC_ALL, nullptr));
+ }
+ }
+
// Also calls Glib::wrap_register_init() and Glib::wrap_init().
Glib::Error::register_init();
+
+ is_initialized = true;
}
} // namespace Glib
diff --git a/glib/glibmm/init.h b/glib/glibmm/init.h
index 844945a..a736093 100644
--- a/glib/glibmm/init.h
+++ b/glib/glibmm/init.h
@@ -1,9 +1,6 @@
-// -*- c++ -*-
#ifndef _GLIBMM_INIT_H
#define _GLIBMM_INIT_H
-/* $Id$ */
-
/* Copyright (C) 2002 The gtkmm Development Team
*
* This library is free software; you can redistribute it and/or
@@ -25,12 +22,50 @@ namespace Glib
{
/** Initialize glibmm.
- * You may call this more than once.
- * You do not need to call this if you are using Glib::MainLoop or Gtk::Main,
- * because they call it for you.
+ *
+ * You may call this more than once. Calls after the first one have no effect.
+ * Sets the global locale as specified by set_init_to_users_preferred_locale().
+ * You do not need to call %Glib::init() if you are using Gtk::Application,
+ * because it calls %Glib::init() for you.
+ *
+ * @see set_init_to_users_preferred_locale()
*/
void init();
+/** Instruct Glib::init() which global locale to set.
+ *
+ * To have the intended effect, this function must be called before init() is called.
+ * Not calling it has the same effect as calling it with @a state = <tt>true</tt>.
+ *
+ * Note the confusing difference between C locale and "C" locale.
+ * The C locale is the locale used by C code, set by std::setlocale(LC_ALL, locale_name).
+ * The "C" locale is the classic locale, set by std::setlocale(LC_ALL, "C")
+ * or std::locale::global(std::locale::classic()). It's the default global locale
+ * in a C or C++ program.
+ *
+ * In a mixed C and C++ program, like a program using glibmm, having the C global
+ * locale differ from std::locale::global() is error prone. Glib::init() tries
+ * to avoid that.
+ *
+ * @param state If <tt>true</tt>, init() will set the C and C++ global locale
+ * to the user's preferred locale (std::locale::global(std::locale(""))).
+ * The user's preferred locale is set in the program's environment,
+ * usually with the LANG environment variable.<br>
+ * If <tt>false</tt>, init() will set the C++ global locale to the C global locale
+ * (std::locale::global(std::locale(std::setlocale(LC_ALL, nullptr)))).
+ *
+ * @newin{2,52}
+ */
+void set_init_to_users_preferred_locale(bool state = true);
+
+/** Get the state, set with set_init_to_users_preferred_locale().
+ * @returns The state, set with set_init_to_users_preferred_locale(); <tt>true</tt>
+ * if set_init_to_users_preferred_locale() has not been called.
+ *
+ * @newin{2,52}
+ */
+bool get_init_to_users_preferred_locale();
+
} // namespace Glib
#endif /* _GLIBMM_INIT_H */
diff --git a/glib/glibmm/ustring.h b/glib/glibmm/ustring.h
index fe45c1a..ba6289d 100644
--- a/glib/glibmm/ustring.h
+++ b/glib/glibmm/ustring.h
@@ -184,7 +184,9 @@ gunichar get_unichar_from_std_iterator(std::string::const_iterator pos) G_GNUC_P
* If you're using std::ostringstream to build strings for display in the
* user interface, you must convert the result back to UTF-8 as shown below:
* @code
- * std::locale::global(std::locale("")); // set the global locale to the user's preferred locale
+ * std::locale::global(std::locale("")); // Set the global locale to the user's preferred locale.
+ * // Usually unnecessary here, because Glib::init()
+ * // does it for you.
* std::ostringstream output;
* output << percentage << " % done";
* label->set_text(Glib::locale_to_utf8(output.str()));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]