home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Module :SEARCH.CPP
- ** Abstract :Search engines
- **
- ** Copyright (C) Sergey I. Yevtushenko
- **
- ** Log: Wed 12/11/1997 Adopted from C SNIPPETS
- */
-
- #include <string.h>
-
- #include <_search.h>
- #include <regexp.h>
- #include <_ctype.h>
- #include <version.h>
-
- #define LARGE 32767
-
- /************************************
- * Case-sensitive search
- */
-
- void BMHSearch::init(char *pattern,int)
- {
- int i, lastpatchar;
-
- if (pat)
- {
- delete pat;
- pat = 0;
- }
-
- patlen = strlen(pattern);
-
- if(!patlen)
- return;
-
- pat = new char[patlen];
-
- for (i = 0; i < patlen; i++)
- pat[i] = pattern[i];
-
- for (i = 0; i <= 256; ++i)
- skip[i] = patlen;
-
- for (i = 0; i < patlen; ++i)
- skip[pat[i]] = patlen - i - 1;
-
- lastpatchar = pat[patlen - 1];
-
- skip[lastpatchar] = LARGE;
- skip2 = patlen;
-
- for (i = 0; i < patlen - 1; ++i)
- {
- if (pat[i] == lastpatchar)
- skip2 = patlen - i - 1;
- }
- }
-
- char *BMHSearch::search(char *string, int& match_len)
- {
- int i, j;
- char *s;
- int stringlen = strlen(string);
-
- match_len = 0;
-
- i = patlen - 1 - stringlen;
-
- if (i >= 0)
- return 0;
-
- string += stringlen;
- for (;;)
- {
- while ((i += skip[(unsigned) string[i]]) < 0)
- ;
- if (i < (LARGE - stringlen))
- return 0;
- i -= LARGE;
- j = patlen - 1;
- s = (char *) string + (i - j);
- while (--j >= 0 && s[j] == pat[j])
- ;
-
- if (j < 0)
- {
- match_len = patlen;
- return s;
- }
-
- if ((i += skip2) >= 0)
- return 0;
- }
- }
-
- /************************************
- * Case-insensitive search
- */
-
- void BMHISearch::init(char *pattern, int)
- {
- int i, lastpatchar;
-
- if (pat)
- {
- delete pat;
- pat = 0;
- }
-
- patlen = strlen(pattern);
-
- if(!patlen)
- return;
-
- pat = new char[patlen];
-
- for (i = 0; i < patlen; i++)
- pat[i] = __to_upper(pattern[i]);
-
- for (i = 0; i <= 256; ++i)
- skip[i] = patlen;
-
- for (i = 0; i < patlen - 1; ++i)
- {
- skip[pat[i]] = patlen - i - 1;
- skip[__to_lower(pat[i])] = patlen - i - 1;
- }
-
- lastpatchar = pat[patlen - 1];
- skip[lastpatchar] = LARGE;
- skip[__to_lower((char)lastpatchar)] = LARGE;
-
- skip2 = patlen;
- for (i = 0; i < patlen - 1; ++i)
- {
- if (pat[i] == lastpatchar)
- skip2 = patlen - i - 1;
- }
- }
-
- char *BMHISearch::search(char *string, int& match_len)
- {
- int i, j;
- char *s;
- int stringlen = strlen(string);
-
- match_len = 0;
-
- i = patlen - 1 - stringlen;
- if (i >= 0)
- return 0;
-
- string += stringlen;
- for (;;)
- {
- while ((i += skip[(unsigned) string[i]]) < 0)
- ;
- if (i < (LARGE - stringlen))
- return 0;
- i -= LARGE;
- j = patlen - 1;
- s = (char *) string + (i - j);
- while (--j >= 0 && __to_upper(s[j]) == pat[j])
- ;
- if (j < 0)
- {
- match_len = patlen;
- return s;
- }
- if ((i += skip2) >= 0)
- return 0;
- }
- }
-
- /************************************
- * regular expression search
- */
-
- void RXSearch::init(char *pattern, int ignore_case)
- {
- expr = regcomp(pattern);
-
- if(expr)
- {
- regexp *r = (regexp*)expr;
- r->regcase = ignore_case;
- }
- }
-
- char* RXSearch::search(char *string, int& match_len)
- {
- regexp *r = (regexp*)expr;
-
- if(!expr)
- return 0;
-
- match_len = 0;
-
- if(regexec(r, string))
- {
- match_len = r->endp[0] - r->startp[0];
- return r->startp[0];
- }
-
- return 0;
- }
-
- void RXSearch::middle(int i)
- {
- regexp *r = (regexp*)expr;
-
- if(!r)
- return;
-
- if(i)
- regexp_bol_off(r);
- else
- regexp_bol_on(r);
- }
-