1 /*----------------------------------------------------------------------- 2 * 3 * PostgreSQL locale utilities 4 * 5 * src/include/utils/pg_locale.h 6 * 7 * Copyright (c) 2002-2020, 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 **extra, GucSource source); 52 extern void assign_locale_messages(const char *newval, void *extra); 53 extern bool check_locale_monetary(char **newval, void **extra, GucSource source); 54 extern void assign_locale_monetary(const char *newval, void *extra); 55 extern bool check_locale_numeric(char **newval, void **extra, GucSource source); 56 extern void assign_locale_numeric(const char *newval, void *extra); 57 extern bool check_locale_time(char **newval, void **extra, GucSource source); 58 extern void assign_locale_time(const char *newval, void *extra); 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