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