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

Annotation of src/usr.bin/indent/indent.h, Revision 1.49

1.49    ! rillig      1: /*     $NetBSD: indent.h,v 1.48 2021/10/24 22:44:13 rillig Exp $       */
1.1       kamil       2:
                      3: /*-
                      4:  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
                      5:  *
                      6:  * Copyright (c) 2001 Jens Schweikhardt
                      7:  * All rights reserved.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  *
                     18:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
                     19:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     20:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     21:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
                     22:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     23:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     24:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     25:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     26:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     27:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     28:  * SUCH DAMAGE.
                     29:  */
1.31      rillig     30: /*-
                     31:  * SPDX-License-Identifier: BSD-4-Clause
                     32:  *
                     33:  * Copyright (c) 1985 Sun Microsystems, Inc.
                     34:  * Copyright (c) 1980, 1993
                     35:  *     The Regents of the University of California.  All rights reserved.
                     36:  * All rights reserved.
                     37:  *
                     38:  * Redistribution and use in source and binary forms, with or without
                     39:  * modification, are permitted provided that the following conditions
                     40:  * are met:
                     41:  * 1. Redistributions of source code must retain the above copyright
                     42:  *    notice, this list of conditions and the following disclaimer.
                     43:  * 2. Redistributions in binary form must reproduce the above copyright
                     44:  *    notice, this list of conditions and the following disclaimer in the
                     45:  *    documentation and/or other materials provided with the distribution.
                     46:  * 3. All advertising materials mentioning features or use of this software
                     47:  *    must display the following acknowledgement:
                     48:  *     This product includes software developed by the University of
                     49:  *     California, Berkeley and its contributors.
                     50:  * 4. Neither the name of the University nor the names of its contributors
                     51:  *    may be used to endorse or promote products derived from this software
                     52:  *    without specific prior written permission.
                     53:  *
                     54:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     55:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     56:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     57:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     58:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     59:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     60:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     61:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     62:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     63:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     64:  * SUCH DAMAGE.
                     65:  */
1.1       kamil      66:
                     67: #if 0
                     68: __FBSDID("$FreeBSD: head/usr.bin/indent/indent.h 336333 2018-07-16 05:46:50Z pstef $");
                     69: #endif
                     70:
1.20      rillig     71: #include <stdbool.h>
                     72:
1.49    ! rillig     73: typedef enum lexer_symbol {
        !            74:     lsym_eof,
        !            75:     lsym_preprocessing,                /* '#' */
        !            76:     lsym_newline,
        !            77:     lsym_form_feed,
        !            78:     lsym_comment,
        !            79:     lsym_lparen_or_lbracket,
        !            80:     lsym_rparen_or_rbracket,
        !            81:     lsym_lbrace,
        !            82:     lsym_rbrace,
        !            83:     lsym_period,
        !            84:     lsym_unary_op,             /* e.g. '+' or '&' */
        !            85:     lsym_binary_op,            /* e.g. '<<' or '+' or '&&' or '/=' */
        !            86:     lsym_postfix_op,           /* trailing '++' or '--' */
        !            87:     lsym_question,             /* the '?' from a '?:' expression */
        !            88:     lsym_colon,
        !            89:     lsym_comma,
        !            90:     lsym_semicolon,
        !            91:     lsym_typedef,
        !            92:     lsym_storage_class,
        !            93:     lsym_type,
        !            94:     lsym_tag,                  /* 'struct', 'union', 'enum' */
        !            95:     lsym_case_label,
        !            96:     lsym_string_prefix,                /* 'L' */
        !            97:     lsym_ident,                        /* identifier, constant or string */
        !            98:     lsym_funcname,
        !            99:     lsym_do,
        !           100:     lsym_else,
        !           101:     lsym_for,
        !           102:     lsym_if,
        !           103:     lsym_switch,
        !           104:     lsym_while,
        !           105: } lexer_symbol;
        !           106:
        !           107: typedef enum parser_symbol {
        !           108:     psym_semicolon,            /* rather a placeholder than a semicolon */
        !           109:     psym_lbrace,
        !           110:     psym_rbrace,
        !           111:     psym_decl,
        !           112:     psym_stmt,
        !           113:     psym_stmt_list,
        !           114:     psym_for_exprs,            /* 'for' '(' ... ')' */
        !           115:     psym_if_expr,              /* 'if' '(' expr ')' */
        !           116:     psym_if_expr_stmt,         /* 'if' '(' expr ')' stmt */
        !           117:     psym_if_expr_stmt_else,    /* 'if' '(' expr ')' stmt 'else' */
        !           118:     psym_else,                 /* 'else' */
        !           119:     psym_switch_expr,          /* 'switch' '(' expr ')' */
        !           120:     psym_do,                   /* 'do' */
        !           121:     psym_do_stmt,              /* 'do' stmt */
        !           122:     psym_while_expr,           /* 'while' '(' expr ')' */
        !           123: } parser_symbol;
        !           124:
        !           125: typedef enum stmt_head {
        !           126:     hd_0,                      /* placeholder for uninitialized */
        !           127:     hd_for,
        !           128:     hd_if,
        !           129:     hd_switch,
        !           130:     hd_while,
        !           131: } stmt_head;
1.31      rillig    132:
                    133: #define sc_size 5000           /* size of save_com buffer */
                    134: #define label_offset 2         /* number of levels a label is placed to left
                    135:                                 * of code */
                    136:
                    137:
                    138: struct buffer {
                    139:     char *buf;                 /* buffer */
                    140:     char *s;                   /* start */
                    141:     char *e;                   /* end */
                    142:     char *l;                   /* limit */
                    143: };
                    144:
1.34      rillig    145: extern FILE *input;
                    146: extern FILE *output;
1.31      rillig    147:
1.34      rillig    148: extern struct buffer lab;      /* label or preprocessor directive */
                    149: extern struct buffer code;     /* code */
                    150: extern struct buffer com;      /* comment */
                    151: extern struct buffer token;    /* the last token scanned */
1.31      rillig    152:
                    153: extern struct buffer inp;
                    154:
1.34      rillig    155: extern char sc_buf[sc_size];   /* input text is saved here when looking for
1.31      rillig    156:                                 * the brace after an if, while, etc */
1.34      rillig    157: extern char *save_com;         /* start of the comment stored in sc_buf */
1.31      rillig    158:
1.34      rillig    159: extern char *saved_inp_s;      /* saved value of inp.s when taking input from
                    160:                                 * save_com */
                    161: extern char *saved_inp_e;      /* similarly saved value of inp.e */
1.31      rillig    162:
                    163:
                    164: extern struct options {
1.34      rillig    165:     bool blanklines_around_conditional_compilation;
                    166:     bool blanklines_after_decl_at_top; /* this is vaguely similar to
                    167:                                         * blanklines_after_decl except that
                    168:                                         * it only applies to the first set of
                    169:                                         * declarations in a procedure (just
                    170:                                         * after the first '{') and it causes
                    171:                                         * a blank line to be generated even
                    172:                                         * if there are no declarations */
                    173:     bool blanklines_after_decl;
                    174:     bool blanklines_after_procs;
                    175:     bool blanklines_before_block_comments;
                    176:     bool break_after_comma;    /* whether to break declarations after commas */
                    177:     bool brace_same_line;      /* whether brace should be on same line as if,
                    178:                                 * while, etc */
                    179:     bool blank_after_sizeof;   /* whether a blank should always be inserted
                    180:                                 * after sizeof */
                    181:     bool comment_delimiter_on_blankline;
                    182:     int decl_comment_column;   /* the column in which comments after
1.31      rillig    183:                                 * declarations should be put */
1.34      rillig    184:     bool cuddle_else;          /* whether 'else' should cuddle up to '}' */
                    185:     int continuation_indent;   /* the indentation between the edge of code
                    186:                                 * and continuation lines */
                    187:     float case_indent;         /* The distance (measured in indentation
1.31      rillig    188:                                 * levels) to indent case labels from the
                    189:                                 * switch statement */
1.34      rillig    190:     int comment_column;                /* the column in which comments to the right
1.31      rillig    191:                                 * of code should start */
1.34      rillig    192:     int decl_indent;           /* indentation of identifier in declaration */
                    193:     bool ljust_decl;           /* true if declarations should be left
1.31      rillig    194:                                 * justified */
1.34      rillig    195:     int unindent_displace;     /* comments not to the right of code will be
                    196:                                 * placed this many indentation levels to the
                    197:                                 * left of code */
                    198:     bool extra_expr_indent;    /* whether continuation lines from the
                    199:                                 * expression part of "if(e)", "while(e)",
                    200:                                 * "for(e;e;e)" should be indented an extra
                    201:                                 * tab stop so that they don't conflict with
                    202:                                 * the code that follows */
                    203:     bool else_if;              /* whether else-if pairs should be handled
1.31      rillig    204:                                 * specially */
1.34      rillig    205:     bool function_brace_split; /* split function declaration and brace onto
                    206:                                 * separate lines */
                    207:     bool format_col1_comments; /* If comments which start in column 1 are to
                    208:                                 * be magically reformatted (just like
                    209:                                 * comments that begin in later columns) */
                    210:     bool format_block_comments;        /* whether comments beginning with '/ * \n'
                    211:                                 * are to be reformatted */
                    212:     bool indent_parameters;
                    213:     int indent_size;           /* the size of one indentation level */
                    214:     int block_comment_max_line_length;
                    215:     int local_decl_indent;     /* like decl_indent but for locals */
                    216:     bool lineup_to_parens_always;      /* whether to not(?) attempt to keep
                    217:                                         * lined-up code within the margin */
                    218:     bool lineup_to_parens;     /* whether continued code within parens will
                    219:                                 * be lined up to the open paren */
                    220:     bool proc_calls_space;     /* whether function calls look like: foo (bar)
                    221:                                 * rather than foo(bar) */
                    222:     bool procnames_start_line; /* whether the names of procedures being
                    223:                                 * defined get placed in column 1 (i.e. a
                    224:                                 * newline is placed between the type of the
                    225:                                 * procedure and its name) */
                    226:     bool space_after_cast;     /* "b = (int) a" vs "b = (int)a" */
                    227:     bool star_comment_cont;    /* whether comment continuation lines should
                    228:                                 * have stars at the beginning of each line. */
                    229:     bool swallow_optional_blanklines;
                    230:     bool auto_typedefs;                /* whether to recognize identifiers ending in
                    231:                                 * "_t" like typedefs */
                    232:     int tabsize;               /* the size of a tab */
                    233:     int max_line_length;
                    234:     bool use_tabs;             /* set true to use tabs for spacing, false
1.31      rillig    235:                                 * uses all spaces */
1.34      rillig    236:     bool verbose;              /* whether non-essential error messages are
                    237:                                 * printed */
                    238: }       opt;
1.31      rillig    239:
                    240: enum keyword_kind {
                    241:     kw_0,
                    242:     kw_offsetof,
                    243:     kw_sizeof,
                    244:     kw_struct_or_union_or_enum,
                    245:     kw_type,
1.47      rillig    246:     kw_for,
                    247:     kw_if,
                    248:     kw_while,
1.46      rillig    249:     kw_do,
                    250:     kw_else,
1.31      rillig    251:     kw_switch,
                    252:     kw_case_or_default,
                    253:     kw_jump,
                    254:     kw_storage_class,
                    255:     kw_typedef,
                    256:     kw_inline_or_restrict
                    257: };
                    258:
                    259:
1.34      rillig    260: extern bool found_err;
1.39      rillig    261: extern int blank_lines_to_output;
1.40      rillig    262: extern bool blank_line_before;
                    263: extern bool blank_line_after;
1.34      rillig    264: extern bool break_comma;       /* when true and not in parens, break after a
1.31      rillig    265:                                 * comma */
1.34      rillig    266: extern float case_ind;         /* indentation level to be used for a "case
1.31      rillig    267:                                 * n:" */
1.34      rillig    268: extern bool had_eof;           /* whether input is exhausted */
                    269: extern int line_no;            /* the current line number. */
                    270: extern bool inhibit_formatting;        /* true if INDENT OFF is in effect */
1.31      rillig    271:
                    272: #define        STACKSIZE 256
                    273:
1.43      rillig    274: /* TODO: group the members by purpose, don't sort them alphabetically */
1.31      rillig    275: extern struct parser_state {
1.49    ! rillig    276:     lexer_symbol last_token;
1.41      rillig    277:
                    278:     int tos;                   /* pointer to top of stack */
1.49    ! rillig    279:     parser_symbol s_sym[STACKSIZE];
1.41      rillig    280:     int s_ind_level[STACKSIZE];
                    281:     float s_case_ind_level[STACKSIZE];
                    282:
1.34      rillig    283:     int comment_delta;         /* used to set up indentation for all lines of
                    284:                                 * a boxed comment after the first one */
                    285:     int n_comment_delta;       /* remembers how many columns there were
1.31      rillig    286:                                 * before the start of a box comment so that
                    287:                                 * forthcoming lines of the comment are
                    288:                                 * indented properly */
1.34      rillig    289:     int cast_mask;             /* indicates which close parens potentially
1.31      rillig    290:                                 * close off casts */
1.34      rillig    291:     int not_cast_mask;         /* indicates which close parens definitely
1.31      rillig    292:                                 * close off something else than casts */
1.34      rillig    293:     bool block_init;           /* whether inside a block initialization */
                    294:     int block_init_level;      /* The level of brace nesting in an
1.31      rillig    295:                                 * initialization */
1.34      rillig    296:     bool last_nl;              /* whether the last thing scanned was a
                    297:                                 * newline */
1.37      rillig    298:     bool init_or_struct;       /* whether there has been a declarator (e.g.
                    299:                                 * int or char) and no left parenthesis since
                    300:                                 * the last semicolon. When true, a '{' is
1.34      rillig    301:                                 * starting a structure definition or an
                    302:                                 * initialization list */
                    303:     bool col_1;                        /* whether the last token started in column 1 */
                    304:     int com_ind;               /* indentation of the current comment */
                    305:     int decl_nest;             /* current nesting level for structure or init */
                    306:     bool decl_on_line;         /* whether this line of code has part of a
                    307:                                 * declaration on it */
                    308:     int ind_level_follow;      /* the level to which ind_level should be set
1.31      rillig    309:                                 * after the current line is printed */
1.34      rillig    310:     bool in_decl;              /* whether we are in a declaration stmt. The
                    311:                                 * processing of braces is then slightly
1.31      rillig    312:                                 * different */
1.34      rillig    313:     bool in_stmt;
                    314:     int ind_level;             /* the current indentation level */
                    315:     bool ind_stmt;             /* whether the next line should have an extra
1.31      rillig    316:                                 * indentation level because we are in the
                    317:                                 * middle of a stmt */
1.42      rillig    318:     bool next_unary;           /* whether the following operator should be
1.31      rillig    319:                                 * unary */
1.34      rillig    320:     int p_l_follow;            /* used to remember how to indent the
1.31      rillig    321:                                 * following statement */
1.34      rillig    322:     int paren_level;           /* parenthesization level. used to indent
1.31      rillig    323:                                 * within statements */
1.34      rillig    324:     short paren_indents[20];   /* indentation of the operand/argument of each
                    325:                                 * level of parentheses or brackets, relative
                    326:                                 * to the enclosing statement */
                    327:     bool is_case_label;                /* 'case' and 'default' labels are indented
1.31      rillig    328:                                 * differently from regular labels */
1.34      rillig    329:     bool search_brace;         /* whether it is necessary to buffer up all
                    330:                                 * info up to the start of a stmt after an if,
                    331:                                 * while, etc */
                    332:     bool want_blank;           /* whether the following token should be
                    333:                                 * prefixed by a blank. (Said prefixing is
1.31      rillig    334:                                 * ignored in some cases.) */
                    335:     enum keyword_kind keyword;
1.34      rillig    336:     bool dumped_decl_indent;
                    337:     bool in_parameter_declaration;
                    338:     char procname[100];                /* The name of the current procedure */
                    339:     int just_saw_decl;
1.31      rillig    340:
                    341:     struct {
1.34      rillig    342:        int comments;
                    343:        int lines;
                    344:        int code_lines;
                    345:        int comment_lines;
                    346:     }      stats;
                    347: }            ps;
1.31      rillig    348:
1.3       rillig    349:
1.45      rillig    350: #define array_length(array) (sizeof (array) / sizeof (array[0]))
1.1       kamil     351:
1.34      rillig    352: void add_typename(const char *);
                    353: int compute_code_indent(void);
                    354: int compute_label_indent(void);
                    355: int indentation_after_range(int, const char *, const char *);
                    356: int indentation_after(int, const char *);
1.5       rillig    357: #ifdef debug
1.34      rillig    358: void
                    359: debug_vis_range(const char *, const char *, const char *,
                    360:     const char *);
                    361: void debug_printf(const char *, ...)__printflike(1, 2);
                    362: void debug_println(const char *, ...)__printflike(1, 2);
1.9       rillig    363: #else
1.16      rillig    364: #define                debug_printf(fmt, ...) do { } while (false)
                    365: #define                debug_println(fmt, ...) do { } while (false)
                    366: #define                debug_vis_range(prefix, s, e, suffix) do { } while (false)
1.5       rillig    367: #endif
1.34      rillig    368: void inbuf_skip(void);
                    369: char inbuf_next(void);
1.49    ! rillig    370: lexer_symbol lexi(struct parser_state *);
1.34      rillig    371: void diag(int, const char *, ...)__printflike(2, 3);
                    372: void dump_line(void);
1.44      rillig    373: void dump_line_ff(void);
1.35      rillig    374: void inbuf_read_line(void);
1.49    ! rillig    375: void parse(parser_symbol);
        !           376: void parse_hd(stmt_head);
1.34      rillig    377: void process_comment(void);
                    378: void set_option(const char *, const char *);
                    379: void load_profiles(const char *);
                    380:
                    381: void *xmalloc(size_t);
                    382: void *xrealloc(void *, size_t);
                    383: char *xstrdup(const char *);
1.25      rillig    384:
1.34      rillig    385: void buf_expand(struct buffer *, size_t);
1.29      rillig    386:
                    387: static inline bool
                    388: is_hspace(char ch)
                    389: {
                    390:     return ch == ' ' || ch == '\t';
                    391: }
1.38      rillig    392:
                    393: static inline int
                    394: next_tab(int ind)
                    395: {
                    396:     return ind - ind % opt.tabsize + opt.tabsize;
                    397: }

CVSweb <webmaster@jp.NetBSD.org>