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

📄 block.c

📁 这是一个功能强大的文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
   source_window = g_status.window_list;
   for (; ptoul( source_window->file_info ) != ptoul( source_file );)
      source_window = source_window->next;
   prompt_line = window->bottom_line;
   dest_file = window->file_info;
   check_block( );
   if (g_status.marked == FALSE)
      return( ERROR );
   block_start = source_file->block_start;
   block_end = source_file->block_end;
   if (block_start == NULL  ||  block_end == NULL)
      return( ERROR );

   block_type = source_file->block_type;
   if (block_type != LINE  &&  block_type != STREAM  &&  block_type != BOX)
      return( ERROR );

   dest = window->ll;
   rline = window->rline;
   if (dest->len == EOF)
      return( ERROR );
   rc = OK;

   /*
    * set up Beginning Column, Ending Column, Beginning Row, Ending Row
    */
   bc = source_file->block_bc;
   ec = source_file->block_ec;
   br = source_file->block_br;
   er = source_file->block_er;

   /*
    * if we are BOX FILLing or BOX NUMBERing, beginning column is bc,
    *   not the column of cursor
    */
   rcol =  (action == FILL || action == NUMBER) ? bc : window->rcol;

   /*
    * must find out if source and destination file are the same.
    * it don't matter with FILL and DELETE - those actions only modify the
    * source file.
    */
   source_first = same = FALSE;
   if (action == FILL) {
      if (block_type == BOX) {
         if (get_block_fill_char( window, &fill_char ) == ERROR)
            return( ERROR );
         dest = block_start;
         same = TRUE;
      } else {
         /*
          * can only fill box blocks.
          */
         error( WARNING, prompt_line, block2 );
         return( ERROR );
      }
   }
   block_inc = 1;
   if (action == NUMBER) {
      if (block_type == BOX) {
         if (get_block_numbers( window, &block_num, &block_inc, &block_just )
              == ERROR)
            return( ERROR );
         dest = block_start;
         same = TRUE;
      } else {
         /*
          * can only number box blocks.
          */
         error( WARNING, prompt_line, block3a );
         return( ERROR );
      }
   }
   if (action == SWAP) {
      if (block_type != BOX) {
         /*
          * can only swap box blocks.
          */
         error( WARNING, prompt_line, block3b );
         return( ERROR );
      }
   }
   if (source_file == dest_file && action != DELETE && action != FILL) {
      same = TRUE;
      if (block_type == BOX && action == MOVE) {
         if (rline == br  &&  (rcol >= bc && rcol <= ec))
            /*
             * a block moved to within the block itself has no effect
             */
            return( ERROR );
      } else if (block_type == LINE || block_type == STREAM) {
         if (rline >= br && rline <= er) {
            if (block_type == LINE) {
                /*
                 * if COPYing or KOPYing within the block itself, reposition the
                 * destination to the next line after the block (if it exists)
                 */
               if (action == COPY || action == KOPY)
                  dest = block_end;
                /*
                 * a block moved to within the block itself has no effect
                 */
               else if (action == MOVE)
                  return( ERROR );
            } else {

               /*
                * to find out if cursor is in a STREAM block we have to do
                * a few more tests.  if cursor is on the beginning row or
                * ending row, then check the beginning and ending column.
                */
               if ((rline > br && rline < er) ||
                   (br == er && rcol >= bc && rcol <= ec) ||
                   (br != er && ((rline == br && rcol >= bc) ||
                                 (rline == er && rcol <= ec)))) {

                  /*
                   * if the cursor is in middle of STREAM, make destination
                   * the last character following the STREAM block.
                   */
                  if (action == COPY || action == KOPY) {
                     dest = block_end;
                     rcol = ec + 1;
                     rline = er;
                  } else if (action == MOVE)
                     return( ERROR );
               }
            }
         }
      }
   }
   if (br < rline)
      source_first = TRUE;

   /*
    * 1. can't create lines greater than g_display.line_length
    * 2. if we are FILLing a BOX - fill block buff once right here
    * 3. only allow overlaying BOXs
    */
   block_len = (ec+1) - bc;
   if (block_type == BOX) {
      if (action != DELETE && action != FILL) {
         if (rcol + block_len > MAX_LINE_LENGTH) {
            /*
             * line too long
             */
            error( WARNING, prompt_line, ltol );
            return( ERROR );
         }
      }
   } else if (block_type == LINE) {
      block_len = 0;
      if (action == OVERLAY) {
         /*
          * can only overlay box blocks
          */
         error( WARNING, prompt_line, block5 );
         return( ERROR );
      }
   } else if (block_type == STREAM) {

      if (action == OVERLAY) {
         /*
          * can only overlay box blocks
          */
         error( WARNING, prompt_line, block5 );
         return( ERROR );
      }

      lend = block_end->len;
      if (action == DELETE || action == MOVE) {

         /*
          * Is what's left on start of STREAM block line plus what's left at
          * end of STREAM block line too long?
          */
         if (lend > ec)
            lend -= ec;
         else
            lend = 0;
         if (bc + lend > MAX_LINE_LENGTH) {
            /*
             * line too long
             */
            error( WARNING, prompt_line, ltol );
            return( ERROR );
         }
      }

      if (action != DELETE) {

         /*
          * We are doing a MOVE, COPY, or KOPY.  Find out if what's on the
          * current line plus the start of the STREAM line are too long.
          * Then find out if end of the STREAM line plus what's left of
          * the current line are too long.
          */
         lens = block_start->len;

         /*
          * if we had to move the destination of the STREAM COPY or KOPY
          * to the end of the STREAM block, then dest and window->ll->line
          * will not be the same.  In this case, set length to length of
          * first line in STREAM block.  Then we can add the residue of
          * the first line in block plus residue of the last line of block.
          */
         if (dest->line == window->ll->line)
            add = dest->len;
         else
            add = lens;

         /*
          * Is current line plus start of STREAM block line too long?
          */
         if (lens > bc)
            lens -= bc;
         else
            lens = 0;
         if (rcol + lens > MAX_LINE_LENGTH) {
            /*
             * line too long
             */
            error( WARNING, prompt_line, ltol );
            return( ERROR );
         }

         /*
          * Is residue of current line plus residue of STREAM block line
          * too long?
          */
         if (add > bc)
            add -= bc;
         else
            add = 0;
         if (lend > ec)
            lend -= ec;
         else
            lend = 0;
         if (add + lend > MAX_LINE_LENGTH) {
            /*
             * line too long
             */
            error( WARNING, prompt_line, ltol );
            return( ERROR );
         }
      }
      if (ptoul( block_start ) == ptoul( block_end )) {
         block_type = BOX;
         block_len = (ec+1) - bc;
      }
   }

   if (mode.do_backups == TRUE) {
      switch (action) {
         case MOVE :
         case DELETE :
         case COPY :
         case KOPY :
         case SWAP :
            window->file_info->modified = TRUE;
            rc = backup_file( window );
            break;
      }
      switch (action) {
         case MOVE :
         case DELETE :
         case FILL :
         case NUMBER :
         case SWAP :
            source_window->file_info->modified = TRUE;
            if (rc != ERROR)
               rc = backup_file( source_window );
            break;
      }
   }
   source = block_start;

   assert( block_start != NULL );
   assert( block_start->len != EOF );
   assert( block_end != NULL );
   assert( block_end->len != EOF );

   if (block_type == LINE)
      do_line_block( window,  source_window,  action,
                     source_file,  dest_file,  block_start,  block_end,
                     source,  dest,  br,  er,  &rc );

   else if (block_type == STREAM)
      do_stream_block( window,  source_window,  action,
                       source_file,  dest_file,  block_start,  block_end,
                       source,  dest,  rline,  br,  er,  bc,  ec,  rcol,  &rc );

   else
      do_box_block( window,  source_window,  action,
                    source_file,  dest_file,  source,  dest,  br,  er,
                    block_inc, rline, block_num, block_just, fill_char,
                    same, block_len, bc, ec,  rcol, &rc );

   dest_file->modified = TRUE;
   dest_file->dirty = GLOBAL;
   if (action == MOVE || action == DELETE || action == FILL || action==NUMBER) {
      source_file->modified = TRUE;
      source_file->dirty = GLOBAL;
   }

   /*
    * unless we are doing a KOPY, FILL, NUMBER, or OVERLAY we need to unmark
    * the block.  if we just did a KOPY, the beginning and ending may have
    * changed.  so, we must readjust beginning and ending rows.
    */
   if (action == KOPY) {
      if (same && !source_first && block_type == LINE  &&  rc != ERROR) {
         number = (er+1) - br;
         source_file->block_br += number;
         source_file->block_er += number;
      }
   } else if (action != FILL && action != OVERLAY && action != NUMBER)
      unmark_block( window );
   show_avail_mem( );
   g_status.copied = FALSE;
   return( rc );
}


/*
 * Name:    do_line_block
 * Purpose: delete, move, copy, or kopy a LINE block
 * Date:    April 1, 1993
 * Passed:  window:  pointer to current window
 * Passed:  window:         pointer to destination window (current window)
 *          source_window:  pointer to source window
 *          action:         block action  --  KOPY, MOVE, etc...
 *          source_file:    pointer to source file structure
 *          dest_file:      pointer to destination file
 *          block_start:    pointer to first node in block
 *          block_end:      pointer to last node in block
 *          source:         pointer to source node
 *          dest:           pointer to destination node
 *          br:             beginning line number in marked block
 *          er:             ending line number in marked block
 *          rc:             return code
 */
void do_line_block( WINDOW *window,  WINDOW *source_window,  int action,
                    file_infos *source_file,  file_infos *dest_file,
                    line_list_ptr block_start,  line_list_ptr block_end,
                    line_list_ptr source,  line_list_ptr dest,
                    long br,  long er, int *rc )
{
line_list_ptr temp_ll;          /* temporary list pointer */
text_ptr l;
int  lens;                      /* length of source line */
long li;                        /* temporary line variables */
long diff;

   if (action == COPY || action == KOPY) {

      assert( br >= 1 );
      assert( br <= source_file->length );
      assert( er >= br );
      assert( er <= source_file->length );

      for (li=br; li <= er  &&  *rc == OK; li++) {
         lens = source->len;

         assert( lens * sizeof(char) < MAX_LINE_LENGTH );

         l = (text_ptr)my_malloc( lens * sizeof(char), rc );
         temp_ll = (line_list_ptr)my_malloc( sizeof(line_list_struc), rc );
         if (*rc == OK) {
            if (lens > 0)
               _fmemcpy( l, source->line, lens );
            temp_ll->line  = l;
            temp_ll->len   = lens;
            temp_ll->dirty = TRUE;

            if (dest->next != NULL) {
               dest->next->prev = temp_ll;
               temp_ll->next = dest->next;
               dest->next = temp_ll;
               temp_ll->prev = dest;
            } else {
               temp_ll->next = dest;
               if (dest->prev != NULL)
                  dest->prev->next = temp_ll;
               temp_ll->prev = dest->prev;
               dest->prev = temp_ll;
               if (temp_ll->prev == NULL)
                  window->file_info->line_list = temp_ll;
            }

            dest = temp_ll;
            source = source->next;
         } else {
            /*

⌨️ 快捷键说明

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