From 7e0f021a9aec35fd8e6725e87e3313b101d26f5e Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 27 Jan 2008 11:37:44 +0100 Subject: Initial import (2.0.2-6) --- reference/C/CONTRIB/SNIP/bmhisrch.c | 94 +++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100755 reference/C/CONTRIB/SNIP/bmhisrch.c (limited to 'reference/C/CONTRIB/SNIP/bmhisrch.c') diff --git a/reference/C/CONTRIB/SNIP/bmhisrch.c b/reference/C/CONTRIB/SNIP/bmhisrch.c new file mode 100755 index 0000000..13a6655 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/bmhisrch.c @@ -0,0 +1,94 @@ +/* +** Case-Insensitive Boyer-Moore-Horspool pattern match +** +** Public Domain version by Thad Smith 7/21/1992, +** based on a 7/92 public domain BMH version by Raymond Gardner. +** +** This program is written in ANSI C and inherits the compilers +** ability (or lack thereof) to support non-"C" locales by use of +** toupper() and tolower() to perform case conversions. +** Limitation: pattern length + string length must be less than 32767. +** +** 10/21/93 rdg Fixed bugs found by Jeff Dunlop +*/ + +#include +#include +#include +#include + +typedef unsigned char uchar; + +#define LARGE 32767 /* flag for last character match */ + +static int patlen; /* # chars in pattern */ +static int skip[UCHAR_MAX+1]; /* skip-ahead count for test chars */ +static int skip2; /* skip-ahead after non-match with + ** matching final character */ +static uchar *pat = NULL; /* uppercase copy of pattern */ + +/* +** bmhi_init() is called prior to bmhi_search() to calculate the +** skip array for the given pattern. +** Error: exit(1) is called if no memory is available. +*/ + +void bmhi_init(const char *pattern) +{ + int i, lastpatchar; + patlen = strlen(pattern); + + /* Make uppercase copy of pattern */ + + pat = realloc ((void*)pat, patlen); + if (!pat) + exit(1); + for (i=0; i < patlen; i++) + pat[i] = toupper(pattern[i]); + + /* initialize skip array */ + + for ( i = 0; i <= UCHAR_MAX; ++i ) /* rdg 10/93 */ + skip[i] = patlen; + for ( i = 0; i < patlen - 1; ++i ) + { + skip[ pat[i] ] = patlen - i - 1; + skip[tolower(pat[i])] = patlen - i - 1; + } + lastpatchar = pat[patlen - 1]; + skip[ lastpatchar ] = LARGE; + skip[tolower(lastpatchar)] = LARGE; + skip2 = patlen; /* Horspool's fixed second shift */ + for (i = 0; i < patlen - 1; ++i) + { + if ( pat[i] == lastpatchar ) + skip2 = patlen - i - 1; + } +} + +char *bmhi_search(const char *string, const int stringlen) +{ + int i, j; + char *s; + + i = patlen - 1 - stringlen; + if (i >= 0) + return NULL; + string += stringlen; + for ( ;; ) + { + while ( (i += skip[((uchar *)string)[i]]) < 0 ) + ; /* mighty fast inner loop */ + if (i < (LARGE - stringlen)) + return NULL; + i -= LARGE; + j = patlen - 1; + s = (char *)string + (i - j); + while ( --j >= 0 && toupper(s[j]) == pat[j] ) + ; + if ( j < 0 ) /* rdg 10/93 */ + return s; /* rdg 10/93 */ + if ( (i += skip2) >= 0 ) /* rdg 10/93 */ + return NULL; /* rdg 10/93 */ + } +} -- cgit v1.2.3-54-g00ecf