From af164f31b9f5f00561d5831a72ab91cfe091f92e Mon Sep 17 00:00:00 2001 From: Jeff Davis 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 2242e72194c..e0c892db713 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 97c2ac1faf9..50b25445f7a 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 7e83594fbaf..009f5334a87 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 00000000000..11a0f996db2 --- /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_ */