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

📄 utils.c

📁 这是一个功能强大的文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:


#include "tdestr.h"
#include "common.h"
#include "define.h"
#include "tdefunc.h"


/*
 * Name:    myiswhitespc
 * Purpose: To determine whether or not a character is *NOT* part of a "word".
 * Date:    July 4, 1992
 * Passed:  c: the character to be tested
 * Returns: TRUE if c is in the character set *NOT* part of a word
 * Notes:   The characters in the set not part of a word will not change as
 *           as much as the characters that are part of a word.  In most
 *           languages, human and computer, the delimiters are much more
 *           common than the tokens that make up a word.  For example,
 *           the set of punction characters don't change as much across
 *           languages, human and computer, as the characters that make
 *           up the alphabet, usually.  In other words, the delimiters
 *           are fairly constant across languages.
 */
int  myiswhitespc( int c )
{
   return( c == ' ' || (ispunct( c ) && c != '_') || iscntrl( c ) );
}


/*
 * Name:    check_virtual_col
 * Purpose: ensure integrity of rcol, ccol, and bcol
 * Date:    June 5, 1991
 * Passed:  window:  pointer to current window
 *          rcol: real column of cursor
 *          ccol: current or logical column of cursor
 */
void check_virtual_col( WINDOW *window, int rcol, int ccol )
{
register int bcol;
int  start_col;
int  end_col;
file_infos *file;

   file      = window->file_info;
   bcol      = window->bcol;
   start_col = window->start_col;
   end_col   = window->end_col;

   /*
    * is logical column past end of screen?
    */
   if (ccol > end_col) {
/*      ccol = start_col + (end_col + 1 - start_col) / 2;  */
      ccol = end_col;
      bcol = rcol - (ccol - start_col);
      file->dirty = LOCAL;
   }

   /*
    * is logical column behind start of screen?
    */
   if (ccol < start_col) {
      if (bcol >= (start_col - ccol))
         bcol -= (start_col - ccol);
      ccol = start_col;
      file->dirty = LOCAL;
   }

   /*
    * is real column < base column?
    */
   if (rcol < bcol) {
      ccol = rcol + start_col;
      bcol = 0;
      if (ccol > end_col) {
         bcol = rcol;
         ccol = start_col;
      }
      file->dirty = LOCAL;
   }

   /*
    * current column + base column MUST equal real column
    */
   if ((ccol - start_col) + bcol != rcol) {
      if (bcol < 0 || bcol > rcol) {
         bcol = rcol;
         file->dirty = LOCAL;
      }
      ccol = rcol - bcol + start_col;
      if (ccol > end_col) {
         bcol = rcol;
         ccol = start_col;
         file->dirty = LOCAL;
      }
   }

   /*
    * rcol CANNOT be negative
    */
   if (rcol < 0) {
      rcol = bcol = 0;
      ccol = start_col;
      file->dirty = LOCAL;
   }

   if (rcol >= MAX_LINE_LENGTH) {
      rcol = MAX_LINE_LENGTH - 1;
      bcol = rcol - (ccol - start_col);
   }

   assert( rcol >= 0 );
   assert( rcol < MAX_LINE_LENGTH );
   assert( bcol >= 0 );
   assert( bcol < MAX_LINE_LENGTH );
   assert( ccol >= start_col );
   assert( ccol <= end_col );

   window->bcol = bcol;
   window->ccol = ccol;
   window->rcol = rcol;
}


/*
 * Name:    copy_line
 * Purpose: To copy the cursor line, if necessary, into the current line
 *           buffer, so that changes can be made efficiently.
 * Date:    June 5, 1991
 * Passed:  text_line: line to be copied to line buffer
 *          line: line to display error message
 * Notes:   See un_copy_line, the reverse operation.
 *          DO NOT use the C library string functions on text in
 *           g_status.line_buff, because Null characters are allowed as
 *           normal text in the file.
 */
void copy_line( line_list_ptr ll )
{
register unsigned int len;
text_ptr text_line;

   if (g_status.copied == FALSE  &&  ll->len != EOF) {

      assert( ll != NULL );

      len = ll->len;
      text_line = ll->line;
      g_status.buff_node = ll;

      assert( len < MAX_LINE_LENGTH );

      if (text_line != NULL)
         _fmemcpy( g_status.line_buff, text_line, len );

      g_status.line_buff_len = len;
      g_status.copied = TRUE;
   }
}


/*
 * Name:    un_copy_line
 * Purpose: To copy the cursor line, if necessary, from the current line
 *           buffer, shifting the main text to make the right amount of
 *           room.
 * Date:    June 5, 1991
 * Passed:  test_line:  location in file to copy line buffer
 *          window:  pointer to current window
 *          del_trailing:  delete the trailing blanks at eol? TRUE or FALSE
 * Notes:   For some functions, trailing spaces should not be removed when
 *           returning the line buffer to the main text.  The JoinLine function
 *           is a good example.  We need to leave trailing space so when we
 *           join lines - the current line will extend at least up to
 *           the column of the cursor.  We need to leave trailing space
 *           during BOX block operations.
 *          See copy_line, the reverse operation.
 */
int  un_copy_line( line_list_ptr ll, WINDOW *window, int del_trailing )
{
text_ptr p;
size_t len;     /* length of line buffer text */
size_t ll_len;  /* length of ll->line */
int  net_change;
int  rc;
char c;
file_infos *file;
WINDOW *wp;

   rc = OK;
   if (mode.do_backups == TRUE)
      rc = backup_file( window );

   if (g_status.copied == TRUE  &&  ll->len != EOF) {

      file = window->file_info;

      /*
       * if we are deleting the entire line, don't worry about the
       *  deleting the trailing space, since we're deleting entire line.
       */
      if (g_status.command == DeleteLine)
         del_trailing = FALSE;

      if (del_trailing  &&  mode.trailing  &&  file->crlf != BINARY) {
         len = g_status.line_buff_len;
         for (p=(text_ptr)(g_status.line_buff+len); len > 0; len--, p--) {
            c = *(p - 1);
            if (c != ' '  &&  c != '\t')
               break;
            if (!mode.inflate_tabs && c == '\t')
               break;
         }
         g_status.line_buff_len = len;
         file->dirty = GLOBAL;
         if (window->visible == TRUE)
            show_changed_line( window );
      }
      len = g_status.line_buff_len;
      ll_len =  (ll->line == NULL) ? 0 : ll->len;


      assert( len < MAX_LINE_LENGTH );
      assert( ll_len < MAX_LINE_LENGTH );

      net_change = len - ll_len;

      if (ll_len != len  ||  ll->line == NULL) {
         /*
          * let malloc space for the new line before we free the old line.
          */
         p = my_malloc( len, &rc );
         if (rc == ERROR)
            error( WARNING, window->bottom_line, main4 );

         /*
          * free the space taken up by current line in far heap.
          */
         if (rc != ERROR  &&  ll->line != NULL)
            my_free( ll->line );
      } else
         p = ll->line;

      if (rc != ERROR) {
         if (len > 0)
            _fmemcpy( p, g_status.line_buff, len );
         ll->line = p;
         ll->len = len;

         if (net_change != 0) {
            for (wp=g_status.window_list; wp != NULL; wp=wp->next) {
               if (wp->file_info == file && wp != window)
                  if (wp->rline > window->rline)
                     wp->bin_offset += net_change;
            }
         }

         file->modified = TRUE;
         show_avail_mem( );
      }
   }
   g_status.copied = FALSE;
   return( rc );
}


/*
 * Name:    un_copy_tab_buffer
 * Purpose: To copy the tab buffer line the main text buffer
 * Date:    October 31, 1992
 * Passed:  line_number:  line number to copy line tab out buffer
 *          window:       pointer to current window
 */
int  un_copy_tab_buffer( line_list_ptr ll, WINDOW *window )
{
text_ptr p;
int  len;               /* length of current line buffer text */
int  net_change;
int  rc;
file_infos *file;
WINDOW *wp;

   rc = OK;
   file = window->file_info;
   /*
    * file has changed.  lets create the back_up if needed
    */
   if (mode.do_backups == TRUE) {
      window->file_info->modified = TRUE;
      rc = backup_file( window );
   }

   len = g_status.tabout_buff_len;

   assert( len >= 0 );
   assert( len < MAX_LINE_LENGTH );
   assert( ll->len >= 0 );
   assert( ll->len < MAX_LINE_LENGTH );

   /*
    * if the far heap has run out of space, then only part of the
    *  current line can be moved back into the far heap. Warn the user
    *  that some of the current line has been lost.
    */
   p = my_malloc( len, &rc );
   if (rc == ERROR)
      error( WARNING, window->bottom_line, main4 );

   if (rc == OK) {
      net_change = len - ll->len;

      if (ll->line != NULL)
         my_free( ll->line );
      if (len > 0)
         _fmemcpy( p, g_status.line_buff, len );
      ll->line = p;
      ll->len  = len;

      if (net_change != 0) {
         for (wp=g_status.window_list; wp != NULL; wp=wp->next) {
            if (wp->file_info == file && wp != window)
               if (wp->rline > window->rline)
                  wp->bin_offset += net_change;
         }
      }

      file->modified = TRUE;
   }
   return( rc );
}


/*
 * Name:    load_undo_buffer
 * Purpose: To copy the cursor line to the undo buffer.
 * Date:    September 26, 1991
 * Passed:  file:          pointer to file
 *          line_to_undo:  pointer to line in file to save
 * Notes:   save the last mode.undo_max lines in a stack.  when we overflow
 *           the stack, dump the oldest line.
 */
void load_undo_buffer( file_infos *file, text_ptr line_to_undo, int len )
{
int  rc;
text_ptr l;
line_list_ptr temp_ll;

   rc = OK;
   if (file->undo_count >= mode.undo_max) {
      --file->undo_count;
      temp_ll = file->undo_bot->prev;
      temp_ll->prev->next = file->undo_bot;
      file->undo_bot->prev = temp_ll->prev;
      if (temp_ll->line != NULL)
         my_free( temp_ll->line );
   } else
      temp_ll = (line_list_ptr)my_malloc( sizeof(line_list_struc), &rc );

   assert( len >= 0 );
   assert( len < MAX_LINE_LENGTH );

   l = my_malloc( len, &rc );

   if (rc == ERROR) {
      if (l != NULL)
         my_free( l );
      if (temp_ll != NULL)
         my_free( temp_ll );
   } else {
      if (len > 0)
         _fmemcpy( l, line_to_undo, len );
      temp_ll->line  = l;
      temp_ll->len   = len;
      temp_ll->dirty = TRUE;

      temp_ll->prev = NULL;
      temp_ll->next = file->undo_top;
      file->undo_top->prev = temp_ll;
      file->undo_top = temp_ll;

      ++file->undo_count;
   }
}


/*
 * Name:    set_prompt
 * Purpose: To display a prompt, highlighted, at the bottom of the screen.
 * Date:    October 1, 1989
 * Passed:  prompt: prompt to be displayed
 *          line:   line to display prompt
 */
void set_prompt( char *prompt, int line )
{
register int prompt_col;

   /*
    * work out where the answer should go
    */
   prompt_col = strlen( prompt );

   assert( prompt_col <= MAX_COLS );

   /*
    * output the prompt
    */
   s_output( prompt, line, 0, g_display.message_color );
   eol_clear( prompt_col, line, g_display.message_color );

   /*
    * put cursor at end of prompt
    */
   xygoto( prompt_col, line );
}


/*
 * Name:    get_name
 * Purpose: To prompt the user and read the string entered in response.
 * Date:    June 5, 1992
 * Passed:  prompt: prompt to offer the user
 *          line:   line to display prompt
 *          name:   default answer
 *          color:  color to display prompt
 * Returns: name:   user's answer
 *          OK if user entered something
 *          ERROR if user aborted the command
 * Notes:   with the addition of macros in tde, this function became a little
 *           more complicated.  we have to deal with both executing macros
 *           and macros that are the user uses when entering normal text
 *           at the prompt.  i call these local and global macros.  a global
 *           macro is when this function is called from a running macro.
 *           the running macro can enter text and return from this function
 *           w/o any action from the user.  a local macro is when the user
 *           presses a key inside this function, which happens quite often
 *           when keys are assigned to ASCII and Extended ASCII characters.
 */
int  get_name( char *prompt, int line, char *name, int color )
{
int  col;               /* cursor column for answer */
int  c;                 /* character user just typed */
char *cp;               /* cursor position in answer */
char *answer;           /* user's answer */
int first = TRUE;       /* first character typed */
register int len;       /* length of answer */
int  plen;              /* length of prompt */
int  func;              /* function of key pressed */
int  stop;              /* flag to stop getting characters */
char *p;                /* for copying text in answer */
char buffer[MAX_COLS+2];/* line on which name is being entered */
char line_buff[(MAX_COLS+1)*2]; /* buffer for char and attribute  */
int  normal;
int  local_macro = FALSE;
int  next;
int  regx_help_on;
char **pp;
int  i;

   /*
    * set up prompt and default
    */
   assert( strlen( prompt ) < MAX_COLS );
   assert( strlen( name )   < MAX_COLS );

   strcpy( buffer, prompt );

⌨️ 快捷键说明

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