mirror of
https://github.com/postgres/postgres.git
synced 2025-11-06 07:49:08 +03:00
All supported systems have locale_t.
locale_t is defined by POSIX.1-2008 and SUSv4, and available on all targeted systems. For Windows, win32_port.h redirects to a partial implementation called _locale_t. We can now remove a lot of compile-time tests for HAVE_LOCALE_T, and associated comments and dead code branches that were needed for older computers. Since configure + MinGW builds didn't detect locale_t but now we assume that all systems have it, further inconsistencies among the 3 Windows build systems were revealed. With this commit, we no longer define HAVE_WCSTOMBS_L and HAVE_MBSTOWCS_L on any Windows build system, but we have logic to deal with that so that replacements are available where appropriate. Reviewed-by: Noah Misch <noah@leadboat.com> Reviewed-by: Tristan Partin <tristan@neon.tech> Reviewed-by: Peter Eisentraut <peter@eisentraut.org> Discussion: https://postgr.es/m/CA%2BhUKGLg7_T2GKwZFAkEf0V7vbnur-NfCjZPKZb%3DZfAXSV1ORw%40mail.gmail.com
This commit is contained in:
@@ -154,6 +154,38 @@ static void icu_set_collation_attributes(UCollator *collator, const char *loc,
|
||||
UErrorCode *status);
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
/*
|
||||
* POSIX doesn't define _l-variants of these functions, but several systems
|
||||
* have them. We provide our own replacements here. For Windows, we have
|
||||
* macros in win32_port.h.
|
||||
*/
|
||||
#ifndef HAVE_MBSTOWCS_L
|
||||
static size_t
|
||||
mbstowcs_l(wchar_t *dest, const char *src, size_t n, locale_t loc)
|
||||
{
|
||||
size_t result;
|
||||
locale_t save_locale = uselocale(loc);
|
||||
|
||||
result = mbstowcs(dest, src, n);
|
||||
uselocale(save_locale);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
#ifndef HAVE_WCSTOMBS_L
|
||||
static size_t
|
||||
wcstombs_l(char *dest, const wchar_t *src, size_t n, locale_t loc)
|
||||
{
|
||||
size_t result;
|
||||
locale_t save_locale = uselocale(loc);
|
||||
|
||||
result = wcstombs(dest, src, n);
|
||||
uselocale(save_locale);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* pg_perm_setlocale
|
||||
*
|
||||
@@ -1420,7 +1452,6 @@ make_icu_collator(const char *iculocstr,
|
||||
|
||||
|
||||
/* simple subroutine for reporting errors from newlocale() */
|
||||
#ifdef HAVE_LOCALE_T
|
||||
static void
|
||||
report_newlocale_failure(const char *localename)
|
||||
{
|
||||
@@ -1449,7 +1480,6 @@ report_newlocale_failure(const char *localename)
|
||||
errdetail("The operating system could not find any locale data for the locale name \"%s\".",
|
||||
localename) : 0)));
|
||||
}
|
||||
#endif /* HAVE_LOCALE_T */
|
||||
|
||||
bool
|
||||
pg_locale_deterministic(pg_locale_t locale)
|
||||
@@ -1466,10 +1496,6 @@ pg_locale_deterministic(pg_locale_t locale)
|
||||
* lifetime of the backend. Thus, do not free the result with freelocale().
|
||||
*
|
||||
* As a special optimization, the default/database collation returns 0.
|
||||
* Callers should then revert to the non-locale_t-enabled code path.
|
||||
* Also, callers should avoid calling this before going down a C/POSIX
|
||||
* fastpath, because such a fastpath should work even on platforms without
|
||||
* locale_t support in the C library.
|
||||
*
|
||||
* For simplicity, we always generate COLLATE + CTYPE even though we
|
||||
* might only need one of them. Since this is called only once per session,
|
||||
@@ -1515,7 +1541,6 @@ pg_newlocale_from_collation(Oid collid)
|
||||
|
||||
if (collform->collprovider == COLLPROVIDER_LIBC)
|
||||
{
|
||||
#ifdef HAVE_LOCALE_T
|
||||
const char *collcollate;
|
||||
const char *collctype pg_attribute_unused();
|
||||
locale_t loc;
|
||||
@@ -1566,12 +1591,6 @@ pg_newlocale_from_collation(Oid collid)
|
||||
}
|
||||
|
||||
result.info.lt = loc;
|
||||
#else /* not HAVE_LOCALE_T */
|
||||
/* platform that doesn't support locale_t */
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("collation provider LIBC is not supported on this platform")));
|
||||
#endif /* not HAVE_LOCALE_T */
|
||||
}
|
||||
else if (collform->collprovider == COLLPROVIDER_ICU)
|
||||
{
|
||||
@@ -1788,11 +1807,9 @@ pg_strncoll_libc_win32_utf8(const char *arg1, size_t len1, const char *arg2,
|
||||
((LPWSTR) a2p)[r] = 0;
|
||||
|
||||
errno = 0;
|
||||
#ifdef HAVE_LOCALE_T
|
||||
if (locale)
|
||||
result = wcscoll_l((LPWSTR) a1p, (LPWSTR) a2p, locale->info.lt);
|
||||
else
|
||||
#endif
|
||||
result = wcscoll((LPWSTR) a1p, (LPWSTR) a2p);
|
||||
if (result == 2147483647) /* _NLSCMPERROR; missing from mingw headers */
|
||||
ereport(ERROR,
|
||||
@@ -1831,14 +1848,7 @@ pg_strcoll_libc(const char *arg1, const char *arg2, pg_locale_t locale)
|
||||
else
|
||||
#endif /* WIN32 */
|
||||
if (locale)
|
||||
{
|
||||
#ifdef HAVE_LOCALE_T
|
||||
result = strcoll_l(arg1, arg2, locale->info.lt);
|
||||
#else
|
||||
/* shouldn't happen */
|
||||
elog(ERROR, "unsupported collprovider: %c", locale->provider);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
result = strcoll(arg1, arg2);
|
||||
|
||||
@@ -2065,11 +2075,9 @@ pg_strxfrm_libc(char *dest, const char *src, size_t destsize,
|
||||
Assert(!locale || locale->provider == COLLPROVIDER_LIBC);
|
||||
|
||||
#ifdef TRUST_STRXFRM
|
||||
#ifdef HAVE_LOCALE_T
|
||||
if (locale)
|
||||
return strxfrm_l(dest, src, destsize, locale->info.lt);
|
||||
else
|
||||
#endif
|
||||
return strxfrm(dest, src, destsize);
|
||||
#else
|
||||
/* shouldn't happen */
|
||||
@@ -2955,23 +2963,8 @@ wchar2char(char *to, const wchar_t *from, size_t tolen, pg_locale_t locale)
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_LOCALE_T
|
||||
#ifdef HAVE_WCSTOMBS_L
|
||||
/* Use wcstombs_l for nondefault locales */
|
||||
result = wcstombs_l(to, from, tolen, locale->info.lt);
|
||||
#else /* !HAVE_WCSTOMBS_L */
|
||||
/* We have to temporarily set the locale as current ... ugh */
|
||||
locale_t save_locale = uselocale(locale->info.lt);
|
||||
|
||||
result = wcstombs(to, from, tolen);
|
||||
|
||||
uselocale(save_locale);
|
||||
#endif /* HAVE_WCSTOMBS_L */
|
||||
#else /* !HAVE_LOCALE_T */
|
||||
/* Can't have locale != 0 without HAVE_LOCALE_T */
|
||||
elog(ERROR, "wcstombs_l is not available");
|
||||
result = 0; /* keep compiler quiet */
|
||||
#endif /* HAVE_LOCALE_T */
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -3032,23 +3025,8 @@ char2wchar(wchar_t *to, size_t tolen, const char *from, size_t fromlen,
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_LOCALE_T
|
||||
#ifdef HAVE_MBSTOWCS_L
|
||||
/* Use mbstowcs_l for nondefault locales */
|
||||
result = mbstowcs_l(to, str, tolen, locale->info.lt);
|
||||
#else /* !HAVE_MBSTOWCS_L */
|
||||
/* We have to temporarily set the locale as current ... ugh */
|
||||
locale_t save_locale = uselocale(locale->info.lt);
|
||||
|
||||
result = mbstowcs(to, str, tolen);
|
||||
|
||||
uselocale(save_locale);
|
||||
#endif /* HAVE_MBSTOWCS_L */
|
||||
#else /* !HAVE_LOCALE_T */
|
||||
/* Can't have locale != 0 without HAVE_LOCALE_T */
|
||||
elog(ERROR, "mbstowcs_l is not available");
|
||||
result = 0; /* keep compiler quiet */
|
||||
#endif /* HAVE_LOCALE_T */
|
||||
}
|
||||
|
||||
pfree(str);
|
||||
|
||||
Reference in New Issue
Block a user