Home | History | Annotate | Line # | Download | only in indent
pr_comment.c revision 1.9
      1 /*	$NetBSD: pr_comment.c,v 1.9 2003/08/07 11:14:09 agc Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1980, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. Neither the name of the University nor the names of its contributors
     16  *    may be used to endorse or promote products derived from this software
     17  *    without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29  * SUCH DAMAGE.
     30  */
     31 
     32 /*
     33  * Copyright (c) 1976 Board of Trustees of the University of Illinois.
     34  * Copyright (c) 1985 Sun Microsystems, Inc.
     35  * All rights reserved.
     36  *
     37  * Redistribution and use in source and binary forms, with or without
     38  * modification, are permitted provided that the following conditions
     39  * are met:
     40  * 1. Redistributions of source code must retain the above copyright
     41  *    notice, this list of conditions and the following disclaimer.
     42  * 2. Redistributions in binary form must reproduce the above copyright
     43  *    notice, this list of conditions and the following disclaimer in the
     44  *    documentation and/or other materials provided with the distribution.
     45  * 3. All advertising materials mentioning features or use of this software
     46  *    must display the following acknowledgement:
     47  *	This product includes software developed by the University of
     48  *	California, Berkeley and its contributors.
     49  * 4. Neither the name of the University nor the names of its contributors
     50  *    may be used to endorse or promote products derived from this software
     51  *    without specific prior written permission.
     52  *
     53  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     54  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     56  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     57  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     58  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     59  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     60  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     61  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     62  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     63  * SUCH DAMAGE.
     64  */
     65 
     66 #include <sys/cdefs.h>
     67 #ifndef lint
     68 #if 0
     69 static char sccsid[] = "@(#)pr_comment.c	8.1 (Berkeley) 6/6/93";
     70 #else
     71 __RCSID("$NetBSD: pr_comment.c,v 1.9 2003/08/07 11:14:09 agc Exp $");
     72 #endif
     73 #endif				/* not lint */
     74 
     75 #include <stdio.h>
     76 #include <stdlib.h>
     77 #include <ctype.h>
     78 #include "indent_globs.h"
     79 
     80 /*
     81  * NAME:
     82  *	pr_comment
     83  *
     84  * FUNCTION:
     85  *	This routine takes care of scanning and printing comments.
     86  *
     87  * ALGORITHM:
     88  *	1) Decide where the comment should be aligned, and if lines should
     89  *	   be broken.
     90  *	2) If lines should not be broken and filled, just copy up to end of
     91  *	   comment.
     92  *	3) If lines should be filled, then scan thru input_buffer copying
     93  *	   characters to com_buf.  Remember where the last blank, tab, or
     94  *	   newline was.  When line is filled, print up to last blank and
     95  *	   continue copying.
     96  *
     97  * HISTORY:
     98  *	November 1976	D A Willcox of CAC	Initial coding
     99  *	12/6/76		D A Willcox of CAC	Modification to handle
    100  *						UNIX-style comments
    101  *
    102  */
    103 
    105 /*
    106  * this routine processes comments.  It makes an attempt to keep comments from
    107  * going over the max line length.  If a line is too long, it moves everything
    108  * from the last blank to the next comment line.  Blanks and tabs from the
    109  * beginning of the input line are removed
    110  */
    111 
    112 
    113 void
    114 pr_comment(void)
    115 {
    116 	int     now_col;	/* column we are in now */
    117 	int     adj_max_col;	/* Adjusted max_col for when we decide to
    118 				 * spill comments over the right margin */
    119 	char   *last_bl;	/* points to the last blank in the output
    120 				 * buffer */
    121 	char   *t_ptr;		/* used for moving string */
    122 	int     unix_comment;	/* tri-state variable used to decide if it is
    123 				 * a unix-style comment. 0 means only blanks
    124 				 * since start, 1 means regular style comment,
    125 				 * 2 means unix style comment */
    126 	int     break_delim = comment_delimiter_on_blankline;
    127 	int     l_just_saw_decl = ps.just_saw_decl;
    128 	/*
    129          * int         ps.last_nl = 0;	/ * true iff the last significant thing
    130          * weve seen is a newline
    131          */
    132 	int     one_liner = 1;	/* true iff this comment is a one-liner */
    133 	adj_max_col = max_col;
    134 	ps.just_saw_decl = 0;
    135 	last_bl = 0;		/* no blanks found so far */
    136 	ps.box_com = false;	/* at first, assume that we are not in a boxed
    137 				 * comment or some other comment that should
    138 				 * not be touched */
    139 	++ps.out_coms;		/* keep track of number of comments */
    140 	unix_comment = 1;	/* set flag to let us figure out if there is a
    141 				 * unix-style comment ** DISABLED: use 0 to
    142 				 * reenable this hack! */
    143 
    144 	/* Figure where to align and how to treat the comment */
    145 
    146 	if (ps.col_1 && !format_col1_comments) {	/* if comment starts in
    147 							 * column 1 it should
    148 							 * not be touched */
    149 		ps.box_com = true;
    150 		ps.com_col = 1;
    151 	} else {
    152 		if (*buf_ptr == '-' || *buf_ptr == '*' || *buf_ptr == '\n') {
    153 			ps.box_com = true;	/* a comment with a '-', '*'
    154 						 * or newline immediately
    155 						 * after the start comment is
    156 						 * assumed to be a boxed
    157 						 * comment */
    158 			break_delim = 0;
    159 		}
    160 		if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) {
    161 			/* klg: check only if this line is blank */
    162 			/*
    163 		         * If this (*and previous lines are*) blank, dont put comment way
    164 		         * out at left
    165 		         */
    166 			ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
    167 			adj_max_col = block_comment_max_col;
    168 			if (ps.com_col <= 1)
    169 				ps.com_col = 1 + !format_col1_comments;
    170 		} else {
    171 			int     target_col;
    172 			break_delim = 0;
    173 			if (s_code != e_code)
    174 				target_col = count_spaces(compute_code_target(), s_code);
    175 			else {
    176 				target_col = 1;
    177 				if (s_lab != e_lab)
    178 					target_col = count_spaces(compute_label_target(), s_lab);
    179 			}
    180 			ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? ps.decl_com_ind : ps.com_ind;
    181 			if (ps.com_col < target_col)
    182 				ps.com_col = ((target_col + 7) & ~7) + 1;
    183 			if (ps.com_col + 24 > adj_max_col)
    184 				adj_max_col = ps.com_col + 24;
    185 		}
    186 	}
    187 	if (ps.box_com) {
    188 		buf_ptr[-2] = 0;
    189 		ps.n_comment_delta = 1 - count_spaces(1, in_buffer);
    190 		buf_ptr[-2] = '/';
    191 	} else {
    192 		ps.n_comment_delta = 0;
    193 		while (*buf_ptr == ' ' || *buf_ptr == '\t')
    194 			buf_ptr++;
    195 	}
    196 	ps.comment_delta = 0;
    197 	*e_com++ = '/';		/* put '/' + '*' into buffer */
    198 	*e_com++ = '*';
    199 	if (*buf_ptr != ' ' && !ps.box_com)
    200 		*e_com++ = ' ';
    201 
    202 	*e_com = '\0';
    203 	if (troff) {
    204 		now_col = 1;
    205 		adj_max_col = 80;
    206 	} else
    207 		now_col = count_spaces(ps.com_col, s_com);	/* figure what column we
    208 								 * would be in if we
    209 								 * printed the comment
    210 								 * now */
    211 
    212 	/* Start to copy the comment */
    213 
    214 	while (1) {		/* this loop will go until the comment is
    215 				 * copied */
    216 		if (!iscntrl((unsigned char)*buf_ptr) && *buf_ptr != '*')
    217 			ps.last_nl = 0;
    218 		CHECK_SIZE_COM;
    219 		switch (*buf_ptr) {	/* this checks for various spcl cases */
    220 		case 014:	/* check for a form feed */
    221 			if (!ps.box_com) {	/* in a text comment, break
    222 						 * the line here */
    223 				ps.use_ff = true;
    224 				/* fix so dump_line uses a form feed */
    225 				dump_line();
    226 				last_bl = 0;
    227 				*e_com++ = ' ';
    228 				*e_com++ = '*';
    229 				*e_com++ = ' ';
    230 				while (*++buf_ptr == ' ' || *buf_ptr == '\t');
    231 			} else {
    232 				if (++buf_ptr >= buf_end)
    233 					fill_buffer();
    234 				*e_com++ = 014;
    235 			}
    236 			break;
    237 
    238 		case '\n':
    239 			if (had_eof) {	/* check for unexpected eof */
    240 				printf("Unterminated comment\n");
    241 				*e_com = '\0';
    242 				dump_line();
    243 				return;
    244 			}
    245 			one_liner = 0;
    246 			if (ps.box_com || ps.last_nl) {	/* if this is a boxed
    247 							 * comment, we dont
    248 							 * ignore the newline */
    249 				if (s_com == e_com) {
    250 					*e_com++ = ' ';
    251 					*e_com++ = ' ';
    252 				}
    253 				*e_com = '\0';
    254 				if (!ps.box_com && e_com - s_com > 3) {
    255 					if (break_delim == 1 && s_com[0] == '/'
    256 					    && s_com[1] == '*' && s_com[2] == ' ') {
    257 						char   *t = e_com;
    258 						break_delim = 2;
    259 						e_com = s_com + 2;
    260 						*e_com = 0;
    261 						if (blanklines_before_blockcomments)
    262 							prefix_blankline_requested = 1;
    263 						dump_line();
    264 						e_com = t;
    265 						s_com[0] = s_com[1] = s_com[2] = ' ';
    266 					}
    267 					dump_line();
    268 					CHECK_SIZE_COM;
    269 					*e_com++ = ' ';
    270 					*e_com++ = ' ';
    271 				}
    272 				dump_line();
    273 				now_col = ps.com_col;
    274 			} else {
    275 				ps.last_nl = 1;
    276 				if (unix_comment != 1) {	/* we not are in
    277 								 * unix_style comment */
    278 					if (unix_comment == 0 && s_code == e_code) {
    279 						/*
    280 						 * if it is a UNIX-style comment, ignore the
    281 						 * requirement that previous line be blank for
    282 						 * unindention
    283 						 */
    284 						ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
    285 						if (ps.com_col <= 1)
    286 							ps.com_col = 2;
    287 					}
    288 					unix_comment = 2;	/* permanently remember
    289 								 * that we are in this
    290 								 * type of comment */
    291 					dump_line();
    292 					++line_no;
    293 					now_col = ps.com_col;
    294 					*e_com++ = ' ';
    295 					/*
    296 				         * fix so that the star at the start of the line will line
    297 				         * up
    298 				         */
    299 					do	/* flush leading white space */
    300 						if (++buf_ptr >= buf_end)
    301 							fill_buffer();
    302 					while (*buf_ptr == ' ' || *buf_ptr == '\t');
    303 					break;
    304 				}
    305 				if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t')
    306 					last_bl = e_com - 1;
    307 				/*
    308 				 * if there was a space at the end of the last line, remember
    309 				 * where it was
    310 				 */
    311 				else {	/* otherwise, insert one */
    312 					last_bl = e_com;
    313 					CHECK_SIZE_COM;
    314 					*e_com++ = ' ';
    315 					++now_col;
    316 				}
    317 			}
    318 			++line_no;	/* keep track of input line number */
    319 			if (!ps.box_com) {
    320 				int     nstar = 1;
    321 				do {	/* flush any blanks and/or tabs at
    322 					 * start of next line */
    323 					if (++buf_ptr >= buf_end)
    324 						fill_buffer();
    325 					if (*buf_ptr == '*' && --nstar >= 0) {
    326 						if (++buf_ptr >= buf_end)
    327 							fill_buffer();
    328 						if (*buf_ptr == '/')
    329 							goto end_of_comment;
    330 					}
    331 				} while (*buf_ptr == ' ' || *buf_ptr == '\t');
    332 			} else
    333 				if (++buf_ptr >= buf_end)
    334 					fill_buffer();
    335 			break;	/* end of case for newline */
    336 
    337 		case '*':	/* must check for possibility of being at end
    338 				 * of comment */
    339 			if (++buf_ptr >= buf_end)	/* get to next char
    340 							 * after * */
    341 				fill_buffer();
    342 
    343 			if (unix_comment == 0)	/* set flag to show we are not
    344 						 * in unix-style comment */
    345 				unix_comment = 1;
    346 
    347 			if (*buf_ptr == '/') {	/* it is the end!!! */
    348 		end_of_comment:
    349 				if (++buf_ptr >= buf_end)
    350 					fill_buffer();
    351 
    352 				if (*(e_com - 1) != ' ' && !ps.box_com) {	/* insure blank before
    353 										 * end */
    354 					*e_com++ = ' ';
    355 					++now_col;
    356 				}
    357 				if (break_delim == 1 && !one_liner && s_com[0] == '/'
    358 				    && s_com[1] == '*' && s_com[2] == ' ') {
    359 					char   *t = e_com;
    360 					break_delim = 2;
    361 					e_com = s_com + 2;
    362 					*e_com = 0;
    363 					if (blanklines_before_blockcomments)
    364 						prefix_blankline_requested = 1;
    365 					dump_line();
    366 					e_com = t;
    367 					s_com[0] = s_com[1] = s_com[2] = ' ';
    368 				}
    369 				if (break_delim == 2 && e_com > s_com + 3
    370 				     /* now_col > adj_max_col - 2 && !ps.box_com */ ) {
    371 					*e_com = '\0';
    372 					dump_line();
    373 					now_col = ps.com_col;
    374 				}
    375 				CHECK_SIZE_COM;
    376 				*e_com++ = '*';
    377 				*e_com++ = '/';
    378 				*e_com = '\0';
    379 				ps.just_saw_decl = l_just_saw_decl;
    380 				return;
    381 			} else {/* handle isolated '*' */
    382 				*e_com++ = '*';
    383 				++now_col;
    384 			}
    385 			break;
    386 		default:	/* we have a random char */
    387 			if (unix_comment == 0 && *buf_ptr != ' ' && *buf_ptr != '\t')
    388 				unix_comment = 1;	/* we are not in
    389 							 * unix-style comment */
    390 
    391 			*e_com = *buf_ptr++;
    392 			if (buf_ptr >= buf_end)
    393 				fill_buffer();
    394 
    395 			if (*e_com == '\t')	/* keep track of column */
    396 				now_col = ((now_col - 1) & tabmask) + tabsize + 1;
    397 			else
    398 				if (*e_com == '\b')	/* this is a backspace */
    399 					--now_col;
    400 				else
    401 					++now_col;
    402 
    403 			if (*e_com == ' ' || *e_com == '\t')
    404 				last_bl = e_com;
    405 			/* remember we saw a blank */
    406 
    407 			++e_com;
    408 			if (now_col > adj_max_col && !ps.box_com && unix_comment == 1
    409 				&& !iscntrl((unsigned char)e_com[-1])
    410 				&& !isblank((unsigned char)e_com[-1])) {
    411 				/*
    412 				 * the comment is too long, it must be broken up
    413 				 */
    414 				if (break_delim == 1 && s_com[0] == '/'
    415 				    && s_com[1] == '*' && s_com[2] == ' ') {
    416 					char   *t = e_com;
    417 					break_delim = 2;
    418 					e_com = s_com + 2;
    419 					*e_com = 0;
    420 					if (blanklines_before_blockcomments)
    421 						prefix_blankline_requested = 1;
    422 					dump_line();
    423 					e_com = t;
    424 					s_com[0] = s_com[1] = s_com[2] = ' ';
    425 				}
    426 				if (last_bl == 0) {	/* we have seen no
    427 							 * blanks */
    428 					last_bl = e_com;	/* fake it */
    429 					*e_com++ = ' ';
    430 				}
    431 				*e_com = '\0';	/* print what we have */
    432 				*last_bl = '\0';
    433 				while (last_bl > s_com && iscntrl((unsigned char)last_bl[-1]) )
    434 					*--last_bl = 0;
    435 				e_com = last_bl;
    436 				dump_line();
    437 
    438 				*e_com++ = ' ';	/* add blanks for continuation */
    439 				*e_com++ = ' ';
    440 				*e_com++ = ' ';
    441 
    442 				t_ptr = last_bl + 1;
    443 				last_bl = 0;
    444 				if (t_ptr >= e_com) {
    445 					while (*t_ptr == ' ' || *t_ptr == '\t')
    446 						t_ptr++;
    447 					while (*t_ptr != '\0') {	/* move unprinted part
    448 									 * of comment down in
    449 									 * buffer */
    450 						if (*t_ptr == ' ' || *t_ptr == '\t')
    451 							last_bl = e_com;
    452 						*e_com++ = *t_ptr++;
    453 					}
    454 				}
    455 				*e_com = '\0';
    456 				now_col = count_spaces(ps.com_col, s_com);	/* recompute current
    457 										 * position */
    458 			}
    459 			break;
    460 		}
    461 	}
    462 }
    463