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.
13 #include <ErrnoMaintainer.h>
15 #include "LocaleBackend.h"
18 using BPrivate::Libroot::gLocaleBackend
;
19 using BPrivate::Libroot::LocaleBackend
;
23 GetLocalesFromEnvironment(int category
, const char** locales
)
25 const char* locale
= getenv("LC_ALL");
26 if (locale
&& *locale
)
27 locales
[category
] = locale
;
29 // the order of the names must match the one specified in locale.h
30 const char* categoryNames
[] = {
40 if (category
== LC_ALL
) {
41 // we need to check each real category if all of them should be set
46 bool haveDifferentLocales
= false;
48 for (int lc
= from
; lc
<= to
; lc
++) {
49 const char* lastLocale
= locale
;
50 locale
= getenv(categoryNames
[lc
]);
51 if (!locale
|| *locale
== '\0')
52 locale
= getenv("LANG");
53 if (!locale
|| *locale
== '\0')
56 if (lastLocale
&& strcasecmp(locale
, lastLocale
) != 0)
57 haveDifferentLocales
= true;
59 if (!haveDifferentLocales
) {
60 // we can set all locales at once
61 locales
[LC_ALL
] = locale
;
70 setlocale(int category
, const char* locale
)
72 BPrivate::ErrnoMaintainer errnoMaintainer
;
74 if (category
< 0 || category
> LC_LAST
)
78 // query the locale of the given category
79 if (gLocaleBackend
!= NULL
)
80 return const_cast<char*>(gLocaleBackend
->SetLocale(category
, NULL
));
82 return const_cast<char*>("POSIX");
85 // we may have to invoke SetLocale once for each category, so we use an
86 // array to collect the locale per category
87 const char* locales
[LC_LAST
+ 1];
88 for (int lc
= 0; lc
<= LC_LAST
; lc
++)
92 GetLocalesFromEnvironment(category
, locales
);
94 locales
[category
] = locale
;
96 if (!gLocaleBackend
) {
97 // for any locale other than POSIX/C, we try to activate the ICU
99 bool needBackend
= false;
100 for (int lc
= 0; lc
<= LC_LAST
; lc
++) {
101 if (locales
[lc
] != NULL
&& strcasecmp(locales
[lc
], "POSIX") != 0
102 && strcasecmp(locales
[lc
], "C") != 0) {
107 if (needBackend
&& LocaleBackend::LoadBackend() != B_OK
)
111 if (gLocaleBackend
!= NULL
) {
112 for (int lc
= 0; lc
<= LC_LAST
; lc
++) {
113 if (locales
[lc
] != NULL
) {
114 locale
= gLocaleBackend
->SetLocale(lc
, locales
[lc
]);
116 // skip the rest, LC_ALL overrides
117 return const_cast<char*>(locale
);
121 return const_cast<char*>(gLocaleBackend
->SetLocale(category
, NULL
));
124 return const_cast<char*>("POSIX");