Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Defines | Typedefs | Enumerations | Functions | Variables

regc_pg_locale.c File Reference

#include "catalog/pg_collation.h"
#include "utils/pg_locale.h"
Include dependency graph for regc_pg_locale.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  pg_ctype_cache

Defines

#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

Typedefs

typedef int(* pg_wc_probefunc )(pg_wchar c)
typedef struct pg_ctype_cache pg_ctype_cache

Enumerations

enum  PG_Locale_Strategy {
  PG_REGEX_LOCALE_C, PG_REGEX_LOCALE_WIDE, PG_REGEX_LOCALE_1BYTE, PG_REGEX_LOCALE_WIDE_L,
  PG_REGEX_LOCALE_1BYTE_L
}

Functions

void pg_set_regex_collation (Oid collation)
static int pg_wc_isdigit (pg_wchar c)
static int pg_wc_isalpha (pg_wchar c)
static int pg_wc_isalnum (pg_wchar c)
static int pg_wc_isupper (pg_wchar c)
static int pg_wc_islower (pg_wchar c)
static int pg_wc_isgraph (pg_wchar c)
static int pg_wc_isprint (pg_wchar c)
static int pg_wc_ispunct (pg_wchar c)
static int pg_wc_isspace (pg_wchar c)
static pg_wchar pg_wc_toupper (pg_wchar c)
static pg_wchar pg_wc_tolower (pg_wchar c)
static bool store_match (pg_ctype_cache *pcc, pg_wchar chr1, int nchrs)
static struct cvecpg_ctype_get_cache (pg_wc_probefunc probefunc)

Variables

static PG_Locale_Strategy pg_regex_strategy
static pg_locale_t pg_regex_locale
static Oid pg_regex_collation
static const unsigned char pg_char_properties [128]
static pg_ctype_cachepg_ctype_cache_list = NULL

Define Documentation

#define PG_ISALNUM   (PG_ISDIGIT | PG_ISALPHA)

Definition at line 83 of file regc_pg_locale.c.

Referenced by pg_wc_isalnum().

#define PG_ISALPHA   0x02

Definition at line 82 of file regc_pg_locale.c.

Referenced by pg_wc_isalpha().

#define PG_ISDIGIT   0x01

Definition at line 81 of file regc_pg_locale.c.

Referenced by pg_wc_isdigit().

#define PG_ISGRAPH   0x10

Definition at line 86 of file regc_pg_locale.c.

Referenced by pg_wc_isgraph().

#define PG_ISLOWER   0x08

Definition at line 85 of file regc_pg_locale.c.

Referenced by pg_wc_islower().

#define PG_ISPRINT   0x20

Definition at line 87 of file regc_pg_locale.c.

Referenced by pg_wc_isprint().

#define PG_ISPUNCT   0x40

Definition at line 88 of file regc_pg_locale.c.

Referenced by pg_wc_ispunct().

#define PG_ISSPACE   0x80

Definition at line 89 of file regc_pg_locale.c.

Referenced by pg_wc_isspace().

#define PG_ISUPPER   0x04

Definition at line 84 of file regc_pg_locale.c.

Referenced by pg_wc_isupper().


Typedef Documentation

typedef int(* pg_wc_probefunc)(pg_wchar c)

Definition at line 679 of file regc_pg_locale.c.


Enumeration Type Documentation

Enumerator:
PG_REGEX_LOCALE_C 
PG_REGEX_LOCALE_WIDE 
PG_REGEX_LOCALE_1BYTE 
PG_REGEX_LOCALE_WIDE_L 
PG_REGEX_LOCALE_1BYTE_L 

Definition at line 65 of file regc_pg_locale.c.

{
    PG_REGEX_LOCALE_C,          /* C locale (encoding independent) */
    PG_REGEX_LOCALE_WIDE,       /* Use <wctype.h> functions */
    PG_REGEX_LOCALE_1BYTE,      /* Use <ctype.h> functions */
    PG_REGEX_LOCALE_WIDE_L,     /* Use locale_t <wctype.h> functions */
    PG_REGEX_LOCALE_1BYTE_L     /* Use locale_t <ctype.h> functions */
} PG_Locale_Strategy;


Function Documentation

static struct cvec* pg_ctype_get_cache ( pg_wc_probefunc  probefunc  )  [static, read]

Definition at line 739 of file regc_pg_locale.c.

References cvec::chrs, cvec::chrspace, pg_ctype_cache::collation, pg_ctype_cache::cv, free, malloc, cvec::nchrs, pg_ctype_cache::next, cvec::nranges, NULL, pg_regex_collation, PG_REGEX_LOCALE_1BYTE, PG_REGEX_LOCALE_1BYTE_L, PG_REGEX_LOCALE_C, PG_REGEX_LOCALE_WIDE, PG_REGEX_LOCALE_WIDE_L, pg_regex_strategy, pg_ctype_cache::probefunc, cvec::ranges, cvec::rangespace, realloc, and store_match().

Referenced by cclass().

{
    pg_ctype_cache *pcc;
    pg_wchar    max_chr;
    pg_wchar    cur_chr;
    int         nmatches;
    chr        *newchrs;

    /*
     * Do we already have the answer cached?
     */
    for (pcc = pg_ctype_cache_list; pcc != NULL; pcc = pcc->next)
    {
        if (pcc->probefunc == probefunc &&
            pcc->collation == pg_regex_collation)
            return &pcc->cv;
    }

    /*
     * Nope, so initialize some workspace ...
     */
    pcc = (pg_ctype_cache *) malloc(sizeof(pg_ctype_cache));
    if (pcc == NULL)
        return NULL;
    pcc->probefunc = probefunc;
    pcc->collation = pg_regex_collation;
    pcc->cv.nchrs = 0;
    pcc->cv.chrspace = 128;
    pcc->cv.chrs = (chr *) malloc(pcc->cv.chrspace * sizeof(chr));
    pcc->cv.nranges = 0;
    pcc->cv.rangespace = 64;
    pcc->cv.ranges = (chr *) malloc(pcc->cv.rangespace * sizeof(chr) * 2);
    if (pcc->cv.chrs == NULL || pcc->cv.ranges == NULL)
        goto out_of_memory;

    /*
     * Decide how many character codes we ought to look through.  For C locale
     * there's no need to go further than 127.  Otherwise, if the encoding is
     * UTF8 go up to 0x7FF, which is a pretty arbitrary cutoff but we cannot
     * extend it as far as we'd like (say, 0xFFFF, the end of the Basic
     * Multilingual Plane) without creating significant performance issues due
     * to too many characters being fed through the colormap code.  This will
     * need redesign to fix reasonably, but at least for the moment we have
     * all common European languages covered.  Otherwise (not C, not UTF8) go
     * up to 255.  These limits are interrelated with restrictions discussed
     * at the head of this file.
     */
    switch (pg_regex_strategy)
    {
        case PG_REGEX_LOCALE_C:
            max_chr = (pg_wchar) 127;
            break;
        case PG_REGEX_LOCALE_WIDE:
        case PG_REGEX_LOCALE_WIDE_L:
            max_chr = (pg_wchar) 0x7FF;
            break;
        case PG_REGEX_LOCALE_1BYTE:
        case PG_REGEX_LOCALE_1BYTE_L:
            max_chr = (pg_wchar) UCHAR_MAX;
            break;
        default:
            max_chr = 0;        /* can't get here, but keep compiler quiet */
            break;
    }

    /*
     * And scan 'em ...
     */
    nmatches = 0;               /* number of consecutive matches */

    for (cur_chr = 0; cur_chr <= max_chr; cur_chr++)
    {
        if ((*probefunc) (cur_chr))
            nmatches++;
        else if (nmatches > 0)
        {
            if (!store_match(pcc, cur_chr - nmatches, nmatches))
                goto out_of_memory;
            nmatches = 0;
        }
    }

    if (nmatches > 0)
        if (!store_match(pcc, cur_chr - nmatches, nmatches))
            goto out_of_memory;

    /*
     * We might have allocated more memory than needed, if so free it
     */
    if (pcc->cv.nchrs == 0)
    {
        free(pcc->cv.chrs);
        pcc->cv.chrs = NULL;
        pcc->cv.chrspace = 0;
    }
    else if (pcc->cv.nchrs < pcc->cv.chrspace)
    {
        newchrs = (chr *) realloc(pcc->cv.chrs,
                                  pcc->cv.nchrs * sizeof(chr));
        if (newchrs == NULL)
            goto out_of_memory;
        pcc->cv.chrs = newchrs;
        pcc->cv.chrspace = pcc->cv.nchrs;
    }
    if (pcc->cv.nranges == 0)
    {
        free(pcc->cv.ranges);
        pcc->cv.ranges = NULL;
        pcc->cv.rangespace = 0;
    }
    else if (pcc->cv.nranges < pcc->cv.rangespace)
    {
        newchrs = (chr *) realloc(pcc->cv.ranges,
                                  pcc->cv.nranges * sizeof(chr) * 2);
        if (newchrs == NULL)
            goto out_of_memory;
        pcc->cv.ranges = newchrs;
        pcc->cv.rangespace = pcc->cv.nranges;
    }

    /*
     * Success, link it into cache chain
     */
    pcc->next = pg_ctype_cache_list;
    pg_ctype_cache_list = pcc;

    return &pcc->cv;

    /*
     * Failure, clean up
     */
out_of_memory:
    if (pcc->cv.chrs)
        free(pcc->cv.chrs);
    if (pcc->cv.ranges)
        free(pcc->cv.ranges);
    free(pcc);

    return NULL;
}

void pg_set_regex_collation ( Oid  collation  ) 

Definition at line 231 of file regc_pg_locale.c.

References DEFAULT_COLLATION_OID, ereport, errcode(), errhint(), errmsg(), ERROR, GetDatabaseEncoding(), lc_ctype_is_c(), OidIsValid, pg_newlocale_from_collation(), pg_regex_collation, pg_regex_locale, pg_regex_strategy, and PG_UTF8.

Referenced by pg_regcomp(), pg_regexec(), and pg_regprefix().

{
    if (lc_ctype_is_c(collation))
    {
        /* C/POSIX collations use this path regardless of database encoding */
        pg_regex_strategy = PG_REGEX_LOCALE_C;
        pg_regex_locale = 0;
        pg_regex_collation = C_COLLATION_OID;
    }
    else
    {
        if (collation == DEFAULT_COLLATION_OID)
            pg_regex_locale = 0;
        else if (OidIsValid(collation))
        {
            /*
             * NB: pg_newlocale_from_collation will fail if not HAVE_LOCALE_T;
             * the case of pg_regex_locale != 0 but not HAVE_LOCALE_T does not
             * have to be considered below.
             */
            pg_regex_locale = pg_newlocale_from_collation(collation);
        }
        else
        {
            /*
             * This typically means that the parser could not resolve a
             * conflict of implicit collations, so report it that way.
             */
            ereport(ERROR,
                    (errcode(ERRCODE_INDETERMINATE_COLLATION),
                     errmsg("could not determine which collation to use for regular expression"),
                     errhint("Use the COLLATE clause to set the collation explicitly.")));
        }

#ifdef USE_WIDE_UPPER_LOWER
        if (GetDatabaseEncoding() == PG_UTF8)
        {
            if (pg_regex_locale)
                pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
            else
                pg_regex_strategy = PG_REGEX_LOCALE_WIDE;
        }
        else
#endif   /* USE_WIDE_UPPER_LOWER */
        {
            if (pg_regex_locale)
                pg_regex_strategy = PG_REGEX_LOCALE_1BYTE_L;
            else
                pg_regex_strategy = PG_REGEX_LOCALE_1BYTE;
        }

        pg_regex_collation = collation;
    }
}

static int pg_wc_isalnum ( pg_wchar  c  )  [static]

Definition at line 353 of file regc_pg_locale.c.

References isalnum_l, iswalnum_l, pg_char_properties, PG_ISALNUM, pg_regex_locale, PG_REGEX_LOCALE_1BYTE, PG_REGEX_LOCALE_1BYTE_L, PG_REGEX_LOCALE_C, PG_REGEX_LOCALE_WIDE, PG_REGEX_LOCALE_WIDE_L, and pg_regex_strategy.

Referenced by cclass().

{
    switch (pg_regex_strategy)
    {
        case PG_REGEX_LOCALE_C:
            return (c <= (pg_wchar) 127 &&
                    (pg_char_properties[c] & PG_ISALNUM));
        case PG_REGEX_LOCALE_WIDE:
#ifdef USE_WIDE_UPPER_LOWER
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return iswalnum((wint_t) c);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE:
            return (c <= (pg_wchar) UCHAR_MAX &&
                    isalnum((unsigned char) c));
        case PG_REGEX_LOCALE_WIDE_L:
#if defined(HAVE_LOCALE_T) && defined(USE_WIDE_UPPER_LOWER)
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return iswalnum_l((wint_t) c, pg_regex_locale);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE_L:
#ifdef HAVE_LOCALE_T
            return (c <= (pg_wchar) UCHAR_MAX &&
                    isalnum_l((unsigned char) c, pg_regex_locale));
#endif
            break;
    }
    return 0;                   /* can't get here, but keep compiler quiet */
}

static int pg_wc_isalpha ( pg_wchar  c  )  [static]

Definition at line 320 of file regc_pg_locale.c.

References isalpha_l, iswalpha_l, pg_char_properties, PG_ISALPHA, pg_regex_locale, PG_REGEX_LOCALE_1BYTE, PG_REGEX_LOCALE_1BYTE_L, PG_REGEX_LOCALE_C, PG_REGEX_LOCALE_WIDE, PG_REGEX_LOCALE_WIDE_L, and pg_regex_strategy.

Referenced by cclass().

{
    switch (pg_regex_strategy)
    {
        case PG_REGEX_LOCALE_C:
            return (c <= (pg_wchar) 127 &&
                    (pg_char_properties[c] & PG_ISALPHA));
        case PG_REGEX_LOCALE_WIDE:
#ifdef USE_WIDE_UPPER_LOWER
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return iswalpha((wint_t) c);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE:
            return (c <= (pg_wchar) UCHAR_MAX &&
                    isalpha((unsigned char) c));
        case PG_REGEX_LOCALE_WIDE_L:
#if defined(HAVE_LOCALE_T) && defined(USE_WIDE_UPPER_LOWER)
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return iswalpha_l((wint_t) c, pg_regex_locale);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE_L:
#ifdef HAVE_LOCALE_T
            return (c <= (pg_wchar) UCHAR_MAX &&
                    isalpha_l((unsigned char) c, pg_regex_locale));
#endif
            break;
    }
    return 0;                   /* can't get here, but keep compiler quiet */
}

static int pg_wc_isdigit ( pg_wchar  c  )  [static]

Definition at line 287 of file regc_pg_locale.c.

References isdigit_l, iswdigit_l, pg_char_properties, PG_ISDIGIT, pg_regex_locale, PG_REGEX_LOCALE_1BYTE, PG_REGEX_LOCALE_1BYTE_L, PG_REGEX_LOCALE_C, PG_REGEX_LOCALE_WIDE, PG_REGEX_LOCALE_WIDE_L, and pg_regex_strategy.

Referenced by cclass().

{
    switch (pg_regex_strategy)
    {
        case PG_REGEX_LOCALE_C:
            return (c <= (pg_wchar) 127 &&
                    (pg_char_properties[c] & PG_ISDIGIT));
        case PG_REGEX_LOCALE_WIDE:
#ifdef USE_WIDE_UPPER_LOWER
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return iswdigit((wint_t) c);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE:
            return (c <= (pg_wchar) UCHAR_MAX &&
                    isdigit((unsigned char) c));
        case PG_REGEX_LOCALE_WIDE_L:
#if defined(HAVE_LOCALE_T) && defined(USE_WIDE_UPPER_LOWER)
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return iswdigit_l((wint_t) c, pg_regex_locale);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE_L:
#ifdef HAVE_LOCALE_T
            return (c <= (pg_wchar) UCHAR_MAX &&
                    isdigit_l((unsigned char) c, pg_regex_locale));
#endif
            break;
    }
    return 0;                   /* can't get here, but keep compiler quiet */
}

static int pg_wc_isgraph ( pg_wchar  c  )  [static]

Definition at line 452 of file regc_pg_locale.c.

References isgraph_l, iswgraph_l, pg_char_properties, PG_ISGRAPH, pg_regex_locale, PG_REGEX_LOCALE_1BYTE, PG_REGEX_LOCALE_1BYTE_L, PG_REGEX_LOCALE_C, PG_REGEX_LOCALE_WIDE, PG_REGEX_LOCALE_WIDE_L, and pg_regex_strategy.

Referenced by cclass().

{
    switch (pg_regex_strategy)
    {
        case PG_REGEX_LOCALE_C:
            return (c <= (pg_wchar) 127 &&
                    (pg_char_properties[c] & PG_ISGRAPH));
        case PG_REGEX_LOCALE_WIDE:
#ifdef USE_WIDE_UPPER_LOWER
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return iswgraph((wint_t) c);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE:
            return (c <= (pg_wchar) UCHAR_MAX &&
                    isgraph((unsigned char) c));
        case PG_REGEX_LOCALE_WIDE_L:
#if defined(HAVE_LOCALE_T) && defined(USE_WIDE_UPPER_LOWER)
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return iswgraph_l((wint_t) c, pg_regex_locale);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE_L:
#ifdef HAVE_LOCALE_T
            return (c <= (pg_wchar) UCHAR_MAX &&
                    isgraph_l((unsigned char) c, pg_regex_locale));
#endif
            break;
    }
    return 0;                   /* can't get here, but keep compiler quiet */
}

static int pg_wc_islower ( pg_wchar  c  )  [static]

Definition at line 419 of file regc_pg_locale.c.

References islower_l, iswlower_l, pg_char_properties, PG_ISLOWER, pg_regex_locale, PG_REGEX_LOCALE_1BYTE, PG_REGEX_LOCALE_1BYTE_L, PG_REGEX_LOCALE_C, PG_REGEX_LOCALE_WIDE, PG_REGEX_LOCALE_WIDE_L, and pg_regex_strategy.

Referenced by cclass().

{
    switch (pg_regex_strategy)
    {
        case PG_REGEX_LOCALE_C:
            return (c <= (pg_wchar) 127 &&
                    (pg_char_properties[c] & PG_ISLOWER));
        case PG_REGEX_LOCALE_WIDE:
#ifdef USE_WIDE_UPPER_LOWER
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return iswlower((wint_t) c);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE:
            return (c <= (pg_wchar) UCHAR_MAX &&
                    islower((unsigned char) c));
        case PG_REGEX_LOCALE_WIDE_L:
#if defined(HAVE_LOCALE_T) && defined(USE_WIDE_UPPER_LOWER)
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return iswlower_l((wint_t) c, pg_regex_locale);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE_L:
#ifdef HAVE_LOCALE_T
            return (c <= (pg_wchar) UCHAR_MAX &&
                    islower_l((unsigned char) c, pg_regex_locale));
#endif
            break;
    }
    return 0;                   /* can't get here, but keep compiler quiet */
}

static int pg_wc_isprint ( pg_wchar  c  )  [static]

Definition at line 485 of file regc_pg_locale.c.

References isprint_l, iswprint_l, pg_char_properties, PG_ISPRINT, pg_regex_locale, PG_REGEX_LOCALE_1BYTE, PG_REGEX_LOCALE_1BYTE_L, PG_REGEX_LOCALE_C, PG_REGEX_LOCALE_WIDE, PG_REGEX_LOCALE_WIDE_L, and pg_regex_strategy.

Referenced by cclass().

{
    switch (pg_regex_strategy)
    {
        case PG_REGEX_LOCALE_C:
            return (c <= (pg_wchar) 127 &&
                    (pg_char_properties[c] & PG_ISPRINT));
        case PG_REGEX_LOCALE_WIDE:
#ifdef USE_WIDE_UPPER_LOWER
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return iswprint((wint_t) c);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE:
            return (c <= (pg_wchar) UCHAR_MAX &&
                    isprint((unsigned char) c));
        case PG_REGEX_LOCALE_WIDE_L:
#if defined(HAVE_LOCALE_T) && defined(USE_WIDE_UPPER_LOWER)
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return iswprint_l((wint_t) c, pg_regex_locale);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE_L:
#ifdef HAVE_LOCALE_T
            return (c <= (pg_wchar) UCHAR_MAX &&
                    isprint_l((unsigned char) c, pg_regex_locale));
#endif
            break;
    }
    return 0;                   /* can't get here, but keep compiler quiet */
}

static int pg_wc_ispunct ( pg_wchar  c  )  [static]

Definition at line 518 of file regc_pg_locale.c.

References ispunct_l, iswpunct_l, pg_char_properties, PG_ISPUNCT, pg_regex_locale, PG_REGEX_LOCALE_1BYTE, PG_REGEX_LOCALE_1BYTE_L, PG_REGEX_LOCALE_C, PG_REGEX_LOCALE_WIDE, PG_REGEX_LOCALE_WIDE_L, and pg_regex_strategy.

Referenced by cclass().

{
    switch (pg_regex_strategy)
    {
        case PG_REGEX_LOCALE_C:
            return (c <= (pg_wchar) 127 &&
                    (pg_char_properties[c] & PG_ISPUNCT));
        case PG_REGEX_LOCALE_WIDE:
#ifdef USE_WIDE_UPPER_LOWER
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return iswpunct((wint_t) c);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE:
            return (c <= (pg_wchar) UCHAR_MAX &&
                    ispunct((unsigned char) c));
        case PG_REGEX_LOCALE_WIDE_L:
#if defined(HAVE_LOCALE_T) && defined(USE_WIDE_UPPER_LOWER)
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return iswpunct_l((wint_t) c, pg_regex_locale);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE_L:
#ifdef HAVE_LOCALE_T
            return (c <= (pg_wchar) UCHAR_MAX &&
                    ispunct_l((unsigned char) c, pg_regex_locale));
#endif
            break;
    }
    return 0;                   /* can't get here, but keep compiler quiet */
}

static int pg_wc_isspace ( pg_wchar  c  )  [static]

Definition at line 551 of file regc_pg_locale.c.

References isspace_l, iswspace_l, pg_char_properties, PG_ISSPACE, pg_regex_locale, PG_REGEX_LOCALE_1BYTE, PG_REGEX_LOCALE_1BYTE_L, PG_REGEX_LOCALE_C, PG_REGEX_LOCALE_WIDE, PG_REGEX_LOCALE_WIDE_L, and pg_regex_strategy.

Referenced by cclass().

{
    switch (pg_regex_strategy)
    {
        case PG_REGEX_LOCALE_C:
            return (c <= (pg_wchar) 127 &&
                    (pg_char_properties[c] & PG_ISSPACE));
        case PG_REGEX_LOCALE_WIDE:
#ifdef USE_WIDE_UPPER_LOWER
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return iswspace((wint_t) c);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE:
            return (c <= (pg_wchar) UCHAR_MAX &&
                    isspace((unsigned char) c));
        case PG_REGEX_LOCALE_WIDE_L:
#if defined(HAVE_LOCALE_T) && defined(USE_WIDE_UPPER_LOWER)
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return iswspace_l((wint_t) c, pg_regex_locale);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE_L:
#ifdef HAVE_LOCALE_T
            return (c <= (pg_wchar) UCHAR_MAX &&
                    isspace_l((unsigned char) c, pg_regex_locale));
#endif
            break;
    }
    return 0;                   /* can't get here, but keep compiler quiet */
}

static int pg_wc_isupper ( pg_wchar  c  )  [static]

Definition at line 386 of file regc_pg_locale.c.

References isupper_l, iswupper_l, pg_char_properties, PG_ISUPPER, pg_regex_locale, PG_REGEX_LOCALE_1BYTE, PG_REGEX_LOCALE_1BYTE_L, PG_REGEX_LOCALE_C, PG_REGEX_LOCALE_WIDE, PG_REGEX_LOCALE_WIDE_L, and pg_regex_strategy.

Referenced by cclass().

{
    switch (pg_regex_strategy)
    {
        case PG_REGEX_LOCALE_C:
            return (c <= (pg_wchar) 127 &&
                    (pg_char_properties[c] & PG_ISUPPER));
        case PG_REGEX_LOCALE_WIDE:
#ifdef USE_WIDE_UPPER_LOWER
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return iswupper((wint_t) c);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE:
            return (c <= (pg_wchar) UCHAR_MAX &&
                    isupper((unsigned char) c));
        case PG_REGEX_LOCALE_WIDE_L:
#if defined(HAVE_LOCALE_T) && defined(USE_WIDE_UPPER_LOWER)
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return iswupper_l((wint_t) c, pg_regex_locale);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE_L:
#ifdef HAVE_LOCALE_T
            return (c <= (pg_wchar) UCHAR_MAX &&
                    isupper_l((unsigned char) c, pg_regex_locale));
#endif
            break;
    }
    return 0;                   /* can't get here, but keep compiler quiet */
}

static pg_wchar pg_wc_tolower ( pg_wchar  c  )  [static]

Definition at line 625 of file regc_pg_locale.c.

References pg_ascii_tolower(), pg_regex_locale, PG_REGEX_LOCALE_1BYTE, PG_REGEX_LOCALE_1BYTE_L, PG_REGEX_LOCALE_C, PG_REGEX_LOCALE_WIDE, PG_REGEX_LOCALE_WIDE_L, pg_regex_strategy, tolower_l, and towlower_l.

Referenced by allcases(), casecmp(), and range().

{
    switch (pg_regex_strategy)
    {
        case PG_REGEX_LOCALE_C:
            if (c <= (pg_wchar) 127)
                return pg_ascii_tolower((unsigned char) c);
            return c;
        case PG_REGEX_LOCALE_WIDE:
            /* force C behavior for ASCII characters, per comments above */
            if (c <= (pg_wchar) 127)
                return pg_ascii_tolower((unsigned char) c);
#ifdef USE_WIDE_UPPER_LOWER
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return towlower((wint_t) c);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE:
            /* force C behavior for ASCII characters, per comments above */
            if (c <= (pg_wchar) 127)
                return pg_ascii_tolower((unsigned char) c);
            if (c <= (pg_wchar) UCHAR_MAX)
                return tolower((unsigned char) c);
            return c;
        case PG_REGEX_LOCALE_WIDE_L:
#if defined(HAVE_LOCALE_T) && defined(USE_WIDE_UPPER_LOWER)
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return towlower_l((wint_t) c, pg_regex_locale);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE_L:
#ifdef HAVE_LOCALE_T
            if (c <= (pg_wchar) UCHAR_MAX)
                return tolower_l((unsigned char) c, pg_regex_locale);
#endif
            return c;
    }
    return 0;                   /* can't get here, but keep compiler quiet */
}

static pg_wchar pg_wc_toupper ( pg_wchar  c  )  [static]

Definition at line 584 of file regc_pg_locale.c.

References pg_ascii_toupper(), pg_regex_locale, PG_REGEX_LOCALE_1BYTE, PG_REGEX_LOCALE_1BYTE_L, PG_REGEX_LOCALE_C, PG_REGEX_LOCALE_WIDE, PG_REGEX_LOCALE_WIDE_L, pg_regex_strategy, toupper_l, and towupper_l.

Referenced by allcases(), and range().

{
    switch (pg_regex_strategy)
    {
        case PG_REGEX_LOCALE_C:
            if (c <= (pg_wchar) 127)
                return pg_ascii_toupper((unsigned char) c);
            return c;
        case PG_REGEX_LOCALE_WIDE:
            /* force C behavior for ASCII characters, per comments above */
            if (c <= (pg_wchar) 127)
                return pg_ascii_toupper((unsigned char) c);
#ifdef USE_WIDE_UPPER_LOWER
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return towupper((wint_t) c);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE:
            /* force C behavior for ASCII characters, per comments above */
            if (c <= (pg_wchar) 127)
                return pg_ascii_toupper((unsigned char) c);
            if (c <= (pg_wchar) UCHAR_MAX)
                return toupper((unsigned char) c);
            return c;
        case PG_REGEX_LOCALE_WIDE_L:
#if defined(HAVE_LOCALE_T) && defined(USE_WIDE_UPPER_LOWER)
            if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
                return towupper_l((wint_t) c, pg_regex_locale);
#endif
            /* FALL THRU */
        case PG_REGEX_LOCALE_1BYTE_L:
#ifdef HAVE_LOCALE_T
            if (c <= (pg_wchar) UCHAR_MAX)
                return toupper_l((unsigned char) c, pg_regex_locale);
#endif
            return c;
    }
    return 0;                   /* can't get here, but keep compiler quiet */
}

static bool store_match ( pg_ctype_cache pcc,
pg_wchar  chr1,
int  nchrs 
) [static]

Definition at line 695 of file regc_pg_locale.c.

References assert, cvec::chrs, cvec::chrspace, pg_ctype_cache::cv, cvec::nchrs, cvec::nranges, NULL, cvec::ranges, cvec::rangespace, and realloc.

Referenced by pg_ctype_get_cache().

{
    chr        *newchrs;

    if (nchrs > 1)
    {
        if (pcc->cv.nranges >= pcc->cv.rangespace)
        {
            pcc->cv.rangespace *= 2;
            newchrs = (chr *) realloc(pcc->cv.ranges,
                                      pcc->cv.rangespace * sizeof(chr) * 2);
            if (newchrs == NULL)
                return false;
            pcc->cv.ranges = newchrs;
        }
        pcc->cv.ranges[pcc->cv.nranges * 2] = chr1;
        pcc->cv.ranges[pcc->cv.nranges * 2 + 1] = chr1 + nchrs - 1;
        pcc->cv.nranges++;
    }
    else
    {
        assert(nchrs == 1);
        if (pcc->cv.nchrs >= pcc->cv.chrspace)
        {
            pcc->cv.chrspace *= 2;
            newchrs = (chr *) realloc(pcc->cv.chrs,
                                      pcc->cv.chrspace * sizeof(chr));
            if (newchrs == NULL)
                return false;
            pcc->cv.chrs = newchrs;
        }
        pcc->cv.chrs[pcc->cv.nchrs++] = chr1;
    }
    return true;
}


Variable Documentation

const unsigned char pg_char_properties[128] [static]

Definition at line 689 of file regc_pg_locale.c.

Definition at line 76 of file regc_pg_locale.c.

Referenced by pg_ctype_get_cache(), and pg_set_regex_collation().