3 #include "locale_impl.h"
7 const char *__lctrans_impl(const char *msg
, const struct __locale_map
*lm
)
10 if (lm
) trans
= __mo_lookup(lm
->map
, lm
->map_size
, msg
);
11 return trans
? trans
: msg
;
14 const unsigned char *__map_file(const char *, size_t *);
15 int __munmap(void *, size_t);
16 char *__strchrnul(const char *, int);
18 static const char envvars
[][12] = {
27 const struct __locale_map
*__get_locale(int cat
, const char *val
)
30 static void *volatile loc_head
;
31 const struct __locale_map
*p
;
32 struct __locale_map
*new = 0;
33 const char *path
= 0, *z
;
38 (val
= getenv("LC_ALL")) && *val
||
39 (val
= getenv(envvars
[cat
])) && *val
||
40 (val
= getenv("LANG")) && *val
||
44 /* Limit name length and forbid leading dot or any slashes. */
45 for (n
=0; n
<LOCALE_NAME_MAX
&& val
[n
] && val
[n
]!='/'; n
++);
46 if (val
[0]=='.' || val
[n
]) val
= "C.UTF-8";
47 int builtin
= (val
[0]=='C' && !val
[1])
48 || !strcmp(val
, "C.UTF-8")
49 || !strcmp(val
, "POSIX");
52 if (cat
== LC_CTYPE
&& val
[1]=='.')
53 return (void *)&__c_dot_utf8
;
57 for (p
=loc_head
; p
; p
=p
->next
)
58 if (!strcmp(val
, p
->name
)) return p
;
62 for (p
=loc_head
; p
; p
=p
->next
)
63 if (!strcmp(val
, p
->name
)) {
68 if (!libc
.secure
) path
= getenv("MUSL_LOCPATH");
69 /* FIXME: add a default path? */
71 if (path
) for (; *path
; path
=z
+!!*z
) {
72 z
= __strchrnul(path
, ':');
74 if (l
>= sizeof buf
- n
- 2) continue;
77 memcpy(buf
+l
+1, val
, n
);
80 const void *map
= __map_file(buf
, &map_size
);
82 new = malloc(sizeof *new);
84 __munmap((void *)map
, map_size
);
88 new->map_size
= map_size
;
89 memcpy(new->name
, val
, n
);
97 /* If no locale definition was found, make a locale map
98 * object anyway to store the name, which is kept for the
99 * sake of being able to do message translations at the
100 * application level. */
101 if (!new && (new = malloc(sizeof *new))) {
102 new->map
= __c_dot_utf8
.map
;
103 new->map_size
= __c_dot_utf8
.map_size
;
104 memcpy(new->name
, val
, n
);
106 new->next
= loc_head
;
110 /* For LC_CTYPE, never return a null pointer unless the
111 * requested name was "C" or "POSIX". */
112 if (!new && cat
== LC_CTYPE
) new = (void *)&__c_dot_utf8
;