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 * 742688Sbostic * %sccs.include.redist.c% 821972Sdist */ 98806Smckusick 1021972Sdist #ifndef lint 11*46695Sbostic static char sccsid[] = "@(#)pr_comment.c 5.12 (Berkeley) 02/26/91"; 1233767Sbostic #endif /* not lint */ 1321972Sdist 14*46695Sbostic #include <stdio.h> 15*46695Sbostic #include <stdlib.h> 16*46695Sbostic #include "indent_globs.h" 17*46695Sbostic 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 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