home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / APPS / elvis_1.4.tar.Z / elvis_1.4.tar / move2.c < prev    next >
C/C++ Source or Header  |  1990-12-06  |  4KB  |  239 lines

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