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

📄 tab.c

📁 《c语言实例解析精粹》
💻 C
📖 第 1 页 / 共 2 页
字号:
                 *to++ = *++s;
                 --len;
               }
               break;
            }
         }
      }
   }
   return( (text_ptr)g_status.tabout_buff );
}


/*
 * Name:    detab_linebuff
 * Purpose: To expand tabs in line buffer so we can handle editing functions
 * Date:    October 31, 1992
 * Notes:   before we do any editing function that modifies text, let's
 *            expand any tabs to space.
 *          if inflate_tabs is FALSE, then nothing is done.
 */
void detab_linebuff( void )
{
int  show_eol;
int  len;

   if (mode.inflate_tabs  &&  g_status.copied) {
      len = g_status.line_buff_len;
      show_eol = mode.show_eol;
      mode.show_eol = FALSE;
      tabout( (text_ptr)g_status.line_buff, &len );

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

      memmove( g_status.line_buff, g_status.tabout_buff, len );
      g_status.line_buff_len = len;
      mode.show_eol = show_eol;
   }
}


/*
 * Name:    entab_linebuff
 * Purpose: To compress space in line buffer
 * Date:    October 31, 1992
 * Notes:   compress spaces back to tabs in the line buffer, if
 *             inflate_tabs == TRUE
 */
void entab_linebuff( void )
{
   if (mode.inflate_tabs  &&  g_status.copied) {
      entab( (text_ptr)g_status.line_buff, g_status.line_buff_len );

      assert( g_status.tabout_buff_len >= 0 );
      assert( g_status.tabout_buff_len < MAX_LINE_LENGTH );

      memmove( g_status.line_buff, g_status.tabout_buff,
                       g_status.tabout_buff_len );
      g_status.line_buff_len = g_status.tabout_buff_len;
   }
}


/*
 * Name:    detab_a_line
 * Purpose: To inflate tabs in any line in the file
 * Date:    October 31, 1992
 * Returns: pointer to text or tabout_buff
 * Notes:   expand an arbitrary line in the file.
 */
text_ptr detab_a_line( text_ptr s, int *len )
{
int  show_eol;

   if (mode.inflate_tabs) {

      assert( *len >= 0 );
      assert( *len < MAX_LINE_LENGTH );
      assert( s != NULL );

      show_eol = mode.show_eol;
      mode.show_eol = FALSE;
      s = tabout( s, len );
      mode.show_eol = show_eol;
   }
   return( s );
}


/*
 * Name:    detab_adjust_rcol
 * Purpose: given rcol in a line, find virtual column
 * Date:    October 31, 1992
 * Passed:  s:  string pointer
 * Notes:   without expanding tabs, calculate the display column according
 *            to current tab stop.
 */
int  detab_adjust_rcol( text_ptr s, int rcol )
{
register int col;

   assert( rcol >= 0 );
   assert( rcol < MAX_LINE_LENGTH );
   assert( s != NULL );
   assert( mode.ptab_size != 0 );

   for (col=0; rcol > 0; rcol--,s++) {
      if (*s == '\t')
         col += (mode.ptab_size - (col % mode.ptab_size));
      else if (rcol > 0)
         col++;
   }

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

   return( col );
}


/*
 * Name:    entab_adjust_rcol
 * Purpose: given virtual rcol in a line, find real column
 * Date:    October 31, 1992
 * Passed:  s:     string pointer
 *          len:   length of string
 *          rcol:  virtual real column
 * Notes:   without expanding tabs, calculate which col the real cursor
 *            referencing.
 */
int  entab_adjust_rcol( text_ptr s, int len, int rcol )
{
register int col;
register int last_col;

   assert( len >= 0 );
   assert( len < MAX_LINE_LENGTH );
   assert( rcol >= 0 );
   assert( rcol < MAX_LINE_LENGTH );
   assert( mode.ptab_size != 0 );

   if (s != NULL) {
      for (last_col=col=0; col < rcol  &&  s != NULL  &&  len > 0; s++, len--) {
         if (*s != '\t')
            ++col;
         else
            col += (mode.ptab_size - (col % mode.ptab_size));
         if (col > rcol)
            break;
         ++last_col;
      }
   } else
      last_col = rcol;

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

   return( last_col );
}


/*
 * Name:    block_expand_tabs
 * Purpose: Expand tabs in a marked block.
 * Date:    June 5, 1991
 * Passed:  window:  pointer to current window
 * Notes:   Tabs are expanded using the current tab interval.
 *          Lines are checked to make sure they are not too long.
 */
int  block_expand_tabs( WINDOW *window )
{
int  prompt_line;
int  len;
int  tab;
int  tab_size;
int  dirty;
register int spaces;
line_list_ptr p;                /* pointer to block line */
file_infos *file;
WINDOW *sw, s_w;
long er;
int  i;
int  rc;
char *b;

   /*
    * make sure block is marked OK and that this is a LINE block
    */
   prompt_line = window->bottom_line;

   if (un_copy_line( window->ll, window, TRUE ) == ERROR)
      return( ERROR );
   check_block( );
   rc = OK;
   if (g_status.marked == TRUE) {

      file  = g_status.marked_file;
      if (file->block_type != LINE) {
         /*
          * can only expand tabs in line blocks
          */
         error( WARNING, prompt_line, block20 );
         return( ERROR );
      }

      /*
       * initialize everything
       */
      dirty = FALSE;
      tab_size = mode.ptab_size;
      sw = g_status.window_list;
      for (; ptoul( sw->file_info ) != ptoul( file );)
         sw = sw->next;
      dup_window_info( &s_w, sw );
      p  = file->block_start;
      er = file->block_er;
      s_w.rline = file->block_br;
      s_w.visible = FALSE;
      for (; s_w.rline <= er  &&  !g_status.control_break; s_w.rline++) {

         /*
          * use the line buffer to expand LINE blocks.
          */
         tab = FALSE;
         g_status.copied = FALSE;

         copy_line( p );
         len = g_status.line_buff_len;
         for (b=g_status.line_buff, i=1; len > 0  &&  rc == OK; b++, len--) {

            /*
             * each line in the LINE block is copied to the g_status.line_buff.
             *  look at the text in the buffer and expand tabs.
             */
            if (*b == '\t') {
               tab = TRUE;
               spaces = i % tab_size;
               if (spaces)
                  spaces = tab_size - spaces;
               if (spaces) {

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

                  memmove( b + spaces, b, len );
               }

               assert( spaces + 1 >= 0 );
               assert( spaces + 1 < MAX_LINE_LENGTH );

               memset( b, ' ', spaces+1 );
               i += spaces + 1;
               b += spaces;
               g_status.line_buff_len += spaces;
            } else
               i++;
         }

         /*
          * if any tabs were found, write g_status.line_buff to file.
          */
         if (tab) {
            rc = un_copy_line( p, &s_w, TRUE );
            dirty = TRUE;
         }
         p = p->next;
      }

      /*
       * IMPORTANT:  we need to reset the copied flag because the cursor may
       * not necessarily be on the last line of the block.
       */
      g_status.copied = FALSE;
      if (dirty)
         file->dirty = GLOBAL;
   }
   return( rc );
}


/*
 * Name:    block_compress_tabs
 * Purpose: Expand tabs in a marked block.
 * Date:    October 31, 1992
 * Passed:  window:  pointer to current window
 * Notes:   Tabs are compress using the current tab setting.
 */
int  block_compress_tabs( WINDOW *window )
{
register int col;
register int spaces;
int  len;
int  rc;
int  prompt_line;
int  last_col;
int  tab;
int  tab_size;
int  dirty;
line_list_ptr p;                /* pointer to block line */
text_ptr from;                  /* line in main text buff being compressed */
file_infos *file;
WINDOW *sw, s_w;
long er;
char *to;
int  indent_only;

   /*
    * make sure block is marked OK and that this is a LINE block
    */
   prompt_line = window->bottom_line;
   entab_linebuff( );
   if (un_copy_line( window->ll, window, TRUE ) == ERROR)
      return( ERROR );
   check_block( );
   rc = OK;
   if (g_status.marked == TRUE) {

      file  = g_status.marked_file;
      if (file->block_type != LINE) {
         /*
          * can only compress tabs in line blocks
          */
         error( WARNING, prompt_line, block26 );
         return( ERROR );
      }

      indent_only = g_status.command == BlockIndentTabs ? TRUE : FALSE;

      /*
       * set the command to word wrap so the un_copy_line function will
       * not display the lines while expanding.
       */
      g_status.command = WordWrap;

      /*
       * initialize everything
       */
      dirty = FALSE;
      tab_size = mode.ptab_size;
      sw = g_status.window_list;
      for (; ptoul( sw->file_info ) != ptoul( file );)
         sw = sw->next;
      dup_window_info( &s_w, sw );
      s_w.visible = FALSE;
      s_w.ll  =  p  = file->block_start;
      er = file->block_er;
      s_w.rline = file->block_br;
      for (; rc == OK  &&  s_w.rline <= er  &&  !g_status.control_break; s_w.rline++) {

         /*
          * use the line buffer to compress LINE blocks.
          */
         tab = FALSE;

         from = p->line;
         to   = g_status.line_buff;
         g_status.line_buff_len = len  = p->len;

         for (last_col=col=0; ; from++, len--) {
            if (len == 0) {

               /*
                * when we reach the eol, compress trailing spaces to tabs.
                *   the un_copy_line function is responsible for trimming
                *   trailing space.
                */
               if (col != last_col) {
                  while (last_col < col) {
                     spaces = tab_size - last_col % tab_size;
                     if (spaces <= 1) {
                        *to++ = ' ';
                        last_col++;
                     } else if (last_col + spaces <= col) {
                        *to++ = '\t';
                        last_col += spaces;
                        g_status.line_buff_len -= (spaces - 1);
                        tab = TRUE;
                     } else {
                        *to++ = ' ';
                        last_col++;
                     }
                  }
               }

               /*
                * stop entabbing when we get to EOL
                */
               break;
            } else if (*from == ' ')
               col++;
            else {
               if (col != last_col) {
                  while (last_col < col) {
                     spaces = tab_size - last_col % tab_size;

                  /*
                   * when space == 1, forget about emmitting a tab
                   *   for 1 space.
                   */
                     if (spaces <= 1) {
                        *to++ = ' ';
                        last_col++;
                     } else if (last_col + spaces <= col) {
                        *to++ = '\t';
                        last_col += spaces;
                        g_status.line_buff_len -= (spaces - 1);
                        tab = TRUE;
                     } else {
                        *to++ = ' ';
                        last_col++;
                     }
                  }
               }

               /*
                * if *from == tab, then adjust the col pointer
                */
               if (*from == '\t')
                  col = col + tab_size - (col % tab_size);
               else
                  ++col;
               last_col = col;
               *to++ = *from;

               /*
                * when we see a quote character, stop entabbing.
                */
               if (*from == '\"' || *from == '\''  || indent_only) {
                  while (len > 0) {
                     *to++ = *++from;
                     --len;
                  }
                  break;
               }
            }
         }

         /*
          * if any tabs were found, write g_status.line_buff to file.
          */
         if (tab) {
            g_status.copied = TRUE;
            rc = un_copy_line( p, &s_w, TRUE );
            dirty = TRUE;
         }
         p = p->next;
      }

      /*
       * IMPORTANT:  we need to reset the copied flag because the cursor may
       * not necessarily be on the last line of the block.
       */
      g_status.copied = FALSE;
      if (dirty)
         file->dirty = GLOBAL;
   }
   return( rc );
}

⌨️ 快捷键说明

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