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