1 /*-------------------------------------------------------------------------
6 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
10 * $PostgreSQL: pgsql/src/backend/tsearch/regis.c,v 1.5 2008/06/17 16:09:06 momjian Exp $
12 *-------------------------------------------------------------------------
17 #include "tsearch/dicts/regis.h"
18 #include "tsearch/ts_locale.h"
21 #define RS_IN_ONEOF_IN 2
22 #define RS_IN_NONEOF 3
27 * Test whether a regex is of the subset supported here.
28 * Keep this in sync with RS_compile!
31 RS_isRegis(const char *str)
33 int state = RS_IN_WAIT;
38 if (state == RS_IN_WAIT)
42 else if (t_iseq(c, '['))
47 else if (state == RS_IN_ONEOF)
51 else if (t_isalpha(c))
52 state = RS_IN_ONEOF_IN;
56 else if (state == RS_IN_ONEOF_IN || state == RS_IN_NONEOF)
60 else if (t_iseq(c, ']'))
66 elog(ERROR, "internal error in RS_isRegis: state %d", state);
70 return (state == RS_IN_WAIT);
74 newRegisNode(RegisNode *prev, int len)
78 ptr = (RegisNode *) palloc0(RNHDRSZ + len + 1);
85 RS_compile(Regis *r, bool issuffix, const char *str)
87 int len = strlen(str);
88 int state = RS_IN_WAIT;
90 RegisNode *ptr = NULL;
92 memset(r, 0, sizeof(Regis));
93 r->issuffix = (issuffix) ? 1 : 0;
97 if (state == RS_IN_WAIT)
102 ptr = newRegisNode(ptr, len);
104 ptr = r->node = newRegisNode(NULL, len);
105 COPYCHAR(ptr->data, c);
106 ptr->type = RSF_ONEOF;
107 ptr->len = pg_mblen(c);
109 else if (t_iseq(c, '['))
112 ptr = newRegisNode(ptr, len);
114 ptr = r->node = newRegisNode(NULL, len);
115 ptr->type = RSF_ONEOF;
118 else /* shouldn't get here */
119 elog(ERROR, "invalid regis pattern: \"%s\"", str);
121 else if (state == RS_IN_ONEOF)
125 ptr->type = RSF_NONEOF;
126 state = RS_IN_NONEOF;
128 else if (t_isalpha(c))
130 COPYCHAR(ptr->data, c);
131 ptr->len = pg_mblen(c);
132 state = RS_IN_ONEOF_IN;
134 else /* shouldn't get here */
135 elog(ERROR, "invalid regis pattern: \"%s\"", str);
137 else if (state == RS_IN_ONEOF_IN || state == RS_IN_NONEOF)
141 COPYCHAR(ptr->data + ptr->len, c);
142 ptr->len += pg_mblen(c);
144 else if (t_iseq(c, ']'))
146 else /* shouldn't get here */
147 elog(ERROR, "invalid regis pattern: \"%s\"", str);
150 elog(ERROR, "internal error in RS_compile: state %d", state);
154 if (state != RS_IN_WAIT) /* shouldn't get here */
155 elog(ERROR, "invalid regis pattern: \"%s\"", str);
168 RegisNode *ptr = r->node,
181 #ifdef USE_WIDE_UPPER_LOWER
183 mb_strchr(char *str, char *c)
185 int clen = pg_mblen(c),
194 plen = pg_mblen(ptr);
200 if (*(ptr + i) != *(c + i))
213 #define mb_strchr(s,c) ( (strchr((s),*(c)) == NULL) ? false : true )
218 RS_execute(Regis *r, char *str)
220 RegisNode *ptr = r->node;
247 if (mb_strchr((char *) ptr->data, c) != true)
251 if (mb_strchr((char *) ptr->data, c) == true)
255 elog(ERROR, "unrecognized regis node type: %d", ptr->type);