tracker-0.16.2/src/libtracker-common/tracker-locale.c

No issues found

  1 /*
  2  * Copyright (C) 2010 Nokia <ivan.frade@nokia.com>
  3  *
  4  * This library is free software; you can redistribute it and/or
  5  * modify it under the terms of the GNU Lesser General Public
  6  * License as published by the Free Software Foundation; either
  7  * version 2.1 of the License, or (at your option) any later version.
  8  *
  9  * This library is distributed in the hope that it will be useful,
 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 12  * Lesser General Public License for more details.
 13  *
 14  * You should have received a copy of the GNU Lesser General Public
 15  * License along with this library; if not, write to the
 16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 17  * Boston, MA  02110-1301, USA.
 18  */
 19 
 20 #include "config.h"
 21 
 22 #include <locale.h>
 23 #include <string.h>
 24 
 25 #include <glib.h>
 26 
 27 #include "tracker-locale.h"
 28 
 29 #ifdef HAVE_MEEGOTOUCH
 30 #include "tracker-locale-gconfdbus.h"
 31 #endif /* HAVE_MEEGOTOUCH */
 32 
 33 /* Current locales in use. They will be stored in heap and available throughout
 34  * the whole program execution, so will be reported as still reachable by Valgrind.
 35  */
 36 static gchar *current_locales[TRACKER_LOCALE_LAST];
 37 
 38 static const gchar *locale_names[TRACKER_LOCALE_LAST] = {
 39 	"TRACKER_LOCALE_LANGUAGE",
 40 	"TRACKER_LOCALE_TIME",
 41 	"TRACKER_LOCALE_COLLATE",
 42 	"TRACKER_LOCALE_NUMERIC",
 43 	"TRACKER_LOCALE_MONETARY"
 44 };
 45 
 46 /* Already initialized? */
 47 static gboolean initialized;
 48 
 49 #if GLIB_CHECK_VERSION (2,31,0)
 50 static GRecMutex locales_mutex;
 51 #else
 52 static GStaticRecMutex locales_mutex = G_STATIC_REC_MUTEX_INIT;
 53 #endif
 54 
 55 const gchar*
 56 tracker_locale_get_name (guint i)
 57 {
 58 	g_return_val_if_fail (i < TRACKER_LOCALE_LAST, NULL);
 59 	return locale_names[i];
 60 }
 61 
 62 void
 63 tracker_locale_set (TrackerLocaleID  id,
 64                     const gchar     *value)
 65 {
 66 #if GLIB_CHECK_VERSION (2,31,0)
 67 	g_rec_mutex_lock (&locales_mutex);
 68 #else
 69 	g_static_rec_mutex_lock (&locales_mutex);
 70 #endif
 71 
 72 	if (current_locales[id]) {
 73 		g_debug ("Locale '%s' was changed from '%s' to '%s'",
 74 		         locale_names[id],
 75 		         current_locales[id],
 76 		         value);
 77 		g_free (current_locales[id]);
 78 	} else {
 79 		g_debug ("Locale '%s' was set to '%s'",
 80 		         locale_names[id],
 81 		         value);
 82 	}
 83 
 84 	/* Store the new one */
 85 	current_locales[id] = g_strdup (value);
 86 
 87 	/* And also set the new one in the corresponding envvar */
 88 	switch (id) {
 89 	case TRACKER_LOCALE_LANGUAGE:
 90 		g_setenv ("LANG", value, TRUE);
 91 		break;
 92 	case TRACKER_LOCALE_TIME:
 93 		setlocale (LC_TIME, value);
 94 		break;
 95 	case TRACKER_LOCALE_COLLATE:
 96 		setlocale (LC_COLLATE, value);
 97 		break;
 98 	case TRACKER_LOCALE_NUMERIC:
 99 		setlocale (LC_NUMERIC, value);
100 		break;
101 	case TRACKER_LOCALE_MONETARY:
102 		setlocale (LC_MONETARY, value);
103 		break;
104 	case TRACKER_LOCALE_LAST:
105 		/* Make compiler happy */
106 		g_warn_if_reached ();
107 		break;
108 	}
109 
110 #if GLIB_CHECK_VERSION (2,31,0)
111 	g_rec_mutex_unlock (&locales_mutex);
112 #else
113 	g_static_rec_mutex_unlock (&locales_mutex);
114 #endif
115 }
116 
117 void
118 tracker_locale_shutdown (void)
119 {
120 #ifdef HAVE_MEEGOTOUCH
121 	tracker_locale_gconfdbus_shutdown ();
122 #endif /* HAVE_MEEGOTOUCH */
123 }
124 
125 void
126 tracker_locale_init (void)
127 {
128 	guint i;
129 
130 #ifdef HAVE_MEEGOTOUCH
131 	tracker_locale_gconfdbus_init ();
132 #endif /* HAVE_MEEGOTOUCH */
133 
134 	/* Initialize those not retrieved from gconf, or if not in meegotouch */
135 	for (i = 0; i < TRACKER_LOCALE_LAST; i++) {
136 		if (!current_locales[i]) {
137 			const gchar *env_locale = NULL;
138 
139 			switch (i) {
140 			case TRACKER_LOCALE_LANGUAGE:
141 				env_locale = g_getenv ("LANG");
142 				break;
143 			case TRACKER_LOCALE_TIME:
144 				env_locale = setlocale (LC_TIME, NULL);
145 				break;
146 			case TRACKER_LOCALE_COLLATE:
147 				env_locale = setlocale (LC_COLLATE, NULL);
148 				break;
149 			case TRACKER_LOCALE_NUMERIC:
150 				env_locale = setlocale (LC_NUMERIC, NULL);
151 				break;
152 			case TRACKER_LOCALE_MONETARY:
153 				env_locale = setlocale (LC_MONETARY, NULL);
154 				break;
155 			case TRACKER_LOCALE_LAST:
156 				/* Make compiler happy. The for loop avoids
157 				 * this from happening. */
158 				break;
159 			}
160 
161 			if (!env_locale) {
162 				g_warning ("Locale '%d' is not set, defaulting to C locale", i);
163 				tracker_locale_set (i, "C");
164 			} else {
165 				tracker_locale_set (i, env_locale);
166 			}
167 		}
168 	}
169 
170 	/* So we're initialized */
171 	initialized = TRUE;
172 }
173 
174 gchar *
175 tracker_locale_get (TrackerLocaleID id)
176 {
177 	gchar *locale;
178 
179 	g_return_val_if_fail (initialized, NULL);
180 
181 #if GLIB_CHECK_VERSION (2,31,0)
182 	g_rec_mutex_lock (&locales_mutex);
183 #else
184 	g_static_rec_mutex_lock (&locales_mutex);
185 #endif
186 
187 	/* Always return a duplicated string, as the locale may change at any
188 	 * moment */
189 	locale = g_strdup (current_locales[id]);
190 
191 #if GLIB_CHECK_VERSION (2,31,0)
192 	g_rec_mutex_unlock (&locales_mutex);
193 #else
194 	g_static_rec_mutex_unlock (&locales_mutex);
195 #endif
196 
197 	return locale;
198 }
199 
200 gpointer
201 tracker_locale_notify_add (TrackerLocaleID         id,
202                            TrackerLocaleNotifyFunc func,
203                            gpointer                user_data,
204                            GFreeFunc               destroy_notify)
205 {
206 #ifdef HAVE_MEEGOTOUCH
207 	return tracker_locale_gconfdbus_notify_add (id, func, user_data, destroy_notify);
208 #else
209 	/* If not using gconf locales, this is a no-op... */
210 	return NULL;
211 #endif /* HAVE_MEEGOTOUCH */
212 }
213 
214 void
215 tracker_locale_notify_remove (gpointer notification_id)
216 {
217 #ifdef HAVE_MEEGOTOUCH
218 	return tracker_locale_gconfdbus_notify_remove (notification_id);
219 #else
220 	/* If not using gconf locales, this is a no-op... */
221 #endif /* HAVE_MEEGOTOUCH */
222 }