mirror of
https://github.com/postgres/postgres.git
synced 2025-11-28 11:44:57 +03:00
Allow pg_locale_t APIs to work when ctype_is_c.
Previously, the caller needed to check ctype_is_c first for some routines and not others. Now, the APIs consistently work, and the caller can just check ctype_is_c for optimization purposes. Discussion: https://postgr.es/m/450ceb6260cad30d7afdf155d991a9caafee7c0d.camel@j-davis.com Reviewed-by: Chao Li <li.evan.chao@gmail.com>
This commit is contained in:
@@ -1257,35 +1257,99 @@ get_collation_actual_version(char collprovider, const char *collcollate)
|
||||
return collversion;
|
||||
}
|
||||
|
||||
/* lowercasing/casefolding in C locale */
|
||||
static size_t
|
||||
strlower_c(char *dst, size_t dstsize, const char *src, ssize_t srclen)
|
||||
{
|
||||
int i;
|
||||
|
||||
srclen = (srclen >= 0) ? srclen : strlen(src);
|
||||
for (i = 0; i < srclen && i < dstsize; i++)
|
||||
dst[i] = pg_ascii_tolower(src[i]);
|
||||
if (i < dstsize)
|
||||
dst[i] = '\0';
|
||||
return srclen;
|
||||
}
|
||||
|
||||
/* titlecasing in C locale */
|
||||
static size_t
|
||||
strtitle_c(char *dst, size_t dstsize, const char *src, ssize_t srclen)
|
||||
{
|
||||
bool wasalnum = false;
|
||||
int i;
|
||||
|
||||
srclen = (srclen >= 0) ? srclen : strlen(src);
|
||||
for (i = 0; i < srclen && i < dstsize; i++)
|
||||
{
|
||||
char c = src[i];
|
||||
|
||||
if (wasalnum)
|
||||
dst[i] = pg_ascii_tolower(c);
|
||||
else
|
||||
dst[i] = pg_ascii_toupper(c);
|
||||
|
||||
wasalnum = ((c >= '0' && c <= '9') ||
|
||||
(c >= 'A' && c <= 'Z') ||
|
||||
(c >= 'a' && c <= 'z'));
|
||||
}
|
||||
if (i < dstsize)
|
||||
dst[i] = '\0';
|
||||
return srclen;
|
||||
}
|
||||
|
||||
/* uppercasing in C locale */
|
||||
static size_t
|
||||
strupper_c(char *dst, size_t dstsize, const char *src, ssize_t srclen)
|
||||
{
|
||||
int i;
|
||||
|
||||
srclen = (srclen >= 0) ? srclen : strlen(src);
|
||||
for (i = 0; i < srclen && i < dstsize; i++)
|
||||
dst[i] = pg_ascii_toupper(src[i]);
|
||||
if (i < dstsize)
|
||||
dst[i] = '\0';
|
||||
return srclen;
|
||||
}
|
||||
|
||||
size_t
|
||||
pg_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen,
|
||||
pg_locale_t locale)
|
||||
{
|
||||
return locale->ctype->strlower(dst, dstsize, src, srclen, locale);
|
||||
if (locale->ctype == NULL)
|
||||
return strlower_c(dst, dstsize, src, srclen);
|
||||
else
|
||||
return locale->ctype->strlower(dst, dstsize, src, srclen, locale);
|
||||
}
|
||||
|
||||
size_t
|
||||
pg_strtitle(char *dst, size_t dstsize, const char *src, ssize_t srclen,
|
||||
pg_locale_t locale)
|
||||
{
|
||||
return locale->ctype->strtitle(dst, dstsize, src, srclen, locale);
|
||||
if (locale->ctype == NULL)
|
||||
return strtitle_c(dst, dstsize, src, srclen);
|
||||
else
|
||||
return locale->ctype->strtitle(dst, dstsize, src, srclen, locale);
|
||||
}
|
||||
|
||||
size_t
|
||||
pg_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen,
|
||||
pg_locale_t locale)
|
||||
{
|
||||
return locale->ctype->strupper(dst, dstsize, src, srclen, locale);
|
||||
if (locale->ctype == NULL)
|
||||
return strupper_c(dst, dstsize, src, srclen);
|
||||
else
|
||||
return locale->ctype->strupper(dst, dstsize, src, srclen, locale);
|
||||
}
|
||||
|
||||
size_t
|
||||
pg_strfold(char *dst, size_t dstsize, const char *src, ssize_t srclen,
|
||||
pg_locale_t locale)
|
||||
{
|
||||
if (locale->ctype->strfold)
|
||||
return locale->ctype->strfold(dst, dstsize, src, srclen, locale);
|
||||
/* in the C locale, casefolding is the same as lowercasing */
|
||||
if (locale->ctype == NULL)
|
||||
return strlower_c(dst, dstsize, src, srclen);
|
||||
else
|
||||
return locale->ctype->strlower(dst, dstsize, src, srclen, locale);
|
||||
return locale->ctype->strfold(dst, dstsize, src, srclen, locale);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1560,6 +1624,8 @@ pg_towlower(pg_wchar wc, pg_locale_t locale)
|
||||
bool
|
||||
char_is_cased(char ch, pg_locale_t locale)
|
||||
{
|
||||
if (locale->ctype == NULL)
|
||||
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
|
||||
return locale->ctype->char_is_cased(ch, locale);
|
||||
}
|
||||
|
||||
@@ -1571,6 +1637,8 @@ char_is_cased(char ch, pg_locale_t locale)
|
||||
bool
|
||||
char_tolower_enabled(pg_locale_t locale)
|
||||
{
|
||||
if (locale->ctype == NULL)
|
||||
return true;
|
||||
return (locale->ctype->char_tolower != NULL);
|
||||
}
|
||||
|
||||
@@ -1582,6 +1650,8 @@ char_tolower_enabled(pg_locale_t locale)
|
||||
char
|
||||
char_tolower(unsigned char ch, pg_locale_t locale)
|
||||
{
|
||||
if (locale->ctype == NULL)
|
||||
return pg_ascii_tolower(ch);
|
||||
return locale->ctype->char_tolower(ch, locale);
|
||||
}
|
||||
|
||||
|
||||
@@ -326,6 +326,8 @@ static const struct ctype_methods ctype_methods_libc_sb = {
|
||||
.strlower = strlower_libc_sb,
|
||||
.strtitle = strtitle_libc_sb,
|
||||
.strupper = strupper_libc_sb,
|
||||
/* in libc, casefolding is the same as lowercasing */
|
||||
.strfold = strlower_libc_sb,
|
||||
.wc_isdigit = wc_isdigit_libc_sb,
|
||||
.wc_isalpha = wc_isalpha_libc_sb,
|
||||
.wc_isalnum = wc_isalnum_libc_sb,
|
||||
@@ -351,6 +353,8 @@ static const struct ctype_methods ctype_methods_libc_other_mb = {
|
||||
.strlower = strlower_libc_mb,
|
||||
.strtitle = strtitle_libc_mb,
|
||||
.strupper = strupper_libc_mb,
|
||||
/* in libc, casefolding is the same as lowercasing */
|
||||
.strfold = strlower_libc_mb,
|
||||
.wc_isdigit = wc_isdigit_libc_sb,
|
||||
.wc_isalpha = wc_isalpha_libc_sb,
|
||||
.wc_isalnum = wc_isalnum_libc_sb,
|
||||
@@ -372,6 +376,8 @@ static const struct ctype_methods ctype_methods_libc_utf8 = {
|
||||
.strlower = strlower_libc_mb,
|
||||
.strtitle = strtitle_libc_mb,
|
||||
.strupper = strupper_libc_mb,
|
||||
/* in libc, casefolding is the same as lowercasing */
|
||||
.strfold = strlower_libc_mb,
|
||||
.wc_isdigit = wc_isdigit_libc_mb,
|
||||
.wc_isalpha = wc_isalpha_libc_mb,
|
||||
.wc_isalnum = wc_isalnum_libc_mb,
|
||||
|
||||
Reference in New Issue
Block a user