| 1 | /*----------------------------------------------------------------------- |
| 2 | * |
| 3 | * PostgreSQL locale utilities |
| 4 | * |
| 5 | * src/include/utils/pg_locale.h |
| 6 | * |
| 7 | * Copyright (c) 2002-2019, PostgreSQL Global Development Group |
| 8 | * |
| 9 | *----------------------------------------------------------------------- |
| 10 | */ |
| 11 | |
| 12 | #ifndef _PG_LOCALE_ |
| 13 | #define _PG_LOCALE_ |
| 14 | |
| 15 | #if defined(LOCALE_T_IN_XLOCALE) || defined(WCSTOMBS_L_IN_XLOCALE) |
| 16 | #include <xlocale.h> |
| 17 | #endif |
| 18 | #ifdef USE_ICU |
| 19 | #include <unicode/ucol.h> |
| 20 | #endif |
| 21 | |
| 22 | #include "utils/guc.h" |
| 23 | |
| 24 | #ifdef USE_ICU |
| 25 | /* |
| 26 | * ucol_strcollUTF8() was introduced in ICU 50, but it is buggy before ICU 53. |
| 27 | * (see |
| 28 | * <https://www.postgresql.org/message-id/flat/f1438ec6-22aa-4029-9a3b-26f79d330e72%40manitou-mail.org>) |
| 29 | */ |
| 30 | #if U_ICU_VERSION_MAJOR_NUM >= 53 |
| 31 | #define HAVE_UCOL_STRCOLLUTF8 1 |
| 32 | #else |
| 33 | #undef HAVE_UCOL_STRCOLLUTF8 |
| 34 | #endif |
| 35 | #endif |
| 36 | |
| 37 | |
| 38 | /* GUC settings */ |
| 39 | extern char *locale_messages; |
| 40 | extern char *locale_monetary; |
| 41 | extern char *locale_numeric; |
| 42 | extern char *locale_time; |
| 43 | |
| 44 | /* lc_time localization cache */ |
| 45 | extern char *localized_abbrev_days[]; |
| 46 | extern char *localized_full_days[]; |
| 47 | extern char *localized_abbrev_months[]; |
| 48 | extern char *localized_full_months[]; |
| 49 | |
| 50 | |
| 51 | extern bool check_locale_messages(char **newval, void **, GucSource source); |
| 52 | extern void assign_locale_messages(const char *newval, void *); |
| 53 | extern bool check_locale_monetary(char **newval, void **, GucSource source); |
| 54 | extern void assign_locale_monetary(const char *newval, void *); |
| 55 | extern bool check_locale_numeric(char **newval, void **, GucSource source); |
| 56 | extern void assign_locale_numeric(const char *newval, void *); |
| 57 | extern bool check_locale_time(char **newval, void **, GucSource source); |
| 58 | extern void assign_locale_time(const char *newval, void *); |
| 59 | |
| 60 | extern bool check_locale(int category, const char *locale, char **canonname); |
| 61 | extern char *pg_perm_setlocale(int category, const char *locale); |
| 62 | extern void check_strxfrm_bug(void); |
| 63 | |
| 64 | extern bool lc_collate_is_c(Oid collation); |
| 65 | extern bool lc_ctype_is_c(Oid collation); |
| 66 | |
| 67 | /* |
| 68 | * Return the POSIX lconv struct (contains number/money formatting |
| 69 | * information) with locale information for all categories. |
| 70 | */ |
| 71 | extern struct lconv *PGLC_localeconv(void); |
| 72 | |
| 73 | extern void cache_locale_time(void); |
| 74 | |
| 75 | |
| 76 | /* |
| 77 | * We define our own wrapper around locale_t so we can keep the same |
| 78 | * function signatures for all builds, while not having to create a |
| 79 | * fake version of the standard type locale_t in the global namespace. |
| 80 | * pg_locale_t is occasionally checked for truth, so make it a pointer. |
| 81 | */ |
| 82 | struct pg_locale_struct |
| 83 | { |
| 84 | char provider; |
| 85 | bool deterministic; |
| 86 | union |
| 87 | { |
| 88 | #ifdef HAVE_LOCALE_T |
| 89 | locale_t lt; |
| 90 | #endif |
| 91 | #ifdef USE_ICU |
| 92 | struct |
| 93 | { |
| 94 | const char *locale; |
| 95 | UCollator *ucol; |
| 96 | } icu; |
| 97 | #endif |
| 98 | int dummy; /* in case we have neither LOCALE_T nor ICU */ |
| 99 | } info; |
| 100 | }; |
| 101 | |
| 102 | typedef struct pg_locale_struct *pg_locale_t; |
| 103 | |
| 104 | extern pg_locale_t pg_newlocale_from_collation(Oid collid); |
| 105 | |
| 106 | extern char *get_collation_actual_version(char collprovider, const char *collcollate); |
| 107 | |
| 108 | #ifdef USE_ICU |
| 109 | extern int32_t icu_to_uchar(UChar **buff_uchar, const char *buff, size_t nbytes); |
| 110 | extern int32_t icu_from_uchar(char **result, const UChar *buff_uchar, int32_t len_uchar); |
| 111 | #endif |
| 112 | |
| 113 | /* These functions convert from/to libc's wchar_t, *not* pg_wchar_t */ |
| 114 | extern size_t wchar2char(char *to, const wchar_t *from, size_t tolen, |
| 115 | pg_locale_t locale); |
| 116 | extern size_t char2wchar(wchar_t *to, size_t tolen, |
| 117 | const char *from, size_t fromlen, pg_locale_t locale); |
| 118 | |
| 119 | #endif /* _PG_LOCALE_ */ |
| 120 | |