home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / fed0217s.zip / source / search.cpp < prev    next >
C/C++ Source or Header  |  2000-12-16  |  4KB  |  222 lines

  1. /*
  2. ** Module   :SEARCH.CPP
  3. ** Abstract :Search engines
  4. **
  5. ** Copyright (C) Sergey I. Yevtushenko
  6. **
  7. ** Log: Wed  12/11/1997       Adopted from C SNIPPETS
  8. */
  9.  
  10. #include <string.h>
  11.  
  12. #include <_search.h>
  13. #include <regexp.h>
  14. #include <_ctype.h>
  15. #include <version.h>
  16.  
  17. #define LARGE 32767
  18.  
  19. /************************************
  20. * Case-sensitive search
  21. */
  22.  
  23. void BMHSearch::init(char *pattern,int)
  24. {
  25.     int i, lastpatchar;
  26.  
  27.     if (pat)
  28.     {
  29.         delete pat;
  30.         pat = 0;
  31.     }
  32.  
  33.     patlen = strlen(pattern);
  34.  
  35.     if(!patlen)
  36.         return;
  37.  
  38.     pat = new char[patlen];
  39.  
  40.     for (i = 0; i < patlen; i++)
  41.         pat[i] = pattern[i];
  42.  
  43.     for (i = 0; i <= 256; ++i)
  44.         skip[i] = patlen;
  45.  
  46.     for (i = 0; i < patlen; ++i)
  47.         skip[pat[i]] = patlen - i - 1;
  48.  
  49.     lastpatchar = pat[patlen - 1];
  50.  
  51.     skip[lastpatchar] = LARGE;
  52.     skip2 = patlen;
  53.  
  54.     for (i = 0; i < patlen - 1; ++i)
  55.     {
  56.         if (pat[i] == lastpatchar)
  57.             skip2 = patlen - i - 1;
  58.     }
  59. }
  60.  
  61. char *BMHSearch::search(char *string, int& match_len)
  62. {
  63.     int i, j;
  64.     char *s;
  65.     int stringlen = strlen(string);
  66.  
  67.     match_len = 0;
  68.  
  69.     i = patlen - 1 - stringlen;
  70.  
  71.     if (i >= 0)
  72.         return 0;
  73.  
  74.     string += stringlen;
  75.     for (;;)
  76.     {
  77.         while ((i += skip[(unsigned) string[i]]) < 0)
  78.             ;
  79.         if (i < (LARGE - stringlen))
  80.             return 0;
  81.         i -= LARGE;
  82.         j = patlen - 1;
  83.         s = (char *) string + (i - j);
  84.         while (--j >= 0 && s[j] == pat[j])
  85.             ;
  86.  
  87.         if (j < 0)
  88.         {
  89.             match_len = patlen;
  90.             return s;
  91.         }
  92.  
  93.         if ((i += skip2) >= 0)
  94.             return 0;
  95.     }
  96. }
  97.  
  98. /************************************
  99. * Case-insensitive search
  100. */
  101.  
  102. void BMHISearch::init(char *pattern, int)
  103. {
  104.     int i, lastpatchar;
  105.  
  106.     if (pat)
  107.     {
  108.         delete pat;
  109.         pat = 0;
  110.     }
  111.  
  112.     patlen = strlen(pattern);
  113.  
  114.     if(!patlen)
  115.         return;
  116.  
  117.     pat = new char[patlen];
  118.  
  119.     for (i = 0; i < patlen; i++)
  120.         pat[i] = __to_upper(pattern[i]);
  121.  
  122.     for (i = 0; i <= 256; ++i)
  123.         skip[i] = patlen;
  124.  
  125.     for (i = 0; i < patlen - 1; ++i)
  126.     {
  127.         skip[pat[i]] = patlen - i - 1;
  128.         skip[__to_lower(pat[i])] = patlen - i - 1;
  129.     }
  130.  
  131.     lastpatchar = pat[patlen - 1];
  132.     skip[lastpatchar] = LARGE;
  133.     skip[__to_lower((char)lastpatchar)] = LARGE;
  134.  
  135.     skip2 = patlen;
  136.     for (i = 0; i < patlen - 1; ++i)
  137.     {
  138.         if (pat[i] == lastpatchar)
  139.             skip2 = patlen - i - 1;
  140.     }
  141. }
  142.  
  143. char *BMHISearch::search(char *string, int& match_len)
  144. {
  145.     int i, j;
  146.     char *s;
  147.     int stringlen = strlen(string);
  148.  
  149.     match_len = 0;
  150.  
  151.     i = patlen - 1 - stringlen;
  152.     if (i >= 0)
  153.         return 0;
  154.  
  155.     string += stringlen;
  156.     for (;;)
  157.     {
  158.         while ((i += skip[(unsigned) string[i]]) < 0)
  159.             ;
  160.         if (i < (LARGE - stringlen))
  161.             return 0;
  162.         i -= LARGE;
  163.         j = patlen - 1;
  164.         s = (char *) string + (i - j);
  165.         while (--j >= 0 && __to_upper(s[j]) == pat[j])
  166.             ;
  167.         if (j < 0)
  168.         {
  169.             match_len = patlen;
  170.             return s;
  171.         }
  172.         if ((i += skip2) >= 0)
  173.             return 0;
  174.     }
  175. }
  176.  
  177. /************************************
  178. * regular expression search
  179. */
  180.  
  181. void RXSearch::init(char *pattern, int ignore_case)
  182. {
  183.     expr = regcomp(pattern);
  184.  
  185.     if(expr)
  186.     {
  187.         regexp *r = (regexp*)expr;
  188.         r->regcase = ignore_case;
  189.     }
  190. }
  191.  
  192. char* RXSearch::search(char *string, int& match_len)
  193. {
  194.     regexp *r = (regexp*)expr;
  195.  
  196.     if(!expr)
  197.         return 0;
  198.  
  199.     match_len = 0;
  200.  
  201.     if(regexec(r, string))
  202.     {
  203.         match_len = r->endp[0] - r->startp[0];
  204.         return r->startp[0];
  205.     }
  206.  
  207.     return 0;
  208. }
  209.  
  210. void RXSearch::middle(int i)
  211. {
  212.     regexp *r = (regexp*)expr;
  213.  
  214.     if(!r)
  215.         return;
  216.  
  217.     if(i)
  218.         regexp_bol_off(r);
  219.     else
  220.         regexp_bol_on(r);
  221. }
  222.