Add pg_iswxdigit(), useful for tsearch.
authorJeff Davis <jdavis@postgresql.org>
Sat, 18 Oct 2025 23:25:11 +0000 (16:25 -0700)
committerJeff Davis <jdavis@postgresql.org>
Sat, 18 Oct 2025 23:25:11 +0000 (16:25 -0700)
Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
Discussion: https://postgr.es/m/0151ad01239e2cc7b3139644358cf8f7b9622ff7.camel@j-davis.com

src/backend/utils/adt/pg_locale.c
src/backend/utils/adt/pg_locale_builtin.c
src/backend/utils/adt/pg_locale_icu.c
src/backend/utils/adt/pg_locale_libc.c
src/include/utils/pg_locale.h

index 50b25445f7ad4695dfbef06ab4e1cda848be9d95..3860ada19052b811c80a28ea5167901e948fa138 100644 (file)
@@ -1493,6 +1493,18 @@ pg_iswspace(pg_wchar wc, pg_locale_t locale)
        return locale->ctype->wc_isspace(wc, locale);
 }
 
+bool
+pg_iswxdigit(pg_wchar wc, pg_locale_t locale)
+{
+   if (locale->ctype == NULL)
+       return (wc <= (pg_wchar) 127 &&
+               ((pg_char_properties[wc] & PG_ISDIGIT) ||
+                ((wc >= 'A' && wc <= 'F') ||
+                 (wc >= 'a' && wc <= 'f'))));
+   else
+       return locale->ctype->wc_isxdigit(wc, locale);
+}
+
 pg_wchar
 pg_towupper(pg_wchar wc, pg_locale_t locale)
 {
index 526ab3c6711244992c87aa71f4c1395c5845f8e3..3dc611b50e15bb79275e8cddb517635f9e959aa3 100644 (file)
@@ -163,6 +163,12 @@ wc_isspace_builtin(pg_wchar wc, pg_locale_t locale)
    return pg_u_isspace(wc);
 }
 
+static bool
+wc_isxdigit_builtin(pg_wchar wc, pg_locale_t locale)
+{
+   return pg_u_isxdigit(wc, !locale->builtin.casemap_full);
+}
+
 static bool
 char_is_cased_builtin(char ch, pg_locale_t locale)
 {
@@ -196,6 +202,7 @@ static const struct ctype_methods ctype_methods_builtin = {
    .wc_isprint = wc_isprint_builtin,
    .wc_ispunct = wc_ispunct_builtin,
    .wc_isspace = wc_isspace_builtin,
+   .wc_isxdigit = wc_isxdigit_builtin,
    .char_is_cased = char_is_cased_builtin,
    .wc_tolower = wc_tolower_builtin,
    .wc_toupper = wc_toupper_builtin,
index 9f0b4eead73a79ab5edabd233bddbbfbcc7fac38..05bad202669885fbc23ed03ef5bb35640b670831 100644 (file)
@@ -212,6 +212,12 @@ wc_isspace_icu(pg_wchar wc, pg_locale_t locale)
    return u_isspace(wc);
 }
 
+static bool
+wc_isxdigit_icu(pg_wchar wc, pg_locale_t locale)
+{
+   return u_isxdigit(wc);
+}
+
 static const struct ctype_methods ctype_methods_icu = {
    .strlower = strlower_icu,
    .strtitle = strtitle_icu,
@@ -226,6 +232,7 @@ static const struct ctype_methods ctype_methods_icu = {
    .wc_isprint = wc_isprint_icu,
    .wc_ispunct = wc_ispunct_icu,
    .wc_isspace = wc_isspace_icu,
+   .wc_isxdigit = wc_isxdigit_icu,
    .char_is_cased = char_is_cased_icu,
    .wc_toupper = toupper_icu,
    .wc_tolower = tolower_icu,
index f56b5dbdd375646d5eaa8454ec3bb355c62d2e18..34865ccf00e24306f966d7f9f838879f1adc4647 100644 (file)
@@ -172,6 +172,16 @@ wc_isspace_libc_sb(pg_wchar wc, pg_locale_t locale)
    return isspace_l((unsigned char) wc, locale->lt);
 }
 
+static bool
+wc_isxdigit_libc_sb(pg_wchar wc, pg_locale_t locale)
+{
+#ifndef WIN32
+   return isxdigit_l((unsigned char) wc, locale->lt);
+#else
+   return _isxdigit_l((unsigned char) wc, locale->lt);
+#endif
+}
+
 static bool
 wc_isdigit_libc_mb(pg_wchar wc, pg_locale_t locale)
 {
@@ -226,6 +236,16 @@ wc_isspace_libc_mb(pg_wchar wc, pg_locale_t locale)
    return iswspace_l((wint_t) wc, locale->lt);
 }
 
+static bool
+wc_isxdigit_libc_mb(pg_wchar wc, pg_locale_t locale)
+{
+#ifndef WIN32
+   return iswxdigit_l((wint_t) wc, locale->lt);
+#else
+   return _iswxdigit_l((wint_t) wc, locale->lt);
+#endif
+}
+
 static char
 char_tolower_libc(unsigned char ch, pg_locale_t locale)
 {
@@ -313,6 +333,7 @@ static const struct ctype_methods ctype_methods_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,
    .char_is_cased = char_is_cased_libc,
    .char_tolower = char_tolower_libc,
    .wc_toupper = toupper_libc_sb,
@@ -337,6 +358,7 @@ static const struct ctype_methods ctype_methods_libc_other_mb = {
    .wc_isprint = wc_isprint_libc_sb,
    .wc_ispunct = wc_ispunct_libc_sb,
    .wc_isspace = wc_isspace_libc_sb,
+   .wc_isxdigit = wc_isxdigit_libc_sb,
    .char_is_cased = char_is_cased_libc,
    .char_tolower = char_tolower_libc,
    .wc_toupper = toupper_libc_sb,
@@ -357,6 +379,7 @@ static const struct ctype_methods ctype_methods_libc_utf8 = {
    .wc_isprint = wc_isprint_libc_mb,
    .wc_ispunct = wc_ispunct_libc_mb,
    .wc_isspace = wc_isspace_libc_mb,
+   .wc_isxdigit = wc_isxdigit_libc_mb,
    .char_is_cased = char_is_cased_libc,
    .char_tolower = char_tolower_libc,
    .wc_toupper = toupper_libc_mb,
index 009f5334a8707155248aad26f7a3cf8ac070c667..29c21d4413ccafc99f4febe5a5d716ff42cb3b12 100644 (file)
@@ -110,6 +110,7 @@ struct ctype_methods
    bool        (*wc_isprint) (pg_wchar wc, pg_locale_t locale);
    bool        (*wc_ispunct) (pg_wchar wc, pg_locale_t locale);
    bool        (*wc_isspace) (pg_wchar wc, pg_locale_t locale);
+   bool        (*wc_isxdigit) (pg_wchar wc, pg_locale_t locale);
    pg_wchar    (*wc_toupper) (pg_wchar wc, pg_locale_t locale);
    pg_wchar    (*wc_tolower) (pg_wchar wc, pg_locale_t locale);
 
@@ -217,6 +218,7 @@ extern bool pg_iswgraph(pg_wchar wc, pg_locale_t locale);
 extern bool pg_iswprint(pg_wchar wc, pg_locale_t locale);
 extern bool pg_iswpunct(pg_wchar wc, pg_locale_t locale);
 extern bool pg_iswspace(pg_wchar wc, pg_locale_t locale);
+extern bool pg_iswxdigit(pg_wchar wc, pg_locale_t locale);
 extern pg_wchar pg_towupper(pg_wchar wc, pg_locale_t locale);
 extern pg_wchar pg_towlower(pg_wchar wc, pg_locale_t locale);