|
1 /* |
|
2 * Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Contains the source for setting the locale |
|
15 * |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 #include <errno.h> |
|
21 #include <locale.h> |
|
22 #include <stdlib.h> |
|
23 #include <string.h> |
|
24 #include <sys/cdefs.h> |
|
25 #include <_ansi.h> |
|
26 #include "lmonetary.h" |
|
27 #include "lnumeric.h" |
|
28 #include "timelocal.h" |
|
29 #include "localeinfo.h" |
|
30 |
|
31 #if (defined(__SYMBIAN32__) && (defined(__WINSCW__) || defined(__WINS__))) |
|
32 #include "libc_wsd_defs.h" |
|
33 #endif |
|
34 |
|
35 #define LOCALE_LENGTH 30 |
|
36 extern int _time_using_locale; |
|
37 extern int _numeric_using_locale; |
|
38 extern int _monetary_using_locale; |
|
39 extern int __nlocale_changed; |
|
40 extern int __mlocale_changed; |
|
41 #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT |
|
42 extern unsigned char __clocale_set; |
|
43 extern unsigned char __applocale_changed; |
|
44 #endif |
|
45 |
|
46 #ifdef EMULATOR |
|
47 int *GET_WSD_VAR_NAME(_monetary_using_locale, g)(); |
|
48 int *GET_WSD_VAR_NAME(_numeric_using_locale, g)(); |
|
49 int *GET_WSD_VAR_NAME(_time_using_locale, g)(); |
|
50 GET_GLOBAL_VAR_FROM_TLS(__mlocale_changed, int) |
|
51 GET_GLOBAL_VAR_FROM_TLS(__nlocale_changed, int) |
|
52 #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT |
|
53 GET_GLOBAL_VAR_FROM_TLS(__clocale_set, unsigned char) |
|
54 GET_GLOBAL_VAR_FROM_TLS(__applocale_changed, unsigned char) |
|
55 #endif |
|
56 |
|
57 #define _monetary_using_locale (*GET_WSD_VAR_NAME(_monetary_using_locale, g)()) |
|
58 #define _numeric_using_locale (*GET_WSD_VAR_NAME(_numeric_using_locale, g)()) |
|
59 #define _time_using_locale (*GET_WSD_VAR_NAME(_time_using_locale, g)()) |
|
60 #define __mlocale_changed (*GET_WSD_VAR_NAME(__mlocale_changed, g)()) |
|
61 #define __nlocale_changed (*GET_WSD_VAR_NAME(__nlocale_changed, g)()) |
|
62 #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT |
|
63 #define __clocale_set (*GET_WSD_VAR_NAME(__clocale_set, g)()) |
|
64 #define __applocale_changed (*GET_WSD_VAR_NAME(__applocale_changed, g)()) |
|
65 #endif |
|
66 #endif //EMULATOR |
|
67 |
|
68 __BEGIN_DECLS |
|
69 #ifndef EMULATOR |
|
70 char LC_CTYPE_LocaleName[LOCALE_LENGTH] = {'\0'}; |
|
71 char LC_COLLATE_LocaleName[LOCALE_LENGTH] = {'\0'}; |
|
72 char LC_NUMERIC_LocaleName[LOCALE_LENGTH] = {'\0'}; |
|
73 char LC_MONETARY_LocaleName[LOCALE_LENGTH] = {'\0'}; |
|
74 char LC_TIME_LocaleName[LOCALE_LENGTH] ={'\0'}; |
|
75 char LC_ALL_LocaleName[LOCALE_LENGTH] = {'\0'}; |
|
76 |
|
77 #else //EMULATOR |
|
78 |
|
79 GET_GLOBAL_ARRAY_FROM_TLS(LC_CTYPE_LocaleName, char) |
|
80 GET_GLOBAL_ARRAY_FROM_TLS(LC_COLLATE_LocaleName, char) |
|
81 GET_GLOBAL_ARRAY_FROM_TLS(LC_NUMERIC_LocaleName, char) |
|
82 GET_GLOBAL_ARRAY_FROM_TLS(LC_MONETARY_LocaleName, char) |
|
83 GET_GLOBAL_ARRAY_FROM_TLS(LC_TIME_LocaleName, char) |
|
84 GET_GLOBAL_ARRAY_FROM_TLS(LC_ALL_LocaleName, char) |
|
85 |
|
86 #define LC_CTYPE_LocaleName (GET_WSD_VAR_NAME(LC_CTYPE_LocaleName, g)()) |
|
87 #define LC_COLLATE_LocaleName (GET_WSD_VAR_NAME(LC_COLLATE_LocaleName, g)()) |
|
88 #define LC_NUMERIC_LocaleName (GET_WSD_VAR_NAME(LC_NUMERIC_LocaleName, g)()) |
|
89 #define LC_MONETARY_LocaleName (GET_WSD_VAR_NAME(LC_MONETARY_LocaleName, g)()) |
|
90 #define LC_TIME_LocaleName (GET_WSD_VAR_NAME(LC_TIME_LocaleName, g)()) |
|
91 #define LC_ALL_LocaleName (GET_WSD_VAR_NAME(LC_ALL_LocaleName, g)()) |
|
92 #endif //EMULATOR |
|
93 |
|
94 |
|
95 __END_DECLS |
|
96 |
|
97 extern "C" { |
|
98 |
|
99 EXPORT_C char * setlocale(int category, const char* locale) |
|
100 { |
|
101 CLocale* loc = CLocale::GetInstance(); |
|
102 |
|
103 //Query the current locale |
|
104 if(NULL == locale) |
|
105 { |
|
106 char* ret = NULL; |
|
107 switch(category) |
|
108 { |
|
109 case LC_CTYPE: if(!*LC_CTYPE_LocaleName) |
|
110 { |
|
111 LC_CTYPE_LocaleName[0] = 'C'; |
|
112 LC_CTYPE_LocaleName[1] = '\0'; |
|
113 } |
|
114 ret = (char*) LC_CTYPE_LocaleName; |
|
115 break; |
|
116 |
|
117 case LC_COLLATE:if(!*LC_COLLATE_LocaleName) |
|
118 { |
|
119 LC_COLLATE_LocaleName[0] = 'C'; |
|
120 LC_COLLATE_LocaleName[1] = '\0'; |
|
121 } |
|
122 ret = (char*) LC_COLLATE_LocaleName; |
|
123 break; |
|
124 |
|
125 case LC_TIME: if(!*LC_TIME_LocaleName) |
|
126 { |
|
127 LC_TIME_LocaleName[0] = 'C'; |
|
128 LC_TIME_LocaleName[1] = '\0'; |
|
129 _time_using_locale = 0; |
|
130 } |
|
131 ret = (char*) LC_TIME_LocaleName; |
|
132 break; |
|
133 |
|
134 case LC_NUMERIC:if(!*LC_NUMERIC_LocaleName) |
|
135 { |
|
136 LC_NUMERIC_LocaleName[0] = 'C'; |
|
137 LC_NUMERIC_LocaleName[1] = '\0'; |
|
138 _numeric_using_locale = 0; |
|
139 } |
|
140 ret = (char*) LC_NUMERIC_LocaleName; |
|
141 break; |
|
142 |
|
143 case LC_MONETARY:if(!*LC_MONETARY_LocaleName) |
|
144 { |
|
145 LC_MONETARY_LocaleName[0] = 'C'; |
|
146 LC_MONETARY_LocaleName[1] = '\0'; |
|
147 _monetary_using_locale = 0; |
|
148 } |
|
149 ret = (char*) LC_MONETARY_LocaleName; |
|
150 break; |
|
151 |
|
152 case LC_MESSAGES: |
|
153 break; |
|
154 |
|
155 case LC_ALL :if(!*LC_ALL_LocaleName) |
|
156 { |
|
157 _time_using_locale = 0; |
|
158 _numeric_using_locale = 0; |
|
159 _monetary_using_locale = 0; |
|
160 |
|
161 LC_CTYPE_LocaleName[0] = 'C'; |
|
162 LC_CTYPE_LocaleName[1] = '\0'; |
|
163 LC_COLLATE_LocaleName[0] = 'C'; |
|
164 LC_COLLATE_LocaleName[1] = '\0'; |
|
165 LC_TIME_LocaleName[0] = 'C'; |
|
166 LC_TIME_LocaleName[1] = '\0'; |
|
167 LC_NUMERIC_LocaleName[0] = 'C'; |
|
168 LC_NUMERIC_LocaleName[1] = '\0'; |
|
169 LC_MONETARY_LocaleName[0] = 'C'; |
|
170 LC_MONETARY_LocaleName[1] = '\0'; |
|
171 LC_ALL_LocaleName[0] = 'C'; |
|
172 LC_ALL_LocaleName[1] = '\0'; |
|
173 } |
|
174 ret = (char*) LC_ALL_LocaleName; |
|
175 break; |
|
176 default: |
|
177 errno = EINVAL; |
|
178 return (NULL); |
|
179 } |
|
180 return ret; |
|
181 } |
|
182 |
|
183 //If locale is "" set each category(LC_CTYPE, LC_COLLATE, LC_NUMERIC, LC_TIME, LC_MONETARY) to C locale |
|
184 if(strcmp(locale, "") == 0 ) |
|
185 { |
|
186 _time_using_locale = 0; |
|
187 _numeric_using_locale = 0; |
|
188 _monetary_using_locale = 0; |
|
189 __nlocale_changed = 1; |
|
190 __mlocale_changed = 1; |
|
191 #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT |
|
192 __clocale_set = 1; |
|
193 __applocale_changed = 1; |
|
194 #endif |
|
195 |
|
196 LC_CTYPE_LocaleName[0] = 'C'; |
|
197 LC_CTYPE_LocaleName[1] = '\0'; |
|
198 LC_COLLATE_LocaleName[0] = 'C'; |
|
199 LC_COLLATE_LocaleName[1] = '\0'; |
|
200 LC_TIME_LocaleName[0] = 'C'; |
|
201 LC_TIME_LocaleName[1] = '\0'; |
|
202 LC_NUMERIC_LocaleName[0] = 'C'; |
|
203 LC_NUMERIC_LocaleName[1] = '\0'; |
|
204 LC_MONETARY_LocaleName[0] = 'C'; |
|
205 LC_MONETARY_LocaleName[1] = '\0'; |
|
206 LC_ALL_LocaleName[0] = 'C'; |
|
207 LC_ALL_LocaleName[1] = '\0'; |
|
208 |
|
209 return "C"; |
|
210 } |
|
211 |
|
212 if (strcmp(locale, "C") == 0 || strcmp(locale, "POSIX") == 0) |
|
213 { |
|
214 if(LC_ALL == category) |
|
215 { |
|
216 _time_using_locale = 0; |
|
217 _numeric_using_locale = 0; |
|
218 _monetary_using_locale = 0; |
|
219 __nlocale_changed = 1; |
|
220 __mlocale_changed = 1; |
|
221 #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT |
|
222 __clocale_set = 1; |
|
223 __applocale_changed = 1; |
|
224 #endif |
|
225 |
|
226 strcpy((char*) LC_ALL_LocaleName, locale); |
|
227 LC_ALL_LocaleName[strlen(locale)] = '\0'; |
|
228 strcpy((char*) LC_CTYPE_LocaleName, locale); |
|
229 LC_CTYPE_LocaleName[strlen(locale)] = '\0'; |
|
230 strcpy((char*) LC_COLLATE_LocaleName, locale); |
|
231 LC_COLLATE_LocaleName[strlen(locale)] = '\0'; |
|
232 strcpy((char*) LC_NUMERIC_LocaleName, locale); |
|
233 LC_NUMERIC_LocaleName[strlen(locale)] = '\0'; |
|
234 strcpy((char*) LC_MONETARY_LocaleName, locale); |
|
235 LC_MONETARY_LocaleName[strlen(locale)] = '\0'; |
|
236 strcpy((char*) LC_TIME_LocaleName, locale); |
|
237 LC_TIME_LocaleName[strlen(locale)] = '\0'; |
|
238 return (char*) locale; |
|
239 } |
|
240 |
|
241 switch(category) |
|
242 { |
|
243 case LC_CTYPE: strcpy((char*) LC_CTYPE_LocaleName, locale); |
|
244 LC_CTYPE_LocaleName[strlen(locale)] = '\0'; |
|
245 break; |
|
246 |
|
247 case LC_COLLATE: strcpy((char*) LC_COLLATE_LocaleName, locale); |
|
248 LC_COLLATE_LocaleName[strlen(locale)] = '\0'; |
|
249 break; |
|
250 |
|
251 case LC_TIME: _time_using_locale = 0; |
|
252 strcpy((char*) LC_TIME_LocaleName, locale); |
|
253 LC_TIME_LocaleName[strlen(locale)] = '\0'; |
|
254 break; |
|
255 |
|
256 case LC_NUMERIC: _numeric_using_locale = 0; |
|
257 __nlocale_changed = 1; |
|
258 #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT |
|
259 __applocale_changed = 1; |
|
260 #endif |
|
261 strcpy((char*) LC_NUMERIC_LocaleName, locale); |
|
262 LC_NUMERIC_LocaleName[strlen(locale)] = '\0'; |
|
263 break; |
|
264 |
|
265 case LC_MONETARY: _monetary_using_locale = 0; |
|
266 __mlocale_changed = 1; |
|
267 #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT |
|
268 __applocale_changed = 1; |
|
269 #endif |
|
270 strcpy((char*) LC_MONETARY_LocaleName, locale); |
|
271 LC_MONETARY_LocaleName[strlen(locale)] = '\0'; |
|
272 break; |
|
273 |
|
274 case LC_MESSAGES: |
|
275 default: |
|
276 errno = EINVAL; |
|
277 return (NULL); |
|
278 } |
|
279 return ((char*) locale); |
|
280 } |
|
281 |
|
282 //If locale is other than C or POSIX |
|
283 TPtrC8 src((const TUint8*)locale); |
|
284 TBuf16 <LOCALE_LENGTH> localeString; |
|
285 localeString.Copy(src); |
|
286 TText* retVal = loc->SetLocale(localeString); |
|
287 if(NULL == retVal) |
|
288 { |
|
289 return NULL; |
|
290 } |
|
291 |
|
292 if(LC_ALL == category) |
|
293 { |
|
294 TInt retVal =0; |
|
295 |
|
296 if( __numeric_load_locale(locale) == -1) |
|
297 { |
|
298 retVal = -1; |
|
299 } |
|
300 if(__monetary_load_locale(locale) == -1) |
|
301 { |
|
302 retVal = -1; |
|
303 } |
|
304 if (__time_load_locale(locale) == -1) |
|
305 { |
|
306 retVal = -1; |
|
307 } |
|
308 |
|
309 if(!retVal) |
|
310 { |
|
311 strcpy((char*) LC_ALL_LocaleName, locale); |
|
312 LC_ALL_LocaleName[strlen(locale)] = '\0'; |
|
313 strcpy((char*) LC_CTYPE_LocaleName, locale); |
|
314 LC_CTYPE_LocaleName[strlen(locale)] = '\0'; |
|
315 strcpy((char*) LC_COLLATE_LocaleName, locale); |
|
316 LC_COLLATE_LocaleName[strlen(locale)] = '\0'; |
|
317 strcpy((char*) LC_NUMERIC_LocaleName, locale); |
|
318 LC_NUMERIC_LocaleName[strlen(locale)] = '\0'; |
|
319 strcpy((char*) LC_MONETARY_LocaleName, locale); |
|
320 LC_MONETARY_LocaleName[strlen(locale)] = '\0'; |
|
321 strcpy((char*) LC_TIME_LocaleName, locale); |
|
322 LC_TIME_LocaleName[strlen(locale)] = '\0'; |
|
323 return (char*) locale; |
|
324 } |
|
325 else |
|
326 { |
|
327 return NULL; |
|
328 } |
|
329 } |
|
330 |
|
331 switch (category) |
|
332 { |
|
333 case LC_CTYPE: strcpy((char*) LC_CTYPE_LocaleName, locale); |
|
334 LC_CTYPE_LocaleName[strlen(locale)] = '\0'; |
|
335 break; |
|
336 |
|
337 case LC_COLLATE: strcpy((char*) LC_COLLATE_LocaleName, locale); |
|
338 LC_COLLATE_LocaleName[strlen(locale)] = '\0'; |
|
339 break; |
|
340 |
|
341 case LC_TIME: if(!__time_load_locale(locale)) |
|
342 { |
|
343 strcpy((char*) LC_TIME_LocaleName, locale); |
|
344 LC_TIME_LocaleName[strlen(locale)] = '\0'; |
|
345 } |
|
346 else |
|
347 { |
|
348 return NULL; |
|
349 } |
|
350 break; |
|
351 |
|
352 case LC_NUMERIC: if(!__numeric_load_locale(locale)) |
|
353 { |
|
354 strcpy((char*) LC_NUMERIC_LocaleName, locale); |
|
355 LC_NUMERIC_LocaleName[strlen(locale)] = '\0'; |
|
356 } |
|
357 else |
|
358 { |
|
359 return NULL; |
|
360 } |
|
361 break; |
|
362 |
|
363 case LC_MONETARY: if(!__monetary_load_locale(locale)) |
|
364 { |
|
365 strcpy((char*) LC_MONETARY_LocaleName, locale); |
|
366 LC_MONETARY_LocaleName[strlen(locale)] = '\0'; |
|
367 } |
|
368 else |
|
369 { |
|
370 return NULL; |
|
371 } |
|
372 break; |
|
373 |
|
374 case LC_MESSAGES: |
|
375 default: |
|
376 errno = EINVAL; |
|
377 return (NULL); |
|
378 } |
|
379 return ((char*) locale); |
|
380 } |
|
381 |
|
382 |
|
383 EXPORT_C wchar_t* wsetlocale(int category, const wchar_t* locale) |
|
384 { |
|
385 char LocaleName[LOCALE_LENGTH]; |
|
386 wchar_t *wideLocaleName = new wchar_t[LOCALE_LENGTH + 1]; |
|
387 char *result = NULL; |
|
388 |
|
389 if (locale != NULL) |
|
390 { |
|
391 if ((size_t)-1 != (wcstombs((char*)LocaleName, locale, LOCALE_LENGTH*sizeof(wchar_t)))) |
|
392 { |
|
393 result = setlocale(category, LocaleName); |
|
394 } |
|
395 } |
|
396 else |
|
397 { |
|
398 result = setlocale(category, NULL); |
|
399 } |
|
400 |
|
401 if (result != NULL) |
|
402 { |
|
403 if ((size_t)-1 != (mbstowcs(wideLocaleName, result, LOCALE_LENGTH*sizeof(wchar_t)))) |
|
404 { |
|
405 return wideLocaleName; |
|
406 } |
|
407 } |
|
408 |
|
409 delete []wideLocaleName; |
|
410 return NULL; |
|
411 } |
|
412 |
|
413 } //extern "C" |