1 /*-------------------------------------------------------------------------
6 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
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
);