121972Sdist /*
235500Sbostic * Copyright (c) 1985 Sun Microsystems, Inc.
3*62040Sbostic * Copyright (c) 1980, 1993
4*62040Sbostic * The Regents of the University of California. All rights reserved.
533767Sbostic * All rights reserved.
633767Sbostic *
742688Sbostic * %sccs.include.redist.c%
821972Sdist */
98806Smckusick
1021972Sdist #ifndef lint
11*62040Sbostic static char sccsid[] = "@(#)pr_comment.c 8.1 (Berkeley) 06/06/93";
1233767Sbostic #endif /* not lint */
1321972Sdist
1446695Sbostic #include <stdio.h>
1546695Sbostic #include <stdlib.h>
1646695Sbostic #include "indent_globs.h"
1746695Sbostic
1833767Sbostic /*
1924457Smckusick * NAME:
2024457Smckusick * pr_comment
2124457Smckusick *
2224457Smckusick * FUNCTION:
2324457Smckusick * This routine takes care of scanning and printing comments.
2424457Smckusick *
2524457Smckusick * ALGORITHM:
2624457Smckusick * 1) Decide where the comment should be aligned, and if lines should
2724457Smckusick * be broken.
2824457Smckusick * 2) If lines should not be broken and filled, just copy up to end of
2924457Smckusick * comment.
3024457Smckusick * 3) If lines should be filled, then scan thru input_buffer copying
3124457Smckusick * characters to com_buf. Remember where the last blank, tab, or
3235500Sbostic * newline was. When line is filled, print up to last blank and
3324457Smckusick * continue copying.
3424457Smckusick *
3524457Smckusick * HISTORY:
3624457Smckusick * November 1976 D A Willcox of CAC Initial coding
3735500Sbostic * 12/6/76 D A Willcox of CAC Modification to handle
3824457Smckusick * UNIX-style comments
3924457Smckusick *
4024457Smckusick */
4124457Smckusick
428806Smckusick /*
4335500Sbostic * this routine processes comments. It makes an attempt to keep comments from
4435500Sbostic * going over the max line length. If a line is too long, it moves everything
4535500Sbostic * from the last blank to the next comment line. Blanks and tabs from the
4635500Sbostic * beginning of the input line are removed
4724457Smckusick */
488806Smckusick
498806Smckusick
pr_comment()5024457Smckusick pr_comment()
5124457Smckusick {
5224457Smckusick int now_col; /* column we are in now */
5324457Smckusick int adj_max_col; /* Adjusted max_col for when we decide to
5424457Smckusick * spill comments over the right margin */
5524457Smckusick char *last_bl; /* points to the last blank in the output
5624457Smckusick * buffer */
5724457Smckusick char *t_ptr; /* used for moving string */
5835500Sbostic int unix_comment; /* tri-state variable used to decide if it is
5935500Sbostic * a unix-style comment. 0 means only blanks
6035500Sbostic * since /*, 1 means regular style comment, 2
6135500Sbostic * means unix style comment */
6224457Smckusick int break_delim = comment_delimiter_on_blankline;
6335500Sbostic int l_just_saw_decl = ps.just_saw_decl;
6424457Smckusick /*
6535500Sbostic * int ps.last_nl = 0; /* true iff the last significant thing
6635500Sbostic * weve seen is a newline
6724457Smckusick */
6824457Smckusick int one_liner = 1; /* true iff this comment is a one-liner */
6924457Smckusick adj_max_col = max_col;
7024457Smckusick ps.just_saw_decl = 0;
7124457Smckusick last_bl = 0; /* no blanks found so far */
7235506Sbostic ps.box_com = false; /* at first, assume that we are not in
7335500Sbostic * a boxed comment or some other
7435500Sbostic * comment that should not be touched */
7524457Smckusick ++ps.out_coms; /* keep track of number of comments */
7635500Sbostic unix_comment = 1; /* set flag to let us figure out if there is a
7735500Sbostic * unix-style comment ** DISABLED: use 0 to
7835500Sbostic * reenable this hack! */
798806Smckusick
8024457Smckusick /* Figure where to align and how to treat the comment */
818806Smckusick
8235500Sbostic if (ps.col_1 && !format_col1_comments) { /* if comment starts in column
8335500Sbostic * 1 it should not be touched */
8435506Sbostic ps.box_com = true;
8524457Smckusick ps.com_col = 1;
8635500Sbostic }
8735500Sbostic else {
8824457Smckusick if (*buf_ptr == '-' || *buf_ptr == '*') {
8924457Smckusick ps.box_com = true; /* a comment with a '-' or '*' immediately
9024457Smckusick * after the /* is assumed to be a boxed
9124457Smckusick * comment */
9224457Smckusick break_delim = 0;
938806Smckusick }
9424457Smckusick if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) {
9524457Smckusick /* klg: check only if this line is blank */
9624457Smckusick /*
9735500Sbostic * If this (*and previous lines are*) blank, dont put comment way
9835500Sbostic * out at left
9924457Smckusick */
10024457Smckusick ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
10124457Smckusick adj_max_col = block_comment_max_col;
10224457Smckusick if (ps.com_col <= 1)
10324457Smckusick ps.com_col = 1 + !format_col1_comments;
10435500Sbostic }
10535500Sbostic else {
10624457Smckusick register target_col;
10724457Smckusick break_delim = 0;
10824457Smckusick if (s_code != e_code)
10924457Smckusick target_col = count_spaces(compute_code_target(), s_code);
11024457Smckusick else {
11124457Smckusick target_col = 1;
11224457Smckusick if (s_lab != e_lab)
11324457Smckusick target_col = count_spaces(compute_label_target(), s_lab);
11424457Smckusick }
11524457Smckusick ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? ps.decl_com_ind : ps.com_ind;
11624457Smckusick if (ps.com_col < target_col)
11724457Smckusick ps.com_col = ((target_col + 7) & ~7) + 1;
11824457Smckusick if (ps.com_col + 24 > adj_max_col)
11924457Smckusick adj_max_col = ps.com_col + 24;
1208806Smckusick }
1218806Smckusick }
12224457Smckusick if (ps.box_com) {
12324457Smckusick buf_ptr[-2] = 0;
12424457Smckusick ps.n_comment_delta = 1 - count_spaces(1, in_buffer);
12524457Smckusick buf_ptr[-2] = '/';
12635500Sbostic }
12735500Sbostic else {
12824457Smckusick ps.n_comment_delta = 0;
12924457Smckusick while (*buf_ptr == ' ' || *buf_ptr == '\t')
13024457Smckusick buf_ptr++;
13124457Smckusick }
13224457Smckusick ps.comment_delta = 0;
13324457Smckusick *e_com++ = '/'; /* put '/*' into buffer */
1348806Smckusick *e_com++ = '*';
13524457Smckusick if (*buf_ptr != ' ' && !ps.box_com)
1368806Smckusick *e_com++ = ' ';
1378806Smckusick
1388806Smckusick *e_com = '\0';
13935500Sbostic if (troff) {
14035500Sbostic now_col = 1;
14135500Sbostic adj_max_col = 80;
14235500Sbostic }
14335500Sbostic else
14435500Sbostic now_col = count_spaces(ps.com_col, s_com); /* figure what column we
14535500Sbostic * would be in if we
14635500Sbostic * printed the comment
14735500Sbostic * now */
1488806Smckusick
14924457Smckusick /* Start to copy the comment */
1508806Smckusick
15124457Smckusick while (1) { /* this loop will go until the comment is
15224457Smckusick * copied */
15324457Smckusick if (*buf_ptr > 040 && *buf_ptr != '*')
15424457Smckusick ps.last_nl = 0;
15540275Sbostic CHECK_SIZE_COM;
15624457Smckusick switch (*buf_ptr) { /* this checks for various spcl cases */
15735500Sbostic case 014: /* check for a form feed */
15835500Sbostic if (!ps.box_com) { /* in a text comment, break the line here */
15935500Sbostic ps.use_ff = true;
16035500Sbostic /* fix so dump_line uses a form feed */
16135500Sbostic dump_line();
16235500Sbostic last_bl = 0;
16335500Sbostic *e_com++ = ' ';
16435500Sbostic *e_com++ = '*';
16535500Sbostic *e_com++ = ' ';
16635500Sbostic while (*++buf_ptr == ' ' || *buf_ptr == '\t');
16735500Sbostic }
16835500Sbostic else {
16935500Sbostic if (++buf_ptr >= buf_end)
17035500Sbostic fill_buffer();
17135500Sbostic *e_com++ = 014;
17235500Sbostic }
17335500Sbostic break;
17435500Sbostic
17535500Sbostic case '\n':
17635500Sbostic if (had_eof) { /* check for unexpected eof */
17735500Sbostic printf("Unterminated comment\n");
17835500Sbostic *e_com = '\0';
17935500Sbostic dump_line();
18035500Sbostic return;
18135500Sbostic }
18235500Sbostic one_liner = 0;
18335500Sbostic if (ps.box_com || ps.last_nl) { /* if this is a boxed comment,
18435500Sbostic * we dont ignore the newline */
18535500Sbostic if (s_com == e_com) {
1868806Smckusick *e_com++ = ' ';
1878806Smckusick *e_com++ = ' ';
1888806Smckusick }
18935500Sbostic *e_com = '\0';
19035500Sbostic if (!ps.box_com && e_com - s_com > 3) {
19135500Sbostic if (break_delim == 1 && s_com[0] == '/'
19224457Smckusick && s_com[1] == '*' && s_com[2] == ' ') {
19335500Sbostic char *t = e_com;
19435500Sbostic break_delim = 2;
19535500Sbostic e_com = s_com + 2;
19635500Sbostic *e_com = 0;
19735500Sbostic if (blanklines_before_blockcomments)
19835500Sbostic prefix_blankline_requested = 1;
19924457Smckusick dump_line();
20035500Sbostic e_com = t;
20135500Sbostic s_com[0] = s_com[1] = s_com[2] = ' ';
2028806Smckusick }
20324457Smckusick dump_line();
20440275Sbostic CHECK_SIZE_COM;
20535500Sbostic *e_com++ = ' ';
20635500Sbostic *e_com++ = ' ';
20735500Sbostic }
20835500Sbostic dump_line();
20935500Sbostic now_col = ps.com_col;
21035500Sbostic }
21135500Sbostic else {
21224457Smckusick ps.last_nl = 1;
21335500Sbostic if (unix_comment != 1) { /* we not are in unix_style
21435500Sbostic * comment */
2158806Smckusick if (unix_comment == 0 && s_code == e_code) {
21624457Smckusick /*
21724457Smckusick * if it is a UNIX-style comment, ignore the
21824457Smckusick * requirement that previous line be blank for
21935500Sbostic * unindention
22024457Smckusick */
22124457Smckusick ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
22224457Smckusick if (ps.com_col <= 1)
22324457Smckusick ps.com_col = 2;
2248806Smckusick }
22535500Sbostic unix_comment = 2; /* permanently remember that we are in
22635500Sbostic * this type of comment */
22724457Smckusick dump_line();
2288806Smckusick ++line_no;
22924457Smckusick now_col = ps.com_col;
2308806Smckusick *e_com++ = ' ';
23124457Smckusick /*
23235500Sbostic * fix so that the star at the start of the line will line
23335500Sbostic * up
23424457Smckusick */
23524457Smckusick do /* flush leading white space */
2368806Smckusick if (++buf_ptr >= buf_end)
23724457Smckusick fill_buffer();
2388806Smckusick while (*buf_ptr == ' ' || *buf_ptr == '\t');
2398806Smckusick break;
2408806Smckusick }
2418806Smckusick if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t')
2428806Smckusick last_bl = e_com - 1;
24324457Smckusick /*
24435500Sbostic * if there was a space at the end of the last line, remember
24535500Sbostic * where it was
24624457Smckusick */
24724457Smckusick else { /* otherwise, insert one */
2488806Smckusick last_bl = e_com;
24940275Sbostic CHECK_SIZE_COM;
2508806Smckusick *e_com++ = ' ';
2518806Smckusick ++now_col;
2528806Smckusick }
25335500Sbostic }
25435500Sbostic ++line_no; /* keep track of input line number */
25535500Sbostic if (!ps.box_com) {
25635500Sbostic int nstar = 1;
25735500Sbostic do { /* flush any blanks and/or tabs at start of
25835500Sbostic * next line */
25935500Sbostic if (++buf_ptr >= buf_end)
26035500Sbostic fill_buffer();
26135500Sbostic if (*buf_ptr == '*' && --nstar >= 0) {
26224457Smckusick if (++buf_ptr >= buf_end)
26324457Smckusick fill_buffer();
26435500Sbostic if (*buf_ptr == '/')
26535500Sbostic goto end_of_comment;
26635500Sbostic }
26735500Sbostic } while (*buf_ptr == ' ' || *buf_ptr == '\t');
26835500Sbostic }
26935500Sbostic else if (++buf_ptr >= buf_end)
27035500Sbostic fill_buffer();
27135500Sbostic break; /* end of case for newline */
2728806Smckusick
27335500Sbostic case '*': /* must check for possibility of being at end
27435500Sbostic * of comment */
27535500Sbostic if (++buf_ptr >= buf_end) /* get to next char after * */
27635500Sbostic fill_buffer();
2778806Smckusick
27835500Sbostic if (unix_comment == 0) /* set flag to show we are not in
27924457Smckusick * unix-style comment */
28035500Sbostic unix_comment = 1;
2818806Smckusick
28235500Sbostic if (*buf_ptr == '/') { /* it is the end!!! */
28335500Sbostic end_of_comment:
28435500Sbostic if (++buf_ptr >= buf_end)
28535500Sbostic fill_buffer();
2868806Smckusick
28735500Sbostic if (*(e_com - 1) != ' ' && !ps.box_com) { /* insure blank before
28824457Smckusick * end */
28935500Sbostic *e_com++ = ' ';
29035500Sbostic ++now_col;
29135500Sbostic }
29235500Sbostic if (break_delim == 1 && !one_liner && s_com[0] == '/'
29324457Smckusick && s_com[1] == '*' && s_com[2] == ' ') {
29435500Sbostic char *t = e_com;
29535500Sbostic break_delim = 2;
29635500Sbostic e_com = s_com + 2;
29735500Sbostic *e_com = 0;
29835500Sbostic if (blanklines_before_blockcomments)
29935500Sbostic prefix_blankline_requested = 1;
30035500Sbostic dump_line();
30135500Sbostic e_com = t;
30235500Sbostic s_com[0] = s_com[1] = s_com[2] = ' ';
30335500Sbostic }
30435500Sbostic if (break_delim == 2 && e_com > s_com + 3
30524457Smckusick /* now_col > adj_max_col - 2 && !ps.box_com */ ) {
3068806Smckusick *e_com = '\0';
30735500Sbostic dump_line();
30835500Sbostic now_col = ps.com_col;
3098806Smckusick }
31040275Sbostic CHECK_SIZE_COM;
31135500Sbostic *e_com++ = '*';
31235500Sbostic *e_com++ = '/';
31335500Sbostic *e_com = '\0';
31435500Sbostic ps.just_saw_decl = l_just_saw_decl;
31535500Sbostic return;
31635500Sbostic }
31735500Sbostic else { /* handle isolated '*' */
31835500Sbostic *e_com++ = '*';
31935500Sbostic ++now_col;
32035500Sbostic }
32135500Sbostic break;
32235500Sbostic default: /* we have a random char */
32335500Sbostic if (unix_comment == 0 && *buf_ptr != ' ' && *buf_ptr != '\t')
32435500Sbostic unix_comment = 1; /* we are not in unix-style comment */
3258806Smckusick
32635500Sbostic *e_com = *buf_ptr++;
32735500Sbostic if (buf_ptr >= buf_end)
32835500Sbostic fill_buffer();
3298806Smckusick
33035500Sbostic if (*e_com == '\t') /* keep track of column */
33135500Sbostic now_col = ((now_col - 1) & tabmask) + tabsize + 1;
33235500Sbostic else if (*e_com == '\b') /* this is a backspace */
33335500Sbostic --now_col;
33435500Sbostic else
33535500Sbostic ++now_col;
3368806Smckusick
33735500Sbostic if (*e_com == ' ' || *e_com == '\t')
33835500Sbostic last_bl = e_com;
33935500Sbostic /* remember we saw a blank */
3408806Smckusick
34135500Sbostic ++e_com;
34235500Sbostic if (now_col > adj_max_col && !ps.box_com && unix_comment == 1 && e_com[-1] > ' ') {
34335500Sbostic /*
34435500Sbostic * the comment is too long, it must be broken up
34535500Sbostic */
34635500Sbostic if (break_delim == 1 && s_com[0] == '/'
34724457Smckusick && s_com[1] == '*' && s_com[2] == ' ') {
34835500Sbostic char *t = e_com;
34935500Sbostic break_delim = 2;
35035500Sbostic e_com = s_com + 2;
35135500Sbostic *e_com = 0;
35235500Sbostic if (blanklines_before_blockcomments)
35335500Sbostic prefix_blankline_requested = 1;
35424457Smckusick dump_line();
35535500Sbostic e_com = t;
35635500Sbostic s_com[0] = s_com[1] = s_com[2] = ' ';
35735500Sbostic }
35835500Sbostic if (last_bl == 0) { /* we have seen no blanks */
35935500Sbostic last_bl = e_com; /* fake it */
3608806Smckusick *e_com++ = ' ';
36135500Sbostic }
36235500Sbostic *e_com = '\0'; /* print what we have */
36335500Sbostic *last_bl = '\0';
36435500Sbostic while (last_bl > s_com && last_bl[-1] < 040)
36535500Sbostic *--last_bl = 0;
36635500Sbostic e_com = last_bl;
36735500Sbostic dump_line();
3688806Smckusick
36935500Sbostic *e_com++ = ' '; /* add blanks for continuation */
37035500Sbostic *e_com++ = ' ';
37135500Sbostic *e_com++ = ' ';
37235500Sbostic
37335500Sbostic t_ptr = last_bl + 1;
37435500Sbostic last_bl = 0;
37535500Sbostic if (t_ptr >= e_com) {
37635500Sbostic while (*t_ptr == ' ' || *t_ptr == '\t')
37735500Sbostic t_ptr++;
37835500Sbostic while (*t_ptr != '\0') { /* move unprinted part of
37935500Sbostic * comment down in buffer */
38035500Sbostic if (*t_ptr == ' ' || *t_ptr == '\t')
38135500Sbostic last_bl = e_com;
38235500Sbostic *e_com++ = *t_ptr++;
3838806Smckusick }
38435500Sbostic }
38535500Sbostic *e_com = '\0';
38635500Sbostic now_col = count_spaces(ps.com_col, s_com); /* recompute current
38724457Smckusick * position */
38835500Sbostic }
38935500Sbostic break;
39024457Smckusick }
39124457Smckusick }
39224457Smckusick }
393