⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 findrep.c

📁 THOMSON-DAVIS用C语言开发的编缉器,简单,易懂.
💻 C
📖 第 1 页 / 共 4 页
字号:
               if ((unsigned int)tolower( s[guard] ) != mini_guard)
                  goto shift_func;

               q = s + 1 - pat_len;
               for (i=0; i < pat_len; i++)
                  if (tolower( q[i] ) != tolower( p[i] ))
                     goto shift_func;
            }
            *offset = (size_t)(q - ll->line);

            assert( *offset <= (unsigned)(ll->len - pat_len) );

            return( ll );
         }
shift_func:
         if (len_s <= 0) {
            ++*rline;
            ll = ll->next;
            s = ll->line;
            if (ll->len == EOF)
               return( NULL );
            len_s = ll->len;
            i = pat_len - 1;
         } else
            i = mini_delta2;
      }
   }
}


/*
 * Name:    backward_boyer_moore_search
 * Purpose: search backward for pattern using boyer array
 * Passed:  window:  pointer to current window
 *          rline:   pointer current real line counter
 *          rcol:    pointer to real column
 * Returns: position in file if found or NULL if not found
 * Date:    June 5, 1991
 * Notes:   Start searching from cursor position to beginning of file. If we
 *          hit beginning end of file without a match, start searching from the
 *          end of file to cursor position.  (do wrapped searches)
 */
line_list_ptr backward_boyer_moore_search( WINDOW *window, long *rline, int *rcol )
{
int  i;
int  len;
int  end;
register WINDOW *win;  /* put window pointer in a register */
line_list_ptr ll;

   win  = window;
   *rline = win->rline;

   /*
    * see if cursor is on EOF line.  if so, move search start to previous node.
    */
   if (win->ll->len != EOF) {
      ll = win->ll;
      i  = win->rcol - 1;
      i += bm.pattern_length - 1;
      len = ll->len;
      if (i >= len)
         i = len - 1;
   } else {
      ll = win->ll->prev;
      --*rline;
      i = 0;
      if (ll != NULL)
         i = ll->len - 1;
   }
   *rcol = i;
   ll = search_backward( ll, rline, (size_t *)rcol );

   if (ll == NULL  &&  win->rline <= win->file_info->length) {

      end = 0;
      if (win->ll->prev != NULL) {
         end = win->ll->prev->len;
         win->ll->prev->len = EOF;
      }

      /*
       * haven't found pattern yet - now search from end of file
       */
      g_status.wrapped = TRUE;
      ll = win->file_info->line_list_end;
      if (ll->prev != NULL)
         *rcol = ll->prev->len;
      else
        *rcol = 0;
      *rline = win->file_info->length;
      ll = search_backward( ll->prev, rline, (size_t *)rcol );

      if (ll == win->ll  &&  *rcol <= win->rcol)
         ll = NULL;

      if (win->ll->prev != NULL)
         win->ll->prev->len = end;
   }
   if (ll != NULL)
      bin_offset_adjust( win, *rline );
   return( ll );
}


/*
 * Name:    search_backward
 * Purpose: search backward for pattern using boyer array
 * Passed:  ll:  pointer to node in linked list to start search
 *          rline:  pointer to real line counter
 *          offset:  offset into ll->line to start search
 * Returns: position in file if found else return NULL
 * Date:    January 8, 1992
 * Notes:   Start searching from cursor position to beginning of file.
 *          mini delta2 is the first rightmost occurrence of the leftmost character.
 */
line_list_ptr search_backward( line_list_ptr ll, long *rline, size_t *offset )
{
register int i;
text_ptr p;
int  mini_delta2;
int  pat_len;
int  len_s;
text_ptr s;

   if (ll == NULL)
      return( NULL );
   if (ll->len == EOF)
      return( NULL );
   else {
      mini_delta2 = bm.backward_md2;
      pat_len  = bm.pattern_length;
      p = bm.pattern;

      i = -bm.pattern_length + 1;

      s = ll->line;
      s += *offset;
      len_s = *offset + 1;
      for (;;) {

         /*
          * Boyer-Moore fast skip loop.  check character count as we move
          *   up the line.
          */
         for (s+=i, len_s+=i; len_s > 0 &&
                 (i = bm.skip_backward[(unsigned char)*s]); s+=i, len_s+=i);
         if (len_s > 0) {
            /*
             * i == 0, possible match.  Boyer-Moore slow match loop.
             */
            if (mode.search_case == MATCH) {
               for (i=0; i < pat_len; i++)
                  if (s[i] != p[i])
                    goto shift_func;
            } else {
               for (i=0; i < pat_len; i++)
                  if (tolower( s[i] ) != tolower( p[i] ))
                     goto shift_func;
            }
            *offset =(size_t)(s - ll->line);

            assert( *offset <= (unsigned)(ll->len - pat_len) );

            return( ll );
         }
shift_func:
         if (len_s <= 0) {
            --*rline;
            ll = ll->prev;
            if (ll == NULL)
               return( NULL );
            if (ll->len == EOF)
               return( NULL );
            len_s = ll->len;
            s = ll->line + len_s - 1;
            i = 1 - pat_len;
         } else
            i = mini_delta2;
      }
   }
}


/*
 * Name:    show_search_message
 * Purpose: display search status
 * Date:    January 8, 1992
 * Passed:  i:     index into message array
 *          color: color to display message
 */
void show_search_message( int i, int color )
{
   /*
    *  0 = blank
    *  1 = wrapped...
    *  2 = searching
    *  3 = replacing
    *  4 = nfa choked
    */
   assert( i >= 0  &&  i <= 4);
   s_output( find7[i], g_display.mode_line, 67, color );
}


/*
 * Name:    bin_offset_adjust
 * Purpose: place cursor on screen given a position in file - default cline
 * Date:    June 5, 1991
 * Passed:  window:  pointer to current window
 *          rline:   real line position some where in the file
 * Notes:   in binary mode, we keep an accurate count of the offset of the
 *          cursor from the beginning of the file.
 */
void bin_offset_adjust( WINDOW *window, long rline )
{
line_list_ptr node;
long found_distance;

   assert( rline >= 1L  &&  rline <= window->file_info->length );

   found_distance = window->rline - rline;
   node = window->ll;
   if (found_distance < 0) {
      while (found_distance++ < 0) {
         window->bin_offset += node->len;
         node = node->next;
      }
   } else if (found_distance > 0) {
      while (found_distance-- > 0) {
         node = node->prev;
         window->bin_offset -= node->len;
      }
   }
   assert( window->bin_offset >= 0 );
 }


/*
 * Name:    find_adjust
 * Purpose: place cursor on screen given a position in file - default cline
 * Date:    June 5, 1991
 * Passed:  window:  pointer to current window
 *          ll:   position anywhere in file
 *          rline:  real line number of ll in the file
 *          rcol:   real column of ll in the file
 * Notes:   ll could be anywhere in file.  Find the start of line that
 *          ll is on.  Determine if start of line is behind or ahead of
 *          current line.  Once that is done, it is easy to determine if ll
 *          is on screen.  Lastly, current cursor position becomes start of
 *          ll line - reposition and display.
 */
void find_adjust( WINDOW *window, line_list_ptr ll, long rline, int rcol )
{
int  cmd;
long test_line;
file_infos *file;
register WINDOW *win;  /* put window pointer in a register */

   win = window;
   file = win->file_info;

   /*
    * find real column found is on.
    */
   if (mode.inflate_tabs)
      rcol = detab_adjust_rcol( ll->line, rcol );

   /*
    * if p, start of found line, is greater than current line, see if
    * p is between current line and bottom line on screen.
    */
   if (win->rline < rline) {
      /*
       * test_line is the number of lines between rline and found line.
       */
      test_line = rline - win->rline;
      if ((long)win->cline + test_line <= (long)win->bottom_line)
         win->cline += (int)test_line;
      else
         file->dirty = LOCAL;

   /*
    * if p, start of found line, is less than current line, see if
    * p is between current line and top line on screen.
    */
   } else if (win->rline > rline) {
      test_line = win->rline - rline;
      if ((long)win->cline - test_line > (long)(win->top_line+win->ruler-1))
         win->cline -= (int)test_line;
      else
         file->dirty = LOCAL;
      if (rline < (long)(win->cline - (win->top_line+win->ruler-1)))
         win->cline = (int)rline + win->top_line+win->ruler - 1;
   }

   /*
    * cursor line becomes found line.  check if column is on screen.
    */
   win->rline = rline;
   win->ll    = ll;
   if (file->dirty == LOCAL && (win->cline == win->bottom_line ||
                                win->cline == win->top_line + win->ruler)) {
      cmd = g_status.command;
      if (cmd == RepeatFindForward1    ||  cmd == RepeatFindBackward1 ||
          cmd == DefineDiff            ||  cmd == RepeatDiff          ||
          cmd == FindRegX              ||  cmd == RepeatFindRegX      ||
          cmd == DefineGrep            ||  cmd == RepeatGrep) {
         center_window( win );
      } else if (cmd == ReplaceString) {
         if (win->visible)
            center_window( win );
      }
   }
   check_virtual_col( win, rcol, rcol );
}


/*
 * Name:    replace_string
 * Purpose: To set up and perform a replace operation.
 * Date:    June 5, 1991
 * Passed:  window:  pointer to current window
 */
int  replace_string( WINDOW *window )
{
int  direction;
char pattern[MAX_COLS];  /* the old and replacement text */
int  net_change;
int  sub_len;
int  file_changed;
int  finished;
int  rc;
int  rcol;
int  rcol_limit;
int  wrapped;
line_list_ptr ll;
long found_line;
long line_limit;
WINDOW wp;
register WINDOW *win;  /* put window pointer in a register */
int  visible;

   win = window;
   direction = get_replace_direction( win );
   if (direction == ERROR)
      return( ERROR );

   entab_linebuff( );
   if (un_copy_line( win->ll, win, TRUE ) == ERROR)
      return( ERROR );

   /*
    * get the search pattern, using the previous as the default
    */
   *pattern = '\0';
   if (g_status.replace_defined == OK) {

      assert( strlen( g_status.pattern ) < MAX_COLS );

      strcpy( pattern, g_status.pattern );
   }

   /*
    * string to find
    */
   if (get_name( find9, win->bottom_line, pattern,
                 g_display.message_color ) != OK  ||  *pattern == '\0')
      return( ERROR );

   assert( strlen( pattern ) < MAX_COLS );

   strcpy( g_status.pattern, pattern );

   /*
    * get the replacement text, using the previous as the default
    */
   *pattern = '\0';
   if (g_status.replace_defined == OK) {

      assert( strlen( g_status.subst ) < MAX_COLS );

      strcpy( pattern, g_status.subst );
   }
   if (get_name( find10, win->bottom_line, pattern,
                 g_display.message_color ) != OK)
      return( ERROR );

   assert( strlen( pattern ) < MAX_COLS );

   strcpy( g_status.subst, pattern );
   sub_len = strlen( pattern );
   strcpy( (char *)bm.pattern, g_status.pattern );
   net_change = sub_len - strlen( g_status.pattern );

   /*
    * get the replace flags, Prompt or NoPrompt
    */
   if (get_replacement_flags( win->bottom_line ) != OK)
      return( ERROR );

   build_boyer_array( );
   dup_window_info( &wp, win );
   update_line( win );
   g_status.replace_defined = OK;

   if (mode.inflate_tabs)
      win->rcol = entab_adjust_rcol( win->ll->line, win->ll->len, win->rcol );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -