os/ossrv/genericopenlibs/openenvcore/libc/src/setlocale.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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"