0007-Use-compact-notation-for-isXXX_l-wrappers.txt

text/plain

Filename: 0007-Use-compact-notation-for-isXXX_l-wrappers.txt
Type: text/plain
Part: 6
Message: Re: C11: should we use char32_t for unicode code points?
From b2ddd005740f73c6d4a9e2441616926fcea94684 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Wed, 29 Oct 2025 17:54:06 +1300
Subject: [PATCH 7/8] Use compact notation for isXXX_l() wrappers.

Instead of loads of repeating functions for the PG_WCHAR_CHAR and
PG_WCHAR_UTF32 handlers, make a macro to avoid typos, as was already
done for the new PG_WCHAR_CUSTOM handlers.
---
 src/backend/utils/adt/pg_locale_libc.c | 166 +++++++------------------
 1 file changed, 43 insertions(+), 123 deletions(-)

diff --git a/src/backend/utils/adt/pg_locale_libc.c b/src/backend/utils/adt/pg_locale_libc.c
index b33897c683e..fc758e2607c 100644
--- a/src/backend/utils/adt/pg_locale_libc.c
+++ b/src/backend/utils/adt/pg_locale_libc.c
@@ -206,134 +206,54 @@ DEFINE_WC_CTYPE_LIBC_CUSTOM(punct);
 DEFINE_WC_CTYPE_LIBC_CUSTOM(space);
 DEFINE_WC_CTYPE_LIBC_CUSTOM(xdigit);
 
-static bool
-wc_isdigit_libc_sb(pg_wchar wc, pg_locale_t locale)
-{
-	return isdigit_l((unsigned char) wc, locale->lt);
-}
-
-static bool
-wc_isalpha_libc_sb(pg_wchar wc, pg_locale_t locale)
-{
-	return isalpha_l((unsigned char) wc, locale->lt);
-}
-
-static bool
-wc_isalnum_libc_sb(pg_wchar wc, pg_locale_t locale)
-{
-	return isalnum_l((unsigned char) wc, locale->lt);
-}
-
-static bool
-wc_isupper_libc_sb(pg_wchar wc, pg_locale_t locale)
-{
-	return isupper_l((unsigned char) wc, locale->lt);
-}
-
-static bool
-wc_islower_libc_sb(pg_wchar wc, pg_locale_t locale)
-{
-	return islower_l((unsigned char) wc, locale->lt);
-}
-
-static bool
-wc_isgraph_libc_sb(pg_wchar wc, pg_locale_t locale)
-{
-	return isgraph_l((unsigned char) wc, locale->lt);
-}
-
-static bool
-wc_isprint_libc_sb(pg_wchar wc, pg_locale_t locale)
-{
-	return isprint_l((unsigned char) wc, locale->lt);
-}
-
-static bool
-wc_ispunct_libc_sb(pg_wchar wc, pg_locale_t locale)
-{
-	return ispunct_l((unsigned char) wc, locale->lt);
-}
-
-static bool
-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)
-{
-	return isxdigit_l((unsigned char) wc, locale->lt);
-}
-
-static bool
-wc_isdigit_libc_utf32(pg_wchar wc, pg_locale_t locale)
-{
-	return (sizeof(wchar_t) >= 4 || wc <= 0xffff) &&
-		iswdigit_l((wint_t) wc, locale->lt);
-}
-
-static bool
-wc_isalpha_libc_utf32(pg_wchar wc, pg_locale_t locale)
-{
-	return (sizeof(wchar_t) >= 4 || wc <= 0xffff) &&
-		iswalpha_l((wint_t) wc, locale->lt);
-}
-
-static bool
-wc_isalnum_libc_utf32(pg_wchar wc, pg_locale_t locale)
-{
-	return (sizeof(wchar_t) >= 4 || wc <= 0xffff) &&
-		iswalnum_l((wint_t) wc, locale->lt);
-}
-
-static bool
-wc_isupper_libc_utf32(pg_wchar wc, pg_locale_t locale)
-{
-	return (sizeof(wchar_t) >= 4 || wc <= 0xffff) &&
-		iswupper_l((wint_t) wc, locale->lt);
-}
-
-static bool
-wc_islower_libc_utf32(pg_wchar wc, pg_locale_t locale)
-{
-	return (sizeof(wchar_t) >= 4 || wc <= 0xffff) &&
-		iswlower_l((wint_t) wc, locale->lt);
-}
-
-static bool
-wc_isgraph_libc_utf32(pg_wchar wc, pg_locale_t locale)
-{
-	return (sizeof(wchar_t) >= 4 || wc <= 0xffff) &&
-		iswgraph_l((wint_t) wc, locale->lt);
-}
-
-static bool
-wc_isprint_libc_utf32(pg_wchar wc, pg_locale_t locale)
-{
-	return (sizeof(wchar_t) >= 4 || wc <= 0xffff) &&
-		iswprint_l((wint_t) wc, locale->lt);
+/*
+ * Generate a function that passes single-byte characters directly to <ctype.h>
+ * functions.  This is suitable for PG_WCHAR_CHAR encodings, where pg_wchar
+ * holds a one byte.
+ */
+#define DEFINE_WC_CTYPE_LIBC_SB(ctype) \
+static bool \
+wc_is##ctype##_libc_sb(pg_wchar wc, pg_locale_t locale) \
+{ \
+	return is##ctype##_l((unsigned char) wc, locale->lt); \
 }
 
-static bool
-wc_ispunct_libc_utf32(pg_wchar wc, pg_locale_t locale)
-{
-	return (sizeof(wchar_t) >= 4 || wc <= 0xffff) &&
-		iswpunct_l((wint_t) wc, locale->lt);
-}
+DEFINE_WC_CTYPE_LIBC_SB(digit);
+DEFINE_WC_CTYPE_LIBC_SB(alpha);
+DEFINE_WC_CTYPE_LIBC_SB(alnum);
+DEFINE_WC_CTYPE_LIBC_SB(upper);
+DEFINE_WC_CTYPE_LIBC_SB(lower);
+DEFINE_WC_CTYPE_LIBC_SB(graph);
+DEFINE_WC_CTYPE_LIBC_SB(print);
+DEFINE_WC_CTYPE_LIBC_SB(punct);
+DEFINE_WC_CTYPE_LIBC_SB(space);
+DEFINE_WC_CTYPE_LIBC_SB(xdigit);
 
-static bool
-wc_isspace_libc_utf32(pg_wchar wc, pg_locale_t locale)
-{
-	return (sizeof(wchar_t) >= 4 || wc <= 0xffff) &&
-		iswspace_l((wint_t) wc, locale->lt);
+/*
+ * Generate a function that passes UTF-32 characters directly to <wctype.h>
+ * functions, This is suitable for PG_WCHAR_UTF32 encodings, with the
+ * assumption that any libc locale that uses UTF-8 as its char encoding must
+ * use UTF-32 or UTF-16 for its wchar_t encoding.  For the UTF-16 case, just
+ * return false for codepoints outside the BMP.
+ */
+#define DEFINE_WC_CTYPE_LIBC_UTF32(ctype) \
+static bool \
+wc_is##ctype##_libc_utf32(pg_wchar wc, pg_locale_t locale) \
+{ \
+	return (sizeof(wchar_t) >= 4 || wc <= 0xffff) && \
+		isw##ctype##_l((wint_t) wc, locale->lt); \
 }
 
-static bool
-wc_isxdigit_libc_utf32(pg_wchar wc, pg_locale_t locale)
-{
-	return iswxdigit_l((wint_t) wc, locale->lt);
-}
+DEFINE_WC_CTYPE_LIBC_UTF32(digit);
+DEFINE_WC_CTYPE_LIBC_UTF32(alpha);
+DEFINE_WC_CTYPE_LIBC_UTF32(alnum);
+DEFINE_WC_CTYPE_LIBC_UTF32(upper);
+DEFINE_WC_CTYPE_LIBC_UTF32(lower);
+DEFINE_WC_CTYPE_LIBC_UTF32(graph);
+DEFINE_WC_CTYPE_LIBC_UTF32(print);
+DEFINE_WC_CTYPE_LIBC_UTF32(punct);
+DEFINE_WC_CTYPE_LIBC_UTF32(space);
+DEFINE_WC_CTYPE_LIBC_UTF32(xdigit);
 
 static char
 char_tolower_libc(unsigned char ch, pg_locale_t locale)
-- 
2.50.1 (Apple Git-155)