PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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)
 
size_t strlower_libc (char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
size_t strtitle_libc (char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
size_t strupper_libc (char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
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 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)
 
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, pg_locale_t locale)
 
size_t char2wchar (wchar_t *to, size_t tolen, const char *from, size_t fromlen, pg_locale_t locale)
 

Variables

static const struct collate_methods collate_methods_libc
 

Macro Definition Documentation

◆ TEXTBUFLEN

#define TEXTBUFLEN   1024

Definition at line 42 of file pg_locale_libc.c.

Function Documentation

◆ char2wchar()

size_t char2wchar ( wchar_t *  to,
size_t  tolen,
const char *  from,
size_t  fromlen,
pg_locale_t  locale 
)

Definition at line 936 of file pg_locale_libc.c.

938{
939 size_t result;
940
941 if (tolen == 0)
942 return 0;
943
944#ifdef WIN32
945 /* See WIN32 "Unicode" comment above */
947 {
948 /* Win32 API does not work for zero-length input */
949 if (fromlen == 0)
950 result = 0;
951 else
952 {
953 result = MultiByteToWideChar(CP_UTF8, 0, from, fromlen, to, tolen - 1);
954 /* A zero return is failure */
955 if (result == 0)
956 result = -1;
957 }
958
959 if (result != -1)
960 {
961 Assert(result < tolen);
962 /* Append trailing null wchar (MultiByteToWideChar() does not) */
963 to[result] = 0;
964 }
965 }
966 else
967#endif /* WIN32 */
968 {
969 /* mbstowcs requires ending '\0' */
970 char *str = pnstrdup(from, fromlen);
971
972 if (locale == (pg_locale_t) 0)
973 {
974 /* Use mbstowcs directly for the default locale */
975 result = mbstowcs(to, str, tolen);
976 }
977 else
978 {
979 /* Use mbstowcs_l for nondefault locales */
980 result = mbstowcs_l(to, str, tolen, locale->info.lt);
981 }
982
983 pfree(str);
984 }
985
986 if (result == -1)
987 {
988 /*
989 * Invalid multibyte character encountered. We try to give a useful
990 * error message by letting pg_verifymbstr check the string. But it's
991 * possible that the string is OK to us, and not OK to mbstowcs ---
992 * this suggests that the LC_CTYPE locale is different from the
993 * database encoding. Give a generic error message if pg_verifymbstr
994 * can't find anything wrong.
995 */
996 pg_verifymbstr(from, fromlen, false); /* might not return */
997 /* but if it does ... */
999 (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
1000 errmsg("invalid multibyte character for locale"),
1001 errhint("The server's LC_CTYPE locale is probably incompatible with the database encoding.")));
1002 }
1003
1004 return result;
1005}
int errhint(const char *fmt,...)
Definition: elog.c:1318
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
Assert(PointerIsAligned(start, uint64))
const char * str
static char * locale
Definition: initdb.c:140
int GetDatabaseEncoding(void)
Definition: mbutils.c:1261
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
Definition: mbutils.c:1556
void pfree(void *pointer)
Definition: mcxt.c:2152
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:2338
static size_t mbstowcs_l(wchar_t *dest, const char *src, size_t n, locale_t loc)
@ PG_UTF8
Definition: pg_wchar.h:232

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

Referenced by strlower_libc_mb(), strtitle_libc_mb(), strupper_libc_mb(), t_isalnum(), t_isalpha(), and TParserInit().

◆ create_pg_locale_libc()

pg_locale_t create_pg_locale_libc ( Oid  collid,
MemoryContext  context 
)

Definition at line 421 of file pg_locale_libc.c.

422{
423 const char *collate;
424 const char *ctype;
425 locale_t loc;
426 pg_locale_t result;
427
428 if (collid == DEFAULT_COLLATION_OID)
429 {
430 HeapTuple tp;
431 Datum datum;
432
434 if (!HeapTupleIsValid(tp))
435 elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
436 datum = SysCacheGetAttrNotNull(DATABASEOID, tp,
437 Anum_pg_database_datcollate);
438 collate = TextDatumGetCString(datum);
439 datum = SysCacheGetAttrNotNull(DATABASEOID, tp,
440 Anum_pg_database_datctype);
441 ctype = TextDatumGetCString(datum);
442
443 ReleaseSysCache(tp);
444 }
445 else
446 {
447 HeapTuple tp;
448 Datum datum;
449
451 if (!HeapTupleIsValid(tp))
452 elog(ERROR, "cache lookup failed for collation %u", collid);
453
454 datum = SysCacheGetAttrNotNull(COLLOID, tp,
455 Anum_pg_collation_collcollate);
456 collate = TextDatumGetCString(datum);
457 datum = SysCacheGetAttrNotNull(COLLOID, tp,
458 Anum_pg_collation_collctype);
459 ctype = TextDatumGetCString(datum);
460
461 ReleaseSysCache(tp);
462 }
463
464
465 loc = make_libc_collator(collate, ctype);
466
467 result = MemoryContextAllocZero(context, sizeof(struct pg_locale_struct));
468 result->provider = COLLPROVIDER_LIBC;
469 result->deterministic = true;
470 result->collate_is_c = (strcmp(collate, "C") == 0) ||
471 (strcmp(collate, "POSIX") == 0);
472 result->ctype_is_c = (strcmp(ctype, "C") == 0) ||
473 (strcmp(ctype, "POSIX") == 0);
474 result->info.lt = loc;
475 if (!result->collate_is_c)
476 {
477#ifdef WIN32
479 result->collate = &collate_methods_libc_win32_utf8;
480 else
481#endif
482 result->collate = &collate_methods_libc;
483 }
484
485 return result;
486}
#define TextDatumGetCString(d)
Definition: builtins.h:98
Oid collid
#define elog(elevel,...)
Definition: elog.h:225
Oid MyDatabaseId
Definition: globals.c:95
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1294
static locale_t make_libc_collator(const char *collate, const char *ctype)
static const struct collate_methods collate_methods_libc
uintptr_t Datum
Definition: postgres.h:69
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
const struct collate_methods * collate
Definition: pg_locale.h:104
bool deterministic
Definition: pg_locale.h:99
union pg_locale_struct::@161 info
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition: syscache.c:631
#define locale_t
Definition: win32_port.h:432

References pg_locale_struct::collate, pg_locale_struct::collate_is_c, collate_methods_libc, collid, pg_locale_struct::ctype_is_c, pg_locale_struct::deterministic, elog, ERROR, GetDatabaseEncoding(), HeapTupleIsValid, pg_locale_struct::info, locale_t, pg_locale_struct::lt, make_libc_collator(), MemoryContextAllocZero(), MyDatabaseId, ObjectIdGetDatum(), PG_UTF8, pg_locale_struct::provider, ReleaseSysCache(), SearchSysCache1(), SysCacheGetAttrNotNull(), and TextDatumGetCString.

Referenced by create_pg_locale(), and init_database_collation().

◆ get_collation_actual_version_libc()

char * get_collation_actual_version_libc ( const char *  collcollate)

Definition at line 659 of file pg_locale_libc.c.

660{
661 char *collversion = NULL;
662
663 if (pg_strcasecmp("C", collcollate) != 0 &&
664 pg_strncasecmp("C.", collcollate, 2) != 0 &&
665 pg_strcasecmp("POSIX", collcollate) != 0)
666 {
667#if defined(__GLIBC__)
668 /* Use the glibc version because we don't have anything better. */
669 collversion = pstrdup(gnu_get_libc_version());
670#elif defined(LC_VERSION_MASK)
671 locale_t loc;
672
673 /* Look up FreeBSD collation version. */
674 loc = newlocale(LC_COLLATE_MASK, collcollate, NULL);
675 if (loc)
676 {
677 collversion =
678 pstrdup(querylocale(LC_COLLATE_MASK | LC_VERSION_MASK, loc));
679 freelocale(loc);
680 }
681 else
683 (errmsg("could not load locale \"%s\"", collcollate)));
684#elif defined(WIN32)
685 /*
686 * If we are targeting Windows Vista and above, we can ask for a name
687 * given a collation name (earlier versions required a location code
688 * that we don't have).
689 */
690 NLSVERSIONINFOEX version = {sizeof(NLSVERSIONINFOEX)};
691 WCHAR wide_collcollate[LOCALE_NAME_MAX_LENGTH];
692
693 MultiByteToWideChar(CP_ACP, 0, collcollate, -1, wide_collcollate,
694 LOCALE_NAME_MAX_LENGTH);
695 if (!GetNLSVersionEx(COMPARE_STRING, wide_collcollate, &version))
696 {
697 /*
698 * GetNLSVersionEx() wants a language tag such as "en-US", not a
699 * locale name like "English_United States.1252". Until those
700 * values can be prevented from entering the system, or 100%
701 * reliably converted to the more useful tag format, tolerate the
702 * resulting error and report that we have no version data.
703 */
704 if (GetLastError() == ERROR_INVALID_PARAMETER)
705 return NULL;
706
708 (errmsg("could not get collation version for locale \"%s\": error code %lu",
709 collcollate,
710 GetLastError())));
711 }
712 collversion = psprintf("%lu.%lu,%lu.%lu",
713 (version.dwNLSVersion >> 8) & 0xFFFF,
714 version.dwNLSVersion & 0xFF,
715 (version.dwDefinedVersion >> 8) & 0xFFFF,
716 version.dwDefinedVersion & 0xFF);
717#endif
718 }
719
720 return collversion;
721}
char * pstrdup(const char *in)
Definition: mcxt.c:2327
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
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 497 of file pg_locale_libc.c.

498{
499 locale_t loc = 0;
500
501 if (strcmp(collate, ctype) == 0)
502 {
503 if (strcmp(ctype, "C") != 0 && strcmp(ctype, "POSIX") != 0)
504 {
505 /* Normal case where they're the same */
506 errno = 0;
507#ifndef WIN32
508 loc = newlocale(LC_COLLATE_MASK | LC_CTYPE_MASK, collate,
509 NULL);
510#else
511 loc = _create_locale(LC_ALL, collate);
512#endif
513 if (!loc)
515 }
516 }
517 else
518 {
519#ifndef WIN32
520 /* We need two newlocale() steps */
521 locale_t loc1 = 0;
522
523 if (strcmp(collate, "C") != 0 && strcmp(collate, "POSIX") != 0)
524 {
525 errno = 0;
526 loc1 = newlocale(LC_COLLATE_MASK, collate, NULL);
527 if (!loc1)
529 }
530
531 if (strcmp(ctype, "C") != 0 && strcmp(ctype, "POSIX") != 0)
532 {
533 errno = 0;
534 loc = newlocale(LC_CTYPE_MASK, ctype, loc1);
535 if (!loc)
536 {
537 if (loc1)
538 freelocale(loc1);
540 }
541 }
542 else
543 loc = loc1;
544#else
545
546 /*
547 * XXX The _create_locale() API doesn't appear to support this. Could
548 * perhaps be worked around by changing pg_locale_t to contain two
549 * separate fields.
550 */
552 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
553 errmsg("collations with different collate and ctype values are not supported on this platform")));
554#endif
555 }
556
557 return loc;
558}
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 838 of file pg_locale_libc.c.

839{
840#ifdef WIN32
841 return _mbstowcs_l(dest, src, n, loc);
842#else
843 size_t result;
844 locale_t save_locale = uselocale(loc);
845
846 result = mbstowcs(dest, src, n);
847 uselocale(save_locale);
848 return result;
849#endif
850}

References generate_unaccent_rules::dest, and locale_t.

Referenced by char2wchar().

◆ report_newlocale_failure()

void report_newlocale_failure ( const char *  localename)

Definition at line 804 of file pg_locale_libc.c.

805{
806 int save_errno;
807
808 /*
809 * Windows doesn't provide any useful error indication from
810 * _create_locale(), and BSD-derived platforms don't seem to feel they
811 * need to set errno either (even though POSIX is pretty clear that
812 * newlocale should do so). So, if errno hasn't been set, assume ENOENT
813 * is what to report.
814 */
815 if (errno == 0)
816 errno = ENOENT;
817
818 /*
819 * ENOENT means "no such locale", not "no such file", so clarify that
820 * errno with an errdetail message.
821 */
822 save_errno = errno; /* auxiliary funcs might change errno */
824 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
825 errmsg("could not create locale \"%s\": %m",
826 localename),
827 (save_errno == ENOENT ?
828 errdetail("The operating system could not find any locale data for the locale name \"%s\".",
829 localename) : 0)));
830}
int errdetail(const char *fmt,...)
Definition: elog.c:1204

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

Referenced by cache_locale_time(), and make_libc_collator().

◆ strlower_libc()

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

Definition at line 123 of file pg_locale_libc.c.

125{
127 return strlower_libc_mb(dst, dstsize, src, srclen, locale);
128 else
129 return strlower_libc_sb(dst, dstsize, src, srclen, locale);
130}
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1546
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)

References locale, pg_database_encoding_max_length(), strlower_libc_mb(), and strlower_libc_sb().

Referenced by pg_strfold(), and pg_strlower().

◆ 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 190 of file pg_locale_libc.c.

192{
193 locale_t loc = locale->info.lt;
194 size_t result_size;
195 wchar_t *workspace;
196 char *result;
197 size_t curr_char;
198 size_t max_size;
199
200 if (srclen < 0)
201 srclen = strlen(src);
202
203 /* Overflow paranoia */
204 if ((srclen + 1) > (INT_MAX / sizeof(wchar_t)))
206 (errcode(ERRCODE_OUT_OF_MEMORY),
207 errmsg("out of memory")));
208
209 /* Output workspace cannot have more codes than input bytes */
210 workspace = (wchar_t *) palloc((srclen + 1) * sizeof(wchar_t));
211
212 char2wchar(workspace, srclen + 1, src, srclen, locale);
213
214 for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
215 workspace[curr_char] = towlower_l(workspace[curr_char], loc);
216
217 /*
218 * Make result large enough; case change might change number of bytes
219 */
220 max_size = curr_char * pg_database_encoding_max_length();
221 result = palloc(max_size + 1);
222
223 result_size = wchar2char(result, workspace, max_size + 1, locale);
224
225 if (result_size + 1 > destsize)
226 return result_size;
227
228 memcpy(dest, result, result_size);
229 dest[result_size] = '\0';
230
231 pfree(workspace);
232 pfree(result);
233
234 return result_size;
235}
void * palloc(Size size)
Definition: mcxt.c:1945
size_t wchar2char(char *to, const wchar_t *from, size_t tolen, pg_locale_t locale)
size_t char2wchar(wchar_t *to, size_t tolen, const char *from, size_t fromlen, pg_locale_t locale)
#define towlower_l
Definition: win32_port.h:435

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

Referenced by strlower_libc().

◆ 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 153 of file pg_locale_libc.c.

155{
156 if (srclen < 0)
157 srclen = strlen(src);
158
159 if (srclen + 1 <= destsize)
160 {
161 locale_t loc = locale->info.lt;
162 char *p;
163
164 if (srclen + 1 > destsize)
165 return srclen;
166
167 memcpy(dest, src, srclen);
168 dest[srclen] = '\0';
169
170 /*
171 * Note: we assume that tolower_l() will not be so broken as to need
172 * an isupper_l() guard test. When using the default collation, we
173 * apply the traditional Postgres behavior that forces ASCII-style
174 * treatment of I/i, but in non-default collations you get exactly
175 * what the collation says.
176 */
177 for (p = dest; *p; p++)
178 {
179 if (locale->is_default)
180 *p = pg_tolower((unsigned char) *p);
181 else
182 *p = tolower_l((unsigned char) *p, loc);
183 }
184 }
185
186 return srclen;
187}
unsigned char pg_tolower(unsigned char ch)
Definition: pgstrcasecmp.c:122
#define tolower_l
Definition: win32_port.h:433

References generate_unaccent_rules::dest, locale, locale_t, pg_tolower(), and tolower_l.

Referenced by strlower_libc().

◆ 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 568 of file pg_locale_libc.c.

570{
571 char sbuf[TEXTBUFLEN];
572 char *buf = sbuf;
573 size_t bufsize1 = (len1 == -1) ? 0 : len1 + 1;
574 size_t bufsize2 = (len2 == -1) ? 0 : len2 + 1;
575 const char *arg1n;
576 const char *arg2n;
577 int result;
578
579 Assert(locale->provider == COLLPROVIDER_LIBC);
580
581 if (bufsize1 + bufsize2 > TEXTBUFLEN)
582 buf = palloc(bufsize1 + bufsize2);
583
584 /* nul-terminate arguments if necessary */
585 if (len1 == -1)
586 {
587 arg1n = arg1;
588 }
589 else
590 {
591 char *buf1 = buf;
592
593 memcpy(buf1, arg1, len1);
594 buf1[len1] = '\0';
595 arg1n = buf1;
596 }
597
598 if (len2 == -1)
599 {
600 arg2n = arg2;
601 }
602 else
603 {
604 char *buf2 = buf + bufsize1;
605
606 memcpy(buf2, arg2, len2);
607 buf2[len2] = '\0';
608 arg2n = buf2;
609 }
610
611 result = strcoll_l(arg1n, arg2n, locale->info.lt);
612
613 if (buf != sbuf)
614 pfree(buf);
615
616 return result;
617}
#define TEXTBUFLEN
static char * buf
Definition: pg_test_fsync.c:72
#define strcoll_l
Definition: win32_port.h:455

References Assert(), 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 627 of file pg_locale_libc.c.

629{
630 char sbuf[TEXTBUFLEN];
631 char *buf = sbuf;
632 size_t bufsize = srclen + 1;
633 size_t result;
634
635 Assert(locale->provider == COLLPROVIDER_LIBC);
636
637 if (srclen == -1)
638 return strxfrm_l(dest, src, destsize, locale->info.lt);
639
640 if (bufsize > TEXTBUFLEN)
641 buf = palloc(bufsize);
642
643 /* nul-terminate argument */
644 memcpy(buf, src, srclen);
645 buf[srclen] = '\0';
646
647 result = strxfrm_l(dest, buf, destsize, locale->info.lt);
648
649 if (buf != sbuf)
650 pfree(buf);
651
652 /* if dest is defined, it should be nul-terminated */
653 Assert(result >= destsize || dest[result] == '\0');
654
655 return result;
656}
#define bufsize
Definition: indent_globs.h:36
#define strxfrm_l
Definition: win32_port.h:456

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

◆ strtitle_libc()

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

Definition at line 133 of file pg_locale_libc.c.

135{
137 return strtitle_libc_mb(dst, dstsize, src, srclen, locale);
138 else
139 return strtitle_libc_sb(dst, dstsize, src, srclen, locale);
140}
static size_t strtitle_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)

References locale, pg_database_encoding_max_length(), strtitle_libc_mb(), and strtitle_libc_sb().

Referenced by pg_strtitle().

◆ 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 284 of file pg_locale_libc.c.

286{
287 locale_t loc = locale->info.lt;
288 int wasalnum = false;
289 size_t result_size;
290 wchar_t *workspace;
291 char *result;
292 size_t curr_char;
293 size_t max_size;
294
295 if (srclen < 0)
296 srclen = strlen(src);
297
298 /* Overflow paranoia */
299 if ((srclen + 1) > (INT_MAX / sizeof(wchar_t)))
301 (errcode(ERRCODE_OUT_OF_MEMORY),
302 errmsg("out of memory")));
303
304 /* Output workspace cannot have more codes than input bytes */
305 workspace = (wchar_t *) palloc((srclen + 1) * sizeof(wchar_t));
306
307 char2wchar(workspace, srclen + 1, src, srclen, locale);
308
309 for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
310 {
311 if (wasalnum)
312 workspace[curr_char] = towlower_l(workspace[curr_char], loc);
313 else
314 workspace[curr_char] = towupper_l(workspace[curr_char], loc);
315 wasalnum = iswalnum_l(workspace[curr_char], loc);
316 }
317
318 /*
319 * Make result large enough; case change might change number of bytes
320 */
321 max_size = curr_char * pg_database_encoding_max_length();
322 result = palloc(max_size + 1);
323
324 result_size = wchar2char(result, workspace, max_size + 1, locale);
325
326 if (result_size + 1 > destsize)
327 return result_size;
328
329 memcpy(dest, result, result_size);
330 dest[result_size] = '\0';
331
332 pfree(workspace);
333 pfree(result);
334
335 return result_size;
336}
#define iswalnum_l
Definition: win32_port.h:442
#define towupper_l
Definition: win32_port.h:436

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

Referenced by strtitle_libc().

◆ 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 238 of file pg_locale_libc.c.

240{
241 if (srclen < 0)
242 srclen = strlen(src);
243
244 if (srclen + 1 <= destsize)
245 {
246 locale_t loc = locale->info.lt;
247 int wasalnum = false;
248 char *p;
249
250 memcpy(dest, src, srclen);
251 dest[srclen] = '\0';
252
253 /*
254 * Note: we assume that toupper_l()/tolower_l() will not be so broken
255 * as to need guard tests. When using the default collation, we apply
256 * the traditional Postgres behavior that forces ASCII-style treatment
257 * of I/i, but in non-default collations you get exactly what the
258 * collation says.
259 */
260 for (p = dest; *p; p++)
261 {
262 if (locale->is_default)
263 {
264 if (wasalnum)
265 *p = pg_tolower((unsigned char) *p);
266 else
267 *p = pg_toupper((unsigned char) *p);
268 }
269 else
270 {
271 if (wasalnum)
272 *p = tolower_l((unsigned char) *p, loc);
273 else
274 *p = toupper_l((unsigned char) *p, loc);
275 }
276 wasalnum = isalnum_l((unsigned char) *p, loc);
277 }
278 }
279
280 return srclen;
281}
unsigned char pg_toupper(unsigned char ch)
Definition: pgstrcasecmp.c:105
#define toupper_l
Definition: win32_port.h:434
#define isalnum_l
Definition: win32_port.h:441

References generate_unaccent_rules::dest, isalnum_l, locale, locale_t, pg_tolower(), pg_toupper(), tolower_l, and toupper_l.

Referenced by strtitle_libc().

◆ strupper_libc()

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

Definition at line 143 of file pg_locale_libc.c.

145{
147 return strupper_libc_mb(dst, dstsize, src, srclen, locale);
148 else
149 return strupper_libc_sb(dst, dstsize, src, srclen, locale);
150}
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)

References locale, pg_database_encoding_max_length(), strupper_libc_mb(), and strupper_libc_sb().

Referenced by pg_strupper().

◆ 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 373 of file pg_locale_libc.c.

375{
376 locale_t loc = locale->info.lt;
377 size_t result_size;
378 wchar_t *workspace;
379 char *result;
380 size_t curr_char;
381 size_t max_size;
382
383 if (srclen < 0)
384 srclen = strlen(src);
385
386 /* Overflow paranoia */
387 if ((srclen + 1) > (INT_MAX / sizeof(wchar_t)))
389 (errcode(ERRCODE_OUT_OF_MEMORY),
390 errmsg("out of memory")));
391
392 /* Output workspace cannot have more codes than input bytes */
393 workspace = (wchar_t *) palloc((srclen + 1) * sizeof(wchar_t));
394
395 char2wchar(workspace, srclen + 1, src, srclen, locale);
396
397 for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
398 workspace[curr_char] = towupper_l(workspace[curr_char], loc);
399
400 /*
401 * Make result large enough; case change might change number of bytes
402 */
403 max_size = curr_char * pg_database_encoding_max_length();
404 result = palloc(max_size + 1);
405
406 result_size = wchar2char(result, workspace, max_size + 1, locale);
407
408 if (result_size + 1 > destsize)
409 return result_size;
410
411 memcpy(dest, result, result_size);
412 dest[result_size] = '\0';
413
414 pfree(workspace);
415 pfree(result);
416
417 return result_size;
418}

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

Referenced by strupper_libc().

◆ 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 339 of file pg_locale_libc.c.

341{
342 if (srclen < 0)
343 srclen = strlen(src);
344
345 if (srclen + 1 <= destsize)
346 {
347 locale_t loc = locale->info.lt;
348 char *p;
349
350 memcpy(dest, src, srclen);
351 dest[srclen] = '\0';
352
353 /*
354 * Note: we assume that toupper_l() will not be so broken as to need
355 * an islower_l() guard test. When using the default collation, we
356 * apply the traditional Postgres behavior that forces ASCII-style
357 * treatment of I/i, but in non-default collations you get exactly
358 * what the collation says.
359 */
360 for (p = dest; *p; p++)
361 {
362 if (locale->is_default)
363 *p = pg_toupper((unsigned char) *p);
364 else
365 *p = toupper_l((unsigned char) *p, loc);
366 }
367 }
368
369 return srclen;
370}

References generate_unaccent_rules::dest, locale, locale_t, pg_toupper(), and toupper_l.

Referenced by strupper_libc().

◆ wchar2char()

size_t wchar2char ( char *  to,
const wchar_t *  from,
size_t  tolen,
pg_locale_t  locale 
)

Definition at line 882 of file pg_locale_libc.c.

883{
884 size_t result;
885
886 if (tolen == 0)
887 return 0;
888
889#ifdef WIN32
890
891 /*
892 * On Windows, the "Unicode" locales assume UTF16 not UTF8 encoding, and
893 * for some reason mbstowcs and wcstombs won't do this for us, so we use
894 * MultiByteToWideChar().
895 */
897 {
898 result = WideCharToMultiByte(CP_UTF8, 0, from, -1, to, tolen,
899 NULL, NULL);
900 /* A zero return is failure */
901 if (result <= 0)
902 result = -1;
903 else
904 {
905 Assert(result <= tolen);
906 /* Microsoft counts the zero terminator in the result */
907 result--;
908 }
909 }
910 else
911#endif /* WIN32 */
912 if (locale == (pg_locale_t) 0)
913 {
914 /* Use wcstombs directly for the default locale */
915 result = wcstombs(to, from, tolen);
916 }
917 else
918 {
919 /* Use wcstombs_l for nondefault locales */
920 result = wcstombs_l(to, from, tolen, locale->info.lt);
921 }
922
923 return result;
924}
static size_t wcstombs_l(char *dest, const wchar_t *src, size_t n, locale_t loc)

References Assert(), GetDatabaseEncoding(), locale, 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 854 of file pg_locale_libc.c.

855{
856#ifdef WIN32
857 return _wcstombs_l(dest, src, n, loc);
858#else
859 size_t result;
860 locale_t save_locale = uselocale(loc);
861
862 result = wcstombs(dest, src, n);
863 uselocale(save_locale);
864 return result;
865#endif
866}

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 88 of file pg_locale_libc.c.

Referenced by create_pg_locale_libc().