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