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

📄 pr_comme.c

📁 GNU 系统开发优化 C 语言程序的应用程序
💻 C
字号:
/* Copyright (c) 1993, Joseph Arceneaux.   This file is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 1, or (at your option)   any later version.   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.   If you do not have a copy of the GNU General Public License, you   may obtain a copy by writing to the Free Software Foundation,   675 Mass Ave, Cambridge, MA 02139, USA.  */#include "sys.h"#include "indent.h"/* Check the limits of the comment buffer, and expand as neccessary. */#define CHECK_COM_SIZE \	if (e_com >= l_com) \          { \	    register 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; \	  }/* The number of comments handled so far. */int out_coms;/* 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 `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.   `max_col'                        ("l"):  The length of a line.  Formatted       comments which extend past this column will be continued on the       following line.   `block_comment_max_col'          ("lc"): Unused.   `blanklines_before_blockcomments'("nbbb"): Unused.   */voidprint_comment (){  register int column, format;  enum codes comment_type;  int start_column, save_length, found_column;  int first_comment_line, right_margin;  int boxed_comment, stars, blankline_delims, paragraph_break,      merge_blank_comment_lines;  char *line_break_ptr = 0;  char *save_ptr = 0;  char *text_on_line = 0;  char *start_delim, *end_delim;  char *line_preamble;  int line_preamble_length, visible_preamble;  /* 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 = 3;      visible_preamble = 1;      boxed_comment = 0;      stars = 0;      blankline_delims = 0;    }  else if (*buf_ptr == '*' || *buf_ptr == '-'	   || *buf_ptr == '=' || *buf_ptr == '_')    /* Boxed comment */    {      start_delim = "/*";      end_delim = "*/";      line_preamble = " ";      line_preamble_length = 1;      visible_preamble = 0;      boxed_comment = 1;      stars = 0;      blankline_delims = 0;    }  else    {      start_delim = "/*";      end_delim = "*/";      line_preamble = 0;      line_preamble_length = 0;      visible_preamble = 0;      boxed_comment = 0;      stars = star_comment_cont;      blankline_delims = comment_delimiter_on_blankline;    }  paragraph_break = 0;  merge_blank_comment_lines = 0;  first_comment_line = com_lines;  right_margin = max_col;  /* Now, compute the correct indentation for this comment     and whether or not it should be formatted. */  found_column = current_column () - 2;  if (boxed_comment)    {      start_column = found_column;      format = 0;      blankline_delims = 0;    }  else    {      /* First handle comments which begin the line. */      if ((s_lab == e_lab) && (s_code == e_code))	{	  /* This is a top-level comment, not within some code. */	  if (parser_state_tos->ind_level <= 0)	    {	      if (parser_state_tos->col_1)		{		  format = format_col1_comments;		  start_column = 1;		}	      else		{		  format = format_comments;		  start_column = found_column;		}	    }	  /* Here for comments starting a line, in the middle of code. */	  else	    {	      if (parser_state_tos->col_1)		{		  format = format_col1_comments;		  start_column = 1;		}	      else		{		  format = format_comments;		  start_column = (parser_state_tos->ind_level				  - unindent_displace + 1);		  if (start_column < 0)		    start_column = 1;		}	    }	}      else	/* This comment follows code of some sort. */	{	  int target;	  /* First, compute where the comment SHOULD go. */	  if (parser_state_tos->decl_on_line)	    target = decl_com_ind;	  else if (else_or_endif)	    target = else_endif_col;	  else	    target = 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 (), s_code);	  else	    /* s_lab != e_lab : there is a label here. */	    start_column = count_columns (compute_label_target (), s_lab);	  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 += (tabsize - (start_column % tabsize) + 1);	    }	  format = 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 = start_column;  parser_state_tos->box_com = boxed_comment;  if (boxed_comment)    {      stars = 0;      blankline_delims = 0;    }  /* Output the beginning comment delimiter.  They are both two     characters long. */  memcpy (e_com, start_delim, 2);  e_com += 2;  column = start_column + 2;  /* If the user specified -cdb, put the delimiter on one line. */  if (blankline_delims)    {      char *p = buf_ptr;      *e_com = '\0';      dump_line ();      /* Check if the delimiter was already on a line by itself,	 and skip whitespace if formating. */      while ((*p == ' ' || *p == TAB) && p < buf_end)	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;      while (*buf_ptr == ' ' || *buf_ptr == TAB)	buf_ptr++;      if (buf_ptr >= buf_end)	fill_buffer ();    }  /* Iterate through the lines of the comment */  while (1)    {      /* Iterate through the characters on one line */      while (1)	{	  CHECK_COM_SIZE;	  switch (*buf_ptr)	    {	    case ' ':	    case TAB:	      /* If formatting, and previous break marker is	         nonexistant, or before text on line, reset		 it to here. */	      if (format && line_break_ptr < text_on_line)		line_break_ptr = e_com;	      if (*buf_ptr == ' ')		{		  *e_com++ = ' ';		  column++;		}	      else		{		  /* Convert the tab to the appropriate number of spaces,		     based on the column we found the comment in, not		     the one we're printing in. */		  int tab_width		    = (tabsize - ((column + found_column - start_column - 1)				  % tabsize));		  column += tab_width;		  while (tab_width--)		    *e_com++ = ' ';		}	      break;	    case EOL:	      /* We may be at the end of a C++ comment */	      if (comment_type == cplus_comment)		{		  dump_line ();		  buf_ptr++;		  if (buf_ptr >= buf_end)		    fill_buffer ();		  parser_state_tos->tos--;		  parser_state_tos->com_col = start_column;		  return;		}	      if (format)		{		  /* Newline and null are the two characters which		     end an input line, so check here if we need to		     get the next line. */		  buf_ptr++;		  if (buf_ptr >= buf_end)		    fill_buffer ();		  /* If this is "\n\n", it's a paragraph break. */		  if (*buf_ptr == EOL || ! text_on_line)		    {		      paragraph_break = 1;		      goto end_line;		    }		  /* This is a single newline.  Transform it, and any		     following whitespace into a single blank. */		  line_break_ptr = e_com;		  *e_com++ = ' ';		  column++;		  while (*buf_ptr == TAB || *buf_ptr == ' ')		    buf_ptr++;		  if (buf_ptr >= buf_end)		    fill_buffer ();		  continue;		}	      else		/* We are printing this line "as is", so output it		   and continue on to the next line. */		goto end_line;	      break;	    case '*':	      /* Check if we've reached the end of the comment. */	      if (comment_type == comment)		{		  if (*(buf_ptr + 1) == '/')		    {		      /* If it's not a boxed comment, put some whitespace		         before the ending delimiter.  Otherwise, simply			 insert the delimiter. */		      if (! boxed_comment)			{			  if (text_on_line)			    {			      if (blankline_delims)				{				  *e_com = '\0';				  dump_line ();				  *e_com++ = ' ';				}			      else				/* Here I also tried some code to ensure				   that the ending delimiter didn't exceed				   max_col of formatted comments.  But it's				   not worth the hassle. */				if (*(e_com - 1) != ' ')				  *e_com++ = ' ';			    }			  else			    e_com = s_com + 1;			}		      *e_com++ = '*';		      *e_com++ = '/';		      *e_com = '\0';		      /* Skip any whitespace following the comment.  If			 there is only whitespace after it, print the line. */		      buf_ptr += 2;		      while (*buf_ptr == ' ' || *buf_ptr == TAB)			buf_ptr++;		      if (buf_ptr >= buf_end)			fill_buffer ();		      parser_state_tos->tos--;		      parser_state_tos->com_col = start_column;		      return;		    }		  /* If this star is on the second line of the		     comment in the same column as the star of the		     beginning delimiter, then consider it		     a boxed comment. */		  if (first_comment_line == com_lines - 1		      && e_com == s_com + line_preamble_length		      && current_column () == start_column + 1)		    {		      line_preamble = " ";		      line_preamble_length = 1;		      boxed_comment = 1;		      format = 0;		      blankline_delims = 0;		      *s_com = ' ';		      *(s_com + 1) = '*';		      e_com = s_com + 2;		      column++;		      break;		    }		}	      /* If it was not the end of the comment, drop through	         and insert the star on the line. */	    default:	      /* Some textual character. */	      text_on_line = e_com;	      *e_com++ = *buf_ptr;	      column++;	      break;	    }	  /* If we are formatting, check that we haven't exceeded the	     line length.  If we haven't set line_break_ptr, keep going. */	  if (format && column > right_margin && line_break_ptr)	    {	      if (line_break_ptr < e_com - 1)		{		  *line_break_ptr = '\0';		  save_ptr = line_break_ptr + 1;		  save_length = e_com - save_ptr;		  e_com = line_break_ptr;		  /* If we had to go past `right_margin' to print stuff out,		     extend `right_margin' out to this point. */		  if ((column - save_length) > right_margin)		    right_margin = column - save_length;		}	      else		*e_com = '\0';	      goto end_line;	    }	  buf_ptr++;	}    end_line:      /* Compress pure whitespace lines into newlines. */      if (! text_on_line	  && ! visible_preamble	  && ! (first_comment_line == com_lines))	e_com = s_com;      *e_com = '\0';      dump_line ();      /* If formatting (paragraph_break is only used for formatted	 comments) and user wants blank lines merged, kill all white	 space after the "\n\n" indicating a paragraph break. */      if (paragraph_break)	{	  if (merge_blank_comment_lines)	    while (*buf_ptr == EOL || *buf_ptr == ' ' || *buf_ptr == TAB)	      if (++buf_ptr >= buf_end)		fill_buffer ();	  paragraph_break = 0;	}      else	{	  /* If it was a paragraph break (`if' clause), we scanned ahead	     one character.  So, here in the `else' clause, advance buf_ptr. */	  buf_ptr++;	  if (buf_ptr >= buf_end)	    fill_buffer ();	}    begin_line:      /* Indent the line properly.  If it's a boxed comment, align with	 the '*' in the beginning slash-star and start inserting there.	 Otherwise, insert blanks for alignment, or a star if the	 user specified -sc. */      if (line_preamble)	{	  memcpy (e_com, line_preamble, line_preamble_length);	  e_com += line_preamble_length;	  column = start_column + line_preamble_length;	}      else	column = start_column;      line_break_ptr = 0;      /* If we have broken the line before the end for formatting,         copy the text after the break onto the beginning of this	 new comment line. */      if (save_ptr)	{	  while ((*save_ptr == ' ' || *save_ptr == TAB) && save_length)	    {	      save_ptr++;	      save_length--;	    }	  memcpy (e_com, save_ptr, save_length);	  text_on_line = e_com;	  e_com += save_length;	  /* We only break if formatting, in which cases there	     are no tabs, only spaces.*/	  column += save_length;	  save_ptr = 0;	}      else	{	  while (*buf_ptr == ' ' || *buf_ptr == TAB)	    buf_ptr++;	  if (buf_ptr >= buf_end)	    fill_buffer ();	  text_on_line = 0;	}    }}

⌨️ 快捷键说明

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