@@ -2853,30 +2853,33 @@ g_strv_length (gchar **str_array)
28532853 * by a \004 character
28542854 * @msgidoffset: the offset of the message id in @msgctxid
28552855 *
2856- * This function is a variant of dgettext () which supports
2856+ * This function is a variant of g_dgettext () which supports
28572857 * a disambiguating message context. GNU gettext uses the
28582858 * '\004' character to separate the message context and
28592859 * message id in @msgctxtid.
28602860 * If 0 is passed as @msgidoffset, this function will fall back to
28612861 * trying to use the deprecated convention of using "|" as a separation
28622862 * character.
28632863 *
2864+ * This uses g_dgettext() internally. See that functions for differences
2865+ * with dgettext() proper.
2866+ *
28642867 * Applications should normally not use this function directly,
28652868 * but use the C_() macro for translations with context.
28662869 *
28672870 * Returns: The translated string
28682871 *
28692872 * Since: 2.16
28702873 */
2871- const gchar *
2874+ G_CONST_RETURN gchar *
28722875g_dpgettext (const gchar * domain ,
28732876 const gchar * msgctxtid ,
28742877 gsize msgidoffset )
28752878{
28762879 const gchar * translation ;
28772880 gchar * sep ;
28782881
2879- translation = dgettext (domain , msgctxtid );
2882+ translation = g_dgettext (domain , msgctxtid );
28802883
28812884 if (translation == msgctxtid )
28822885 {
@@ -2894,7 +2897,7 @@ g_dpgettext (const gchar *domain,
28942897 strcpy (tmp , msgctxtid );
28952898 tmp [sep - msgctxtid ] = '\004' ;
28962899
2897- translation = dgettext (domain , tmp );
2900+ translation = g_dgettext (domain , tmp );
28982901
28992902 if (translation == tmp )
29002903 return sep + 1 ;
@@ -2904,6 +2907,134 @@ g_dpgettext (const gchar *domain,
29042907 return translation ;
29052908}
29062909
2910+ static gboolean
2911+ _g_dgettext_should_translate (void )
2912+ {
2913+ static gsize translate = 0 ;
2914+ enum {
2915+ SHOULD_TRANSLATE = 1 ,
2916+ SHOULD_NOT_TRANSLATE = 2
2917+ };
2918+
2919+ if (G_UNLIKELY (g_once_init_enter (& translate )))
2920+ {
2921+ gboolean should_translate = TRUE;
2922+
2923+ const char * default_domain = textdomain (NULL );
2924+ const char * translator_comment = gettext ("" );
2925+ const char * translate_locale = setlocale (LC_MESSAGES , NULL );
2926+
2927+ /* We should NOT translate only if all the following hold:
2928+ * - user has called textdomain() and set textdomain to non-default
2929+ * - default domain has no translations
2930+ * - locale does not start with "en_" and is not "C"
2931+ *
2932+ * Rationale:
2933+ * - If text domain is still the default domain, maybe user calls
2934+ * it later. Continue with old behavior of translating.
2935+ * - If locale starts with "en_", we can continue using the
2936+ * translations even if the app doesn't have translations for
2937+ * this locale. That is, en_UK and en_CA for example.
2938+ * - If locale is "C", maybe user calls setlocale(LC_ALL,"") later.
2939+ * Continue with old behavior of translating.
2940+ */
2941+ if (0 != strcmp (default_domain , "messages" ) &&
2942+ '\0' == * translator_comment &&
2943+ 0 != strncmp (translate_locale , "en_" , 3 ) &&
2944+ 0 != strcmp (translate_locale , "C" ))
2945+ should_translate = FALSE;
2946+
2947+ g_once_init_leave (& translate ,
2948+ should_translate ?
2949+ SHOULD_TRANSLATE :
2950+ SHOULD_NOT_TRANSLATE );
2951+ }
2952+
2953+ return translate == SHOULD_TRANSLATE ;
2954+ }
2955+
2956+ /**
2957+ * g_dgettext:
2958+ * @domain: the translation domain to use, or %NULL to use
2959+ * the domain set with textdomain()
2960+ * @msgid: message to translate
2961+ *
2962+ * This function is a wrapper of dgettext() which does not translate
2963+ * the message if the default domain as set with textdomain() has no
2964+ * translations for the current locale.
2965+ *
2966+ * The advantage of using this function over dgettext() proper is that
2967+ * libraries using this function (like GTK+) will not use translations
2968+ * if the application using the library does not have translations for
2969+ * the current locale. This results in a consistent English-only
2970+ * interface instead of one having partial translations. For this
2971+ * feature to work, the call to textdomain() and setlocale() should
2972+ * precede any g_dgettext() invocations. For GTK+, it means calling
2973+ * textdomain() before gtk_init or its variants.
2974+ *
2975+ * This function disables translations if and only if upon its first
2976+ * call all the following conditions hold:
2977+ * <itemizedlist>
2978+ * <listitem>@domain is not %NULL</listitem>
2979+ * <listitem>textdomain() has been called to set a default text domain</listitem>
2980+ * <listitem>there is no translations available for the default text domain
2981+ * and the current locale</listitem>
2982+ * <listitem>current locale is not "C" or any English locales (those
2983+ * starting with "en_")</listitem>
2984+ * </itemizedlist>
2985+ *
2986+ * Note that this behavior may not be desired for example if an application
2987+ * has its untranslated messages in a language other than English. In those
2988+ * cases the application should call textdomain() after initializing GTK+.
2989+ *
2990+ * Applications should normally not use this function directly,
2991+ * but use the _() macro for translations.
2992+ *
2993+ * Returns: The translated string
2994+ *
2995+ * Since: 2.18
2996+ */
2997+ G_CONST_RETURN gchar *
2998+ g_dgettext (const gchar * domain ,
2999+ const gchar * msgid )
3000+ {
3001+ if (domain && G_UNLIKELY (!_g_dgettext_should_translate ()))
3002+ return msgid ;
3003+
3004+ return dgettext (domain , msgid );
3005+ }
3006+
3007+ /**
3008+ * g_dngettext:
3009+ * @domain: the translation domain to use, or %NULL to use
3010+ * the domain set with textdomain()
3011+ * @msgid: message to translate
3012+ * @msgid_plural: plural form of the message
3013+ * @n: the quantity for which translation is needed
3014+ *
3015+ * This function is a wrapper of dngettext() which does not translate
3016+ * the message if the default domain as set with textdomain() has no
3017+ * translations for the current locale.
3018+ *
3019+ * See g_dgettext() for details of how this differs from dngettext()
3020+ * proper.
3021+ *
3022+ * Returns: The translated string
3023+ *
3024+ * Since: 2.18
3025+ */
3026+ G_CONST_RETURN gchar *
3027+ g_dngettext (const gchar * domain ,
3028+ const gchar * msgid ,
3029+ const gchar * msgid_plural ,
3030+ gulong n )
3031+ {
3032+ if (domain && G_UNLIKELY (!_g_dgettext_should_translate ()))
3033+ return n == 1 ? msgid : msgid_plural ;
3034+
3035+ return dngettext (domain , msgid , msgid_plural , n );
3036+ }
3037+
29073038
29083039#define __G_STRFUNCS_C__
29093040#include "galiasdef.c"
0 commit comments