genericopenlibs/openenvcore/libc/src/setlocale.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     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"