PostgreSQL Source Code git master
pg_locale_libc.c File Reference
#include "postgres.h"
#include <limits.h>
#include <wctype.h>
#include "access/htup_details.h"
#include "catalog/pg_database.h"
#include "catalog/pg_collation.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/formatting.h"
#include "utils/memutils.h"
#include "utils/pg_locale.h"
#include "utils/syscache.h"
Include dependency graph for pg_locale_libc.c:

Go to the source code of this file.

Macros

#define TEXTBUFLEN   1024
 

Functions

pg_locale_t create_pg_locale_libc (Oid collid, MemoryContext context)
 
static int strncoll_libc (const char *arg1, ssize_t len1, const char *arg2, ssize_t len2, pg_locale_t locale)
 
static size_t strnxfrm_libc (char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
char * get_collation_actual_version_libc (const char *collcollate)
 
static locale_t make_libc_collator (const char *collate, const char *ctype)
 
static size_t char2wchar (wchar_t *to, size_t tolen, const char *from, size_t fromlen, locale_t loc)
 
static size_t strlower_libc_sb (char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
static size_t strlower_libc_mb (char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
static size_t strtitle_libc_sb (char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
static size_t strtitle_libc_mb (char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
static size_t strupper_libc_sb (char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
static size_t strupper_libc_mb (char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
static bool wc_isdigit_libc_sb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_isalpha_libc_sb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_isalnum_libc_sb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_isupper_libc_sb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_islower_libc_sb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_isgraph_libc_sb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_isprint_libc_sb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_ispunct_libc_sb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_isspace_libc_sb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_isxdigit_libc_sb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_iscased_libc_sb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_isdigit_libc_mb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_isalpha_libc_mb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_isalnum_libc_mb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_isupper_libc_mb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_islower_libc_mb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_isgraph_libc_mb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_isprint_libc_mb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_ispunct_libc_mb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_isspace_libc_mb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_isxdigit_libc_mb (pg_wchar wc, pg_locale_t locale)
 
static bool wc_iscased_libc_mb (pg_wchar wc, pg_locale_t locale)
 
static pg_wchar toupper_libc_sb (pg_wchar wc, pg_locale_t locale)
 
static pg_wchar toupper_libc_mb (pg_wchar wc, pg_locale_t locale)
 
static pg_wchar tolower_libc_sb (pg_wchar wc, pg_locale_t locale)
 
static pg_wchar tolower_libc_mb (pg_wchar wc, pg_locale_t locale)
 
static size_t downcase_ident_libc_sb (char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
void report_newlocale_failure (const char *localename)
 
static size_t mbstowcs_l (wchar_t *dest, const char *src, size_t n, locale_t loc)
 
static size_t wcstombs_l (char *dest, const wchar_t *src, size_t n, locale_t loc)
 
size_t wchar2char (char *to, const wchar_t *from, size_t tolen, locale_t loc)
 

Variables

static const struct ctype_methods ctype_methods_libc_sb
 
static const struct ctype_methods ctype_methods_libc_other_mb
 
static const struct ctype_methods ctype_methods_libc_utf8
 
static const struct collate_methods collate_methods_libc
 

Macro Definition Documentation

◆ TEXTBUFLEN

#define TEXTBUFLEN   1024

Definition at line 81 of file pg_locale_libc.c.

Function Documentation

◆ char2wchar()

static size_t char2wchar ( wchar_t *  to,
size_t  tolen,
const char *  from,
size_t  fromlen,
locale_t  loc 
)
static

Definition at line 1259 of file pg_locale_libc.c.

1261{
1262 size_t result;
1263
1264 if (tolen == 0)
1265 return 0;
1266
1267#ifdef WIN32
1268 /* See WIN32 "Unicode" comment above */
1270 {
1271 /* Win32 API does not work for zero-length input */
1272 if (fromlen == 0)
1273 result = 0;
1274 else
1275 {
1276 result = MultiByteToWideChar(CP_UTF8, 0, from, fromlen, to, tolen - 1);
1277 /* A zero return is failure */
1278 if (result == 0)
1279 result = -1;
1280 }
1281
1282 if (result != -1)
1283 {
1284 Assert(result < tolen);
1285 /* Append trailing null wchar (MultiByteToWideChar() does not) */
1286 to[result] = 0;
1287 }
1288 }
1289 else
1290#endif /* WIN32 */
1291 {
1292 /* mbstowcs requires ending '\0' */
1293 char *str = pnstrdup(from, fromlen);
1294
1295 if (loc == (locale_t) 0)
1296 {
1297 /* Use mbstowcs directly for the default locale */
1298 result = mbstowcs(to, str, tolen);
1299 }
1300 else
1301 {
1302 /* Use mbstowcs_l for nondefault locales */
1303 result = mbstowcs_l(to, str, tolen, loc);
1304 }
1305
1306 pfree(str);
1307 }
1308
1309 if (result == -1)
1310 {
1311 /*
1312 * Invalid multibyte character encountered. We try to give a useful
1313 * error message by letting pg_verifymbstr check the string. But it's
1314 * possible that the string is OK to us, and not OK to mbstowcs ---
1315 * this suggests that the LC_CTYPE locale is different from the
1316 * database encoding. Give a generic error message if pg_verifymbstr
1317 * can't find anything wrong.
1318 */
1319 pg_verifymbstr(from, fromlen, false); /* might not return */
1320 /* but if it does ... */
1321 ereport(ERROR,
1322 (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
1323 errmsg("invalid multibyte character for locale"),
1324 errhint("The server's LC_CTYPE locale is probably incompatible with the database encoding.")));
1325 }
1326
1327 return result;
1328}
int errhint(const char *fmt,...)
Definition: elog.c:1330
int errcode(int sqlerrcode)
Definition: elog.c:863
int errmsg(const char *fmt,...)
Definition: elog.c:1080
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:150
Assert(PointerIsAligned(start, uint64))
const char * str
int GetDatabaseEncoding(void)
Definition: mbutils.c:1264
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
Definition: mbutils.c:1559
void pfree(void *pointer)
Definition: mcxt.c:1616
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1792
static size_t mbstowcs_l(wchar_t *dest, const char *src, size_t n, locale_t loc)
@ PG_UTF8
Definition: pg_wchar.h:232
#define locale_t
Definition: win32_port.h:429

References Assert(), ereport, errcode(), errhint(), errmsg(), ERROR, GetDatabaseEncoding(), locale_t, mbstowcs_l(), pfree(), PG_UTF8, pg_verifymbstr(), pnstrdup(), and str.

Referenced by strlower_libc_mb(), strtitle_libc_mb(), and strupper_libc_mb().

◆ create_pg_locale_libc()

pg_locale_t create_pg_locale_libc ( Oid  collid,
MemoryContext  context 
)

Definition at line 741 of file pg_locale_libc.c.

742{
743 const char *collate;
744 const char *ctype;
745 locale_t loc;
746 pg_locale_t result;
747
748 if (collid == DEFAULT_COLLATION_OID)
749 {
750 HeapTuple tp;
751 Datum datum;
752
754 if (!HeapTupleIsValid(tp))
755 elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
756 datum = SysCacheGetAttrNotNull(DATABASEOID, tp,
757 Anum_pg_database_datcollate);
758 collate = TextDatumGetCString(datum);
759 datum = SysCacheGetAttrNotNull(DATABASEOID, tp,
760 Anum_pg_database_datctype);
761 ctype = TextDatumGetCString(datum);
762
763 ReleaseSysCache(tp);
764 }
765 else
766 {
767 HeapTuple tp;
768 Datum datum;
769
771 if (!HeapTupleIsValid(tp))
772 elog(ERROR, "cache lookup failed for collation %u", collid);
773
774 datum = SysCacheGetAttrNotNull(COLLOID, tp,
775 Anum_pg_collation_collcollate);
776 collate = TextDatumGetCString(datum);
777 datum = SysCacheGetAttrNotNull(COLLOID, tp,
778 Anum_pg_collation_collctype);
779 ctype = TextDatumGetCString(datum);
780
781 ReleaseSysCache(tp);
782 }
783
784
785 loc = make_libc_collator(collate, ctype);
786
787 result = MemoryContextAllocZero(context, sizeof(struct pg_locale_struct));
788 result->deterministic = true;
789 result->collate_is_c = (strcmp(collate, "C") == 0) ||
790 (strcmp(collate, "POSIX") == 0);
791 result->ctype_is_c = (strcmp(ctype, "C") == 0) ||
792 (strcmp(ctype, "POSIX") == 0);
793 result->lt = loc;
794 if (!result->collate_is_c)
795 {
796#ifdef WIN32
798 result->collate = &collate_methods_libc_win32_utf8;
799 else
800#endif
801 result->collate = &collate_methods_libc;
802 }
803 if (!result->ctype_is_c)
804 {
809 else
810 result->ctype = &ctype_methods_libc_sb;
811 }
812
813 return result;
814}
#define TextDatumGetCString(d)
Definition: builtins.h:98
Oid collid
#define elog(elevel,...)
Definition: elog.h:226
Oid MyDatabaseId
Definition: globals.c:94
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1549
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1266
static const struct ctype_methods ctype_methods_libc_other_mb
static const struct ctype_methods ctype_methods_libc_utf8
static locale_t make_libc_collator(const char *collate, const char *ctype)
static const struct collate_methods collate_methods_libc
static const struct ctype_methods ctype_methods_libc_sb
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:262
uint64_t Datum
Definition: postgres.h:70
const struct ctype_methods * ctype
Definition: pg_locale.h:155
const struct collate_methods * collate
Definition: pg_locale.h:154
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:264
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:220
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition: syscache.c:625

References pg_locale_struct::collate, pg_locale_struct::collate_is_c, collate_methods_libc, collid, pg_locale_struct::ctype, pg_locale_struct::ctype_is_c, ctype_methods_libc_other_mb, ctype_methods_libc_sb, ctype_methods_libc_utf8, pg_locale_struct::deterministic, elog, ERROR, GetDatabaseEncoding(), HeapTupleIsValid, if(), locale_t, pg_locale_struct::lt, make_libc_collator(), MemoryContextAllocZero(), MyDatabaseId, ObjectIdGetDatum(), pg_database_encoding_max_length(), PG_UTF8, ReleaseSysCache(), SearchSysCache1(), SysCacheGetAttrNotNull(), and TextDatumGetCString.

Referenced by create_pg_locale(), and init_database_collation().

◆ downcase_ident_libc_sb()

static size_t downcase_ident_libc_sb ( char *  dst,
size_t  dstsize,
const char *  src,
ssize_t  srclen,
pg_locale_t  locale 
)
static

Definition at line 326 of file pg_locale_libc.c.

328{
329 locale_t loc = locale->lt;
330 int i;
331
332 for (i = 0; i < srclen && i < dstsize; i++)
333 {
334 unsigned char ch = (unsigned char) src[i];
335
336 if (ch >= 'A' && ch <= 'Z')
337 ch = pg_ascii_tolower(ch);
338 else if (IS_HIGHBIT_SET(ch) && isupper_l(ch, loc))
339 ch = tolower_l(ch, loc);
340 dst[i] = (char) ch;
341 }
342
343 if (i < dstsize)
344 dst[i] = '\0';
345
346 return srclen;
347}
#define IS_HIGHBIT_SET(ch)
Definition: c.h:1132
static char * locale
Definition: initdb.c:140
int i
Definition: isn.c:77
static unsigned char pg_ascii_tolower(unsigned char ch)
Definition: port.h:188
#define tolower_l
Definition: win32_port.h:430
#define isupper_l
Definition: win32_port.h:440

References i, IS_HIGHBIT_SET, isupper_l, locale, locale_t, pg_ascii_tolower(), and tolower_l.

◆ get_collation_actual_version_libc()

char * get_collation_actual_version_libc ( const char *  collcollate)

Definition at line 983 of file pg_locale_libc.c.

984{
985 char *collversion = NULL;
986
987 if (pg_strcasecmp("C", collcollate) != 0 &&
988 pg_strncasecmp("C.", collcollate, 2) != 0 &&
989 pg_strcasecmp("POSIX", collcollate) != 0)
990 {
991#if defined(__GLIBC__)
992 /* Use the glibc version because we don't have anything better. */
993 collversion = pstrdup(gnu_get_libc_version());
994#elif defined(LC_VERSION_MASK)
995 locale_t loc;
996
997 /* Look up FreeBSD collation version. */
998 loc = newlocale(LC_COLLATE_MASK, collcollate, NULL);
999 if (loc)
1000 {
1001 collversion =
1002 pstrdup(querylocale(LC_COLLATE_MASK | LC_VERSION_MASK, loc));
1003 freelocale(loc);
1004 }
1005 else
1006 ereport(ERROR,
1007 (errmsg("could not load locale \"%s\"", collcollate)));
1008#elif defined(WIN32)
1009 /*
1010 * If we are targeting Windows Vista and above, we can ask for a name
1011 * given a collation name (earlier versions required a location code
1012 * that we don't have).
1013 */
1014 NLSVERSIONINFOEX version = {sizeof(NLSVERSIONINFOEX)};
1015 WCHAR wide_collcollate[LOCALE_NAME_MAX_LENGTH];
1016
1017 MultiByteToWideChar(CP_ACP, 0, collcollate, -1, wide_collcollate,
1018 LOCALE_NAME_MAX_LENGTH);
1019 if (!GetNLSVersionEx(COMPARE_STRING, wide_collcollate, &version))
1020 {
1021 /*
1022 * GetNLSVersionEx() wants a language tag such as "en-US", not a
1023 * locale name like "English_United States.1252". Until those
1024 * values can be prevented from entering the system, or 100%
1025 * reliably converted to the more useful tag format, tolerate the
1026 * resulting error and report that we have no version data.
1027 */
1028 if (GetLastError() == ERROR_INVALID_PARAMETER)
1029 return NULL;
1030
1031 ereport(ERROR,
1032 (errmsg("could not get collation version for locale \"%s\": error code %lu",
1033 collcollate,
1034 GetLastError())));
1035 }
1036 collversion = psprintf("%lu.%lu,%lu.%lu",
1037 (version.dwNLSVersion >> 8) & 0xFFFF,
1038 version.dwNLSVersion & 0xFF,
1039 (version.dwDefinedVersion >> 8) & 0xFFFF,
1040 version.dwDefinedVersion & 0xFF);
1041#endif
1042 }
1043
1044 return collversion;
1045}
char * pstrdup(const char *in)
Definition: mcxt.c:1781
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:32
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:65
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43

References ereport, errmsg(), ERROR, locale_t, pg_strcasecmp(), pg_strncasecmp(), psprintf(), and pstrdup().

Referenced by get_collation_actual_version().

◆ make_libc_collator()

static locale_t make_libc_collator ( const char *  collate,
const char *  ctype 
)
static

Definition at line 825 of file pg_locale_libc.c.

826{
827 locale_t loc = 0;
828
829 if (strcmp(collate, ctype) == 0)
830 {
831 if (strcmp(ctype, "C") != 0 && strcmp(ctype, "POSIX") != 0)
832 {
833 /* Normal case where they're the same */
834 errno = 0;
835#ifndef WIN32
836 loc = newlocale(LC_COLLATE_MASK | LC_CTYPE_MASK, collate,
837 NULL);
838#else
839 loc = _create_locale(LC_ALL, collate);
840#endif
841 if (!loc)
843 }
844 }
845 else
846 {
847#ifndef WIN32
848 /* We need two newlocale() steps */
849 locale_t loc1 = 0;
850
851 if (strcmp(collate, "C") != 0 && strcmp(collate, "POSIX") != 0)
852 {
853 errno = 0;
854 loc1 = newlocale(LC_COLLATE_MASK, collate, NULL);
855 if (!loc1)
857 }
858
859 if (strcmp(ctype, "C") != 0 && strcmp(ctype, "POSIX") != 0)
860 {
861 errno = 0;
862 loc = newlocale(LC_CTYPE_MASK, ctype, loc1);
863 if (!loc)
864 {
865 if (loc1)
866 freelocale(loc1);
868 }
869 }
870 else
871 loc = loc1;
872#else
873
874 /*
875 * XXX The _create_locale() API doesn't appear to support this. Could
876 * perhaps be worked around by changing pg_locale_t to contain two
877 * separate fields.
878 */
880 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
881 errmsg("collations with different collate and ctype values are not supported on this platform")));
882#endif
883 }
884
885 return loc;
886}
void report_newlocale_failure(const char *localename)

References ereport, errcode(), errmsg(), ERROR, locale_t, and report_newlocale_failure().

Referenced by create_pg_locale_libc().

◆ mbstowcs_l()

static size_t mbstowcs_l ( wchar_t *  dest,
const char *  src,
size_t  n,
locale_t  loc 
)
static

Definition at line 1161 of file pg_locale_libc.c.

1162{
1163#ifdef WIN32
1164 return _mbstowcs_l(dest, src, n, loc);
1165#else
1166 size_t result;
1167 locale_t save_locale = uselocale(loc);
1168
1169 result = mbstowcs(dest, src, n);
1170 uselocale(save_locale);
1171 return result;
1172#endif
1173}

References generate_unaccent_rules::dest, and locale_t.

Referenced by char2wchar().

◆ report_newlocale_failure()

void report_newlocale_failure ( const char *  localename)

Definition at line 1127 of file pg_locale_libc.c.

1128{
1129 int save_errno;
1130
1131 /*
1132 * Windows doesn't provide any useful error indication from
1133 * _create_locale(), and BSD-derived platforms don't seem to feel they
1134 * need to set errno either (even though POSIX is pretty clear that
1135 * newlocale should do so). So, if errno hasn't been set, assume ENOENT
1136 * is what to report.
1137 */
1138 if (errno == 0)
1139 errno = ENOENT;
1140
1141 /*
1142 * ENOENT means "no such locale", not "no such file", so clarify that
1143 * errno with an errdetail message.
1144 */
1145 save_errno = errno; /* auxiliary funcs might change errno */
1146 ereport(ERROR,
1147 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1148 errmsg("could not create locale \"%s\": %m",
1149 localename),
1150 (save_errno == ENOENT ?
1151 errdetail("The operating system could not find any locale data for the locale name \"%s\".",
1152 localename) : 0)));
1153}
int errdetail(const char *fmt,...)
Definition: elog.c:1216

References ereport, errcode(), errdetail(), errmsg(), and ERROR.

Referenced by cache_locale_time(), and make_libc_collator().

◆ strlower_libc_mb()

static size_t strlower_libc_mb ( char *  dest,
size_t  destsize,
const char *  src,
ssize_t  srclen,
pg_locale_t  locale 
)
static

Definition at line 495 of file pg_locale_libc.c.

497{
498 locale_t loc = locale->lt;
499 size_t result_size;
500 wchar_t *workspace;
501 char *result;
502 size_t curr_char;
503 size_t max_size;
504
505 if (srclen < 0)
506 srclen = strlen(src);
507
508 /* Overflow paranoia */
509 if ((srclen + 1) > (INT_MAX / sizeof(wchar_t)))
511 (errcode(ERRCODE_OUT_OF_MEMORY),
512 errmsg("out of memory")));
513
514 /* Output workspace cannot have more codes than input bytes */
515 workspace = palloc_array(wchar_t, srclen + 1);
516
517 char2wchar(workspace, srclen + 1, src, srclen, loc);
518
519 for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
520 workspace[curr_char] = towlower_l(workspace[curr_char], loc);
521
522 /*
523 * Make result large enough; case change might change number of bytes
524 */
525 max_size = curr_char * pg_database_encoding_max_length();
526 result = palloc(max_size + 1);
527
528 result_size = wchar2char(result, workspace, max_size + 1, loc);
529
530 if (result_size + 1 > destsize)
531 return result_size;
532
533 memcpy(dest, result, result_size);
534 dest[result_size] = '\0';
535
536 pfree(workspace);
537 pfree(result);
538
539 return result_size;
540}
#define palloc_array(type, count)
Definition: fe_memutils.h:76
void * palloc(Size size)
Definition: mcxt.c:1387
size_t wchar2char(char *to, const wchar_t *from, size_t tolen, locale_t loc)
static size_t char2wchar(wchar_t *to, size_t tolen, const char *from, size_t fromlen, locale_t loc)
#define towlower_l
Definition: win32_port.h:432

References char2wchar(), generate_unaccent_rules::dest, ereport, errcode(), errmsg(), ERROR, locale, locale_t, palloc(), palloc_array, pfree(), pg_database_encoding_max_length(), towlower_l, and wchar2char().

◆ strlower_libc_sb()

static size_t strlower_libc_sb ( char *  dest,
size_t  destsize,
const char *  src,
ssize_t  srclen,
pg_locale_t  locale 
)
static

Definition at line 456 of file pg_locale_libc.c.

458{
459 if (srclen < 0)
460 srclen = strlen(src);
461
462 if (srclen + 1 <= destsize)
463 {
464 locale_t loc = locale->lt;
465 char *p;
466
467 memcpy(dest, src, srclen);
468 dest[srclen] = '\0';
469
470 /*
471 * Note: we assume that tolower_l() will not be so broken as to need
472 * an isupper_l() guard test. When using the default collation, we
473 * apply the traditional Postgres behavior that forces ASCII-style
474 * treatment of I/i, but in non-default collations you get exactly
475 * what the collation says.
476 */
477 for (p = dest; *p; p++)
478 {
479 if (locale->is_default)
480 {
481 if (*p >= 'A' && *p <= 'Z')
482 *p += 'a' - 'A';
483 else if (IS_HIGHBIT_SET(*p) && isupper_l(*p, loc))
484 *p = tolower_l((unsigned char) *p, loc);
485 }
486 else
487 *p = tolower_l((unsigned char) *p, loc);
488 }
489 }
490
491 return srclen;
492}

References generate_unaccent_rules::dest, IS_HIGHBIT_SET, isupper_l, locale, locale_t, and tolower_l.

◆ strncoll_libc()

int strncoll_libc ( const char *  arg1,
ssize_t  len1,
const char *  arg2,
ssize_t  len2,
pg_locale_t  locale 
)
static

Definition at line 896 of file pg_locale_libc.c.

898{
899 char sbuf[TEXTBUFLEN];
900 char *buf = sbuf;
901 size_t bufsize1 = (len1 == -1) ? 0 : len1 + 1;
902 size_t bufsize2 = (len2 == -1) ? 0 : len2 + 1;
903 const char *arg1n;
904 const char *arg2n;
905 int result;
906
907 if (bufsize1 + bufsize2 > TEXTBUFLEN)
908 buf = palloc(bufsize1 + bufsize2);
909
910 /* nul-terminate arguments if necessary */
911 if (len1 == -1)
912 {
913 arg1n = arg1;
914 }
915 else
916 {
917 char *buf1 = buf;
918
919 memcpy(buf1, arg1, len1);
920 buf1[len1] = '\0';
921 arg1n = buf1;
922 }
923
924 if (len2 == -1)
925 {
926 arg2n = arg2;
927 }
928 else
929 {
930 char *buf2 = buf + bufsize1;
931
932 memcpy(buf2, arg2, len2);
933 buf2[len2] = '\0';
934 arg2n = buf2;
935 }
936
937 result = strcoll_l(arg1n, arg2n, locale->lt);
938
939 if (buf != sbuf)
940 pfree(buf);
941
942 return result;
943}
#define TEXTBUFLEN
static char buf[DEFAULT_XLOG_SEG_SIZE]
Definition: pg_test_fsync.c:71
#define strcoll_l
Definition: win32_port.h:452

References buf, locale, palloc(), pfree(), strcoll_l, and TEXTBUFLEN.

◆ strnxfrm_libc()

size_t strnxfrm_libc ( char *  dest,
size_t  destsize,
const char *  src,
ssize_t  srclen,
pg_locale_t  locale 
)
static

Definition at line 953 of file pg_locale_libc.c.

955{
956 char sbuf[TEXTBUFLEN];
957 char *buf = sbuf;
958 size_t bufsize = srclen + 1;
959 size_t result;
960
961 if (srclen == -1)
962 return strxfrm_l(dest, src, destsize, locale->lt);
963
964 if (bufsize > TEXTBUFLEN)
965 buf = palloc(bufsize);
966
967 /* nul-terminate argument */
968 memcpy(buf, src, srclen);
969 buf[srclen] = '\0';
970
971 result = strxfrm_l(dest, buf, destsize, locale->lt);
972
973 if (buf != sbuf)
974 pfree(buf);
975
976 /* if dest is defined, it should be nul-terminated */
977 Assert(result >= destsize || dest[result] == '\0');
978
979 return result;
980}
#define bufsize
Definition: indent_globs.h:36
#define strxfrm_l
Definition: win32_port.h:453

References Assert(), buf, bufsize, generate_unaccent_rules::dest, locale, palloc(), pfree(), strxfrm_l, and TEXTBUFLEN.

◆ strtitle_libc_mb()

static size_t strtitle_libc_mb ( char *  dest,
size_t  destsize,
const char *  src,
ssize_t  srclen,
pg_locale_t  locale 
)
static

Definition at line 599 of file pg_locale_libc.c.

601{
602 locale_t loc = locale->lt;
603 int wasalnum = false;
604 size_t result_size;
605 wchar_t *workspace;
606 char *result;
607 size_t curr_char;
608 size_t max_size;
609
610 if (srclen < 0)
611 srclen = strlen(src);
612
613 /* Overflow paranoia */
614 if ((srclen + 1) > (INT_MAX / sizeof(wchar_t)))
616 (errcode(ERRCODE_OUT_OF_MEMORY),
617 errmsg("out of memory")));
618
619 /* Output workspace cannot have more codes than input bytes */
620 workspace = palloc_array(wchar_t, srclen + 1);
621
622 char2wchar(workspace, srclen + 1, src, srclen, loc);
623
624 for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
625 {
626 if (wasalnum)
627 workspace[curr_char] = towlower_l(workspace[curr_char], loc);
628 else
629 workspace[curr_char] = towupper_l(workspace[curr_char], loc);
630 wasalnum = iswalnum_l(workspace[curr_char], loc);
631 }
632
633 /*
634 * Make result large enough; case change might change number of bytes
635 */
636 max_size = curr_char * pg_database_encoding_max_length();
637 result = palloc(max_size + 1);
638
639 result_size = wchar2char(result, workspace, max_size + 1, loc);
640
641 if (result_size + 1 > destsize)
642 return result_size;
643
644 memcpy(dest, result, result_size);
645 dest[result_size] = '\0';
646
647 pfree(workspace);
648 pfree(result);
649
650 return result_size;
651}
#define iswalnum_l
Definition: win32_port.h:439
#define towupper_l
Definition: win32_port.h:433

References char2wchar(), generate_unaccent_rules::dest, ereport, errcode(), errmsg(), ERROR, iswalnum_l, locale, locale_t, palloc(), palloc_array, pfree(), pg_database_encoding_max_length(), towlower_l, towupper_l, and wchar2char().

◆ strtitle_libc_sb()

static size_t strtitle_libc_sb ( char *  dest,
size_t  destsize,
const char *  src,
ssize_t  srclen,
pg_locale_t  locale 
)
static

Definition at line 543 of file pg_locale_libc.c.

545{
546 if (srclen < 0)
547 srclen = strlen(src);
548
549 if (srclen + 1 <= destsize)
550 {
551 locale_t loc = locale->lt;
552 int wasalnum = false;
553 char *p;
554
555 memcpy(dest, src, srclen);
556 dest[srclen] = '\0';
557
558 /*
559 * Note: we assume that toupper_l()/tolower_l() will not be so broken
560 * as to need guard tests. When using the default collation, we apply
561 * the traditional Postgres behavior that forces ASCII-style treatment
562 * of I/i, but in non-default collations you get exactly what the
563 * collation says.
564 */
565 for (p = dest; *p; p++)
566 {
567 if (locale->is_default)
568 {
569 if (wasalnum)
570 {
571 if (*p >= 'A' && *p <= 'Z')
572 *p += 'a' - 'A';
573 else if (IS_HIGHBIT_SET(*p) && isupper_l(*p, loc))
574 *p = tolower_l((unsigned char) *p, loc);
575 }
576 else
577 {
578 if (*p >= 'a' && *p <= 'z')
579 *p -= 'a' - 'A';
580 else if (IS_HIGHBIT_SET(*p) && islower_l(*p, loc))
581 *p = toupper_l((unsigned char) *p, loc);
582 }
583 }
584 else
585 {
586 if (wasalnum)
587 *p = tolower_l((unsigned char) *p, loc);
588 else
589 *p = toupper_l((unsigned char) *p, loc);
590 }
591 wasalnum = isalnum_l((unsigned char) *p, loc);
592 }
593 }
594
595 return srclen;
596}
#define toupper_l
Definition: win32_port.h:431
#define isalnum_l
Definition: win32_port.h:438
#define islower_l
Definition: win32_port.h:442

References generate_unaccent_rules::dest, IS_HIGHBIT_SET, isalnum_l, islower_l, isupper_l, locale, locale_t, tolower_l, and toupper_l.

◆ strupper_libc_mb()

static size_t strupper_libc_mb ( char *  dest,
size_t  destsize,
const char *  src,
ssize_t  srclen,
pg_locale_t  locale 
)
static

Definition at line 693 of file pg_locale_libc.c.

695{
696 locale_t loc = locale->lt;
697 size_t result_size;
698 wchar_t *workspace;
699 char *result;
700 size_t curr_char;
701 size_t max_size;
702
703 if (srclen < 0)
704 srclen = strlen(src);
705
706 /* Overflow paranoia */
707 if ((srclen + 1) > (INT_MAX / sizeof(wchar_t)))
709 (errcode(ERRCODE_OUT_OF_MEMORY),
710 errmsg("out of memory")));
711
712 /* Output workspace cannot have more codes than input bytes */
713 workspace = palloc_array(wchar_t, srclen + 1);
714
715 char2wchar(workspace, srclen + 1, src, srclen, loc);
716
717 for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
718 workspace[curr_char] = towupper_l(workspace[curr_char], loc);
719
720 /*
721 * Make result large enough; case change might change number of bytes
722 */
723 max_size = curr_char * pg_database_encoding_max_length();
724 result = palloc(max_size + 1);
725
726 result_size = wchar2char(result, workspace, max_size + 1, loc);
727
728 if (result_size + 1 > destsize)
729 return result_size;
730
731 memcpy(dest, result, result_size);
732 dest[result_size] = '\0';
733
734 pfree(workspace);
735 pfree(result);
736
737 return result_size;
738}

References char2wchar(), generate_unaccent_rules::dest, ereport, errcode(), errmsg(), ERROR, locale, locale_t, palloc(), palloc_array, pfree(), pg_database_encoding_max_length(), towupper_l, and wchar2char().

◆ strupper_libc_sb()

static size_t strupper_libc_sb ( char *  dest,
size_t  destsize,
const char *  src,
ssize_t  srclen,
pg_locale_t  locale 
)
static

Definition at line 654 of file pg_locale_libc.c.

656{
657 if (srclen < 0)
658 srclen = strlen(src);
659
660 if (srclen + 1 <= destsize)
661 {
662 locale_t loc = locale->lt;
663 char *p;
664
665 memcpy(dest, src, srclen);
666 dest[srclen] = '\0';
667
668 /*
669 * Note: we assume that toupper_l() will not be so broken as to need
670 * an islower_l() guard test. When using the default collation, we
671 * apply the traditional Postgres behavior that forces ASCII-style
672 * treatment of I/i, but in non-default collations you get exactly
673 * what the collation says.
674 */
675 for (p = dest; *p; p++)
676 {
677 if (locale->is_default)
678 {
679 if (*p >= 'a' && *p <= 'z')
680 *p -= 'a' - 'A';
681 else if (IS_HIGHBIT_SET(*p) && islower_l(*p, loc))
682 *p = toupper_l((unsigned char) *p, loc);
683 }
684 else
685 *p = toupper_l((unsigned char) *p, loc);
686 }
687 }
688
689 return srclen;
690}

References generate_unaccent_rules::dest, IS_HIGHBIT_SET, islower_l, locale, locale_t, and toupper_l.

◆ tolower_libc_mb()

static pg_wchar tolower_libc_mb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 308 of file pg_locale_libc.c.

309{
311
312 /* force C behavior for ASCII characters, per comments above */
313 if (locale->is_default && wc <= (pg_wchar) 127)
314 return pg_ascii_tolower((unsigned char) wc);
315 if (sizeof(wchar_t) >= 4 || wc <= (pg_wchar) 0xFFFF)
316 return towlower_l((wint_t) wc, locale->lt);
317 else
318 return wc;
319}
unsigned int pg_wchar
Definition: mbprint.c:31

References Assert(), GetDatabaseEncoding(), locale, pg_ascii_tolower(), PG_UTF8, and towlower_l.

◆ tolower_libc_sb()

static pg_wchar tolower_libc_sb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 294 of file pg_locale_libc.c.

295{
297
298 /* force C behavior for ASCII characters, per comments above */
299 if (locale->is_default && wc <= (pg_wchar) 127)
300 return pg_ascii_tolower((unsigned char) wc);
301 if (wc <= (pg_wchar) UCHAR_MAX)
302 return tolower_l((unsigned char) wc, locale->lt);
303 else
304 return wc;
305}

References Assert(), GetDatabaseEncoding(), locale, pg_ascii_tolower(), PG_UTF8, and tolower_l.

◆ toupper_libc_mb()

static pg_wchar toupper_libc_mb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 280 of file pg_locale_libc.c.

281{
283
284 /* force C behavior for ASCII characters, per comments above */
285 if (locale->is_default && wc <= (pg_wchar) 127)
286 return pg_ascii_toupper((unsigned char) wc);
287 if (sizeof(wchar_t) >= 4 || wc <= (pg_wchar) 0xFFFF)
288 return towupper_l((wint_t) wc, locale->lt);
289 else
290 return wc;
291}
static unsigned char pg_ascii_toupper(unsigned char ch)
Definition: port.h:177

References Assert(), GetDatabaseEncoding(), locale, pg_ascii_toupper(), PG_UTF8, and towupper_l.

◆ toupper_libc_sb()

static pg_wchar toupper_libc_sb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 266 of file pg_locale_libc.c.

267{
269
270 /* force C behavior for ASCII characters, per comments above */
271 if (locale->is_default && wc <= (pg_wchar) 127)
272 return pg_ascii_toupper((unsigned char) wc);
273 if (wc <= (pg_wchar) UCHAR_MAX)
274 return toupper_l((unsigned char) wc, locale->lt);
275 else
276 return wc;
277}

References Assert(), GetDatabaseEncoding(), locale, pg_ascii_toupper(), PG_UTF8, and toupper_l.

◆ wc_isalnum_libc_mb()

static bool wc_isalnum_libc_mb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 207 of file pg_locale_libc.c.

208{
209 return iswalnum_l((wint_t) wc, locale->lt);
210}

References iswalnum_l, and locale.

◆ wc_isalnum_libc_sb()

static bool wc_isalnum_libc_sb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 136 of file pg_locale_libc.c.

137{
138 return isalnum_l((unsigned char) wc, locale->lt);
139}

References isalnum_l, and locale.

◆ wc_isalpha_libc_mb()

static bool wc_isalpha_libc_mb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 201 of file pg_locale_libc.c.

202{
203 return iswalpha_l((wint_t) wc, locale->lt);
204}
#define iswalpha_l
Definition: win32_port.h:437

References iswalpha_l, and locale.

◆ wc_isalpha_libc_sb()

static bool wc_isalpha_libc_sb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 130 of file pg_locale_libc.c.

131{
132 return isalpha_l((unsigned char) wc, locale->lt);
133}
#define isalpha_l
Definition: win32_port.h:436

References isalpha_l, and locale.

◆ wc_iscased_libc_mb()

static bool wc_iscased_libc_mb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 259 of file pg_locale_libc.c.

260{
261 return iswupper_l((wint_t) wc, locale->lt) ||
262 iswlower_l((wint_t) wc, locale->lt);
263}
#define iswupper_l
Definition: win32_port.h:441
#define iswlower_l
Definition: win32_port.h:443

References iswlower_l, iswupper_l, and locale.

◆ wc_iscased_libc_sb()

static bool wc_iscased_libc_sb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 188 of file pg_locale_libc.c.

189{
190 return isupper_l((unsigned char) wc, locale->lt) ||
191 islower_l((unsigned char) wc, locale->lt);
192}

References islower_l, isupper_l, and locale.

◆ wc_isdigit_libc_mb()

static bool wc_isdigit_libc_mb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 195 of file pg_locale_libc.c.

196{
197 return iswdigit_l((wint_t) wc, locale->lt);
198}
#define iswdigit_l
Definition: win32_port.h:435

References iswdigit_l, and locale.

◆ wc_isdigit_libc_sb()

static bool wc_isdigit_libc_sb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 124 of file pg_locale_libc.c.

125{
126 return isdigit_l((unsigned char) wc, locale->lt);
127}
#define isdigit_l
Definition: win32_port.h:434

References isdigit_l, and locale.

◆ wc_isgraph_libc_mb()

static bool wc_isgraph_libc_mb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 225 of file pg_locale_libc.c.

226{
227 return iswgraph_l((wint_t) wc, locale->lt);
228}
#define iswgraph_l
Definition: win32_port.h:445

References iswgraph_l, and locale.

◆ wc_isgraph_libc_sb()

static bool wc_isgraph_libc_sb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 154 of file pg_locale_libc.c.

155{
156 return isgraph_l((unsigned char) wc, locale->lt);
157}
#define isgraph_l
Definition: win32_port.h:444

References isgraph_l, and locale.

◆ wc_islower_libc_mb()

static bool wc_islower_libc_mb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 219 of file pg_locale_libc.c.

220{
221 return iswlower_l((wint_t) wc, locale->lt);
222}

References iswlower_l, and locale.

◆ wc_islower_libc_sb()

static bool wc_islower_libc_sb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 148 of file pg_locale_libc.c.

149{
150 return islower_l((unsigned char) wc, locale->lt);
151}

References islower_l, and locale.

◆ wc_isprint_libc_mb()

static bool wc_isprint_libc_mb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 231 of file pg_locale_libc.c.

232{
233 return iswprint_l((wint_t) wc, locale->lt);
234}
#define iswprint_l
Definition: win32_port.h:447

References iswprint_l, and locale.

◆ wc_isprint_libc_sb()

static bool wc_isprint_libc_sb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 160 of file pg_locale_libc.c.

161{
162 return isprint_l((unsigned char) wc, locale->lt);
163}
#define isprint_l
Definition: win32_port.h:446

References isprint_l, and locale.

◆ wc_ispunct_libc_mb()

static bool wc_ispunct_libc_mb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 237 of file pg_locale_libc.c.

238{
239 return iswpunct_l((wint_t) wc, locale->lt);
240}
#define iswpunct_l
Definition: win32_port.h:449

References iswpunct_l, and locale.

◆ wc_ispunct_libc_sb()

static bool wc_ispunct_libc_sb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 166 of file pg_locale_libc.c.

167{
168 return ispunct_l((unsigned char) wc, locale->lt);
169}
#define ispunct_l
Definition: win32_port.h:448

References ispunct_l, and locale.

◆ wc_isspace_libc_mb()

static bool wc_isspace_libc_mb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 243 of file pg_locale_libc.c.

244{
245 return iswspace_l((wint_t) wc, locale->lt);
246}
#define iswspace_l
Definition: win32_port.h:451

References iswspace_l, and locale.

◆ wc_isspace_libc_sb()

static bool wc_isspace_libc_sb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 172 of file pg_locale_libc.c.

173{
174 return isspace_l((unsigned char) wc, locale->lt);
175}
#define isspace_l
Definition: win32_port.h:450

References isspace_l, and locale.

◆ wc_isupper_libc_mb()

static bool wc_isupper_libc_mb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 213 of file pg_locale_libc.c.

214{
215 return iswupper_l((wint_t) wc, locale->lt);
216}

References iswupper_l, and locale.

◆ wc_isupper_libc_sb()

static bool wc_isupper_libc_sb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 142 of file pg_locale_libc.c.

143{
144 return isupper_l((unsigned char) wc, locale->lt);
145}

References isupper_l, and locale.

◆ wc_isxdigit_libc_mb()

static bool wc_isxdigit_libc_mb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 249 of file pg_locale_libc.c.

250{
251#ifndef WIN32
252 return iswxdigit_l((wint_t) wc, locale->lt);
253#else
254 return _iswxdigit_l((wint_t) wc, locale->lt);
255#endif
256}

References locale.

◆ wc_isxdigit_libc_sb()

static bool wc_isxdigit_libc_sb ( pg_wchar  wc,
pg_locale_t  locale 
)
static

Definition at line 178 of file pg_locale_libc.c.

179{
180#ifndef WIN32
181 return isxdigit_l((unsigned char) wc, locale->lt);
182#else
183 return _isxdigit_l((unsigned char) wc, locale->lt);
184#endif
185}

References locale.

◆ wchar2char()

size_t wchar2char ( char *  to,
const wchar_t *  from,
size_t  tolen,
locale_t  loc 
)

Definition at line 1205 of file pg_locale_libc.c.

1206{
1207 size_t result;
1208
1209 if (tolen == 0)
1210 return 0;
1211
1212#ifdef WIN32
1213
1214 /*
1215 * On Windows, the "Unicode" locales assume UTF16 not UTF8 encoding, and
1216 * for some reason mbstowcs and wcstombs won't do this for us, so we use
1217 * MultiByteToWideChar().
1218 */
1220 {
1221 result = WideCharToMultiByte(CP_UTF8, 0, from, -1, to, tolen,
1222 NULL, NULL);
1223 /* A zero return is failure */
1224 if (result <= 0)
1225 result = -1;
1226 else
1227 {
1228 Assert(result <= tolen);
1229 /* Microsoft counts the zero terminator in the result */
1230 result--;
1231 }
1232 }
1233 else
1234#endif /* WIN32 */
1235 if (loc == (locale_t) 0)
1236 {
1237 /* Use wcstombs directly for the default locale */
1238 result = wcstombs(to, from, tolen);
1239 }
1240 else
1241 {
1242 /* Use wcstombs_l for nondefault locales */
1243 result = wcstombs_l(to, from, tolen, loc);
1244 }
1245
1246 return result;
1247}
static size_t wcstombs_l(char *dest, const wchar_t *src, size_t n, locale_t loc)

References Assert(), GetDatabaseEncoding(), locale_t, PG_UTF8, and wcstombs_l().

Referenced by strlower_libc_mb(), strtitle_libc_mb(), and strupper_libc_mb().

◆ wcstombs_l()

static size_t wcstombs_l ( char *  dest,
const wchar_t *  src,
size_t  n,
locale_t  loc 
)
static

Definition at line 1177 of file pg_locale_libc.c.

1178{
1179#ifdef WIN32
1180 return _wcstombs_l(dest, src, n, loc);
1181#else
1182 size_t result;
1183 locale_t save_locale = uselocale(loc);
1184
1185 result = wcstombs(dest, src, n);
1186 uselocale(save_locale);
1187 return result;
1188#endif
1189}

References generate_unaccent_rules::dest, and locale_t.

Referenced by wchar2char().

Variable Documentation

◆ collate_methods_libc

const struct collate_methods collate_methods_libc
static
Initial value:
= {
.strncoll = strncoll_libc,
.strnxfrm = strnxfrm_libc,
.strnxfrm_prefix = NULL,
.strxfrm_is_safe = false,
}
static int strncoll_libc(const char *arg1, ssize_t len1, const char *arg2, ssize_t len2, pg_locale_t locale)
static size_t strnxfrm_libc(char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)

Definition at line 421 of file pg_locale_libc.c.

Referenced by create_pg_locale_libc().

◆ ctype_methods_libc_other_mb

const struct ctype_methods ctype_methods_libc_other_mb
static
Initial value:
= {
.strlower = strlower_libc_mb,
.strtitle = strtitle_libc_mb,
.strupper = strupper_libc_mb,
.strfold = strlower_libc_mb,
.downcase_ident = NULL,
.wc_isdigit = wc_isdigit_libc_sb,
.wc_isalpha = wc_isalpha_libc_sb,
.wc_isalnum = wc_isalnum_libc_sb,
.wc_isupper = wc_isupper_libc_sb,
.wc_islower = wc_islower_libc_sb,
.wc_isgraph = wc_isgraph_libc_sb,
.wc_isprint = wc_isprint_libc_sb,
.wc_ispunct = wc_ispunct_libc_sb,
.wc_isspace = wc_isspace_libc_sb,
.wc_isxdigit = wc_isxdigit_libc_sb,
.wc_iscased = wc_iscased_libc_sb,
.wc_toupper = toupper_libc_sb,
.wc_tolower = tolower_libc_sb,
}
static size_t strtitle_libc_mb(char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)
static bool wc_ispunct_libc_sb(pg_wchar wc, pg_locale_t locale)
static bool wc_iscased_libc_sb(pg_wchar wc, pg_locale_t locale)
static bool wc_isdigit_libc_sb(pg_wchar wc, pg_locale_t locale)
static bool wc_isspace_libc_sb(pg_wchar wc, pg_locale_t locale)
static bool wc_islower_libc_sb(pg_wchar wc, pg_locale_t locale)
static pg_wchar toupper_libc_sb(pg_wchar wc, pg_locale_t locale)
static bool wc_isalnum_libc_sb(pg_wchar wc, pg_locale_t locale)
static bool wc_isalpha_libc_sb(pg_wchar wc, pg_locale_t locale)
static bool wc_isprint_libc_sb(pg_wchar wc, pg_locale_t locale)
static bool wc_isupper_libc_sb(pg_wchar wc, pg_locale_t locale)
static bool wc_isgraph_libc_sb(pg_wchar wc, pg_locale_t locale)
static pg_wchar tolower_libc_sb(pg_wchar wc, pg_locale_t locale)
static size_t strupper_libc_mb(char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)
static bool wc_isxdigit_libc_sb(pg_wchar wc, pg_locale_t locale)
static size_t strlower_libc_mb(char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)

Definition at line 375 of file pg_locale_libc.c.

Referenced by create_pg_locale_libc().

◆ ctype_methods_libc_sb

const struct ctype_methods ctype_methods_libc_sb
static
Initial value:
= {
.strlower = strlower_libc_sb,
.strtitle = strtitle_libc_sb,
.strupper = strupper_libc_sb,
.strfold = strlower_libc_sb,
.downcase_ident = downcase_ident_libc_sb,
.wc_isdigit = wc_isdigit_libc_sb,
.wc_isalpha = wc_isalpha_libc_sb,
.wc_isalnum = wc_isalnum_libc_sb,
.wc_isupper = wc_isupper_libc_sb,
.wc_islower = wc_islower_libc_sb,
.wc_isgraph = wc_isgraph_libc_sb,
.wc_isprint = wc_isprint_libc_sb,
.wc_ispunct = wc_ispunct_libc_sb,
.wc_isspace = wc_isspace_libc_sb,
.wc_isxdigit = wc_isxdigit_libc_sb,
.wc_iscased = wc_iscased_libc_sb,
.wc_toupper = toupper_libc_sb,
.wc_tolower = tolower_libc_sb,
}
static size_t downcase_ident_libc_sb(char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
static size_t strupper_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)
static size_t strlower_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)
static size_t strtitle_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)

Definition at line 349 of file pg_locale_libc.c.

Referenced by create_pg_locale_libc().

◆ ctype_methods_libc_utf8

const struct ctype_methods ctype_methods_libc_utf8
static
Initial value:
= {
.strlower = strlower_libc_mb,
.strtitle = strtitle_libc_mb,
.strupper = strupper_libc_mb,
.strfold = strlower_libc_mb,
.downcase_ident = NULL,
.wc_isdigit = wc_isdigit_libc_mb,
.wc_isalpha = wc_isalpha_libc_mb,
.wc_isalnum = wc_isalnum_libc_mb,
.wc_isupper = wc_isupper_libc_mb,
.wc_islower = wc_islower_libc_mb,
.wc_isgraph = wc_isgraph_libc_mb,
.wc_isprint = wc_isprint_libc_mb,
.wc_ispunct = wc_ispunct_libc_mb,
.wc_isspace = wc_isspace_libc_mb,
.wc_isxdigit = wc_isxdigit_libc_mb,
.wc_iscased = wc_iscased_libc_mb,
.wc_toupper = toupper_libc_mb,
.wc_tolower = tolower_libc_mb,
}
static bool wc_isalpha_libc_mb(pg_wchar wc, pg_locale_t locale)
static pg_wchar toupper_libc_mb(pg_wchar wc, pg_locale_t locale)
static bool wc_isprint_libc_mb(pg_wchar wc, pg_locale_t locale)
static bool wc_isupper_libc_mb(pg_wchar wc, pg_locale_t locale)
static bool wc_isgraph_libc_mb(pg_wchar wc, pg_locale_t locale)
static bool wc_isalnum_libc_mb(pg_wchar wc, pg_locale_t locale)
static bool wc_iscased_libc_mb(pg_wchar wc, pg_locale_t locale)
static bool wc_ispunct_libc_mb(pg_wchar wc, pg_locale_t locale)
static bool wc_islower_libc_mb(pg_wchar wc, pg_locale_t locale)
static pg_wchar tolower_libc_mb(pg_wchar wc, pg_locale_t locale)
static bool wc_isdigit_libc_mb(pg_wchar wc, pg_locale_t locale)
static bool wc_isspace_libc_mb(pg_wchar wc, pg_locale_t locale)
static bool wc_isxdigit_libc_mb(pg_wchar wc, pg_locale_t locale)

Definition at line 398 of file pg_locale_libc.c.

Referenced by create_pg_locale_libc().