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

📄 block.c

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

            assert( bc >= 0 );
            assert( bc <= MAX_LINE_LENGTH );
            assert( lens >= 0 );
            assert( lens <= MAX_LINE_LENGTH );
            assert( rcol >= 0 );
            assert( rcol <= MAX_LINE_LENGTH );

            _fmemcpy( g_status.line_buff+rcol, block_start->line+bc, lens );
            g_status.line_buff_len = lens + rcol;
            *rc = un_copy_line( dest, &d_w, TRUE );
            dest->dirty = TRUE;
         }

         if (*rc == OK  &&  ptoul( block_start->next ) != ptoul( block_end )) {
            block_start->next->prev = dest;
            temp_ll->prev = block_end->prev;
            block_end->prev->next = temp_ll;
            dest->next = block_start->next;
         }

         if (*rc == OK) {
            copy_line( block_start );
            detab_linebuff( );
            lend = bc;
            lens = block_end->len - (ec + 1);

            assert( bc >= 0 );
            assert( bc <= MAX_LINE_LENGTH );
            assert( lens >= 0 );
            assert( lens <= MAX_LINE_LENGTH );
            assert( lend >= 0 );
            assert( lend <= MAX_LINE_LENGTH );
            assert( ec + 1 >= 0 );
            assert( ec + 1 <= MAX_LINE_LENGTH );
            assert( lens + lend >= 0 );
            assert( lens + lend <= MAX_LINE_LENGTH );

            _fmemcpy( g_status.line_buff+bc, block_end->line+ec+1, lens );
            g_status.line_buff_len = lend + lens;
            *rc = un_copy_line( block_start, &s_w, TRUE );
            block_start->dirty = TRUE;
            block_start->next = block_end->next;
            block_end->next->prev = block_start;
            if (block_end->line != NULL)
               my_free( block_end->line );
            my_free( block_end );
         }
      }
   } else if (action == DELETE) {
      copy_line( block_start );
      lens = block_end->len - (ec + 1);

      assert( bc >= 0 );
      assert( bc <= MAX_LINE_LENGTH );
      assert( lens >= 0 );
      assert( lens <= MAX_LINE_LENGTH );
      assert( ec + 1 >= 0 );
      assert( ec + 1 <= MAX_LINE_LENGTH );
      assert( bc + lens >= 0 );
      assert( bc + lens <= MAX_LINE_LENGTH );

      _fmemcpy( g_status.line_buff+bc, block_end->line + ec+1, lens );
      g_status.line_buff_len = bc + lens;
      *rc = un_copy_line( block_start, &s_w, TRUE );
      block_start->dirty = TRUE;
      source = block_start->next;
      block_start->next = block_end->next;
      block_end->next->prev = block_start;
      block_end->next = NULL;
      while (source != NULL) {
         temp_ll = source;
         source = source->next;
         if (temp_ll->line != NULL)
            my_free( temp_ll->line );
         my_free( temp_ll );
      }
   }

   if (*rc == OK) {
      diff = er - br;
      if (action == COPY || action == KOPY || action == MOVE)
         dest_file->length += diff;
      if (action == DELETE || action == MOVE)
         source_file->length -= diff;
      if (action == DELETE && source_window->rline >= br) {
         source_window->rline -= diff;
         if (source_window->rline < br)
            source_window->rline = br;
      }
   }

   /*
    * restore all cursors in all windows
    */
   restore_cursors( dest_file );
   if (dest_file != source_file)
      restore_cursors( source_file );
   show_avail_mem( );
}


/*
 * Name:    do_box_block
 * Purpose: delete, move, copy, or kopy a BOX block
 * Date:    June 5, 1991
 * Passed:  window:         pointer to destination window (current window)
 *          source_window:  pointer to source window
 *          action:         block action  --  OVERLAY, FILL, etc...
 *          source_file:    pointer to source file structure
 *          dest_file:      pointer to destination file
 *          source:         pointer to source node
 *          dest:           pointer to destination node
 *          br:             beginning line number in marked block
 *          er:             ending line number in marked block
 *          block_inc:      increment used to number a block
 *          rline:          current line number in destination file
 *          block_num:      starting number when numbering a block
 *          block_just:     LEFT or RIGHT justified numbers in block
 *          fill_char:      character to fill a block
 *          same:           are source and destination files same? T or F
 *          block_len:      width of box block
 *          bc:             beginning column of block
 *          ec:             ending column of block
 *          rcol:           current column of cursor
 *          rc:             return code
 */
void do_box_block( WINDOW *window,  WINDOW *source_window,  int action,
                    file_infos *source_file,  file_infos *dest_file,
                    line_list_ptr source,  line_list_ptr dest, long br,
                    long er, long block_inc,
                    long rline, long block_num, int block_just, int fill_char,
                    int same, int block_len, int bc, int ec, int rcol, int *rc )
{
line_list_ptr p;                /* temporary list pointer */
int  lens;                      /* length of source line */
int  lend;                      /* length of destination line */
int  add;                       /* characters being added from another line */
char *block_buff;
char *swap_buff;
int  xbc, xec;                  /* temporary column variables */
long li;                        /* temporary line variables */
long dest_add;                  /* number of bytes added to destination file */
WINDOW s_w, d_w;       /* a couple of temporary WINDOWs for BOX stuff */
int  padded_file;
WINDOW *w;

   padded_file = FALSE;
   dup_window_info( &s_w, source_window );
   dup_window_info( &d_w, window );
   s_w.rline   = br;
   s_w.ll      = source;
   s_w.visible = FALSE;
   d_w.rline   = rline;
   d_w.ll      = dest;
   d_w.visible = FALSE;

   block_buff = (char *)calloc( BUFF_SIZE + 2, sizeof(char) );
   swap_buff  = (char *)calloc( BUFF_SIZE + 2, sizeof(char) );
   if (block_buff == NULL || swap_buff == NULL) {
      error( WARNING, window->bottom_line, block4 );
      *rc = ERROR;
   }

   /*
    * special case for block actions.  since block actions always
    *   move forward thru the file, overlapping text in an OVERLAY
    *   action don't do right.  make the operation start at the end
    *   of the block and work backwards.
    */
   if (*rc == OK  &&  (action == OVERLAY || action == SWAP) &&
           same  &&  rline > br  &&  rline <= er) {

      /*
       * see if we need to add padd lines at eof.
       */
      dest_add = rline - br;
      if (dest_add + er > window->file_info->length) {
         dest_add = dest_add - (window->file_info->length - er);
         p = dest_file->line_list_end->prev;
         for (; dest_add > 0  &&  *rc == OK; dest_add--)
            *rc = pad_dest_line( window, dest_file, p );
         padded_file = TRUE;
      }

      /*
       * move source and dest pointers to the end of the OVERLAY
       */
      for (li=er-br; li > 0; li--) {
         load_undo_buffer( dest_file, dest->line, dest->len );
         dest = dest->next;
         ++d_w.rline;
         source = source->next;
         ++s_w.rline;
      }

      /*
       * work backwards so the overlapped OVERLAY block don't use
       * overlayed text to fill the block.  same for SWAPPing blocks.
       */
      for (li=er; *rc == OK  &&  li >= br  &&  !g_status.control_break;
                                       li--, s_w.rline--, d_w.rline--) {
         lens = find_end( source->line, source->len );
         lend = find_end( dest->line, dest->len );
         if (lens != 0 || lend != 0) {
            load_box_buff( block_buff, source, bc, ec, ' ' );
            if (action == SWAP)
               load_box_buff( swap_buff, dest, rcol, rcol+block_len, ' ' );
            *rc = copy_buff_2file( &d_w, block_buff, dest, rcol,
                                    block_len, action );
            dest->dirty = TRUE;
            if (action == SWAP) {
               add = 0;
               *rc = copy_buff_2file( &s_w, swap_buff, source, bc,
                                block_len, action );
               source->dirty = TRUE;
            }
         }
         source = source->prev;
         dest = dest->prev;
      }
   } else {
      if (action == FILL)
         block_fill( block_buff, fill_char, block_len );
      for (li=br; *rc == OK  &&  li <= er  &&  !g_status.control_break;
                           li++, s_w.rline++, d_w.rline++) {
         lens = find_end( source->line, source->len );
         lend = find_end( dest->line, dest->len );

         switch (action) {
            case FILL    :
            case NUMBER  :
            case DELETE  :
            case MOVE    :
               load_undo_buffer( source_file, source->line, source->len );
               break;
            case COPY    :
            case KOPY    :
            case OVERLAY :
               load_undo_buffer( dest_file, dest->line, dest->len );
               break;
         }

         /*
          * with FILL and NUMBER operations, we're just adding chars
          *   to the file at the source location.  we don't have to
          *   worry about bookkeeping.
          */
         if (action == FILL || action == NUMBER) {
            if (action == NUMBER) {
              number_block_buff( block_buff, block_len, block_num, block_just );
              block_num += block_inc;
            }
            *rc = copy_buff_2file( &s_w, block_buff, source, rcol,
                                block_len, action );
            source->dirty = TRUE;

         /*
          * if we are doing a BOX action and both the source and
          * destination are 0 then we have nothing to do.
          */
         } else if (lens != 0 || lend != 0) {

            /*
             * do actions that may require adding to file
             */
            if (action == MOVE     ||  action == COPY || action == KOPY ||
                action == OVERLAY  ||  action == SWAP) {
               xbc = bc;
               xec = ec;
               if (action != OVERLAY  &&  action != SWAP  &&  same) {
                  if (rcol < bc && rline > br && rline <=er)
                     if (li >= rline) {
                        xbc = bc + block_len;
                        xec = ec + block_len;
                     }
               }
               load_box_buff( block_buff, source, xbc, xec, ' ' );
               if (action == SWAP)
                  load_box_buff( swap_buff, dest, rcol, rcol+block_len, ' ' );
               *rc = copy_buff_2file( &d_w, block_buff, dest, rcol,
                                block_len, action );
               dest->dirty = TRUE;
               if (action == SWAP && *rc == OK) {
                  *rc = copy_buff_2file( &s_w, swap_buff, source, xbc,
                                   block_len, action );
                  source->dirty = TRUE;
               }
            }

            /*
             * do actions that may require deleting from file
             */
            if (action == MOVE || action == DELETE) {
               lens = find_end( source->line, source->len );
               if (lens >= (bc + 1)) {
                  source->dirty = TRUE;
                  add = block_len;
                  xbc = bc;
                  if (lens <= (ec + 1))
                     add = lens - bc;
                  if (same && action == MOVE) {
                     if (rcol < bc && rline >= br && rline <=er)
                        if (li >= rline) {
                           xbc = bc + block_len;
                           if (lens <= (ec + block_len + 1))
                              add = lens - xbc;
                        }
                  }
                  if (add > 0)
                     *rc = delete_box_block( &s_w, source, xbc, add );
               }
            }
         }

         /*
          * if we are doing any BOX action we need to move the source pointer
          * to the next line.
          */
         source = source->next;

         /*
          * if we are doing any action other than DELETE, we need to move
          * the destination to the next line in marked block.
          * In BOX mode, we may need to pad the end of the file
          * with a blank line before we process the next line.
          */
         if (action != DELETE && action != FILL && action != NUMBER) {
            p = dest->next;
            if (p->len != EOF)
               dest = p;
            else if (li < er) {
               padded_file = TRUE;
               pad_dest_line( window, dest_file, p );
               dest = dest->next;
            }
         }
      }
   }
   if (block_buff != NULL)
      free( block_buff );
   if (swap_buff != NULL)
      free( swap_buff );
   if (padded_file) {
      w = g_status.window_list;
      while (w != NULL) {
         if (w->file_info == dest_file  &&  w->visible)
            show_size( w );
         w = w->next;
      }
   }
   show_avail_mem( );
}


/*
 * Name:    load_box_buff
 * Class:   helper function
 * Purpose: copy the contents of a BOX to a block buffer.
 * Date:    June 5, 1991
 * Passed:  block_buff: local buffer for block moves
 *          ll:         node to source line in file to load
 *          bc:     beginning column of BOX. used only in BOX operations.
 *          ec:     ending column of BOX. used only in BOX operations.
 *          filler: character to fill boxes that end past eol
 * Notes:   For BOX blocks, there are several things to take care of:
 *            1) The BOX begins and ends within a line - just copy the blocked
 *            characters to the block buff.  2) the BOX begins within a line
 *            but ends past the eol - copy all the characters within the line
 *            to the block buff then fill with padding.  3) the BOX begins and
 *            ends past eol - fill entire block buff with padding (filler).
 *          the fill character varies with the block operation.  for sorting
 *            a box block, the fill character is '\0'.  for adding text to
 *            the file, the fill character is a space.
 */
void load_box_buff( char *block_buff, line_list_ptr ll, int bc, int ec,
                    char filler )
{
int len;
int avlen;
register int i;
register char *bb;
text_ptr s;

   assert( bc >= 0 );
   assert( ec >= bc );
   assert( ec < MAX_LINE_LENGTH );

   bb = block_buff;
   len = ll->len;
   s = detab_a_line( ll->line, &len );
   /*
    * block start may be past eol
    */

⌨️ 快捷键说明

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