1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1998 Peter Mattis, Spencer Kimball and Josh MacDonald
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 of the License, or (at your option) any later version.
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.
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., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GLib Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GLib at ftp://ftp.gtk.org/pub/gtk/.
40 ensure_gettext_initialized (void)
42 static gsize initialised;
44 if (g_once_init_enter (&initialised))
47 gchar *tmp = _glib_get_locale_dir ();
48 bindtextdomain (GETTEXT_PACKAGE, tmp);
51 bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR);
53 # ifdef HAVE_BIND_TEXTDOMAIN_CODESET
54 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
56 g_once_init_leave (&initialised, TRUE);
62 * @str: The string to be translated
64 * Returns the translated string from the glib translations.
65 * This is an internal function and should only be used by
66 * the internals of glib (such as libgio).
68 * Returns: the transation of @str to the current locale
71 glib_gettext (const gchar *str)
73 ensure_gettext_initialized ();
75 return g_dgettext (GETTEXT_PACKAGE, str);
80 * @msgctxtid: a combined message context and message id, separated
82 * @msgidoffset: the offset of the message id in @msgctxid
84 * This function is a variant of glib_gettext() which supports
85 * a disambiguating message context. See g_dpgettext() for full
88 * This is an internal function and should only be used by
89 * the internals of glib (such as libgio).
91 * Returns: the transation of @str to the current locale
94 glib_pgettext (const gchar *msgctxtid,
97 ensure_gettext_initialized ();
99 return g_dpgettext (GETTEXT_PACKAGE, msgctxtid, msgidoffset);
105 * @msgval: another string
107 * An auxiliary function for gettext() support (see Q_()).
109 * Return value: @msgval, unless @msgval is identical to @msgid
110 * and contains a '|' character, in which case a pointer to
111 * the substring of msgid after the first '|' character is returned.
116 g_strip_context (const gchar *msgid,
121 const char *c = strchr (msgid, '|');
131 * @domain: the translation domain to use, or %NULL to use
132 * the domain set with textdomain()
133 * @msgctxtid: a combined message context and message id, separated
134 * by a \004 character
135 * @msgidoffset: the offset of the message id in @msgctxid
137 * This function is a variant of g_dgettext() which supports
138 * a disambiguating message context. GNU gettext uses the
139 * '\004' character to separate the message context and
140 * message id in @msgctxtid.
141 * If 0 is passed as @msgidoffset, this function will fall back to
142 * trying to use the deprecated convention of using "|" as a separation
145 * This uses g_dgettext() internally. See that functions for differences
146 * with dgettext() proper.
148 * Applications should normally not use this function directly,
149 * but use the C_() macro for translations with context.
151 * Returns: The translated string
156 g_dpgettext (const gchar *domain,
157 const gchar *msgctxtid,
160 const gchar *translation;
163 translation = g_dgettext (domain, msgctxtid);
165 if (translation == msgctxtid)
168 return msgctxtid + msgidoffset;
169 sep = strchr (msgctxtid, '|');
173 /* try with '\004' instead of '|', in case
174 * xgettext -kQ_:1g was used
176 gchar *tmp = g_alloca (strlen (msgctxtid) + 1);
177 strcpy (tmp, msgctxtid);
178 tmp[sep - msgctxtid] = '\004';
180 translation = g_dgettext (domain, tmp);
182 if (translation == tmp)
190 /* This function is taken from gettext.h
191 * GNU gettext uses '\004' to separate context and msgid in .mo files.
195 * @domain: the translation domain to use, or %NULL to use
196 * the domain set with textdomain()
197 * @context: the message context
198 * @msgid: the message
200 * This function is a variant of g_dgettext() which supports
201 * a disambiguating message context. GNU gettext uses the
202 * '\004' character to separate the message context and
203 * message id in @msgctxtid.
205 * This uses g_dgettext() internally. See that functions for differences
206 * with dgettext() proper.
208 * This function differs from C_() in that it is not a macro and
209 * thus you may use non-string-literals as context and msgid arguments.
211 * Returns: The translated string
216 g_dpgettext2 (const gchar *domain,
217 const gchar *msgctxt,
220 size_t msgctxt_len = strlen (msgctxt) + 1;
221 size_t msgid_len = strlen (msgid) + 1;
222 const char *translation;
225 msg_ctxt_id = g_alloca (msgctxt_len + msgid_len);
227 memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
228 msg_ctxt_id[msgctxt_len - 1] = '\004';
229 memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
231 translation = g_dgettext (domain, msg_ctxt_id);
233 if (translation == msg_ctxt_id)
235 /* try the old way of doing message contexts, too */
236 msg_ctxt_id[msgctxt_len - 1] = '|';
237 translation = g_dgettext (domain, msg_ctxt_id);
239 if (translation == msg_ctxt_id)
247 _g_dgettext_should_translate (void)
249 static gsize translate = 0;
251 SHOULD_TRANSLATE = 1,
252 SHOULD_NOT_TRANSLATE = 2
255 if (G_UNLIKELY (g_once_init_enter (&translate)))
257 gboolean should_translate = TRUE;
259 const char *default_domain = textdomain (NULL);
260 const char *translator_comment = gettext ("");
262 const char *translate_locale = setlocale (LC_MESSAGES, NULL);
264 const char *translate_locale = g_win32_getlocale ();
266 /* We should NOT translate only if all the following hold:
267 * - user has called textdomain() and set textdomain to non-default
268 * - default domain has no translations
269 * - locale does not start with "en_" and is not "C"
272 * - If text domain is still the default domain, maybe user calls
273 * it later. Continue with old behavior of translating.
274 * - If locale starts with "en_", we can continue using the
275 * translations even if the app doesn't have translations for
276 * this locale. That is, en_UK and en_CA for example.
277 * - If locale is "C", maybe user calls setlocale(LC_ALL,"") later.
278 * Continue with old behavior of translating.
280 if (0 != strcmp (default_domain, "messages") &&
281 '\0' == *translator_comment &&
282 0 != strncmp (translate_locale, "en_", 3) &&
283 0 != strcmp (translate_locale, "C"))
284 should_translate = FALSE;
286 g_once_init_leave (&translate,
289 SHOULD_NOT_TRANSLATE);
292 return translate == SHOULD_TRANSLATE;
297 * @domain: the translation domain to use, or %NULL to use
298 * the domain set with textdomain()
299 * @msgid: message to translate
301 * This function is a wrapper of dgettext() which does not translate
302 * the message if the default domain as set with textdomain() has no
303 * translations for the current locale.
305 * The advantage of using this function over dgettext() proper is that
306 * libraries using this function (like GTK+) will not use translations
307 * if the application using the library does not have translations for
308 * the current locale. This results in a consistent English-only
309 * interface instead of one having partial translations. For this
310 * feature to work, the call to textdomain() and setlocale() should
311 * precede any g_dgettext() invocations. For GTK+, it means calling
312 * textdomain() before gtk_init or its variants.
314 * This function disables translations if and only if upon its first
315 * call all the following conditions hold:
317 * <listitem>@domain is not %NULL</listitem>
318 * <listitem>textdomain() has been called to set a default text domain</listitem>
319 * <listitem>there is no translations available for the default text domain
320 * and the current locale</listitem>
321 * <listitem>current locale is not "C" or any English locales (those
322 * starting with "en_")</listitem>
325 * Note that this behavior may not be desired for example if an application
326 * has its untranslated messages in a language other than English. In those
327 * cases the application should call textdomain() after initializing GTK+.
329 * Applications should normally not use this function directly,
330 * but use the _() macro for translations.
332 * Returns: The translated string
337 g_dgettext (const gchar *domain,
340 if (domain && G_UNLIKELY (!_g_dgettext_should_translate ()))
343 return dgettext (domain, msgid);
348 * @domain: (allow-none): the translation domain to use, or %NULL to use
349 * the domain set with textdomain()
350 * @msgid: message to translate
351 * @category: a locale category
353 * This is a variant of g_dgettext() that allows specifying a locale
354 * category instead of always using %LC_MESSAGES. See g_dgettext() for
355 * more information about how this functions differs from calling
356 * dcgettext() directly.
358 * Returns: the translated string for the given locale category
363 g_dcgettext (const gchar *domain,
367 if (domain && G_UNLIKELY (!_g_dgettext_should_translate ()))
370 return dcgettext (domain, msgid, category);
375 * @domain: the translation domain to use, or %NULL to use
376 * the domain set with textdomain()
377 * @msgid: message to translate
378 * @msgid_plural: plural form of the message
379 * @n: the quantity for which translation is needed
381 * This function is a wrapper of dngettext() which does not translate
382 * the message if the default domain as set with textdomain() has no
383 * translations for the current locale.
385 * See g_dgettext() for details of how this differs from dngettext()
388 * Returns: The translated string
393 g_dngettext (const gchar *domain,
395 const gchar *msgid_plural,
398 if (domain && G_UNLIKELY (!_g_dgettext_should_translate ()))
399 return n == 1 ? msgid : msgid_plural;
401 return dngettext (domain, msgid, msgid_plural, n);