mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-01 20:30:28 +02:00
Language-specific case-conversion doesn't honor locale
Libunistring uses a function uc_locale_language to extract the current language from the locale information. It does this by calling setlocale. This makes incompatible with Guile functions that use the locale_t thread-specific locale API, because the values returned by the call to setlocale ignore the locale set by uselocale. As a workaround, this patch extracts the language from the locale_t structure's __names field. A more complete solution is needed. Perhaps that solution would test that the __names field exists in the configure step and revert to !USE_GNU_LOCALE_API in that case. * libguile/i18n.c (locale_language): new function that performs the same job as uc_locale_language but is compatible with uselocale (u32_locale_casecoll, u32_locale_tocase): replace uc_locale_language with locale_language
This commit is contained in:
parent
bcccf04158
commit
aafb5062b8
1 changed files with 49 additions and 5 deletions
|
@ -775,6 +775,50 @@ compare_u32_strings (SCM s1, SCM s2, SCM locale, const char *func_name)
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
/* Return the current language of the locale. */
|
||||||
|
static const char *
|
||||||
|
locale_language ()
|
||||||
|
{
|
||||||
|
#ifdef USE_GNU_LOCALE_API
|
||||||
|
{
|
||||||
|
static char lang[10];
|
||||||
|
scm_t_locale loc;
|
||||||
|
const char *c_result;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
/* If we are here, the locale has been set with 'uselocale'. We
|
||||||
|
can't use libunistring's uc_locale_language because it calls
|
||||||
|
setlocale. */
|
||||||
|
loc = uselocale (0);
|
||||||
|
if (loc == (scm_t_locale) -1)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
/* The internal structure of locale_t may be specific to the C
|
||||||
|
library, but, there doesn't seem to be any other way to extract
|
||||||
|
the locale name. */
|
||||||
|
c_result = loc->__names[LC_CTYPE];
|
||||||
|
p = (char *) c_result;
|
||||||
|
while (*p != '\0' && *p != '_' && *p != '.' && *p != '@')
|
||||||
|
p++;
|
||||||
|
|
||||||
|
/* Return a statically allocated pointer to the language portion,
|
||||||
|
so that the caller of this function does not need to free() the
|
||||||
|
result. */
|
||||||
|
if (p != c_result)
|
||||||
|
{
|
||||||
|
memcpy (lang, c_result, p - c_result);
|
||||||
|
lang[p - c_result] = '\0';
|
||||||
|
return lang;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* The locale has been set with setlocale. */
|
||||||
|
return uc_locale_language ();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
u32_locale_casecoll (const char *func_name, const scm_t_uint32 *c_s1,
|
u32_locale_casecoll (const char *func_name, const scm_t_uint32 *c_s1,
|
||||||
const scm_t_uint32 *c_s2,
|
const scm_t_uint32 *c_s2,
|
||||||
|
@ -784,7 +828,7 @@ u32_locale_casecoll (const char *func_name, const scm_t_uint32 *c_s1,
|
||||||
make any non-local exit. */
|
make any non-local exit. */
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
const char *loc = uc_locale_language ();
|
const char *loc = locale_language ();
|
||||||
|
|
||||||
ret = u32_casecoll (c_s1, u32_strlen (c_s1),
|
ret = u32_casecoll (c_s1, u32_strlen (c_s1),
|
||||||
c_s2, u32_strlen (c_s2),
|
c_s2, u32_strlen (c_s2),
|
||||||
|
@ -1081,7 +1125,7 @@ u32_locale_tocase (const scm_t_uint32 *c_s1, size_t len,
|
||||||
make any non-local exit. */
|
make any non-local exit. */
|
||||||
|
|
||||||
scm_t_uint32 *ret;
|
scm_t_uint32 *ret;
|
||||||
const char *loc = uc_locale_language ();
|
const char *loc = locale_language ();
|
||||||
|
|
||||||
/* The first NULL here indicates that no NFC or NFKC normalization
|
/* The first NULL here indicates that no NFC or NFKC normalization
|
||||||
is done. The second NULL means the return buffer is
|
is done. The second NULL means the return buffer is
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue