|
1 /* |
|
2 * Copyright (c) 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: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 # include "stlport_prefix.h" |
|
20 #include <limits.h> |
|
21 |
|
22 //madhu - 18/8/06 |
|
23 #include "locale.h" |
|
24 #include "langinfo.h" |
|
25 #include <string.h> |
|
26 #include <stdlib.h> |
|
27 #include <cwctype> |
|
28 #include "c_locale.h" |
|
29 #define CODECVT_ICONV //Define CODECVT_ICONV to use ICONV APIs for code conversion. |
|
30 |
|
31 //#define _MESSAGE_CATALOG_ |
|
32 #ifdef _MESSAGE_CATALOG_ |
|
33 #include <libintl.h> |
|
34 #endif |
|
35 |
|
36 # ifdef _STLP_REAL_LOCALE_IMPLEMENTED |
|
37 |
|
38 // here, we'll put C locale implementation for those compilers where |
|
39 // it has to be done in C++ |
|
40 |
|
41 # else |
|
42 |
|
43 /* This is a "stub" implementation of the "c_locale.h" interface, |
|
44 intended for operating systems where we have not yet written |
|
45 a real implementation. A C++ library using this stub implementation |
|
46 is still standard-conforming, since the C++ standard does not require |
|
47 that any locales other than "C" be supported. |
|
48 */ |
|
49 |
|
50 #if 0 //Madhu - 18/8/06 |
|
51 /* Framework functions */ |
|
52 |
|
53 struct _Locale_ctype /* { } */ ; |
|
54 struct _Locale_numeric /* { } */; |
|
55 struct _Locale_time /* { } */; |
|
56 struct _Locale_collate /*{ } */; |
|
57 struct _Locale_monetary /* { } */; |
|
58 struct _Locale_messages /* { } */; |
|
59 |
|
60 #endif //#if 0 |
|
61 |
|
62 |
|
63 #ifdef CODECVT_ICONV |
|
64 #include <iconv.h> |
|
65 #include <errno.h> |
|
66 #define UNICODESTR "UCS2" |
|
67 struct node; |
|
68 enum CONVWAY |
|
69 { |
|
70 |
|
71 IN = 0, |
|
72 OUT |
|
73 |
|
74 }; |
|
75 typedef struct node |
|
76 { |
|
77 mbstate_t *state; |
|
78 iconv_t in_iconvstate; |
|
79 iconv_t out_iconvstate; |
|
80 struct node *next; |
|
81 }StateList; |
|
82 |
|
83 void BEtoLE(wchar_t* src, int size) |
|
84 { |
|
85 int i = 0; |
|
86 |
|
87 for (i = 0;i<size;i++) |
|
88 src[i] = (src[i]>>8) | (src[i]<<8); |
|
89 } |
|
90 |
|
91 void ExtractCodeset(char* name, char* codeset) |
|
92 { |
|
93 char* temp = strstr(name,"."); |
|
94 if( temp != NULL) |
|
95 { |
|
96 temp++; |
|
97 while ( (*temp)&&(*temp!='=') ) |
|
98 *codeset++ = *temp++; |
|
99 } |
|
100 } |
|
101 |
|
102 int AddState(StateList **list, iconv_t icnvstate, mbstate_t* state, enum CONVWAY way) |
|
103 { |
|
104 StateList *temp = *list; |
|
105 StateList *newnode = NULL; |
|
106 while(temp) |
|
107 { |
|
108 if (temp->state == state) |
|
109 break; |
|
110 temp = temp->next; |
|
111 } |
|
112 |
|
113 if (!temp) |
|
114 { |
|
115 newnode = new StateList; |
|
116 if (newnode == NULL) |
|
117 return 0; |
|
118 newnode->next = NULL; |
|
119 newnode->state = state; |
|
120 newnode->in_iconvstate = newnode->out_iconvstate = NULL; |
|
121 } |
|
122 if(newnode) |
|
123 temp = newnode; |
|
124 if (!way) |
|
125 temp->in_iconvstate = icnvstate; |
|
126 else |
|
127 temp->out_iconvstate = icnvstate; |
|
128 |
|
129 if (*list == NULL) |
|
130 { |
|
131 *list = temp; |
|
132 return 1; |
|
133 } |
|
134 else if(newnode) |
|
135 { |
|
136 |
|
137 StateList *move = *list; |
|
138 while(move->next) |
|
139 move = move->next; |
|
140 |
|
141 move->next = temp; |
|
142 } |
|
143 return 1; |
|
144 |
|
145 } |
|
146 |
|
147 iconv_t GetState(StateList *list, mbstate_t* state, enum CONVWAY way) |
|
148 { |
|
149 while(list) |
|
150 { |
|
151 if (list->state == state) |
|
152 { |
|
153 if (!way) |
|
154 return (iconv_t)list->in_iconvstate; |
|
155 else |
|
156 return (iconv_t)list->out_iconvstate; |
|
157 } |
|
158 |
|
159 list = list->next; |
|
160 } |
|
161 return NULL; |
|
162 } |
|
163 |
|
164 void DeleteAllStates(StateList *list) |
|
165 { |
|
166 while(list) |
|
167 { |
|
168 StateList *temp =list ; |
|
169 iconv_close(temp->in_iconvstate); |
|
170 iconv_close(temp->out_iconvstate); |
|
171 list = list->next; |
|
172 delete temp; |
|
173 } |
|
174 } |
|
175 |
|
176 |
|
177 #endif |
|
178 |
|
179 |
|
180 |
|
181 //Madhu - locale function definitions - START |
|
182 //Madhu - temporarily hardcoded system default locale - 18/8/06 |
|
183 #define LOCALE_SYSTEM_DEFAULT "C" |
|
184 #define MAX_NAME_LEN 64 |
|
185 char presentLocaleName[64]; // Stores present locale name. |
|
186 |
|
187 |
|
188 |
|
189 #if defined (__GNUC__) || defined (_KCC) || defined(__ICC) |
|
190 typedef unsigned short int _Locale_mask_t; |
|
191 #else |
|
192 typedef unsigned int _Locale_mask_t; |
|
193 #endif |
|
194 |
|
195 typedef struct _Locale_ctype { |
|
196 char name[MAX_NAME_LEN]; |
|
197 _Locale_mask_t ctable[257]; |
|
198 #ifdef CODECVT_ICONV |
|
199 StateList *statelist; |
|
200 ~_Locale_ctype() |
|
201 { |
|
202 DeleteAllStates(statelist); |
|
203 } |
|
204 #endif |
|
205 |
|
206 } L_ctype_t; |
|
207 |
|
208 |
|
209 typedef struct _Locale_numeric { |
|
210 char name[MAX_NAME_LEN]; |
|
211 char decimal_point[4]; |
|
212 char thousands_sep[4]; |
|
213 char *grouping; |
|
214 } L_numeric_t; |
|
215 |
|
216 typedef struct _Locale_time { |
|
217 char name[MAX_NAME_LEN]; |
|
218 char *month[12]; |
|
219 char *abbrev_month[12]; |
|
220 char *dayofweek[7]; |
|
221 char *abbrev_dayofweek[7]; |
|
222 } L_time_t; |
|
223 |
|
224 typedef struct _Locale_collate { |
|
225 char name[MAX_NAME_LEN]; |
|
226 } L_collate_t; |
|
227 |
|
228 typedef struct _Locale_monetary { |
|
229 char name[MAX_NAME_LEN]; |
|
230 char decimal_point[4]; |
|
231 char thousands_sep[4]; |
|
232 char *grouping; |
|
233 char int_curr_symbol[5]; // 3+1+1 |
|
234 char curr_symbol[6]; |
|
235 char negative_sign[5]; |
|
236 char positive_sign[5]; |
|
237 int frac_digits; |
|
238 int int_frac_digits; |
|
239 } L_monetary_t; |
|
240 |
|
241 typedef struct _Locale_messages { |
|
242 char name[MAX_NAME_LEN]; |
|
243 char* domain; |
|
244 } L_messages_t; |
|
245 |
|
246 |
|
247 char* __getString(char* str) |
|
248 { |
|
249 int len = strlen(str)+1; |
|
250 char* temp = (char*) new char[len]; |
|
251 strcpy(temp, str); |
|
252 |
|
253 return temp; |
|
254 |
|
255 } |
|
256 |
|
257 /* Common function to set locale information */ |
|
258 #if 0 |
|
259 static void* Locale_Common_Create(const char* locale) |
|
260 { |
|
261 |
|
262 setlocale(LC_ALL, locale); |
|
263 |
|
264 return (void*) localeconv(); |
|
265 |
|
266 |
|
267 } |
|
268 #endif |
|
269 |
|
270 /* Gets the system locale name */ |
|
271 static const char* Locale_common_default( char* name) |
|
272 { |
|
273 #if 0 |
|
274 char* presentLocalename = NULL; |
|
275 char* defaultLocalename = NULL; |
|
276 |
|
277 //Madhu - going round to get default system locale, need to find alternative - 18/8/96 |
|
278 presentLocalename = setlocale(LC_ALL, NULL); |
|
279 defaultLocalename = setlocale(LC_ALL, ""); |
|
280 setlocale(LC_ALL, presentLocalename); |
|
281 #endif |
|
282 |
|
283 if(name!=NULL) |
|
284 strcpy(name,LOCALE_SYSTEM_DEFAULT); |
|
285 |
|
286 return LOCALE_SYSTEM_DEFAULT; |
|
287 |
|
288 } |
|
289 |
|
290 #if 0 |
|
291 /* Gets the present locale name */ |
|
292 static char* Locale_common_name(const void* cat, char* name) |
|
293 { |
|
294 #if 0 |
|
295 char* presentLocalename = NULL; |
|
296 |
|
297 presentLocalename = setlocale(LC_ALL, NULL); |
|
298 strcpy(name,presentLocalename); |
|
299 |
|
300 return presentLocalename; |
|
301 #endif |
|
302 L_ctype_t* locale = (L_ctype_t*) cat; |
|
303 strcpy(name,locale->name); |
|
304 return name; |
|
305 } |
|
306 #endif |
|
307 /* */ |
|
308 static char * Locale_extract_name ( const char *cname, char *into, int category ) |
|
309 { |
|
310 int i = 0; |
|
311 const char * end; |
|
312 const char* strstar = "*", *strnull = ""; |
|
313 |
|
314 if ( cname[0] != '/' ) |
|
315 { |
|
316 if (strcmp(cname,strnull) == 0) |
|
317 return strcpy(into, strstar); |
|
318 else |
|
319 return strcpy(into, cname); /* simple locale name */ |
|
320 } |
|
321 |
|
322 for ( i = 0; i <= category; i ++ ) { |
|
323 while ( *cname != '\0' && *cname != '/' ) |
|
324 cname++; |
|
325 if ( *cname == '\0' ) |
|
326 return into; |
|
327 cname++; |
|
328 } |
|
329 |
|
330 if ( *cname == '\0' ) |
|
331 return into; |
|
332 |
|
333 end = cname; |
|
334 while ( *end != '\0' && *end != '/' ) |
|
335 end++; |
|
336 |
|
337 strncpy ( into, cname, end - cname ); |
|
338 into [ end - cname ] = '\0'; |
|
339 |
|
340 return into; |
|
341 } |
|
342 |
|
343 # ifdef __cplusplus |
|
344 _STLP_BEGIN_NAMESPACE //Madhu - moved to here |
|
345 extern "C" { |
|
346 |
|
347 _Locale_mask_t Get_locale_wchar_ctype(wint_t wc, _Locale_mask_t /*mask*/) |
|
348 |
|
349 { |
|
350 _Locale_mask_t ret = 0; |
|
351 |
|
352 if (iswcntrl(wc)) ret |= _Locale_CNTRL; |
|
353 if (iswupper(wc)) ret |= _Locale_UPPER; |
|
354 if (iswlower(wc)) ret |= _Locale_LOWER; |
|
355 if (iswdigit(wc)) ret |= _Locale_DIGIT; |
|
356 if (iswxdigit(wc)) ret |= _Locale_XDIGIT; |
|
357 if (iswpunct(wc)) ret |= _Locale_PUNCT; |
|
358 if (iswspace(wc)) ret |= _Locale_SPACE; |
|
359 if (iswprint(wc)) ret |= _Locale_PRINT; |
|
360 if (iswalpha(wc)) ret |= _Locale_ALPHA; |
|
361 |
|
362 return ret; |
|
363 |
|
364 } |
|
365 |
|
366 _Locale_mask_t Get_locale_char_ctype(unsigned char c) |
|
367 |
|
368 { |
|
369 _Locale_mask_t ret = 0; |
|
370 |
|
371 if (iscntrl(c)) ret |= _Locale_CNTRL; |
|
372 if (isupper(c)) ret |= _Locale_UPPER; |
|
373 if (islower(c)) ret |= _Locale_LOWER; |
|
374 if (isdigit(c)) ret |= _Locale_DIGIT; |
|
375 if (isxdigit(c)) ret |= _Locale_XDIGIT; |
|
376 if (ispunct(c)) ret |= _Locale_PUNCT; |
|
377 if (isspace(c)) ret |= _Locale_SPACE; |
|
378 if (isprint(c)) ret |= _Locale_PRINT; |
|
379 if (isalpha(c)) ret |= _Locale_ALPHA; |
|
380 |
|
381 return ret; |
|
382 |
|
383 } |
|
384 //Madhu - locale function definitions - END |
|
385 |
|
386 |
|
387 //# ifdef __cplusplus |
|
388 //_STLP_BEGIN_NAMESPACE |
|
389 |
|
390 # define __DUMMY_PAR |
|
391 # define __DUMMY_PAR1 |
|
392 # define __DUMMY_PAR2 |
|
393 # define __DUMMY_PAR3 |
|
394 # define __DUMMY_PAR4 |
|
395 # define __DUMMY_PAR5 |
|
396 # define __DUMMY_PAR6 |
|
397 # define __DUMMY_PAR7 |
|
398 # define __DUMMY_PAR8 |
|
399 # endif |
|
400 |
|
401 void* _Locale_ctype_create(const char * name) |
|
402 { |
|
403 |
|
404 unsigned char buffer[256]; |
|
405 int i; |
|
406 _Locale_mask_t* ctable; |
|
407 |
|
408 L_ctype_t *plocCType = (L_ctype_t*) new (L_ctype_t); |
|
409 |
|
410 if (!plocCType) |
|
411 return NULL; |
|
412 |
|
413 strcpy(plocCType->name, name); |
|
414 char* ptemp = setlocale(LC_CTYPE, name); |
|
415 if (!ptemp) |
|
416 return NULL; |
|
417 ctable = plocCType->ctable; |
|
418 |
|
419 /* Partial implementation for ANSI code page, need to implement for DBCS code pages*/ |
|
420 |
|
421 /* Make table with all characters. */ |
|
422 for(i = 0; i < 256; i++) buffer[i] = i; |
|
423 |
|
424 for (i=0;i<256;i++) |
|
425 { |
|
426 |
|
427 ctable[i+1] = Get_locale_char_ctype(buffer[i]); |
|
428 } |
|
429 ctable[0] = 0; //EOF |
|
430 #ifdef CODECVT_ICONV |
|
431 plocCType->statelist = NULL; |
|
432 #endif |
|
433 return plocCType; |
|
434 } |
|
435 |
|
436 void* _Locale_numeric_create(const char *name) |
|
437 { |
|
438 L_numeric_t *plocNumeric = (L_numeric_t *)new (L_numeric_t); |
|
439 struct lconv *plconv; |
|
440 |
|
441 if (!plocNumeric) |
|
442 return NULL; |
|
443 strcpy(plocNumeric->name, name); |
|
444 |
|
445 char* ptemp = setlocale(LC_NUMERIC, name); |
|
446 if (!ptemp) |
|
447 return NULL; |
|
448 plconv = localeconv(); |
|
449 |
|
450 //copy locale numeric data to local structure |
|
451 strcpy(plocNumeric->decimal_point, plconv->decimal_point); |
|
452 plocNumeric->grouping = __getString(plconv->grouping); |
|
453 strcpy(plocNumeric->thousands_sep, plconv->thousands_sep); |
|
454 |
|
455 return plocNumeric; |
|
456 } |
|
457 |
|
458 void*_Locale_time_create(const char * name) |
|
459 { |
|
460 L_time_t *plocTime = (L_time_t *)new(L_time_t); |
|
461 //struct lconv *plconv; |
|
462 |
|
463 if (!plocTime ) |
|
464 return NULL; |
|
465 strcpy(plocTime ->name, name); |
|
466 |
|
467 char* ptemp = setlocale(LC_TIME, name); |
|
468 if (!ptemp) |
|
469 return NULL; |
|
470 //plconv = localeconv(); |
|
471 |
|
472 int i; |
|
473 int index = (MON_1); |
|
474 //Get all month names |
|
475 for (i = 0;i<12;i++,index++) |
|
476 plocTime->month[i] = __getString(nl_langinfo(index)); |
|
477 |
|
478 //Get all abbrevated month names |
|
479 index = (ABMON_1); |
|
480 for (i = 0;i<12;i++,index++) |
|
481 plocTime->abbrev_month[i] = __getString(nl_langinfo(index)); |
|
482 |
|
483 //Get all weekday names |
|
484 index = (DAY_1); |
|
485 for (i = 0;i<7;i++,index++) |
|
486 plocTime->dayofweek[i] = __getString(nl_langinfo(index)); |
|
487 |
|
488 //Get all weekday names |
|
489 index = (ABDAY_1); |
|
490 for (i = 0;i<7;i++,index++) |
|
491 plocTime->abbrev_dayofweek[i] = __getString(nl_langinfo(index)); |
|
492 |
|
493 |
|
494 return plocTime; |
|
495 } |
|
496 |
|
497 void* _Locale_collate_create(const char *name) |
|
498 { |
|
499 L_collate_t *plocCollate = (L_collate_t *)new(L_collate_t); |
|
500 |
|
501 if (!plocCollate) |
|
502 return NULL; |
|
503 strcpy(plocCollate->name, name); |
|
504 |
|
505 return plocCollate; |
|
506 } |
|
507 |
|
508 void* _Locale_monetary_create(const char * name) |
|
509 { |
|
510 L_monetary_t *plocMonetary = (L_monetary_t *)new(L_monetary_t); |
|
511 struct lconv *plconv; |
|
512 |
|
513 if (!plocMonetary) |
|
514 return NULL; |
|
515 strcpy(plocMonetary->name, name); |
|
516 |
|
517 char* ptemp = setlocale(LC_MONETARY, name); |
|
518 if (!ptemp) |
|
519 return NULL; |
|
520 plconv = localeconv(); |
|
521 |
|
522 strcpy(plocMonetary->decimal_point,plconv->mon_decimal_point); |
|
523 strcpy(plocMonetary->thousands_sep, plconv->mon_thousands_sep); |
|
524 plocMonetary->grouping = __getString(plconv->mon_grouping); |
|
525 strcpy(plocMonetary->int_curr_symbol, plconv->int_curr_symbol); // 3+1+1 |
|
526 strcpy(plocMonetary->curr_symbol, plconv->currency_symbol); |
|
527 strcpy(plocMonetary->negative_sign, plconv->negative_sign); |
|
528 strcpy(plocMonetary->positive_sign, plconv->positive_sign); |
|
529 plocMonetary->frac_digits = plconv->frac_digits; |
|
530 plocMonetary->int_frac_digits = plconv->int_frac_digits; |
|
531 |
|
532 return plocMonetary; |
|
533 } |
|
534 void* _Locale_messages_create(const char *name) |
|
535 { |
|
536 L_messages_t *plocMessages= (L_messages_t *)new(L_messages_t); |
|
537 |
|
538 if (!plocMessages) |
|
539 return NULL; |
|
540 strcpy(plocMessages->name, name); |
|
541 |
|
542 return plocMessages; |
|
543 } |
|
544 |
|
545 const char* _Locale_ctype_default(char* buff) |
|
546 { |
|
547 return Locale_common_default(buff); |
|
548 } |
|
549 |
|
550 const char* _Locale_numeric_default(char *buff) |
|
551 { |
|
552 return Locale_common_default(buff); |
|
553 } |
|
554 |
|
555 const char* _Locale_time_default(char* buff) |
|
556 { |
|
557 return Locale_common_default(buff); |
|
558 } |
|
559 |
|
560 const char* _Locale_collate_default(char* buff) |
|
561 { |
|
562 return Locale_common_default(buff); |
|
563 } |
|
564 |
|
565 const char* _Locale_monetary_default(char* buff) |
|
566 { |
|
567 return Locale_common_default(buff); |
|
568 } |
|
569 |
|
570 const char* _Locale_messages_default(char* buff) |
|
571 { |
|
572 return Locale_common_default(buff); |
|
573 } |
|
574 |
|
575 char* _Locale_ctype_name(const void* cat, char* buff) |
|
576 { |
|
577 L_ctype_t* locale = (L_ctype_t*) cat; |
|
578 strcpy(buff,locale->name); |
|
579 return buff; |
|
580 //return Locale_common_name(locale,buff); |
|
581 } |
|
582 |
|
583 char* _Locale_numeric_name(const void* cat, char* buff) |
|
584 { |
|
585 L_numeric_t* locale = (L_numeric_t*) cat; |
|
586 strcpy(buff,locale->name); |
|
587 return buff; |
|
588 //return Locale_common_name(locale,buff); |
|
589 } |
|
590 |
|
591 char* _Locale_time_name(const void* cat, char* buff) |
|
592 { |
|
593 L_time_t* locale = (L_time_t*) cat; |
|
594 strcpy(buff,locale->name); |
|
595 return buff; |
|
596 //return Locale_common_name(locale,buff); |
|
597 } |
|
598 |
|
599 char* _Locale_collate_name(const void* cat, char* buff) |
|
600 { |
|
601 L_collate_t* locale = (L_collate_t*) cat; |
|
602 strcpy(buff,locale->name); |
|
603 return buff; |
|
604 //return Locale_common_name(locale,buff); |
|
605 } |
|
606 |
|
607 char* _Locale_monetary_name(const void* cat, char* buff) |
|
608 { |
|
609 L_monetary_t* locale = (L_monetary_t*) cat; |
|
610 strcpy(buff,locale->name); |
|
611 return buff; |
|
612 //return Locale_common_name(locale,buff); |
|
613 } |
|
614 |
|
615 char* _Locale_messages_name(const void* cat, char* buff) |
|
616 { |
|
617 L_messages_t* locale = (L_messages_t*) cat; |
|
618 strcpy(buff,locale->name); |
|
619 return buff; |
|
620 //return Locale_common_name(locale,buff); |
|
621 } |
|
622 |
|
623 void _Locale_ctype_destroy(void* locale) |
|
624 { |
|
625 #ifdef CODECVT_ICONV |
|
626 DeleteAllStates(((L_ctype_t*)locale)->statelist); |
|
627 #endif |
|
628 delete((L_ctype_t*)locale); |
|
629 } |
|
630 |
|
631 void _Locale_numeric_destroy(void* locale) |
|
632 { |
|
633 delete ((L_numeric_t*)locale)->grouping; |
|
634 delete (L_numeric_t*)locale; |
|
635 } |
|
636 |
|
637 void _Locale_time_destroy(void* locale) |
|
638 { |
|
639 int i; |
|
640 L_time_t* plocTime =(L_time_t*)locale; |
|
641 //delete months |
|
642 for (i = 0;i<12;i++) |
|
643 delete (plocTime->month[i]); |
|
644 //delete abbrevated months |
|
645 for (i = 0;i<12;i++) |
|
646 delete (plocTime->abbrev_month[i]); |
|
647 //delete week day |
|
648 for (i = 0;i<7;i++) |
|
649 delete (plocTime->dayofweek[i]); |
|
650 //delete abbrevated week day |
|
651 for (i = 0;i<7;i++) |
|
652 delete (plocTime->abbrev_dayofweek[i]); |
|
653 |
|
654 delete((L_time_t*)locale); |
|
655 } |
|
656 |
|
657 void _Locale_collate_destroy(void* locale) |
|
658 { |
|
659 delete((L_collate_t*)locale); |
|
660 } |
|
661 |
|
662 void _Locale_monetary_destroy(void* locale) |
|
663 { |
|
664 delete ((L_monetary_t*)locale)->grouping; |
|
665 delete((L_monetary_t*)locale); |
|
666 } |
|
667 |
|
668 void _Locale_messages_destroy(void* locale) |
|
669 { |
|
670 delete((L_messages_t*)locale); |
|
671 } |
|
672 |
|
673 char* _Locale_extract_ctype_name(const char* cname, char* buf) |
|
674 { |
|
675 return Locale_extract_name(cname, buf, LC_CTYPE); |
|
676 } |
|
677 |
|
678 char* _Locale_extract_numeric_name(const char* cname, char* buf) |
|
679 { |
|
680 return Locale_extract_name(cname, buf, LC_NUMERIC); |
|
681 } |
|
682 |
|
683 char* _Locale_extract_time_name(const char* cname, char* buf) |
|
684 { |
|
685 return Locale_extract_name(cname, buf, LC_TIME); |
|
686 } |
|
687 |
|
688 char* _Locale_extract_collate_name(const char* cname, char* buf) |
|
689 { |
|
690 return Locale_extract_name(cname, buf, LC_COLLATE); |
|
691 } |
|
692 |
|
693 char* _Locale_extract_monetary_name(const char* cname, char* buf) |
|
694 { |
|
695 return Locale_extract_name(cname, buf, LC_MONETARY); |
|
696 } |
|
697 |
|
698 char* _Locale_extract_messages_name(const char* cname, char* buf) |
|
699 { |
|
700 return Locale_extract_name(cname, buf, LC_MESSAGES); |
|
701 } |
|
702 |
|
703 char* _Locale_compose_name(char* buf, |
|
704 const char* ctype, const char* numeric, |
|
705 const char* time, const char* collate, |
|
706 const char* monetary, const char* messages, |
|
707 const char* /*default_name*/) |
|
708 { |
|
709 |
|
710 if ( !strcmp ( ctype, numeric ) && |
|
711 !strcmp ( ctype, time ) && |
|
712 !strcmp ( ctype, collate ) && |
|
713 !strcmp ( ctype, monetary ) && |
|
714 !strcmp ( ctype, messages ) ) |
|
715 return strcpy ( buf, ctype ); |
|
716 |
|
717 strcpy ( buf, "/" ); |
|
718 strcat ( buf, ctype ); |
|
719 |
|
720 strcat ( buf, "/" ); |
|
721 strcat ( buf, numeric ); |
|
722 |
|
723 strcat ( buf, "/" ); |
|
724 strcat ( buf, time ); |
|
725 |
|
726 strcat ( buf, "/" ); |
|
727 strcat ( buf, collate ); |
|
728 |
|
729 strcat ( buf, "/" ); |
|
730 strcat ( buf, monetary ); |
|
731 |
|
732 strcat ( buf, "/" ); |
|
733 strcat ( buf, messages ); |
|
734 |
|
735 return buf; |
|
736 } |
|
737 |
|
738 |
|
739 /* ctype */ |
|
740 |
|
741 const _Locale_mask_t* _Locale_ctype_table(struct _Locale_ctype* lctype) |
|
742 { |
|
743 |
|
744 return lctype->ctable; |
|
745 } |
|
746 |
|
747 int _Locale_toupper(struct _Locale_ctype* /*lctype*/, int c) |
|
748 { |
|
749 return toupper(c); |
|
750 } |
|
751 |
|
752 int _Locale_tolower(L_ctype_t* /*lctype*/, int c) |
|
753 { |
|
754 return tolower(c); |
|
755 } |
|
756 |
|
757 #ifndef _STLP_NO_WCHAR_T |
|
758 |
|
759 _Locale_mask_t _Locale_wchar_ctype(L_ctype_t* /*lctype*/, wint_t c, _Locale_mask_t which_bits) |
|
760 { |
|
761 _Locale_mask_t mask = Get_locale_wchar_ctype(c,which_bits); |
|
762 |
|
763 return mask & which_bits; |
|
764 } |
|
765 |
|
766 wint_t _Locale_wchar_tolower(L_ctype_t* lctype, wint_t c) |
|
767 { |
|
768 setlocale(LC_CTYPE, lctype->name); |
|
769 return towlower(c); |
|
770 } |
|
771 |
|
772 wint_t _Locale_wchar_toupper(L_ctype_t* /*lctype*/, wint_t c) |
|
773 { |
|
774 return towupper(c); |
|
775 } |
|
776 |
|
777 # endif |
|
778 |
|
779 # ifndef _STLP_NO_MBSTATE_T |
|
780 |
|
781 int _Locale_mb_cur_max (L_ctype_t * /*lctype*/) |
|
782 { |
|
783 return MB_CUR_MAX; |
|
784 } |
|
785 |
|
786 int _Locale_mb_cur_min (L_ctype_t * /*lctype*/) |
|
787 { |
|
788 return 1; |
|
789 } |
|
790 |
|
791 int _Locale_is_stateless (L_ctype_t * /*lctype*/) |
|
792 { |
|
793 return (MB_CUR_MAX == 1)?1:0; |
|
794 } |
|
795 |
|
796 #ifndef _STLP_NO_WCHAR_T |
|
797 wint_t _Locale_btowc(L_ctype_t * lctype, int c) |
|
798 { |
|
799 setlocale(LC_CTYPE, lctype->name); |
|
800 return btowc(c); |
|
801 } |
|
802 |
|
803 int _Locale_wctob(L_ctype_t * lctype, wint_t wc) |
|
804 { |
|
805 setlocale(LC_CTYPE, lctype->name); |
|
806 return wctob(wc); |
|
807 } |
|
808 |
|
809 size_t _Locale_mbtowc(L_ctype_t *lctype, |
|
810 wchar_t *to, size_t n1, |
|
811 const char *from, size_t n, int* chars_write, |
|
812 mbstate_t * shift_state) |
|
813 { |
|
814 #ifdef CODECVT_ICONV |
|
815 char codeset[64] = |
|
816 { |
|
817 0 |
|
818 }; |
|
819 iconv_t state = GetState(lctype->statelist, shift_state, IN); |
|
820 if (state == NULL) |
|
821 { |
|
822 ExtractCodeset(lctype->name, codeset); |
|
823 state= iconv_open(UNICODESTR,codeset); |
|
824 if (state==NULL) |
|
825 return (size_t)-1; |
|
826 if (AddState(&lctype->statelist,state,shift_state,IN) == 0) |
|
827 return (size_t)-1; |
|
828 |
|
829 } |
|
830 char* outbuf = (char*)to; |
|
831 const char* inbuf = (char*)from; |
|
832 unsigned int inbytes = n; |
|
833 unsigned int outbytes = n1*sizeof(wchar_t); |
|
834 unsigned int chars_read = iconv((void*)state,&inbuf,&inbytes,&outbuf,&outbytes); |
|
835 *chars_write = (wchar_t*)outbuf - to; |
|
836 if (chars_read == (size_t)-1) |
|
837 { |
|
838 if ( (errno == EINVAL) || (outbuf!=(char*)to) ) |
|
839 { |
|
840 BEtoLE(to,(wchar_t*)outbuf-to); |
|
841 return inbuf-from; |
|
842 } |
|
843 |
|
844 return (size_t)-1; |
|
845 |
|
846 } |
|
847 BEtoLE(to,(wchar_t*)outbuf-to); |
|
848 //return (wchar_t*)outbuf-to; |
|
849 return inbuf-from; |
|
850 |
|
851 #else |
|
852 setlocale(LC_CTYPE, lctype->name); |
|
853 return (size_t) mbtowc(to, from,n); |
|
854 #endif |
|
855 } |
|
856 |
|
857 size_t _Locale_wctomb(L_ctype_t* lctype, |
|
858 char *to, size_t n, |
|
859 const wchar_t c, |
|
860 mbstate_t *shift_state) |
|
861 { |
|
862 #ifdef CODECVT_ICONV |
|
863 char codeset[64] = |
|
864 { |
|
865 0 |
|
866 }; |
|
867 iconv_t state = GetState(lctype->statelist, shift_state,OUT); |
|
868 if (state == NULL) |
|
869 { |
|
870 ExtractCodeset(lctype->name, codeset); |
|
871 state= iconv_open(codeset, UNICODESTR); |
|
872 if (state==NULL) |
|
873 return (size_t)-1; |
|
874 if (AddState(&lctype->statelist,state,shift_state,OUT) == 0) |
|
875 return (size_t)-1; |
|
876 |
|
877 } |
|
878 char* outbuf = to; |
|
879 const char* inbuf = (char*)&c; |
|
880 unsigned int inbytes = 2; |
|
881 unsigned int outbytes = n; |
|
882 unsigned int chars_read = iconv((void*)state,&inbuf,&inbytes,&outbuf,&outbytes); |
|
883 if (chars_read == (size_t)-1) |
|
884 { |
|
885 if (errno == EINVAL) |
|
886 return outbuf-to; |
|
887 else |
|
888 return (size_t)-1; |
|
889 |
|
890 } |
|
891 //BEtoLE(to,(wchar_t*)outbuf-to); |
|
892 return outbuf-to; |
|
893 #else |
|
894 setlocale(LC_CTYPE, lctype->name); |
|
895 return (size_t) wctomb(to, c); |
|
896 |
|
897 #endif |
|
898 } |
|
899 |
|
900 # endif |
|
901 |
|
902 //Madhu - Need to double check the implementation. |
|
903 size_t _Locale_unshift(L_ctype_t * /*lctype*/, |
|
904 mbstate_t *st, |
|
905 char *buff, size_t n, char ** next) |
|
906 { |
|
907 #if 0 |
|
908 if(*st == 0) |
|
909 { |
|
910 *next = buff; |
|
911 return 0; |
|
912 } |
|
913 else |
|
914 { |
|
915 if(n < 1) |
|
916 { |
|
917 *next = buff; |
|
918 return (size_t)-2; |
|
919 } |
|
920 |
|
921 *next = buff + 1; |
|
922 return 1; |
|
923 } |
|
924 #endif |
|
925 //Conversion is not required, because iconv will not do partial conversion. |
|
926 *next = buff; |
|
927 return 0; |
|
928 } |
|
929 |
|
930 # endif /* _STLP_NO_MBSTATE_T */ |
|
931 |
|
932 |
|
933 /* Collate */ |
|
934 int _Locale_strcmp(L_collate_t* lcol, |
|
935 const char* pStr1, size_t len1, const char* pStr2, |
|
936 size_t len2) |
|
937 { |
|
938 |
|
939 char *ptempStr1, *ptempStr2; |
|
940 int tempLen1,tempLen2; |
|
941 |
|
942 tempLen1 = _Locale_strxfrm(lcol, NULL,0,pStr1,len1); |
|
943 tempLen2 = _Locale_strxfrm(lcol, NULL,0,pStr2,len2); |
|
944 ptempStr1 = (char*) new char[tempLen1]; |
|
945 ptempStr2 = (char*) new char[tempLen2]; |
|
946 int ret; |
|
947 int minN = tempLen1 < tempLen2 ? tempLen1 : tempLen2; |
|
948 setlocale(LC_COLLATE, lcol->name); |
|
949 _Locale_strxfrm(lcol, ptempStr1,tempLen1,pStr1,len1); |
|
950 _Locale_strxfrm(lcol, ptempStr2,tempLen2,pStr2,len2); |
|
951 ret = strncmp(ptempStr1, ptempStr2, minN); |
|
952 if (ret == 0) |
|
953 { |
|
954 if (len1 < len2) |
|
955 return -1; |
|
956 else if (len1 > len2) |
|
957 return 1; |
|
958 else |
|
959 return 0; |
|
960 } else |
|
961 return ret; |
|
962 |
|
963 } |
|
964 |
|
965 # ifndef _STLP_NO_WCHAR_T |
|
966 |
|
967 int _Locale_strwcmp(L_collate_t* lcol, |
|
968 const wchar_t* pStr1, size_t len1, |
|
969 const wchar_t* pStr2, size_t len2) |
|
970 { |
|
971 wchar_t *ptempStr1, *ptempStr2; |
|
972 int tempLen1,tempLen2; |
|
973 |
|
974 tempLen1 = _Locale_strwxfrm(lcol, NULL,0,pStr1,len1); |
|
975 tempLen2 = _Locale_strwxfrm(lcol, NULL,0,pStr2,len2); |
|
976 ptempStr1 = (wchar_t*) new wchar_t[tempLen1+1]; |
|
977 ptempStr2 = (wchar_t*) new wchar_t[tempLen2+1]; |
|
978 int ret; |
|
979 int minN = tempLen1 < tempLen2 ? tempLen1 : tempLen2; |
|
980 setlocale(LC_COLLATE, lcol->name); |
|
981 _Locale_strwxfrm(lcol, ptempStr1,tempLen1,pStr1,len1); |
|
982 _Locale_strwxfrm(lcol, ptempStr2,tempLen2,pStr2,len2); |
|
983 ret = wcsncmp(ptempStr1, ptempStr2, minN); |
|
984 if (ret == 0) |
|
985 { |
|
986 if (len1 < len2) |
|
987 return -1; |
|
988 else if (len1 > len2) |
|
989 return 1; |
|
990 else |
|
991 return 0; |
|
992 } else |
|
993 return ret; |
|
994 |
|
995 |
|
996 } |
|
997 |
|
998 # endif |
|
999 |
|
1000 size_t _Locale_strxfrm(L_collate_t* lcol, |
|
1001 char* pDestStr, size_t destLen, |
|
1002 const char* pSrcStr, size_t srcLen) |
|
1003 { |
|
1004 size_t n; |
|
1005 setlocale(LC_COLLATE, lcol->name); |
|
1006 |
|
1007 char* ptemp = (char*) new char[srcLen+1]; |
|
1008 if(ptemp == NULL) |
|
1009 return 0; |
|
1010 memmove(ptemp,pSrcStr,srcLen); |
|
1011 *(ptemp+srcLen) = 0; |
|
1012 |
|
1013 n = strxfrm(pDestStr, ptemp, destLen); |
|
1014 |
|
1015 delete []ptemp; |
|
1016 |
|
1017 if ((pDestStr == NULL) || (destLen ==0) ) |
|
1018 return n; |
|
1019 else if(n > destLen) |
|
1020 return (size_t)-1; |
|
1021 |
|
1022 pDestStr[n] = 0; |
|
1023 return n; |
|
1024 } |
|
1025 |
|
1026 # ifndef _STLP_NO_WCHAR_T |
|
1027 |
|
1028 size_t _Locale_strwxfrm(L_collate_t* lcol, |
|
1029 wchar_t* pDestStr, size_t destLen, |
|
1030 const wchar_t* pSrcStr, size_t srcLen) |
|
1031 { |
|
1032 size_t n; |
|
1033 setlocale(LC_COLLATE, lcol->name); |
|
1034 wchar_t* ptemp = (wchar_t*) new wchar_t[srcLen+1]; |
|
1035 if(ptemp == NULL) |
|
1036 return 0; |
|
1037 memmove(ptemp,pSrcStr,srcLen*sizeof(wchar_t)); |
|
1038 *(ptemp+srcLen) = 0; |
|
1039 n = wcsxfrm(pDestStr, ptemp, destLen); |
|
1040 |
|
1041 delete []ptemp; |
|
1042 if ((pDestStr == NULL) || (destLen ==0) ) |
|
1043 return n; |
|
1044 else if(n > destLen) |
|
1045 return (size_t)-1; |
|
1046 |
|
1047 pDestStr[n] = 0; |
|
1048 return n; |
|
1049 } |
|
1050 |
|
1051 # endif |
|
1052 |
|
1053 /* Numeric */ |
|
1054 |
|
1055 char _Locale_decimal_point(L_numeric_t* lnum) |
|
1056 { |
|
1057 |
|
1058 return lnum->decimal_point[0]; |
|
1059 } |
|
1060 |
|
1061 char _Locale_thousands_sep(L_numeric_t* lnum) |
|
1062 { |
|
1063 |
|
1064 return lnum->thousands_sep[0]; |
|
1065 } |
|
1066 const char* _Locale_grouping(L_numeric_t*lnum) |
|
1067 { |
|
1068 |
|
1069 return lnum->grouping; |
|
1070 } |
|
1071 |
|
1072 const char * _Locale_true(L_numeric_t * /*lnum*/) |
|
1073 { |
|
1074 const char* __true_name="true"; //glib and NT doing the same |
|
1075 |
|
1076 |
|
1077 return __true_name; |
|
1078 } |
|
1079 |
|
1080 const char * _Locale_false(L_numeric_t * /*lnum*/) |
|
1081 { |
|
1082 const char* __false_name="false"; //glib and NT doing the same |
|
1083 |
|
1084 return __false_name; |
|
1085 } |
|
1086 |
|
1087 |
|
1088 /* Monetary */ |
|
1089 |
|
1090 const char* _Locale_int_curr_symbol(L_monetary_t * lmon) |
|
1091 { |
|
1092 |
|
1093 return lmon->int_curr_symbol; |
|
1094 } |
|
1095 |
|
1096 const char* _Locale_currency_symbol(L_monetary_t * lmon) |
|
1097 { |
|
1098 |
|
1099 return lmon->curr_symbol; |
|
1100 } |
|
1101 |
|
1102 char _Locale_mon_decimal_point(L_monetary_t * lmon) |
|
1103 { |
|
1104 return lmon->decimal_point[0]; |
|
1105 } |
|
1106 |
|
1107 char _Locale_mon_thousands_sep(L_monetary_t * lmon) |
|
1108 { |
|
1109 |
|
1110 return lmon->thousands_sep[0]; |
|
1111 } |
|
1112 |
|
1113 const char* _Locale_mon_grouping(L_monetary_t * lmon) |
|
1114 { |
|
1115 |
|
1116 return lmon->grouping; |
|
1117 } |
|
1118 |
|
1119 const char* _Locale_positive_sign(L_monetary_t * lmon) |
|
1120 { |
|
1121 |
|
1122 return lmon->positive_sign; |
|
1123 } |
|
1124 |
|
1125 const char* _Locale_negative_sign(L_monetary_t * lmon) |
|
1126 { |
|
1127 |
|
1128 return lmon->negative_sign; |
|
1129 } |
|
1130 |
|
1131 char _Locale_int_frac_digits(L_monetary_t * lmon) |
|
1132 { |
|
1133 |
|
1134 return lmon->int_frac_digits; |
|
1135 } |
|
1136 |
|
1137 char _Locale_frac_digits(L_monetary_t * lmon) |
|
1138 { |
|
1139 |
|
1140 return lmon->frac_digits; |
|
1141 } |
|
1142 |
|
1143 int _Locale_p_cs_precedes(L_monetary_t * lmon) |
|
1144 { |
|
1145 struct lconv* plconv; |
|
1146 setlocale(LC_MONETARY, lmon->name); |
|
1147 plconv = localeconv(); |
|
1148 |
|
1149 return plconv->p_cs_precedes; |
|
1150 } |
|
1151 |
|
1152 int _Locale_p_sep_by_space(L_monetary_t * lmon) |
|
1153 { |
|
1154 struct lconv* plconv; |
|
1155 setlocale(LC_MONETARY, lmon->name); |
|
1156 plconv = localeconv(); |
|
1157 |
|
1158 return plconv->p_sep_by_space; |
|
1159 } |
|
1160 |
|
1161 int _Locale_p_sign_posn(L_monetary_t * lmon) |
|
1162 { |
|
1163 struct lconv* plconv; |
|
1164 setlocale(LC_MONETARY, lmon->name); |
|
1165 plconv = localeconv(); |
|
1166 |
|
1167 return plconv->p_sign_posn; |
|
1168 } |
|
1169 |
|
1170 int _Locale_n_cs_precedes(L_monetary_t * lmon) |
|
1171 { |
|
1172 struct lconv* plconv; |
|
1173 setlocale(LC_MONETARY, lmon->name); |
|
1174 plconv = localeconv(); |
|
1175 |
|
1176 return plconv->n_cs_precedes; |
|
1177 } |
|
1178 |
|
1179 int _Locale_n_sep_by_space(L_monetary_t * lmon) |
|
1180 { |
|
1181 struct lconv* plconv; |
|
1182 setlocale(LC_MONETARY, lmon->name); |
|
1183 plconv = localeconv(); |
|
1184 |
|
1185 return plconv->n_sep_by_space; |
|
1186 } |
|
1187 |
|
1188 int _Locale_n_sign_posn(L_monetary_t * lmon) |
|
1189 { |
|
1190 struct lconv* plconv; |
|
1191 setlocale(LC_MONETARY, lmon->name); |
|
1192 plconv = localeconv(); |
|
1193 |
|
1194 return plconv->n_sign_posn; |
|
1195 } |
|
1196 |
|
1197 |
|
1198 /* Time */ |
|
1199 const char * _Locale_full_monthname(L_time_t * ltime, int month) |
|
1200 { |
|
1201 |
|
1202 return ltime->month[month]; |
|
1203 } |
|
1204 |
|
1205 const char * _Locale_abbrev_monthname(L_time_t * ltime, int month) |
|
1206 { |
|
1207 |
|
1208 return ltime->abbrev_month[month]; |
|
1209 } |
|
1210 |
|
1211 const char * _Locale_full_dayofweek(L_time_t * ltime, int day) |
|
1212 { |
|
1213 |
|
1214 return ltime->dayofweek[day]; |
|
1215 } |
|
1216 |
|
1217 const char * _Locale_abbrev_dayofweek(L_time_t * ltime, int day) |
|
1218 { |
|
1219 |
|
1220 return ltime->abbrev_dayofweek[day]; |
|
1221 } |
|
1222 |
|
1223 const char* _Locale_d_t_fmt(L_time_t* ltime) |
|
1224 { |
|
1225 setlocale(LC_TIME, ltime->name); |
|
1226 return nl_langinfo(D_T_FMT); |
|
1227 } |
|
1228 |
|
1229 const char* _Locale_d_fmt(L_time_t* ltime) |
|
1230 { |
|
1231 setlocale(LC_TIME, ltime->name); |
|
1232 return nl_langinfo(D_FMT); |
|
1233 } |
|
1234 |
|
1235 const char* _Locale_t_fmt(L_time_t* ltime) |
|
1236 { |
|
1237 setlocale(LC_TIME, ltime->name); |
|
1238 return nl_langinfo(T_FMT); |
|
1239 } |
|
1240 |
|
1241 const char* _Locale_long_d_t_fmt(L_time_t* ltime) |
|
1242 { |
|
1243 setlocale(LC_TIME, ltime->name); |
|
1244 return nl_langinfo(D_T_FMT); //Madhu--now same as D_T_FMT, need to check |
|
1245 } |
|
1246 |
|
1247 const char* _Locale_long_d_fmt(L_time_t* ltime) |
|
1248 { |
|
1249 setlocale(LC_TIME, ltime->name); |
|
1250 return nl_langinfo(D_FMT); //Madhu--now same as D_FMT, need to check |
|
1251 } |
|
1252 const char* _Locale_am_str(L_time_t* ltime) |
|
1253 { |
|
1254 setlocale(LC_TIME, ltime->name); |
|
1255 return nl_langinfo(AM_STR); |
|
1256 } |
|
1257 |
|
1258 const char* _Locale_pm_str(L_time_t* ltime) |
|
1259 { |
|
1260 setlocale(LC_TIME, ltime->name); |
|
1261 return nl_langinfo(PM_STR); |
|
1262 } |
|
1263 |
|
1264 const char* _Locale_t_fmt_ampm(L_time_t* ltime) |
|
1265 { |
|
1266 setlocale(LC_TIME, ltime->name); |
|
1267 return nl_langinfo(T_FMT_AMPM); |
|
1268 } |
|
1269 |
|
1270 /* Messages */ // Madhu - support after libc team supported. |
|
1271 |
|
1272 |
|
1273 |
|
1274 int _Locale_catopen(L_messages_t* lmessage, const char* catalogName) |
|
1275 { |
|
1276 lmessage->domain = __getString((char*)catalogName); |
|
1277 return 1;//catopen(catalogName,/*NL_CAT_LOCALE*/1); |
|
1278 } |
|
1279 |
|
1280 void _Locale_catclose(L_messages_t* lmessage, int /*catalog_desc*/) |
|
1281 { |
|
1282 //setlocale(LC_MESSAGES, lmessage->name); |
|
1283 delete(lmessage->domain); |
|
1284 lmessage->domain = NULL; |
|
1285 //catclose(catalog_desc); |
|
1286 |
|
1287 } |
|
1288 |
|
1289 const char* _Locale_catgets(L_messages_t* lmessage, int /*catalog_desc*/, |
|
1290 int /*set*/, int /*message*/, |
|
1291 const char *dfault) |
|
1292 { |
|
1293 char* locale = setlocale(LC_ALL, lmessage->name); |
|
1294 #ifdef _MESSAGE_CATALOG_ |
|
1295 textdomain(lmessage->domain); |
|
1296 |
|
1297 return gettext(dfault); |
|
1298 #else |
|
1299 return NULL; |
|
1300 #endif |
|
1301 |
|
1302 } |
|
1303 |
|
1304 #ifdef __cplusplus |
|
1305 } /* extern C */ |
|
1306 _STLP_END_NAMESPACE |
|
1307 #endif |
|
1308 |
|
1309 #endif /* real locale */ |