[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
localename: Add support for Haiku's per-thread locales
From: |
Bruno Haible |
Subject: |
localename: Add support for Haiku's per-thread locales |
Date: |
Wed, 05 Apr 2023 15:40:52 +0200 |
In 2022, Haiku got support for per-thread locales (POSIX functions
uselocale, newlocale, duplocale, freelocale).
Gnulib needs support for this in the 'localename' module (so that
GNU gettext will work when a per-thread locale is installed).
This patch does it. It is pretty ugly, though.
2023-04-05 Bruno Haible <bruno@clisp.org>
localename: Add support for Haiku's per-thread locales.
* lib/localename.c: Include <dlfcn.h>.
(gl_locale_name_thread_unsafe): Add special code for Haiku.
diff --git a/lib/localename.c b/lib/localename.c
index 8fe90e0bf2..3c1dc67c14 100644
--- a/lib/localename.c
+++ b/lib/localename.c
@@ -59,6 +59,9 @@ extern char * getlocalename_l(int, locale_t);
# if HAVE_NAMELESS_LOCALES
# include "localename-table.h"
# endif
+# if defined __HAIKU__
+# include <dlfcn.h>
+# endif
#endif
#if HAVE_CFPREFERENCESCOPYAPPVALUE
@@ -3203,6 +3206,68 @@ gl_locale_name_thread_unsafe (int category, _GL_UNUSED
const char *categoryname)
};
return ((struct __locale_t *) thread_locale)->categories[category];
# endif
+# elif defined __HAIKU__
+ /* Since 2022, Haiku has per-thread locales. locale_t is 'void *',
+ but in fact a 'LocaleBackendData *'. */
+ struct LocaleBackendData {
+ int magic;
+ void /*BPrivate::Libroot::LocaleBackend*/ *backend;
+ void /*BPrivate::Libroot::LocaleDataBridge*/ *databridge;
+ };
+ void *thread_locale_backend =
+ ((struct LocaleBackendData *) thread_locale)->backend;
+ if (thread_locale_backend != NULL)
+ {
+ /* The only existing concrete subclass of
+ BPrivate::Libroot::LocaleBackend is
+ BPrivate::Libroot::ICULocaleBackend.
+ Invoke the (non-virtual) method
+ BPrivate::Libroot::ICULocaleBackend::_QueryLocale on it.
+ This method is located in a separate shared library,
+ libroot-addon-icu.so. */
+ static void * volatile querylocale_method /* = NULL */;
+ static int volatile querylocale_found /* = 0 */;
+ /* Attempt to open this shared library, the first time we get
+ here. */
+ if (querylocale_found == 0)
+ {
+ void *handle =
+ dlopen ("/boot/system/lib/libroot-addon-icu.so", 0);
+ if (handle != NULL)
+ {
+ void *sym =
+ dlsym (handle,
"_ZN8BPrivate7Libroot16ICULocaleBackend12_QueryLocaleEi");
+ if (sym != NULL)
+ {
+ querylocale_method = sym;
+ querylocale_found = 1;
+ }
+ else
+ /* Could not find the symbol. */
+ querylocale_found = -1;
+ }
+ else
+ /* Could not open the separate shared library. */
+ querylocale_found = -1;
+ }
+ if (querylocale_found > 0)
+ {
+ /* The _QueryLocale method is a non-static C++ method with
+ parameters (int category) and return type 'const char *'.
+ See
+ haiku/headers/private/libroot/locale/ICULocaleBackend.h
+ haiku/src/system/libroot/add-ons/icu/ICULocaleBackend.cpp
+ This is the same as a C function with parameters
+ (BPrivate::Libroot::LocaleBackend* this, int category)
+ and return type 'const char *'. Invoke it. */
+ const char * (*querylocale_func) (void *, int) =
+ (const char * (*) (void *, int)) querylocale_method;
+ return querylocale_func (thread_locale_backend, category);
+ }
+ }
+ else
+ /* It's the "C" or "POSIX" locale. */
+ return "C";
# elif defined __ANDROID__
return MB_CUR_MAX == 4 ? "C.UTF-8" : "C";
# endif
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- localename: Add support for Haiku's per-thread locales,
Bruno Haible <=