Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #include "libts.h"
00025 #include "Regex.h"
00026 
00027 DFA::~DFA()
00028 {
00029   dfa_pattern * p = _my_patterns;
00030   dfa_pattern * t;
00031 
00032   while(p) {
00033     if (p->_pe)
00034       pcre_free(p->_pe);
00035     if (p->_re)
00036       pcre_free(p->_re);
00037     if(p->_p)
00038       ats_free(p->_p);
00039     t = p->_next;
00040     ats_free(p);
00041     p = t;
00042   }
00043 }
00044 
00045 dfa_pattern *
00046 DFA::build(const char *pattern, unsigned flags)
00047 {
00048   const char *error;
00049   int erroffset;
00050   dfa_pattern* ret;
00051   int options = PCRE_ANCHORED;
00052 
00053   ret = (dfa_pattern*)ats_malloc(sizeof(dfa_pattern));
00054   ret->_p = NULL;
00055 
00056   if (flags & RE_CASE_INSENSITIVE) {
00057     options |= PCRE_CASELESS;
00058   }
00059 
00060   if (flags & RE_UNANCHORED) {
00061     options &= ~PCRE_ANCHORED;
00062   }
00063 
00064   ret->_re = pcre_compile(pattern, options, &error, &erroffset, NULL);
00065   if (error) {
00066     ats_free(ret);
00067     return NULL;
00068   }
00069 
00070   ret->_pe = pcre_study(ret->_re, 0, &error);
00071 
00072   if (error) {
00073     ats_free(ret);
00074     return NULL;
00075   }
00076 
00077   ret->_idx = 0;
00078   ret->_p = ats_strndup(pattern, strlen(pattern));
00079   ret->_next = NULL;
00080   return ret;
00081 }
00082 
00083 int DFA::compile(const char *pattern, unsigned flags) {
00084   ink_assert(_my_patterns == NULL);
00085   _my_patterns = build(pattern,flags);
00086   if (_my_patterns)
00087     return 0;
00088   else
00089     return -1;
00090 }
00091 
00092 int
00093 DFA::compile(const char **patterns, int npatterns, unsigned flags)
00094 {
00095   const char *pattern;
00096   dfa_pattern *ret = NULL;
00097   dfa_pattern *end = NULL;
00098   int i;
00099   
00100 
00101   for (i = 0; i < npatterns; i++) {
00102     pattern = patterns[i];
00103     
00104     ret = build(pattern,flags);
00105     if (!ret) {
00106       continue;
00107     }
00108 
00109     if (!_my_patterns) {
00110       _my_patterns = ret;
00111       _my_patterns->_next = NULL;
00112       _my_patterns->_idx = i;
00113     }
00114     else {
00115       end = _my_patterns;
00116       while( end->_next ) {
00117         end = end->_next;
00118       }
00119       end->_next = ret; 
00120       ret->_idx = i;
00121     }
00122 
00123   }
00124 
00125   return 0;
00126 }
00127 
00128 int
00129 DFA::match(const char *str) const
00130 {
00131   return match(str,strlen(str));
00132 }
00133 
00134 int
00135 DFA::match(const char *str, int length) const
00136 {
00137   int rc;
00138   int ovector[30];
00139   
00140   dfa_pattern * p = _my_patterns;
00141 
00142   while(p) {
00143     rc = pcre_exec(p->_re, p->_pe, str, length , 0, 0, ovector, 30);
00144     if (rc > 0) {
00145       return p->_idx;
00146     }
00147     p = p->_next;
00148   }
00149 
00150   return -1;
00151 }