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

📄 comments.c

📁 代码格式化工具。 其实就是linux下indent的windows版本。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (c) 1993 - 1998, Joseph Arceneaux.  All rights reserved.
 *
 * This file is subject to the terms of the GNU General Public License as
 * published by the Free Software Foundation.  A copy of this license is
 * included with this software distribution in the file COPYING.  If you
 * do not have a copy, you may obtain a copy by writing to the Free
 * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <string.h>

#include "sys.h"
#include "indent.h"
#include "io.h"
#include "comments.h"
#include "globs.h"
#include "parse.h"

RCSTAG_CC ("$Id: comments.c,v 1.33 2002/08/04 17:08:41 david Exp $");

/* Check the limits of the comment buffer, and expand as neccessary. */

#define CHECK_COM_SIZE \
        if (e_com >= l_com) \
          { \
            int nsize = l_com - s_com + 400; \
            combuf = (char *) xrealloc (combuf, nsize); \
            e_com = combuf + (e_com - s_com) + 1; \
            l_com = combuf + nsize - 5; \
            s_com = combuf + 1; \
          }

/* Output a comment.  `buf_ptr' is pointing to the character after
 * the beginning comment delimiter when this is called.  This handles
 * both C and C++ comments.
 *
 * As far as indent is concerned, there are basically two types
 * of comments -- those on lines by themselves and those which are
 * on lines with other code.  Variables (and the options specifying them)
 * affecting the printing of comments are:
 *
 * `format_comments'                ("fca"):  Ignore newlines in the
 *     comment and perform filling up to `comment_max_col'.  Double
 *     newlines indicate paragraph breaks.
 *
 * `format_col1_comments'           ("fc1"):  Format comments which
 *     begin in column 1.
 *
 * `unindent_displace'              ("d"):  The hanging indentation for
 *     comments which do not appear to the right of code.
 *
 * `comment_delimiter_on_blankline' ("cdb"):  If set, place the comment
 *     delimiters on lines by themselves.  This only affects comments
 *     which are not to the right of code.
 *
 * `com_ind'                        ("c"):  The column in which to begin
 *     comments that are to the right of code.
 *
 * `decl_com_ind'                   ("cd"):  The column in which to begin
 *     comments that are to the right of declarations.
 *
 * `else_endif_col'                 ("cp"):  The column in which to begin
 *     comments to the right of preprocessor directives.
 *
 * `star_comment_cont'              ("sc"):  Place a star ('*') to the
 *     left of the comment body.
 *
 * `comment_max_col'                ("lc"): The length of a comment line.
 *     Formatted comments which extend past this column will be continued on
 *     the following line.  If this option is not specified, `max_col' is
 *     used.
 */

void print_comment (int *paren_targ)
{
  register int column, format;
  codes_ty comment_type;

  int start_column;
  int found_column;
  int first_comment_line;
  int right_margin;
  int boxed_comment;
  int stars;
  int blankline_delims;
  int paragraph_break;
  int merge_blank_comment_lines;

  int two_contiguous_comments = 0;
  int save_length = 0;
  char *save_ptr = NULL;
  char *text_on_line = NULL;
  char *line_break_ptr = NULL;
  char *start_delim = NULL;

  char *line_preamble = NULL;
  int line_preamble_length;
  int visible_preamble;
  int suppress_cdb = 0;

  /* GDB_HOOK_print_comment() */

  /* Increment the parser stack, as we will store some things
   * there for dump_line to use. */

  inc_pstack ();

  /* Have to do it this way because this piece of shit program doesn't
   * always place the last token code on the stack. */

  if (*(token + 1) == '/')
    {
      comment_type = cplus_comment;
    }
  else
    {
      comment_type = comment;
    }

  /* First, decide what kind of comment this is: C++, C, or boxed C.
   * Even if this appears to be a normal C comment, we may change our
   * minds if we find a star in the right column of the second line,
   * in which case that's a boxed comment too.
   */

  if (comment_type == cplus_comment)
    {
      start_delim = "//";
      line_preamble = "// ";
      line_preamble_length = strlen (line_preamble);
      visible_preamble = 1;
      boxed_comment = 0;
      stars = 0;
      blankline_delims = 0;
    }
  else if ((*buf_ptr == '*') || (*buf_ptr == '-') || (*buf_ptr == '=') ||
	   (*buf_ptr == '_') || (parser_state_tos->col_1 &&
				 !settings.format_col1_comments))
    {
      /* Boxed comment.  This block of code will return. */
      int comment_lines_count = 1;
      stars = 0;
      boxed_comment = 0;
      blankline_delims = 0;
      line_preamble_length = 0;
      visible_preamble = 0;

      start_column = current_column () - 2;
      found_column = start_column;
      parser_state_tos->box_com = 1;
      parser_state_tos->com_col = found_column;

      if (settings.blanklines_before_blockcomments)
	{
	  prefix_blankline_requested = 1;
	}

      *e_com++ = '/';
      *e_com++ = '*';

      while (1)
	{
	  do
	    {
	      if (*buf_ptr == EOL)	/* Count line numbers within comment blocks */
		{
		  ++line_no;
		}

	      *e_com++ = *buf_ptr++;
	      CHECK_COM_SIZE;
	    }
	  while ((*buf_ptr != '*') && (buf_ptr < buf_end));

	  /* We have reached the end of the comment, and it's all on
	   * this line. */

	  if ((*buf_ptr == '*') && (*(buf_ptr + 1) == '/'))
	    {
	      if (buf_ptr == buf_end)
		{
		  fill_buffer ();
		}

	      buf_ptr += 2;

	      if (buf_ptr == buf_end)
		{
		  fill_buffer ();
		}

	      *e_com++ = '*';
	      *e_com++ = '/';
	      *e_com = '\0';
	      parser_state_tos->tos--;

	      /* If this is the only line of a boxed comment, it may
	       * be after some other text (e.g., #if foo <comment>),
	       * in which case we want to specify the correct column.
	       * In the other cases, the leading spaces account for
	       * the columns and we start it in column 1. */

	      if (comment_lines_count > 1)
		{
		  parser_state_tos->com_col = 1;
		}
	      else
		{
		  parser_state_tos->com_col = found_column;
		}

	      return;
	    }

	  /* End of the line, or end of file. */

	  if (buf_ptr == buf_end)
	    {
	      if (*(buf_ptr - 1) == EOL)
		{
		  *(--e_com) = EOS;
		  dump_line (true, paren_targ);
		  comment_lines_count++;
		  parser_state_tos->com_col = 1;
		}

	      fill_buffer ();

	      if (had_eof)
		{
		  *e_com++ = '\0';
		  parser_state_tos->tos--;
		  parser_state_tos->com_col = start_column;
		  return;
		}
	    }
	}
    }
  else
    {
      start_delim = "/*";
      line_preamble = 0;
      line_preamble_length = 0;
      visible_preamble = 0;
      boxed_comment = 0;
      stars = settings.star_comment_cont;
      blankline_delims = settings.comment_delimiter_on_blankline;
    }

  paragraph_break = 0;
  merge_blank_comment_lines = 0;
  first_comment_line = com_lines;
  right_margin = settings.comment_max_col;

  /* Now, compute the correct indentation for this comment
   * and whether or not it should be formatted. */

  found_column = current_column () - 2;

  if ((s_lab == e_lab) && (s_code == e_code))
    {
      /* First handle comments which begin the line. */

      if (parser_state_tos->col_1 && !settings.format_col1_comments)
	{
	  format = settings.format_col1_comments;
	  start_column = 1;
	}
      else
	{
	  format = settings.format_comments;

	  if ((parser_state_tos->ind_level <= 0) &&
	      (!parser_state_tos->in_stmt ||
	       (parser_state_tos->in_decl
		&& (parser_state_tos->paren_level == 0))))
	    {
	      start_column = found_column;
	    }
	  else
	    {
	      /* This comment is within a procedure or other code. */
	      start_column =
		compute_code_target (*paren_targ) -
		settings.unindent_displace;
	      if (start_column < 0)
		{
		  start_column = 1;
		}
	    }
	}
    }
  else
    {
      /* This comment follows code of some sort. */
      int target;

      suppress_cdb = 1;

      /* First, compute where the comment SHOULD go. */

      if (parser_state_tos->decl_on_line)
	{
	  target = settings.decl_com_ind;
	}
      else if (else_or_endif)
	{
	  target = settings.else_endif_col;
	}
      else
	{
	  target = settings.com_ind;
	}

      /* Now determine if the code on the line is short enough
       * to allow the comment to begin where it should. */

      if (s_code != e_code)
	{
	  start_column =
	    count_columns (compute_code_target (*paren_targ), s_code,
			   NULL_CHAR);
	}
      else
	{
	  /* s_lab != e_lab : there is a label here. */
	  start_column =
	    count_columns (compute_label_target (), s_lab, NULL_CHAR);
	}

      if (start_column < target)
	{
	  start_column = target;
	}
      else
	{
	  /* If the too-long code is a pre-processor command,
	     start the comment 1 space afterwards, otherwise
	     start at the next tab mark. */
	  if (else_or_endif)
	    {
	      start_column++;
	      else_or_endif = false;
	    }
	  else
	    {
	      start_column +=
		settings.tabsize - ((start_column - 1) % settings.tabsize);
	    }
	}

      format = settings.format_comments;
    }

  if (!line_preamble)
    {
      line_preamble_length = 3;

      if (stars)
	{
	  line_preamble = " * ";
	  visible_preamble = 1;
	}
      else
	{
	  line_preamble = "   ";
	  visible_preamble = 0;
	}
    }

  /* These are the parser stack variables used to communicate
   * formatting information to dump_line (). */

  parser_state_tos->com_col = (two_contiguous_comments ? 1 : start_column);
  parser_state_tos->box_com = boxed_comment;

  /* Output the beginning comment delimiter.  They are both two
   * characters long. */

  *e_com++ = *start_delim;
  *e_com++ = *(start_delim + 1);
  column = start_column + 2;

  /* If the user specified -cdb, put the delimiter on one line. */

  if (blankline_delims && !suppress_cdb)
    {
      char *p = buf_ptr;

      *e_com = '\0';
      dump_line (true, paren_targ);

      /* Check if the delimiter was already on a line by itself,
         and skip whitespace if formating. */

      p = skip_horiz_space (p);

      if (*p == EOL)
	{
	  buf_ptr = p + 1;
	}
      else if (format)
	{
	  buf_ptr = p;
	}

      if (buf_ptr >= buf_end)
	{
	  fill_buffer ();
	}

      column = start_column;
      goto begin_line;
    }
  else if (format)
    {
      *e_com++ = ' ';
      column = start_column + 3;

      skip_buffered_space ();	/* adjusts buf_ptr */
    }

  /* Iterate through the lines of the comment */

  while (!had_eof)
    {
      /* Iterate through the characters on one line */

      while (!had_eof)
	{
	  CHECK_COM_SIZE;

⌨️ 快捷键说明

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