From af164f31b9f5f00561d5831a72ab91cfe091f92e Mon Sep 17 00:00:00 2001
From: Jeff Davis <jdavis@postgresql.org>
Date: Wed, 15 Oct 2025 12:54:01 -0700
Subject: [PATCH] Add pg_iswalpha() and related functions.

Per-character pg_locale_t APIs. Useful for tsearch parsing and
potentially other places.

Significant overlap with the regc_wc_isalpha() and related functions
in regc_pg_locale.c, but this change leaves those intact for
now.

Discussion: https://postgr.es/m/0151ad01239e2cc7b3139644358cf8f7b9622ff7.camel@j-davis.com
---
 src/backend/regex/regc_pg_locale.c | 150 ++-------------------------
 src/backend/utils/adt/pg_locale.c  | 124 ++++++++++++++++++++++
 src/include/utils/pg_locale.h      |  12 +++
 src/include/utils/pg_locale_c.h    | 160 +++++++++++++++++++++++++++++
 4 files changed, 302 insertions(+), 144 deletions(-)
 create mode 100644 src/include/utils/pg_locale_c.h

diff --git a/src/backend/regex/regc_pg_locale.c b/src/backend/regex/regc_pg_locale.c
index 2242e72194..e0c892db71 100644
--- a/src/backend/regex/regc_pg_locale.c
+++ b/src/backend/regex/regc_pg_locale.c
@@ -19,6 +19,7 @@
 #include "common/unicode_case.h"
 #include "common/unicode_category.h"
 #include "utils/pg_locale.h"
+#include "utils/pg_locale_c.h"
 
 static pg_locale_t pg_regex_locale;
 
@@ -27,150 +28,6 @@ static struct pg_locale_struct dummy_c_locale = {
 	.ctype_is_c = true,
 };
 
-/*
- * Hard-wired character properties for C locale
- */
-#define PG_ISDIGIT	0x01
-#define PG_ISALPHA	0x02
-#define PG_ISALNUM	(PG_ISDIGIT | PG_ISALPHA)
-#define PG_ISUPPER	0x04
-#define PG_ISLOWER	0x08
-#define PG_ISGRAPH	0x10
-#define PG_ISPRINT	0x20
-#define PG_ISPUNCT	0x40
-#define PG_ISSPACE	0x80
-
-static const unsigned char pg_char_properties[128] = {
-	 /* NUL */ 0,
-	 /* ^A */ 0,
-	 /* ^B */ 0,
-	 /* ^C */ 0,
-	 /* ^D */ 0,
-	 /* ^E */ 0,
-	 /* ^F */ 0,
-	 /* ^G */ 0,
-	 /* ^H */ 0,
-	 /* ^I */ PG_ISSPACE,
-	 /* ^J */ PG_ISSPACE,
-	 /* ^K */ PG_ISSPACE,
-	 /* ^L */ PG_ISSPACE,
-	 /* ^M */ PG_ISSPACE,
-	 /* ^N */ 0,
-	 /* ^O */ 0,
-	 /* ^P */ 0,
-	 /* ^Q */ 0,
-	 /* ^R */ 0,
-	 /* ^S */ 0,
-	 /* ^T */ 0,
-	 /* ^U */ 0,
-	 /* ^V */ 0,
-	 /* ^W */ 0,
-	 /* ^X */ 0,
-	 /* ^Y */ 0,
-	 /* ^Z */ 0,
-	 /* ^[ */ 0,
-	 /* ^\ */ 0,
-	 /* ^] */ 0,
-	 /* ^^ */ 0,
-	 /* ^_ */ 0,
-	 /* */ PG_ISPRINT | PG_ISSPACE,
-	 /* !  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* "  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* #  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* $  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* %  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* &  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* '  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* (  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* )  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* *  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* +  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* ,  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* -  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* .  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* /  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* 0  */ PG_ISDIGIT | PG_ISGRAPH | PG_ISPRINT,
-	 /* 1  */ PG_ISDIGIT | PG_ISGRAPH | PG_ISPRINT,
-	 /* 2  */ PG_ISDIGIT | PG_ISGRAPH | PG_ISPRINT,
-	 /* 3  */ PG_ISDIGIT | PG_ISGRAPH | PG_ISPRINT,
-	 /* 4  */ PG_ISDIGIT | PG_ISGRAPH | PG_ISPRINT,
-	 /* 5  */ PG_ISDIGIT | PG_ISGRAPH | PG_ISPRINT,
-	 /* 6  */ PG_ISDIGIT | PG_ISGRAPH | PG_ISPRINT,
-	 /* 7  */ PG_ISDIGIT | PG_ISGRAPH | PG_ISPRINT,
-	 /* 8  */ PG_ISDIGIT | PG_ISGRAPH | PG_ISPRINT,
-	 /* 9  */ PG_ISDIGIT | PG_ISGRAPH | PG_ISPRINT,
-	 /* :  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* ;  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* <  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* =  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* >  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* ?  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* @  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* A  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* B  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* C  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* D  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* E  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* F  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* G  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* H  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* I  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* J  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* K  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* L  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* M  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* N  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* O  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* P  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* Q  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* R  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* S  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* T  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* U  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* V  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* W  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* X  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* Y  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* Z  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
-	 /* [  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* \  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* ]  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* ^  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* _  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* `  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* a  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* b  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* c  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* d  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* e  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* f  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* g  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* h  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* i  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* j  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* k  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* l  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* m  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* n  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* o  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* p  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* q  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* r  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* s  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* t  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* u  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* v  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* w  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* x  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* y  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* z  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
-	 /* {  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* |  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* }  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* ~  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
-	 /* DEL */ 0
-};
-
 
 /*
  * pg_set_regex_collation: set collation for these functions to obey
@@ -227,6 +84,11 @@ pg_set_regex_collation(Oid collation)
 	pg_regex_locale = locale;
 }
 
+/*
+ * The following functions overlap with those defined in pg_locale.c. XXX:
+ * consider refactor.
+ */
+
 static int
 regc_wc_isdigit(pg_wchar c)
 {
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 97c2ac1faf..50b25445f7 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -45,6 +45,7 @@
 #include "utils/lsyscache.h"
 #include "utils/memutils.h"
 #include "utils/pg_locale.h"
+#include "utils/pg_locale_c.h"
 #include "utils/relcache.h"
 #include "utils/syscache.h"
 
@@ -1149,6 +1150,13 @@ init_database_collation(void)
 		PGLOCALE_SUPPORT_ERROR(dbform->datlocprovider);
 
 	result->is_default = true;
+
+	Assert((result->collate_is_c && result->collate == NULL) ||
+		   (!result->collate_is_c && result->collate != NULL));
+
+	Assert((result->ctype_is_c && result->ctype == NULL) ||
+		   (!result->ctype_is_c && result->ctype != NULL));
+
 	ReleaseSysCache(tup);
 
 	default_locale = result;
@@ -1395,6 +1403,122 @@ pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
 	return locale->collate->strnxfrm_prefix(dest, destsize, src, srclen, locale);
 }
 
+bool
+pg_iswdigit(pg_wchar wc, pg_locale_t locale)
+{
+	if (locale->ctype == NULL)
+		return (wc <= (pg_wchar) 127 &&
+				(pg_char_properties[wc] & PG_ISDIGIT));
+	else
+		return locale->ctype->wc_isdigit(wc, locale);
+}
+
+bool
+pg_iswalpha(pg_wchar wc, pg_locale_t locale)
+{
+	if (locale->ctype == NULL)
+		return (wc <= (pg_wchar) 127 &&
+				(pg_char_properties[wc] & PG_ISALPHA));
+	else
+		return locale->ctype->wc_isalpha(wc, locale);
+}
+
+bool
+pg_iswalnum(pg_wchar wc, pg_locale_t locale)
+{
+	if (locale->ctype == NULL)
+		return (wc <= (pg_wchar) 127 &&
+				(pg_char_properties[wc] & PG_ISALNUM));
+	else
+		return locale->ctype->wc_isalnum(wc, locale);
+}
+
+bool
+pg_iswupper(pg_wchar wc, pg_locale_t locale)
+{
+	if (locale->ctype == NULL)
+		return (wc <= (pg_wchar) 127 &&
+				(pg_char_properties[wc] & PG_ISUPPER));
+	else
+		return locale->ctype->wc_isupper(wc, locale);
+}
+
+bool
+pg_iswlower(pg_wchar wc, pg_locale_t locale)
+{
+	if (locale->ctype == NULL)
+		return (wc <= (pg_wchar) 127 &&
+				(pg_char_properties[wc] & PG_ISLOWER));
+	else
+		return locale->ctype->wc_islower(wc, locale);
+}
+
+bool
+pg_iswgraph(pg_wchar wc, pg_locale_t locale)
+{
+	if (locale->ctype == NULL)
+		return (wc <= (pg_wchar) 127 &&
+				(pg_char_properties[wc] & PG_ISGRAPH));
+	else
+		return locale->ctype->wc_isgraph(wc, locale);
+}
+
+bool
+pg_iswprint(pg_wchar wc, pg_locale_t locale)
+{
+	if (locale->ctype == NULL)
+		return (wc <= (pg_wchar) 127 &&
+				(pg_char_properties[wc] & PG_ISPRINT));
+	else
+		return locale->ctype->wc_isprint(wc, locale);
+}
+
+bool
+pg_iswpunct(pg_wchar wc, pg_locale_t locale)
+{
+	if (locale->ctype == NULL)
+		return (wc <= (pg_wchar) 127 &&
+				(pg_char_properties[wc] & PG_ISPUNCT));
+	else
+		return locale->ctype->wc_ispunct(wc, locale);
+}
+
+bool
+pg_iswspace(pg_wchar wc, pg_locale_t locale)
+{
+	if (locale->ctype == NULL)
+		return (wc <= (pg_wchar) 127 &&
+				(pg_char_properties[wc] & PG_ISSPACE));
+	else
+		return locale->ctype->wc_isspace(wc, locale);
+}
+
+pg_wchar
+pg_towupper(pg_wchar wc, pg_locale_t locale)
+{
+	if (locale->ctype == NULL)
+	{
+		if (wc <= (pg_wchar) 127)
+			return pg_ascii_toupper((unsigned char) wc);
+		return wc;
+	}
+	else
+		return locale->ctype->wc_toupper(wc, locale);
+}
+
+pg_wchar
+pg_towlower(pg_wchar wc, pg_locale_t locale)
+{
+	if (locale->ctype == NULL)
+	{
+		if (wc <= (pg_wchar) 127)
+			return pg_ascii_tolower((unsigned char) wc);
+		return wc;
+	}
+	else
+		return locale->ctype->wc_tolower(wc, locale);
+}
+
 /*
  * char_is_cased()
  *
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index 7e83594fba..009f5334a8 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -208,6 +208,18 @@ extern size_t pg_strxfrm_prefix(char *dest, const char *src, size_t destsize,
 extern size_t pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
 								 ssize_t srclen, pg_locale_t locale);
 
+extern bool pg_iswdigit(pg_wchar wc, pg_locale_t locale);
+extern bool pg_iswalpha(pg_wchar wc, pg_locale_t locale);
+extern bool pg_iswalnum(pg_wchar wc, pg_locale_t locale);
+extern bool pg_iswupper(pg_wchar wc, pg_locale_t locale);
+extern bool pg_iswlower(pg_wchar wc, pg_locale_t locale);
+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 pg_wchar pg_towupper(pg_wchar wc, pg_locale_t locale);
+extern pg_wchar pg_towlower(pg_wchar wc, pg_locale_t locale);
+
 extern int	builtin_locale_encoding(const char *locale);
 extern const char *builtin_validate_locale(int encoding, const char *locale);
 extern void icu_validate_locale(const char *loc_str);
diff --git a/src/include/utils/pg_locale_c.h b/src/include/utils/pg_locale_c.h
new file mode 100644
index 0000000000..11a0f996db
--- /dev/null
+++ b/src/include/utils/pg_locale_c.h
@@ -0,0 +1,160 @@
+/*-----------------------------------------------------------------------
+ *
+ * PostgreSQL locale utilities
+ *
+ * src/include/utils/pg_locale_c.h
+ *
+ * Copyright (c) 2002-2025, PostgreSQL Global Development Group
+ *
+ *-----------------------------------------------------------------------
+ */
+
+#ifndef _PG_LOCALE_C_
+#define _PG_LOCALE_C_
+
+/*
+ * Hard-wired character properties for C locale
+ */
+
+#define PG_ISDIGIT	0x01
+#define PG_ISALPHA	0x02
+#define PG_ISALNUM	(PG_ISDIGIT | PG_ISALPHA)
+#define PG_ISUPPER	0x04
+#define PG_ISLOWER	0x08
+#define PG_ISGRAPH	0x10
+#define PG_ISPRINT	0x20
+#define PG_ISPUNCT	0x40
+#define PG_ISSPACE	0x80
+
+static const unsigned char pg_char_properties[128] = {
+	 /* NUL */ 0,
+	 /* ^A */ 0,
+	 /* ^B */ 0,
+	 /* ^C */ 0,
+	 /* ^D */ 0,
+	 /* ^E */ 0,
+	 /* ^F */ 0,
+	 /* ^G */ 0,
+	 /* ^H */ 0,
+	 /* ^I */ PG_ISSPACE,
+	 /* ^J */ PG_ISSPACE,
+	 /* ^K */ PG_ISSPACE,
+	 /* ^L */ PG_ISSPACE,
+	 /* ^M */ PG_ISSPACE,
+	 /* ^N */ 0,
+	 /* ^O */ 0,
+	 /* ^P */ 0,
+	 /* ^Q */ 0,
+	 /* ^R */ 0,
+	 /* ^S */ 0,
+	 /* ^T */ 0,
+	 /* ^U */ 0,
+	 /* ^V */ 0,
+	 /* ^W */ 0,
+	 /* ^X */ 0,
+	 /* ^Y */ 0,
+	 /* ^Z */ 0,
+	 /* ^[ */ 0,
+	 /* ^\ */ 0,
+	 /* ^] */ 0,
+	 /* ^^ */ 0,
+	 /* ^_ */ 0,
+	 /* */ PG_ISPRINT | PG_ISSPACE,
+	 /* !  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* "  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* #  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* $  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* %  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* &  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* '  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* (  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* )  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* *  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* +  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* ,  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* -  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* .  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* /  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* 0  */ PG_ISDIGIT | PG_ISGRAPH | PG_ISPRINT,
+	 /* 1  */ PG_ISDIGIT | PG_ISGRAPH | PG_ISPRINT,
+	 /* 2  */ PG_ISDIGIT | PG_ISGRAPH | PG_ISPRINT,
+	 /* 3  */ PG_ISDIGIT | PG_ISGRAPH | PG_ISPRINT,
+	 /* 4  */ PG_ISDIGIT | PG_ISGRAPH | PG_ISPRINT,
+	 /* 5  */ PG_ISDIGIT | PG_ISGRAPH | PG_ISPRINT,
+	 /* 6  */ PG_ISDIGIT | PG_ISGRAPH | PG_ISPRINT,
+	 /* 7  */ PG_ISDIGIT | PG_ISGRAPH | PG_ISPRINT,
+	 /* 8  */ PG_ISDIGIT | PG_ISGRAPH | PG_ISPRINT,
+	 /* 9  */ PG_ISDIGIT | PG_ISGRAPH | PG_ISPRINT,
+	 /* :  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* ;  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* <  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* =  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* >  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* ?  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* @  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* A  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* B  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* C  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* D  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* E  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* F  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* G  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* H  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* I  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* J  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* K  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* L  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* M  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* N  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* O  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* P  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* Q  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* R  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* S  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* T  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* U  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* V  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* W  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* X  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* Y  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* Z  */ PG_ISALPHA | PG_ISUPPER | PG_ISGRAPH | PG_ISPRINT,
+	 /* [  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* \  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* ]  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* ^  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* _  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* `  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* a  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* b  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* c  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* d  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* e  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* f  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* g  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* h  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* i  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* j  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* k  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* l  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* m  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* n  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* o  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* p  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* q  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* r  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* s  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* t  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* u  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* v  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* w  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* x  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* y  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* z  */ PG_ISALPHA | PG_ISLOWER | PG_ISGRAPH | PG_ISPRINT,
+	 /* {  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* |  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* }  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* ~  */ PG_ISGRAPH | PG_ISPRINT | PG_ISPUNCT,
+	 /* DEL */ 0
+};
+
+#endif							/* _PG_LOCALE_C_ */
-- 
2.39.5

