1331147Seadler/*- 21590Srgrimes * Copyright (c) 1985 Sun Microsystems, Inc. 31590Srgrimes * Copyright (c) 1980, 1993 41590Srgrimes * The Regents of the University of California. All rights reserved. 51590Srgrimes * All rights reserved. 61590Srgrimes * 71590Srgrimes * Redistribution and use in source and binary forms, with or without 81590Srgrimes * modification, are permitted provided that the following conditions 91590Srgrimes * are met: 101590Srgrimes * 1. Redistributions of source code must retain the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer. 121590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 131590Srgrimes * notice, this list of conditions and the following disclaimer in the 141590Srgrimes * documentation and/or other materials provided with the distribution. 151590Srgrimes * 3. All advertising materials mentioning features or use of this software 161590Srgrimes * must display the following acknowledgement: 171590Srgrimes * This product includes software developed by the University of 181590Srgrimes * California, Berkeley and its contributors. 191590Srgrimes * 4. Neither the name of the University nor the names of its contributors 201590Srgrimes * may be used to endorse or promote products derived from this software 211590Srgrimes * without specific prior written permission. 221590Srgrimes * 231590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 241590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 251590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 261590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 271590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 281590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 291590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 301590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 311590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 321590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 331590Srgrimes * SUCH DAMAGE. 341590Srgrimes */ 3599112Sobrien 36116390Scharnier#if 0 3799112Sobrien#ifndef lint 381590Srgrimesstatic char sccsid[] = "@(#)pr_comment.c 8.1 (Berkeley) 6/6/93"; 39116390Scharnier#endif /* not lint */ 4099112Sobrien#endif 41116390Scharnier 4299112Sobrien#include <sys/cdefs.h> 4399112Sobrien__FBSDID("$FreeBSD: stable/11/usr.bin/indent/pr_comment.c 331722 2018-03-29 02:50:57Z eadler $"); 4499112Sobrien 45116390Scharnier#include <err.h> 461590Srgrimes#include <stdio.h> 471590Srgrimes#include <stdlib.h> 48331147Seadler#include <string.h> 491590Srgrimes#include "indent_globs.h" 50331147Seadler#include "indent_codes.h" 5185632Sschweikh#include "indent.h" 521590Srgrimes/* 531590Srgrimes * NAME: 541590Srgrimes * pr_comment 551590Srgrimes * 561590Srgrimes * FUNCTION: 571590Srgrimes * This routine takes care of scanning and printing comments. 581590Srgrimes * 591590Srgrimes * ALGORITHM: 601590Srgrimes * 1) Decide where the comment should be aligned, and if lines should 611590Srgrimes * be broken. 621590Srgrimes * 2) If lines should not be broken and filled, just copy up to end of 631590Srgrimes * comment. 641590Srgrimes * 3) If lines should be filled, then scan thru input_buffer copying 651590Srgrimes * characters to com_buf. Remember where the last blank, tab, or 661590Srgrimes * newline was. When line is filled, print up to last blank and 671590Srgrimes * continue copying. 681590Srgrimes * 691590Srgrimes * HISTORY: 701590Srgrimes * November 1976 D A Willcox of CAC Initial coding 711590Srgrimes * 12/6/76 D A Willcox of CAC Modification to handle 721590Srgrimes * UNIX-style comments 731590Srgrimes * 741590Srgrimes */ 751590Srgrimes 761590Srgrimes/* 771590Srgrimes * this routine processes comments. It makes an attempt to keep comments from 781590Srgrimes * going over the max line length. If a line is too long, it moves everything 791590Srgrimes * from the last blank to the next comment line. Blanks and tabs from the 801590Srgrimes * beginning of the input line are removed 811590Srgrimes */ 821590Srgrimes 8385632Sschweikhvoid 8485632Sschweikhpr_comment(void) 851590Srgrimes{ 861590Srgrimes int now_col; /* column we are in now */ 871590Srgrimes int adj_max_col; /* Adjusted max_col for when we decide to 881590Srgrimes * spill comments over the right margin */ 891590Srgrimes char *last_bl; /* points to the last blank in the output 901590Srgrimes * buffer */ 911590Srgrimes char *t_ptr; /* used for moving string */ 921590Srgrimes int break_delim = comment_delimiter_on_blankline; 931590Srgrimes int l_just_saw_decl = ps.just_saw_decl; 941590Srgrimes adj_max_col = max_col; 951590Srgrimes ps.just_saw_decl = 0; 96331147Seadler last_bl = NULL; /* no blanks found so far */ 971590Srgrimes ps.box_com = false; /* at first, assume that we are not in 981590Srgrimes * a boxed comment or some other 991590Srgrimes * comment that should not be touched */ 1001590Srgrimes ++ps.out_coms; /* keep track of number of comments */ 1011590Srgrimes 1021590Srgrimes /* Figure where to align and how to treat the comment */ 1031590Srgrimes 1041590Srgrimes if (ps.col_1 && !format_col1_comments) { /* if comment starts in column 1051590Srgrimes * 1 it should not be touched */ 1061590Srgrimes ps.box_com = true; 107331147Seadler break_delim = false; 1081590Srgrimes ps.com_col = 1; 1091590Srgrimes } 1101590Srgrimes else { 11169795Sobrien if (*buf_ptr == '-' || *buf_ptr == '*' || 11269795Sobrien (*buf_ptr == '\n' && !format_block_comments)) { 11369795Sobrien ps.box_com = true; /* A comment with a '-' or '*' immediately 11485632Sschweikh * after the /+* is assumed to be a boxed 11569795Sobrien * comment. A comment with a newline 11685632Sschweikh * immediately after the /+* is assumed to 11769795Sobrien * be a block comment and is treated as a 11869795Sobrien * box comment unless format_block_comments 11969795Sobrien * is nonzero (the default). */ 120331147Seadler break_delim = false; 1211590Srgrimes } 1221590Srgrimes if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) { 1231590Srgrimes /* klg: check only if this line is blank */ 1241590Srgrimes /* 1251590Srgrimes * If this (*and previous lines are*) blank, dont put comment way 1261590Srgrimes * out at left 1271590Srgrimes */ 1281590Srgrimes ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1; 1291590Srgrimes adj_max_col = block_comment_max_col; 1301590Srgrimes if (ps.com_col <= 1) 1311590Srgrimes ps.com_col = 1 + !format_col1_comments; 1321590Srgrimes } 1331590Srgrimes else { 13498771Sjmallett int target_col; 135331147Seadler break_delim = false; 1361590Srgrimes if (s_code != e_code) 1371590Srgrimes target_col = count_spaces(compute_code_target(), s_code); 1381590Srgrimes else { 1391590Srgrimes target_col = 1; 1401590Srgrimes if (s_lab != e_lab) 1411590Srgrimes target_col = count_spaces(compute_label_target(), s_lab); 1421590Srgrimes } 1431590Srgrimes ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? ps.decl_com_ind : ps.com_ind; 144331147Seadler if (ps.com_col <= target_col) 1451590Srgrimes ps.com_col = ((target_col + 7) & ~7) + 1; 1461590Srgrimes if (ps.com_col + 24 > adj_max_col) 1471590Srgrimes adj_max_col = ps.com_col + 24; 1481590Srgrimes } 1491590Srgrimes } 1501590Srgrimes if (ps.box_com) { 151331147Seadler /* 152331147Seadler * Find out how much indentation there was originally, because that 153331147Seadler * much will have to be ignored by pad_output() in dump_line(). This 154331147Seadler * is a box comment, so nothing changes -- not even indentation. 155331147Seadler * 156331147Seadler * The comment we're about to read usually comes from in_buffer, 157331147Seadler * unless it has been copied into save_com. 158331147Seadler */ 159331147Seadler char *start = buf_ptr >= save_com && buf_ptr < save_com + sc_size ? bp_save : buf_ptr; 160331147Seadler ps.n_comment_delta = 1 - count_spaces_until(1, in_buffer, start - 2); 1611590Srgrimes } 1621590Srgrimes else { 1631590Srgrimes ps.n_comment_delta = 0; 1641590Srgrimes while (*buf_ptr == ' ' || *buf_ptr == '\t') 1651590Srgrimes buf_ptr++; 1661590Srgrimes } 1671590Srgrimes ps.comment_delta = 0; 16885632Sschweikh *e_com++ = '/'; /* put '/' followed by '*' into buffer */ 1691590Srgrimes *e_com++ = '*'; 1701590Srgrimes if (*buf_ptr != ' ' && !ps.box_com) 1711590Srgrimes *e_com++ = ' '; 1721590Srgrimes 173331147Seadler /* 174331147Seadler * Don't put a break delimiter if this is a one-liner that won't wrap. 175331147Seadler */ 176331147Seadler if (break_delim) 177331147Seadler for (t_ptr = buf_ptr; *t_ptr != '\0' && *t_ptr != '\n'; t_ptr++) { 178331147Seadler if (t_ptr >= buf_end) 179331147Seadler fill_buffer(); 180331147Seadler if (t_ptr[0] == '*' && t_ptr[1] == '/') { 181331147Seadler if (adj_max_col >= count_spaces_until(ps.com_col, buf_ptr, t_ptr + 2)) 182331147Seadler break_delim = false; 183331147Seadler break; 184331147Seadler } 185331147Seadler } 186331147Seadler 187331147Seadler if (break_delim) { 188331147Seadler char *t = e_com; 189331147Seadler e_com = s_com + 2; 190331147Seadler *e_com = 0; 191331147Seadler if (blanklines_before_blockcomments && ps.last_token != lbrace) 192331147Seadler prefix_blankline_requested = 1; 193331147Seadler dump_line(); 194331147Seadler e_com = s_com = t; 195331147Seadler if (!ps.box_com && star_comment_cont) 196331147Seadler *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; 1971590Srgrimes } 1981590Srgrimes 199331147Seadler if (troff) 200331147Seadler adj_max_col = 80; 201331147Seadler 2021590Srgrimes /* Start to copy the comment */ 2031590Srgrimes 2041590Srgrimes while (1) { /* this loop will go until the comment is 2051590Srgrimes * copied */ 2061590Srgrimes CHECK_SIZE_COM; 2071590Srgrimes switch (*buf_ptr) { /* this checks for various spcl cases */ 2081590Srgrimes case 014: /* check for a form feed */ 2091590Srgrimes if (!ps.box_com) { /* in a text comment, break the line here */ 2101590Srgrimes ps.use_ff = true; 2111590Srgrimes /* fix so dump_line uses a form feed */ 2121590Srgrimes dump_line(); 213331147Seadler last_bl = NULL; 214331147Seadler if (!ps.box_com && star_comment_cont) 215331147Seadler *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; 216331147Seadler while (*++buf_ptr == ' ' || *buf_ptr == '\t') 217331147Seadler ; 2181590Srgrimes } 2191590Srgrimes else { 2201590Srgrimes if (++buf_ptr >= buf_end) 2211590Srgrimes fill_buffer(); 2221590Srgrimes *e_com++ = 014; 2231590Srgrimes } 2241590Srgrimes break; 2251590Srgrimes 2261590Srgrimes case '\n': 2271590Srgrimes if (had_eof) { /* check for unexpected eof */ 2281590Srgrimes printf("Unterminated comment\n"); 2291590Srgrimes dump_line(); 2301590Srgrimes return; 2311590Srgrimes } 232331147Seadler last_bl = NULL; 2331590Srgrimes if (ps.box_com || ps.last_nl) { /* if this is a boxed comment, 2341590Srgrimes * we dont ignore the newline */ 235331147Seadler if (s_com == e_com) 2361590Srgrimes *e_com++ = ' '; 2371590Srgrimes if (!ps.box_com && e_com - s_com > 3) { 2381590Srgrimes dump_line(); 239331147Seadler if (star_comment_cont) 240331147Seadler *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; 2411590Srgrimes } 2421590Srgrimes dump_line(); 243331147Seadler if (!ps.box_com && star_comment_cont) 244331147Seadler *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; 2451590Srgrimes } 2461590Srgrimes else { 2471590Srgrimes ps.last_nl = 1; 2481590Srgrimes if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t') 2491590Srgrimes last_bl = e_com - 1; 2501590Srgrimes /* 2511590Srgrimes * if there was a space at the end of the last line, remember 2521590Srgrimes * where it was 2531590Srgrimes */ 2541590Srgrimes else { /* otherwise, insert one */ 2551590Srgrimes last_bl = e_com; 2561590Srgrimes CHECK_SIZE_COM; 2571590Srgrimes *e_com++ = ' '; 2581590Srgrimes } 2591590Srgrimes } 2601590Srgrimes ++line_no; /* keep track of input line number */ 2611590Srgrimes if (!ps.box_com) { 2621590Srgrimes int nstar = 1; 2631590Srgrimes do { /* flush any blanks and/or tabs at start of 2641590Srgrimes * next line */ 2651590Srgrimes if (++buf_ptr >= buf_end) 2661590Srgrimes fill_buffer(); 2671590Srgrimes if (*buf_ptr == '*' && --nstar >= 0) { 2681590Srgrimes if (++buf_ptr >= buf_end) 2691590Srgrimes fill_buffer(); 2701590Srgrimes if (*buf_ptr == '/') 2711590Srgrimes goto end_of_comment; 2721590Srgrimes } 2731590Srgrimes } while (*buf_ptr == ' ' || *buf_ptr == '\t'); 2741590Srgrimes } 2751590Srgrimes else if (++buf_ptr >= buf_end) 2761590Srgrimes fill_buffer(); 2771590Srgrimes break; /* end of case for newline */ 2781590Srgrimes 2791590Srgrimes case '*': /* must check for possibility of being at end 2801590Srgrimes * of comment */ 2811590Srgrimes if (++buf_ptr >= buf_end) /* get to next char after * */ 2821590Srgrimes fill_buffer(); 2831590Srgrimes 2841590Srgrimes if (*buf_ptr == '/') { /* it is the end!!! */ 2851590Srgrimes end_of_comment: 2861590Srgrimes if (++buf_ptr >= buf_end) 2871590Srgrimes fill_buffer(); 288331147Seadler CHECK_SIZE_COM; 289331147Seadler if (break_delim) { 290331147Seadler if (e_com > s_com + 3) { 291331147Seadler dump_line(); 292331147Seadler } 293331147Seadler else 294331147Seadler s_com = e_com; 2951590Srgrimes *e_com++ = ' '; 2961590Srgrimes } 297331147Seadler if (e_com[-1] != ' ' && e_com[-1] != '\t' && !ps.box_com) 298331147Seadler *e_com++ = ' '; /* ensure blank before end */ 299331147Seadler *e_com++ = '*', *e_com++ = '/', *e_com = '\0'; 3001590Srgrimes ps.just_saw_decl = l_just_saw_decl; 3011590Srgrimes return; 3021590Srgrimes } 303331147Seadler else /* handle isolated '*' */ 3041590Srgrimes *e_com++ = '*'; 3051590Srgrimes break; 3061590Srgrimes default: /* we have a random char */ 307331147Seadler now_col = count_spaces_until(ps.com_col, s_com, e_com); 308331147Seadler do { 309331147Seadler *e_com = *buf_ptr++; 310331147Seadler if (buf_ptr >= buf_end) 311331147Seadler fill_buffer(); 312331147Seadler if (*e_com == ' ' || *e_com == '\t') 313331147Seadler last_bl = e_com; /* remember we saw a blank */ 314331147Seadler ++e_com; 315331147Seadler now_col++; 316331147Seadler } while (!memchr("*\n\r\b\t", *buf_ptr, 6) && 317331147Seadler (now_col <= adj_max_col || !last_bl)); 318331147Seadler ps.last_nl = false; 319331147Seadler if (now_col > adj_max_col && !ps.box_com && e_com[-1] > ' ') { 3201590Srgrimes /* 3211590Srgrimes * the comment is too long, it must be broken up 3221590Srgrimes */ 323331147Seadler if (last_bl == NULL) { 3241590Srgrimes dump_line(); 325331147Seadler if (!ps.box_com && star_comment_cont) 326331147Seadler *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; 327331147Seadler break; 3281590Srgrimes } 329331147Seadler *e_com = '\0'; 3301590Srgrimes e_com = last_bl; 3311590Srgrimes dump_line(); 332331147Seadler if (!ps.box_com && star_comment_cont) 333331147Seadler *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; 334331147Seadler for (t_ptr = last_bl + 1; *t_ptr == ' ' || *t_ptr == '\t'; 335331147Seadler t_ptr++) 336331147Seadler ; 337331147Seadler last_bl = NULL; 338331147Seadler while (*t_ptr != '\0') { 339331147Seadler if (*t_ptr == ' ' || *t_ptr == '\t') 340331147Seadler last_bl = e_com; 341331147Seadler *e_com++ = *t_ptr++; 342331147Seadler } 3431590Srgrimes } 3441590Srgrimes break; 3451590Srgrimes } 3461590Srgrimes } 3471590Srgrimes} 348