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

Annotation of src/usr.bin/indent/indent.c, Revision 1.232

1.232   ! rillig      1: /*     $NetBSD: indent.c,v 1.231 2021/11/25 07:45:32 rillig Exp $      */
1.4       tls         2:
1.25      kamil       3: /*-
                      4:  * SPDX-License-Identifier: BSD-4-Clause
                      5:  *
                      6:  * Copyright (c) 1985 Sun Microsystems, Inc.
                      7:  * Copyright (c) 1976 Board of Trustees of the University of Illinois.
1.5       mrg         8:  * Copyright (c) 1980, 1993
                      9:  *     The Regents of the University of California.  All rights reserved.
1.15      agc        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.
1.1       cgd        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.25      kamil      40: #if 0
                     41: static char sccsid[] = "@(#)indent.c   5.17 (Berkeley) 6/7/93";
                     42: #endif
1.1       cgd        43:
1.25      kamil      44: #include <sys/cdefs.h>
                     45: #if defined(__NetBSD__)
1.232   ! rillig     46: __RCSID("$NetBSD: indent.c,v 1.231 2021/11/25 07:45:32 rillig Exp $");
1.25      kamil      47: #elif defined(__FreeBSD__)
                     48: __FBSDID("$FreeBSD: head/usr.bin/indent/indent.c 340138 2018-11-04 19:24:49Z oshogbo $");
                     49: #endif
1.1       cgd        50:
                     51: #include <sys/param.h>
1.25      kamil      52: #if HAVE_CAPSICUM
                     53: #include <sys/capsicum.h>
                     54: #include <capsicum_helpers.h>
                     55: #endif
1.176     rillig     56: #include <assert.h>
1.6       lukem      57: #include <err.h>
                     58: #include <errno.h>
1.1       cgd        59: #include <fcntl.h>
1.227     rillig     60: #include <stdarg.h>
1.1       cgd        61: #include <stdio.h>
                     62: #include <stdlib.h>
                     63: #include <string.h>
1.82      rillig     64: #include <unistd.h>
1.29      rillig     65:
1.25      kamil      66: #include "indent.h"
                     67:
1.71      rillig     68: struct options opt = {
1.122     rillig     69:     .brace_same_line = true,
1.86      rillig     70:     .comment_delimiter_on_blankline = true,
                     71:     .cuddle_else = true,
                     72:     .comment_column = 33,
                     73:     .decl_indent = 16,
                     74:     .else_if = true,
                     75:     .function_brace_split = true,
                     76:     .format_col1_comments = true,
                     77:     .format_block_comments = true,
                     78:     .indent_parameters = true,
                     79:     .indent_size = 8,
                     80:     .local_decl_indent = -1,
                     81:     .lineup_to_parens = true,
                     82:     .procnames_start_line = true,
                     83:     .star_comment_cont = true,
                     84:     .tabsize = 8,
                     85:     .max_line_length = 78,
                     86:     .use_tabs = true,
1.71      rillig     87: };
                     88:
1.175     rillig     89: struct parser_state ps;
1.27      joerg      90:
1.192     rillig     91: struct buffer token;
                     92:
1.63      rillig     93: struct buffer lab;
1.65      rillig     94: struct buffer code;
1.63      rillig     95: struct buffer com;
1.86      rillig     96:
                     97: bool found_err;
1.140     rillig     98: int blank_lines_to_output;
1.142     rillig     99: bool blank_line_before;
                    100: bool blank_line_after;
1.86      rillig    101: bool break_comma;
                    102: float case_ind;
                    103: bool had_eof;
1.174     rillig    104: int line_no = 1;
1.86      rillig    105: bool inhibit_formatting;
1.27      joerg     106:
1.88      rillig    107: static int ifdef_level;
                    108: static struct parser_state state_stack[5];
1.27      joerg     109:
1.86      rillig    110: FILE *input;
                    111: FILE *output;
1.27      joerg     112:
1.88      rillig    113: static const char *in_name = "Standard Input";
                    114: static const char *out_name = "Standard Output";
                    115: static const char *backup_suffix = ".BAK";
                    116: static char bakfile[MAXPATHLEN] = "";
1.1       cgd       117:
1.40      rillig    118: #if HAVE_CAPSICUM
                    119: static void
                    120: init_capsicum(void)
1.1       cgd       121: {
1.25      kamil     122:     cap_rights_t rights;
1.40      rillig    123:
                    124:     /* Restrict input/output descriptors and enter Capsicum sandbox. */
                    125:     cap_rights_init(&rights, CAP_FSTAT, CAP_WRITE);
                    126:     if (caph_rights_limit(fileno(output), &rights) < 0)
                    127:        err(EXIT_FAILURE, "unable to limit rights for %s", out_name);
                    128:     cap_rights_init(&rights, CAP_FSTAT, CAP_READ);
                    129:     if (caph_rights_limit(fileno(input), &rights) < 0)
                    130:        err(EXIT_FAILURE, "unable to limit rights for %s", in_name);
                    131:     if (caph_enter() < 0)
                    132:        err(EXIT_FAILURE, "unable to enter capability mode");
                    133: }
1.41      rillig    134: #endif
                    135:
1.193     rillig    136: static void
                    137: buf_init(struct buffer *buf)
                    138: {
                    139:     size_t size = 200;
                    140:     buf->buf = xmalloc(size);
                    141:     buf->l = buf->buf + size - 5 /* safety margin */;
                    142:     buf->s = buf->buf + 1;     /* allow accessing buf->e[-1] */
                    143:     buf->e = buf->s;
                    144:     buf->buf[0] = ' ';
                    145:     buf->buf[1] = '\0';
                    146: }
                    147:
                    148: static size_t
                    149: buf_len(const struct buffer *buf)
                    150: {
                    151:     return (size_t)(buf->e - buf->s);
                    152: }
                    153:
                    154: void
                    155: buf_expand(struct buffer *buf, size_t add_size)
                    156: {
                    157:     size_t new_size = (size_t)(buf->l - buf->s) + 400 + add_size;
                    158:     size_t len = buf_len(buf);
                    159:     buf->buf = xrealloc(buf->buf, new_size);
                    160:     buf->l = buf->buf + new_size - 5;
                    161:     buf->s = buf->buf + 1;
                    162:     buf->e = buf->s + len;
                    163:     /* At this point, the buffer may not be null-terminated anymore. */
                    164: }
                    165:
                    166: static void
                    167: buf_reserve(struct buffer *buf, size_t n)
                    168: {
                    169:     if (n >= (size_t)(buf->l - buf->e))
                    170:        buf_expand(buf, n);
                    171: }
                    172:
                    173: static void
                    174: buf_add_char(struct buffer *buf, char ch)
                    175: {
                    176:     buf_reserve(buf, 1);
                    177:     *buf->e++ = ch;
                    178: }
                    179:
                    180: static void
                    181: buf_add_buf(struct buffer *buf, const struct buffer *add)
                    182: {
                    183:     size_t len = buf_len(add);
                    184:     buf_reserve(buf, len);
                    185:     memcpy(buf->e, add->s, len);
                    186:     buf->e += len;
                    187: }
                    188:
                    189: static void
                    190: buf_terminate(struct buffer *buf)
                    191: {
                    192:     buf_reserve(buf, 1);
                    193:     *buf->e = '\0';
                    194: }
                    195:
                    196: static void
                    197: buf_reset(struct buffer *buf)
                    198: {
                    199:     buf->e = buf->s;
                    200: }
                    201:
1.148     rillig    202: void
                    203: diag(int level, const char *msg, ...)
                    204: {
                    205:     va_list ap;
                    206:
                    207:     if (level != 0)
                    208:        found_err = true;
                    209:
                    210:     va_start(ap, msg);
                    211:     fprintf(stderr, "%s: %s:%d: ",
                    212:        level == 0 ? "warning" : "error", in_name, line_no);
                    213:     vfprintf(stderr, msg, ap);
                    214:     fprintf(stderr, "\n");
                    215:     va_end(ap);
                    216: }
                    217:
1.189     rillig    218: static void
1.158     rillig    219: search_stmt_newline(bool *force_nl)
1.91      rillig    220: {
1.224     rillig    221:     inp_comment_init_newline();
1.223     rillig    222:     inp_comment_add_char('\n');
                    223:     debug_inp(__func__);
1.91      rillig    224:
1.147     rillig    225:     line_no++;
                    226:
1.91      rillig    227:     /*
1.92      rillig    228:      * We may have inherited a force_nl == true from the previous token (like
                    229:      * a semicolon). But once we know that a newline has been scanned in this
                    230:      * loop, force_nl should be false.
1.91      rillig    231:      *
1.92      rillig    232:      * However, the force_nl == true must be preserved if newline is never
                    233:      * scanned in this loop, so this assignment cannot be done earlier.
1.91      rillig    234:      */
1.104     rillig    235:     *force_nl = false;
1.91      rillig    236: }
                    237:
                    238: static void
1.196     rillig    239: search_stmt_comment(void)
1.91      rillig    240: {
1.224     rillig    241:     inp_comment_init_comment();
1.223     rillig    242:     inp_comment_add_range(token.s, token.e);
1.218     rillig    243:     if (token.e[-1] == '/') {
1.224     rillig    244:        while (inp_peek() != '\n')
1.223     rillig    245:            inp_comment_add_char(inp_next());
                    246:        debug_inp("search_stmt_comment end C99");
1.218     rillig    247:     } else {
1.224     rillig    248:        while (!inp_comment_complete_block())
1.223     rillig    249:            inp_comment_add_char(inp_next());
                    250:        debug_inp("search_stmt_comment end block");
1.91      rillig    251:     }
                    252: }
                    253:
                    254: static bool
1.158     rillig    255: search_stmt_lbrace(void)
1.91      rillig    256: {
                    257:     /*
1.92      rillig    258:      * Put KNF-style lbraces before the buffered up tokens and jump out of
1.117     rillig    259:      * this loop in order to avoid copying the token again.
1.91      rillig    260:      */
1.225     rillig    261:     if (inp_comment_seen() && opt.brace_same_line) {
                    262:        inp_comment_insert_lbrace();
1.91      rillig    263:        /*
1.92      rillig    264:         * Originally the lbrace may have been alone on its own line, but it
                    265:         * will be moved into "the else's line", so if there was a newline
                    266:         * resulting from the "{" before, it must be scanned now and ignored.
1.91      rillig    267:         */
1.228     rillig    268:        while (ch_isspace(inp_peek())) {
1.210     rillig    269:            inp_skip();
1.222     rillig    270:            if (inp_peek() == '\n')
1.91      rillig    271:                break;
                    272:        }
1.223     rillig    273:        debug_inp(__func__);
1.91      rillig    274:        return true;
                    275:     }
                    276:     return false;
                    277: }
                    278:
                    279: static bool
1.158     rillig    280: search_stmt_other(lexer_symbol lsym, bool *force_nl,
1.91      rillig    281:     bool comment_buffered, bool last_else)
                    282: {
                    283:     bool remove_newlines;
                    284:
                    285:     remove_newlines =
1.160     rillig    286:        /* "} else" */
                    287:        (lsym == lsym_else && code.e != code.s && code.e[-1] == '}')
                    288:        /* "else if" */
                    289:        || (lsym == lsym_if && last_else && opt.else_if);
1.91      rillig    290:     if (remove_newlines)
1.104     rillig    291:        *force_nl = false;
1.119     rillig    292:
1.225     rillig    293:     if (!inp_comment_seen()) {
1.158     rillig    294:        ps.search_stmt = false;
1.91      rillig    295:        return false;
                    296:     }
1.119     rillig    297:
1.223     rillig    298:     debug_inp(__func__);
1.225     rillig    299:     inp_comment_rtrim();
1.119     rillig    300:
1.91      rillig    301:     if (opt.swallow_optional_blanklines ||
                    302:        (!comment_buffered && remove_newlines)) {
1.104     rillig    303:        *force_nl = !remove_newlines;
1.225     rillig    304:        inp_comment_rtrim_newline();
1.91      rillig    305:     }
1.119     rillig    306:
1.117     rillig    307:     if (*force_nl) {           /* if we should insert a nl here, put it into
1.91      rillig    308:                                 * the buffer */
1.104     rillig    309:        *force_nl = false;
1.91      rillig    310:        --line_no;              /* this will be re-increased when the newline
                    311:                                 * is read from the buffer */
1.223     rillig    312:        inp_comment_add_char('\n');
                    313:        inp_comment_add_char(' ');
1.117     rillig    314:        if (opt.verbose)        /* warn if the line was not already broken */
1.91      rillig    315:            diag(0, "Line broken");
                    316:     }
1.119     rillig    317:
1.91      rillig    318:     for (const char *t_ptr = token.s; *t_ptr != '\0'; ++t_ptr)
1.223     rillig    319:        inp_comment_add_char(*t_ptr);
                    320:     debug_inp("search_stmt_other end");
1.91      rillig    321:     return true;
                    322: }
                    323:
                    324: static void
                    325: switch_buffer(void)
                    326: {
1.158     rillig    327:     ps.search_stmt = false;
1.223     rillig    328:     inp_comment_add_char(' ');         /* add trailing blank, just in case */
                    329:     inp_from_comment();
1.91      rillig    330: }
                    331:
                    332: static void
1.158     rillig    333: search_stmt_lookahead(lexer_symbol *lsym)
1.91      rillig    334: {
1.156     rillig    335:     if (*lsym == lsym_eof)
1.115     rillig    336:        return;
                    337:
1.91      rillig    338:     /*
1.149     rillig    339:      * The only intended purpose of calling lexi() below is to categorize the
                    340:      * next token in order to decide whether to continue buffering forthcoming
                    341:      * tokens. Once the buffering is over, lexi() will be called again
                    342:      * elsewhere on all of the tokens - this time for normal processing.
1.115     rillig    343:      *
1.149     rillig    344:      * Calling it for this purpose is a bug, because lexi() also changes the
                    345:      * parser state and discards leading whitespace, which is needed mostly
                    346:      * for comment-related considerations.
1.115     rillig    347:      *
1.149     rillig    348:      * Work around the former problem by giving lexi() a copy of the current
                    349:      * parser state and discard it if the call turned out to be just a
                    350:      * lookahead.
1.115     rillig    351:      *
                    352:      * Work around the latter problem by copying all whitespace characters
                    353:      * into the buffer so that the later lexi() call will read them.
1.91      rillig    354:      */
1.225     rillig    355:     if (inp_comment_seen()) {
1.222     rillig    356:        while (ch_isblank(inp_peek()))
1.223     rillig    357:            inp_comment_add_char(inp_next());
                    358:        debug_inp(__func__);
1.115     rillig    359:     }
1.91      rillig    360:
1.165     rillig    361:     struct parser_state backup_ps = ps;
1.179     rillig    362:     debug_println("made backup of parser state");
1.165     rillig    363:     *lsym = lexi();
                    364:     if (*lsym == lsym_newline || *lsym == lsym_form_feed ||
1.166     rillig    365:        *lsym == lsym_comment || ps.search_stmt) {
1.165     rillig    366:        ps = backup_ps;
1.166     rillig    367:        debug_println("rolled back parser state");
                    368:     }
1.91      rillig    369: }
                    370:
1.164     rillig    371: /*
                    372:  * Move newlines and comments following an 'if (expr)', 'while (expr)',
                    373:  * 'else', etc. up to the start of the following statement to a buffer. This
                    374:  * allows proper handling of both kinds of brace placement (-br, -bl) and
                    375:  * "cuddling else" (-ce).
                    376:  */
1.91      rillig    377: static void
1.196     rillig    378: search_stmt(lexer_symbol *lsym, bool *force_nl, bool *last_else)
1.41      rillig    379: {
1.196     rillig    380:     bool comment_buffered = false;
                    381:
1.158     rillig    382:     while (ps.search_stmt) {
1.156     rillig    383:        switch (*lsym) {
                    384:        case lsym_newline:
1.158     rillig    385:            search_stmt_newline(force_nl);
1.59      rillig    386:            break;
1.156     rillig    387:        case lsym_form_feed:
1.217     rillig    388:            /* XXX: Is simply removed from the source code. */
1.41      rillig    389:            break;
1.156     rillig    390:        case lsym_comment:
1.196     rillig    391:            search_stmt_comment();
                    392:            comment_buffered = true;
1.41      rillig    393:            break;
1.156     rillig    394:        case lsym_lbrace:
1.158     rillig    395:            if (search_stmt_lbrace())
1.115     rillig    396:                goto switch_buffer;
1.41      rillig    397:            /* FALLTHROUGH */
1.214     rillig    398:        default:
1.196     rillig    399:            if (!search_stmt_other(*lsym, force_nl, comment_buffered,
                    400:                    *last_else))
1.41      rillig    401:                return;
1.149     rillig    402:     switch_buffer:
1.91      rillig    403:            switch_buffer();
1.41      rillig    404:        }
1.158     rillig    405:        search_stmt_lookahead(lsym);
1.41      rillig    406:     }
1.40      rillig    407:
1.104     rillig    408:     *last_else = false;
1.41      rillig    409: }
1.1       cgd       410:
1.53      rillig    411: static void
                    412: main_init_globals(void)
1.40      rillig    413: {
1.225     rillig    414:     inp_init();
1.173     rillig    415:
1.174     rillig    416:     buf_init(&token);
1.119     rillig    417:
1.174     rillig    418:     buf_init(&lab);
                    419:     buf_init(&code);
1.203     rillig    420:     buf_init(&com);
1.25      kamil     421:
1.182     rillig    422:     ps.s_sym[0] = psym_stmt_list;
1.175     rillig    423:     ps.prev_token = lsym_semicolon;
1.208     rillig    424:     ps.next_col_1 = true;
1.175     rillig    425:
1.53      rillig    426:     const char *suffix = getenv("SIMPLE_BACKUP_SUFFIX");
                    427:     if (suffix != NULL)
1.88      rillig    428:        backup_suffix = suffix;
1.53      rillig    429: }
                    430:
1.131     rillig    431: /*
                    432:  * Copy the input file to the backup file, then make the backup file the input
                    433:  * and the original input file the output.
                    434:  */
                    435: static void
                    436: bakcopy(void)
                    437: {
                    438:     ssize_t n;
                    439:     int bak_fd;
                    440:     char buff[8 * 1024];
                    441:
                    442:     const char *last_slash = strrchr(in_name, '/');
                    443:     snprintf(bakfile, sizeof(bakfile), "%s%s",
1.149     rillig    444:        last_slash != NULL ? last_slash + 1 : in_name, backup_suffix);
1.131     rillig    445:
                    446:     /* copy in_name to backup file */
                    447:     bak_fd = creat(bakfile, 0600);
                    448:     if (bak_fd < 0)
                    449:        err(1, "%s", bakfile);
                    450:
                    451:     while ((n = read(fileno(input), buff, sizeof(buff))) > 0)
                    452:        if (write(bak_fd, buff, (size_t)n) != n)
                    453:            err(1, "%s", bakfile);
                    454:     if (n < 0)
                    455:        err(1, "%s", in_name);
                    456:
                    457:     close(bak_fd);
                    458:     (void)fclose(input);
                    459:
                    460:     /* re-open backup file as the input file */
                    461:     input = fopen(bakfile, "r");
                    462:     if (input == NULL)
                    463:        err(1, "%s", bakfile);
                    464:     /* now the original input file will be the output */
                    465:     output = fopen(in_name, "w");
                    466:     if (output == NULL) {
                    467:        unlink(bakfile);
                    468:        err(1, "%s", in_name);
                    469:     }
                    470: }
                    471:
1.53      rillig    472: static void
1.180     rillig    473: main_load_profiles(int argc, char **argv)
                    474: {
                    475:     const char *profile_name = NULL;
                    476:
                    477:     for (int i = 1; i < argc; ++i) {
                    478:        const char *arg = argv[i];
                    479:
                    480:        if (strcmp(arg, "-npro") == 0)
                    481:            return;
                    482:        if (arg[0] == '-' && arg[1] == 'P' && arg[2] != '\0')
                    483:            profile_name = arg + 2;
                    484:     }
                    485:     load_profiles(profile_name);
                    486: }
                    487:
                    488: static void
1.53      rillig    489: main_parse_command_line(int argc, char **argv)
                    490: {
1.180     rillig    491:     for (int i = 1; i < argc; ++i) {
                    492:        const char *arg = argv[i];
1.1       cgd       493:
1.180     rillig    494:        if (arg[0] == '-') {
                    495:            set_option(arg, "Command line");
1.80      rillig    496:
                    497:        } else if (input == NULL) {
1.180     rillig    498:            in_name = arg;
1.181     rillig    499:            if ((input = fopen(in_name, "r")) == NULL)
1.80      rillig    500:                err(1, "%s", in_name);
                    501:
                    502:        } else if (output == NULL) {
1.180     rillig    503:            out_name = arg;
1.80      rillig    504:            if (strcmp(in_name, out_name) == 0)
                    505:                errx(1, "input and output files must be different");
1.181     rillig    506:            if ((output = fopen(out_name, "w")) == NULL)
1.80      rillig    507:                err(1, "%s", out_name);
1.1       cgd       508:
1.80      rillig    509:        } else
1.180     rillig    510:            errx(1, "too many arguments: %s", arg);
1.80      rillig    511:     }
                    512:
1.181     rillig    513:     if (input == NULL) {
1.25      kamil     514:        input = stdin;
1.181     rillig    515:        output = stdout;
                    516:     } else if (output == NULL) {
                    517:        out_name = in_name;
                    518:        bakcopy();
1.25      kamil     519:     }
                    520:
1.57      rillig    521:     if (opt.comment_column <= 1)
                    522:        opt.comment_column = 2; /* don't put normal comments before column 2 */
1.51      rillig    523:     if (opt.block_comment_max_line_length <= 0)
                    524:        opt.block_comment_max_line_length = opt.max_line_length;
1.100     rillig    525:     if (opt.local_decl_indent < 0)     /* if not specified by user, set this */
1.25      kamil     526:        opt.local_decl_indent = opt.decl_indent;
1.57      rillig    527:     if (opt.decl_comment_column <= 0)  /* if not specified by user, set this */
                    528:        opt.decl_comment_column = opt.ljust_decl
                    529:            ? (opt.comment_column <= 10 ? 2 : opt.comment_column - 8)
                    530:            : opt.comment_column;
1.25      kamil     531:     if (opt.continuation_indent == 0)
1.57      rillig    532:        opt.continuation_indent = opt.indent_size;
1.53      rillig    533: }
                    534:
                    535: static void
                    536: main_prepare_parsing(void)
                    537: {
1.210     rillig    538:     inp_read_line();
1.25      kamil     539:
1.106     rillig    540:     int ind = 0;
1.225     rillig    541:     for (const char *p = inp_p();; p++) {
1.53      rillig    542:        if (*p == ' ')
1.106     rillig    543:            ind++;
1.53      rillig    544:        else if (*p == '\t')
1.136     rillig    545:            ind = next_tab(ind);
1.53      rillig    546:        else
                    547:            break;
1.25      kamil     548:     }
1.137     rillig    549:
1.106     rillig    550:     if (ind >= opt.indent_size)
1.107     rillig    551:        ps.ind_level = ps.ind_level_follow = ind / opt.indent_size;
1.53      rillig    552: }
1.25      kamil     553:
1.131     rillig    554: static void
1.184     rillig    555: code_add_decl_indent(int decl_ind, bool tabs_to_var)
1.131     rillig    556: {
1.184     rillig    557:     int base_ind = ps.ind_level * opt.indent_size;
                    558:     int ind = base_ind + (int)buf_len(&code);
                    559:     int target_ind = base_ind + decl_ind;
1.131     rillig    560:     char *orig_code_e = code.e;
                    561:
1.184     rillig    562:     if (tabs_to_var)
                    563:        for (int next; (next = next_tab(ind)) <= target_ind; ind = next)
1.131     rillig    564:            buf_add_char(&code, '\t');
                    565:
1.184     rillig    566:     for (; ind < target_ind; ind++)
1.131     rillig    567:        buf_add_char(&code, ' ');
                    568:
                    569:     if (code.e == orig_code_e && ps.want_blank) {
1.185     rillig    570:        buf_add_char(&code, ' ');
1.131     rillig    571:        ps.want_blank = false;
                    572:     }
                    573: }
                    574:
1.60      rillig    575: static void __attribute__((__noreturn__))
1.216     rillig    576: process_eof(void)
1.54      rillig    577: {
1.65      rillig    578:     if (lab.s != lab.e || code.s != code.e || com.s != com.e)
1.54      rillig    579:        dump_line();
                    580:
                    581:     if (ps.tos > 1)            /* check for balanced braces */
                    582:        diag(1, "Stuff missing from end of file");
                    583:
                    584:     if (opt.verbose) {
                    585:        printf("There were %d output lines and %d comments\n",
1.86      rillig    586:            ps.stats.lines, ps.stats.comments);
1.54      rillig    587:        printf("(Lines with comments)/(Lines with code): %6.3f\n",
1.86      rillig    588:            (1.0 * ps.stats.comment_lines) / ps.stats.code_lines);
1.54      rillig    589:     }
                    590:
                    591:     fflush(output);
1.83      rillig    592:     exit(found_err ? EXIT_FAILURE : EXIT_SUCCESS);
1.54      rillig    593: }
                    594:
                    595: static void
1.207     rillig    596: maybe_break_line(lexer_symbol lsym, bool *force_nl)
1.54      rillig    597: {
1.207     rillig    598:     if (!*force_nl)
                    599:        return;
                    600:     if (lsym == lsym_semicolon)
                    601:        return;
1.229     rillig    602:     if (lsym == lsym_lbrace && opt.brace_same_line)
1.207     rillig    603:        return;
1.54      rillig    604:
1.207     rillig    605:     if (opt.verbose)
                    606:        diag(0, "Line broken");
                    607:     dump_line();
                    608:     ps.want_blank = false;
                    609:     *force_nl = false;
                    610: }
1.54      rillig    611:
1.207     rillig    612: static void
                    613: move_com_to_code(void)
                    614: {
                    615:     buf_add_char(&code, ' ');
                    616:     buf_add_buf(&code, &com);
                    617:     buf_add_char(&code, ' ');
                    618:     buf_terminate(&code);
                    619:     buf_reset(&com);
                    620:     ps.want_blank = false;
1.54      rillig    621: }
                    622:
                    623: static void
                    624: process_form_feed(void)
                    625: {
1.145     rillig    626:     dump_line_ff();
1.54      rillig    627:     ps.want_blank = false;
                    628: }
                    629:
                    630: static void
                    631: process_newline(void)
                    632: {
1.171     rillig    633:     if (ps.prev_token == lsym_comma && ps.p_l_follow == 0 && !ps.block_init &&
1.141     rillig    634:        !opt.break_after_comma && break_comma &&
                    635:        com.s == com.e)
                    636:        goto stay_in_line;
                    637:
                    638:     dump_line();
                    639:     ps.want_blank = false;
                    640:
                    641: stay_in_line:
1.116     rillig    642:     ++line_no;
1.54      rillig    643: }
                    644:
1.94      rillig    645: static bool
                    646: want_blank_before_lparen(void)
                    647: {
1.95      rillig    648:     if (!ps.want_blank)
                    649:        return false;
1.202     rillig    650:     if (opt.proc_calls_space)
                    651:        return true;
1.171     rillig    652:     if (ps.prev_token == lsym_rparen_or_rbracket)
1.96      rillig    653:        return false;
1.198     rillig    654:     if (ps.prev_token == lsym_offsetof)
1.202     rillig    655:        return false;
1.197     rillig    656:     if (ps.prev_token == lsym_sizeof)
1.202     rillig    657:        return opt.blank_after_sizeof;
1.211     rillig    658:     if (ps.prev_token == lsym_word || ps.prev_token == lsym_funcname)
                    659:        return false;
1.202     rillig    660:     return true;
1.94      rillig    661: }
                    662:
1.54      rillig    663: static void
1.157     rillig    664: process_lparen_or_lbracket(int decl_ind, bool tabs_to_var, bool spaced_expr)
1.54      rillig    665: {
1.146     rillig    666:     if (++ps.p_l_follow == array_length(ps.paren_indents)) {
1.168     rillig    667:        diag(0, "Reached internal limit of %zu unclosed parentheses",
1.146     rillig    668:            array_length(ps.paren_indents));
1.54      rillig    669:        ps.p_l_follow--;
                    670:     }
1.119     rillig    671:
1.93      rillig    672:     if (token.s[0] == '(' && ps.in_decl
1.170     rillig    673:        && !ps.block_init && !ps.decl_indent_done &&
1.226     rillig    674:        !ps.is_function_definition && ps.paren_level == 0) {
1.54      rillig    675:        /* function pointer declarations */
1.170     rillig    676:        code_add_decl_indent(decl_ind, tabs_to_var);
                    677:        ps.decl_indent_done = true;
1.94      rillig    678:     } else if (want_blank_before_lparen())
1.65      rillig    679:        *code.e++ = ' ';
1.54      rillig    680:     ps.want_blank = false;
1.67      rillig    681:     *code.e++ = token.s[0];
1.58      rillig    682:
1.205     rillig    683:     ps.paren_indents[ps.p_l_follow - 1] = (short)ind_add(0, code.s, code.e);
1.135     rillig    684:     debug_println("paren_indents[%d] is now %d",
1.58      rillig    685:        ps.p_l_follow - 1, ps.paren_indents[ps.p_l_follow - 1]);
                    686:
1.157     rillig    687:     if (spaced_expr && ps.p_l_follow == 1 && opt.extra_expr_indent
1.58      rillig    688:            && ps.paren_indents[0] < 2 * opt.indent_size) {
1.103     rillig    689:        ps.paren_indents[0] = (short)(2 * opt.indent_size);
1.135     rillig    690:        debug_println("paren_indents[0] is now %d", ps.paren_indents[0]);
1.58      rillig    691:     }
1.119     rillig    692:
1.134     rillig    693:     if (ps.init_or_struct && *token.s == '(' && ps.tos <= 2) {
1.54      rillig    694:        /*
1.86      rillig    695:         * this is a kluge to make sure that declarations will be aligned
                    696:         * right if proc decl has an explicit type on it, i.e. "int a(x) {..."
1.54      rillig    697:         */
1.156     rillig    698:        parse(psym_semicolon);  /* I said this was a kluge... */
1.134     rillig    699:        ps.init_or_struct = false;
1.54      rillig    700:     }
1.119     rillig    701:
1.54      rillig    702:     /* parenthesized type following sizeof or offsetof is not a cast */
1.200     rillig    703:     if (ps.prev_token == lsym_offsetof || ps.prev_token == lsym_sizeof)
1.54      rillig    704:        ps.not_cast_mask |= 1 << ps.p_l_follow;
                    705: }
                    706:
                    707: static void
1.157     rillig    708: process_rparen_or_rbracket(bool *spaced_expr, bool *force_nl, stmt_head hd)
1.54      rillig    709: {
1.73      rillig    710:     if ((ps.cast_mask & (1 << ps.p_l_follow) & ~ps.not_cast_mask) != 0) {
1.144     rillig    711:        ps.next_unary = true;
1.54      rillig    712:        ps.cast_mask &= (1 << ps.p_l_follow) - 1;
                    713:        ps.want_blank = opt.space_after_cast;
                    714:     } else
                    715:        ps.want_blank = true;
                    716:     ps.not_cast_mask &= (1 << ps.p_l_follow) - 1;
                    717:
1.169     rillig    718:     if (ps.p_l_follow > 0)
                    719:        ps.p_l_follow--;
                    720:     else
1.168     rillig    721:        diag(0, "Extra '%c'", *token.s);
1.54      rillig    722:
1.65      rillig    723:     if (code.e == code.s)      /* if the paren starts the line */
1.54      rillig    724:        ps.paren_level = ps.p_l_follow; /* then indent it */
                    725:
1.67      rillig    726:     *code.e++ = token.s[0];
1.54      rillig    727:
1.157     rillig    728:     if (*spaced_expr && ps.p_l_follow == 0) {  /* check for end of 'if
                    729:                                                 * (...)', or some such */
                    730:        *spaced_expr = false;
1.104     rillig    731:        *force_nl = true;       /* must force newline after if */
1.144     rillig    732:        ps.next_unary = true;
1.231     rillig    733:        ps.in_stmt_or_decl = false;     /* don't use stmt continuation
                    734:                                         * indentation */
1.54      rillig    735:
1.167     rillig    736:        parse_stmt_head(hd);
1.54      rillig    737:     }
1.122     rillig    738:
                    739:     /*
                    740:      * This should ensure that constructs such as main(){...} and int[]{...}
                    741:      * have their braces put in the right place.
                    742:      */
1.158     rillig    743:     ps.search_stmt = opt.brace_same_line;
1.54      rillig    744: }
                    745:
1.206     rillig    746: static bool
                    747: want_blank_before_unary_op(void)
                    748: {
                    749:     if (ps.want_blank)
                    750:        return true;
                    751:     if (token.s[0] == '+' || token.s[0] == '-')
1.213     rillig    752:        return code.e > code.s && code.e[-1] == token.s[0];
1.206     rillig    753:     return false;
                    754: }
                    755:
1.54      rillig    756: static void
1.105     rillig    757: process_unary_op(int decl_ind, bool tabs_to_var)
1.54      rillig    758: {
1.170     rillig    759:     if (!ps.decl_indent_done && ps.in_decl && !ps.block_init &&
1.226     rillig    760:        !ps.is_function_definition && ps.paren_level == 0) {
1.54      rillig    761:        /* pointer declarations */
1.170     rillig    762:        code_add_decl_indent(decl_ind - (int)buf_len(&token), tabs_to_var);
                    763:        ps.decl_indent_done = true;
1.206     rillig    764:     } else if (want_blank_before_unary_op())
1.65      rillig    765:        *code.e++ = ' ';
1.54      rillig    766:
1.112     rillig    767:     buf_add_buf(&code, &token);
1.54      rillig    768:     ps.want_blank = false;
                    769: }
                    770:
                    771: static void
                    772: process_binary_op(void)
                    773: {
1.195     rillig    774:     if (buf_len(&code) > 0)
1.112     rillig    775:        buf_add_char(&code, ' ');
                    776:     buf_add_buf(&code, &token);
1.54      rillig    777:     ps.want_blank = true;
                    778: }
                    779:
                    780: static void
                    781: process_postfix_op(void)
                    782: {
1.67      rillig    783:     *code.e++ = token.s[0];
                    784:     *code.e++ = token.s[1];
1.54      rillig    785:     ps.want_blank = true;
                    786: }
                    787:
                    788: static void
1.152     rillig    789: process_question(int *quest_level)
1.54      rillig    790: {
1.152     rillig    791:     (*quest_level)++;
1.54      rillig    792:     if (ps.want_blank)
1.65      rillig    793:        *code.e++ = ' ';
                    794:     *code.e++ = '?';
1.54      rillig    795:     ps.want_blank = true;
                    796: }
                    797:
                    798: static void
1.152     rillig    799: process_colon(int *quest_level, bool *force_nl, bool *seen_case)
1.54      rillig    800: {
1.152     rillig    801:     if (*quest_level > 0) {    /* part of a '?:' operator */
                    802:        --*quest_level;
1.54      rillig    803:        if (ps.want_blank)
1.65      rillig    804:            *code.e++ = ' ';
                    805:        *code.e++ = ':';
1.54      rillig    806:        ps.want_blank = true;
                    807:        return;
                    808:     }
1.113     rillig    809:
1.149     rillig    810:     if (ps.init_or_struct) {   /* bit-field */
1.65      rillig    811:        *code.e++ = ':';
1.54      rillig    812:        ps.want_blank = false;
                    813:        return;
                    814:     }
                    815:
1.113     rillig    816:     buf_add_buf(&lab, &code);  /* 'case' or 'default' or named label */
1.112     rillig    817:     buf_add_char(&lab, ':');
                    818:     buf_terminate(&lab);
                    819:     buf_reset(&code);
                    820:
1.231     rillig    821:     ps.in_stmt_or_decl = false;
1.113     rillig    822:     ps.is_case_label = *seen_case;
                    823:     *force_nl = *seen_case;
1.105     rillig    824:     *seen_case = false;
1.54      rillig    825:     ps.want_blank = false;
                    826: }
                    827:
                    828: static void
1.152     rillig    829: process_semicolon(bool *seen_case, int *quest_level, int decl_ind,
1.157     rillig    830:     bool tabs_to_var, bool *spaced_expr, stmt_head hd, bool *force_nl)
1.54      rillig    831: {
1.215     rillig    832:     if (ps.decl_level == 0)
1.135     rillig    833:        ps.init_or_struct = false;
1.105     rillig    834:     *seen_case = false;                /* these will only need resetting in an error */
1.152     rillig    835:     *quest_level = 0;
1.171     rillig    836:     if (ps.prev_token == lsym_rparen_or_rbracket)
1.232   ! rillig    837:        ps.in_func_def_params = false;
1.54      rillig    838:     ps.cast_mask = 0;
                    839:     ps.not_cast_mask = 0;
1.73      rillig    840:     ps.block_init = false;
1.54      rillig    841:     ps.block_init_level = 0;
                    842:     ps.just_saw_decl--;
                    843:
1.65      rillig    844:     if (ps.in_decl && code.s == code.e && !ps.block_init &&
1.170     rillig    845:        !ps.decl_indent_done && ps.paren_level == 0) {
1.54      rillig    846:        /* indent stray semicolons in declarations */
1.170     rillig    847:        code_add_decl_indent(decl_ind - 1, tabs_to_var);
                    848:        ps.decl_indent_done = true;
1.54      rillig    849:     }
                    850:
1.215     rillig    851:     ps.in_decl = ps.decl_level > 0;    /* if we were in a first level
1.216     rillig    852:                                         * structure declaration before, we
                    853:                                         * aren't anymore */
1.54      rillig    854:
1.157     rillig    855:     if ((!*spaced_expr || hd != hd_for) && ps.p_l_follow > 0) {
1.54      rillig    856:
                    857:        /*
1.168     rillig    858:         * There were unbalanced parentheses in the statement. It is a bit
1.135     rillig    859:         * complicated, because the semicolon might be in a for statement.
1.54      rillig    860:         */
1.168     rillig    861:        diag(1, "Unbalanced parentheses");
1.54      rillig    862:        ps.p_l_follow = 0;
1.167     rillig    863:        if (*spaced_expr) {     /* 'if', 'while', etc. */
1.157     rillig    864:            *spaced_expr = false;
1.167     rillig    865:            parse_stmt_head(hd);
1.54      rillig    866:        }
                    867:     }
1.65      rillig    868:     *code.e++ = ';';
1.54      rillig    869:     ps.want_blank = true;
1.231     rillig    870:     ps.in_stmt_or_decl = ps.p_l_follow > 0;
1.54      rillig    871:
1.157     rillig    872:     if (!*spaced_expr) {       /* if not if for (;;) */
1.156     rillig    873:        parse(psym_semicolon);  /* let parser know about end of stmt */
1.104     rillig    874:        *force_nl = true;       /* force newline after an end of stmt */
1.54      rillig    875:     }
                    876: }
                    877:
                    878: static void
1.157     rillig    879: process_lbrace(bool *force_nl, bool *spaced_expr, stmt_head hd,
1.105     rillig    880:     int *di_stack, int di_stack_cap, int *decl_ind)
1.54      rillig    881: {
1.231     rillig    882:     ps.in_stmt_or_decl = false;                /* don't indent the {} */
1.119     rillig    883:
1.54      rillig    884:     if (!ps.block_init)
1.104     rillig    885:        *force_nl = true;       /* force other stuff on same line as '{' onto
1.54      rillig    886:                                 * new line */
                    887:     else if (ps.block_init_level <= 0)
                    888:        ps.block_init_level = 1;
                    889:     else
                    890:        ps.block_init_level++;
                    891:
1.65      rillig    892:     if (code.s != code.e && !ps.block_init) {
1.122     rillig    893:        if (!opt.brace_same_line) {
1.54      rillig    894:            dump_line();
                    895:            ps.want_blank = false;
1.232   ! rillig    896:        } else if (ps.in_func_def_params && !ps.init_or_struct) {
1.79      rillig    897:            ps.ind_level_follow = 0;
1.86      rillig    898:            if (opt.function_brace_split) {     /* dump the line prior to the
                    899:                                                 * brace ... */
1.54      rillig    900:                dump_line();
                    901:                ps.want_blank = false;
                    902:            } else              /* add a space between the decl and brace */
                    903:                ps.want_blank = true;
                    904:        }
                    905:     }
1.119     rillig    906:
1.232   ! rillig    907:     if (ps.in_func_def_params)
1.142     rillig    908:        blank_line_before = false;
1.54      rillig    909:
1.168     rillig    910:     if (ps.p_l_follow > 0) {
                    911:        diag(1, "Unbalanced parentheses");
1.54      rillig    912:        ps.p_l_follow = 0;
1.157     rillig    913:        if (*spaced_expr) {     /* check for unclosed 'if', 'for', etc. */
                    914:            *spaced_expr = false;
1.167     rillig    915:            parse_stmt_head(hd);
1.79      rillig    916:            ps.ind_level = ps.ind_level_follow;
1.54      rillig    917:        }
                    918:     }
1.119     rillig    919:
1.65      rillig    920:     if (code.s == code.e)
1.230     rillig    921:        ps.in_stmt_cont = false;        /* don't indent the '{' itself */
1.134     rillig    922:     if (ps.in_decl && ps.init_or_struct) {
1.215     rillig    923:        di_stack[ps.decl_level] = *decl_ind;
                    924:        if (++ps.decl_level == di_stack_cap) {
1.54      rillig    925:            diag(0, "Reached internal limit of %d struct levels",
1.86      rillig    926:                di_stack_cap);
1.215     rillig    927:            ps.decl_level--;
1.54      rillig    928:        }
                    929:     } else {
1.86      rillig    930:        ps.decl_on_line = false;        /* we can't be in the middle of a
                    931:                                         * declaration, so don't do special
                    932:                                         * indentation of comments */
1.232   ! rillig    933:        if (opt.blanklines_after_decl_at_top && ps.in_func_def_params)
1.142     rillig    934:            blank_line_after = true;
1.232   ! rillig    935:        ps.in_func_def_params = false;
1.54      rillig    936:        ps.in_decl = false;
                    937:     }
1.119     rillig    938:
1.105     rillig    939:     *decl_ind = 0;
1.156     rillig    940:     parse(psym_lbrace);
1.116     rillig    941:     if (ps.want_blank)
1.65      rillig    942:        *code.e++ = ' ';
1.54      rillig    943:     ps.want_blank = false;
1.65      rillig    944:     *code.e++ = '{';
1.54      rillig    945:     ps.just_saw_decl = 0;
                    946: }
                    947:
                    948: static void
1.157     rillig    949: process_rbrace(bool *spaced_expr, int *decl_ind, const int *di_stack)
1.54      rillig    950: {
1.156     rillig    951:     if (ps.s_sym[ps.tos] == psym_decl && !ps.block_init) {
                    952:        /* semicolons can be omitted in declarations */
                    953:        parse(psym_semicolon);
                    954:     }
1.119     rillig    955:
1.169     rillig    956:     if (ps.p_l_follow > 0) {   /* check for unclosed if, for, else. */
1.168     rillig    957:        diag(1, "Unbalanced parentheses");
1.54      rillig    958:        ps.p_l_follow = 0;
1.157     rillig    959:        *spaced_expr = false;
1.54      rillig    960:     }
1.119     rillig    961:
1.54      rillig    962:     ps.just_saw_decl = 0;
                    963:     ps.block_init_level--;
1.119     rillig    964:
1.65      rillig    965:     if (code.s != code.e && !ps.block_init) {  /* '}' must be first on line */
1.54      rillig    966:        if (opt.verbose)
                    967:            diag(0, "Line broken");
                    968:        dump_line();
                    969:     }
1.119     rillig    970:
1.65      rillig    971:     *code.e++ = '}';
1.54      rillig    972:     ps.want_blank = true;
1.231     rillig    973:     ps.in_stmt_or_decl = false;
1.230     rillig    974:     ps.in_stmt_cont = false;
1.119     rillig    975:
1.215     rillig    976:     if (ps.decl_level > 0) { /* we are in multi-level structure declaration */
                    977:        *decl_ind = di_stack[--ps.decl_level];
1.232   ! rillig    978:        if (ps.decl_level == 0 && !ps.in_func_def_params) {
1.54      rillig    979:            ps.just_saw_decl = 2;
1.151     rillig    980:            *decl_ind = ps.ind_level == 0
                    981:                ? opt.decl_indent : opt.local_decl_indent;
                    982:        }
1.54      rillig    983:        ps.in_decl = true;
                    984:     }
1.119     rillig    985:
1.142     rillig    986:     blank_line_before = false;
1.156     rillig    987:     parse(psym_rbrace);
1.158     rillig    988:     ps.search_stmt = opt.cuddle_else
1.156     rillig    989:        && ps.s_sym[ps.tos] == psym_if_expr_stmt
1.143     rillig    990:        && ps.s_ind_level[ps.tos] >= ps.ind_level;
1.119     rillig    991:
1.215     rillig    992:     if (ps.tos <= 1 && opt.blanklines_after_procs && ps.decl_level <= 0)
1.142     rillig    993:        blank_line_after = true;
1.54      rillig    994: }
                    995:
                    996: static void
1.209     rillig    997: process_do(bool *force_nl, bool *last_else)
1.54      rillig    998: {
1.231     rillig    999:     ps.in_stmt_or_decl = false;
1.119     rillig   1000:
1.127     rillig   1001:     if (code.e != code.s) {    /* make sure this starts a line */
                   1002:        if (opt.verbose)
                   1003:            diag(0, "Line broken");
                   1004:        dump_line();
                   1005:        ps.want_blank = false;
                   1006:     }
1.119     rillig   1007:
1.127     rillig   1008:     *force_nl = true;          /* following stuff must go onto new line */
                   1009:     *last_else = false;
1.156     rillig   1010:     parse(psym_do);
1.127     rillig   1011: }
1.119     rillig   1012:
1.127     rillig   1013: static void
1.209     rillig   1014: process_else(bool *force_nl, bool *last_else)
1.127     rillig   1015: {
1.231     rillig   1016:     ps.in_stmt_or_decl = false;
1.119     rillig   1017:
1.214     rillig   1018:     if (code.e > code.s && !(opt.cuddle_else && code.e[-1] == '}')) {
1.127     rillig   1019:        if (opt.verbose)
                   1020:            diag(0, "Line broken");
                   1021:        dump_line();            /* make sure this starts a line */
                   1022:        ps.want_blank = false;
1.54      rillig   1023:     }
1.127     rillig   1024:
                   1025:     *force_nl = true;          /* following stuff must go onto new line */
                   1026:     *last_else = true;
1.156     rillig   1027:     parse(psym_else);
1.54      rillig   1028: }
                   1029:
                   1030: static void
1.164     rillig   1031: process_type(int *decl_ind, bool *tabs_to_var)
1.54      rillig   1032: {
1.156     rillig   1033:     parse(psym_decl);          /* let the parser worry about indentation */
1.119     rillig   1034:
1.171     rillig   1035:     if (ps.prev_token == lsym_rparen_or_rbracket && ps.tos <= 1) {
1.65      rillig   1036:        if (code.s != code.e) {
1.54      rillig   1037:            dump_line();
1.73      rillig   1038:            ps.want_blank = false;
1.54      rillig   1039:        }
                   1040:     }
1.119     rillig   1041:
1.232   ! rillig   1042:     if (ps.in_func_def_params && opt.indent_parameters &&
1.215     rillig   1043:            ps.decl_level == 0) {
1.79      rillig   1044:        ps.ind_level = ps.ind_level_follow = 1;
1.230     rillig   1045:        ps.in_stmt_cont = false;
1.54      rillig   1046:     }
1.119     rillig   1047:
1.134     rillig   1048:     ps.init_or_struct = /* maybe */ true;
1.171     rillig   1049:     ps.in_decl = ps.decl_on_line = ps.prev_token != lsym_typedef;
1.215     rillig   1050:     if (ps.decl_level <= 0)
1.54      rillig   1051:        ps.just_saw_decl = 2;
1.119     rillig   1052:
1.142     rillig   1053:     blank_line_before = false;
1.54      rillig   1054:
1.132     rillig   1055:     int len = (int)buf_len(&token) + 1;
1.215     rillig   1056:     int ind = ps.ind_level == 0 || ps.decl_level > 0
1.149     rillig   1057:        ? opt.decl_indent       /* global variable or local member */
                   1058:        : opt.local_decl_indent;        /* local variable */
1.132     rillig   1059:     *decl_ind = ind > 0 ? ind : len;
                   1060:     *tabs_to_var = opt.use_tabs && ind > 0;
1.54      rillig   1061: }
                   1062:
                   1063: static void
1.156     rillig   1064: process_ident(lexer_symbol lsym, int decl_ind, bool tabs_to_var,
1.157     rillig   1065:     bool *spaced_expr, bool *force_nl, stmt_head hd)
1.54      rillig   1066: {
                   1067:     if (ps.in_decl) {
1.156     rillig   1068:        if (lsym == lsym_funcname) {
1.54      rillig   1069:            ps.in_decl = false;
1.65      rillig   1070:            if (opt.procnames_start_line && code.s != code.e) {
                   1071:                *code.e = '\0';
1.54      rillig   1072:                dump_line();
                   1073:            } else if (ps.want_blank) {
1.65      rillig   1074:                *code.e++ = ' ';
1.54      rillig   1075:            }
                   1076:            ps.want_blank = false;
1.119     rillig   1077:
1.170     rillig   1078:        } else if (!ps.block_init && !ps.decl_indent_done &&
                   1079:            ps.paren_level == 0) {
                   1080:            code_add_decl_indent(decl_ind, tabs_to_var);
                   1081:            ps.decl_indent_done = true;
1.54      rillig   1082:            ps.want_blank = false;
                   1083:        }
1.119     rillig   1084:
1.157     rillig   1085:     } else if (*spaced_expr && ps.p_l_follow == 0) {
                   1086:        *spaced_expr = false;
1.104     rillig   1087:        *force_nl = true;
1.144     rillig   1088:        ps.next_unary = true;
1.231     rillig   1089:        ps.in_stmt_or_decl = false;
1.167     rillig   1090:        parse_stmt_head(hd);
1.54      rillig   1091:     }
                   1092: }
                   1093:
                   1094: static void
1.111     rillig   1095: copy_token(void)
1.54      rillig   1096: {
                   1097:     if (ps.want_blank)
1.112     rillig   1098:        buf_add_char(&code, ' ');
                   1099:     buf_add_buf(&code, &token);
1.54      rillig   1100: }
                   1101:
                   1102: static void
                   1103: process_string_prefix(void)
                   1104: {
1.112     rillig   1105:     copy_token();
1.54      rillig   1106:     ps.want_blank = false;
                   1107: }
                   1108:
                   1109: static void
                   1110: process_period(void)
                   1111: {
1.213     rillig   1112:     if (code.e > code.s && code.e[-1] == ',')
1.85      rillig   1113:        *code.e++ = ' ';
1.102     rillig   1114:     *code.e++ = '.';
                   1115:     ps.want_blank = false;
1.54      rillig   1116: }
                   1117:
                   1118: static void
1.105     rillig   1119: process_comma(int decl_ind, bool tabs_to_var, bool *force_nl)
1.54      rillig   1120: {
1.135     rillig   1121:     ps.want_blank = code.s != code.e;  /* only put blank after comma if comma
1.86      rillig   1122:                                         * does not start the line */
1.119     rillig   1123:
1.226     rillig   1124:     if (ps.in_decl && !ps.is_function_definition && !ps.block_init &&
1.170     rillig   1125:        !ps.decl_indent_done && ps.paren_level == 0) {
1.54      rillig   1126:        /* indent leading commas and not the actual identifiers */
1.170     rillig   1127:        code_add_decl_indent(decl_ind - 1, tabs_to_var);
                   1128:        ps.decl_indent_done = true;
1.54      rillig   1129:     }
1.119     rillig   1130:
1.65      rillig   1131:     *code.e++ = ',';
1.119     rillig   1132:
1.54      rillig   1133:     if (ps.p_l_follow == 0) {
                   1134:        if (ps.block_init_level <= 0)
1.73      rillig   1135:            ps.block_init = false;
1.186     rillig   1136:        int varname_len = 8;    /* rough estimate for the length of a typical
                   1137:                                 * variable name */
1.87      rillig   1138:        if (break_comma && (opt.break_after_comma ||
1.205     rillig   1139:                ind_add(compute_code_indent(), code.s, code.e)
1.186     rillig   1140:                >= opt.max_line_length - varname_len))
1.104     rillig   1141:            *force_nl = true;
1.54      rillig   1142:     }
                   1143: }
                   1144:
1.112     rillig   1145: /* move the whole line to the 'label' buffer */
1.54      rillig   1146: static void
1.115     rillig   1147: read_preprocessing_line(void)
1.54      rillig   1148: {
1.129     rillig   1149:     enum {
                   1150:        PLAIN, STR, CHR, COMM
                   1151:     } state;
                   1152:
1.112     rillig   1153:     buf_add_char(&lab, '#');
1.54      rillig   1154:
1.129     rillig   1155:     state = PLAIN;
1.115     rillig   1156:     int com_start = 0, com_end = 0;
                   1157:
1.222     rillig   1158:     while (ch_isblank(inp_peek()))
1.210     rillig   1159:        inp_skip();
1.115     rillig   1160:
1.222     rillig   1161:     while (inp_peek() != '\n' || (state == COMM && !had_eof)) {
1.115     rillig   1162:        buf_reserve(&lab, 2);
1.210     rillig   1163:        *lab.e++ = inp_next();
1.115     rillig   1164:        switch (lab.e[-1]) {
                   1165:        case '\\':
1.129     rillig   1166:            if (state != COMM)
1.210     rillig   1167:                *lab.e++ = inp_next();
1.115     rillig   1168:            break;
                   1169:        case '/':
1.222     rillig   1170:            if (inp_peek() == '*' && state == PLAIN) {
1.129     rillig   1171:                state = COMM;
1.222     rillig   1172:                *lab.e++ = inp_next();
1.115     rillig   1173:                com_start = (int)buf_len(&lab) - 2;
                   1174:            }
                   1175:            break;
                   1176:        case '"':
1.129     rillig   1177:            if (state == STR)
                   1178:                state = PLAIN;
                   1179:            else if (state == PLAIN)
                   1180:                state = STR;
1.115     rillig   1181:            break;
                   1182:        case '\'':
1.129     rillig   1183:            if (state == CHR)
                   1184:                state = PLAIN;
                   1185:            else if (state == PLAIN)
                   1186:                state = CHR;
1.115     rillig   1187:            break;
                   1188:        case '*':
1.222     rillig   1189:            if (inp_peek() == '/' && state == COMM) {
1.129     rillig   1190:                state = PLAIN;
1.222     rillig   1191:                *lab.e++ = inp_next();
1.115     rillig   1192:                com_end = (int)buf_len(&lab);
1.54      rillig   1193:            }
1.115     rillig   1194:            break;
1.54      rillig   1195:        }
1.115     rillig   1196:     }
1.54      rillig   1197:
1.177     rillig   1198:     while (lab.e > lab.s && ch_isblank(lab.e[-1]))
1.115     rillig   1199:        lab.e--;
1.225     rillig   1200:     if (lab.e - lab.s == com_end && !inp_comment_seen()) {
1.115     rillig   1201:        /* comment on preprocessor line */
1.225     rillig   1202:        inp_comment_init_preproc();
1.223     rillig   1203:        inp_comment_add_range(lab.s + com_start, lab.s + com_end);
1.115     rillig   1204:        lab.e = lab.s + com_start;
1.177     rillig   1205:        while (lab.e > lab.s && ch_isblank(lab.e[-1]))
1.63      rillig   1206:            lab.e--;
1.223     rillig   1207:        inp_comment_add_char(' ');      /* add trailing blank, just in case */
1.225     rillig   1208:        inp_from_comment();
1.54      rillig   1209:     }
1.115     rillig   1210:     buf_terminate(&lab);
                   1211: }
                   1212:
                   1213: static void
                   1214: process_preprocessing(void)
                   1215: {
                   1216:     if (com.s != com.e || lab.s != lab.e || code.s != code.e)
                   1217:        dump_line();
                   1218:
                   1219:     read_preprocessing_line();
                   1220:
                   1221:     ps.is_case_label = false;
1.54      rillig   1222:
1.86      rillig   1223:     if (strncmp(lab.s, "#if", 3) == 0) {       /* also ifdef, ifndef */
1.146     rillig   1224:        if ((size_t)ifdef_level < array_length(state_stack))
1.54      rillig   1225:            state_stack[ifdef_level++] = ps;
1.88      rillig   1226:        else
1.54      rillig   1227:            diag(1, "#if stack overflow");
1.119     rillig   1228:
1.86      rillig   1229:     } else if (strncmp(lab.s, "#el", 3) == 0) {        /* else, elif */
1.54      rillig   1230:        if (ifdef_level <= 0)
1.63      rillig   1231:            diag(1, lab.s[3] == 'i' ? "Unmatched #elif" : "Unmatched #else");
1.88      rillig   1232:        else
1.54      rillig   1233:            ps = state_stack[ifdef_level - 1];
1.119     rillig   1234:
1.63      rillig   1235:     } else if (strncmp(lab.s, "#endif", 6) == 0) {
1.54      rillig   1236:        if (ifdef_level <= 0)
                   1237:            diag(1, "Unmatched #endif");
                   1238:        else
                   1239:            ifdef_level--;
1.119     rillig   1240:
1.54      rillig   1241:     } else {
1.63      rillig   1242:        if (strncmp(lab.s + 1, "pragma", 6) != 0 &&
                   1243:            strncmp(lab.s + 1, "error", 5) != 0 &&
                   1244:            strncmp(lab.s + 1, "line", 4) != 0 &&
                   1245:            strncmp(lab.s + 1, "undef", 5) != 0 &&
                   1246:            strncmp(lab.s + 1, "define", 6) != 0 &&
                   1247:            strncmp(lab.s + 1, "include", 7) != 0) {
1.54      rillig   1248:            diag(1, "Unrecognized cpp directive");
                   1249:            return;
                   1250:        }
                   1251:     }
1.119     rillig   1252:
1.54      rillig   1253:     if (opt.blanklines_around_conditional_compilation) {
1.142     rillig   1254:        blank_line_after = true;
1.140     rillig   1255:        blank_lines_to_output = 0;
1.54      rillig   1256:     } else {
1.142     rillig   1257:        blank_line_after = false;
                   1258:        blank_line_before = false;
1.54      rillig   1259:     }
                   1260:
                   1261:     /*
                   1262:      * subsequent processing of the newline character will cause the line to
                   1263:      * be printed
                   1264:      */
                   1265: }
                   1266:
1.60      rillig   1267: static void __attribute__((__noreturn__))
1.53      rillig   1268: main_loop(void)
                   1269: {
1.150     rillig   1270:     bool force_nl = false;     /* when true, code must be broken */
1.75      rillig   1271:     bool last_else = false;    /* true iff last keyword was an else */
1.150     rillig   1272:     int decl_ind = 0;          /* current indentation for declarations */
1.86      rillig   1273:     int di_stack[20];          /* a stack of structure indentation levels */
1.150     rillig   1274:     bool tabs_to_var = false;  /* true if using tabs to indent to var name */
1.157     rillig   1275:     bool spaced_expr = false;  /* whether we are in the expression of
1.53      rillig   1276:                                 * if(...), while(...), etc. */
1.160     rillig   1277:     stmt_head hd = hd_0;       /* the type of statement for 'if (...)', 'for
                   1278:                                 * (...)', etc */
1.152     rillig   1279:     int quest_level = 0;       /* when this is positive, we have seen a '?'
                   1280:                                 * without the matching ':' in a '?:'
                   1281:                                 * expression */
1.150     rillig   1282:     bool seen_case = false;    /* set to true when we see a 'case', so we
1.53      rillig   1283:                                 * know what to do with the following colon */
                   1284:
1.215     rillig   1285:     di_stack[ps.decl_level = 0] = 0;
1.1       cgd      1286:
1.196     rillig   1287:     for (;;) {                 /* loop until we reach eof */
                   1288:        lexer_symbol lsym = lexi();
1.1       cgd      1289:
1.196     rillig   1290:        search_stmt(&lsym, &force_nl, &last_else);
1.25      kamil    1291:
1.156     rillig   1292:        if (lsym == lsym_eof) {
1.216     rillig   1293:            process_eof();
1.60      rillig   1294:            /* NOTREACHED */
1.54      rillig   1295:        }
1.25      kamil    1296:
1.156     rillig   1297:        if (lsym == lsym_newline || lsym == lsym_form_feed ||
                   1298:                lsym == lsym_preprocessing)
1.130     rillig   1299:            force_nl = false;
1.207     rillig   1300:        else if (lsym != lsym_comment) {
                   1301:            maybe_break_line(lsym, &force_nl);
1.231     rillig   1302:            ps.in_stmt_or_decl = true;  /* add an extra level of indentation;
                   1303:                                         * turned off again by a ';' or '}' */
1.207     rillig   1304:            if (com.s != com.e)
                   1305:                move_com_to_code();
                   1306:        }
1.25      kamil    1307:
1.112     rillig   1308:        buf_reserve(&code, 3);  /* space for 2 characters plus '\0' */
1.1       cgd      1309:
1.156     rillig   1310:        switch (lsym) {
1.25      kamil    1311:
1.156     rillig   1312:        case lsym_form_feed:
1.54      rillig   1313:            process_form_feed();
1.25      kamil    1314:            break;
                   1315:
1.156     rillig   1316:        case lsym_newline:
1.54      rillig   1317:            process_newline();
1.25      kamil    1318:            break;
                   1319:
1.156     rillig   1320:        case lsym_lparen_or_lbracket:
1.157     rillig   1321:            process_lparen_or_lbracket(decl_ind, tabs_to_var, spaced_expr);
1.25      kamil    1322:            break;
                   1323:
1.156     rillig   1324:        case lsym_rparen_or_rbracket:
1.157     rillig   1325:            process_rparen_or_rbracket(&spaced_expr, &force_nl, hd);
1.25      kamil    1326:            break;
                   1327:
1.156     rillig   1328:        case lsym_unary_op:
1.105     rillig   1329:            process_unary_op(decl_ind, tabs_to_var);
1.25      kamil    1330:            break;
                   1331:
1.156     rillig   1332:        case lsym_binary_op:
1.54      rillig   1333:            process_binary_op();
1.25      kamil    1334:            break;
                   1335:
1.156     rillig   1336:        case lsym_postfix_op:
1.54      rillig   1337:            process_postfix_op();
1.25      kamil    1338:            break;
                   1339:
1.156     rillig   1340:        case lsym_question:
1.152     rillig   1341:            process_question(&quest_level);
1.25      kamil    1342:            break;
                   1343:
1.164     rillig   1344:        case lsym_case_label:
1.116     rillig   1345:            seen_case = true;
1.111     rillig   1346:            goto copy_token;
1.25      kamil    1347:
1.156     rillig   1348:        case lsym_colon:
1.152     rillig   1349:            process_colon(&quest_level, &force_nl, &seen_case);
1.25      kamil    1350:            break;
                   1351:
1.156     rillig   1352:        case lsym_semicolon:
1.152     rillig   1353:            process_semicolon(&seen_case, &quest_level, decl_ind, tabs_to_var,
1.157     rillig   1354:                &spaced_expr, hd, &force_nl);
1.25      kamil    1355:            break;
                   1356:
1.156     rillig   1357:        case lsym_lbrace:
1.157     rillig   1358:            process_lbrace(&force_nl, &spaced_expr, hd, di_stack,
1.146     rillig   1359:                (int)array_length(di_stack), &decl_ind);
1.25      kamil    1360:            break;
                   1361:
1.156     rillig   1362:        case lsym_rbrace:
1.157     rillig   1363:            process_rbrace(&spaced_expr, &decl_ind, di_stack);
1.25      kamil    1364:            break;
                   1365:
1.156     rillig   1366:        case lsym_switch:
1.157     rillig   1367:            spaced_expr = true; /* the interesting stuff is done after the
1.156     rillig   1368:                                 * expressions are scanned */
                   1369:            hd = hd_switch;     /* remember the type of header for later use
1.164     rillig   1370:                                 * by the parser */
1.111     rillig   1371:            goto copy_token;
1.25      kamil    1372:
1.156     rillig   1373:        case lsym_for:
1.157     rillig   1374:            spaced_expr = true;
1.156     rillig   1375:            hd = hd_for;
1.154     rillig   1376:            goto copy_token;
1.25      kamil    1377:
1.156     rillig   1378:        case lsym_if:
1.157     rillig   1379:            spaced_expr = true;
1.156     rillig   1380:            hd = hd_if;
1.154     rillig   1381:            goto copy_token;
                   1382:
1.156     rillig   1383:        case lsym_while:
1.157     rillig   1384:            spaced_expr = true;
1.156     rillig   1385:            hd = hd_while;
1.111     rillig   1386:            goto copy_token;
1.25      kamil    1387:
1.156     rillig   1388:        case lsym_do:
1.209     rillig   1389:            process_do(&force_nl, &last_else);
1.153     rillig   1390:            goto copy_token;
                   1391:
1.156     rillig   1392:        case lsym_else:
1.209     rillig   1393:            process_else(&force_nl, &last_else);
1.111     rillig   1394:            goto copy_token;
1.25      kamil    1395:
1.156     rillig   1396:        case lsym_typedef:
                   1397:        case lsym_storage_class:
1.142     rillig   1398:            blank_line_before = false;
1.111     rillig   1399:            goto copy_token;
1.25      kamil    1400:
1.156     rillig   1401:        case lsym_tag:
1.25      kamil    1402:            if (ps.p_l_follow > 0)
1.111     rillig   1403:                goto copy_token;
1.25      kamil    1404:            /* FALLTHROUGH */
1.212     rillig   1405:        case lsym_type_outside_parentheses:
1.164     rillig   1406:            process_type(&decl_ind, &tabs_to_var);
1.111     rillig   1407:            goto copy_token;
1.25      kamil    1408:
1.211     rillig   1409:        case lsym_type_in_parentheses:
1.198     rillig   1410:        case lsym_offsetof:
1.197     rillig   1411:        case lsym_sizeof:
1.211     rillig   1412:        case lsym_word:
1.156     rillig   1413:        case lsym_funcname:
1.204     rillig   1414:        case lsym_return:
1.157     rillig   1415:            process_ident(lsym, decl_ind, tabs_to_var, &spaced_expr,
                   1416:                &force_nl, hd);
1.111     rillig   1417:     copy_token:
                   1418:            copy_token();
1.156     rillig   1419:            if (lsym != lsym_funcname)
1.25      kamil    1420:                ps.want_blank = true;
                   1421:            break;
                   1422:
1.156     rillig   1423:        case lsym_string_prefix:
1.54      rillig   1424:            process_string_prefix();
1.25      kamil    1425:            break;
1.1       cgd      1426:
1.156     rillig   1427:        case lsym_period:
1.54      rillig   1428:            process_period();
1.25      kamil    1429:            break;
                   1430:
1.156     rillig   1431:        case lsym_comma:
1.105     rillig   1432:            process_comma(decl_ind, tabs_to_var, &force_nl);
1.25      kamil    1433:            break;
                   1434:
1.164     rillig   1435:        case lsym_preprocessing:
1.54      rillig   1436:            process_preprocessing();
                   1437:            break;
1.119     rillig   1438:
1.164     rillig   1439:        case lsym_comment:
1.56      rillig   1440:            process_comment();
1.25      kamil    1441:            break;
1.30      rillig   1442:
                   1443:        default:
                   1444:            break;
1.64      rillig   1445:        }
1.25      kamil    1446:
1.65      rillig   1447:        *code.e = '\0';
1.156     rillig   1448:        if (lsym != lsym_comment && lsym != lsym_newline &&
                   1449:                lsym != lsym_preprocessing)
1.171     rillig   1450:            ps.prev_token = lsym;
1.53      rillig   1451:     }
                   1452: }
                   1453:
                   1454: int
                   1455: main(int argc, char **argv)
                   1456: {
                   1457:     main_init_globals();
1.180     rillig   1458:     main_load_profiles(argc, argv);
1.53      rillig   1459:     main_parse_command_line(argc, argv);
                   1460: #if HAVE_CAPSICUM
                   1461:     init_capsicum();
                   1462: #endif
                   1463:     main_prepare_parsing();
                   1464:     main_loop();
1.25      kamil    1465: }
1.6       lukem    1466:
1.48      rillig   1467: #ifdef debug
                   1468: void
                   1469: debug_printf(const char *fmt, ...)
                   1470: {
                   1471:     FILE *f = output == stdout ? stderr : stdout;
                   1472:     va_list ap;
                   1473:
                   1474:     va_start(ap, fmt);
                   1475:     vfprintf(f, fmt, ap);
                   1476:     va_end(ap);
                   1477: }
                   1478:
                   1479: void
                   1480: debug_println(const char *fmt, ...)
                   1481: {
                   1482:     FILE *f = output == stdout ? stderr : stdout;
                   1483:     va_list ap;
                   1484:
                   1485:     va_start(ap, fmt);
                   1486:     vfprintf(f, fmt, ap);
                   1487:     va_end(ap);
                   1488:     fprintf(f, "\n");
                   1489: }
                   1490:
                   1491: void
                   1492: debug_vis_range(const char *prefix, const char *s, const char *e,
1.86      rillig   1493:     const char *suffix)
1.48      rillig   1494: {
                   1495:     debug_printf("%s", prefix);
                   1496:     for (const char *p = s; p < e; p++) {
1.159     rillig   1497:        if (*p == '\\' || *p == '"')
                   1498:            debug_printf("\\%c", *p);
                   1499:        else if (isprint((unsigned char)*p))
1.48      rillig   1500:            debug_printf("%c", *p);
                   1501:        else if (*p == '\n')
                   1502:            debug_printf("\\n");
                   1503:        else if (*p == '\t')
                   1504:            debug_printf("\\t");
                   1505:        else
1.162     rillig   1506:            debug_printf("\\x%02x", (unsigned char)*p);
1.48      rillig   1507:     }
                   1508:     debug_printf("%s", suffix);
                   1509: }
                   1510: #endif
1.68      rillig   1511:
                   1512: static void *
                   1513: nonnull(void *p)
                   1514: {
                   1515:     if (p == NULL)
                   1516:        err(EXIT_FAILURE, NULL);
                   1517:     return p;
                   1518: }
                   1519:
                   1520: void *
                   1521: xmalloc(size_t size)
                   1522: {
                   1523:     return nonnull(malloc(size));
                   1524: }
                   1525:
                   1526: void *
                   1527: xrealloc(void *p, size_t new_size)
                   1528: {
                   1529:     return nonnull(realloc(p, new_size));
                   1530: }
                   1531:
                   1532: char *
                   1533: xstrdup(const char *s)
                   1534: {
                   1535:     return nonnull(strdup(s));
                   1536: }

CVSweb <webmaster@jp.NetBSD.org>