1 /* 2 * Copyright (c) 1985 Sun Microsystems, Inc. 3 * Copyright (c) 1980 The Regents of the University of California. 4 * Copyright (c) 1976 Board of Trustees of the University of Illinois. 5 * All rights reserved. 6 * 7 * %sccs.include.redist.c% 8 */ 9 10 #ifndef lint 11 static char sccsid[] = "@(#)pr_comment.c 5.11 (Berkeley) 06/01/90"; 12 #endif /* not lint */ 13 14 /* 15 * NAME: 16 * pr_comment 17 * 18 * FUNCTION: 19 * This routine takes care of scanning and printing comments. 20 * 21 * ALGORITHM: 22 * 1) Decide where the comment should be aligned, and if lines should 23 * be broken. 24 * 2) If lines should not be broken and filled, just copy up to end of 25 * comment. 26 * 3) If lines should be filled, then scan thru input_buffer copying 27 * characters to com_buf. Remember where the last blank, tab, or 28 * newline was. When line is filled, print up to last blank and 29 * continue copying. 30 * 31 * HISTORY: 32 * November 1976 D A Willcox of CAC Initial coding 33 * 12/6/76 D A Willcox of CAC Modification to handle 34 * UNIX-style comments 35 * 36 */ 37 38 /* 39 * this routine processes comments. It makes an attempt to keep comments from 40 * going over the max line length. If a line is too long, it moves everything 41 * from the last blank to the next comment line. Blanks and tabs from the 42 * beginning of the input line are removed 43 */ 44 45 46 #include "indent_globs.h" 47 48 49 pr_comment() 50 { 51 int now_col; /* column we are in now */ 52 int adj_max_col; /* Adjusted max_col for when we decide to 53 * spill comments over the right margin */ 54 char *last_bl; /* points to the last blank in the output 55 * buffer */ 56 char *t_ptr; /* used for moving string */ 57 int unix_comment; /* tri-state variable used to decide if it is 58 * a unix-style comment. 0 means only blanks 59 * since /*, 1 means regular style comment, 2 60 * means unix style comment */ 61 int break_delim = comment_delimiter_on_blankline; 62 int l_just_saw_decl = ps.just_saw_decl; 63 /* 64 * int ps.last_nl = 0; /* true iff the last significant thing 65 * weve seen is a newline 66 */ 67 int one_liner = 1; /* true iff this comment is a one-liner */ 68 adj_max_col = max_col; 69 ps.just_saw_decl = 0; 70 last_bl = 0; /* no blanks found so far */ 71 ps.box_com = false; /* at first, assume that we are not in 72 * a boxed comment or some other 73 * comment that should not be touched */ 74 ++ps.out_coms; /* keep track of number of comments */ 75 unix_comment = 1; /* set flag to let us figure out if there is a 76 * unix-style comment ** DISABLED: use 0 to 77 * reenable this hack! */ 78 79 /* Figure where to align and how to treat the comment */ 80 81 if (ps.col_1 && !format_col1_comments) { /* if comment starts in column 82 * 1 it should not be touched */ 83 ps.box_com = true; 84 ps.com_col = 1; 85 } 86 else { 87 if (*buf_ptr == '-' || *buf_ptr == '*') { 88 ps.box_com = true; /* a comment with a '-' or '*' immediately 89 * after the /* is assumed to be a boxed 90 * comment */ 91 break_delim = 0; 92 } 93 if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) { 94 /* klg: check only if this line is blank */ 95 /* 96 * If this (*and previous lines are*) blank, dont put comment way 97 * out at left 98 */ 99 ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1; 100 adj_max_col = block_comment_max_col; 101 if (ps.com_col <= 1) 102 ps.com_col = 1 + !format_col1_comments; 103 } 104 else { 105 register target_col; 106 break_delim = 0; 107 if (s_code != e_code) 108 target_col = count_spaces(compute_code_target(), s_code); 109 else { 110 target_col = 1; 111 if (s_lab != e_lab) 112 target_col = count_spaces(compute_label_target(), s_lab); 113 } 114 ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? ps.decl_com_ind : ps.com_ind; 115 if (ps.com_col < target_col) 116 ps.com_col = ((target_col + 7) & ~7) + 1; 117 if (ps.com_col + 24 > adj_max_col) 118 adj_max_col = ps.com_col + 24; 119 } 120 } 121 if (ps.box_com) { 122 buf_ptr[-2] = 0; 123 ps.n_comment_delta = 1 - count_spaces(1, in_buffer); 124 buf_ptr[-2] = '/'; 125 } 126 else { 127 ps.n_comment_delta = 0; 128 while (*buf_ptr == ' ' || *buf_ptr == '\t') 129 buf_ptr++; 130 } 131 ps.comment_delta = 0; 132 *e_com++ = '/'; /* put '/*' into buffer */ 133 *e_com++ = '*'; 134 if (*buf_ptr != ' ' && !ps.box_com) 135 *e_com++ = ' '; 136 137 *e_com = '\0'; 138 if (troff) { 139 now_col = 1; 140 adj_max_col = 80; 141 } 142 else 143 now_col = count_spaces(ps.com_col, s_com); /* figure what column we 144 * would be in if we 145 * printed the comment 146 * now */ 147 148 /* Start to copy the comment */ 149 150 while (1) { /* this loop will go until the comment is 151 * copied */ 152 if (*buf_ptr > 040 && *buf_ptr != '*') 153 ps.last_nl = 0; 154 CHECK_SIZE_COM; 155 switch (*buf_ptr) { /* this checks for various spcl cases */ 156 case 014: /* check for a form feed */ 157 if (!ps.box_com) { /* in a text comment, break the line here */ 158 ps.use_ff = true; 159 /* fix so dump_line uses a form feed */ 160 dump_line(); 161 last_bl = 0; 162 *e_com++ = ' '; 163 *e_com++ = '*'; 164 *e_com++ = ' '; 165 while (*++buf_ptr == ' ' || *buf_ptr == '\t'); 166 } 167 else { 168 if (++buf_ptr >= buf_end) 169 fill_buffer(); 170 *e_com++ = 014; 171 } 172 break; 173 174 case '\n': 175 if (had_eof) { /* check for unexpected eof */ 176 printf("Unterminated comment\n"); 177 *e_com = '\0'; 178 dump_line(); 179 return; 180 } 181 one_liner = 0; 182 if (ps.box_com || ps.last_nl) { /* if this is a boxed comment, 183 * we dont ignore the newline */ 184 if (s_com == e_com) { 185 *e_com++ = ' '; 186 *e_com++ = ' '; 187 } 188 *e_com = '\0'; 189 if (!ps.box_com && e_com - s_com > 3) { 190 if (break_delim == 1 && s_com[0] == '/' 191 && s_com[1] == '*' && s_com[2] == ' ') { 192 char *t = e_com; 193 break_delim = 2; 194 e_com = s_com + 2; 195 *e_com = 0; 196 if (blanklines_before_blockcomments) 197 prefix_blankline_requested = 1; 198 dump_line(); 199 e_com = t; 200 s_com[0] = s_com[1] = s_com[2] = ' '; 201 } 202 dump_line(); 203 CHECK_SIZE_COM; 204 *e_com++ = ' '; 205 *e_com++ = ' '; 206 } 207 dump_line(); 208 now_col = ps.com_col; 209 } 210 else { 211 ps.last_nl = 1; 212 if (unix_comment != 1) { /* we not are in unix_style 213 * comment */ 214 if (unix_comment == 0 && s_code == e_code) { 215 /* 216 * if it is a UNIX-style comment, ignore the 217 * requirement that previous line be blank for 218 * unindention 219 */ 220 ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1; 221 if (ps.com_col <= 1) 222 ps.com_col = 2; 223 } 224 unix_comment = 2; /* permanently remember that we are in 225 * this type of comment */ 226 dump_line(); 227 ++line_no; 228 now_col = ps.com_col; 229 *e_com++ = ' '; 230 /* 231 * fix so that the star at the start of the line will line 232 * up 233 */ 234 do /* flush leading white space */ 235 if (++buf_ptr >= buf_end) 236 fill_buffer(); 237 while (*buf_ptr == ' ' || *buf_ptr == '\t'); 238 break; 239 } 240 if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t') 241 last_bl = e_com - 1; 242 /* 243 * if there was a space at the end of the last line, remember 244 * where it was 245 */ 246 else { /* otherwise, insert one */ 247 last_bl = e_com; 248 CHECK_SIZE_COM; 249 *e_com++ = ' '; 250 ++now_col; 251 } 252 } 253 ++line_no; /* keep track of input line number */ 254 if (!ps.box_com) { 255 int nstar = 1; 256 do { /* flush any blanks and/or tabs at start of 257 * next line */ 258 if (++buf_ptr >= buf_end) 259 fill_buffer(); 260 if (*buf_ptr == '*' && --nstar >= 0) { 261 if (++buf_ptr >= buf_end) 262 fill_buffer(); 263 if (*buf_ptr == '/') 264 goto end_of_comment; 265 } 266 } while (*buf_ptr == ' ' || *buf_ptr == '\t'); 267 } 268 else if (++buf_ptr >= buf_end) 269 fill_buffer(); 270 break; /* end of case for newline */ 271 272 case '*': /* must check for possibility of being at end 273 * of comment */ 274 if (++buf_ptr >= buf_end) /* get to next char after * */ 275 fill_buffer(); 276 277 if (unix_comment == 0) /* set flag to show we are not in 278 * unix-style comment */ 279 unix_comment = 1; 280 281 if (*buf_ptr == '/') { /* it is the end!!! */ 282 end_of_comment: 283 if (++buf_ptr >= buf_end) 284 fill_buffer(); 285 286 if (*(e_com - 1) != ' ' && !ps.box_com) { /* insure blank before 287 * end */ 288 *e_com++ = ' '; 289 ++now_col; 290 } 291 if (break_delim == 1 && !one_liner && s_com[0] == '/' 292 && s_com[1] == '*' && s_com[2] == ' ') { 293 char *t = e_com; 294 break_delim = 2; 295 e_com = s_com + 2; 296 *e_com = 0; 297 if (blanklines_before_blockcomments) 298 prefix_blankline_requested = 1; 299 dump_line(); 300 e_com = t; 301 s_com[0] = s_com[1] = s_com[2] = ' '; 302 } 303 if (break_delim == 2 && e_com > s_com + 3 304 /* now_col > adj_max_col - 2 && !ps.box_com */ ) { 305 *e_com = '\0'; 306 dump_line(); 307 now_col = ps.com_col; 308 } 309 CHECK_SIZE_COM; 310 *e_com++ = '*'; 311 *e_com++ = '/'; 312 *e_com = '\0'; 313 ps.just_saw_decl = l_just_saw_decl; 314 return; 315 } 316 else { /* handle isolated '*' */ 317 *e_com++ = '*'; 318 ++now_col; 319 } 320 break; 321 default: /* we have a random char */ 322 if (unix_comment == 0 && *buf_ptr != ' ' && *buf_ptr != '\t') 323 unix_comment = 1; /* we are not in unix-style comment */ 324 325 *e_com = *buf_ptr++; 326 if (buf_ptr >= buf_end) 327 fill_buffer(); 328 329 if (*e_com == '\t') /* keep track of column */ 330 now_col = ((now_col - 1) & tabmask) + tabsize + 1; 331 else if (*e_com == '\b') /* this is a backspace */ 332 --now_col; 333 else 334 ++now_col; 335 336 if (*e_com == ' ' || *e_com == '\t') 337 last_bl = e_com; 338 /* remember we saw a blank */ 339 340 ++e_com; 341 if (now_col > adj_max_col && !ps.box_com && unix_comment == 1 && e_com[-1] > ' ') { 342 /* 343 * the comment is too long, it must be broken up 344 */ 345 if (break_delim == 1 && s_com[0] == '/' 346 && s_com[1] == '*' && s_com[2] == ' ') { 347 char *t = e_com; 348 break_delim = 2; 349 e_com = s_com + 2; 350 *e_com = 0; 351 if (blanklines_before_blockcomments) 352 prefix_blankline_requested = 1; 353 dump_line(); 354 e_com = t; 355 s_com[0] = s_com[1] = s_com[2] = ' '; 356 } 357 if (last_bl == 0) { /* we have seen no blanks */ 358 last_bl = e_com; /* fake it */ 359 *e_com++ = ' '; 360 } 361 *e_com = '\0'; /* print what we have */ 362 *last_bl = '\0'; 363 while (last_bl > s_com && last_bl[-1] < 040) 364 *--last_bl = 0; 365 e_com = last_bl; 366 dump_line(); 367 368 *e_com++ = ' '; /* add blanks for continuation */ 369 *e_com++ = ' '; 370 *e_com++ = ' '; 371 372 t_ptr = last_bl + 1; 373 last_bl = 0; 374 if (t_ptr >= e_com) { 375 while (*t_ptr == ' ' || *t_ptr == '\t') 376 t_ptr++; 377 while (*t_ptr != '\0') { /* move unprinted part of 378 * comment down in buffer */ 379 if (*t_ptr == ' ' || *t_ptr == '\t') 380 last_bl = e_com; 381 *e_com++ = *t_ptr++; 382 } 383 } 384 *e_com = '\0'; 385 now_col = count_spaces(ps.com_col, s_com); /* recompute current 386 * position */ 387 } 388 break; 389 } 390 } 391 } 392