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

📄 block.c

📁 这是一个功能强大的文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
   if (len < ec + 1) {
      /*
       * does block start past eol? - fill with pad
       */
      assert( ec + 1 - bc >= 0 );

      memset( block_buff, filler, (ec + 1) - bc );
      if (len >= bc) {
         /*
          * block ends past eol - fill with pad
          */
         avlen = len - bc;
         s += bc;
         for (i=avlen; i>0; i--)
            *bb++ = *s++;
      }
   } else {
      /*
       * block is within line - copy block to buffer
       */
      avlen = (ec + 1) - bc;
      s = s + bc;
      for (i=avlen; i>0; i--)
         *bb++ = *s++;
   }
}


/*
 * Name:    copy_buff_2file
 * Class:   helper function
 * Purpose: copy the contents of block buffer to destination file
 * Date:    June 5, 1991
 * Passed:  window:     pointer to current window
 *          block_buff: local buffer for moves
 *          dest:       pointer to destination line in destination file
 *          rcol:       if in BOX mode, destination column in destination file
 *          block_len:  if in BOX mode, width of block to copy
 *          action:     type of block action
 * Notes:   In BOX mode, the destination line has already been prepared.
 *          Just copy the BOX buffer to the destination line.
 */
int  copy_buff_2file( WINDOW *window, char *block_buff, line_list_ptr dest,
                      int rcol, int block_len, int action )
{
char *s;
char *d;
int len;
int pad;
int add;

   copy_line( dest );
   if (mode.inflate_tabs)
      detab_linebuff( );

   len = g_status.line_buff_len;

   assert( len >= 0 );
   assert( len < MAX_LINE_LENGTH );
   assert( rcol >= 0 );
   assert( rcol < MAX_LINE_LENGTH );
   assert( block_len >= 0 );
   assert( block_len < BUFF_SIZE );

   if (rcol > len) {
      pad = rcol - len;

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

      memset( g_status.line_buff + len, ' ', pad );
      len += pad;
   }

   s = g_status.line_buff + rcol;

   /*
    * s is pointing to location to perform BOX operation.  If we do a
    * FILL or OVERLAY, we do not necessarily add any extra space.  If the
    * line does not extend all the thru the BOX then we add.
    * we always add space when we COPY, KOPY, or MOVE
    */
   if (action == FILL || action == OVERLAY || action == NUMBER || action == SWAP) {
      add = len - rcol;
      if (add < block_len) {
         pad = block_len - add;

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

         memset( g_status.line_buff + len, ' ', pad );
         len += pad;
      }
   } else {
      d = s + block_len;
      add = len - rcol;

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

      memmove( d, s, add );
      len += block_len;
   }

   assert( rcol + block_len <= len );
   assert( len >= 0 );
   assert( len < MAX_LINE_LENGTH );

   memmove( s, block_buff, block_len );
   g_status.line_buff_len = len;
   if (mode.inflate_tabs)
      entab_linebuff( );
   return( un_copy_line( dest, window, TRUE ) );
}


/*
 * Name:    block_fill
 * Class:   helper function
 * Purpose: fill the block buffer with character
 * Date:    June 5, 1991
 * Passed:  block_buff: local buffer for moves
 *          fill_char:  fill character
 *          block_len:  number of columns in block
 * Notes:   Fill block_buffer for block_len characters using fill_char.  This
 *          function is used only for BOX blocks.
 */
void block_fill( char *block_buff, int fill_char, int block_len )
{
   assert( block_len >= 0 );
   assert( block_len < BUFF_SIZE );
   assert( block_buff != NULL );

   memset( block_buff, fill_char, block_len );
}


/*
 * Name:    number_block_buff
 * Class:   helper function
 * Purpose: put a number into the block buffer
 * Date:    June 5, 1991
 * Passed:  block_buff: local buffer for moves
 *          block_len:  number of columns in block
 *          block_num:  long number to fill block
 *          just:       LEFT or RIGHT justified?
 * Notes:   Fill block_buffer for block_len characters with number.
 *          This function is used only for BOX blocks.
 */
void number_block_buff( char *block_buff, int block_len, long block_num,
                        int just )
{
int len;                /* length of number buffer */
int i;
char temp[MAX_COLS];    /* buffer for long number to ascii conversion  */

   assert( block_len >= 0 );
   assert( block_len < BUFF_SIZE );

   block_fill( block_buff, ' ', block_len );
   len = strlen( ltoa( block_num, temp, 10 ) );
   if (just == RIGHT) {
      block_len--;
      len--;
      for (;block_len >= 0 && len >= 0; block_len--, len--)
         block_buff[block_len] = temp[len];
   } else {
      for (i=0; block_len > 0 && i < len; block_len--, i++)
         block_buff[i] = temp[i];
   }
}


/*
 * Name:    restore_cursors
 * Class:   helper function
 * Purpose: a file has been modified - must restore all cursor pointers
 * Date:    June 5, 1991
 * Passed:  file:  pointer to file with changes
 * Notes:   Go through the window list and adjust the cursor pointers
 *          as needed.
 */
void restore_cursors( file_infos *file )
{
register WINDOW *window;
line_list_ptr ll;
long n;

   assert( file != NULL );

   window = g_status.window_list;
   while (window != NULL) {
      if (window->file_info == file) {
         window->bin_offset = 0;
         if (window->rline < 1L)
            window->rline = 1L;
         if (window->rline > file->length)
            window->rline = file->length;
         ll = file->line_list;
         n = 1L;
         for (; n < window->rline; n++) {
            window->bin_offset += ll->len;
            ll = ll->next;
         }
         window->ll = ll;
         if (window->rline < (window->cline - (window->top_line+window->ruler-1)))
            window->cline = (int)window->rline + window->top_line+window->ruler-1;
         if (window->cline < window->top_line + window->ruler)
            window->cline = window->top_line + window->ruler;
         if (window->visible)
            show_size( window );
      }
      window = window->next;
   }
}


/*
 * Name:    delete_box_block
 * Class:   helper function
 * Purpose: delete the marked text
 * Date:    June 5, 1991
 * Passed:  s_w:    source window
 *          source: pointer to line with block to delete
 *          bc:     beginning column of block - BOX mode only
 *          add:    number of characters in block to delete
 * Notes:   Used only for BOX blocks.  Delete the block.
 */
int  delete_box_block( WINDOW *s_w, line_list_ptr source, int bc, int add )
{
char *s;
int number;

   assert( s_w != NULL );
   assert( source != NULL );
   assert( bc >= 0 );
   assert( bc < MAX_LINE_LENGTH );
   assert( add >= 0 );
   assert( add < MAX_LINE_LENGTH );

   copy_line( source );
   detab_linebuff( );
   number = g_status.line_buff_len - bc;
   s = g_status.line_buff + bc + add;

   assert( number >= 0 );
   assert( number < MAX_LINE_LENGTH );
   assert( bc + add >= 0 );
   assert( bc + add < MAX_LINE_LENGTH );
   assert( add <= g_status.line_buff_len );

   memmove( s - add, s, number );
   g_status.line_buff_len -= add;
   entab_linebuff( );
   return( un_copy_line( source, s_w, TRUE ) );
}


/*
 * Name:    check_block
 * Class:   helper function
 * Purpose: To check that the block is still valid.
 * Date:    June 5, 1991
 * Notes:   After some editing, the marked block may not be valid.  For example,
 *          deleting all the lines in a block in another window.  We don't
 *          need to keep up with the block text pointers while doing normal
 *          editing; however, we need to refresh them before doing block stuff.
 */
void check_block( void )
{
register file_infos *file;
WINDOW filler;

   file = g_status.marked_file;
   if (file == NULL || file->block_br > file->length)
      unmark_block( &filler );
   else {
      if (file->block_er > file->length)
         file->block_er = file->length;
      find_begblock( file );
      find_endblock( file );
   }
}


/*
 * Name:    find_begblock
 * Class:   helper editor function
 * Purpose: find the beginning line in file with marked block
 * Date:    June 5, 1991
 * Passed:  file: file containing marked block
 * Notes:   file->block_start contains starting line of marked block.
 */
void find_begblock( file_infos *file )
{
line_list_ptr ll;
long li;           /* line counter (long i) */

   assert( file != NULL );
   assert( file->line_list != NULL );

   ll = file->line_list;
   for (li=1; li<file->block_br && ll->next != NULL; li++)
      ll = ll->next;

   file->block_start = ll;
}


/*
 * Name:    find_endblock
 * Class:   helper function
 * Purpose: find the ending line in file with marked block
 * Date:    June 5, 1991
 * Passed:  file: file containing marked block
 * Notes:   If in LINE mode, file->block_end is set to end of line of last
 *          line in block.  If in BOX mode, file->block_end is set to
 *          beginning of last line in marked block.  If the search for the
 *          ending line of the marked block goes past the eof, set the
 *          ending line of the block to the last line in the file.
 */
void find_endblock( file_infos *file )
{
line_list_ptr ll; /* start from beginning of file and go to end */
long i;           /* line counter */
register file_infos *fp;

   assert( file != NULL );
   assert( file->block_start != NULL );

   fp = file;
   ll = fp->block_start;
   if (ll != NULL) {
      for (i=fp->block_br;  i < fp->block_er && ll->next != NULL; i++)
         ll = ll->next;
      if (ll != NULL)
         fp->block_end = ll;
      else {

         /*
          * last line in marked block is NULL.  if LINE block, set end to
          * last character in the file.  if STREAM or BOX block, set end to
          * start of last line in file.  ending row, or er, is then set to
          * file length.
          */
         fp->block_end = fp->line_list_end->prev;
         fp->block_er = fp->length;
      }
   }
}


/*
 * Name:    block_write
 * Class:   primary editor function
 * Purpose: To write the currently marked block to a disk file.
 * Date:    June 5, 1991
 * Passed:  window:  pointer to current window
 * Notes:   If the file already exists, the user gets to choose whether
 *           to overwrite or append.
 */
int  block_write( WINDOW *window )
{
int prompt_line;
int rc;
char buff[MAX_COLS+2]; /* buffer for char and attribute  */
char line_buff[(MAX_COLS+1)*2]; /* buffer for char and attribute  */
file_infos *file;
int block_type;
int fattr;

   /*
    * make sure block is marked OK
    */
   entab_linebuff( );
   rc = un_copy_line( window->ll, window, TRUE );
   check_block( );
   if (rc == OK  &&  g_status.marked == TRUE) {
      prompt_line = window->bottom_line;
      file        = g_status.marked_file;

      assert( file != NULL );

      block_type  = file->block_type;

      /*
       * find out which file to write to
       */
      save_screen_line( 0, prompt_line, line_buff );
      *g_status.rw_name = '\0';
      if (get_name( block6, prompt_line, g_s

⌨️ 快捷键说明

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