/* * Copyright (c) 2004 Teodor Sigaev * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "tlog.h" #include "tmalloc.h" #include "regis.h" int RS_isRegis(const char *str) { unsigned char *ptr=(unsigned char *)str; while(ptr && *ptr) if ( isalpha(*ptr) || *ptr=='[' || *ptr==']' || *ptr=='^') ptr++; else return 0; return 1; } #define RS_IN_ONEOF 1 #define RS_IN_ONEOF_IN 2 #define RS_IN_NONEOF 3 #define RS_IN_WAIT 4 static RegisNode* newRegisNode(RegisNode *prev, int len) { RegisNode *ptr; ptr = (RegisNode*)t0malloc(RNHDRSZ+len+1); if (prev) prev->next=ptr; return ptr; } int RS_compile(Regis *r, int issuffix, const char *str) { int i,len = strlen(str); int state = RS_IN_WAIT; RegisNode *ptr=NULL; memset(r,0,sizeof(Regis)); r->issuffix = (issuffix) ? 1 : 0; for(i=0;inode = newRegisNode(NULL,len); ptr->data[ 0 ] = c; ptr->type = RSF_ONEOF; ptr->len=1; } else if ( c=='[' ) { if ( ptr ) ptr = newRegisNode(ptr,len); else ptr = r->node = newRegisNode(NULL,len); ptr->type = RSF_ONEOF; state=RS_IN_ONEOF; } else tlog(TL_ALARM|TL_EXIT,"Error in regis: %s at pos %d\n", str, i+1); } else if ( state == RS_IN_ONEOF ) { if ( c=='^' ) { ptr->type = RSF_NONEOF; state=RS_IN_NONEOF; } else if ( isalpha(c) ) { ptr->data[ 0 ] = c; ptr->len=1; state=RS_IN_ONEOF_IN; } else tlog(TL_ALARM|TL_EXIT,"Error in regis: %s at pos %d\n", str, i+1); } else if ( state == RS_IN_ONEOF_IN || state == RS_IN_NONEOF ) { if ( isalpha(c) ) { ptr->data[ ptr->len ] = c; ptr->len++; } else if ( c==']' ) { state=RS_IN_WAIT; } else tlog(TL_ALARM|TL_EXIT,"Error in regis: %s at pos %d\n", str, i+1); } else tlog(TL_CRIT|TL_EXIT,"Internal error in RS_compile: %d\n", state); } ptr = r->node; while(ptr) { r->nchar++; ptr=ptr->next; } return 0; } void RS_free(Regis *r) { RegisNode *ptr=r->node,*tmp; while(ptr) { tmp=ptr->next; tfree(ptr); ptr = tmp; } r->node = NULL; } int RS_execute(Regis *r, const char *str, int len) { RegisNode *ptr=r->node; unsigned char *c; if (len<0) len=strlen(str); if (lennchar) return 0; if ( r->issuffix ) c = ((unsigned char*)str) + len - r->nchar; else c = (unsigned char*)str; while(ptr) { switch(ptr->type) { case RSF_ONEOF: if ( ptr->len==0 ) { if ( *c != *(ptr->data) ) return 0; } else if ( strchr((char*)ptr->data, *c) == NULL ) return 0; break; case RSF_NONEOF: if ( ptr->len==0 ) { if ( *c == *(ptr->data) ) return 0; } else if ( strchr((char*)ptr->data, *c) != NULL ) return 0; break; default: tlog(TL_CRIT|TL_EXIT,"RS_execute: Unknown type node: %d\n", ptr->type); } ptr=ptr->next; c++; } return 1; }