diff options
Diffstat (limited to 'src/backend/utils/adt/pg_locale.c')
-rw-r--r-- | src/backend/utils/adt/pg_locale.c | 86 |
1 files changed, 32 insertions, 54 deletions
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index c8b36f3af2f..0eb764e8977 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -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); |