Age Owner Branch data TLA Line data Source code
1 : : /*-
2 : : * Copyright (c) 1985 Sun Microsystems, Inc.
3 : : * Copyright (c) 1980, 1993
4 : : * The Regents of the University of California. All rights reserved.
5 : : * 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 : : #if 0
33 : : #ifndef lint
34 : : static char sccsid[] = "@(#)pr_comment.c 8.1 (Berkeley) 6/6/93";
35 : : #endif /* not lint */
36 : : #endif
37 : :
38 : : #include "c.h"
39 : :
40 : : #include <err.h>
41 : : #include <stdio.h>
42 : : #include <stdlib.h>
43 : : #include <string.h>
44 : : #include "indent_globs.h"
45 : : #include "indent_codes.h"
46 : : #include "indent.h"
47 : : /*
48 : : * NAME:
49 : : * pr_comment
50 : : *
51 : : * FUNCTION:
52 : : * This routine takes care of scanning and printing comments.
53 : : *
54 : : * ALGORITHM:
55 : : * 1) Decide where the comment should be aligned, and if lines should
56 : : * be broken.
57 : : * 2) If lines should not be broken and filled, just copy up to end of
58 : : * comment.
59 : : * 3) If lines should be filled, then scan thru input_buffer copying
60 : : * characters to com_buf. Remember where the last blank, tab, or
61 : : * newline was. When line is filled, print up to last blank and
62 : : * continue copying.
63 : : *
64 : : * HISTORY:
65 : : * November 1976 D A Willcox of CAC Initial coding
66 : : * 12/6/76 D A Willcox of CAC Modification to handle
67 : : * UNIX-style comments
68 : : *
69 : : */
70 : :
71 : : /*
72 : : * this routine processes comments. It makes an attempt to keep comments from
73 : : * going over the max line length. If a line is too long, it moves everything
74 : : * from the last blank to the next comment line. Blanks and tabs from the
75 : : * beginning of the input line are removed
76 : : */
77 : :
78 : : void
427 tgl@sss.pgh.pa.us 79 :CBC 58 : pr_comment(void)
80 : : {
81 : : int now_col; /* column we are in now */
82 : : int adj_max_col; /* Adjusted max_col for when we decide to
83 : : * spill comments over the right margin */
84 : : char *last_bl; /* points to the last blank in the output
85 : : * buffer */
86 : : char *t_ptr; /* used for moving string */
87 : 58 : int break_delim = comment_delimiter_on_blankline;
88 : 58 : int l_just_saw_decl = ps.just_saw_decl;
89 : 58 : adj_max_col = max_col;
90 : 58 : ps.just_saw_decl = 0;
91 : 58 : last_bl = NULL; /* no blanks found so far */
92 : 58 : ps.box_com = false; /* at first, assume that we are not in
93 : : * a boxed comment or some other
94 : : * comment that should not be touched */
95 : 58 : ++ps.out_coms; /* keep track of number of comments */
96 : :
97 : : /* Figure where to align and how to treat the comment */
98 : :
99 [ + + - + ]: 58 : if (ps.col_1 && !format_col1_comments) { /* if comment starts in column
100 : : * 1 it should not be touched */
427 tgl@sss.pgh.pa.us 101 :UBC 0 : ps.box_com = true;
102 : 0 : break_delim = false;
103 : 0 : ps.com_col = 1;
104 : : }
105 : : else {
427 tgl@sss.pgh.pa.us 106 [ + + + - ]:CBC 58 : if (*buf_ptr == '-' || *buf_ptr == '*' ||
107 [ + + - + ]: 54 : (*buf_ptr == '\n' && !format_block_comments)) {
108 : 4 : ps.box_com = true; /* A comment with a '-' or '*' immediately
109 : : * after the /+* is assumed to be a boxed
110 : : * comment. A comment with a newline
111 : : * immediately after the /+* is assumed to
112 : : * be a block comment and is treated as a
113 : : * box comment unless format_block_comments
114 : : * is nonzero (the default). */
115 : 4 : break_delim = false;
116 : : }
117 [ + + + + ]: 58 : if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) {
118 : : /* klg: check only if this line is blank */
119 : : /*
120 : : * If this (*and previous lines are*) blank, dont put comment way
121 : : * out at left
122 : : */
123 : 36 : ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
124 : 36 : adj_max_col = block_comment_max_col;
125 [ + + ]: 36 : if (ps.com_col <= 1)
126 [ - + ]: 24 : ps.com_col = 1 + !format_col1_comments;
127 : : }
128 : : else {
129 : : int target_col;
130 : 22 : break_delim = false;
131 [ + + ]: 22 : if (s_code != e_code)
132 : 16 : target_col = count_spaces(compute_code_target(), s_code);
133 : : else {
134 : 6 : target_col = 1;
135 [ + - ]: 6 : if (s_lab != e_lab)
136 : 6 : target_col = count_spaces(compute_label_target(), s_lab);
137 : : }
138 [ + + + + ]: 22 : if (s_lab != e_lab && s_lab[1] == 'e' &&
139 [ + + ]: 3 : (strncmp(s_lab, "#endif", 6) == 0 ||
140 [ + + ]: 2 : strncmp(s_lab, "#else", 5) == 0))
141 : 2 : ps.com_col = else_endif_com_ind <= target_col
142 [ + - ]: 2 : ? target_col + 1 : else_endif_com_ind;
143 : : else
144 [ + + ]: 31 : ps.com_col = ps.decl_on_line || ps.ind_level == 0
145 [ + + ]: 31 : ? ps.decl_com_ind : ps.com_ind;
146 [ + + ]: 22 : if (ps.com_col <= target_col)
147 : 5 : ps.com_col = tabsize * (1 + (target_col - 1) / tabsize) + 1;
148 [ + + ]: 22 : if (ps.com_col + 24 > adj_max_col)
149 : 1 : adj_max_col = ps.com_col + 24;
150 : : }
151 : : }
152 [ + + ]: 58 : if (ps.box_com) {
153 : : /*
154 : : * Find out how much indentation there was originally, because that
155 : : * much will have to be ignored by pad_output() in dump_line(). This
156 : : * is a box comment, so nothing changes -- not even indentation.
157 : : *
158 : : * The comment we're about to read usually comes from in_buffer,
159 : : * unless it has been copied into save_com.
160 : : */
161 : : char *start;
162 : :
163 [ + + ]: 4 : start = buf_ptr >= save_com && buf_ptr < save_com + sc_size ?
164 [ + - ]: 8 : sc_buf : in_buffer;
165 : 4 : ps.n_comment_delta = 1 - count_spaces_until(1, start, buf_ptr - 2);
166 : : }
167 : : else {
168 : 54 : ps.n_comment_delta = 0;
169 [ + + - + ]: 105 : while (*buf_ptr == ' ' || *buf_ptr == '\t')
170 : 51 : buf_ptr++;
171 : : }
172 : 58 : ps.comment_delta = 0;
173 : 58 : *e_com++ = '/'; /* put '/' followed by '*' into buffer */
174 : 58 : *e_com++ = '*';
175 [ + - + + ]: 58 : if (*buf_ptr != ' ' && !ps.box_com)
176 : 54 : *e_com++ = ' ';
177 : :
178 : : /*
179 : : * Don't put a break delimiter if this is a one-liner that won't wrap.
180 : : */
181 [ + + ]: 58 : if (break_delim)
182 [ + - + + ]: 632 : for (t_ptr = buf_ptr; *t_ptr != '\0' && *t_ptr != '\n'; t_ptr++) {
183 [ - + ]: 629 : if (t_ptr >= buf_end)
427 tgl@sss.pgh.pa.us 184 :UBC 0 : fill_buffer();
427 tgl@sss.pgh.pa.us 185 [ + + + - ]:CBC 629 : if (t_ptr[0] == '*' && t_ptr[1] == '/') {
186 [ + + ]: 31 : if (adj_max_col >= count_spaces_until(ps.com_col, buf_ptr, t_ptr + 2))
187 : 30 : break_delim = false;
188 : 31 : break;
189 : : }
190 : : }
191 : :
192 [ + + ]: 58 : if (break_delim) {
193 : 4 : char *t = e_com;
194 : 4 : e_com = s_com + 2;
195 : 4 : *e_com = 0;
196 [ + - - + ]: 4 : if (blanklines_before_blockcomments && ps.last_token != lbrace)
427 tgl@sss.pgh.pa.us 197 :UBC 0 : prefix_blankline_requested = 1;
427 tgl@sss.pgh.pa.us 198 :CBC 4 : dump_line();
199 : 4 : e_com = s_com = t;
200 [ + - + - ]: 4 : if (!ps.box_com && star_comment_cont)
201 : 4 : *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
202 : : }
203 : :
204 : : /* Start to copy the comment */
205 : :
206 : : while (1) { /* this loop will go until the comment is
207 : : * copied */
208 [ - + + + ]: 213 : switch (*buf_ptr) { /* this checks for various spcl cases */
427 tgl@sss.pgh.pa.us 209 :UBC 0 : case 014: /* check for a form feed */
210 [ # # # # : 0 : CHECK_SIZE_COM(3);
# # # # ]
211 [ # # ]: 0 : if (!ps.box_com) { /* in a text comment, break the line here */
212 : 0 : ps.use_ff = true;
213 : : /* fix so dump_line uses a form feed */
214 : 0 : dump_line();
215 : 0 : last_bl = NULL;
216 [ # # # # ]: 0 : if (!ps.box_com && star_comment_cont)
217 : 0 : *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
218 [ # # # # ]: 0 : while (*++buf_ptr == ' ' || *buf_ptr == '\t')
219 : : ;
220 : : }
221 : : else {
222 [ # # ]: 0 : if (++buf_ptr >= buf_end)
223 : 0 : fill_buffer();
224 : 0 : *e_com++ = 014;
225 : : }
226 : 0 : break;
227 : :
427 tgl@sss.pgh.pa.us 228 :CBC 20 : case '\n':
229 [ - + ]: 20 : if (had_eof) { /* check for unexpected eof */
427 tgl@sss.pgh.pa.us 230 :UBC 0 : printf("Unterminated comment\n");
231 : 0 : dump_line();
232 : 0 : return;
233 : : }
427 tgl@sss.pgh.pa.us 234 :CBC 20 : last_bl = NULL;
235 [ - + - - : 20 : CHECK_SIZE_COM(4);
- - - - ]
236 [ + + + + ]: 20 : if (ps.box_com || ps.last_nl) { /* if this is a boxed comment,
237 : : * we dont ignore the newline */
238 [ - + ]: 11 : if (s_com == e_com)
427 tgl@sss.pgh.pa.us 239 :UBC 0 : *e_com++ = ' ';
427 tgl@sss.pgh.pa.us 240 [ + + + - ]:CBC 11 : if (!ps.box_com && e_com - s_com > 3) {
241 : 3 : dump_line();
242 [ + - ]: 3 : if (star_comment_cont)
243 : 3 : *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
244 : : }
245 : 11 : dump_line();
246 [ + + + - ]: 11 : if (!ps.box_com && star_comment_cont)
247 : 3 : *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
248 : : }
249 : : else {
250 : 9 : ps.last_nl = 1;
251 [ + + - + ]: 9 : if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t')
252 : 4 : last_bl = e_com - 1;
253 : : /*
254 : : * if there was a space at the end of the last line, remember
255 : : * where it was
256 : : */
257 : : else { /* otherwise, insert one */
258 : 5 : last_bl = e_com;
259 : 5 : *e_com++ = ' ';
260 : : }
261 : : }
262 : 20 : ++line_no; /* keep track of input line number */
263 [ + + ]: 20 : if (!ps.box_com) {
264 : 12 : int nstar = 1;
265 : : do { /* flush any blanks and/or tabs at start of
266 : : * next line */
267 [ + + ]: 44 : if (++buf_ptr >= buf_end)
268 : 12 : fill_buffer();
269 [ + + + + ]: 44 : if (*buf_ptr == '*' && --nstar >= 0) {
270 [ - + ]: 12 : if (++buf_ptr >= buf_end)
427 tgl@sss.pgh.pa.us 271 :UBC 0 : fill_buffer();
427 tgl@sss.pgh.pa.us 272 [ + + ]:CBC 12 : if (*buf_ptr == '/')
273 : 3 : goto end_of_comment;
274 : : }
275 [ + + + + ]: 41 : } while (*buf_ptr == ' ' || *buf_ptr == '\t');
276 : : }
277 [ + + ]: 8 : else if (++buf_ptr >= buf_end)
278 : 4 : fill_buffer();
279 : 17 : break; /* end of case for newline */
280 : :
281 : 93 : case '*': /* must check for possibility of being at end
282 : : * of comment */
283 [ - + ]: 93 : if (++buf_ptr >= buf_end) /* get to next char after * */
427 tgl@sss.pgh.pa.us 284 :UBC 0 : fill_buffer();
427 tgl@sss.pgh.pa.us 285 [ - + - - :CBC 93 : CHECK_SIZE_COM(4);
- - - - ]
286 [ + + ]: 93 : if (*buf_ptr == '/') { /* it is the end!!! */
287 : 55 : end_of_comment:
288 [ - + ]: 58 : if (++buf_ptr >= buf_end)
427 tgl@sss.pgh.pa.us 289 :UBC 0 : fill_buffer();
427 tgl@sss.pgh.pa.us 290 [ + + ]:CBC 58 : if (break_delim) {
291 [ + + ]: 4 : if (e_com > s_com + 3) {
292 : 3 : dump_line();
293 : : }
294 : : else
295 : 1 : s_com = e_com;
296 : 4 : *e_com++ = ' ';
297 : : }
298 [ + + - + : 58 : if (e_com[-1] != ' ' && e_com[-1] != '\t' && !ps.box_com)
- - ]
427 tgl@sss.pgh.pa.us 299 :UBC 0 : *e_com++ = ' '; /* ensure blank before end */
427 tgl@sss.pgh.pa.us 300 :CBC 58 : *e_com++ = '*', *e_com++ = '/', *e_com = '\0';
301 : 58 : ps.just_saw_decl = l_just_saw_decl;
302 : 58 : return;
303 : : }
304 : : else /* handle isolated '*' */
305 : 38 : *e_com++ = '*';
306 : 38 : break;
307 : 100 : default: /* we have a random char */
308 : 100 : now_col = count_spaces_until(ps.com_col, s_com, e_com);
309 : : do {
310 [ - + - - : 1281 : CHECK_SIZE_COM(1);
- - - - ]
311 : 1281 : *e_com = *buf_ptr++;
312 [ - + ]: 1281 : if (buf_ptr >= buf_end)
427 tgl@sss.pgh.pa.us 313 :UBC 0 : fill_buffer();
427 tgl@sss.pgh.pa.us 314 [ + + + + ]:CBC 1281 : if (*e_com == ' ' || *e_com == '\t')
315 : 244 : last_bl = e_com; /* remember we saw a blank */
316 : 1281 : ++e_com;
317 : 1281 : now_col++;
318 [ + + + + ]: 1281 : } while (!memchr("*\n\r\b\t", *buf_ptr, 6) &&
319 [ + + ]: 55 : (now_col <= adj_max_col || !last_bl));
320 : 100 : ps.last_nl = false;
321 [ + + + - : 100 : if (now_col > adj_max_col && !ps.box_com && e_com[-1] > ' ') {
+ - ]
322 : : /*
323 : : * the comment is too long, it must be broken up
324 : : */
325 [ + + ]: 4 : if (last_bl == NULL) {
326 : 1 : dump_line();
327 [ + - + - ]: 1 : if (!ps.box_com && star_comment_cont)
328 : 1 : *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
329 : 1 : break;
330 : : }
331 : 3 : *e_com = '\0';
332 : 3 : e_com = last_bl;
333 : 3 : dump_line();
334 [ + - + - ]: 3 : if (!ps.box_com && star_comment_cont)
335 : 3 : *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
336 [ - + - + ]: 3 : for (t_ptr = last_bl + 1; *t_ptr == ' ' || *t_ptr == '\t';
427 tgl@sss.pgh.pa.us 337 :UBC 0 : t_ptr++)
338 : : ;
427 tgl@sss.pgh.pa.us 339 :CBC 3 : last_bl = NULL;
340 : : /*
341 : : * t_ptr will be somewhere between e_com (dump_line() reset)
342 : : * and l_com. So it's safe to copy byte by byte from t_ptr
343 : : * to e_com without any CHECK_SIZE_COM().
344 : : */
345 [ + + ]: 7 : while (*t_ptr != '\0') {
346 [ + - - + ]: 4 : if (*t_ptr == ' ' || *t_ptr == '\t')
427 tgl@sss.pgh.pa.us 347 :UBC 0 : last_bl = e_com;
427 tgl@sss.pgh.pa.us 348 :CBC 4 : *e_com++ = *t_ptr++;
349 : : }
350 : : }
351 : 99 : break;
352 : : }
353 : : }
354 : : }
|