[BACK]Return to pr_comment.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / usr.bin / indent

Annotation of src/usr.bin/indent/pr_comment.c, Revision 1.17

1.17    ! rillig      1: /*     $NetBSD: pr_comment.c,v 1.16 2021/03/11 22:15:44 rillig Exp $   */
1.4       tls         2:
1.11      kamil       3: /*-
                      4:  * SPDX-License-Identifier: BSD-4-Clause
                      5:  *
                      6:  * Copyright (c) 1985 Sun Microsystems, Inc.
1.5       mrg         7:  * Copyright (c) 1980, 1993
                      8:  *     The Regents of the University of California.  All rights reserved.
1.1       cgd         9:  * All rights reserved.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *     This product includes software developed by the University of
                     22:  *     California, Berkeley and its contributors.
                     23:  * 4. Neither the name of the University nor the names of its contributors
                     24:  *    may be used to endorse or promote products derived from this software
                     25:  *    without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     28:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     29:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     30:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     31:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     32:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     33:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     34:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     35:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     36:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     37:  * SUCH DAMAGE.
                     38:  */
                     39:
1.11      kamil      40: #if 0
                     41: #ifndef lint
                     42: static char sccsid[] = "@(#)pr_comment.c       8.1 (Berkeley) 6/6/93";
                     43: #endif /* not lint */
                     44: #endif
                     45:
1.6       lukem      46: #include <sys/cdefs.h>
1.1       cgd        47: #ifndef lint
1.11      kamil      48: #if defined(__NetBSD__)
1.17    ! rillig     49: __RCSID("$NetBSD: pr_comment.c,v 1.16 2021/03/11 22:15:44 rillig Exp $");
1.11      kamil      50: #elif defined(__FreeBSD__)
                     51: __FBSDID("$FreeBSD: head/usr.bin/indent/pr_comment.c 334927 2018-06-10 16:44:18Z pstef $");
                     52: #endif
1.5       mrg        53: #endif
1.1       cgd        54:
1.11      kamil      55: #include <err.h>
1.1       cgd        56: #include <stdio.h>
                     57: #include <stdlib.h>
1.11      kamil      58: #include <string.h>
1.12      rillig     59:
1.11      kamil      60: #include "indent.h"
1.12      rillig     61:
1.14      rillig     62: static void
                     63: check_size_comment(size_t desired_size, char **last_bl_ptr)
                     64: {
                     65:     if (e_com + (desired_size) >= l_com) {
                     66:        int nsize = l_com - s_com + 400 + desired_size;
                     67:        int com_len = e_com - s_com;
                     68:        int blank_pos;
                     69:        if (*last_bl_ptr != NULL)
                     70:            blank_pos = *last_bl_ptr - combuf;
                     71:        else
                     72:            blank_pos = -1;
1.17    ! rillig     73:        combuf = realloc(combuf, nsize);
1.14      rillig     74:        if (combuf == NULL)
                     75:            err(1, NULL);
                     76:        e_com = combuf + com_len + 1;
                     77:        if (blank_pos > 0)
                     78:            *last_bl_ptr = combuf + blank_pos;
                     79:        l_com = combuf + nsize - 5;
                     80:        s_com = combuf + 1;
                     81:     }
                     82: }
                     83:
1.1       cgd        84: /*
                     85:  * NAME:
                     86:  *     pr_comment
                     87:  *
                     88:  * FUNCTION:
                     89:  *     This routine takes care of scanning and printing comments.
                     90:  *
                     91:  * ALGORITHM:
                     92:  *     1) Decide where the comment should be aligned, and if lines should
                     93:  *        be broken.
                     94:  *     2) If lines should not be broken and filled, just copy up to end of
                     95:  *        comment.
                     96:  *     3) If lines should be filled, then scan thru input_buffer copying
                     97:  *        characters to com_buf.  Remember where the last blank, tab, or
                     98:  *        newline was.  When line is filled, print up to last blank and
                     99:  *        continue copying.
                    100:  *
                    101:  * HISTORY:
                    102:  *     November 1976   D A Willcox of CAC      Initial coding
                    103:  *     12/6/76         D A Willcox of CAC      Modification to handle
                    104:  *                                             UNIX-style comments
                    105:  *
                    106:  */
                    107:
                    108: /*
                    109:  * this routine processes comments.  It makes an attempt to keep comments from
                    110:  * going over the max line length.  If a line is too long, it moves everything
                    111:  * from the last blank to the next comment line.  Blanks and tabs from the
                    112:  * beginning of the input line are removed
                    113:  */
                    114:
1.6       lukem     115: void
1.7       wiz       116: pr_comment(void)
1.1       cgd       117: {
1.11      kamil     118:     int         now_col;       /* column we are in now */
                    119:     int         adj_max_col;   /* Adjusted max_col for when we decide to
1.1       cgd       120:                                 * spill comments over the right margin */
1.11      kamil     121:     char       *last_bl;       /* points to the last blank in the output
1.1       cgd       122:                                 * buffer */
1.11      kamil     123:     char       *t_ptr;         /* used for moving string */
                    124:     int         break_delim = opt.comment_delimiter_on_blankline;
                    125:     int         l_just_saw_decl = ps.just_saw_decl;
                    126:
                    127:     adj_max_col = opt.max_col;
                    128:     ps.just_saw_decl = 0;
                    129:     last_bl = NULL;            /* no blanks found so far */
                    130:     ps.box_com = false;                /* at first, assume that we are not in
1.15      rillig    131:                                 * a boxed comment or some other
                    132:                                 * comment that should not be touched */
1.11      kamil     133:     ++ps.out_coms;             /* keep track of number of comments */
                    134:
                    135:     /* Figure where to align and how to treat the comment */
                    136:
                    137:     if (ps.col_1 && !opt.format_col1_comments) {       /* if comment starts in column
                    138:                                                 * 1 it should not be touched */
                    139:        ps.box_com = true;
                    140:        break_delim = false;
                    141:        ps.com_col = 1;
                    142:     }
                    143:     else {
1.13      rillig    144:        if (*buf_ptr == '-' || *buf_ptr == '*' || e_token[-1] == '/' ||
1.11      kamil     145:            (*buf_ptr == '\n' && !opt.format_block_comments)) {
                    146:            ps.box_com = true;  /* A comment with a '-' or '*' immediately
                    147:                                 * after the /+* is assumed to be a boxed
                    148:                                 * comment. A comment with a newline
                    149:                                 * immediately after the /+* is assumed to
                    150:                                 * be a block comment and is treated as a
                    151:                                 * box comment unless format_block_comments
                    152:                                 * is nonzero (the default). */
                    153:            break_delim = false;
                    154:        }
                    155:        if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) {
                    156:            /* klg: check only if this line is blank */
                    157:            /*
                    158:             * If this (*and previous lines are*) blank, dont put comment way
                    159:             * out at left
                    160:             */
                    161:            ps.com_col = (ps.ind_level - opt.unindent_displace) * opt.ind_size + 1;
                    162:            adj_max_col = opt.block_comment_max_col;
                    163:            if (ps.com_col <= 1)
                    164:                ps.com_col = 1 + !opt.format_col1_comments;
                    165:        }
                    166:        else {
                    167:            int target_col;
                    168:            break_delim = false;
                    169:            if (s_code != e_code)
                    170:                target_col = count_spaces(compute_code_target(), s_code);
                    171:            else {
                    172:                target_col = 1;
                    173:                if (s_lab != e_lab)
                    174:                    target_col = count_spaces(compute_label_target(), s_lab);
                    175:            }
                    176:            ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? opt.decl_com_ind : opt.com_ind;
                    177:            if (ps.com_col <= target_col)
                    178:                ps.com_col = opt.tabsize * (1 + (target_col - 1) / opt.tabsize) + 1;
                    179:            if (ps.com_col + 24 > adj_max_col)
                    180:                adj_max_col = ps.com_col + 24;
                    181:        }
                    182:     }
                    183:     if (ps.box_com) {
1.6       lukem     184:        /*
1.11      kamil     185:         * Find out how much indentation there was originally, because that
                    186:         * much will have to be ignored by pad_output() in dump_line(). This
                    187:         * is a box comment, so nothing changes -- not even indentation.
                    188:         *
                    189:         * The comment we're about to read usually comes from in_buffer,
                    190:         * unless it has been copied into save_com.
                    191:         */
                    192:        char *start;
                    193:
                    194:        start = buf_ptr >= save_com && buf_ptr < save_com + sc_size ?
                    195:            sc_buf : in_buffer;
                    196:        ps.n_comment_delta = 1 - count_spaces_until(1, start, buf_ptr - 2);
                    197:     }
                    198:     else {
                    199:        ps.n_comment_delta = 0;
                    200:        while (*buf_ptr == ' ' || *buf_ptr == '\t')
                    201:            buf_ptr++;
                    202:     }
                    203:     ps.comment_delta = 0;
1.13      rillig    204:     *e_com++ = '/';
                    205:     *e_com++ = e_token[-1];
1.11      kamil     206:     if (*buf_ptr != ' ' && !ps.box_com)
                    207:        *e_com++ = ' ';
                    208:
                    209:     /*
                    210:      * Don't put a break delimiter if this is a one-liner that won't wrap.
                    211:      */
                    212:     if (break_delim)
                    213:        for (t_ptr = buf_ptr; *t_ptr != '\0' && *t_ptr != '\n'; t_ptr++) {
                    214:            if (t_ptr >= buf_end)
                    215:                fill_buffer();
                    216:            if (t_ptr[0] == '*' && t_ptr[1] == '/') {
                    217:                if (adj_max_col >= count_spaces_until(ps.com_col, buf_ptr, t_ptr + 2))
                    218:                    break_delim = false;
                    219:                break;
                    220:            }
1.6       lukem     221:        }
1.1       cgd       222:
1.11      kamil     223:     if (break_delim) {
                    224:        char       *t = e_com;
                    225:        e_com = s_com + 2;
                    226:        *e_com = 0;
                    227:        if (opt.blanklines_before_blockcomments && ps.last_token != lbrace)
                    228:            prefix_blankline_requested = 1;
                    229:        dump_line();
                    230:        e_com = s_com = t;
                    231:        if (!ps.box_com && opt.star_comment_cont)
                    232:            *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
                    233:     }
                    234:
                    235:     /* Start to copy the comment */
1.1       cgd       236:
1.11      kamil     237:     while (1) {                        /* this loop will go until the comment is
1.6       lukem     238:                                 * copied */
1.11      kamil     239:        switch (*buf_ptr) {     /* this checks for various spcl cases */
                    240:        case 014:               /* check for a form feed */
1.14      rillig    241:            check_size_comment(3, &last_bl);
1.11      kamil     242:            if (!ps.box_com) {  /* in a text comment, break the line here */
                    243:                ps.use_ff = true;
                    244:                /* fix so dump_line uses a form feed */
                    245:                dump_line();
                    246:                last_bl = NULL;
                    247:                if (!ps.box_com && opt.star_comment_cont)
                    248:                    *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
                    249:                while (*++buf_ptr == ' ' || *buf_ptr == '\t')
                    250:                    ;
                    251:            }
                    252:            else {
                    253:                if (++buf_ptr >= buf_end)
                    254:                    fill_buffer();
                    255:                *e_com++ = 014;
                    256:            }
                    257:            break;
                    258:
                    259:        case '\n':
1.13      rillig    260:            if (e_token[-1] == '/') {
                    261:                ++line_no;
                    262:                goto end_of_comment;
                    263:            }
1.11      kamil     264:            if (had_eof) {      /* check for unexpected eof */
                    265:                printf("Unterminated comment\n");
                    266:                dump_line();
                    267:                return;
                    268:            }
                    269:            last_bl = NULL;
1.14      rillig    270:            check_size_comment(4, &last_bl);
1.11      kamil     271:            if (ps.box_com || ps.last_nl) {     /* if this is a boxed comment,
                    272:                                                 * we dont ignore the newline */
                    273:                if (s_com == e_com)
                    274:                    *e_com++ = ' ';
                    275:                if (!ps.box_com && e_com - s_com > 3) {
                    276:                    dump_line();
                    277:                    if (opt.star_comment_cont)
                    278:                        *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
                    279:                }
                    280:                dump_line();
                    281:                if (!ps.box_com && opt.star_comment_cont)
                    282:                    *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
                    283:            }
                    284:            else {
                    285:                ps.last_nl = 1;
1.16      rillig    286:                if (e_com[-1] == ' ' || e_com[-1] == '\t')
1.11      kamil     287:                    last_bl = e_com - 1;
                    288:                /*
                    289:                 * if there was a space at the end of the last line, remember
                    290:                 * where it was
                    291:                 */
                    292:                else {          /* otherwise, insert one */
                    293:                    last_bl = e_com;
                    294:                    *e_com++ = ' ';
                    295:                }
                    296:            }
                    297:            ++line_no;          /* keep track of input line number */
                    298:            if (!ps.box_com) {
                    299:                int         nstar = 1;
                    300:                do {            /* flush any blanks and/or tabs at start of
                    301:                                 * next line */
                    302:                    if (++buf_ptr >= buf_end)
                    303:                        fill_buffer();
                    304:                    if (*buf_ptr == '*' && --nstar >= 0) {
                    305:                        if (++buf_ptr >= buf_end)
                    306:                            fill_buffer();
                    307:                        if (*buf_ptr == '/')
                    308:                            goto end_of_comment;
                    309:                    }
                    310:                } while (*buf_ptr == ' ' || *buf_ptr == '\t');
                    311:            }
                    312:            else if (++buf_ptr >= buf_end)
                    313:                fill_buffer();
                    314:            break;              /* end of case for newline */
1.1       cgd       315:
1.11      kamil     316:        case '*':               /* must check for possibility of being at end
1.6       lukem     317:                                 * of comment */
1.11      kamil     318:            if (++buf_ptr >= buf_end)   /* get to next char after * */
                    319:                fill_buffer();
1.14      rillig    320:            check_size_comment(4, &last_bl);
1.11      kamil     321:            if (*buf_ptr == '/') {      /* it is the end!!! */
                    322:        end_of_comment:
                    323:                if (++buf_ptr >= buf_end)
                    324:                    fill_buffer();
                    325:                if (break_delim) {
                    326:                    if (e_com > s_com + 3) {
                    327:                        dump_line();
                    328:                    }
                    329:                    else
                    330:                        s_com = e_com;
                    331:                    *e_com++ = ' ';
                    332:                }
                    333:                if (e_com[-1] != ' ' && e_com[-1] != '\t' && !ps.box_com)
                    334:                    *e_com++ = ' ';     /* ensure blank before end */
1.13      rillig    335:                if (e_token[-1] == '/')
                    336:                    *e_com++ = '\n', *e_com = '\0';
                    337:                else
                    338:                    *e_com++ = '*', *e_com++ = '/', *e_com = '\0';
1.11      kamil     339:                ps.just_saw_decl = l_just_saw_decl;
                    340:                return;
                    341:            }
                    342:            else                /* handle isolated '*' */
                    343:                *e_com++ = '*';
                    344:            break;
                    345:        default:                /* we have a random char */
                    346:            now_col = count_spaces_until(ps.com_col, s_com, e_com);
                    347:            do {
1.14      rillig    348:                check_size_comment(1, &last_bl);
1.11      kamil     349:                *e_com = *buf_ptr++;
                    350:                if (buf_ptr >= buf_end)
                    351:                    fill_buffer();
                    352:                if (*e_com == ' ' || *e_com == '\t')
                    353:                    last_bl = e_com;    /* remember we saw a blank */
                    354:                ++e_com;
                    355:                now_col++;
                    356:            } while (!memchr("*\n\r\b\t", *buf_ptr, 6) &&
                    357:                (now_col <= adj_max_col || !last_bl));
                    358:            ps.last_nl = false;
                    359:            if (now_col > adj_max_col && !ps.box_com && e_com[-1] > ' ') {
                    360:                /*
                    361:                 * the comment is too long, it must be broken up
                    362:                 */
                    363:                if (last_bl == NULL) {
                    364:                    dump_line();
                    365:                    if (!ps.box_com && opt.star_comment_cont)
                    366:                        *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
                    367:                    break;
                    368:                }
                    369:                *e_com = '\0';
                    370:                e_com = last_bl;
                    371:                dump_line();
                    372:                if (!ps.box_com && opt.star_comment_cont)
                    373:                    *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
                    374:                for (t_ptr = last_bl + 1; *t_ptr == ' ' || *t_ptr == '\t';
                    375:                    t_ptr++)
                    376:                        ;
                    377:                last_bl = NULL;
                    378:                /*
                    379:                 * t_ptr will be somewhere between e_com (dump_line() reset)
                    380:                 * and l_com. So it's safe to copy byte by byte from t_ptr
1.14      rillig    381:                 * to e_com without any check_size_comment().
1.11      kamil     382:                 */
                    383:                while (*t_ptr != '\0') {
                    384:                    if (*t_ptr == ' ' || *t_ptr == '\t')
                    385:                        last_bl = e_com;
                    386:                    *e_com++ = *t_ptr++;
1.1       cgd       387:                }
1.11      kamil     388:            }
                    389:            break;
1.1       cgd       390:        }
1.11      kamil     391:     }
1.1       cgd       392: }

CVSweb <webmaster@jp.NetBSD.org>