1 /* 2 * Copyright 2004-2007, Axel Dörfler, axeld@pinc-software.de 3 * Copyright 2010, Oliver Tappe, zooey@hirschkaefer.de 4 * All rights reserved. Distributed under the terms of the MIT License. 5 */ 6 7 8 #include <ctype.h> 9 #include <locale.h> 10 #include <strings.h> 11 12 #include <ErrnoMaintainer.h> 13 14 #include "LocaleBackend.h" 15 #include "LocaleInternal.h" 16 17 18 using BPrivate::Libroot::gGlobalLocaleBackend; 19 using BPrivate::Libroot::GetLocalesFromEnvironment; 20 using BPrivate::Libroot::LocaleBackend; 21 22 23 extern "C" char* 24 setlocale(int category, const char* locale) 25 { 26 BPrivate::ErrnoMaintainer errnoMaintainer; 27 28 if (category < 0 || category > LC_LAST) 29 return NULL; 30 31 if (locale == NULL) { 32 // query the locale of the given category 33 if (gGlobalLocaleBackend != NULL) 34 return const_cast<char*>(gGlobalLocaleBackend->SetLocale(category, NULL)); 35 else 36 return const_cast<char*>("POSIX"); 37 } 38 39 // we may have to invoke SetLocale once for each category, so we use an 40 // array to collect the locale per category 41 const char* locales[LC_LAST + 1]; 42 for (int lc = 0; lc <= LC_LAST; lc++) 43 locales[lc] = NULL; 44 45 if (*locale == '\0') 46 GetLocalesFromEnvironment(category, locales); 47 else 48 locales[category] = locale; 49 50 if (gGlobalLocaleBackend == NULL) { 51 // for any locale other than POSIX/C, we try to activate the ICU 52 // backend 53 bool needBackend = false; 54 for (int lc = 0; lc <= LC_LAST; lc++) { 55 if (locales[lc] != NULL && strcasecmp(locales[lc], "POSIX") != 0 56 && strcasecmp(locales[lc], "C") != 0) { 57 needBackend = true; 58 break; 59 } 60 } 61 if (needBackend && LocaleBackend::LoadBackend() != B_OK) 62 return NULL; 63 } 64 65 if (gGlobalLocaleBackend != NULL) { 66 for (int lc = 0; lc <= LC_LAST; lc++) { 67 if (locales[lc] != NULL) { 68 locale = gGlobalLocaleBackend->SetLocale(lc, locales[lc]); 69 if (lc == LC_ALL) { 70 // skip the rest, LC_ALL overrides 71 return const_cast<char*>(locale); 72 } 73 } 74 } 75 return const_cast<char*>(gGlobalLocaleBackend->SetLocale(category, NULL)); 76 } 77 78 return const_cast<char*>("POSIX"); 79 } 80