📄 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 "indent_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 + -