>From b26275c034637b80caa2af0128daa93f0423989f Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 15 Sep 2026 19:01:33 -0400 Subject: [PATCH 10/18] locale: add loader for new locale format & adjust related logic --- src/internal/locale_impl.h | 13 +++++++++++-- src/locale/c_locale.c | 4 ---- src/locale/locale_map.c | 33 ++++++++++++++++++++++++++------- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/internal/locale_impl.h b/src/internal/locale_impl.h index 33e54347..8aab137b 100644 --- a/src/internal/locale_impl.h +++ b/src/internal/locale_impl.h @@ -8,11 +8,20 @@ #define LOCALE_NAME_MAX 23 +enum { + K_HEADER, + K_LCONV, + K_LANGINFO, + K_COLLATION, + K_ERRORS, +}; + struct __locale_map { - const void *map; - size_t map_size; char name[LOCALE_NAME_MAX+1]; const struct __locale_map *next; + const unsigned char *table_root; + const unsigned char *langinfo; + const unsigned char *errors; }; extern hidden volatile int __locale_lock[1]; diff --git a/src/locale/c_locale.c b/src/locale/c_locale.c index 77ccf587..620060fa 100644 --- a/src/locale/c_locale.c +++ b/src/locale/c_locale.c @@ -1,11 +1,7 @@ #include "locale_impl.h" #include -static const uint32_t empty_mo[] = { 0x950412de, 0, -1, -1, -1 }; - const struct __locale_map __c_dot_utf8 = { - .map = empty_mo, - .map_size = sizeof empty_mo, .name = "C.UTF-8" }; diff --git a/src/locale/locale_map.c b/src/locale/locale_map.c index 9ebf7ced..f4ecad28 100644 --- a/src/locale/locale_map.c +++ b/src/locale/locale_map.c @@ -2,10 +2,12 @@ #include #include #include +#include #include "locale_impl.h" #include "libc.h" #include "lock.h" #include "fork_impl.h" +#include "ikmlt.h" #define malloc __libc_malloc #define calloc undef @@ -14,9 +16,7 @@ const char *__lctrans_impl(const char *msg, const struct __locale_map *lm) { - const char *trans = 0; - if (lm) trans = __mo_lookup(lm->map, lm->map_size, msg); - return trans ? trans : msg; + return msg; } static const char envvars[][12] = { @@ -31,6 +31,25 @@ static const char envvars[][12] = { volatile int __locale_lock[1]; volatile int *const __locale_lockptr = __locale_lock; +static int load_locale(struct __locale_map *l, const unsigned char *lm) +{ + const unsigned char *root; + + if (memcmp(lm, "ikmlt\xff\xc0\xc1loc2\0\0\0\0", 16)) { + errno = EINVAL; + return -1; + } + l->table_root = root = lm+16; + + /* langinfo() keys */ + l->langinfo = ikmlt_lookup(root, K_LANGINFO); + + /* strerror, etc. strings */ + l->errors = ikmlt_lookup(root, K_ERRORS); + + return 0; +} + const struct __locale_map *__get_locale(int cat, const char *val) { static void *volatile loc_head; @@ -75,13 +94,13 @@ const struct __locale_map *__get_locale(int cat, const char *val) size_t map_size; const void *map = __map_file(buf, &map_size); if (map) { - new = malloc(sizeof *new); - if (!new) { + struct __locale_map tmp; + if (load_locale(&tmp, map) || + !(new = malloc(sizeof *new))) { __munmap((void *)map, map_size); break; } - new->map = map; - new->map_size = map_size; + *new = tmp; memcpy(new->name, val, n); new->name[n] = 0; new->next = loc_head; -- 2.21.0