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