Header And Logo

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

Defines | Functions

regis.c File Reference

#include "postgres.h"
#include "tsearch/dicts/regis.h"
#include "tsearch/ts_locale.h"
Include dependency graph for regis.c:

Go to the source code of this file.

Defines

#define RS_IN_ONEOF   1
#define RS_IN_ONEOF_IN   2
#define RS_IN_NONEOF   3
#define RS_IN_WAIT   4
#define mb_strchr(s, c)   ( (strchr((s),*(c)) == NULL) ? false : true )

Functions

bool RS_isRegis (const char *str)
static RegisNodenewRegisNode (RegisNode *prev, int len)
void RS_compile (Regis *r, bool issuffix, const char *str)
void RS_free (Regis *r)
bool RS_execute (Regis *r, char *str)

Define Documentation

#define mb_strchr (   s,
  c 
)    ( (strchr((s),*(c)) == NULL) ? false : true )

Definition at line 213 of file regis.c.

Referenced by RS_execute().

#define RS_IN_NONEOF   3

Definition at line 22 of file regis.c.

Referenced by RS_compile(), and RS_isRegis().

#define RS_IN_ONEOF   1

Definition at line 20 of file regis.c.

Referenced by RS_compile(), and RS_isRegis().

#define RS_IN_ONEOF_IN   2

Definition at line 21 of file regis.c.

Referenced by RS_compile(), and RS_isRegis().

#define RS_IN_WAIT   4

Definition at line 23 of file regis.c.

Referenced by RS_compile(), and RS_isRegis().


Function Documentation

static RegisNode* newRegisNode ( RegisNode prev,
int  len 
) [static]

Definition at line 74 of file regis.c.

References RegisNode::next, palloc0(), and RNHDRSZ.

Referenced by RS_compile().

{
    RegisNode  *ptr;

    ptr = (RegisNode *) palloc0(RNHDRSZ + len + 1);
    if (prev)
        prev->next = ptr;
    return ptr;
}

void RS_compile ( Regis r,
bool  issuffix,
const char *  str 
)

Definition at line 85 of file regis.c.

References COPYCHAR, RegisNode::data, elog, ERROR, Regis::issuffix, RegisNode::len, Regis::nchar, newRegisNode(), RegisNode::next, Regis::node, NULL, pg_mblen(), RS_IN_NONEOF, RS_IN_ONEOF, RS_IN_ONEOF_IN, RS_IN_WAIT, t_isalpha, t_iseq, and RegisNode::type.

Referenced by NIAddAffix().

{
    int         len = strlen(str);
    int         state = RS_IN_WAIT;
    const char *c = str;
    RegisNode  *ptr = NULL;

    memset(r, 0, sizeof(Regis));
    r->issuffix = (issuffix) ? 1 : 0;

    while (*c)
    {
        if (state == RS_IN_WAIT)
        {
            if (t_isalpha(c))
            {
                if (ptr)
                    ptr = newRegisNode(ptr, len);
                else
                    ptr = r->node = newRegisNode(NULL, len);
                COPYCHAR(ptr->data, c);
                ptr->type = RSF_ONEOF;
                ptr->len = pg_mblen(c);
            }
            else if (t_iseq(c, '['))
            {
                if (ptr)
                    ptr = newRegisNode(ptr, len);
                else
                    ptr = r->node = newRegisNode(NULL, len);
                ptr->type = RSF_ONEOF;
                state = RS_IN_ONEOF;
            }
            else    /* shouldn't get here */
                elog(ERROR, "invalid regis pattern: \"%s\"", str);
        }
        else if (state == RS_IN_ONEOF)
        {
            if (t_iseq(c, '^'))
            {
                ptr->type = RSF_NONEOF;
                state = RS_IN_NONEOF;
            }
            else if (t_isalpha(c))
            {
                COPYCHAR(ptr->data, c);
                ptr->len = pg_mblen(c);
                state = RS_IN_ONEOF_IN;
            }
            else    /* shouldn't get here */
                elog(ERROR, "invalid regis pattern: \"%s\"", str);
        }
        else if (state == RS_IN_ONEOF_IN || state == RS_IN_NONEOF)
        {
            if (t_isalpha(c))
            {
                COPYCHAR(ptr->data + ptr->len, c);
                ptr->len += pg_mblen(c);
            }
            else if (t_iseq(c, ']'))
                state = RS_IN_WAIT;
            else    /* shouldn't get here */
                elog(ERROR, "invalid regis pattern: \"%s\"", str);
        }
        else
            elog(ERROR, "internal error in RS_compile: state %d", state);
        c += pg_mblen(c);
    }

    if (state != RS_IN_WAIT)    /* shouldn't get here */
        elog(ERROR, "invalid regis pattern: \"%s\"", str);

    ptr = r->node;
    while (ptr)
    {
        r->nchar++;
        ptr = ptr->next;
    }
}

bool RS_execute ( Regis r,
char *  str 
)

Definition at line 218 of file regis.c.

References RegisNode::data, elog, ERROR, Regis::issuffix, mb_strchr, Regis::nchar, RegisNode::next, Regis::node, pg_mblen(), RSF_NONEOF, RSF_ONEOF, and RegisNode::type.

Referenced by CheckAffix().

{
    RegisNode  *ptr = r->node;
    char       *c = str;
    int         len = 0;

    while (*c)
    {
        len++;
        c += pg_mblen(c);
    }

    if (len < r->nchar)
        return 0;

    c = str;
    if (r->issuffix)
    {
        len -= r->nchar;
        while (len-- > 0)
            c += pg_mblen(c);
    }


    while (ptr)
    {
        switch (ptr->type)
        {
            case RSF_ONEOF:
                if (!mb_strchr((char *) ptr->data, c))
                    return false;
                break;
            case RSF_NONEOF:
                if (mb_strchr((char *) ptr->data, c))
                    return false;
                break;
            default:
                elog(ERROR, "unrecognized regis node type: %d", ptr->type);
        }
        ptr = ptr->next;
        c += pg_mblen(c);
    }

    return true;
}

void RS_free ( Regis r  ) 

Definition at line 166 of file regis.c.

References RegisNode::next, Regis::node, and pfree().

{
    RegisNode  *ptr = r->node,
               *tmp;

    while (ptr)
    {
        tmp = ptr->next;
        pfree(ptr);
        ptr = tmp;
    }

    r->node = NULL;
}

bool RS_isRegis ( const char *  str  ) 

Definition at line 31 of file regis.c.

References elog, ERROR, pg_mblen(), RS_IN_NONEOF, RS_IN_ONEOF, RS_IN_ONEOF_IN, RS_IN_WAIT, t_isalpha, and t_iseq.

Referenced by NIAddAffix().

{
    int         state = RS_IN_WAIT;
    const char *c = str;

    while (*c)
    {
        if (state == RS_IN_WAIT)
        {
            if (t_isalpha(c))
                 /* okay */ ;
            else if (t_iseq(c, '['))
                state = RS_IN_ONEOF;
            else
                return false;
        }
        else if (state == RS_IN_ONEOF)
        {
            if (t_iseq(c, '^'))
                state = RS_IN_NONEOF;
            else if (t_isalpha(c))
                state = RS_IN_ONEOF_IN;
            else
                return false;
        }
        else if (state == RS_IN_ONEOF_IN || state == RS_IN_NONEOF)
        {
            if (t_isalpha(c))
                 /* okay */ ;
            else if (t_iseq(c, ']'))
                state = RS_IN_WAIT;
            else
                return false;
        }
        else
            elog(ERROR, "internal error in RS_isRegis: state %d", state);
        c += pg_mblen(c);
    }

    return (state == RS_IN_WAIT);
}