4 #include "locale_impl.h"
7 #define malloc __libc_malloc
12 static int default_locale_init_done
;
13 static struct __locale_struct default_locale
, default_ctype_locale
;
15 int __loc_is_allocated(locale_t loc
)
17 return loc
&& loc
!= C_LOCALE
&& loc
!= UTF8_LOCALE
18 && loc
!= &default_locale
&& loc
!= &default_ctype_locale
;
21 static locale_t
do_newlocale(int mask
, const char *name
, locale_t loc
)
23 struct __locale_struct tmp
;
25 for (int i
=0; i
<LC_ALL
; i
++) {
26 tmp
.cat
[i
] = (!(mask
& (1<<i
)) && loc
) ? loc
->cat
[i
] :
27 __get_locale(i
, (mask
& (1<<i
)) ? name
: "");
28 if (tmp
.cat
[i
] == LOC_MAP_FAILED
)
32 /* For locales with allocated storage, modify in-place. */
33 if (__loc_is_allocated(loc
)) {
38 /* Otherwise, first see if we can use one of the builtin locales.
39 * This makes the common usage case for newlocale, getting a C locale
40 * with predictable behavior, very fast, and more importantly, fail-safe. */
41 if (!memcmp(&tmp
, C_LOCALE
, sizeof tmp
)) return C_LOCALE
;
42 if (!memcmp(&tmp
, UTF8_LOCALE
, sizeof tmp
)) return UTF8_LOCALE
;
44 /* And provide builtins for the initial default locale, and a
45 * variant of the C locale honoring the default locale's encoding. */
46 if (!default_locale_init_done
) {
47 for (int i
=0; i
<LC_ALL
; i
++)
48 default_locale
.cat
[i
] = __get_locale(i
, "");
49 default_ctype_locale
.cat
[LC_CTYPE
] = default_locale
.cat
[LC_CTYPE
];
50 default_locale_init_done
= 1;
52 if (!memcmp(&tmp
, &default_locale
, sizeof tmp
)) return &default_locale
;
53 if (!memcmp(&tmp
, &default_ctype_locale
, sizeof tmp
))
54 return &default_ctype_locale
;
56 /* If no builtin locale matched, attempt to allocate and copy. */
57 if ((loc
= malloc(sizeof *loc
))) *loc
= tmp
;
62 locale_t
__newlocale(int mask
, const char *name
, locale_t loc
)
65 loc
= do_newlocale(mask
, name
, loc
);
66 UNLOCK(__locale_lock
);
70 weak_alias(__newlocale
, newlocale
);