Fix getauxval error at qemu
[platform/upstream/glib.git] / glib / ggettext.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1998  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 /*
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/. 
25  */
26
27 #include "config.h"
28
29 #include "ggettext.h"
30 #include "glibintl.h"
31 #include "glib-private.h"
32
33 #include "galloca.h"
34 #include "gthread.h"
35 #include "gmem.h"
36 #ifdef G_OS_WIN32
37 #include "gwin32.h"
38 #include "gfileutils.h"
39 #include "gstrfuncs.h"
40 #include "glib-init.h"
41 #endif
42
43 #include <string.h>
44 #include <locale.h>
45 #include <libintl.h>
46
47 #ifdef G_OS_WIN32
48
49 /**
50  * _glib_get_locale_dir:
51  *
52  * Return the path to the share\locale or lib\locale subfolder of the
53  * GLib installation folder. The path is in the system codepage. We
54  * have to use system codepage as bindtextdomain() doesn't have a
55  * UTF-8 interface.
56  */
57 gchar *
58 _glib_get_locale_dir (void)
59 {
60   gchar *install_dir = NULL, *locale_dir;
61   gchar *retval = NULL;
62
63   if (glib_dll != NULL)
64     install_dir = g_win32_get_package_installation_directory_of_module (glib_dll);
65
66   if (install_dir)
67     {
68       /*
69        * Append "/share/locale" or "/lib/locale" depending on whether
70        * autoconfigury detected GNU gettext or not.
71        */
72       const char *p = GLIB_LOCALE_DIR + strlen (GLIB_LOCALE_DIR);
73       while (*--p != '/')
74         ;
75       while (*--p != '/')
76         ;
77
78       locale_dir = g_build_filename (install_dir, p, NULL);
79
80       retval = g_win32_locale_filename_from_utf8 (locale_dir);
81
82       g_free (install_dir);
83       g_free (locale_dir);
84     }
85
86   if (retval)
87     return retval;
88   else
89     return g_strdup ("");
90 }
91
92 #undef GLIB_LOCALE_DIR
93
94 #endif /* G_OS_WIN32 */
95
96
97 static void
98 ensure_gettext_initialized (void)
99 {
100   static gsize initialised;
101
102   if (g_once_init_enter (&initialised))
103     {
104 #ifdef G_OS_WIN32
105       gchar *tmp = _glib_get_locale_dir ();
106       bindtextdomain (GETTEXT_PACKAGE, tmp);
107       g_free (tmp);
108 #else
109       bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR);
110 #endif
111 #    ifdef HAVE_BIND_TEXTDOMAIN_CODESET
112       bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
113 #    endif
114       g_once_init_leave (&initialised, TRUE);
115     }
116 }
117
118 /**
119  * glib_gettext:
120  * @str: The string to be translated
121  *
122  * Returns the translated string from the glib translations.
123  * This is an internal function and should only be used by
124  * the internals of glib (such as libgio).
125  *
126  * Returns: the translation of @str to the current locale
127  */
128 const gchar *
129 glib_gettext (const gchar *str)
130 {
131   ensure_gettext_initialized ();
132
133   return g_dgettext (GETTEXT_PACKAGE, str);
134 }
135
136 /**
137  * glib_pgettext:
138  * @msgctxtid: a combined message context and message id, separated
139  *   by a \004 character
140  * @msgidoffset: the offset of the message id in @msgctxid
141  *
142  * This function is a variant of glib_gettext() which supports
143  * a disambiguating message context. See g_dpgettext() for full
144  * details.
145  *
146  * This is an internal function and should only be used by
147  * the internals of glib (such as libgio).
148  *
149  * Returns: the translation of @str to the current locale
150  */
151 const gchar *
152 glib_pgettext (const gchar *msgctxtid,
153                gsize        msgidoffset)
154 {
155   ensure_gettext_initialized ();
156
157   return g_dpgettext (GETTEXT_PACKAGE, msgctxtid, msgidoffset);
158 }
159
160 /**
161  * g_strip_context:
162  * @msgid: a string
163  * @msgval: another string
164  *
165  * An auxiliary function for gettext() support (see Q_()).
166  *
167  * Returns: @msgval, unless @msgval is identical to @msgid
168  *     and contains a '|' character, in which case a pointer to
169  *     the substring of msgid after the first '|' character is returned.
170  *
171  * Since: 2.4
172  */
173 const gchar *
174 g_strip_context (const gchar *msgid,
175                  const gchar *msgval)
176 {
177   if (msgval == msgid)
178     {
179       const char *c = strchr (msgid, '|');
180       if (c != NULL)
181         return c + 1;
182     }
183
184   return msgval;
185 }
186
187 /**
188  * g_dpgettext:
189  * @domain: (nullable): the translation domain to use, or %NULL to use
190  *   the domain set with textdomain()
191  * @msgctxtid: a combined message context and message id, separated
192  *   by a \004 character
193  * @msgidoffset: the offset of the message id in @msgctxid
194  *
195  * This function is a variant of g_dgettext() which supports
196  * a disambiguating message context. GNU gettext uses the
197  * '\004' character to separate the message context and
198  * message id in @msgctxtid.
199  * If 0 is passed as @msgidoffset, this function will fall back to
200  * trying to use the deprecated convention of using "|" as a separation
201  * character.
202  *
203  * This uses g_dgettext() internally. See that functions for differences
204  * with dgettext() proper.
205  *
206  * Applications should normally not use this function directly,
207  * but use the C_() macro for translations with context.
208  *
209  * Returns: The translated string
210  *
211  * Since: 2.16
212  */
213 const gchar *
214 g_dpgettext (const gchar *domain,
215              const gchar *msgctxtid,
216              gsize        msgidoffset)
217 {
218   const gchar *translation;
219   gchar *sep;
220
221   translation = g_dgettext (domain, msgctxtid);
222
223   if (translation == msgctxtid)
224     {
225       if (msgidoffset > 0)
226         return msgctxtid + msgidoffset;
227       sep = strchr (msgctxtid, '|');
228
229       if (sep)
230         {
231           /* try with '\004' instead of '|', in case
232            * xgettext -kQ_:1g was used
233            */
234           gchar *tmp = g_alloca (strlen (msgctxtid) + 1);
235           strcpy (tmp, msgctxtid);
236           tmp[sep - msgctxtid] = '\004';
237
238           translation = g_dgettext (domain, tmp);
239
240           if (translation == tmp)
241             return sep + 1;
242         }
243     }
244
245   return translation;
246 }
247
248 /* This function is taken from gettext.h
249  * GNU gettext uses '\004' to separate context and msgid in .mo files.
250  */
251 /**
252  * g_dpgettext2:
253  * @domain: (nullable): the translation domain to use, or %NULL to use
254  *   the domain set with textdomain()
255  * @context: the message context
256  * @msgid: the message
257  *
258  * This function is a variant of g_dgettext() which supports
259  * a disambiguating message context. GNU gettext uses the
260  * '\004' character to separate the message context and
261  * message id in @msgctxtid.
262  *
263  * This uses g_dgettext() internally. See that functions for differences
264  * with dgettext() proper.
265  *
266  * This function differs from C_() in that it is not a macro and
267  * thus you may use non-string-literals as context and msgid arguments.
268  *
269  * Returns: The translated string
270  *
271  * Since: 2.18
272  */
273 const gchar *
274 g_dpgettext2 (const gchar *domain,
275               const gchar *msgctxt,
276               const gchar *msgid)
277 {
278   size_t msgctxt_len = strlen (msgctxt) + 1;
279   size_t msgid_len = strlen (msgid) + 1;
280   const char *translation;
281   char* msg_ctxt_id;
282
283   msg_ctxt_id = g_alloca (msgctxt_len + msgid_len);
284
285   memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
286   msg_ctxt_id[msgctxt_len - 1] = '\004';
287   memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
288
289   translation = g_dgettext (domain, msg_ctxt_id);
290
291   if (translation == msg_ctxt_id)
292     {
293       /* try the old way of doing message contexts, too */
294       msg_ctxt_id[msgctxt_len - 1] = '|';
295       translation = g_dgettext (domain, msg_ctxt_id);
296
297       if (translation == msg_ctxt_id)
298         return msgid;
299     }
300
301   return translation;
302 }
303
304 static gboolean
305 _g_dgettext_should_translate (void)
306 {
307   static gsize translate = 0;
308   enum {
309     SHOULD_TRANSLATE = 1,
310     SHOULD_NOT_TRANSLATE = 2
311   };
312
313   if (G_UNLIKELY (g_once_init_enter (&translate)))
314     {
315       gboolean should_translate = TRUE;
316
317       const char *default_domain     = textdomain (NULL);
318       const char *translator_comment = gettext ("");
319 #ifndef G_OS_WIN32
320       const char *translate_locale   = setlocale (LC_MESSAGES, NULL);
321 #else
322       const char *translate_locale   = g_win32_getlocale ();
323 #endif
324       /* We should NOT translate only if all the following hold:
325        *   - user has called textdomain() and set textdomain to non-default
326        *   - default domain has no translations
327        *   - locale does not start with "en_" and is not "C"
328        *
329        * Rationale:
330        *   - If text domain is still the default domain, maybe user calls
331        *     it later. Continue with old behavior of translating.
332        *   - If locale starts with "en_", we can continue using the
333        *     translations even if the app doesn't have translations for
334        *     this locale.  That is, en_UK and en_CA for example.
335        *   - If locale is "C", maybe user calls setlocale(LC_ALL,"") later.
336        *     Continue with old behavior of translating.
337        */
338       if (!default_domain || !translator_comment || !translate_locale ||
339           (0 != strcmp (default_domain, "messages") &&
340           '\0' == *translator_comment &&
341           0 != strncmp (translate_locale, "en_", 3) &&
342           0 != strcmp (translate_locale, "C")))
343         should_translate = FALSE;
344
345       g_once_init_leave (&translate,
346                          should_translate ?
347                          SHOULD_TRANSLATE :
348                          SHOULD_NOT_TRANSLATE);
349     }
350
351   return translate == SHOULD_TRANSLATE;
352 }
353
354 /**
355  * g_dgettext:
356  * @domain: (nullable): the translation domain to use, or %NULL to use
357  *   the domain set with textdomain()
358  * @msgid: message to translate
359  *
360  * This function is a wrapper of dgettext() which does not translate
361  * the message if the default domain as set with textdomain() has no
362  * translations for the current locale.
363  *
364  * The advantage of using this function over dgettext() proper is that
365  * libraries using this function (like GTK) will not use translations
366  * if the application using the library does not have translations for
367  * the current locale.  This results in a consistent English-only
368  * interface instead of one having partial translations.  For this
369  * feature to work, the call to textdomain() and setlocale() should
370  * precede any g_dgettext() invocations.  For GTK, it means calling
371  * textdomain() before gtk_init or its variants.
372  *
373  * This function disables translations if and only if upon its first
374  * call all the following conditions hold:
375  * 
376  * - @domain is not %NULL
377  *
378  * - textdomain() has been called to set a default text domain
379  *
380  * - there is no translations available for the default text domain
381  *   and the current locale
382  *
383  * - current locale is not "C" or any English locales (those
384  *   starting with "en_")
385  *
386  * Note that this behavior may not be desired for example if an application
387  * has its untranslated messages in a language other than English. In those
388  * cases the application should call textdomain() after initializing GTK.
389  *
390  * Applications should normally not use this function directly,
391  * but use the _() macro for translations.
392  *
393  * Returns: The translated string
394  *
395  * Since: 2.18
396  */
397 const gchar *
398 g_dgettext (const gchar *domain,
399             const gchar *msgid)
400 {
401   if (domain && G_UNLIKELY (!_g_dgettext_should_translate ()))
402     return msgid;
403
404   return dgettext (domain, msgid);
405 }
406
407 /**
408  * g_dcgettext:
409  * @domain: (nullable): the translation domain to use, or %NULL to use
410  *   the domain set with textdomain()
411  * @msgid: message to translate
412  * @category: a locale category
413  *
414  * This is a variant of g_dgettext() that allows specifying a locale
415  * category instead of always using `LC_MESSAGES`. See g_dgettext() for
416  * more information about how this functions differs from calling
417  * dcgettext() directly.
418  *
419  * Returns: the translated string for the given locale category
420  *
421  * Since: 2.26
422  */
423 const gchar *
424 g_dcgettext (const gchar *domain,
425              const gchar *msgid,
426              gint         category)
427 {
428   if (domain && G_UNLIKELY (!_g_dgettext_should_translate ()))
429     return msgid;
430
431   return dcgettext (domain, msgid, category);
432 }
433
434 /**
435  * g_dngettext:
436  * @domain: (nullable): the translation domain to use, or %NULL to use
437  *   the domain set with textdomain()
438  * @msgid: message to translate
439  * @msgid_plural: plural form of the message
440  * @n: the quantity for which translation is needed
441  *
442  * This function is a wrapper of dngettext() which does not translate
443  * the message if the default domain as set with textdomain() has no
444  * translations for the current locale.
445  *
446  * See g_dgettext() for details of how this differs from dngettext()
447  * proper.
448  *
449  * Returns: The translated string
450  *
451  * Since: 2.18
452  */
453 const gchar *
454 g_dngettext (const gchar *domain,
455              const gchar *msgid,
456              const gchar *msgid_plural,
457              gulong       n)
458 {
459   if (domain && G_UNLIKELY (!_g_dgettext_should_translate ()))
460     return n == 1 ? msgid : msgid_plural;
461
462   return dngettext (domain, msgid, msgid_plural, n);
463 }
464
465
466 /**
467  * SECTION:i18n
468  * @title: Internationalization
469  * @short_description: gettext support macros
470  * @see_also: the gettext manual
471  *
472  * GLib doesn't force any particular localization method upon its users.
473  * But since GLib itself is localized using the gettext() mechanism, it seems
474  * natural to offer the de-facto standard gettext() support macros in an
475  * easy-to-use form.
476  *
477  * In order to use these macros in an application, you must include
478  * `<glib/gi18n.h>`. For use in a library, you must include
479  * `<glib/gi18n-lib.h>`
480  * after defining the %GETTEXT_PACKAGE macro suitably for your library:
481  * |[<!-- language="C" -->
482  * #define GETTEXT_PACKAGE "gtk20"
483  * #include <glib/gi18n-lib.h>
484  * ]|
485  * For an application, note that you also have to call bindtextdomain(),
486  * bind_textdomain_codeset(), textdomain() and setlocale() early on in your
487  * main() to make gettext() work. For example:
488  * |[<!-- language="C" -->
489  * #include <glib/gi18n.h>
490  * #include <locale.h>
491  *
492  * int
493  * main (int argc, char **argv)
494  * {
495  *   setlocale (LC_ALL, "");
496  *   bindtextdomain (GETTEXT_PACKAGE, DATADIR "/locale");
497  *   bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
498  *   textdomain (GETTEXT_PACKAGE);
499  *
500  *   // Rest of your application.
501  * }
502  * ]|
503  * where `DATADIR` is as typically provided by automake or Meson.
504  *
505  * For a library, you only have to call bindtextdomain() and
506  * bind_textdomain_codeset() in your initialization function. If your library
507  * doesn't have an initialization function, you can call the functions before
508  * the first translated message.
509  *
510  * The
511  * [gettext manual](http://www.gnu.org/software/gettext/manual/gettext.html#Maintainers)
512  * covers details of how to integrate gettext into a project’s build system and
513  * workflow.
514  */
515
516 /**
517  * _:
518  * @String: the string to be translated
519  *
520  * Marks a string for translation, gets replaced with the translated string
521  * at runtime.
522  *
523  * Since: 2.4
524  */
525
526 /**
527  * Q_:
528  * @String: the string to be translated, with a '|'-separated prefix
529  *     which must not be translated
530  *
531  * Like _(), but handles context in message ids. This has the advantage
532  * that the string can be adorned with a prefix to guarantee uniqueness
533  * and provide context to the translator.
534  *
535  * One use case given in the gettext manual is GUI translation, where one
536  * could e.g. disambiguate two "Open" menu entries as "File|Open" and
537  * "Printer|Open". Another use case is the string "Russian" which may
538  * have to be translated differently depending on whether it's the name
539  * of a character set or a language. This could be solved by using
540  * "charset|Russian" and "language|Russian".
541  *
542  * See the C_() macro for a different way to mark up translatable strings
543  * with context.
544  *
545  * If you are using the Q_() macro, you need to make sure that you pass
546  * `--keyword=Q_` to xgettext when extracting messages.
547  * If you are using GNU gettext >= 0.15, you can also use
548  * `--keyword=Q_:1g` to let xgettext split the context
549  * string off into a msgctxt line in the po file.
550  *
551  * Returns: the translated message
552  *
553  * Since: 2.4
554  */
555
556 /**
557  * C_:
558  * @Context: a message context, must be a string literal
559  * @String: a message id, must be a string literal
560  *
561  * Uses gettext to get the translation for @String. @Context is
562  * used as a context. This is mainly useful for short strings which
563  * may need different translations, depending on the context in which
564  * they are used.
565  * |[<!-- language="C" -->
566  * label1 = C_("Navigation", "Back");
567  * label2 = C_("Body part", "Back");
568  * ]|
569  *
570  * If you are using the C_() macro, you need to make sure that you pass
571  * `--keyword=C_:1c,2` to xgettext when extracting messages.
572  * Note that this only works with GNU gettext >= 0.15.
573  *
574  * Returns: the translated message
575  *
576  * Since: 2.16
577  */
578
579 /**
580  * N_:
581  * @String: the string to be translated
582  *
583  * Only marks a string for translation. This is useful in situations
584  * where the translated strings can't be directly used, e.g. in string
585  * array initializers. To get the translated string, call gettext()
586  * at runtime.
587  * |[<!-- language="C" -->
588  * {
589  *   static const char *messages[] = {
590  *     N_("some very meaningful message"),
591  *     N_("and another one")
592  *   };
593  *   const char *string;
594  *   ...
595  *   string
596  *     = index &gt; 1 ? _("a default message") : gettext (messages[index]);
597  *
598  *   fputs (string);
599  *   ...
600  * }
601  * ]|
602  *
603  * Since: 2.4
604  */
605
606 /**
607  * NC_:
608  * @Context: a message context, must be a string literal
609  * @String: a message id, must be a string literal
610  *
611  * Only marks a string for translation, with context.
612  * This is useful in situations where the translated strings can't
613  * be directly used, e.g. in string array initializers. To get the
614  * translated string, you should call g_dpgettext2() at runtime.
615  *
616  * |[<!-- language="C" -->
617  * {
618  *   static const char *messages[] = {
619  *     NC_("some context", "some very meaningful message"),
620  *     NC_("some context", "and another one")
621  *   };
622  *   const char *string;
623  *   ...
624  *   string
625  *     = index > 1 ? g_dpgettext2 (NULL, "some context", "a default message")
626  *                 : g_dpgettext2 (NULL, "some context", messages[index]);
627  *
628  *   fputs (string);
629  *   ...
630  * }
631  * ]|
632  *
633  * If you are using the NC_() macro, you need to make sure that you pass
634  * `--keyword=NC_:1c,2` to xgettext when extracting messages.
635  * Note that this only works with GNU gettext >= 0.15. Intltool has support
636  * for the NC_() macro since version 0.40.1.
637  *
638  * Since: 2.18
639  */