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.7 (Berkeley) 09/15/88"; 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 int col_1_com; /* this comment should not be touched */ 66 char *last_bl; /* points to the last blank in the output 67 * buffer */ 68 char achar; 69 char *t_ptr; /* used for moving string */ 70 int unix_comment; /* tri-state variable used to decide if it is 71 * a unix-style comment. 0 means only blanks 72 * since /*, 1 means regular style comment, 2 73 * means unix style comment */ 74 int break_delim = comment_delimiter_on_blankline; 75 int l_just_saw_decl = ps.just_saw_decl; 76 /* 77 * int ps.last_nl = 0; /* true iff the last significant thing 78 * weve seen is a newline 79 */ 80 int one_liner = 1; /* true iff this comment is a one-liner */ 81 adj_max_col = max_col; 82 ps.just_saw_decl = 0; 83 last_bl = 0; /* no blanks found so far */ 84 ps.box_com = col_1_com = false; /* at first, assume that we are not in 85 * a boxed comment or some other 86 * comment that should not be touched */ 87 ++ps.out_coms; /* keep track of number of comments */ 88 unix_comment = 1; /* set flag to let us figure out if there is a 89 * unix-style comment ** DISABLED: use 0 to 90 * reenable this hack! */ 91 92 /* Figure where to align and how to treat the comment */ 93 94 if (ps.col_1 && !format_col1_comments) { /* if comment starts in column 95 * 1 it should not be touched */ 96 col_1_com = ps.box_com = true; 97 ps.com_col = 1; 98 } 99 else { 100 if (*buf_ptr == '-' || *buf_ptr == '*') { 101 ps.box_com = true; /* a comment with a '-' or '*' immediately 102 * after the /* is assumed to be a boxed 103 * comment */ 104 col_1_com = true; 105 break_delim = 0; 106 } 107 if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) { 108 /* klg: check only if this line is blank */ 109 /* 110 * If this (*and previous lines are*) blank, dont put comment way 111 * out at left 112 */ 113 ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1; 114 adj_max_col = block_comment_max_col; 115 if (ps.com_col <= 1) 116 ps.com_col = 1 + !format_col1_comments; 117 } 118 else { 119 register target_col; 120 break_delim = 0; 121 if (s_code != e_code) 122 target_col = count_spaces(compute_code_target(), s_code); 123 else { 124 target_col = 1; 125 if (s_lab != e_lab) 126 target_col = count_spaces(compute_label_target(), s_lab); 127 } 128 ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? ps.decl_com_ind : ps.com_ind; 129 if (ps.com_col < target_col) 130 ps.com_col = ((target_col + 7) & ~7) + 1; 131 if (ps.com_col + 24 > adj_max_col) 132 adj_max_col = ps.com_col + 24; 133 } 134 } 135 if (ps.box_com) { 136 buf_ptr[-2] = 0; 137 ps.n_comment_delta = 1 - count_spaces(1, in_buffer); 138 buf_ptr[-2] = '/'; 139 } 140 else { 141 ps.n_comment_delta = 0; 142 while (*buf_ptr == ' ' || *buf_ptr == '\t') 143 buf_ptr++; 144 } 145 ps.comment_delta = 0; 146 *e_com++ = '/'; /* put '/*' into buffer */ 147 *e_com++ = '*'; 148 if (*buf_ptr != ' ' && !ps.box_com) 149 *e_com++ = ' '; 150 151 *e_com = '\0'; 152 if (troff) { 153 now_col = 1; 154 adj_max_col = 80; 155 } 156 else 157 now_col = count_spaces(ps.com_col, s_com); /* figure what column we 158 * would be in if we 159 * printed the comment 160 * now */ 161 162 /* Start to copy the comment */ 163 164 while (1) { /* this loop will go until the comment is 165 * copied */ 166 if (*buf_ptr > 040 && *buf_ptr != '*') 167 ps.last_nl = 0; 168 check_size(com); 169 switch (*buf_ptr) { /* this checks for various spcl cases */ 170 case 014: /* check for a form feed */ 171 if (!ps.box_com) { /* in a text comment, break the line here */ 172 ps.use_ff = true; 173 /* fix so dump_line uses a form feed */ 174 dump_line(); 175 last_bl = 0; 176 *e_com++ = ' '; 177 *e_com++ = '*'; 178 *e_com++ = ' '; 179 while (*++buf_ptr == ' ' || *buf_ptr == '\t'); 180 } 181 else { 182 if (++buf_ptr >= buf_end) 183 fill_buffer(); 184 *e_com++ = 014; 185 } 186 break; 187 188 case '\n': 189 if (had_eof) { /* check for unexpected eof */ 190 printf("Unterminated comment\n"); 191 *e_com = '\0'; 192 dump_line(); 193 return; 194 } 195 one_liner = 0; 196 if (ps.box_com || ps.last_nl) { /* if this is a boxed comment, 197 * we dont ignore the newline */ 198 if (s_com == e_com) { 199 *e_com++ = ' '; 200 *e_com++ = ' '; 201 } 202 *e_com = '\0'; 203 if (!ps.box_com && e_com - s_com > 3) { 204 if (break_delim == 1 && s_com[0] == '/' 205 && s_com[1] == '*' && s_com[2] == ' ') { 206 char *t = e_com; 207 break_delim = 2; 208 e_com = s_com + 2; 209 *e_com = 0; 210 if (blanklines_before_blockcomments) 211 prefix_blankline_requested = 1; 212 dump_line(); 213 e_com = t; 214 s_com[0] = s_com[1] = s_com[2] = ' '; 215 } 216 dump_line(); 217 check_size(com); 218 *e_com++ = ' '; 219 *e_com++ = ' '; 220 } 221 dump_line(); 222 now_col = ps.com_col; 223 } 224 else { 225 ps.last_nl = 1; 226 if (unix_comment != 1) { /* we not are in unix_style 227 * comment */ 228 if (unix_comment == 0 && s_code == e_code) { 229 /* 230 * if it is a UNIX-style comment, ignore the 231 * requirement that previous line be blank for 232 * unindention 233 */ 234 ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1; 235 if (ps.com_col <= 1) 236 ps.com_col = 2; 237 } 238 unix_comment = 2; /* permanently remember that we are in 239 * this type of comment */ 240 dump_line(); 241 ++line_no; 242 now_col = ps.com_col; 243 *e_com++ = ' '; 244 /* 245 * fix so that the star at the start of the line will line 246 * up 247 */ 248 do /* flush leading white space */ 249 if (++buf_ptr >= buf_end) 250 fill_buffer(); 251 while (*buf_ptr == ' ' || *buf_ptr == '\t'); 252 break; 253 } 254 if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t') 255 last_bl = e_com - 1; 256 /* 257 * if there was a space at the end of the last line, remember 258 * where it was 259 */ 260 else { /* otherwise, insert one */ 261 last_bl = e_com; 262 check_size(com); 263 *e_com++ = ' '; 264 ++now_col; 265 } 266 } 267 ++line_no; /* keep track of input line number */ 268 if (!ps.box_com) { 269 int nstar = 1; 270 do { /* flush any blanks and/or tabs at start of 271 * next line */ 272 if (++buf_ptr >= buf_end) 273 fill_buffer(); 274 if (*buf_ptr == '*' && --nstar >= 0) { 275 if (++buf_ptr >= buf_end) 276 fill_buffer(); 277 if (*buf_ptr == '/') 278 goto end_of_comment; 279 } 280 } while (*buf_ptr == ' ' || *buf_ptr == '\t'); 281 } 282 else if (++buf_ptr >= buf_end) 283 fill_buffer(); 284 break; /* end of case for newline */ 285 286 case '*': /* must check for possibility of being at end 287 * of comment */ 288 if (++buf_ptr >= buf_end) /* get to next char after * */ 289 fill_buffer(); 290 291 if (unix_comment == 0) /* set flag to show we are not in 292 * unix-style comment */ 293 unix_comment = 1; 294 295 if (*buf_ptr == '/') { /* it is the end!!! */ 296 end_of_comment: 297 if (++buf_ptr >= buf_end) 298 fill_buffer(); 299 300 if (*(e_com - 1) != ' ' && !ps.box_com) { /* insure blank before 301 * end */ 302 *e_com++ = ' '; 303 ++now_col; 304 } 305 if (break_delim == 1 && !one_liner && s_com[0] == '/' 306 && s_com[1] == '*' && s_com[2] == ' ') { 307 char *t = e_com; 308 break_delim = 2; 309 e_com = s_com + 2; 310 *e_com = 0; 311 if (blanklines_before_blockcomments) 312 prefix_blankline_requested = 1; 313 dump_line(); 314 e_com = t; 315 s_com[0] = s_com[1] = s_com[2] = ' '; 316 } 317 if (break_delim == 2 && e_com > s_com + 3 318 /* now_col > adj_max_col - 2 && !ps.box_com */ ) { 319 *e_com = '\0'; 320 dump_line(); 321 now_col = ps.com_col; 322 } 323 check_size(com); 324 *e_com++ = '*'; 325 *e_com++ = '/'; 326 *e_com = '\0'; 327 ps.just_saw_decl = l_just_saw_decl; 328 return; 329 } 330 else { /* handle isolated '*' */ 331 *e_com++ = '*'; 332 ++now_col; 333 } 334 break; 335 default: /* we have a random char */ 336 if (unix_comment == 0 && *buf_ptr != ' ' && *buf_ptr != '\t') 337 unix_comment = 1; /* we are not in unix-style comment */ 338 339 *e_com = *buf_ptr++; 340 if (buf_ptr >= buf_end) 341 fill_buffer(); 342 343 if (*e_com == '\t') /* keep track of column */ 344 now_col = ((now_col - 1) & tabmask) + tabsize + 1; 345 else if (*e_com == '\b') /* this is a backspace */ 346 --now_col; 347 else 348 ++now_col; 349 350 if (*e_com == ' ' || *e_com == '\t') 351 last_bl = e_com; 352 /* remember we saw a blank */ 353 354 ++e_com; 355 if (now_col > adj_max_col && !ps.box_com && unix_comment == 1 && e_com[-1] > ' ') { 356 /* 357 * the comment is too long, it must be broken up 358 */ 359 if (break_delim == 1 && s_com[0] == '/' 360 && s_com[1] == '*' && s_com[2] == ' ') { 361 char *t = e_com; 362 break_delim = 2; 363 e_com = s_com + 2; 364 *e_com = 0; 365 if (blanklines_before_blockcomments) 366 prefix_blankline_requested = 1; 367 dump_line(); 368 e_com = t; 369 s_com[0] = s_com[1] = s_com[2] = ' '; 370 } 371 if (last_bl == 0) { /* we have seen no blanks */ 372 last_bl = e_com; /* fake it */ 373 *e_com++ = ' '; 374 } 375 *e_com = '\0'; /* print what we have */ 376 *last_bl = '\0'; 377 while (last_bl > s_com && last_bl[-1] < 040) 378 *--last_bl = 0; 379 e_com = last_bl; 380 dump_line(); 381 382 *e_com++ = ' '; /* add blanks for continuation */ 383 *e_com++ = ' '; 384 *e_com++ = ' '; 385 386 t_ptr = last_bl + 1; 387 last_bl = 0; 388 if (t_ptr >= e_com) { 389 while (*t_ptr == ' ' || *t_ptr == '\t') 390 t_ptr++; 391 while (*t_ptr != '\0') { /* move unprinted part of 392 * comment down in buffer */ 393 if (*t_ptr == ' ' || *t_ptr == '\t') 394 last_bl = e_com; 395 *e_com++ = *t_ptr++; 396 } 397 } 398 *e_com = '\0'; 399 now_col = count_spaces(ps.com_col, s_com); /* recompute current 400 * position */ 401 } 402 break; 403 } 404 } 405 } 406