Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

mstring.c

Go to the documentation of this file.
00001 /* $Id$ */
00002 /*
00003 ** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
00004 
00005 ** This program is free software; you can redistribute it and/or modify
00006 ** it under the terms of the GNU General Public License as published by
00007 ** the Free Software Foundation; either version 2 of the License, or
00008 ** (at your option) any later version.
00009 **
00010 ** This program is distributed in the hope that it will be useful,
00011 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 ** GNU General Public License for more details.
00014 **
00015 ** You should have received a copy of the GNU General Public License
00016 ** along with this program; if not, write to the Free Software
00017 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00018 */
00019 
00020 /***************************************************************************
00021  *
00022  * File: MSTRING.C
00023  *
00024  * Purpose: Provide a variety of string functions not included in libc.  Makes
00025  *          up for the fact that the libstdc++ is hard to get reference
00026  *          material on and I don't want to write any more non-portable c++
00027  *          code until I have solid references and libraries to use.
00028  *
00029  * History:
00030  *
00031  * Date:      Author:  Notes:
00032  * ---------- ------- ----------------------------------------------
00033  *  08/19/98    MFR    Initial coding begun
00034  *  03/06/99    MFR    Added Boyer-Moore pattern match routine, don't use
00035  *                     mContainsSubstr() any more if you don't have to
00036  *  12/31/99    JGW    Added a full Boyer-Moore implementation to increase
00037  *                     performance. Added a case insensitive version of mSearch
00038  *  07/24/01    MFR    Fixed Regex pattern matcher introduced by Fyodor
00039  *
00040  **************************************************************************/
00041 #ifdef HAVE_CONFIG_H
00042 #include "config.h"
00043 #endif
00044 
00045 #include <sys/types.h>
00046 
00047 #include "mstring.h"
00048 #include "debug.h"
00049 #include "plugbase.h" /* needed for fasthex() */
00050 
00051 #ifdef GIDS
00052 extern int detect_depth;
00053 #endif /* GIDS */
00054 
00055 #ifdef TEST_MSTRING
00056 #define FatalPrintError perror
00057 #else
00058 void FatalPrintError(char *);
00059 #endif
00060 
00061 extern u_int8_t *doe_ptr;
00062 
00063 #ifdef TEST_MSTRING
00064 
00065 int main()
00066 {
00067     char test[] = "\0\0\0\0\0\0\0\0\0CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\0\0";
00068     char find[] = "CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\0\0";
00069 
00070 /*   char test[] = "\x90\x90\x90\x90\x90\x90\xe8\xc0\xff\xff\xff/bin/sh\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90";
00071      char find[] = "\xe8\xc0\xff\xff\xff/bin/sh";  */
00072     int i;
00073     int toks;
00074     int *shift;
00075     int *skip;
00076 
00077 /*   shift=make_shift(find,sizeof(find)-1);
00078      skip=make_skip(find,sizeof(find)-1); */
00079 
00080     DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,"%d\n",
00081                             mSearch(test, sizeof(test) - 1, find,
00082                                     sizeof(find) - 1, shift, skip)););
00083 
00084     return 0;
00085 }
00086 
00087 #endif
00088 
00089 /****************************************************************
00090  *
00091  *  Function: mSplit()
00092  *
00093  *  Purpose: Splits a string into tokens non-destructively.
00094  *
00095  *  Parameters:
00096  *      char *str => the string to be split
00097  *      char *sep => a string of token seperaters
00098  *      int max_strs => how many tokens should be returned
00099  *      int *toks => place to store the number of tokens found in str
00100  *      char meta => the "escape metacharacter", treat the character
00101  *                   after this character as a literal and "escape" a
00102  *                   seperator
00103  *
00104  *  Returns:
00105  *      2D char array with one token per "row" of the returned
00106  *      array.
00107  *
00108  ****************************************************************/
00109 char **mSplit(char *str, char *sep, int max_strs, int *toks, char meta)
00110 {
00111     char **retstr;      /* 2D array which is returned to caller */
00112     char *idx;          /* index pointer into str */
00113     char *end;          /* ptr to end of str */
00114     char *sep_end;      /* ptr to end of seperator string */
00115     char *sep_idx;      /* index ptr into seperator string */
00116     int len = 0;        /* length of current token string */
00117     int curr_str = 0;       /* current index into the 2D return array */
00118     char last_char = (char) 0xFF;
00119 
00120     if(!toks) return NULL;
00121 
00122     *toks = 0;
00123 
00124     if (!str) return NULL;
00125 
00126     DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, 
00127                 "[*] Splitting string: %s\n", str);
00128             DebugMessage(DEBUG_PATTERN_MATCH, "curr_str = %d\n", curr_str););
00129 
00130     /*
00131      * find the ends of the respective passed strings so our while() loops
00132      * know where to stop
00133      */
00134     sep_end = sep + strlen(sep);
00135     end = str + strlen(str);
00136 
00137     /* remove trailing whitespace */
00138     while(isspace((int) *(end - 1)) && ((end - 1) >= str))
00139         *(--end) = '\0';    /* -1 because of NULL */
00140 
00141     /* set our indexing pointers */
00142     sep_idx = sep;
00143     idx = str;
00144 
00145     /*
00146      * alloc space for the return string, this is where the pointers to the
00147      * tokens will be stored
00148      */
00149     if((retstr = (char **) malloc((sizeof(char **) * max_strs))) == NULL)
00150         FatalPrintError("malloc");
00151 
00152 
00153     max_strs--;
00154 
00155     DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, 
00156                 "max_strs = %d  curr_str = %d\n", 
00157                 max_strs, curr_str););
00158 
00159     /* loop thru each letter in the string being tokenized */
00160     while(idx < end)
00161     {
00162         /* loop thru each seperator string char */
00163         while(sep_idx < sep_end)
00164         {
00165             /*
00166              * if the current string-indexed char matches the current
00167              * seperator char...
00168              */
00169             if((*idx == *sep_idx) && (last_char != meta))
00170             {
00171                 /* if there's something to store... */
00172                 if(len > 0)
00173                 {
00174                     DEBUG_WRAP(
00175                             DebugMessage(DEBUG_PATTERN_MATCH, 
00176                                 "Allocating %d bytes for token ", len + 1););
00177                     if(curr_str <= max_strs)
00178                     {
00179                         /* allocate space for the new token */
00180                         if((retstr[curr_str] = (char *)
00181                                     malloc((sizeof(char) * len) + 1)) == NULL)
00182                         {
00183                             FatalPrintError("malloc");
00184                         }
00185 
00186                         /* copy the token into the return string array */
00187                         memcpy(retstr[curr_str], (idx - len), len);
00188                         retstr[curr_str][len] = 0;
00189                         DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, 
00190                                     "tok[%d]: %s\n", curr_str, 
00191                                     retstr[curr_str]););
00192 
00193                         /* twiddle the necessary pointers and vars */
00194                         len = 0;
00195                         curr_str++;
00196                         DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, 
00197                                     "curr_str = %d\n", curr_str);
00198                                 DebugMessage(DEBUG_PATTERN_MATCH, 
00199                                     "max_strs = %d  curr_str = %d\n", 
00200                                     max_strs, curr_str););
00201 
00202                         last_char = *idx;
00203                         idx++;
00204                     }
00205 
00206                     DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, 
00207                                 "Checking if curr_str (%d) >= max_strs (%d)\n",
00208                                curr_str, max_strs););
00209 
00210                     /*
00211                      * if we've gotten all the tokens requested, return the
00212                      * list
00213                      */
00214                     if(curr_str >= max_strs)
00215                     {
00216                         while(isspace((int) *idx))
00217                             idx++;
00218 
00219                         len = end - idx;
00220                         DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, 
00221                                     "Finishing up...\n");
00222                                 DebugMessage(DEBUG_PATTERN_MATCH, 
00223                                     "Allocating %d bytes "
00224                                     "for last token ", len + 1););
00225                         fflush(stdout);
00226 
00227                         if((retstr[curr_str] = (char *)
00228                                     malloc((sizeof(char) * len) + 1)) == NULL)
00229                             FatalPrintError("malloc");
00230 
00231                         memcpy(retstr[curr_str], idx, len);
00232                         retstr[curr_str][len] = 0;
00233 
00234                         DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, 
00235                                     "tok[%d]: %s\n", curr_str, 
00236                                     retstr[curr_str]););
00237 
00238                         *toks = curr_str + 1;
00239                         DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, 
00240                                     "max_strs = %d  curr_str = %d\n", 
00241                                     max_strs, curr_str);
00242                                 DebugMessage(DEBUG_PATTERN_MATCH, 
00243                                     "mSplit got %d tokens!\n", *toks););
00244 
00245                         return retstr;
00246                     }
00247                 }
00248                 else
00249                     /*
00250                      * otherwise, the previous char was a seperator as well,
00251                      * and we should just continue
00252                      */
00253                 {
00254                     last_char = *idx;
00255                     idx++;
00256                     /* make sure to reset this so we test all the sep. chars */
00257                     sep_idx = sep;
00258                     len = 0;
00259                 }
00260             }
00261             else
00262             {
00263                 /* go to the next seperator */
00264                 sep_idx++;
00265             }
00266         }
00267 
00268         sep_idx = sep;
00269         len++;
00270         last_char = *idx;
00271         idx++;
00272     }
00273 
00274     /* put the last string into the list */
00275 
00276     if(len > 0)
00277     {
00278         DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, 
00279                     "Allocating %d bytes for last token ", len + 1););
00280 
00281         if((retstr[curr_str] = (char *)
00282                     malloc((sizeof(char) * len) + 1)) == NULL)
00283             FatalPrintError("malloc");
00284 
00285         memcpy(retstr[curr_str], (idx - len), len);
00286         retstr[curr_str][len] = 0;
00287 
00288         DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,"tok[%d]: %s\n", curr_str, 
00289                     retstr[curr_str]););
00290         *toks = curr_str + 1;
00291     }
00292 
00293     DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, 
00294                 "mSplit got %d tokens!\n", *toks););
00295 
00296     /* return the token list */
00297     return retstr;
00298 }
00299 
00300 
00301 
00302 
00303 /****************************************************************
00304  *
00305  * Free the buffer allocated by mSplit().
00306  *
00307  * char** toks = NULL;
00308  * int num_toks = 0;
00309  * toks = (str, " ", 2, &num_toks, 0);
00310  * mSplitFree(&toks, num_toks);
00311  *
00312  * At this point, toks is again NULL.
00313  *
00314  ****************************************************************/
00315 void mSplitFree(char ***pbuf, int num_toks)
00316 {
00317     int i;
00318     char** buf;  /* array of string pointers */
00319 
00320     if( pbuf==NULL || *pbuf==NULL )
00321     {
00322         return;
00323     }
00324 
00325     buf = *pbuf;
00326 
00327     for( i=0; i<num_toks; i++ )
00328     {
00329         if( buf[i] != NULL )
00330         {
00331             free( buf[i] );
00332             buf[i] = NULL;
00333         }
00334     }
00335 
00336     free(buf);
00337     *pbuf = NULL;
00338 }
00339 
00340 
00341 
00342 
00343 /****************************************************************
00344  *
00345  *  Function: mContainsSubstr(char *, int, char *, int)
00346  *
00347  *  Purpose: Determines if a string contains a (non-regex)
00348  *           substring.
00349  *
00350  *  Parameters:
00351  *      buf => data buffer we want to find the data in
00352  *      b_len => data buffer length
00353  *      pat => pattern to find
00354  *      p_len => length of the data in the pattern buffer
00355  *
00356  *  Returns:
00357  *      Integer value, 1 on success (str constains substr), 0 on
00358  *      failure (substr not in str)
00359  *
00360  ****************************************************************/
00361 int mContainsSubstr(char *buf, int b_len, char *pat, int p_len)
00362 {
00363     char *b_idx;        /* index ptr into the data buffer */
00364     char *p_idx;        /* index ptr into the pattern buffer */
00365     char *b_end;        /* ptr to the end of the data buffer */
00366     int m_cnt = 0;      /* number of pattern matches so far... */
00367 #ifdef DEBUG
00368     unsigned long loopcnt = 0;
00369 #endif
00370 
00371     /* mark the end of the strs */
00372     b_end = (char *) (buf + b_len);
00373 
00374     /* init the index ptrs */
00375     b_idx = buf;
00376     p_idx = pat;
00377 
00378     do
00379     {
00380 #ifdef DEBUG
00381         loopcnt++;
00382 #endif
00383 
00384         if(*p_idx == *b_idx)
00385         {
00386 
00387             if(m_cnt == (p_len - 1))
00388             {
00389                 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00390                                         "\n%ld compares for match\n", loopcnt););
00391                 return 1;
00392             }
00393             m_cnt++;
00394             b_idx++;
00395             p_idx++;
00396         }
00397         else
00398         {
00399             if(m_cnt == 0)
00400             {
00401                 b_idx++;
00402             }
00403             else
00404             {
00405                 b_idx = b_idx - (m_cnt - 1);
00406             }
00407 
00408             p_idx = pat;
00409 
00410             m_cnt = 0;
00411         }
00412 
00413     } while(b_idx < b_end);
00414 
00415 
00416     /* if we make it here we didn't find what we were looking for */
00417     return 0;
00418 }
00419 
00420 
00421 
00422 
00423 /****************************************************************
00424  *
00425  *  Function: make_skip(char *, int)
00426  *
00427  *  Purpose: Create a Boyer-Moore skip table for a given pattern
00428  *
00429  *  Parameters:
00430  *      ptrn => pattern
00431  *      plen => length of the data in the pattern buffer
00432  *
00433  *  Returns:
00434  *      int * - the skip table
00435  *
00436  ****************************************************************/
00437 int *make_skip(char *ptrn, int plen)
00438 {
00439     int *skip = (int *) malloc(256 * sizeof(int));
00440     int *sptr = &skip[256];
00441 
00442     if (skip == NULL)
00443         FatalPrintError("malloc");
00444 
00445     while(sptr-- != skip)
00446         *sptr = plen + 1;
00447 
00448     while(plen != 0)
00449         skip[(unsigned char) *ptrn++] = plen--;
00450 
00451     return skip;
00452 }
00453 
00454 
00455 
00456 /****************************************************************
00457  *
00458  *  Function: make_shift(char *, int)
00459  *
00460  *  Purpose: Create a Boyer-Moore shift table for a given pattern
00461  *
00462  *  Parameters:
00463  *      ptrn => pattern
00464  *      plen => length of the data in the pattern buffer
00465  *
00466  *  Returns:
00467  *      int * - the shift table
00468  *
00469  ****************************************************************/
00470 int *make_shift(char *ptrn, int plen)
00471 {
00472     int *shift = (int *) malloc(plen * sizeof(int));
00473     int *sptr = shift + plen - 1;
00474     char *pptr = ptrn + plen - 1;
00475     char c;
00476 
00477     if (shift == NULL)
00478         FatalPrintError("malloc");
00479 
00480      c = ptrn[plen - 1];
00481 
00482     *sptr = 1;
00483 
00484     while(sptr-- != shift)
00485     {
00486         char *p1 = ptrn + plen - 2, *p2, *p3;
00487 
00488         do
00489         {
00490             while(p1 >= ptrn && *p1-- != c);
00491 
00492             p2 = ptrn + plen - 2;
00493             p3 = p1;
00494 
00495             while(p3 >= ptrn && *p3-- == *p2-- && p2 >= pptr);
00496         }
00497         while(p3 >= ptrn && p2 >= pptr);
00498 
00499         *sptr = shift + plen - sptr + p2 - p3;
00500 
00501         pptr--;
00502     }
00503 
00504     return shift;
00505 }
00506 
00507 
00508 
00509 /****************************************************************
00510  *
00511  *  Function: mSearch(char *, int, char *, int)
00512  *
00513  *  Purpose: Determines if a string contains a (non-regex)
00514  *           substring.
00515  *
00516  *  Parameters:
00517  *      buf => data buffer we want to find the data in
00518  *      blen => data buffer length
00519  *      ptrn => pattern to find
00520  *      plen => length of the data in the pattern buffer
00521  *      skip => the B-M skip array
00522  *      shift => the B-M shift array
00523  *
00524  *  Returns:
00525  *      Integer value, 1 on success (str constains substr), 0 on
00526  *      failure (substr not in str)
00527  *
00528  ****************************************************************/
00529 int mSearch(char *buf, int blen, char *ptrn, int plen, int *skip, int *shift)
00530 {
00531     int b_idx = plen;
00532 
00533 #ifdef DEBUG
00534     char *hexbuf;
00535     int cmpcnt = 0;
00536 #endif
00537 
00538     DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,"buf: %p  blen: %d  ptrn: %p  "
00539                 "plen: %d\n", buf, blen, ptrn, plen););
00540 
00541 #ifdef DEBUG
00542     hexbuf = fasthex(buf, blen);
00543     DebugMessage(DEBUG_PATTERN_MATCH,"buf: %s\n", hexbuf);
00544     free(hexbuf);
00545     hexbuf = fasthex(ptrn, plen);
00546     DebugMessage(DEBUG_PATTERN_MATCH,"ptrn: %s\n", hexbuf);
00547     free(hexbuf);
00548     DebugMessage(DEBUG_PATTERN_MATCH,"buf: %p  blen: %d  ptrn: %p  "
00549                  "plen: %d\n", buf, blen, ptrn, plen);
00550 #endif /* DEBUG */
00551     if(plen == 0)
00552         return 1;
00553 
00554     while(b_idx <= blen)
00555     {
00556         int p_idx = plen, skip_stride, shift_stride;
00557 
00558         while(buf[--b_idx] == ptrn[--p_idx])
00559         {
00560 #ifdef DEBUG
00561             cmpcnt++;
00562 #endif
00563             if(b_idx < 0)
00564                 return 0;
00565 
00566             if(p_idx == 0)
00567             {
00568                 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, 
00569                             "match: compares = %d.\n", cmpcnt););
00570 
00571                 doe_ptr = &(buf[b_idx]) + plen;
00572 
00573 #ifdef GIDS
00574                 detect_depth = b_idx;
00575 #endif /* GIDS */
00576 
00577                 return 1;
00578             }
00579         }
00580 
00581         skip_stride = skip[(unsigned char) buf[b_idx]];
00582         shift_stride = shift[p_idx];
00583 
00584         b_idx += (skip_stride > shift_stride) ? skip_stride : shift_stride;
00585     }
00586 
00587     DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00588                 "no match: compares = %d.\n", cmpcnt););
00589 
00590     return 0;
00591 }
00592 
00593 
00594 
00595 /****************************************************************
00596  *
00597  *  Function: mSearchCI(char *, int, char *, int)
00598  *
00599  *  Purpose: Determines if a string contains a (non-regex)
00600  *           substring matching is case insensitive
00601  *
00602  *  Parameters:
00603  *      buf => data buffer we want to find the data in
00604  *      blen => data buffer length
00605  *      ptrn => pattern to find
00606  *      plen => length of the data in the pattern buffer
00607  *      skip => the B-M skip array
00608  *      shift => the B-M shift array
00609  *
00610  *  Returns:
00611  *      Integer value, 1 on success (str constains substr), 0 on
00612  *      failure (substr not in str)
00613  *
00614  ****************************************************************/
00615 int mSearchCI(char *buf, int blen, char *ptrn, int plen, int *skip, int *shift)
00616 {
00617     int b_idx = plen;
00618 #ifdef DEBUG
00619     int cmpcnt = 0;
00620 #endif
00621 
00622     if(plen == 0)
00623         return 1;
00624 
00625     while(b_idx <= blen)
00626     {
00627         int p_idx = plen, skip_stride, shift_stride;
00628 
00629         while((unsigned char) ptrn[--p_idx] == 
00630                 toupper((unsigned char) buf[--b_idx]))
00631         {
00632 #ifdef DEBUG
00633             cmpcnt++;
00634 #endif
00635             if(p_idx == 0)
00636             {
00637                 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, 
00638                             "match: compares = %d.\n", 
00639                             cmpcnt););
00640                 doe_ptr = &(buf[b_idx]) + plen;
00641 #ifdef GIDS
00642                 detect_depth = b_idx;
00643 #endif /* GIDS */
00644                 return 1;
00645             }
00646         }
00647 
00648         skip_stride = skip[toupper((unsigned char) buf[b_idx])];
00649         shift_stride = shift[p_idx];
00650 
00651         b_idx += (skip_stride > shift_stride) ? skip_stride : shift_stride;
00652     }
00653 
00654     DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "no match: compares = %d.\n", cmpcnt););
00655 
00656     return 0;
00657 }
00658 
00659 
00660 /****************************************************************
00661  *
00662  *  Function: mSearchREG(char *, int, char *, int)
00663  *
00664  *  Purpose: Determines if a string contains a (regex)
00665  *           substring.
00666  *
00667  *  Parameters:
00668  *      buf => data buffer we want to find the data in
00669  *      blen => data buffer length
00670  *      ptrn => pattern to find
00671  *      plen => length of the data in the pattern buffer
00672  *      skip => the B-M skip array
00673  *      shift => the B-M shift array
00674  *
00675  *  Returns:
00676  *      Integer value, 1 on success (str constains substr), 0 on
00677  *      failure (substr not in str)
00678  *
00679  ****************************************************************/
00680 int mSearchREG(char *buf, int blen, char *ptrn, int plen, int *skip, int *shift)
00681 {
00682     int b_idx = plen;
00683     int literal = 0;
00684     int regexcomp = 0;
00685 #ifdef DEBUG
00686     int cmpcnt = 0;
00687 #endif /*DEBUG*/
00688     
00689     DEBUG_WRAP(
00690                DebugMessage(DEBUG_PATTERN_MATCH, "buf: %p  blen: %d  ptrn: %p "
00691                             " plen: %d b_idx: %d\n", buf, blen, ptrn, plen, b_idx);
00692                DebugMessage(DEBUG_PATTERN_MATCH, "packet data: \"%s\"\n", buf);
00693                DebugMessage(DEBUG_PATTERN_MATCH, "matching for \"%s\"\n", ptrn);
00694                );
00695                
00696     if(plen == 0)
00697         return 1;
00698 
00699     while(b_idx <= blen)
00700     {
00701         int p_idx = plen, skip_stride, shift_stride;
00702 
00703         DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Looping... "
00704                                 "([%d]0x%X (%c) -> [%d]0x%X(%c))\n",
00705                                 b_idx, buf[b_idx-1], 
00706                                 buf[b_idx-1], 
00707                                 p_idx, ptrn[p_idx-1], ptrn[p_idx-1]););
00708 
00709         while(buf[--b_idx] == ptrn[--p_idx]
00710               || (ptrn[p_idx] == '?' && !literal)
00711               || (ptrn[p_idx] == '*' && !literal)
00712               || (ptrn[p_idx] == '\\' && !literal))
00713         {
00714             DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "comparing: b:%c -> p:%c\n", 
00715                                     buf[b_idx], ptrn[p_idx]););
00716 #ifdef DEBUG
00717             cmpcnt++;
00718 #endif
00719 
00720             if(literal)
00721                 literal = 0;
00722             if(!literal && ptrn[p_idx] == '\\')
00723                 literal = 1;
00724             if(ptrn[p_idx] == '*')
00725             {
00726                 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,"Checking wildcard matching...\n"););
00727                 while(p_idx != 0 && ptrn[--p_idx] == '*'); /* fool-proof */
00728 
00729                 while(buf[--b_idx] != ptrn[p_idx])
00730                 {
00731                     DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "comparing: b[%d]:%c -> p[%d]:%c\n",
00732                                             b_idx, buf[b_idx], p_idx, ptrn[p_idx]););
00733 
00734                    regexcomp++;
00735                     if(b_idx == 0)
00736                     {
00737                         DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00738                                                 "b_idx went to 0, returning 0\n");)
00739                         return 0;
00740                     }
00741                 }
00742 
00743                 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "got wildcard final char match! (b[%d]: %c -> p[%d]: %c\n", b_idx, buf[b_idx], p_idx, ptrn[p_idx]););
00744             }
00745 
00746             if(p_idx == 0)
00747             {
00748                 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "match: compares = %d.\n", 
00749                                         cmpcnt););
00750                 return 1;
00751             }
00752 
00753             if(b_idx == 0)
00754                 break;
00755         }
00756 
00757         DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "skip-shifting...\n"););
00758         skip_stride = skip[(unsigned char) buf[b_idx]];
00759         shift_stride = shift[p_idx];
00760         
00761         b_idx += (skip_stride > shift_stride) ? skip_stride : shift_stride;
00762         DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "b_idx skip-shifted to %d\n", b_idx););
00763         b_idx += regexcomp;
00764         DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00765                                 "b_idx regex compensated %d steps, to %d\n", regexcomp, b_idx););
00766         regexcomp = 0;
00767     }
00768 
00769     DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "no match: compares = %d, b_idx = %d, "
00770                             "blen = %d\n", cmpcnt, b_idx, blen););
00771 
00772     return 0;
00773 }

Generated on Sun May 14 14:51:14 2006 by  doxygen 1.4.2