2 * Copyright (c) 2004 Teodor Sigaev <teodor@sigaev.ru>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the author nor the names of any co-contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 RS_isRegis(const char *str) {
40 unsigned char *ptr=(unsigned char *)str;
43 if ( isalpha(*ptr) || *ptr=='[' || *ptr==']' || *ptr=='^')
51 #define RS_IN_ONEOF_IN 2
52 #define RS_IN_NONEOF 3
56 newRegisNode(RegisNode *prev, int len) {
58 ptr = (RegisNode*)t0malloc(RNHDRSZ+len+1);
65 RS_compile(Regis *r, int issuffix, const char *str) {
66 int i,len = strlen(str);
67 int state = RS_IN_WAIT;
70 memset(r,0,sizeof(Regis));
71 r->issuffix = (issuffix) ? 1 : 0;
74 unsigned char c = *( ( (unsigned char*)str ) + i );
75 if ( state == RS_IN_WAIT ) {
78 ptr = newRegisNode(ptr,len);
80 ptr = r->node = newRegisNode(NULL,len);
82 ptr->type = RSF_ONEOF;
84 } else if ( c=='[' ) {
86 ptr = newRegisNode(ptr,len);
88 ptr = r->node = newRegisNode(NULL,len);
89 ptr->type = RSF_ONEOF;
92 tlog(TL_ALARM|TL_EXIT,"Error in regis: %s at pos %d\n", str, i+1);
93 } else if ( state == RS_IN_ONEOF ) {
95 ptr->type = RSF_NONEOF;
97 } else if ( isalpha(c) ) {
100 state=RS_IN_ONEOF_IN;
102 tlog(TL_ALARM|TL_EXIT,"Error in regis: %s at pos %d\n", str, i+1);
103 } else if ( state == RS_IN_ONEOF_IN || state == RS_IN_NONEOF ) {
105 ptr->data[ ptr->len ] = c;
107 } else if ( c==']' ) {
110 tlog(TL_ALARM|TL_EXIT,"Error in regis: %s at pos %d\n", str, i+1);
112 tlog(TL_CRIT|TL_EXIT,"Internal error in RS_compile: %d\n", state);
126 RegisNode *ptr=r->node,*tmp;
138 RS_execute(Regis *r, const char *str, int len) {
139 RegisNode *ptr=r->node;
149 c = ((unsigned char*)str) + len - r->nchar;
151 c = (unsigned char*)str;
157 if ( *c != *(ptr->data) )
159 } else if ( strchr((char*)ptr->data, *c) == NULL )
164 if ( *c == *(ptr->data) )
166 } else if ( strchr((char*)ptr->data, *c) != NULL )
170 tlog(TL_CRIT|TL_EXIT,"RS_execute: Unknown type node: %d\n", ptr->type);