Update contrib.
1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // Name : c_locale_libc.cpp
15 // Part of : libstdcpp
16 // Adaptation layer to get locale functionality.
18 // This material, including documentation and any related
19 // computer programs, is protected by copyright controlled by
20 // Nokia Corporation. All rights are reserved. Copying,
21 // including reproducing, storing, adapting or translating, any
22 // or all of this material requires the prior written consent of
23 // Nokia Corporation. This material also contains confidential
24 // information which may not be disclosed to others without the
25 // prior written consent of Nokia Corporation.
30 //#include "stlport_prefix.h"
41 #ifdef _MESSAGE_CATALOG_
45 #define LOCALE_SYSTEM_DEFAULT "C"
46 #define MAX_NAME_LEN 30
48 #if (defined (__GNUC__) || defined (_KCC) || defined(__ICC)) && (!defined (__SYMBIAN32__))
49 typedef unsigned short int _Locale_mask_t;
51 typedef unsigned int _Locale_mask_t;
54 typedef struct _Locale_ctype {
55 char name[MAX_NAME_LEN];
56 _Locale_mask_t ctable[257];
60 typedef struct _Locale_numeric {
61 char name[MAX_NAME_LEN];
62 char decimal_point[4];
63 char thousands_sep[4];
67 typedef struct _Locale_time {
68 char name[MAX_NAME_LEN];
70 char *abbrev_month[12];
72 char *abbrev_dayofweek[7];
75 typedef struct _Locale_collate {
76 char name[MAX_NAME_LEN];
79 typedef struct _Locale_monetary {
80 char name[MAX_NAME_LEN];
81 char decimal_point[4];
82 char thousands_sep[4];
84 char int_curr_symbol[5]; // 3+1+1
86 char negative_sign[5];
87 char positive_sign[5];
92 typedef struct _Locale_messages {
93 char name[MAX_NAME_LEN];
97 char* __getString(char* str)
99 int len = strlen(str)+1;
100 char* temp = (char*) new char[len];
107 size_t _Locale_strxfrm(L_collate_t* lcol, char* pDestStr, size_t destLen,
108 const char* pSrcStr, size_t srcLen);
110 size_t _Locale_strwxfrm(L_collate_t* lcol, wchar_t* pDestStr, size_t destLen,
111 const wchar_t* pSrcStr, size_t srcLen);
119 /* Gets the system locale name */
120 static const char* Locale_common_default( char* name)
124 strcpy(name,LOCALE_SYSTEM_DEFAULT);
126 return LOCALE_SYSTEM_DEFAULT;
130 static char * Locale_extract_name ( const char *cname, char *into, int category )
134 const char* strstar = "*", *strnull = "";
135 if ( cname[0] != '/' )
137 if (strcmp(cname,strnull) == 0)
138 return strcpy(into, strstar);
140 return strcpy(into, cname); /* simple locale name */
143 for ( i = 0; i <= category; i ++ ) {
144 while ( *cname != '\0' && *cname != '/' )
146 if ( *cname == '\0' )
151 if ( *cname == '\0' )
155 while ( *end != '\0' && *end != '/' )
157 strncpy ( into, cname, end - cname );
158 into [ end - cname ] = '\0';
162 _Locale_mask_t Get_locale_wchar_ctype(wint_t wc, _Locale_mask_t /*mask*/)
164 _Locale_mask_t ret = 0;
166 if (iswcntrl(wc)) ret |= _Locale_CNTRL;
167 if (iswupper(wc)) ret |= _Locale_UPPER;
168 if (iswlower(wc)) ret |= _Locale_LOWER;
169 if (iswdigit(wc)) ret |= _Locale_DIGIT;
170 if (iswxdigit(wc)) ret |= _Locale_XDIGIT;
171 if (iswpunct(wc)) ret |= _Locale_PUNCT;
172 if (iswspace(wc)) ret |= _Locale_SPACE;
173 if (iswprint(wc)) ret |= _Locale_PRINT;
174 if (iswalpha(wc)) ret |= _Locale_ALPHA;
178 _Locale_mask_t Get_locale_char_ctype(unsigned char c)
180 _Locale_mask_t ret = 0;
182 if (iscntrl(c)) ret |= _Locale_CNTRL;
183 if (isupper(c)) ret |= _Locale_UPPER;
184 if (islower(c)) ret |= _Locale_LOWER;
185 if (isdigit(c)) ret |= _Locale_DIGIT;
186 if (isxdigit(c)) ret |= _Locale_XDIGIT;
187 if (ispunct(c)) ret |= _Locale_PUNCT;
188 if (isspace(c)) ret |= _Locale_SPACE;
189 if (isprint(c)) ret |= _Locale_PRINT;
190 if (isalpha(c)) ret |= _Locale_ALPHA;
196 void* _Locale_ctype_create(const char * name, struct _Locale_name_hint* /*hint*/)
198 unsigned char buffer[256];
200 _Locale_mask_t* ctable;
202 L_ctype_t *plocCType = new (L_ctype_t);
206 strcpy(plocCType->name, name);
207 char* ptemp = setlocale(LC_CTYPE, name);
211 ctable = plocCType->ctable;
213 /* Partial implementation for ANSI code page, need to implement for DBCS code pages*/
215 /* Make table with all characters. */
216 for(i = 0; i < 256; i++)
222 ctable[i+1] = Get_locale_char_ctype(buffer[i]);
228 void* _Locale_numeric_create(const char *name, struct _Locale_name_hint* /*hint*/)
230 L_numeric_t *plocNumeric = new (L_numeric_t);
231 struct lconv *plconv;
236 strcpy(plocNumeric->name, name);
237 char* ptemp = setlocale(LC_NUMERIC, name);
241 plconv = localeconv();
243 //copy locale numeric data to local structure
244 plocNumeric->grouping = __getString(plconv->grouping);
245 strcpy(plocNumeric->decimal_point, plconv->decimal_point);
246 strcpy(plocNumeric->thousands_sep, plconv->thousands_sep);
251 void*_Locale_time_create(const char * name, struct _Locale_name_hint* /*hint*/)
253 L_time_t *plocTime = new(L_time_t);
258 strcpy(plocTime ->name, name);
259 char* ptemp = setlocale(LC_TIME, name);
265 //Get all month names
267 for (i = 0;i<12;i++,index++)
268 plocTime->month[i] = __getString(nl_langinfo(index));
270 //Get all abbrevated month names
272 for (i = 0;i<12;i++,index++)
273 plocTime->abbrev_month[i] = __getString(nl_langinfo(index));
275 //Get all weekday names
277 for (i = 0;i<7;i++,index++)
278 plocTime->dayofweek[i] = __getString(nl_langinfo(index));
280 //Get all weekday names
282 for (i = 0;i<7;i++,index++)
283 plocTime->abbrev_dayofweek[i] = __getString(nl_langinfo(index));
288 void* _Locale_collate_create(const char *name, struct _Locale_name_hint* /*hint*/)
290 L_collate_t *plocCollate = new(L_collate_t);
295 char* ptemp = setlocale(LC_COLLATE, name);
299 strcpy(plocCollate->name, name);
303 void* _Locale_monetary_create(const char * name, struct _Locale_name_hint* /*hint*/)
305 L_monetary_t *plocMonetary = new(L_monetary_t);
306 struct lconv *plconv;
311 strcpy(plocMonetary->name, name);
312 char* ptemp = setlocale(LC_MONETARY, name);
316 plconv = localeconv();
318 strcpy(plocMonetary->decimal_point,plconv->mon_decimal_point);
319 strcpy(plocMonetary->thousands_sep, plconv->mon_thousands_sep);
320 strcpy(plocMonetary->int_curr_symbol, plconv->int_curr_symbol);
321 strcpy(plocMonetary->curr_symbol, plconv->currency_symbol);
322 strcpy(plocMonetary->negative_sign, plconv->negative_sign);
323 strcpy(plocMonetary->positive_sign, plconv->positive_sign);
324 plocMonetary->grouping = __getString(plconv->mon_grouping);
325 plocMonetary->frac_digits = plconv->frac_digits;
326 plocMonetary->int_frac_digits = plconv->int_frac_digits;
331 void* _Locale_messages_create(const char *name, struct _Locale_name_hint* /*hint*/)
333 L_messages_t *plocMessages= new(L_messages_t);
338 char* ptemp = setlocale(LC_MESSAGES, name);
342 strcpy(plocMessages->name, name);
346 const char* _Locale_ctype_default(char* buff)
348 return Locale_common_default(buff);
351 const char* _Locale_numeric_default(char *buff)
353 return Locale_common_default(buff);
356 const char* _Locale_time_default(char* buff)
358 return Locale_common_default(buff);
361 const char* _Locale_collate_default(char* buff)
363 return Locale_common_default(buff);
366 const char* _Locale_monetary_default(char* buff)
368 return Locale_common_default(buff);
371 const char* _Locale_messages_default(char* buff)
373 return Locale_common_default(buff);
376 char const* _Locale_ctype_name(const void* cat, char* buff)
378 strcpy(buff, ((L_ctype_t*)cat)->name);
382 char const* _Locale_numeric_name(const void* cat, char* buff)
384 strcpy(buff, ((L_numeric_t*)cat)->name);
388 char const* _Locale_time_name(const void* cat, char* buff)
390 strcpy(buff, ((L_time_t*)cat)->name);
394 char const* _Locale_collate_name(const void* cat, char* buff)
396 strcpy(buff, ((L_collate_t*)cat)->name);
400 char const* _Locale_monetary_name(const void* cat, char* buff)
402 strcpy(buff, ((L_monetary_t*)cat)->name);
406 char const* _Locale_messages_name(const void* cat, char* buff)
408 strcpy(buff, ((L_messages_t*)cat)->name);
412 void _Locale_ctype_destroy(void* locale)
414 delete((L_ctype_t*)locale);
417 void _Locale_numeric_destroy(void* locale)
419 delete ((L_numeric_t*)locale)->grouping;
420 delete (L_numeric_t*)locale;
423 void _Locale_time_destroy(void* locale)
426 L_time_t* plocTime =(L_time_t*)locale;
430 delete (plocTime->month[i]);
432 //delete abbrevated months
434 delete (plocTime->abbrev_month[i]);
438 delete (plocTime->dayofweek[i]);
440 //delete abbrevated week day
442 delete (plocTime->abbrev_dayofweek[i]);
444 delete((L_time_t*)locale);
447 void _Locale_collate_destroy(void* locale)
449 delete((L_collate_t*)locale);
452 void _Locale_monetary_destroy(void* locale)
454 delete ((L_monetary_t*)locale)->grouping;
455 delete((L_monetary_t*)locale);
458 void _Locale_messages_destroy(void* locale)
460 delete((L_messages_t*)locale);
463 char const* _Locale_extract_ctype_name(const char* cname, char* buf, struct _Locale_name_hint* /*__hint*/)
465 return Locale_extract_name(cname, buf, LC_CTYPE);
468 char const* _Locale_extract_numeric_name(const char* cname, char* buf, struct _Locale_name_hint* /*__hint*/)
470 return Locale_extract_name(cname, buf, LC_NUMERIC);
473 char const* _Locale_extract_time_name(const char* cname, char* buf, struct _Locale_name_hint* /*__hint*/)
475 return Locale_extract_name(cname, buf, LC_TIME);
478 char const* _Locale_extract_collate_name(const char* cname, char* buf, struct _Locale_name_hint* /*__hint*/)
480 return Locale_extract_name(cname, buf, LC_COLLATE);
483 char const* _Locale_extract_monetary_name(const char* cname, char* buf, struct _Locale_name_hint* /*__hint*/)
485 return Locale_extract_name(cname, buf, LC_MONETARY);
488 char const* _Locale_extract_messages_name(const char* cname, char* buf, struct _Locale_name_hint* /*__hint*/)
490 return Locale_extract_name(cname, buf, LC_MESSAGES);
493 const char* _Locale_compose_name(char* buf,
494 const char* ctype, const char* numeric,
495 const char* time, const char* collate,
496 const char* monetary, const char* messages,
497 const char* /*default_name*/)
500 if ( !strcmp ( ctype, numeric ) &&
501 !strcmp ( ctype, time ) &&
502 !strcmp ( ctype, collate ) &&
503 !strcmp ( ctype, monetary ) &&
504 !strcmp ( ctype, messages ) )
505 return strcpy ( buf, ctype );
508 strcat ( buf, ctype );
511 strcat ( buf, numeric );
514 strcat ( buf, time );
517 strcat ( buf, collate );
520 strcat ( buf, monetary );
523 strcat ( buf, messages );
528 struct _Locale_name_hint* _Locale_get_ctype_hint(struct _Locale_ctype* /*ctype*/)
530 struct _Locale_name_hint* _Locale_get_numeric_hint(struct _Locale_numeric* /*numeric*/)
532 struct _Locale_name_hint* _Locale_get_time_hint(struct _Locale_time* /*time*/)
534 struct _Locale_name_hint* _Locale_get_collate_hint(struct _Locale_collate* /*collate*/)
536 struct _Locale_name_hint* _Locale_get_monetary_hint(struct _Locale_monetary* /*monetary*/)
538 struct _Locale_name_hint* _Locale_get_messages_hint(struct _Locale_messages* /*messages*/)
543 const _Locale_mask_t* _Locale_ctype_table(struct _Locale_ctype* lctype)
545 return lctype->ctable;
548 int _Locale_toupper(struct _Locale_ctype* /*lctype*/, int c)
553 int _Locale_tolower(L_ctype_t* /*lctype*/, int c)
558 _Locale_mask_t _Locale_wchar_ctype(L_ctype_t* /*lctype*/, wint_t c, _Locale_mask_t which_bits)
560 _Locale_mask_t mask = Get_locale_wchar_ctype(c,which_bits);
561 return mask & which_bits;
564 wint_t _Locale_wchar_tolower(L_ctype_t* /*lctype*/, wint_t c)
569 wint_t _Locale_wchar_toupper(L_ctype_t* /*lctype*/, wint_t c)
574 int _Locale_mb_cur_max (L_ctype_t * /*lctype*/)
579 int _Locale_mb_cur_min (L_ctype_t * /*lctype*/)
584 int _Locale_is_stateless (L_ctype_t * /*lctype*/)
586 return (MB_CUR_MAX == 1)?1:0;
589 wint_t _Locale_btowc(L_ctype_t * lctype, int c)
591 setlocale(LC_CTYPE, lctype->name);
595 int _Locale_wctob(L_ctype_t * lctype, wint_t wc)
597 setlocale(LC_CTYPE, lctype->name);
601 size_t _Locale_mbtowc(struct _Locale_ctype *lctype,
602 wchar_t *to, /* size_t n1 - removed in 5.x? */
603 const char *from, size_t n,
604 mbstate_t * /*shift_state*/)
606 setlocale(LC_CTYPE, lctype->name);
607 return (size_t) mbtowc(to, from,n);
610 size_t _Locale_wctomb(L_ctype_t* lctype,
611 char *to, size_t /*n*/,
613 mbstate_t */*shift_state*/)
615 setlocale(LC_CTYPE, lctype->name);
616 return (size_t) wctomb(to, c);
620 size_t _Locale_unshift(L_ctype_t * /*lctype*/,
622 char *buff, size_t /*n*/, char ** next)
624 //Conversion is not required, because iconv will not do partial conversion.
631 int _Locale_strcmp(L_collate_t* lcol,
632 const char* pStr1, size_t len1, const char* pStr2,
636 char *ptempStr1 = NULL, *ptempStr2 = NULL;
637 int tempLen1, tempLen2;
639 tempLen1 = _Locale_strxfrm(lcol, NULL, 0, pStr1, len1);
640 tempLen2 = _Locale_strxfrm(lcol, NULL, 0, pStr2, len2);
641 ptempStr1 = (char*) new char[tempLen1+1];
642 ptempStr2 = (char*) new char[tempLen2+1];
644 int minN = tempLen1 < tempLen2 ? tempLen1 : tempLen2;
645 setlocale(LC_COLLATE, lcol->name);
646 _Locale_strxfrm(lcol, ptempStr1, tempLen1, pStr1, len1);
647 _Locale_strxfrm(lcol, ptempStr2, tempLen2, pStr2, len2);
648 ret = strncmp(ptempStr1, ptempStr2, minN);
657 else if (len1 > len2)
667 int _Locale_strwcmp(L_collate_t* lcol,
668 const wchar_t* pStr1, size_t len1,
669 const wchar_t* pStr2, size_t len2)
671 wchar_t *ptempStr1 = NULL, *ptempStr2 = NULL;
672 int tempLen1,tempLen2;
674 tempLen1 = _Locale_strwxfrm(lcol, NULL,0,pStr1,len1);
675 tempLen2 = _Locale_strwxfrm(lcol, NULL,0,pStr2,len2);
676 ptempStr1 = (wchar_t*) new wchar_t[tempLen1+1];
677 ptempStr2 = (wchar_t*) new wchar_t[tempLen2+1];
679 int minN = tempLen1 < tempLen2 ? tempLen1 : tempLen2;
680 setlocale(LC_COLLATE, lcol->name);
681 _Locale_strwxfrm(lcol, ptempStr1,tempLen1+1,pStr1,len1);
682 _Locale_strwxfrm(lcol, ptempStr2,tempLen2+1,pStr2,len2);
683 ret = wcsncmp(ptempStr1, ptempStr2, minN);
692 else if (len1 > len2)
701 size_t _Locale_strxfrm(L_collate_t* lcol,
702 char* pDestStr, size_t destLen,
703 const char* pSrcStr, size_t srcLen)
706 setlocale(LC_COLLATE, lcol->name);
708 char* ptemp = (char*) new char[srcLen+1];
711 strncpy(ptemp, pSrcStr, srcLen);
712 *(ptemp + srcLen) = 0;
714 n = strxfrm(pDestStr, ptemp, destLen);
718 if ((pDestStr == NULL) || (destLen ==0) )
727 size_t _Locale_strwxfrm(L_collate_t* lcol,
728 wchar_t* pDestStr, size_t destLen,
729 const wchar_t* pSrcStr, size_t srcLen)
732 setlocale(LC_COLLATE, lcol->name);
733 wchar_t* ptemp = (wchar_t*) new wchar_t[srcLen+1];
736 wcsncpy(ptemp, pSrcStr, srcLen);
738 n = wcsxfrm(pDestStr, ptemp, destLen);
740 if ((pDestStr == NULL) || (destLen ==0) )
751 char _Locale_decimal_point(L_numeric_t* lnum)
753 return lnum->decimal_point[0];
756 char _Locale_thousands_sep(L_numeric_t* lnum)
758 return lnum->thousands_sep[0];
760 const char* _Locale_grouping(L_numeric_t*lnum)
762 return lnum->grouping;
765 const char * _Locale_true(L_numeric_t * /*lnum*/)
767 const char* __true_name="true"; //glib and NT doing the same
771 const char * _Locale_false(L_numeric_t * /*lnum*/)
773 const char* __false_name="false"; //glib and NT doing the same
780 const char* _Locale_int_curr_symbol(L_monetary_t * lmon)
782 return lmon->int_curr_symbol;
785 const char* _Locale_currency_symbol(L_monetary_t * lmon)
787 return lmon->curr_symbol;
790 char _Locale_mon_decimal_point(L_monetary_t * lmon)
792 return lmon->decimal_point[0];
795 char _Locale_mon_thousands_sep(L_monetary_t * lmon)
797 return lmon->thousands_sep[0];
800 const char* _Locale_mon_grouping(L_monetary_t * lmon)
802 return lmon->grouping;
805 const char* _Locale_positive_sign(L_monetary_t * lmon)
807 return lmon->positive_sign;
810 const char* _Locale_negative_sign(L_monetary_t * lmon)
812 return lmon->negative_sign;
815 char _Locale_int_frac_digits(L_monetary_t * lmon)
817 return lmon->int_frac_digits;
820 char _Locale_frac_digits(L_monetary_t * lmon)
822 return lmon->frac_digits;
825 int _Locale_p_cs_precedes(L_monetary_t * lmon)
827 struct lconv* plconv;
828 setlocale(LC_MONETARY, lmon->name);
829 plconv = localeconv();
830 return plconv->p_cs_precedes;
833 int _Locale_p_sep_by_space(L_monetary_t * lmon)
835 struct lconv* plconv;
836 setlocale(LC_MONETARY, lmon->name);
837 plconv = localeconv();
838 return plconv->p_sep_by_space;
841 int _Locale_p_sign_posn(L_monetary_t * lmon)
843 struct lconv* plconv;
844 setlocale(LC_MONETARY, lmon->name);
845 plconv = localeconv();
846 return plconv->p_sign_posn;
849 int _Locale_n_cs_precedes(L_monetary_t * lmon)
851 struct lconv* plconv;
852 setlocale(LC_MONETARY, lmon->name);
853 plconv = localeconv();
854 return plconv->n_cs_precedes;
857 int _Locale_n_sep_by_space(L_monetary_t * lmon)
859 struct lconv* plconv;
860 setlocale(LC_MONETARY, lmon->name);
861 plconv = localeconv();
862 return plconv->n_sep_by_space;
865 int _Locale_n_sign_posn(L_monetary_t * lmon)
867 struct lconv* plconv;
868 setlocale(LC_MONETARY, lmon->name);
869 plconv = localeconv();
870 return plconv->n_sign_posn;
874 const char * _Locale_full_monthname(L_time_t * ltime, int month)
876 return ltime->month[month];
879 const char * _Locale_abbrev_monthname(L_time_t * ltime, int month)
881 return ltime->abbrev_month[month];
884 const char * _Locale_full_dayofweek(L_time_t * ltime, int day)
886 return ltime->dayofweek[day];
889 const char * _Locale_abbrev_dayofweek(L_time_t * ltime, int day)
891 return ltime->abbrev_dayofweek[day];
894 const char* _Locale_d_t_fmt(L_time_t* ltime)
896 setlocale(LC_TIME, ltime->name);
897 return nl_langinfo(D_T_FMT);
900 const char* _Locale_d_fmt(L_time_t* ltime)
902 setlocale(LC_TIME, ltime->name);
903 return nl_langinfo(D_FMT);
906 const char* _Locale_t_fmt(L_time_t* ltime)
908 setlocale(LC_TIME, ltime->name);
909 return nl_langinfo(T_FMT);
912 const char* _Locale_long_d_t_fmt(L_time_t* ltime)
914 setlocale(LC_TIME, ltime->name);
915 return nl_langinfo(D_T_FMT);
918 const char* _Locale_long_d_fmt(L_time_t* ltime)
920 setlocale(LC_TIME, ltime->name);
921 return nl_langinfo(D_FMT);
924 const char* _Locale_am_str(L_time_t* ltime)
926 setlocale(LC_TIME, ltime->name);
927 return nl_langinfo(AM_STR);
930 const char* _Locale_pm_str(L_time_t* ltime)
932 setlocale(LC_TIME, ltime->name);
933 return nl_langinfo(PM_STR);
936 const char* _Locale_t_fmt_ampm(L_time_t* ltime)
938 setlocale(LC_TIME, ltime->name);
939 return nl_langinfo(T_FMT_AMPM);
944 nl_catd_type _Locale_catopen(struct _Locale_messages* lmessage, const char* catalogName)
946 lmessage->domain = __getString((char*)catalogName);
950 void _Locale_catclose(struct _Locale_messages* lmessage, nl_catd_type /*catalog_desc*/)
952 delete(lmessage->domain);
953 lmessage->domain = NULL;
956 const char* _Locale_catgets(struct _Locale_messages* lmessage, nl_catd_type /*catalog_desc*/,
957 int /*set*/, int /*message*/,
958 const char * /*dfault*/)
960 char* locale = setlocale(LC_ALL, lmessage->name);
961 #ifdef _MESSAGE_CATALOG_
962 textdomain(lmessage->domain);
964 return gettext(dfault);