Add pg_iswalpha() and related functions.
authorJeff Davis <jdavis@postgresql.org>
Wed, 15 Oct 2025 19:54:01 +0000 (12:54 -0700)
committerJeff Davis <jdavis@postgresql.org>
Wed, 15 Oct 2025 19:54:01 +0000 (12:54 -0700)
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
src/backend/utils/adt/pg_locale.c
src/include/utils/pg_locale.h
src/include/utils/pg_locale_c.h [new file with mode: 0644]

index 2242e72194c01c8084644d0f17e996c72a5a5f0d..e0c892db713a4e43faf7564fe0491eab7b33303d 100644 (file)
@@ -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)
 {
index 97c2ac1faf9a44617e42105546674c676e442347..50b25445f7ad4695dfbef06ab4e1cda848be9d95 100644 (file)
@@ -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()
  *
index 7e83594fbaf64d065a1541b2c6b6c62171ac4dad..009f5334a8707155248aad26f7a3cf8ac070c667 100644 (file)
@@ -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 (file)
index 0000000..11a0f99
--- /dev/null
@@ -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_ */