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