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