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 void report_newlocale_failure (const char *localename)
 
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 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 937 of file pg_locale_libc.c.

939{
940 size_t result;
941
942 if (tolen == 0)
943 return 0;
944
945#ifdef WIN32
946 /* See WIN32 "Unicode" comment above */
948 {
949 /* Win32 API does not work for zero-length input */
950 if (fromlen == 0)
951 result = 0;
952 else
953 {
954 result = MultiByteToWideChar(CP_UTF8, 0, from, fromlen, to, tolen - 1);
955 /* A zero return is failure */
956 if (result == 0)
957 result = -1;
958 }
959
960 if (result != -1)
961 {
962 Assert(result < tolen);
963 /* Append trailing null wchar (MultiByteToWideChar() does not) */
964 to[result] = 0;
965 }
966 }
967 else
968#endif /* WIN32 */
969 {
970 /* mbstowcs requires ending '\0' */
971 char *str = pnstrdup(from, fromlen);
972
973 if (locale == (pg_locale_t) 0)
974 {
975 /* Use mbstowcs directly for the default locale */
976 result = mbstowcs(to, str, tolen);
977 }
978 else
979 {
980 /* Use mbstowcs_l for nondefault locales */
981 result = mbstowcs_l(to, str, tolen, locale->info.lt);
982 }
983
984 pfree(str);
985 }
986
987 if (result == -1)
988 {
989 /*
990 * Invalid multibyte character encountered. We try to give a useful
991 * error message by letting pg_verifymbstr check the string. But it's
992 * possible that the string is OK to us, and not OK to mbstowcs ---
993 * this suggests that the LC_CTYPE locale is different from the
994 * database encoding. Give a generic error message if pg_verifymbstr
995 * can't find anything wrong.
996 */
997 pg_verifymbstr(from, fromlen, false); /* might not return */
998 /* but if it does ... */
1000 (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
1001 errmsg("invalid multibyte character for locale"),
1002 errhint("The server's LC_CTYPE locale is probably incompatible with the database encoding.")));
1003 }
1004
1005 return result;
1006}
int errhint(const char *fmt,...)
Definition: elog.c:1317
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#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:1524
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1710
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 422 of file pg_locale_libc.c.

423{
424 const char *collate;
425 const char *ctype;
426 locale_t loc;
427 pg_locale_t result;
428
429 if (collid == DEFAULT_COLLATION_OID)
430 {
431 HeapTuple tp;
432 Datum datum;
433
435 if (!HeapTupleIsValid(tp))
436 elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
437 datum = SysCacheGetAttrNotNull(DATABASEOID, tp,
438 Anum_pg_database_datcollate);
439 collate = TextDatumGetCString(datum);
440 datum = SysCacheGetAttrNotNull(DATABASEOID, tp,
441 Anum_pg_database_datctype);
442 ctype = TextDatumGetCString(datum);
443
444 ReleaseSysCache(tp);
445 }
446 else
447 {
448 HeapTuple tp;
449 Datum datum;
450
452 if (!HeapTupleIsValid(tp))
453 elog(ERROR, "cache lookup failed for collation %u", collid);
454
455 datum = SysCacheGetAttrNotNull(COLLOID, tp,
456 Anum_pg_collation_collcollate);
457 collate = TextDatumGetCString(datum);
458 datum = SysCacheGetAttrNotNull(COLLOID, tp,
459 Anum_pg_collation_collctype);
460 ctype = TextDatumGetCString(datum);
461
462 ReleaseSysCache(tp);
463 }
464
465
466 loc = make_libc_collator(collate, ctype);
467
468 result = MemoryContextAllocZero(context, sizeof(struct pg_locale_struct));
469 result->provider = COLLPROVIDER_LIBC;
470 result->deterministic = true;
471 result->collate_is_c = (strcmp(collate, "C") == 0) ||
472 (strcmp(collate, "POSIX") == 0);
473 result->ctype_is_c = (strcmp(ctype, "C") == 0) ||
474 (strcmp(ctype, "POSIX") == 0);
475 result->info.lt = loc;
476 if (!result->collate_is_c)
477 {
478#ifdef WIN32
480 result->collate = &collate_methods_libc_win32_utf8;
481 else
482#endif
483 result->collate = &collate_methods_libc;
484 }
485
486 return result;
487}
#define TextDatumGetCString(d)
Definition: builtins.h:98
Oid collid
#define elog(elevel,...)
Definition: elog.h:225
Oid MyDatabaseId
Definition: globals.c:93
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1215
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
union pg_locale_struct::@158 info
bool deterministic
Definition: pg_locale.h:99
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 660 of file pg_locale_libc.c.

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

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

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

References generate_unaccent_rules::dest, and locale_t.

Referenced by char2wchar().

◆ report_newlocale_failure()

static void report_newlocale_failure ( const char *  localename)
static

Definition at line 805 of file pg_locale_libc.c.

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

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

Referenced by 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 124 of file pg_locale_libc.c.

126{
128 return strlower_libc_mb(dst, dstsize, src, srclen, locale);
129 else
130 return strlower_libc_sb(dst, dstsize, src, srclen, locale);
131}
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 191 of file pg_locale_libc.c.

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

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

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

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

136{
138 return strtitle_libc_mb(dst, dstsize, src, srclen, locale);
139 else
140 return strtitle_libc_sb(dst, dstsize, src, srclen, locale);
141}
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 285 of file pg_locale_libc.c.

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

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

146{
148 return strupper_libc_mb(dst, dstsize, src, srclen, locale);
149 else
150 return strupper_libc_sb(dst, dstsize, src, srclen, locale);
151}
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 374 of file pg_locale_libc.c.

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

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

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

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

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

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

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

Referenced by create_pg_locale_libc().