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