SetLocale.c revision 1ab64890
1/* $XdotOrg: lib/X11/src/SetLocale.c,v 1.4 2005-07-03 07:00:55 daniels Exp $ */
2/* $Xorg: SetLocale.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */
3
4/*
5 * Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation,
6 *                      and Nippon Telegraph and Telephone Corporation
7 *
8 * Permission to use, copy, modify, distribute, and sell this software and its
9 * documentation for any purpose is hereby granted without fee, provided that
10 * the above copyright notice appear in all copies and that both that
11 * copyright notice and this permission notice appear in supporting
12 * documentation, and that the names of OMRON, NTT Software, and NTT
13 * not be used in advertising or publicity pertaining to distribution of the
14 * software without specific, written prior permission. OMRON, NTT Software,
15 * and NTT make no representations about the suitability of this
16 * software for any purpose.  It is provided "as is" without express or
17 * implied warranty.
18 *
19 * OMRON, NTT SOFTWARE, AND NTT, DISCLAIM ALL WARRANTIES WITH REGARD
20 * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
21 * AND FITNESS, IN NO EVENT SHALL OMRON, NTT SOFTWARE, OR NTT, BE
22 * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
23 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
24 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
25 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26 *
27 *	Authors: Li Yuhong		OMRON Corporation
28 *		 Tetsuya Kato		NTT Software Corporation
29 *		 Hiroshi Kuribayashi	OMRON Corporation
30 *
31 */
32/*
33
34Copyright 1987,1998  The Open Group
35
36Permission to use, copy, modify, distribute, and sell this software and its
37documentation for any purpose is hereby granted without fee, provided that
38the above copyright notice appear in all copies and that both that
39copyright notice and this permission notice appear in supporting
40documentation.
41
42The above copyright notice and this permission notice shall be included
43in all copies or substantial portions of the Software.
44
45THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
46OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
47MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
48IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
49OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
50ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
51OTHER DEALINGS IN THE SOFTWARE.
52
53Except as contained in this notice, the name of The Open Group shall
54not be used in advertising or otherwise to promote the sale, use or
55other dealings in this Software without prior written authorization
56from The Open Group.
57
58*/
59/* $XFree86: xc/lib/X11/SetLocale.c,v 3.20 2003/11/17 22:20:08 dawes Exp $ */
60
61#ifdef HAVE_CONFIG_H
62#include <config.h>
63#endif
64#include "Xlibint.h"
65#include "Xlcint.h"
66#include <X11/Xlocale.h>
67#include <X11/Xos.h>
68#include "XlcPubI.h"
69
70#define MAXLOCALE	64	/* buffer size of locale name */
71
72#ifdef X_LOCALE
73
74/* alternative setlocale() for when the OS does not provide one */
75
76char *
77_Xsetlocale(
78    int		  category,
79    _Xconst char  *name
80)
81{
82    static char *xsl_name;
83    char *old_name;
84    XrmMethods methods;
85    XPointer state;
86
87    if (category != LC_CTYPE && category != LC_ALL)
88	return NULL;
89    if (!name) {
90	if (xsl_name)
91	    return xsl_name;
92	return "C";
93    }
94    if (!*name)
95	name = getenv("LC_CTYPE");
96    if (!name || !*name)
97	name = getenv("LANG");
98    if (name && strlen(name) >= MAXLOCALE)
99	name = NULL;
100    if (!name || !*name || !_XOpenLC((char *) name))
101	name = "C";
102    old_name = xsl_name;
103    xsl_name = (char *)name;
104    methods = _XrmInitParseInfo(&state);
105    xsl_name = old_name;
106    if (!methods)
107	return NULL;
108    name = (*methods->lcname)(state);
109    xsl_name = Xmalloc(strlen(name) + 1);
110    if (!xsl_name) {
111	xsl_name = old_name;
112	(*methods->destroy)(state);
113	return NULL;
114    }
115    strcpy(xsl_name, name);
116    if (old_name)
117	Xfree(old_name);
118    (*methods->destroy)(state);
119    return xsl_name;
120}
121
122#else /* X_LOCALE */
123
124#ifdef __APPLE__
125char *
126_Xsetlocale(
127    int           category,
128    _Xconst char  *name
129)
130{
131    return setlocale(category, name);
132}
133#endif /* __APPLE__ */
134
135/*
136 * _XlcMapOSLocaleName is an implementation dependent routine that derives
137 * the LC_CTYPE locale name as used in the sample implementation from that
138 * returned by setlocale.
139 *
140 * Should match the code in Xt ExtractLocaleName.
141 *
142 * This function name is a bit of a misnomer. Even the siname parameter
143 * name is a misnomer. On most modern operating systems this function is
144 * a no-op, simply returning the osname; but on older operating systems
145 * like Ultrix, or HPUX 9.x and earlier, when you set LANG=german.88591
146 * then the string returned by setlocale(LC_ALL, "") will look something
147 * like: "german.88591 german.88591 ... german.88591". Then this function
148 * will pick out the LC_CTYPE component and return a pointer to that.
149 */
150
151char *
152_XlcMapOSLocaleName(
153    char *osname,
154    char *siname)
155{
156#if defined(hpux) || defined(CSRG_BASED) || defined(sun) || defined(SVR4) || defined(sgi) || defined(__osf__) || defined(AIXV3) || defined(ultrix) || defined(WIN32) || defined(__UNIXOS2__) || defined(linux)
157# ifdef hpux
158#  ifndef _LastCategory
159   /* HPUX 9 and earlier */
160#   define SKIPCOUNT 2
161#   define STARTCHAR ':'
162#   define ENDCHAR ';'
163#  else
164   /* HPUX 10 */
165#   define ENDCHAR ' '
166#  endif
167# else
168#  ifdef ultrix
169#   define SKIPCOUNT 2
170#   define STARTCHAR '\001'
171#   define ENDCHAR '\001'
172#  else
173#   if defined(WIN32) || defined(__UNIXOS2__)
174#    define SKIPCOUNT 1
175#    define STARTCHAR '='
176#    define ENDCHAR ';'
177#    define WHITEFILL
178#   else
179#    if defined(__osf__) || (defined(AIXV3) && !defined(AIXV4))
180#     define STARTCHAR ' '
181#     define ENDCHAR ' '
182#    else
183#     if defined(linux)
184#      define STARTSTR "LC_CTYPE="
185#      define ENDCHAR ';'
186#     else
187#      if !defined(sun) || defined(SVR4)
188#       define STARTCHAR '/'
189#       define ENDCHAR '/'
190#      endif
191#     endif
192#    endif
193#   endif
194#  endif
195# endif
196
197    char           *start;
198    char           *end;
199    int             len;
200# ifdef SKIPCOUNT
201    int		    n;
202# endif
203
204    start = osname;
205# ifdef SKIPCOUNT
206    for (n = SKIPCOUNT;
207	 --n >= 0 && start && (start = strchr (start, STARTCHAR));
208	 start++)
209	;
210    if (!start)
211	start = osname;
212# endif
213# ifdef STARTCHAR
214    if (start && (start = strchr (start, STARTCHAR)))
215# elif  defined (STARTSTR)
216    if (start && (start = strstr (start,STARTSTR)))
217# endif
218    {
219# ifdef STARTCHAR
220	start++;
221# elif defined (STARTSTR)
222	start += strlen(STARTSTR);
223# endif
224	if ((end = strchr (start, ENDCHAR))) {
225	    len = end - start;
226	    if (len >= MAXLOCALE)
227		len = MAXLOCALE - 1;
228	    strncpy(siname, start, len);
229	    *(siname + len) = '\0';
230# ifdef WHITEFILL
231	    for (start = siname; start = strchr(start, ' '); )
232		*start++ = '-';
233# endif
234	    return siname;
235	} else  /* if no ENDCHAR is found we are at the end of the line */
236	    return start;
237    }
238# ifdef WHITEFILL
239    if (strchr(osname, ' ')) {
240	len = strlen(osname);
241	if (len >= MAXLOCALE - 1)
242	    len = MAXLOCALE - 1;
243	strncpy(siname, osname, len);
244	*(siname + len) = '\0';
245	for (start = siname; start = strchr(start, ' '); )
246	    *start++ = '-';
247	return siname;
248    }
249# endif
250# undef STARTCHAR
251# undef ENDCHAR
252# undef WHITEFILL
253#endif
254    return osname;
255}
256
257#endif  /* X_LOCALE */
258