| OLD | NEW |
| 1 #include <locale.h> | 1 #include <locale.h> |
| 2 #include <string.h> | 2 #include <string.h> |
| 3 #include "locale_impl.h" | 3 #include "locale_impl.h" |
| 4 #include "libc.h" | 4 #include "libc.h" |
| 5 #include "atomic.h" | 5 #include "atomic.h" |
| 6 | 6 |
| 7 const char *__lctrans_impl(const char *msg, const struct __locale_map *lm) | 7 const char* __lctrans_impl(const char* msg, const struct __locale_map* lm) { |
| 8 { | 8 const char* trans = 0; |
| 9 » const char *trans = 0; | 9 if (lm) |
| 10 » if (lm) trans = __mo_lookup(lm->map, lm->map_size, msg); | 10 trans = __mo_lookup(lm->map, lm->map_size, msg); |
| 11 » return trans ? trans : msg; | 11 return trans ? trans : msg; |
| 12 } | 12 } |
| 13 | 13 |
| 14 const unsigned char *__map_file(const char *, size_t *); | 14 const unsigned char* __map_file(const char*, size_t*); |
| 15 int __munmap(void *, size_t); | 15 int __munmap(void*, size_t); |
| 16 char *__strchrnul(const char *, int); | 16 char* __strchrnul(const char*, int); |
| 17 | 17 |
| 18 static const char envvars[][12] = { | 18 static const char envvars[][12] = { |
| 19 » "LC_CTYPE", | 19 "LC_CTYPE", "LC_NUMERIC", "LC_TIME", |
| 20 » "LC_NUMERIC", | 20 "LC_COLLATE", "LC_MONETARY", "LC_MESSAGES", |
| 21 » "LC_TIME", | |
| 22 » "LC_COLLATE", | |
| 23 » "LC_MONETARY", | |
| 24 » "LC_MESSAGES", | |
| 25 }; | 21 }; |
| 26 | 22 |
| 27 const struct __locale_map *__get_locale(int cat, const char *val) | 23 const struct __locale_map* __get_locale(int cat, const char* val) { |
| 28 { | 24 static int lock[2]; |
| 29 » static int lock[2]; | 25 static void* volatile loc_head; |
| 30 » static void *volatile loc_head; | 26 const struct __locale_map* p; |
| 31 » const struct __locale_map *p; | 27 struct __locale_map* new = 0; |
| 32 » struct __locale_map *new = 0; | 28 const char *path = 0, *z; |
| 33 » const char *path = 0, *z; | 29 char buf[256]; |
| 34 » char buf[256]; | 30 size_t l, n; |
| 35 » size_t l, n; | |
| 36 | 31 |
| 37 » if (!*val) { | 32 if (!*val) { |
| 38 » » ((val = getenv("LC_ALL")) && *val) || | 33 ((val = getenv("LC_ALL")) && *val) || |
| 39 » » ((val = getenv(envvars[cat])) && *val) || | 34 ((val = getenv(envvars[cat])) && *val) || |
| 40 » » ((val = getenv("LANG")) && *val) || | 35 ((val = getenv("LANG")) && *val) || (val = "C.UTF-8"); |
| 41 » » (val = "C.UTF-8"); | 36 } |
| 42 » } | |
| 43 | 37 |
| 44 » /* Limit name length and forbid leading dot or any slashes. */ | 38 /* Limit name length and forbid leading dot or any slashes. */ |
| 45 » for (n=0; n<LOCALE_NAME_MAX && val[n] && val[n]!='/'; n++); | 39 for (n = 0; n < LOCALE_NAME_MAX && val[n] && val[n] != '/'; n++) |
| 46 » if (val[0]=='.' || val[n]) val = "C.UTF-8"; | 40 ; |
| 47 » int builtin = (val[0]=='C' && !val[1]) | 41 if (val[0] == '.' || val[n]) |
| 48 » » || !strcmp(val, "C.UTF-8") | 42 val = "C.UTF-8"; |
| 49 » » || !strcmp(val, "POSIX"); | 43 int builtin = (val[0] == 'C' && !val[1]) || !strcmp(val, "C.UTF-8") || |
| 44 !strcmp(val, "POSIX"); |
| 50 | 45 |
| 51 » if (builtin) { | 46 if (builtin) { |
| 52 » » if (cat == LC_CTYPE && val[1]=='.') | 47 if (cat == LC_CTYPE && val[1] == '.') |
| 53 » » » return (void *)&__c_dot_utf8; | 48 return (void*)&__c_dot_utf8; |
| 54 » » return 0; | 49 return 0; |
| 55 » } | 50 } |
| 56 | 51 |
| 57 » for (p=loc_head; p; p=p->next) | 52 for (p = loc_head; p; p = p->next) |
| 58 » » if (!strcmp(val, p->name)) return p; | 53 if (!strcmp(val, p->name)) |
| 54 return p; |
| 59 | 55 |
| 60 » LOCK(lock); | 56 LOCK(lock); |
| 61 | 57 |
| 62 » for (p=loc_head; p; p=p->next) | 58 for (p = loc_head; p; p = p->next) |
| 63 » » if (!strcmp(val, p->name)) { | 59 if (!strcmp(val, p->name)) { |
| 64 » » » UNLOCK(lock); | 60 UNLOCK(lock); |
| 65 » » » return p; | 61 return p; |
| 66 » » } | 62 } |
| 67 | 63 |
| 68 » if (!libc.secure) path = getenv("MUSL_LOCPATH"); | 64 if (!libc.secure) |
| 69 » /* FIXME: add a default path? */ | 65 path = getenv("MUSL_LOCPATH"); |
| 66 /* FIXME: add a default path? */ |
| 70 | 67 |
| 71 » if (path) for (; *path; path=z+!!*z) { | 68 if (path) |
| 72 » » z = __strchrnul(path, ':'); | 69 for (; *path; path = z + !!*z) { |
| 73 » » l = z - path - !!*z; | 70 z = __strchrnul(path, ':'); |
| 74 » » if (l >= sizeof buf - n - 2) continue; | 71 l = z - path - !!*z; |
| 75 » » memcpy(buf, path, l); | 72 if (l >= sizeof buf - n - 2) |
| 76 » » buf[l] = '/'; | 73 continue; |
| 77 » » memcpy(buf+l+1, val, n); | 74 memcpy(buf, path, l); |
| 78 » » buf[l+1+n] = 0; | 75 buf[l] = '/'; |
| 79 » » size_t map_size; | 76 memcpy(buf + l + 1, val, n); |
| 80 » » const void *map = __map_file(buf, &map_size); | 77 buf[l + 1 + n] = 0; |
| 81 » » if (map) { | 78 size_t map_size; |
| 82 » » » new = malloc(sizeof *new); | 79 const void* map = __map_file(buf, &map_size); |
| 83 » » » if (!new) { | 80 if (map) { |
| 84 » » » » __munmap((void *)map, map_size); | 81 new = malloc(sizeof *new); |
| 85 » » » » break; | 82 if (!new) { |
| 86 » » » } | 83 __munmap((void*)map, map_size); |
| 87 » » » new->map = map; | 84 break; |
| 88 » » » new->map_size = map_size; | 85 } |
| 89 » » » memcpy(new->name, val, n); | 86 new->map = map; |
| 90 » » » new->name[n] = 0; | 87 new->map_size = map_size; |
| 91 » » » new->next = loc_head; | 88 memcpy(new->name, val, n); |
| 92 » » » loc_head = new; | 89 new->name[n] = 0; |
| 93 » » » break; | 90 new->next = loc_head; |
| 94 » » } | 91 loc_head = new; |
| 95 » } | 92 break; |
| 93 } |
| 94 } |
| 96 | 95 |
| 97 » /* If no locale definition was found, make a locale map | 96 /* If no locale definition was found, make a locale map |
| 98 » * object anyway to store the name, which is kept for the | 97 * object anyway to store the name, which is kept for the |
| 99 » * sake of being able to do message translations at the | 98 * sake of being able to do message translations at the |
| 100 » * application level. */ | 99 * application level. */ |
| 101 » if (!new && (new = malloc(sizeof *new))) { | 100 if (!new && (new = malloc(sizeof *new))) { |
| 102 » » new->map = __c_dot_utf8.map; | 101 new->map = __c_dot_utf8.map; |
| 103 » » new->map_size = __c_dot_utf8.map_size; | 102 new->map_size = __c_dot_utf8.map_size; |
| 104 » » memcpy(new->name, val, n); | 103 memcpy(new->name, val, n); |
| 105 » » new->name[n] = 0; | 104 new->name[n] = 0; |
| 106 » » new->next = loc_head; | 105 new->next = loc_head; |
| 107 » » loc_head = new; | 106 loc_head = new; |
| 108 » } | 107 } |
| 109 | 108 |
| 110 » /* For LC_CTYPE, never return a null pointer unless the | 109 /* For LC_CTYPE, never return a null pointer unless the |
| 111 » * requested name was "C" or "POSIX". */ | 110 * requested name was "C" or "POSIX". */ |
| 112 » if (!new && cat == LC_CTYPE) new = (void *)&__c_dot_utf8; | 111 if (!new&& cat == LC_CTYPE) |
| 112 new = (void*)&__c_dot_utf8; |
| 113 | 113 |
| 114 » UNLOCK(lock); | 114 UNLOCK(lock); |
| 115 » return new; | 115 return new; |
| 116 } | 116 } |
| OLD | NEW |