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. */
|
/* Returns the name of the current locale's encoding. */
|
||||||
|
|
||||||
RKTIO_EXTERN void rktio_set_locale(rktio_t *rktio, rktio_const_string_t name);
|
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
|
conversions. It can also affect the C library's character-property
|
||||||
predicates and number printing/parsing. The empty string
|
predicates and number printing/parsing by setting a thread-local or
|
||||||
corresponds to the OS's native locale. */
|
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_NOERR void *rktio_push_c_numeric_locale(rktio_t *rktio);
|
||||||
RKTIO_EXTERN void rktio_pop_c_numeric_locale(rktio_t *rktio, char *prev);
|
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
|
/* Use this pair of functions to temporarily switch the locale to the
|
||||||
locale for number parsing and printing. The result of the first
|
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. */
|
function is deallocated when passed to second function. */
|
||||||
|
|
||||||
RKTIO_EXTERN char *rktio_system_language_country(rktio_t *rktio);
|
RKTIO_EXTERN char *rktio_system_language_country(rktio_t *rktio);
|
||||||
|
|
|
@ -1338,14 +1338,14 @@
|
||||||
(((ref rktio_t) rktio) (rktio_const_string_t name)))
|
(((ref rktio_t) rktio) (rktio_const_string_t name)))
|
||||||
(define-function
|
(define-function
|
||||||
()
|
()
|
||||||
(ref char)
|
(ref void)
|
||||||
rktio_push_c_numeric_locale
|
rktio_push_c_numeric_locale
|
||||||
(((ref rktio_t) rktio)))
|
(((ref rktio_t) rktio)))
|
||||||
(define-function
|
(define-function
|
||||||
()
|
()
|
||||||
void
|
void
|
||||||
rktio_pop_c_numeric_locale
|
rktio_pop_c_numeric_locale
|
||||||
(((ref rktio_t) rktio) ((*ref char) prev)))
|
(((ref rktio_t) rktio) ((ref void) prev)))
|
||||||
(define-function/errno
|
(define-function/errno
|
||||||
NULL
|
NULL
|
||||||
()
|
()
|
||||||
|
|
|
@ -20,6 +20,21 @@
|
||||||
# include <CoreFoundation/CFLocale.h>
|
# include <CoreFoundation/CFLocale.h>
|
||||||
#endif
|
#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 */
|
/* 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)
|
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
|
/* We only need CTYPE and COLLATE; two calls seem to be much
|
||||||
faster than one call with ALL */
|
faster than one call with ALL */
|
||||||
if (name) {
|
if (name) {
|
||||||
|
@ -239,22 +263,32 @@ void rktio_set_locale(rktio_t *rktio, const char *name)
|
||||||
setlocale(LC_CTYPE, "C");
|
setlocale(LC_CTYPE, "C");
|
||||||
setlocale(LC_COLLATE, "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;
|
char *prev;
|
||||||
prev = setlocale(LC_NUMERIC, NULL);
|
prev = setlocale(LC_NUMERIC, NULL);
|
||||||
if (!prev || !strcmp(prev, "C"))
|
if (!prev || !strcmp(prev, "C"))
|
||||||
return NULL;
|
return NULL;
|
||||||
else
|
else
|
||||||
return setlocale(LC_NUMERIC, "C");
|
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)
|
if (prev)
|
||||||
setlocale(LC_NUMERIC, 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
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
|
|
||||||
static char *nl_langinfo_dup()
|
static char *nl_langinfo_dup(rktio_t *rktio)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char *current_locale_name;
|
char *current_locale_name;
|
||||||
|
@ -318,11 +352,15 @@ static char *nl_langinfo_dup()
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static char *nl_langinfo_dup()
|
static char *nl_langinfo_dup(rktio_t *rktio)
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
# if HAVE_CODESET
|
# if HAVE_CODESET
|
||||||
|
# ifdef RKTIO_USE_XLOCALE
|
||||||
|
s = nl_langinfo_l(CODESET, rktio->locale);
|
||||||
|
# else
|
||||||
s = nl_langinfo(CODESET);
|
s = nl_langinfo(CODESET);
|
||||||
|
# endif
|
||||||
# else
|
# else
|
||||||
/* nl_langinfo doesn't work, so just make up something */
|
/* nl_langinfo doesn't work, so just make up something */
|
||||||
s = "UTF-8";
|
s = "UTF-8";
|
||||||
|
@ -335,7 +373,7 @@ static char *nl_langinfo_dup()
|
||||||
|
|
||||||
char *rktio_locale_encoding(rktio_t *rktio)
|
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" */
|
/* Re-case chars in "out" */
|
||||||
for (i = 0; i < iilen; i++) {
|
for (i = 0; i < iilen; i++) {
|
||||||
char t;
|
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]);
|
t = (to_up) ? toupper(out[i]) : tolower(out[i]);
|
||||||
|
#endif
|
||||||
out[i] = t;
|
out[i] = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,9 +595,14 @@ char *rktio_locale_recase(rktio_t *rktio,
|
||||||
wchar_t *wc, *ws, wcbuf[RKTIO_WC_BUF_SIZE], cwc;
|
wchar_t *wc, *ws, wcbuf[RKTIO_WC_BUF_SIZE], cwc;
|
||||||
const char *s;
|
const char *s;
|
||||||
unsigned int j;
|
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: */
|
/* The "n" versions are apparently not too standard: */
|
||||||
# define mz_mbsnrtowcs(t, f, fl, tl, s) mbsrtowcs(t, f, tl, s)
|
# 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)
|
# define mz_wcsnrtombs(t, f, fl, tl, s) wcsrtombs(t, f, tl, s)
|
||||||
|
# endif
|
||||||
|
|
||||||
/* ----- to wide char ---- */
|
/* ----- to wide char ---- */
|
||||||
|
|
||||||
|
@ -584,12 +631,20 @@ char *rktio_locale_recase(rktio_t *rktio,
|
||||||
|
|
||||||
if (to_up) {
|
if (to_up) {
|
||||||
for (j = 0; j < wl; j++) {
|
for (j = 0; j < wl; j++) {
|
||||||
|
# ifdef RKTIO_USE_XLOCALE
|
||||||
|
cwc = towupper_l(wc[j], rktio->locale);
|
||||||
|
# else
|
||||||
cwc = towupper(wc[j]);
|
cwc = towupper(wc[j]);
|
||||||
|
#endif
|
||||||
wc[j] = cwc;
|
wc[j] = cwc;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (j = 0; j < wl; j++) {
|
for (j = 0; j < wl; j++) {
|
||||||
|
# ifdef RKTIO_USE_XLOCALE
|
||||||
|
cwc = towlower_l(wc[j], rktio->locale);
|
||||||
|
# else
|
||||||
cwc = towlower(wc[j]);
|
cwc = towlower(wc[j]);
|
||||||
|
# endif
|
||||||
wc[j] = cwc;
|
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)
|
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);
|
return strcoll(s1, s2);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int rktio_strcoll_utf16(rktio_t *rktio,
|
int rktio_strcoll_utf16(rktio_t *rktio,
|
||||||
|
|
|
@ -38,6 +38,8 @@ rktio_t *rktio_init(void)
|
||||||
|
|
||||||
rktio_syslog_init(rktio);
|
rktio_syslog_init(rktio);
|
||||||
|
|
||||||
|
rktio_convert_init(rktio);
|
||||||
|
|
||||||
#ifdef OS_X
|
#ifdef OS_X
|
||||||
{
|
{
|
||||||
int a[2], i, k = 0;
|
int a[2], i, k = 0;
|
||||||
|
@ -66,6 +68,7 @@ void rktio_destroy(rktio_t *rktio)
|
||||||
{
|
{
|
||||||
rktio_stop_background(rktio);
|
rktio_stop_background(rktio);
|
||||||
rktio_syslog_clean(rktio);
|
rktio_syslog_clean(rktio);
|
||||||
|
rktio_convert_deinit(rktio);
|
||||||
rktio_dll_clean(rktio);
|
rktio_dll_clean(rktio);
|
||||||
rktio_error_clean(rktio);
|
rktio_error_clean(rktio);
|
||||||
rktio_process_deinit(rktio);
|
rktio_process_deinit(rktio);
|
||||||
|
|
|
@ -11,6 +11,9 @@
|
||||||
#ifdef RKTIO_USE_PTHREADS
|
#ifdef RKTIO_USE_PTHREADS
|
||||||
# include <pthread.h>
|
# include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef RKTIO_USE_XLOCALE
|
||||||
|
# include <xlocale.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(RKTIO_SYSTEM_UNIX) && !defined(RKTIO_STATIC_FDSET_SIZE)
|
#if defined(RKTIO_SYSTEM_UNIX) && !defined(RKTIO_STATIC_FDSET_SIZE)
|
||||||
# define USE_DYNAMIC_FDSET_SIZE
|
# define USE_DYNAMIC_FDSET_SIZE
|
||||||
|
@ -132,6 +135,10 @@ struct rktio_t {
|
||||||
#ifdef OS_X
|
#ifdef OS_X
|
||||||
int macos_kernel_version; /* e.g., 10 => 10.6, 15 => 10.11 */
|
int macos_kernel_version; /* e.g., 10 => 10.6, 15 => 10.11 */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef RKTIO_USE_XLOCALE
|
||||||
|
locale_t locale;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/*========================================================================*/
|
/*========================================================================*/
|
||||||
|
@ -276,6 +283,9 @@ typedef char WIDE_PATH_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void rktio_convert_init(rktio_t *rktio);
|
||||||
|
void rktio_convert_deinit(rktio_t *rktio);
|
||||||
|
|
||||||
/*========================================================================*/
|
/*========================================================================*/
|
||||||
/* Hash table */
|
/* Hash table */
|
||||||
/*========================================================================*/
|
/*========================================================================*/
|
||||||
|
|
Loading…
Reference in New Issue
Block a user