[libgda] Fix for bug #637010 - bug on changing locale



commit 067c96d860bdc88cf4ba9735861e932dabfc96f8
Author: Vivien Malerba <malerba gnome-db org>
Date:   Sun Dec 12 16:09:21 2010 +0100

    Fix for bug #637010 - bug on changing locale

 doc/C/libgda-sections.txt                   |    1 +
 doc/C/tmpl/libgda.sgml                      |    8 +++
 libgda/gda-init.c                           |   66 +++++++++++++++++++++------
 libgda/libgda.symbols                       |    1 +
 providers/mysql/gda-mysql-recordset.c       |    6 +-
 providers/postgres/gda-postgres-recordset.c |   13 +++---
 6 files changed, 71 insertions(+), 24 deletions(-)
---
diff --git a/doc/C/libgda-sections.txt b/doc/C/libgda-sections.txt
index 13af538..421c79f 100644
--- a/doc/C/libgda-sections.txt
+++ b/doc/C/libgda-sections.txt
@@ -393,6 +393,7 @@ gda_data_model_iter_get_type
 <FILE>libgda</FILE>
 <TITLE>Libgda Initialization</TITLE>
 gda_init
+gda_locale_changed
 gda_get_application_exec_path
 <SUBSECTION Standard>
 </SECTION>
diff --git a/doc/C/tmpl/libgda.sgml b/doc/C/tmpl/libgda.sgml
index 6ebc03e..ad24a9f 100644
--- a/doc/C/tmpl/libgda.sgml
+++ b/doc/C/tmpl/libgda.sgml
@@ -28,6 +28,14 @@ Library initialization
 @void: 
 
 
+<!-- ##### FUNCTION gda_locale_changed ##### -->
+<para>
+
+</para>
+
+ void: 
+
+
 <!-- ##### FUNCTION gda_get_application_exec_path ##### -->
 <para>
 
diff --git a/libgda/gda-init.c b/libgda/gda-init.c
index 7c0516e..ef89a35 100644
--- a/libgda/gda-init.c
+++ b/libgda/gda-init.c
@@ -48,15 +48,66 @@ xmlDtdPtr       gda_array_dtd = NULL;
 xmlDtdPtr       gda_paramlist_dtd = NULL;
 xmlDtdPtr       gda_server_op_dtd = NULL;
 
+static gboolean numeric_locale_dyn = FALSE;
 gchar          *gda_numeric_locale = "";
+static gboolean lang_locale_dyn = FALSE;
 gchar          *gda_lang_locale = "";
 
 /**
+ * gda_locale_changed
+ *
+ * Call this function whenever the setlocale() function has been called
+ * to change the current locale; this function is first called by gda_init() so you
+ * don't need to call it if you have set the locale before calling gda_init().
+ *
+ * Failing to call this function after having changed the current locale may result
+ * in Libgda reverting to the previous set locale.
+ *
+ * Since: 4.2.3
+ */
+void
+gda_locale_changed (void)
+{
+	/* free previous setting */
+	if (numeric_locale_dyn)
+		g_free (gda_numeric_locale);
+	if (lang_locale_dyn)
+		g_free (gda_lang_locale);
+
+	/* net new settings */
+	gda_numeric_locale = setlocale (LC_NUMERIC, NULL);
+	if (gda_numeric_locale) {
+		numeric_locale_dyn = TRUE;
+		gda_numeric_locale = g_strdup (gda_numeric_locale);
+	}
+	else {
+		numeric_locale_dyn = FALSE;
+		gda_numeric_locale = "";
+	}
+#ifdef HAVE_LC_MESSAGES
+        gda_lang_locale = setlocale (LC_MESSAGES, NULL);
+#else
+        gda_lang_locale = setlocale (LC_CTYPE, NULL);
+#endif
+	if (gda_lang_locale) {
+		lang_locale_dyn = TRUE;
+		gda_lang_locale = g_strdup (gda_lang_locale);
+	}
+	else {
+		lang_locale_dyn = FALSE;
+		gda_lang_locale = "";
+	}
+}
+
+/**
  * gda_init
  * 
  * Initializes the GDA library, must be called prior to any Libgda usage. Note that unless the
  * LIBGDA_NO_THREADS environment variable is set (to any value), the GLib thread system will
  * be initialized as well if not yet initialized.
+ *
+ * Please note that if you call setlocale() to modify the current locale, you should also
+ * call gda_locale_changed() before using Libgda again.
  */
 void
 gda_init (void)
@@ -121,20 +172,7 @@ gda_init (void)
 	g_assert (type);
 
 	/* acquire locale */
-	gda_numeric_locale = setlocale (LC_NUMERIC, NULL);
-	if (gda_numeric_locale)
-		gda_numeric_locale = g_strdup (gda_numeric_locale);
-	else
-		gda_numeric_locale = g_strdup ("");
-#ifdef HAVE_LC_MESSAGES
-        gda_lang_locale = setlocale (LC_MESSAGES, NULL);
-#else
-        gda_lang_locale = setlocale (LC_CTYPE, NULL);
-#endif
-	if (gda_lang_locale)
-		gda_lang_locale = g_strdup (gda_lang_locale);
-	else
-		gda_lang_locale = g_strdup ("");
+	gda_locale_changed ();
 
 	/* binreloc */
 	gda_gbr_init ();
diff --git a/libgda/libgda.symbols b/libgda/libgda.symbols
index aaf67b8..35ca289 100644
--- a/libgda/libgda.symbols
+++ b/libgda/libgda.symbols
@@ -402,6 +402,7 @@
 	gda_insert_row_into_table
 	gda_insert_row_into_table_v
 	gda_lang_locale
+	gda_locale_changed
 	gda_lockable_get_type
 	gda_lockable_lock
 	gda_lockable_trylock
diff --git a/providers/mysql/gda-mysql-recordset.c b/providers/mysql/gda-mysql-recordset.c
index ad88014..d03a77c 100644
--- a/providers/mysql/gda-mysql-recordset.c
+++ b/providers/mysql/gda-mysql-recordset.c
@@ -35,6 +35,7 @@
 #ifdef HAVE_LOCALE_H
 #include <locale.h>
 #endif
+extern gchar *gda_numeric_locale;
 
 #define _GDA_PSTMT(x) ((GdaPStmt*)(x))
 
@@ -931,10 +932,9 @@ new_row_from_mysql_stmt (GdaMysqlRecordset *imodel, gint rownum, GError **error)
 			}
 			else if (type == G_TYPE_DOUBLE) {
 				if (length > 0) {
-					char *current_locale;
-					current_locale = setlocale (LC_NUMERIC, "C");
+					setlocale (LC_NUMERIC, "C");
 					g_value_set_double (value, atof (strvalue));
-					setlocale (LC_NUMERIC, current_locale);
+					setlocale (LC_NUMERIC, gda_numeric_locale);
 				}
 				else {
 					/* error: wrong column type */
diff --git a/providers/postgres/gda-postgres-recordset.c b/providers/postgres/gda-postgres-recordset.c
index 17560be..840968e 100644
--- a/providers/postgres/gda-postgres-recordset.c
+++ b/providers/postgres/gda-postgres-recordset.c
@@ -1,5 +1,5 @@
 /* GDA Postgres provider
- * Copyright (C) 2008 The GNOME Foundation.
+ * Copyright (C) 2008  2010 The GNOME Foundation.
  *
  * AUTHORS:
  *      Vivien Malerba <malerba gnome-db org>
@@ -33,6 +33,7 @@
 #ifdef HAVE_LOCALE_H
 #include <locale.h>
 #endif
+extern gchar *gda_numeric_locale;
 
 #define _GDA_PSTMT(x) ((GdaPStmt*)(x))
 
@@ -646,16 +647,14 @@ set_value (GdaConnection *cnc, GdaRow *row, GValue *value, GType type, const gch
 	else if (type == GDA_TYPE_SHORT)
 		gda_value_set_short (value, atoi (thevalue));
 	else if (type == G_TYPE_FLOAT) {
-		char *current_locale;
-		current_locale = setlocale (LC_NUMERIC, "C");
+		setlocale (LC_NUMERIC, "C");
 		g_value_set_float (value, atof (thevalue));
-		setlocale (LC_NUMERIC, current_locale);
+		setlocale (LC_NUMERIC, gda_numeric_locale);
 	}
 	else if (type == G_TYPE_DOUBLE) {
-		char *current_locale;
-		current_locale = setlocale (LC_NUMERIC, "C");
+		setlocale (LC_NUMERIC, "C");
 		g_value_set_double (value, atof (thevalue));
-		setlocale (LC_NUMERIC, current_locale);
+		setlocale (LC_NUMERIC, gda_numeric_locale);
 	}
 	else if (type == GDA_TYPE_NUMERIC) {
 		GdaNumeric numeric;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]