home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1707 / move2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  3.9 KB  |  213 lines

  1. /* m_2.c */
  2.  
  3. /* Author:
  4.  *    Steve Kirkendall
  5.  *    16820 SW Tallac Way
  6.  *    Beaverton, OR 97006
  7.  *    kirkenda@jove.cs.pdx.edu, or ...uunet!tektronix!psueea!jove!kirkenda
  8.  */
  9.  
  10.  
  11. /* This function contains the mvoement functions that perform RE searching */
  12.  
  13. #include "config.h"
  14. #include "vi.h"
  15. #include "regexp.h"
  16.  
  17. static regexp    *re;    /* compiled version of the pattern to search for */
  18. static        prevsf;    /* boolean: previous search direction was forward? */
  19.  
  20. MARK    m_nsrch(m)
  21.     MARK    m;    /* where to start searching */
  22. {
  23.     if (prevsf)
  24.     {
  25.         m = m_fsrch(m, "");
  26.         prevsf = TRUE;
  27.     }
  28.     else
  29.     {
  30.         m = m_bsrch(m, "");
  31.         prevsf = FALSE;
  32.     }
  33.     return m;
  34. }
  35.  
  36. MARK    m_Nsrch(m)
  37.     MARK    m;    /* where to start searching */
  38. {
  39.     if (prevsf)
  40.     {
  41.         m = m_bsrch(m, "");
  42.         prevsf = TRUE;
  43.     }
  44.     else
  45.     {
  46.         m = m_fsrch(m, "");
  47.         prevsf = FALSE;
  48.     }
  49.     return m;
  50. }
  51.  
  52. MARK    m_fsrch(m, ptrn)
  53.     MARK    m;    /* where to start searching */
  54.     char    *ptrn;    /* pattern to search for */
  55. {
  56.     long    l;    /* line# of line to be searched */
  57.     char    *line;    /* text of line to be searched */
  58.     int    wrapped;/* boolean: has our search wrapped yet? */
  59.     int    pos;    /* where we are in the line */
  60.  
  61.     /* remember: "previous search was forward" */
  62.     prevsf = TRUE;
  63.  
  64.     if (ptrn && *ptrn)
  65.     {
  66.         /* free the previous pattern */
  67.         if (re) free(re);
  68.  
  69.         /* compile the pattern */
  70.         re = regcomp(ptrn);
  71.         if (!re)
  72.         {
  73.             return MARK_UNSET;
  74.         }
  75.     }
  76.     else if (!re)
  77.     {
  78.         msg("No previous expression");
  79.         return MARK_UNSET;
  80.     }
  81.  
  82.     /* search forward for the pattern */
  83.     pos = markidx(m) + 1;
  84.     pfetch(markline(m));
  85.     if (pos >= plen)
  86.     {
  87.         pos = 0;
  88.         m = (m | (BLKSIZE - 1)) + 1;
  89.     }
  90.     wrapped = FALSE;
  91.     for (l = markline(m); l != markline(m) + 1 || !wrapped; l++)
  92.     {
  93.         /* wrap search */
  94.         if (l > nlines)
  95.         {
  96.             /* if we wrapped once already, then the search failed */
  97.             if (wrapped)
  98.             {
  99.                 break;
  100.             }
  101.  
  102.             /* else maybe we should wrap now? */
  103.             if (*o_wrapscan)
  104.             {
  105.                 l = 0;
  106.                 wrapped = TRUE;
  107.                 continue;
  108.             }
  109.             else
  110.             {
  111.                 break;
  112.             }
  113.         }
  114.  
  115.         /* get this line */
  116.         line = fetchline(l);
  117.  
  118.         /* check this line */
  119.         if (regexec(re, &line[pos], (pos == 0)))
  120.         {
  121.             /* match! */
  122.             if (wrapped && *o_warn)
  123.                 msg("(wrapped)");
  124.             return MARK_AT_LINE(l) + (int)(re->startp[0] - line);
  125.         }
  126.         pos = 0;
  127.     }
  128.  
  129.     /* not found */
  130.     msg(*o_wrapscan ? "Not found" : "Hit bottom without finding RE");
  131.     return MARK_UNSET;
  132. }
  133.  
  134. MARK    m_bsrch(m, ptrn)
  135.     MARK    m;    /* where to start searching */
  136.     char    *ptrn;    /* pattern to search for */
  137. {
  138.     long    l;    /* line# of line to be searched */
  139.     char    *line;    /* text of line to be searched */
  140.     int    wrapped;/* boolean: has our search wrapped yet? */
  141.     int    pos;    /* last acceptable idx for a match on this line */
  142.     int    last;    /* remembered idx of the last acceptable match on this line */
  143.     int    try;    /* an idx at which we strat searching for another match */
  144.  
  145.     /* remember: "previous search was not forward" */
  146.     prevsf = FALSE;
  147.  
  148.     if (ptrn && *ptrn)
  149.     {
  150.         /* free the previous pattern, if any */
  151.         if (re) free(re);
  152.  
  153.         /* compile the pattern */
  154.         re = regcomp(ptrn);
  155.         if (!re)
  156.         {
  157.             return MARK_UNSET;
  158.         }
  159.     }
  160.     else if (!re)
  161.     {
  162.         msg("No previous expression");
  163.         return MARK_UNSET;
  164.     }
  165.  
  166.     /* search backward for the pattern */
  167.     pos = markidx(m);
  168.     wrapped = FALSE;
  169.     for (l = markline(m); l != markline(m) - 1 || !wrapped; l--)
  170.     {
  171.         /* wrap search */
  172.         if (l < 1)
  173.         {
  174.             if (*o_wrapscan)
  175.             {
  176.                 l = nlines + 1;
  177.                 wrapped = TRUE;
  178.                 continue;
  179.             }
  180.             else
  181.             {
  182.                 break;
  183.             }
  184.         }
  185.  
  186.         /* get this line */
  187.         line = fetchline(l);
  188.  
  189.         /* check this line */
  190.         if (regexec(re, line, 1) && (int)(re->startp[0] - line) < pos)
  191.         {
  192.             /* match!  now find the last acceptable one in this line */
  193.             do
  194.             {
  195.                 last = (int)(re->startp[0] - line);
  196.                 try = (int)(re->endp[0] - line);
  197.             } while (try > 0
  198.                  && regexec(re, &line[try], FALSE)
  199.                  && (int)(re->startp[0] - line) < pos);
  200.  
  201.             if (wrapped && *o_warn)
  202.                 msg("(wrapped)");
  203.             return MARK_AT_LINE(l) + last;
  204.         }
  205.         pos = BLKSIZE;
  206.     }
  207.  
  208.     /* not found */
  209.     msg(*o_wrapscan ? "Not found" : "Hit top without finding RE");
  210.     return MARK_UNSET;
  211. }
  212.  
  213.