sl@0: /* sl@0: * Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: Contains the source for setting the locale sl@0: * sl@0: * sl@0: */ sl@0: sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include <_ansi.h> sl@0: #include "lmonetary.h" sl@0: #include "lnumeric.h" sl@0: #include "timelocal.h" sl@0: #include "localeinfo.h" sl@0: sl@0: #if (defined(__SYMBIAN32__) && (defined(__WINSCW__) || defined(__WINS__))) sl@0: #include "libc_wsd_defs.h" sl@0: #endif sl@0: sl@0: #define LOCALE_LENGTH 30 sl@0: extern int _time_using_locale; sl@0: extern int _numeric_using_locale; sl@0: extern int _monetary_using_locale; sl@0: extern int __nlocale_changed; sl@0: extern int __mlocale_changed; sl@0: #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT sl@0: extern unsigned char __clocale_set; sl@0: extern unsigned char __applocale_changed; sl@0: #endif sl@0: sl@0: #ifdef EMULATOR sl@0: int *GET_WSD_VAR_NAME(_monetary_using_locale, g)(); sl@0: int *GET_WSD_VAR_NAME(_numeric_using_locale, g)(); sl@0: int *GET_WSD_VAR_NAME(_time_using_locale, g)(); sl@0: GET_GLOBAL_VAR_FROM_TLS(__mlocale_changed, int) sl@0: GET_GLOBAL_VAR_FROM_TLS(__nlocale_changed, int) sl@0: #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT sl@0: GET_GLOBAL_VAR_FROM_TLS(__clocale_set, unsigned char) sl@0: GET_GLOBAL_VAR_FROM_TLS(__applocale_changed, unsigned char) sl@0: #endif sl@0: sl@0: #define _monetary_using_locale (*GET_WSD_VAR_NAME(_monetary_using_locale, g)()) sl@0: #define _numeric_using_locale (*GET_WSD_VAR_NAME(_numeric_using_locale, g)()) sl@0: #define _time_using_locale (*GET_WSD_VAR_NAME(_time_using_locale, g)()) sl@0: #define __mlocale_changed (*GET_WSD_VAR_NAME(__mlocale_changed, g)()) sl@0: #define __nlocale_changed (*GET_WSD_VAR_NAME(__nlocale_changed, g)()) sl@0: #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT sl@0: #define __clocale_set (*GET_WSD_VAR_NAME(__clocale_set, g)()) sl@0: #define __applocale_changed (*GET_WSD_VAR_NAME(__applocale_changed, g)()) sl@0: #endif sl@0: #endif //EMULATOR sl@0: sl@0: __BEGIN_DECLS sl@0: #ifndef EMULATOR sl@0: char LC_CTYPE_LocaleName[LOCALE_LENGTH] = {'\0'}; sl@0: char LC_COLLATE_LocaleName[LOCALE_LENGTH] = {'\0'}; sl@0: char LC_NUMERIC_LocaleName[LOCALE_LENGTH] = {'\0'}; sl@0: char LC_MONETARY_LocaleName[LOCALE_LENGTH] = {'\0'}; sl@0: char LC_TIME_LocaleName[LOCALE_LENGTH] ={'\0'}; sl@0: char LC_ALL_LocaleName[LOCALE_LENGTH] = {'\0'}; sl@0: sl@0: #else //EMULATOR sl@0: sl@0: GET_GLOBAL_ARRAY_FROM_TLS(LC_CTYPE_LocaleName, char) sl@0: GET_GLOBAL_ARRAY_FROM_TLS(LC_COLLATE_LocaleName, char) sl@0: GET_GLOBAL_ARRAY_FROM_TLS(LC_NUMERIC_LocaleName, char) sl@0: GET_GLOBAL_ARRAY_FROM_TLS(LC_MONETARY_LocaleName, char) sl@0: GET_GLOBAL_ARRAY_FROM_TLS(LC_TIME_LocaleName, char) sl@0: GET_GLOBAL_ARRAY_FROM_TLS(LC_ALL_LocaleName, char) sl@0: sl@0: #define LC_CTYPE_LocaleName (GET_WSD_VAR_NAME(LC_CTYPE_LocaleName, g)()) sl@0: #define LC_COLLATE_LocaleName (GET_WSD_VAR_NAME(LC_COLLATE_LocaleName, g)()) sl@0: #define LC_NUMERIC_LocaleName (GET_WSD_VAR_NAME(LC_NUMERIC_LocaleName, g)()) sl@0: #define LC_MONETARY_LocaleName (GET_WSD_VAR_NAME(LC_MONETARY_LocaleName, g)()) sl@0: #define LC_TIME_LocaleName (GET_WSD_VAR_NAME(LC_TIME_LocaleName, g)()) sl@0: #define LC_ALL_LocaleName (GET_WSD_VAR_NAME(LC_ALL_LocaleName, g)()) sl@0: #endif //EMULATOR sl@0: sl@0: sl@0: __END_DECLS sl@0: sl@0: extern "C" { sl@0: sl@0: EXPORT_C char * setlocale(int category, const char* locale) sl@0: { sl@0: CLocale* loc = CLocale::GetInstance(); sl@0: sl@0: //Query the current locale sl@0: if(NULL == locale) sl@0: { sl@0: char* ret = NULL; sl@0: switch(category) sl@0: { sl@0: case LC_CTYPE: if(!*LC_CTYPE_LocaleName) sl@0: { sl@0: LC_CTYPE_LocaleName[0] = 'C'; sl@0: LC_CTYPE_LocaleName[1] = '\0'; sl@0: } sl@0: ret = (char*) LC_CTYPE_LocaleName; sl@0: break; sl@0: sl@0: case LC_COLLATE:if(!*LC_COLLATE_LocaleName) sl@0: { sl@0: LC_COLLATE_LocaleName[0] = 'C'; sl@0: LC_COLLATE_LocaleName[1] = '\0'; sl@0: } sl@0: ret = (char*) LC_COLLATE_LocaleName; sl@0: break; sl@0: sl@0: case LC_TIME: if(!*LC_TIME_LocaleName) sl@0: { sl@0: LC_TIME_LocaleName[0] = 'C'; sl@0: LC_TIME_LocaleName[1] = '\0'; sl@0: _time_using_locale = 0; sl@0: } sl@0: ret = (char*) LC_TIME_LocaleName; sl@0: break; sl@0: sl@0: case LC_NUMERIC:if(!*LC_NUMERIC_LocaleName) sl@0: { sl@0: LC_NUMERIC_LocaleName[0] = 'C'; sl@0: LC_NUMERIC_LocaleName[1] = '\0'; sl@0: _numeric_using_locale = 0; sl@0: } sl@0: ret = (char*) LC_NUMERIC_LocaleName; sl@0: break; sl@0: sl@0: case LC_MONETARY:if(!*LC_MONETARY_LocaleName) sl@0: { sl@0: LC_MONETARY_LocaleName[0] = 'C'; sl@0: LC_MONETARY_LocaleName[1] = '\0'; sl@0: _monetary_using_locale = 0; sl@0: } sl@0: ret = (char*) LC_MONETARY_LocaleName; sl@0: break; sl@0: sl@0: case LC_MESSAGES: sl@0: break; sl@0: sl@0: case LC_ALL :if(!*LC_ALL_LocaleName) sl@0: { sl@0: _time_using_locale = 0; sl@0: _numeric_using_locale = 0; sl@0: _monetary_using_locale = 0; sl@0: sl@0: LC_CTYPE_LocaleName[0] = 'C'; sl@0: LC_CTYPE_LocaleName[1] = '\0'; sl@0: LC_COLLATE_LocaleName[0] = 'C'; sl@0: LC_COLLATE_LocaleName[1] = '\0'; sl@0: LC_TIME_LocaleName[0] = 'C'; sl@0: LC_TIME_LocaleName[1] = '\0'; sl@0: LC_NUMERIC_LocaleName[0] = 'C'; sl@0: LC_NUMERIC_LocaleName[1] = '\0'; sl@0: LC_MONETARY_LocaleName[0] = 'C'; sl@0: LC_MONETARY_LocaleName[1] = '\0'; sl@0: LC_ALL_LocaleName[0] = 'C'; sl@0: LC_ALL_LocaleName[1] = '\0'; sl@0: } sl@0: ret = (char*) LC_ALL_LocaleName; sl@0: break; sl@0: default: sl@0: errno = EINVAL; sl@0: return (NULL); sl@0: } sl@0: return ret; sl@0: } sl@0: sl@0: //If locale is "" set each category(LC_CTYPE, LC_COLLATE, LC_NUMERIC, LC_TIME, LC_MONETARY) to C locale sl@0: if(strcmp(locale, "") == 0 ) sl@0: { sl@0: _time_using_locale = 0; sl@0: _numeric_using_locale = 0; sl@0: _monetary_using_locale = 0; sl@0: __nlocale_changed = 1; sl@0: __mlocale_changed = 1; sl@0: #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT sl@0: __clocale_set = 1; sl@0: __applocale_changed = 1; sl@0: #endif sl@0: sl@0: LC_CTYPE_LocaleName[0] = 'C'; sl@0: LC_CTYPE_LocaleName[1] = '\0'; sl@0: LC_COLLATE_LocaleName[0] = 'C'; sl@0: LC_COLLATE_LocaleName[1] = '\0'; sl@0: LC_TIME_LocaleName[0] = 'C'; sl@0: LC_TIME_LocaleName[1] = '\0'; sl@0: LC_NUMERIC_LocaleName[0] = 'C'; sl@0: LC_NUMERIC_LocaleName[1] = '\0'; sl@0: LC_MONETARY_LocaleName[0] = 'C'; sl@0: LC_MONETARY_LocaleName[1] = '\0'; sl@0: LC_ALL_LocaleName[0] = 'C'; sl@0: LC_ALL_LocaleName[1] = '\0'; sl@0: sl@0: return "C"; sl@0: } sl@0: sl@0: if (strcmp(locale, "C") == 0 || strcmp(locale, "POSIX") == 0) sl@0: { sl@0: if(LC_ALL == category) sl@0: { sl@0: _time_using_locale = 0; sl@0: _numeric_using_locale = 0; sl@0: _monetary_using_locale = 0; sl@0: __nlocale_changed = 1; sl@0: __mlocale_changed = 1; sl@0: #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT sl@0: __clocale_set = 1; sl@0: __applocale_changed = 1; sl@0: #endif sl@0: sl@0: strcpy((char*) LC_ALL_LocaleName, locale); sl@0: LC_ALL_LocaleName[strlen(locale)] = '\0'; sl@0: strcpy((char*) LC_CTYPE_LocaleName, locale); sl@0: LC_CTYPE_LocaleName[strlen(locale)] = '\0'; sl@0: strcpy((char*) LC_COLLATE_LocaleName, locale); sl@0: LC_COLLATE_LocaleName[strlen(locale)] = '\0'; sl@0: strcpy((char*) LC_NUMERIC_LocaleName, locale); sl@0: LC_NUMERIC_LocaleName[strlen(locale)] = '\0'; sl@0: strcpy((char*) LC_MONETARY_LocaleName, locale); sl@0: LC_MONETARY_LocaleName[strlen(locale)] = '\0'; sl@0: strcpy((char*) LC_TIME_LocaleName, locale); sl@0: LC_TIME_LocaleName[strlen(locale)] = '\0'; sl@0: return (char*) locale; sl@0: } sl@0: sl@0: switch(category) sl@0: { sl@0: case LC_CTYPE: strcpy((char*) LC_CTYPE_LocaleName, locale); sl@0: LC_CTYPE_LocaleName[strlen(locale)] = '\0'; sl@0: break; sl@0: sl@0: case LC_COLLATE: strcpy((char*) LC_COLLATE_LocaleName, locale); sl@0: LC_COLLATE_LocaleName[strlen(locale)] = '\0'; sl@0: break; sl@0: sl@0: case LC_TIME: _time_using_locale = 0; sl@0: strcpy((char*) LC_TIME_LocaleName, locale); sl@0: LC_TIME_LocaleName[strlen(locale)] = '\0'; sl@0: break; sl@0: sl@0: case LC_NUMERIC: _numeric_using_locale = 0; sl@0: __nlocale_changed = 1; sl@0: #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT sl@0: __applocale_changed = 1; sl@0: #endif sl@0: strcpy((char*) LC_NUMERIC_LocaleName, locale); sl@0: LC_NUMERIC_LocaleName[strlen(locale)] = '\0'; sl@0: break; sl@0: sl@0: case LC_MONETARY: _monetary_using_locale = 0; sl@0: __mlocale_changed = 1; sl@0: #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT sl@0: __applocale_changed = 1; sl@0: #endif sl@0: strcpy((char*) LC_MONETARY_LocaleName, locale); sl@0: LC_MONETARY_LocaleName[strlen(locale)] = '\0'; sl@0: break; sl@0: sl@0: case LC_MESSAGES: sl@0: default: sl@0: errno = EINVAL; sl@0: return (NULL); sl@0: } sl@0: return ((char*) locale); sl@0: } sl@0: sl@0: //If locale is other than C or POSIX sl@0: TPtrC8 src((const TUint8*)locale); sl@0: TBuf16 localeString; sl@0: localeString.Copy(src); sl@0: TText* retVal = loc->SetLocale(localeString); sl@0: if(NULL == retVal) sl@0: { sl@0: return NULL; sl@0: } sl@0: sl@0: if(LC_ALL == category) sl@0: { sl@0: TInt retVal =0; sl@0: sl@0: if( __numeric_load_locale(locale) == -1) sl@0: { sl@0: retVal = -1; sl@0: } sl@0: if(__monetary_load_locale(locale) == -1) sl@0: { sl@0: retVal = -1; sl@0: } sl@0: if (__time_load_locale(locale) == -1) sl@0: { sl@0: retVal = -1; sl@0: } sl@0: sl@0: if(!retVal) sl@0: { sl@0: strcpy((char*) LC_ALL_LocaleName, locale); sl@0: LC_ALL_LocaleName[strlen(locale)] = '\0'; sl@0: strcpy((char*) LC_CTYPE_LocaleName, locale); sl@0: LC_CTYPE_LocaleName[strlen(locale)] = '\0'; sl@0: strcpy((char*) LC_COLLATE_LocaleName, locale); sl@0: LC_COLLATE_LocaleName[strlen(locale)] = '\0'; sl@0: strcpy((char*) LC_NUMERIC_LocaleName, locale); sl@0: LC_NUMERIC_LocaleName[strlen(locale)] = '\0'; sl@0: strcpy((char*) LC_MONETARY_LocaleName, locale); sl@0: LC_MONETARY_LocaleName[strlen(locale)] = '\0'; sl@0: strcpy((char*) LC_TIME_LocaleName, locale); sl@0: LC_TIME_LocaleName[strlen(locale)] = '\0'; sl@0: return (char*) locale; sl@0: } sl@0: else sl@0: { sl@0: return NULL; sl@0: } sl@0: } sl@0: sl@0: switch (category) sl@0: { sl@0: case LC_CTYPE: strcpy((char*) LC_CTYPE_LocaleName, locale); sl@0: LC_CTYPE_LocaleName[strlen(locale)] = '\0'; sl@0: break; sl@0: sl@0: case LC_COLLATE: strcpy((char*) LC_COLLATE_LocaleName, locale); sl@0: LC_COLLATE_LocaleName[strlen(locale)] = '\0'; sl@0: break; sl@0: sl@0: case LC_TIME: if(!__time_load_locale(locale)) sl@0: { sl@0: strcpy((char*) LC_TIME_LocaleName, locale); sl@0: LC_TIME_LocaleName[strlen(locale)] = '\0'; sl@0: } sl@0: else sl@0: { sl@0: return NULL; sl@0: } sl@0: break; sl@0: sl@0: case LC_NUMERIC: if(!__numeric_load_locale(locale)) sl@0: { sl@0: strcpy((char*) LC_NUMERIC_LocaleName, locale); sl@0: LC_NUMERIC_LocaleName[strlen(locale)] = '\0'; sl@0: } sl@0: else sl@0: { sl@0: return NULL; sl@0: } sl@0: break; sl@0: sl@0: case LC_MONETARY: if(!__monetary_load_locale(locale)) sl@0: { sl@0: strcpy((char*) LC_MONETARY_LocaleName, locale); sl@0: LC_MONETARY_LocaleName[strlen(locale)] = '\0'; sl@0: } sl@0: else sl@0: { sl@0: return NULL; sl@0: } sl@0: break; sl@0: sl@0: case LC_MESSAGES: sl@0: default: sl@0: errno = EINVAL; sl@0: return (NULL); sl@0: } sl@0: return ((char*) locale); sl@0: } sl@0: sl@0: sl@0: EXPORT_C wchar_t* wsetlocale(int category, const wchar_t* locale) sl@0: { sl@0: char LocaleName[LOCALE_LENGTH]; sl@0: wchar_t *wideLocaleName = new wchar_t[LOCALE_LENGTH + 1]; sl@0: char *result = NULL; sl@0: sl@0: if (locale != NULL) sl@0: { sl@0: if ((size_t)-1 != (wcstombs((char*)LocaleName, locale, LOCALE_LENGTH*sizeof(wchar_t)))) sl@0: { sl@0: result = setlocale(category, LocaleName); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: result = setlocale(category, NULL); sl@0: } sl@0: sl@0: if (result != NULL) sl@0: { sl@0: if ((size_t)-1 != (mbstowcs(wideLocaleName, result, LOCALE_LENGTH*sizeof(wchar_t)))) sl@0: { sl@0: return wideLocaleName; sl@0: } sl@0: } sl@0: sl@0: delete []wideLocaleName; sl@0: return NULL; sl@0: } sl@0: sl@0: } //extern "C"