3 #if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
6 #include "locale_impl.h"
9 #define malloc __libc_malloc
14 static int default_locale_init_done
;
15 static struct __locale_struct default_locale
, default_ctype_locale
;
17 int __loc_is_allocated(locale_t loc
)
19 return loc
&& loc
!= C_LOCALE
&& loc
!= UTF8_LOCALE
20 && loc
!= &default_locale
&& loc
!= &default_ctype_locale
;
23 static locale_t
do_newlocale(int mask
, const char *name
, locale_t loc
)
25 struct __locale_struct tmp
;
27 for (int i
=0; i
<LC_ALL
; i
++) {
28 tmp
.cat
[i
] = (!(mask
& (1<<i
)) && loc
) ? loc
->cat
[i
] :
29 __get_locale(i
, (mask
& (1<<i
)) ? name
: "");
30 if (tmp
.cat
[i
] == LOC_MAP_FAILED
)
34 /* For locales with allocated storage, modify in-place. */
35 if (__loc_is_allocated(loc
)) {
40 /* Otherwise, first see if we can use one of the builtin locales.
41 * This makes the common usage case for newlocale, getting a C locale
42 * with predictable behavior, very fast, and more importantly, fail-safe. */
43 if (!memcmp(&tmp
, C_LOCALE
, sizeof tmp
)) return C_LOCALE
;
44 if (!memcmp(&tmp
, UTF8_LOCALE
, sizeof tmp
)) return UTF8_LOCALE
;
46 /* And provide builtins for the initial default locale, and a
47 * variant of the C locale honoring the default locale's encoding. */
48 if (!default_locale_init_done
) {
49 for (int i
=0; i
<LC_ALL
; i
++)
50 default_locale
.cat
[i
] = __get_locale(i
, "");
51 default_ctype_locale
.cat
[LC_CTYPE
] = default_locale
.cat
[LC_CTYPE
];
52 default_locale_init_done
= 1;
54 if (!memcmp(&tmp
, &default_locale
, sizeof tmp
)) return &default_locale
;
55 if (!memcmp(&tmp
, &default_ctype_locale
, sizeof tmp
))
56 return &default_ctype_locale
;
58 /* If no builtin locale matched, attempt to allocate and copy. */
59 if ((loc
= malloc(sizeof *loc
))) *loc
= tmp
;
64 locale_t
__newlocale(int mask
, const char *name
, locale_t loc
)
67 loc
= do_newlocale(mask
, name
, loc
);
68 UNLOCK(__locale_lock
);
72 weak_alias(__newlocale
, newlocale
);