5 #include "locale_impl.h"
10 #define malloc __libc_malloc
15 const char *__lctrans_impl(const char *msg
, const struct __locale_map
*lm
)
17 const char *trans
= 0;
18 if (lm
) trans
= __mo_lookup(lm
->map
, lm
->map_size
, msg
);
19 return trans
? trans
: msg
;
22 static const char envvars
[][12] = {
31 volatile int __locale_lock
[1];
32 volatile int *const __locale_lockptr
= __locale_lock
;
34 const struct __locale_map
*__get_locale(int cat
, const char *val
)
36 static void *volatile loc_head
;
37 const struct __locale_map
*p
;
38 struct __locale_map
*new = 0;
39 const char *path
= 0, *z
;
44 (val
= getenv("LC_ALL")) && *val
||
45 (val
= getenv(envvars
[cat
])) && *val
||
46 (val
= getenv("LANG")) && *val
||
50 /* Limit name length and forbid leading dot or any slashes. */
51 for (n
=0; n
<LOCALE_NAME_MAX
&& val
[n
] && val
[n
]!='/'; n
++);
52 if (val
[0]=='.' || val
[n
]) val
= "C.UTF-8";
53 int builtin
= (val
[0]=='C' && !val
[1])
54 || !strcmp(val
, "C.UTF-8")
55 || !strcmp(val
, "POSIX");
58 if (cat
== LC_CTYPE
&& val
[1]=='.')
59 return (void *)&__c_dot_utf8
;
63 for (p
=loc_head
; p
; p
=p
->next
)
64 if (!strcmp(val
, p
->name
)) return p
;
66 if (!libc
.secure
) path
= getenv("MUSL_LOCPATH");
67 /* FIXME: add a default path? */
69 if (path
) for (; *path
; path
=z
+!!*z
) {
70 z
= __strchrnul(path
, ':');
72 if (l
>= sizeof buf
- n
- 2) continue;
75 memcpy(buf
+l
+1, val
, n
);
78 const void *map
= __map_file(buf
, &map_size
);
80 new = malloc(sizeof *new);
82 __munmap((void *)map
, map_size
);
86 new->map_size
= map_size
;
87 memcpy(new->name
, val
, n
);
95 /* If no locale definition was found, make a locale map
96 * object anyway to store the name, which is kept for the
97 * sake of being able to do message translations at the
98 * application level. */
99 if (!new && (new = malloc(sizeof *new))) {
100 new->map
= __c_dot_utf8
.map
;
101 new->map_size
= __c_dot_utf8
.map_size
;
102 memcpy(new->name
, val
, n
);
104 new->next
= loc_head
;
108 /* For LC_CTYPE, never return a null pointer unless the
109 * requested name was "C" or "POSIX". */
110 if (!new && cat
== LC_CTYPE
) new = (void *)&__c_dot_utf8
;