1 /* localename.c - Determine the current selected locale.
2 * Copyright (C) 1995-1999, 2000-2003, 2007,
3 * 2008 Free Software Foundation, Inc.
4 *
5 * This file is free software; you can redistribute it and/or modify
6 * it under the terms of either
7 *
8 * - the GNU Lesser General Public License as published by the Free
9 * Software Foundation; either version 3 of the License, or (at
10 * your option) any later version.
11 *
12 * or
13 *
14 * - the GNU General Public License as published by the Free
15 * Software Foundation; either version 2 of the License, or (at
16 * your option) any later version.
17 *
18 * or both in parallel, as here.
19 *
20 * This file is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public
26 * License along with this program; if not, see <https://www.gnu.org/licenses/>.
27 */
28 /* Written by Ulrich Drepper <drepper@gnu.org>, 1995. */
29 /* Win32 code written by Tor Lillqvist <tml@iki.fi>. */
30 /* Modified for GpgOL use by Werner Koch <wk@gnupg.org>, 2005. */
31 /* Modified for GnuPG use by Werner Koch <wk@gnupg.org>, 2007 */
32
33 #ifdef HAVE_CONFIG_H
34 # include <config.h>
35 #endif
36
37 #include <stdlib.h>
38 #include <string.h>
39 #ifdef HAVE_LOCALE_H
40 #include <locale.h>
41 #endif
42 #include <gpg-error.h> /* We need gettext_localename for W32. */
43
44 #include "../common/w32help.h"
45
46 /* XPG3 defines the result of 'setlocale (category, NULL)' as:
47 "Directs 'setlocale()' to query 'category' and return the current
48 setting of 'local'."
49 However it does not specify the exact format. Neither do SUSV2 and
50 ISO C 99. So we can use this feature only on selected systems (e.g.
51 those using GNU C Library). */
52 #if defined _LIBC || (defined __GNU_LIBRARY__ && __GNU_LIBRARY__ >= 2)
53 # define HAVE_LOCALE_NULL
54 #endif
55
56 /* Use a dummy value for LC_MESSAGES in case it is not defined. This
57 works because we always test for HAVE_LC_MESSAGES and the core
58 function takes the category as a string as well. */
59 #ifndef HAVE_LC_MESSAGES
60 #define LC_MESSAGES 0
61 #endif
62
63
64 /* Determine the current locale's name, and canonicalize it into XPG syntax
65 language[_territory[.codeset]][@modifier]
66 The codeset part in the result is not reliable; the locale_charset()
67 should be used for codeset information instead.
68 The result must not be freed; it is statically allocated. */
69
70 #ifndef HAVE_W32_SYSTEM
71 static const char *
do_nl_locale_name(int category,const char * categoryname)72 do_nl_locale_name (int category, const char *categoryname)
73 {
74 const char *retval;
75
76 /* Use the POSIX methods of looking to 'LC_ALL', 'LC_xxx', and 'LANG'.
77 On some systems this can be done by the 'setlocale' function itself. */
78 # if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
79 (void)categoryname;
80 retval = setlocale (category, NULL);
81 # else
82 (void)category;
83 /* Setting of LC_ALL overwrites all other. */
84 retval = getenv ("LC_ALL");
85 if (retval == NULL || retval[0] == '\0')
86 {
87 /* Next comes the name of the desired category. */
88 retval = getenv (categoryname);
89 if (retval == NULL || retval[0] == '\0')
90 {
91 /* Last possibility is the LANG environment variable. */
92 retval = getenv ("LANG");
93 if (retval == NULL || retval[0] == '\0')
94 /* We use C as the default domain. POSIX says this is
95 implementation defined. */
96 retval = "C";
97 }
98 }
99 # endif
100
101 return retval;
102 }
103 #endif /* HAVE_W32_SYSTEM */
104
105
106
107 /* Return the locale used for translatable messages. The standard C
108 and POSIX are locale names are mapped to an empty string. If a
109 locale can't be found an empty string will be returned. */
110 const char *
gnupg_messages_locale_name(void)111 gnupg_messages_locale_name (void)
112 {
113 const char *s;
114
115 #ifdef HAVE_W32_SYSTEM
116 /* We use the localename function libgpg-error. */
117 s = gettext_localename ();
118 #else
119 s = do_nl_locale_name (LC_MESSAGES, "LC_MESSAGES");
120 #endif
121 if (!s)
122 s = "";
123 else if (!strcmp (s, "C") || !strcmp (s, "POSIX"))
124 s = "";
125
126 return s;
127 }
128