📄 comments.c
字号:
/* 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 + -