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