Header And Logo

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

Data Structures | Functions | Variables

regc_locale.c File Reference

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  cname

Functions

static celt element (struct vars *v, const chr *startp, const chr *endp)
static struct cvecrange (struct vars *v, celt a, celt b, int cases)
static int before (celt x, celt y)
static struct cvececlass (struct vars *v, celt c, int cases)
static struct cveccclass (struct vars *v, const chr *startp, const chr *endp, int cases)
static struct cvecallcases (struct vars *v, chr pc)
static int cmp (const chr *x, const chr *y, size_t len)
static int casecmp (const chr *x, const chr *y, size_t len)

Variables

static struct cname cnames []

Function Documentation

static struct cvec* allcases ( struct vars v,
chr  pc 
) [static, read]

Definition at line 649 of file regc_locale.c.

References addchr(), getcvec(), pg_wc_tolower(), and pg_wc_toupper().

Referenced by eclass().

{
    struct cvec *cv;
    chr         c = (chr) pc;
    chr         lc,
                uc;

    lc = pg_wc_tolower((chr) c);
    uc = pg_wc_toupper((chr) c);

    cv = getcvec(v, 2, 0);
    addchr(cv, lc);
    if (lc != uc)
        addchr(cv, uc);
    return cv;
}

static int before ( celt  x,
celt  y 
) [static]

Definition at line 457 of file regc_locale.c.

Referenced by range().

{
    if (x < y)
        return 1;
    return 0;
}

static int casecmp ( const chr x,
const chr y,
size_t  len 
) [static]

Definition at line 691 of file regc_locale.c.

References pg_wc_tolower().

{
    for (; len > 0; len--, x++, y++)
    {
        if ((*x != *y) && (pg_wc_tolower(*x) != pg_wc_tolower(*y)))
            return 1;
    }
    return 0;
}

static struct cvec* cclass ( struct vars v,
const chr startp,
const chr endp,
int  cases 
) [static, read]

Definition at line 509 of file regc_locale.c.

References addchr(), addrange(), ERR, getcvec(), i, NULL, pg_char_and_wchar_strncmp(), pg_ctype_get_cache(), pg_wc_isalnum(), pg_wc_isalpha(), pg_wc_isdigit(), pg_wc_isgraph(), pg_wc_islower(), pg_wc_isprint(), pg_wc_ispunct(), pg_wc_isspace(), pg_wc_isupper(), REG_ECTYPE, and REG_ESPACE.

{
    size_t      len;
    struct cvec *cv = NULL;
    const char *const * namePtr;
    int         i,
                index;

    /*
     * The following arrays define the valid character class names.
     */

    static const char *const classNames[] = {
        "alnum", "alpha", "ascii", "blank", "cntrl", "digit", "graph",
        "lower", "print", "punct", "space", "upper", "xdigit", NULL
    };

    enum classes
    {
        CC_ALNUM, CC_ALPHA, CC_ASCII, CC_BLANK, CC_CNTRL, CC_DIGIT, CC_GRAPH,
        CC_LOWER, CC_PRINT, CC_PUNCT, CC_SPACE, CC_UPPER, CC_XDIGIT
    };

    /*
     * Map the name to the corresponding enumerated value.
     */
    len = endp - startp;
    index = -1;
    for (namePtr = classNames, i = 0; *namePtr != NULL; namePtr++, i++)
    {
        if (strlen(*namePtr) == len &&
            pg_char_and_wchar_strncmp(*namePtr, startp, len) == 0)
        {
            index = i;
            break;
        }
    }
    if (index == -1)
    {
        ERR(REG_ECTYPE);
        return NULL;
    }

    /*
     * Remap lower and upper to alpha if the match is case insensitive.
     */

    if (cases &&
        ((enum classes) index == CC_LOWER ||
         (enum classes) index == CC_UPPER))
        index = (int) CC_ALPHA;

    /*
     * Now compute the character class contents.  For classes that are based
     * on the behavior of a <wctype.h> or <ctype.h> function, we use
     * pg_ctype_get_cache so that we can cache the results.  Other classes
     * have definitions that are hard-wired here, and for those we just
     * construct a transient cvec on the fly.
     */

    switch ((enum classes) index)
    {
        case CC_PRINT:
            cv = pg_ctype_get_cache(pg_wc_isprint);
            break;
        case CC_ALNUM:
            cv = pg_ctype_get_cache(pg_wc_isalnum);
            break;
        case CC_ALPHA:
            cv = pg_ctype_get_cache(pg_wc_isalpha);
            break;
        case CC_ASCII:
            /* hard-wired meaning */
            cv = getcvec(v, 0, 1);
            if (cv)
                addrange(cv, 0, 0x7f);
            break;
        case CC_BLANK:
            /* hard-wired meaning */
            cv = getcvec(v, 2, 0);
            addchr(cv, '\t');
            addchr(cv, ' ');
            break;
        case CC_CNTRL:
            /* hard-wired meaning */
            cv = getcvec(v, 0, 2);
            addrange(cv, 0x0, 0x1f);
            addrange(cv, 0x7f, 0x9f);
            break;
        case CC_DIGIT:
            cv = pg_ctype_get_cache(pg_wc_isdigit);
            break;
        case CC_PUNCT:
            cv = pg_ctype_get_cache(pg_wc_ispunct);
            break;
        case CC_XDIGIT:

            /*
             * It's not clear how to define this in non-western locales, and
             * even less clear that there's any particular use in trying. So
             * just hard-wire the meaning.
             */
            cv = getcvec(v, 0, 3);
            if (cv)
            {
                addrange(cv, '0', '9');
                addrange(cv, 'a', 'f');
                addrange(cv, 'A', 'F');
            }
            break;
        case CC_SPACE:
            cv = pg_ctype_get_cache(pg_wc_isspace);
            break;
        case CC_LOWER:
            cv = pg_ctype_get_cache(pg_wc_islower);
            break;
        case CC_UPPER:
            cv = pg_ctype_get_cache(pg_wc_isupper);
            break;
        case CC_GRAPH:
            cv = pg_ctype_get_cache(pg_wc_isgraph);
            break;
    }

    /* If cv is NULL now, the reason must be "out of memory" */
    if (cv == NULL)
        ERR(REG_ESPACE);
    return cv;
}

static int cmp ( const chr x,
const chr y,
size_t  len 
) [static]
static struct cvec* eclass ( struct vars v,
celt  c,
int  cases 
) [static, read]

Definition at line 469 of file regc_locale.c.

References addchr(), allcases(), assert, vars::cflags, getcvec(), NULL, and REG_FAKE.

{
    struct cvec *cv;

    /* crude fake equivalence class for testing */
    if ((v->cflags & REG_FAKE) && c == 'x')
    {
        cv = getcvec(v, 4, 0);
        addchr(cv, (chr) 'x');
        addchr(cv, (chr) 'y');
        if (cases)
        {
            addchr(cv, (chr) 'X');
            addchr(cv, (chr) 'Y');
        }
        return cv;
    }

    /* otherwise, none */
    if (cases)
        return allcases(v, c);
    cv = getcvec(v, 1, 0);
    assert(cv != NULL);
    addchr(cv, (chr) c);
    return cv;
}

static celt element ( struct vars v,
const chr startp,
const chr endp 
) [static]

Definition at line 367 of file regc_locale.c.

References assert, CHR, cnames, cname::code, ERR, cname::name, NOTE, NULL, pg_char_and_wchar_strncmp(), REG_ECOLLATE, and REG_ULOCALE.

Referenced by chrnamed(), ExecEvalArray(), json_array_element(), json_array_element_text(), transformCreateSchemaStmt(), and transformCreateStmt().

{
    const struct cname *cn;
    size_t      len;

    /* generic:  one-chr names stand for themselves */
    assert(startp < endp);
    len = endp - startp;
    if (len == 1)
        return *startp;

    NOTE(REG_ULOCALE);

    /* search table */
    for (cn = cnames; cn->name != NULL; cn++)
    {
        if (strlen(cn->name) == len &&
            pg_char_and_wchar_strncmp(cn->name, startp, len) == 0)
        {
            break;              /* NOTE BREAK OUT */
        }
    }
    if (cn->name != NULL)
        return CHR(cn->code);

    /* couldn't find it */
    ERR(REG_ECOLLATE);
    return 0;
}

static struct cvec* range ( struct vars v,
celt  a,
celt  b,
int  cases 
) [static, read]

Definition at line 403 of file regc_locale.c.

References addchr(), addrange(), before(), ERR, getcvec(), cvec::nchrs, NOERRN, pg_wc_tolower(), pg_wc_toupper(), and REG_ERANGE.

Referenced by AdjustIntervalForTypmod(), chrnamed(), DecodeInterval(), range_gist_class_split(), range_gist_fallback_split(), range_gist_picksplit(), range_gist_single_sorting_split(), range_out(), range_send(), spg_range_quad_inner_consistent(), and spg_range_quad_picksplit().

{
    int         nchrs;
    struct cvec *cv;
    celt        c,
                lc,
                uc;

    if (a != b && !before(a, b))
    {
        ERR(REG_ERANGE);
        return NULL;
    }

    if (!cases)
    {                           /* easy version */
        cv = getcvec(v, 0, 1);
        NOERRN();
        addrange(cv, a, b);
        return cv;
    }

    /*
     * When case-independent, it's hard to decide when cvec ranges are usable,
     * so for now at least, we won't try.  We allocate enough space for two
     * case variants plus a little extra for the two title case variants.
     */

    nchrs = (b - a + 1) * 2 + 4;

    cv = getcvec(v, nchrs, 0);
    NOERRN();

    for (c = a; c <= b; c++)
    {
        addchr(cv, c);
        lc = pg_wc_tolower((chr) c);
        if (c != lc)
            addchr(cv, lc);
        uc = pg_wc_toupper((chr) c);
        if (c != uc)
            addchr(cv, uc);
    }

    return cv;
}


Variable Documentation

struct cname cnames[] [static]

Referenced by element(), and extractRemainingColumns().