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