121972Sdist /* 235500Sbostic * Copyright (c) 1985 Sun Microsystems, Inc. 335500Sbostic * Copyright (c) 1980 The Regents of the University of California. 433767Sbostic * Copyright (c) 1976 Board of Trustees of the University of Illinois. 533767Sbostic * All rights reserved. 633767Sbostic * 733767Sbostic * Redistribution and use in source and binary forms are permitted 834885Sbostic * provided that the above copyright notice and this paragraph are 934885Sbostic * duplicated in all such forms and that any documentation, 1034885Sbostic * advertising materials, and other materials related to such 1134885Sbostic * distribution and use acknowledge that the software was developed 1235500Sbostic * by the University of California, Berkeley, the University of Illinois, 1335500Sbostic * Urbana, and Sun Microsystems, Inc. The name of either University 1435500Sbostic * or Sun Microsystems may not be used to endorse or promote products 1535500Sbostic * derived from this software without specific prior written permission. 1634885Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1734885Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1834885Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1921972Sdist */ 208806Smckusick 2121972Sdist #ifndef lint 22*35506Sbostic static char sccsid[] = "@(#)pr_comment.c 5.9 (Berkeley) 09/15/88"; 2333767Sbostic #endif /* not lint */ 2421972Sdist 2533767Sbostic /* 2624457Smckusick * NAME: 2724457Smckusick * pr_comment 2824457Smckusick * 2924457Smckusick * FUNCTION: 3024457Smckusick * This routine takes care of scanning and printing comments. 3124457Smckusick * 3224457Smckusick * ALGORITHM: 3324457Smckusick * 1) Decide where the comment should be aligned, and if lines should 3424457Smckusick * be broken. 3524457Smckusick * 2) If lines should not be broken and filled, just copy up to end of 3624457Smckusick * comment. 3724457Smckusick * 3) If lines should be filled, then scan thru input_buffer copying 3824457Smckusick * characters to com_buf. Remember where the last blank, tab, or 3935500Sbostic * newline was. When line is filled, print up to last blank and 4024457Smckusick * continue copying. 4124457Smckusick * 4224457Smckusick * HISTORY: 4324457Smckusick * November 1976 D A Willcox of CAC Initial coding 4435500Sbostic * 12/6/76 D A Willcox of CAC Modification to handle 4524457Smckusick * UNIX-style comments 4624457Smckusick * 4724457Smckusick */ 4824457Smckusick 498806Smckusick /* 5035500Sbostic * this routine processes comments. It makes an attempt to keep comments from 5135500Sbostic * going over the max line length. If a line is too long, it moves everything 5235500Sbostic * from the last blank to the next comment line. Blanks and tabs from the 5335500Sbostic * beginning of the input line are removed 5424457Smckusick */ 558806Smckusick 568806Smckusick 5735501Sbostic #include "indent_globs.h" 588806Smckusick 5935500Sbostic 6024457Smckusick pr_comment() 6124457Smckusick { 6224457Smckusick int now_col; /* column we are in now */ 6324457Smckusick int adj_max_col; /* Adjusted max_col for when we decide to 6424457Smckusick * spill comments over the right margin */ 6524457Smckusick char *last_bl; /* points to the last blank in the output 6624457Smckusick * buffer */ 6724457Smckusick char *t_ptr; /* used for moving string */ 6835500Sbostic int unix_comment; /* tri-state variable used to decide if it is 6935500Sbostic * a unix-style comment. 0 means only blanks 7035500Sbostic * since /*, 1 means regular style comment, 2 7135500Sbostic * means unix style comment */ 7224457Smckusick int break_delim = comment_delimiter_on_blankline; 7335500Sbostic int l_just_saw_decl = ps.just_saw_decl; 7424457Smckusick /* 7535500Sbostic * int ps.last_nl = 0; /* true iff the last significant thing 7635500Sbostic * weve seen is a newline 7724457Smckusick */ 7824457Smckusick int one_liner = 1; /* true iff this comment is a one-liner */ 7924457Smckusick adj_max_col = max_col; 8024457Smckusick ps.just_saw_decl = 0; 8124457Smckusick last_bl = 0; /* no blanks found so far */ 82*35506Sbostic ps.box_com = false; /* at first, assume that we are not in 8335500Sbostic * a boxed comment or some other 8435500Sbostic * comment that should not be touched */ 8524457Smckusick ++ps.out_coms; /* keep track of number of comments */ 8635500Sbostic unix_comment = 1; /* set flag to let us figure out if there is a 8735500Sbostic * unix-style comment ** DISABLED: use 0 to 8835500Sbostic * reenable this hack! */ 898806Smckusick 9024457Smckusick /* Figure where to align and how to treat the comment */ 918806Smckusick 9235500Sbostic if (ps.col_1 && !format_col1_comments) { /* if comment starts in column 9335500Sbostic * 1 it should not be touched */ 94*35506Sbostic ps.box_com = true; 9524457Smckusick ps.com_col = 1; 9635500Sbostic } 9735500Sbostic else { 9824457Smckusick if (*buf_ptr == '-' || *buf_ptr == '*') { 9924457Smckusick ps.box_com = true; /* a comment with a '-' or '*' immediately 10024457Smckusick * after the /* is assumed to be a boxed 10124457Smckusick * comment */ 10224457Smckusick break_delim = 0; 1038806Smckusick } 10424457Smckusick if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) { 10524457Smckusick /* klg: check only if this line is blank */ 10624457Smckusick /* 10735500Sbostic * If this (*and previous lines are*) blank, dont put comment way 10835500Sbostic * out at left 10924457Smckusick */ 11024457Smckusick ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1; 11124457Smckusick adj_max_col = block_comment_max_col; 11224457Smckusick if (ps.com_col <= 1) 11324457Smckusick ps.com_col = 1 + !format_col1_comments; 11435500Sbostic } 11535500Sbostic else { 11624457Smckusick register target_col; 11724457Smckusick break_delim = 0; 11824457Smckusick if (s_code != e_code) 11924457Smckusick target_col = count_spaces(compute_code_target(), s_code); 12024457Smckusick else { 12124457Smckusick target_col = 1; 12224457Smckusick if (s_lab != e_lab) 12324457Smckusick target_col = count_spaces(compute_label_target(), s_lab); 12424457Smckusick } 12524457Smckusick ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? ps.decl_com_ind : ps.com_ind; 12624457Smckusick if (ps.com_col < target_col) 12724457Smckusick ps.com_col = ((target_col + 7) & ~7) + 1; 12824457Smckusick if (ps.com_col + 24 > adj_max_col) 12924457Smckusick adj_max_col = ps.com_col + 24; 1308806Smckusick } 1318806Smckusick } 13224457Smckusick if (ps.box_com) { 13324457Smckusick buf_ptr[-2] = 0; 13424457Smckusick ps.n_comment_delta = 1 - count_spaces(1, in_buffer); 13524457Smckusick buf_ptr[-2] = '/'; 13635500Sbostic } 13735500Sbostic else { 13824457Smckusick ps.n_comment_delta = 0; 13924457Smckusick while (*buf_ptr == ' ' || *buf_ptr == '\t') 14024457Smckusick buf_ptr++; 14124457Smckusick } 14224457Smckusick ps.comment_delta = 0; 14324457Smckusick *e_com++ = '/'; /* put '/*' into buffer */ 1448806Smckusick *e_com++ = '*'; 14524457Smckusick if (*buf_ptr != ' ' && !ps.box_com) 1468806Smckusick *e_com++ = ' '; 1478806Smckusick 1488806Smckusick *e_com = '\0'; 14935500Sbostic if (troff) { 15035500Sbostic now_col = 1; 15135500Sbostic adj_max_col = 80; 15235500Sbostic } 15335500Sbostic else 15435500Sbostic now_col = count_spaces(ps.com_col, s_com); /* figure what column we 15535500Sbostic * would be in if we 15635500Sbostic * printed the comment 15735500Sbostic * now */ 1588806Smckusick 15924457Smckusick /* Start to copy the comment */ 1608806Smckusick 16124457Smckusick while (1) { /* this loop will go until the comment is 16224457Smckusick * copied */ 16324457Smckusick if (*buf_ptr > 040 && *buf_ptr != '*') 16424457Smckusick ps.last_nl = 0; 16535500Sbostic check_size(com); 16624457Smckusick switch (*buf_ptr) { /* this checks for various spcl cases */ 16735500Sbostic case 014: /* check for a form feed */ 16835500Sbostic if (!ps.box_com) { /* in a text comment, break the line here */ 16935500Sbostic ps.use_ff = true; 17035500Sbostic /* fix so dump_line uses a form feed */ 17135500Sbostic dump_line(); 17235500Sbostic last_bl = 0; 17335500Sbostic *e_com++ = ' '; 17435500Sbostic *e_com++ = '*'; 17535500Sbostic *e_com++ = ' '; 17635500Sbostic while (*++buf_ptr == ' ' || *buf_ptr == '\t'); 17735500Sbostic } 17835500Sbostic else { 17935500Sbostic if (++buf_ptr >= buf_end) 18035500Sbostic fill_buffer(); 18135500Sbostic *e_com++ = 014; 18235500Sbostic } 18335500Sbostic break; 18435500Sbostic 18535500Sbostic case '\n': 18635500Sbostic if (had_eof) { /* check for unexpected eof */ 18735500Sbostic printf("Unterminated comment\n"); 18835500Sbostic *e_com = '\0'; 18935500Sbostic dump_line(); 19035500Sbostic return; 19135500Sbostic } 19235500Sbostic one_liner = 0; 19335500Sbostic if (ps.box_com || ps.last_nl) { /* if this is a boxed comment, 19435500Sbostic * we dont ignore the newline */ 19535500Sbostic if (s_com == e_com) { 1968806Smckusick *e_com++ = ' '; 1978806Smckusick *e_com++ = ' '; 1988806Smckusick } 19935500Sbostic *e_com = '\0'; 20035500Sbostic if (!ps.box_com && e_com - s_com > 3) { 20135500Sbostic if (break_delim == 1 && s_com[0] == '/' 20224457Smckusick && s_com[1] == '*' && s_com[2] == ' ') { 20335500Sbostic char *t = e_com; 20435500Sbostic break_delim = 2; 20535500Sbostic e_com = s_com + 2; 20635500Sbostic *e_com = 0; 20735500Sbostic if (blanklines_before_blockcomments) 20835500Sbostic prefix_blankline_requested = 1; 20924457Smckusick dump_line(); 21035500Sbostic e_com = t; 21135500Sbostic s_com[0] = s_com[1] = s_com[2] = ' '; 2128806Smckusick } 21324457Smckusick dump_line(); 21435500Sbostic check_size(com); 21535500Sbostic *e_com++ = ' '; 21635500Sbostic *e_com++ = ' '; 21735500Sbostic } 21835500Sbostic dump_line(); 21935500Sbostic now_col = ps.com_col; 22035500Sbostic } 22135500Sbostic else { 22224457Smckusick ps.last_nl = 1; 22335500Sbostic if (unix_comment != 1) { /* we not are in unix_style 22435500Sbostic * comment */ 2258806Smckusick if (unix_comment == 0 && s_code == e_code) { 22624457Smckusick /* 22724457Smckusick * if it is a UNIX-style comment, ignore the 22824457Smckusick * requirement that previous line be blank for 22935500Sbostic * unindention 23024457Smckusick */ 23124457Smckusick ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1; 23224457Smckusick if (ps.com_col <= 1) 23324457Smckusick ps.com_col = 2; 2348806Smckusick } 23535500Sbostic unix_comment = 2; /* permanently remember that we are in 23635500Sbostic * this type of comment */ 23724457Smckusick dump_line(); 2388806Smckusick ++line_no; 23924457Smckusick now_col = ps.com_col; 2408806Smckusick *e_com++ = ' '; 24124457Smckusick /* 24235500Sbostic * fix so that the star at the start of the line will line 24335500Sbostic * up 24424457Smckusick */ 24524457Smckusick do /* flush leading white space */ 2468806Smckusick if (++buf_ptr >= buf_end) 24724457Smckusick fill_buffer(); 2488806Smckusick while (*buf_ptr == ' ' || *buf_ptr == '\t'); 2498806Smckusick break; 2508806Smckusick } 2518806Smckusick if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t') 2528806Smckusick last_bl = e_com - 1; 25324457Smckusick /* 25435500Sbostic * if there was a space at the end of the last line, remember 25535500Sbostic * where it was 25624457Smckusick */ 25724457Smckusick else { /* otherwise, insert one */ 2588806Smckusick last_bl = e_com; 25935500Sbostic check_size(com); 2608806Smckusick *e_com++ = ' '; 2618806Smckusick ++now_col; 2628806Smckusick } 26335500Sbostic } 26435500Sbostic ++line_no; /* keep track of input line number */ 26535500Sbostic if (!ps.box_com) { 26635500Sbostic int nstar = 1; 26735500Sbostic do { /* flush any blanks and/or tabs at start of 26835500Sbostic * next line */ 26935500Sbostic if (++buf_ptr >= buf_end) 27035500Sbostic fill_buffer(); 27135500Sbostic if (*buf_ptr == '*' && --nstar >= 0) { 27224457Smckusick if (++buf_ptr >= buf_end) 27324457Smckusick fill_buffer(); 27435500Sbostic if (*buf_ptr == '/') 27535500Sbostic goto end_of_comment; 27635500Sbostic } 27735500Sbostic } while (*buf_ptr == ' ' || *buf_ptr == '\t'); 27835500Sbostic } 27935500Sbostic else if (++buf_ptr >= buf_end) 28035500Sbostic fill_buffer(); 28135500Sbostic break; /* end of case for newline */ 2828806Smckusick 28335500Sbostic case '*': /* must check for possibility of being at end 28435500Sbostic * of comment */ 28535500Sbostic if (++buf_ptr >= buf_end) /* get to next char after * */ 28635500Sbostic fill_buffer(); 2878806Smckusick 28835500Sbostic if (unix_comment == 0) /* set flag to show we are not in 28924457Smckusick * unix-style comment */ 29035500Sbostic unix_comment = 1; 2918806Smckusick 29235500Sbostic if (*buf_ptr == '/') { /* it is the end!!! */ 29335500Sbostic end_of_comment: 29435500Sbostic if (++buf_ptr >= buf_end) 29535500Sbostic fill_buffer(); 2968806Smckusick 29735500Sbostic if (*(e_com - 1) != ' ' && !ps.box_com) { /* insure blank before 29824457Smckusick * end */ 29935500Sbostic *e_com++ = ' '; 30035500Sbostic ++now_col; 30135500Sbostic } 30235500Sbostic if (break_delim == 1 && !one_liner && s_com[0] == '/' 30324457Smckusick && s_com[1] == '*' && s_com[2] == ' ') { 30435500Sbostic char *t = e_com; 30535500Sbostic break_delim = 2; 30635500Sbostic e_com = s_com + 2; 30735500Sbostic *e_com = 0; 30835500Sbostic if (blanklines_before_blockcomments) 30935500Sbostic prefix_blankline_requested = 1; 31035500Sbostic dump_line(); 31135500Sbostic e_com = t; 31235500Sbostic s_com[0] = s_com[1] = s_com[2] = ' '; 31335500Sbostic } 31435500Sbostic if (break_delim == 2 && e_com > s_com + 3 31524457Smckusick /* now_col > adj_max_col - 2 && !ps.box_com */ ) { 3168806Smckusick *e_com = '\0'; 31735500Sbostic dump_line(); 31835500Sbostic now_col = ps.com_col; 3198806Smckusick } 32035500Sbostic check_size(com); 32135500Sbostic *e_com++ = '*'; 32235500Sbostic *e_com++ = '/'; 32335500Sbostic *e_com = '\0'; 32435500Sbostic ps.just_saw_decl = l_just_saw_decl; 32535500Sbostic return; 32635500Sbostic } 32735500Sbostic else { /* handle isolated '*' */ 32835500Sbostic *e_com++ = '*'; 32935500Sbostic ++now_col; 33035500Sbostic } 33135500Sbostic break; 33235500Sbostic default: /* we have a random char */ 33335500Sbostic if (unix_comment == 0 && *buf_ptr != ' ' && *buf_ptr != '\t') 33435500Sbostic unix_comment = 1; /* we are not in unix-style comment */ 3358806Smckusick 33635500Sbostic *e_com = *buf_ptr++; 33735500Sbostic if (buf_ptr >= buf_end) 33835500Sbostic fill_buffer(); 3398806Smckusick 34035500Sbostic if (*e_com == '\t') /* keep track of column */ 34135500Sbostic now_col = ((now_col - 1) & tabmask) + tabsize + 1; 34235500Sbostic else if (*e_com == '\b') /* this is a backspace */ 34335500Sbostic --now_col; 34435500Sbostic else 34535500Sbostic ++now_col; 3468806Smckusick 34735500Sbostic if (*e_com == ' ' || *e_com == '\t') 34835500Sbostic last_bl = e_com; 34935500Sbostic /* remember we saw a blank */ 3508806Smckusick 35135500Sbostic ++e_com; 35235500Sbostic if (now_col > adj_max_col && !ps.box_com && unix_comment == 1 && e_com[-1] > ' ') { 35335500Sbostic /* 35435500Sbostic * the comment is too long, it must be broken up 35535500Sbostic */ 35635500Sbostic if (break_delim == 1 && s_com[0] == '/' 35724457Smckusick && s_com[1] == '*' && s_com[2] == ' ') { 35835500Sbostic char *t = e_com; 35935500Sbostic break_delim = 2; 36035500Sbostic e_com = s_com + 2; 36135500Sbostic *e_com = 0; 36235500Sbostic if (blanklines_before_blockcomments) 36335500Sbostic prefix_blankline_requested = 1; 36424457Smckusick dump_line(); 36535500Sbostic e_com = t; 36635500Sbostic s_com[0] = s_com[1] = s_com[2] = ' '; 36735500Sbostic } 36835500Sbostic if (last_bl == 0) { /* we have seen no blanks */ 36935500Sbostic last_bl = e_com; /* fake it */ 3708806Smckusick *e_com++ = ' '; 37135500Sbostic } 37235500Sbostic *e_com = '\0'; /* print what we have */ 37335500Sbostic *last_bl = '\0'; 37435500Sbostic while (last_bl > s_com && last_bl[-1] < 040) 37535500Sbostic *--last_bl = 0; 37635500Sbostic e_com = last_bl; 37735500Sbostic dump_line(); 3788806Smckusick 37935500Sbostic *e_com++ = ' '; /* add blanks for continuation */ 38035500Sbostic *e_com++ = ' '; 38135500Sbostic *e_com++ = ' '; 38235500Sbostic 38335500Sbostic t_ptr = last_bl + 1; 38435500Sbostic last_bl = 0; 38535500Sbostic if (t_ptr >= e_com) { 38635500Sbostic while (*t_ptr == ' ' || *t_ptr == '\t') 38735500Sbostic t_ptr++; 38835500Sbostic while (*t_ptr != '\0') { /* move unprinted part of 38935500Sbostic * comment down in buffer */ 39035500Sbostic if (*t_ptr == ' ' || *t_ptr == '\t') 39135500Sbostic last_bl = e_com; 39235500Sbostic *e_com++ = *t_ptr++; 3938806Smckusick } 39435500Sbostic } 39535500Sbostic *e_com = '\0'; 39635500Sbostic now_col = count_spaces(ps.com_col, s_com); /* recompute current 39724457Smckusick * position */ 39835500Sbostic } 39935500Sbostic break; 40024457Smckusick } 40124457Smckusick } 40224457Smckusick } 403