rktio: add support for xlocale
Add support for using xlocale's thread-friendly API instead of setlocale --- but it's not turned on, yet, for any platform.
This commit is contained in:
parent
4525c231a7
commit
4d8851d1be
|
@ -1196,15 +1196,19 @@ RKTIO_EXTERN char *rktio_locale_encoding(rktio_t *rktio);
|
|||
/* Returns the name of the current locale's encoding. */
|
||||
|
||||
RKTIO_EXTERN void rktio_set_locale(rktio_t *rktio, rktio_const_string_t name);
|
||||
/* Sets the current locale, which affects string comparisons and
|
||||
/* Sets the current locale, which affects rktio string comparisons and
|
||||
conversions. It can also affect the C library's character-property
|
||||
predicates and number printing/parsing. The empty string
|
||||
corresponds to the OS's native locale. */
|
||||
predicates and number printing/parsing by setting a thread-local or
|
||||
process-wide locale, but that effect is not guaranteed. The empty
|
||||
string corresponds to the OS's native locale, and a NULL string
|
||||
pointer corresponds to the C locale. */
|
||||
|
||||
RKTIO_EXTERN_NOERR char *rktio_push_c_numeric_locale(rktio_t *rktio);
|
||||
RKTIO_EXTERN void rktio_pop_c_numeric_locale(rktio_t *rktio, char *prev);
|
||||
/* Use this pair of functions to temporarily switch the locale to the C
|
||||
locale for number parsing and printing. The result of the first
|
||||
RKTIO_EXTERN_NOERR void *rktio_push_c_numeric_locale(rktio_t *rktio);
|
||||
RKTIO_EXTERN void rktio_pop_c_numeric_locale(rktio_t *rktio, void *prev);
|
||||
/* Use this pair of functions to temporarily switch the locale to the
|
||||
C locale for number parsing and printing. Unlike
|
||||
rktio_set_locale(), these functions set and restore the
|
||||
thread-local or even process-wide locale. The result of the first
|
||||
function is deallocated when passed to second function. */
|
||||
|
||||
RKTIO_EXTERN char *rktio_system_language_country(rktio_t *rktio);
|
||||
|
|
|
@ -1338,14 +1338,14 @@
|
|||
(((ref rktio_t) rktio) (rktio_const_string_t name)))
|
||||
(define-function
|
||||
()
|
||||
(ref char)
|
||||
(ref void)
|
||||
rktio_push_c_numeric_locale
|
||||
(((ref rktio_t) rktio)))
|
||||
(define-function
|
||||
()
|
||||
void
|
||||
rktio_pop_c_numeric_locale
|
||||
(((ref rktio_t) rktio) ((*ref char) prev)))
|
||||
(((ref rktio_t) rktio) ((ref void) prev)))
|
||||
(define-function/errno
|
||||
NULL
|
||||
()
|
||||
|
|
|
@ -20,6 +20,21 @@
|
|||
# include <CoreFoundation/CFLocale.h>
|
||||
#endif
|
||||
|
||||
void rktio_convert_init(rktio_t *rktio) {
|
||||
#ifdef RKTIO_USE_XLOCALE
|
||||
rktio->locale = LC_GLOBAL_LOCALE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void rktio_convert_deinit(rktio_t *rktio) {
|
||||
#ifdef RKTIO_USE_XLOCALE
|
||||
if (rktio->locale != LC_GLOBAL_LOCALE) {
|
||||
freelocale(rktio->locale);
|
||||
rktio->locale = LC_GLOBAL_LOCALE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*============================================================*/
|
||||
/* Using iconv via a DLL */
|
||||
/*============================================================*/
|
||||
|
@ -228,6 +243,15 @@ int rktio_convert_properties(rktio_t *rktio)
|
|||
|
||||
void rktio_set_locale(rktio_t *rktio, const char *name)
|
||||
{
|
||||
#ifdef RKTIO_USE_XLOCALE
|
||||
if (rktio->locale != LC_GLOBAL_LOCALE) {
|
||||
freelocale(rktio->locale);
|
||||
rktio->locale = LC_GLOBAL_LOCALE;
|
||||
}
|
||||
rktio->locale = newlocale(LC_COLLATE_MASK | LC_CTYPE_MASK, name, NULL);
|
||||
if (rktio->locale == NULL)
|
||||
rktio->locale = LC_GLOBAL_LOCALE;
|
||||
#else
|
||||
/* We only need CTYPE and COLLATE; two calls seem to be much
|
||||
faster than one call with ALL */
|
||||
if (name) {
|
||||
|
@ -239,22 +263,32 @@ void rktio_set_locale(rktio_t *rktio, const char *name)
|
|||
setlocale(LC_CTYPE, "C");
|
||||
setlocale(LC_COLLATE, "C");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
char *rktio_push_c_numeric_locale(rktio_t *rktio)
|
||||
void *rktio_push_c_numeric_locale(rktio_t *rktio)
|
||||
{
|
||||
#ifdef RKTIO_USE_XLOCALE
|
||||
return (void *)uselocale(newlocale(LC_NUMERIC, "C", NULL));
|
||||
#else
|
||||
char *prev;
|
||||
prev = setlocale(LC_NUMERIC, NULL);
|
||||
if (!prev || !strcmp(prev, "C"))
|
||||
return NULL;
|
||||
else
|
||||
return setlocale(LC_NUMERIC, "C");
|
||||
#endif
|
||||
}
|
||||
|
||||
void rktio_pop_c_numeric_locale(rktio_t *rktio, char *prev)
|
||||
void rktio_pop_c_numeric_locale(rktio_t *rktio, void *prev)
|
||||
{
|
||||
#ifdef RKTIO_USE_XLOCALE
|
||||
locale_t tmp = uselocale((locale_t)prev);
|
||||
freelocale(tmp);
|
||||
#else
|
||||
if (prev)
|
||||
setlocale(LC_NUMERIC, prev);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*============================================================*/
|
||||
|
@ -263,7 +297,7 @@ void rktio_pop_c_numeric_locale(rktio_t *rktio, char *prev)
|
|||
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
|
||||
static char *nl_langinfo_dup()
|
||||
static char *nl_langinfo_dup(rktio_t *rktio)
|
||||
{
|
||||
int i;
|
||||
char *current_locale_name;
|
||||
|
@ -318,11 +352,15 @@ static char *nl_langinfo_dup()
|
|||
|
||||
#else
|
||||
|
||||
static char *nl_langinfo_dup()
|
||||
static char *nl_langinfo_dup(rktio_t *rktio)
|
||||
{
|
||||
char *s;
|
||||
# if HAVE_CODESET
|
||||
# ifdef RKTIO_USE_XLOCALE
|
||||
s = nl_langinfo_l(CODESET, rktio->locale);
|
||||
# else
|
||||
s = nl_langinfo(CODESET);
|
||||
# endif
|
||||
# else
|
||||
/* nl_langinfo doesn't work, so just make up something */
|
||||
s = "UTF-8";
|
||||
|
@ -335,7 +373,7 @@ static char *nl_langinfo_dup()
|
|||
|
||||
char *rktio_locale_encoding(rktio_t *rktio)
|
||||
{
|
||||
return nl_langinfo_dup();
|
||||
return nl_langinfo_dup(rktio);
|
||||
}
|
||||
|
||||
/*============================================================*/
|
||||
|
@ -539,7 +577,11 @@ char *rktio_locale_recase(rktio_t *rktio,
|
|||
/* Re-case chars in "out" */
|
||||
for (i = 0; i < iilen; i++) {
|
||||
char t;
|
||||
#ifdef RKTIO_USE_XLOCALE
|
||||
t = (to_up) ? toupper_l(out[i], rktio->locale) : tolower_l(out[i], rktio->locale);
|
||||
#else
|
||||
t = (to_up) ? toupper(out[i]) : tolower(out[i]);
|
||||
#endif
|
||||
out[i] = t;
|
||||
}
|
||||
|
||||
|
@ -553,9 +595,14 @@ char *rktio_locale_recase(rktio_t *rktio,
|
|||
wchar_t *wc, *ws, wcbuf[RKTIO_WC_BUF_SIZE], cwc;
|
||||
const char *s;
|
||||
unsigned int j;
|
||||
# ifdef RKTIO_USE_XLOCALE
|
||||
# define mz_mbsnrtowcs(t, f, fl, tl, s) mbsrtowcs_l(t, f, tl, s, rktio->locale)
|
||||
# define mz_wcsnrtombs(t, f, fl, tl, s) wcsrtombs_l(t, f, tl, s, rktio->locale)
|
||||
# else
|
||||
/* The "n" versions are apparently not too standard: */
|
||||
# define mz_mbsnrtowcs(t, f, fl, tl, s) mbsrtowcs(t, f, tl, s)
|
||||
# define mz_wcsnrtombs(t, f, fl, tl, s) wcsrtombs(t, f, tl, s)
|
||||
# endif
|
||||
|
||||
/* ----- to wide char ---- */
|
||||
|
||||
|
@ -584,12 +631,20 @@ char *rktio_locale_recase(rktio_t *rktio,
|
|||
|
||||
if (to_up) {
|
||||
for (j = 0; j < wl; j++) {
|
||||
# ifdef RKTIO_USE_XLOCALE
|
||||
cwc = towupper_l(wc[j], rktio->locale);
|
||||
# else
|
||||
cwc = towupper(wc[j]);
|
||||
#endif
|
||||
wc[j] = cwc;
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < wl; j++) {
|
||||
# ifdef RKTIO_USE_XLOCALE
|
||||
cwc = towlower_l(wc[j], rktio->locale);
|
||||
# else
|
||||
cwc = towlower(wc[j]);
|
||||
# endif
|
||||
wc[j] = cwc;
|
||||
}
|
||||
}
|
||||
|
@ -678,7 +733,11 @@ rktio_char16_t *rktio_recase_utf16(rktio_t *rktio, rktio_bool_t to_up, rktio_cha
|
|||
|
||||
int rktio_locale_strcoll(rktio_t *rktio, const char *s1, const char *s2)
|
||||
{
|
||||
#ifdef RKTIO_USE_XLOCALE
|
||||
return strcoll_l(s1, s2, rktio->locale);
|
||||
#else
|
||||
return strcoll(s1, s2);
|
||||
#endif
|
||||
}
|
||||
|
||||
int rktio_strcoll_utf16(rktio_t *rktio,
|
||||
|
|
|
@ -38,6 +38,8 @@ rktio_t *rktio_init(void)
|
|||
|
||||
rktio_syslog_init(rktio);
|
||||
|
||||
rktio_convert_init(rktio);
|
||||
|
||||
#ifdef OS_X
|
||||
{
|
||||
int a[2], i, k = 0;
|
||||
|
@ -66,6 +68,7 @@ void rktio_destroy(rktio_t *rktio)
|
|||
{
|
||||
rktio_stop_background(rktio);
|
||||
rktio_syslog_clean(rktio);
|
||||
rktio_convert_deinit(rktio);
|
||||
rktio_dll_clean(rktio);
|
||||
rktio_error_clean(rktio);
|
||||
rktio_process_deinit(rktio);
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
#ifdef RKTIO_USE_PTHREADS
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
#ifdef RKTIO_USE_XLOCALE
|
||||
# include <xlocale.h>
|
||||
#endif
|
||||
|
||||
#if defined(RKTIO_SYSTEM_UNIX) && !defined(RKTIO_STATIC_FDSET_SIZE)
|
||||
# define USE_DYNAMIC_FDSET_SIZE
|
||||
|
@ -132,6 +135,10 @@ struct rktio_t {
|
|||
#ifdef OS_X
|
||||
int macos_kernel_version; /* e.g., 10 => 10.6, 15 => 10.11 */
|
||||
#endif
|
||||
|
||||
#ifdef RKTIO_USE_XLOCALE
|
||||
locale_t locale;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*========================================================================*/
|
||||
|
@ -276,6 +283,9 @@ typedef char WIDE_PATH_t;
|
|||
|
||||
#endif
|
||||
|
||||
void rktio_convert_init(rktio_t *rktio);
|
||||
void rktio_convert_deinit(rktio_t *rktio);
|
||||
|
||||
/*========================================================================*/
|
||||
/* Hash table */
|
||||
/*========================================================================*/
|
||||
|
|
Loading…
Reference in New Issue
Block a user