From 5b8a4a76d4f9ad0473a6bed722a83d51bfa856ba Mon Sep 17 00:00:00 2001 From: eadler Date: Sun, 18 Mar 2018 22:19:52 +0000 Subject: MFC r303452,r303482,r303483,r303484,r303485,r303487,r303489,r303498,r303499,r303502,r303523,r303525,r303570,r303571,r303588,r303596,r303597,r303598,r303599,r303600,r303601,r303625,r303629,r303718,r304651,r304684,r304686,r305983,r309217,r309219,r309341,r309342,r309343,r309382,r309415,r309417,r309418,r309419,r310863,r311141,r314613,r318471,r321382,r321383,r321396: indent(1): avoid calling write(2) with a negative second parameter. indent(1): Avoid out of bound access of array codebuf. indent(1): Avoid potential use-after-free. indent(1): Fix breakage caused by single comment following "else". indent(1) simply wasn't taught that "else" may be followed by a comment without any opening brace anywhere on the line, so it was very confused in such cases. indent(1): fix struct termination detection. indent(1): fix struct termination detection. indent(1): Removed whitespace shouldn't be considered in column calculations. indent(1): Support "f" and "F" floating constant suffixes. indent(1): Use NULL instead of zero for pointers. indent(1): Attempt to preserve some consistent style. indent(1): Yet more style issues. indent(1): Consistently indent declarations. indent(1): Bail out if there's no more space on the parser stack. indent(1): Remove dead code relating to unix-style comments. indent(1): Simplify pr_comment(). indent(1): Fix wrapping of some lines in comments. indent(1): Untangle the connection between pr_comment.c and io.c. indent(1): Don't newline on cpp lines like #endif unless -bacc is on. indent(1): replace function call to bzero with memset. indent(1): Rearrange option parsing code to squelch clang's static analyzer. indent(1): Use a dash in the license headers. indent(1): accept offsetof(3) as a keyword. indent(1): add some comments to quiet down Coverity. indent(1): remove dead assignments. indent(1): have the memset invocation somewhat more canonical. indent(1): Capsicumify indent(1): minor off-by-one error. indent(1): fix regression introduced in r303596. indent(1): Avoid out of bound access of array in_buffer indent(1): Don't ignore newlines after comments that follow braces. indent(1): Don't unnecessarily add a blank before a comment ends. indent(1): Do not define opchar unless it will be used. indent(1): Optimize parser stack usage. indent(1): Remove an extra newline added in a previous commit. indent(1): Avoid out-of-bound accesses of arrays. indent(1): Avoid out-of-bound accesses of array ps.p_stack. indent(1): Avoid out of bounds access of array ps.paren_indents indent(1): add a piece missed in r311138. indent(1): Support binary integer literals. indent(1): don't produce unnecessary blank lines. indent(1): rename the profile file. indent(1): better alignment of comments on code. --- usr.bin/indent/Makefile | 6 + usr.bin/indent/args.c | 21 +- usr.bin/indent/indent.c | 301 ++++++++++++++++------------ usr.bin/indent/indent.h | 3 +- usr.bin/indent/indent_codes.h | 2 +- usr.bin/indent/indent_globs.h | 29 +-- usr.bin/indent/io.c | 48 +++-- usr.bin/indent/lexi.c | 87 +++++--- usr.bin/indent/parse.c | 18 +- usr.bin/indent/pr_comment.c | 274 +++++++++---------------- usr.bin/indent/tests/Makefile | 45 +++++ usr.bin/indent/tests/binary.0 | 10 + usr.bin/indent/tests/binary.0.stdout | 12 ++ usr.bin/indent/tests/comments.0 | 7 + usr.bin/indent/tests/comments.0.pro | 2 + usr.bin/indent/tests/comments.0.stdout | 7 + usr.bin/indent/tests/elsecomment.0.pro | 2 + usr.bin/indent/tests/elsecomment.pro | 2 - usr.bin/indent/tests/functional_test.sh | 90 +++++++++ usr.bin/indent/tests/label.0.pro | 2 + usr.bin/indent/tests/label.pro | 2 - usr.bin/indent/tests/nsac.0.pro | 2 + usr.bin/indent/tests/nsac.pro | 2 - usr.bin/indent/tests/sac.0.pro | 2 + usr.bin/indent/tests/sac.pro | 2 - usr.bin/indent/tests/surplusbad.0.pro | 2 + usr.bin/indent/tests/surplusbad.pro | 2 - usr.bin/indent/tests/types_from_file.0.list | 2 + usr.bin/indent/tests/types_from_file.0.pro | 2 + usr.bin/indent/tests/types_from_file.list | 2 - usr.bin/indent/tests/types_from_file.pro | 2 - 31 files changed, 583 insertions(+), 407 deletions(-) create mode 100644 usr.bin/indent/tests/Makefile create mode 100644 usr.bin/indent/tests/binary.0 create mode 100644 usr.bin/indent/tests/binary.0.stdout create mode 100644 usr.bin/indent/tests/comments.0.pro create mode 100644 usr.bin/indent/tests/elsecomment.0.pro delete mode 100644 usr.bin/indent/tests/elsecomment.pro create mode 100755 usr.bin/indent/tests/functional_test.sh create mode 100644 usr.bin/indent/tests/label.0.pro delete mode 100644 usr.bin/indent/tests/label.pro create mode 100644 usr.bin/indent/tests/nsac.0.pro delete mode 100644 usr.bin/indent/tests/nsac.pro create mode 100644 usr.bin/indent/tests/sac.0.pro delete mode 100644 usr.bin/indent/tests/sac.pro create mode 100644 usr.bin/indent/tests/surplusbad.0.pro delete mode 100644 usr.bin/indent/tests/surplusbad.pro create mode 100644 usr.bin/indent/tests/types_from_file.0.list create mode 100644 usr.bin/indent/tests/types_from_file.0.pro delete mode 100644 usr.bin/indent/tests/types_from_file.list delete mode 100644 usr.bin/indent/tests/types_from_file.pro (limited to 'usr.bin') diff --git a/usr.bin/indent/Makefile b/usr.bin/indent/Makefile index dcd7e39..2eb1c32 100644 --- a/usr.bin/indent/Makefile +++ b/usr.bin/indent/Makefile @@ -1,9 +1,15 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 # $FreeBSD$ +.include + PROG= indent SRCS= indent.c io.c lexi.c parse.c pr_comment.c args.c NO_WMISSING_VARIABLE_DECLARATIONS= +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif + .include diff --git a/usr.bin/indent/args.c b/usr.bin/indent/args.c index 09df243..00456e1 100644 --- a/usr.bin/indent/args.c +++ b/usr.bin/indent/args.c @@ -1,4 +1,4 @@ -/* +/*- * SPDX-License-Identifier: BSD-4-Clause * * Copyright (c) 1985 Sun Microsystems, Inc. @@ -93,6 +93,7 @@ struct pro { } pro[] = { {"T", PRO_SPECIAL, 0, KEY, 0}, + {"P", PRO_SPECIAL, 0, IGN, 0}, {"bacc", PRO_BOOL, false, ON, &blanklines_around_conditional_compilation}, {"badp", PRO_BOOL, false, ON, &blanklines_after_declarations_at_proctop}, {"bad", PRO_BOOL, false, ON, &blanklines_after_declarations}, @@ -225,17 +226,14 @@ scan_profile(FILE *f) } } -const char *param_start; - -static int +static const char * eqin(const char *s1, const char *s2) { while (*s1) { if (*s1++ != *s2++) - return (false); + return (NULL); } - param_start = s2; - return (true); + return (s2); } /* @@ -259,11 +257,12 @@ set_defaults(void) void set_option(char *arg) { - struct pro *p; + struct pro *p; + const char *param_start; arg++; /* ignore leading "-" */ for (p = pro; p->p_name; p++) - if (*p->p_name == *arg && eqin(p->p_name, arg)) + if (*p->p_name == *arg && (param_start = eqin(p->p_name, arg)) != NULL) goto found; errx(1, "%s: unknown parameter \"%s\"", option_source, arg - 1); found: @@ -282,9 +281,9 @@ found: break; case STDIN: - if (input == 0) + if (input == NULL) input = stdin; - if (output == 0) + if (output == NULL) output = stdout; break; diff --git a/usr.bin/indent/indent.c b/usr.bin/indent/indent.c index c461017..44399fe 100644 --- a/usr.bin/indent/indent.c +++ b/usr.bin/indent/indent.c @@ -1,4 +1,4 @@ -/* +/*- * SPDX-License-Identifier: BSD-4-Clause * * Copyright (c) 1985 Sun Microsystems, Inc. @@ -52,8 +52,10 @@ static char sccsid[] = "@(#)indent.c 5.17 (Berkeley) 6/7/93"; #include __FBSDID("$FreeBSD$"); +#include #include #include +#include #include #include #include @@ -65,6 +67,7 @@ __FBSDID("$FreeBSD$"); #include "indent.h" static void bakcopy(void); +static void indent_declaration(int, int); const char *in_name = "Standard Input"; /* will always point to name of input * file */ @@ -77,6 +80,7 @@ char bakfile[MAXPATHLEN] = ""; int main(int argc, char **argv) { + cap_rights_t rights; int dec_ind; /* current indentation for declarations */ int di_stack[20]; /* a stack of structure indentation levels */ @@ -151,11 +155,11 @@ main(int argc, char **argv) scase = ps.pcase = false; squest = 0; - sc_end = 0; - bp_save = 0; - be_save = 0; + sc_end = NULL; + bp_save = NULL; + be_save = NULL; - output = 0; + output = NULL; tabs_to_var = 0; envval = getenv("SIMPLE_BACKUP_SUFFIX"); @@ -240,6 +244,17 @@ main(int argc, char **argv) bakcopy(); } } + + /* Restrict input/output descriptors and enter Capsicum sandbox. */ + cap_rights_init(&rights, CAP_FSTAT, CAP_WRITE); + if (cap_rights_limit(fileno(output), &rights) < 0 && errno != ENOSYS) + err(EXIT_FAILURE, "unable to limit rights for %s", out_name); + cap_rights_init(&rights, CAP_FSTAT, CAP_READ); + if (cap_rights_limit(fileno(input), &rights) < 0 && errno != ENOSYS) + err(EXIT_FAILURE, "unable to limit rights for %s", in_name); + if (cap_enter() < 0 && errno != ENOSYS) + err(EXIT_FAILURE, "unable to enter capability mode"); + if (ps.com_ind <= 1) ps.com_ind = 2; /* dont put normal comments before column 2 */ if (troff) { @@ -327,6 +342,10 @@ main(int argc, char **argv) switch (type_code) { case newline: ++line_no; + if (sc_end != NULL) { /* dump comment, if any */ + *sc_end++ = '\n'; /* newlines are needed in this case */ + goto sw_buffer; + } flushed_nl = true; case form_feed: break; /* form feeds and newlines found here will be @@ -334,7 +353,7 @@ main(int argc, char **argv) case lbrace: /* this is a brace that starts the compound * stmt */ - if (sc_end == 0) { /* ignore buffering if a comment wasn't + if (sc_end == NULL) { /* ignore buffering if a comment wasn't * stored up */ ps.search_brace = false; goto check_type; @@ -347,9 +366,9 @@ main(int argc, char **argv) } case comment: /* we have a comment, so we must copy it into * the buffer */ - if (!flushed_nl || sc_end != 0) { - if (sc_end == 0) { /* if this is the first comment, we - * must set up the buffer */ + if (!flushed_nl || sc_end != NULL) { + if (sc_end == NULL) { /* if this is the first comment, we + * must set up the buffer */ save_com[0] = save_com[1] = ' '; sc_end = &(save_com[2]); } @@ -392,7 +411,7 @@ main(int argc, char **argv) && e_code != s_code && e_code[-1] == '}')) force_nl = false; - if (sc_end == 0) { /* ignore buffering if comment wasn't + if (sc_end == NULL) { /* ignore buffering if comment wasn't * saved up */ ps.search_brace = false; goto check_type; @@ -423,7 +442,7 @@ main(int argc, char **argv) * save_com */ *sc_end++ = ' ';/* add trailing blank, just in case */ buf_end = sc_end; - sc_end = 0; + sc_end = NULL; break; } /* end of switch */ if (type_code != 0) /* we must make this check, just in case there @@ -513,31 +532,38 @@ check_type: break; case lparen: /* got a '(' or '[' */ - ++ps.p_l_follow; /* count parens to make Healy happy */ + /* count parens to make Healy happy */ + if (++ps.p_l_follow == nitems(ps.paren_indents)) { + diag3(0, "Reached internal limit of %d unclosed parens", + nitems(ps.paren_indents)); + ps.p_l_follow--; + } if (ps.want_blank && *token != '[' && - (ps.last_token != ident || proc_calls_space - || (ps.its_a_keyword && (!ps.sizeof_keyword || Bill_Shannon)))) + (ps.last_token != ident || proc_calls_space || + /* offsetof (1) is never allowed a space; sizeof (2) gets + * one iff -bs; all other keywords (>2) always get a space + * before lparen */ + (ps.keyword + Bill_Shannon > 2))) *e_code++ = ' '; - if (ps.in_decl && !ps.block_init) - if (troff && !ps.dumped_decl_indent && !is_procname && ps.last_token == decl) { - ps.dumped_decl_indent = 1; + ps.want_blank = false; + if (ps.in_decl && !ps.block_init && !ps.dumped_decl_indent && + !is_procname) { + /* function pointer declarations */ + if (troff) { sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); e_code += strlen(e_code); } else { - while ((e_code - s_code) < dec_ind) { - CHECK_SIZE_CODE; - *e_code++ = ' '; - } - *e_code++ = token[0]; + indent_declaration(dec_ind, tabs_to_var); } - else + ps.dumped_decl_indent = true; + } + if (!troff) *e_code++ = token[0]; ps.paren_indents[ps.p_l_follow - 1] = e_code - s_code; if (sp_sw && ps.p_l_follow == 1 && extra_expression_indent && ps.paren_indents[0] < 2 * ps.ind_size) ps.paren_indents[0] = 2 * ps.ind_size; - ps.want_blank = false; if (ps.in_or_st && *token == '(' && ps.tos <= 2) { /* * this is a kluge to make sure that declarations will be @@ -548,19 +574,20 @@ check_type: ps.in_or_st = false; /* turn off flag for structure decl or * initialization */ } - if (ps.sizeof_keyword) - ps.sizeof_mask |= 1 << ps.p_l_follow; + /* parenthesized type following sizeof or offsetof is not a cast */ + if (ps.keyword == 1 || ps.keyword == 2) + ps.not_cast_mask |= 1 << ps.p_l_follow; break; case rparen: /* got a ')' or ']' */ rparen_count--; - if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.sizeof_mask) { + if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.not_cast_mask) { ps.last_u_d = true; ps.cast_mask &= (1 << ps.p_l_follow) - 1; ps.want_blank = false; } else ps.want_blank = true; - ps.sizeof_mask &= (1 << ps.p_l_follow) - 1; + ps.not_cast_mask &= (1 << ps.p_l_follow) - 1; if (--ps.p_l_follow < 0) { ps.p_l_follow = 0; diag3(0, "Extra %c", *token); @@ -588,27 +615,30 @@ check_type: break; case unary_op: /* this could be any unary operation */ - if (ps.want_blank) - *e_code++ = ' '; - - if (troff && !ps.dumped_decl_indent && ps.in_decl && !is_procname) { - sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); - ps.dumped_decl_indent = 1; - e_code += strlen(e_code); + if (!ps.dumped_decl_indent && ps.in_decl && !is_procname && + !ps.block_init) { + /* pointer declarations */ + if (troff) { + if (ps.want_blank) + *e_code++ = ' '; + sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, + token); + e_code += strlen(e_code); + } + else { + /* if this is a unary op in a declaration, we should + * indent this token */ + for (i = 0; token[i]; ++i) + /* find length of token */; + indent_declaration(dec_ind - i, tabs_to_var); + } + ps.dumped_decl_indent = true; } - else { + else if (ps.want_blank) + *e_code++ = ' '; + { const char *res = token; - if (ps.in_decl && !ps.block_init) { /* if this is a unary op - * in a declaration, we - * should indent this - * token */ - for (i = 0; token[i]; ++i); /* find length of token */ - while ((e_code - s_code) < (dec_ind - i)) { - CHECK_SIZE_CODE; - *e_code++ = ' '; /* pad it */ - } - } if (troff && token[0] == '-' && token[1] == '>') res = "\\(->"; for (t_ptr = res; *t_ptr; ++t_ptr) { @@ -707,23 +737,25 @@ check_type: break; case semicolon: /* got a ';' */ - ps.in_or_st = false;/* we are not in an initialization or - * structure declaration */ + if (ps.dec_nest == 0) + ps.in_or_st = false;/* we are not in an initialization or + * structure declaration */ scase = false; /* these will only need resetting in an error */ squest = 0; if (ps.last_token == rparen && rparen_count == 0) ps.in_parameter_declaration = 0; ps.cast_mask = 0; - ps.sizeof_mask = 0; + ps.not_cast_mask = 0; ps.block_init = 0; ps.block_init_level = 0; ps.just_saw_decl--; - if (ps.in_decl && s_code == e_code && !ps.block_init) - while ((e_code - s_code) < (dec_ind - 1)) { - CHECK_SIZE_CODE; - *e_code++ = ' '; - } + if (ps.in_decl && s_code == e_code && !ps.block_init && + !ps.dumped_decl_indent) { + /* indent stray semicolons in declarations */ + indent_declaration(dec_ind - 1, tabs_to_var); + ps.dumped_decl_indent = true; + } ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level * structure declaration, we @@ -937,58 +969,25 @@ check_type: if (ps.in_decl) { /* if we are in a declaration, we must indent * identifier */ if (is_procname == 0 || !procnames_start_line) { - if (!ps.block_init) { - if (troff && !ps.dumped_decl_indent) { + if (!ps.block_init && !ps.dumped_decl_indent) { + if (troff) { if (ps.want_blank) *e_code++ = ' '; - ps.want_blank = false; sprintf(e_code, "\n.De %dp+\200p\n", dec_ind * 7); - ps.dumped_decl_indent = 1; e_code += strlen(e_code); - } else { - int cur_dec_ind; - int pos, startpos; - - /* - * in order to get the tab math right for - * indentations that are not multiples of 8 we - * need to modify both startpos and dec_ind - * (cur_dec_ind) here by eight minus the - * remainder of the current starting column - * divided by eight. This seems to be a - * properly working fix - */ - startpos = e_code - s_code; - cur_dec_ind = dec_ind; - pos = startpos; - if ((ps.ind_level * ps.ind_size) % 8 != 0) { - pos += (ps.ind_level * ps.ind_size) % 8; - cur_dec_ind += (ps.ind_level * ps.ind_size) % 8; - } - - if (tabs_to_var) { - while ((pos & ~7) + 8 <= cur_dec_ind) { - CHECK_SIZE_CODE; - *e_code++ = '\t'; - pos = (pos & ~7) + 8; - } - } - while (pos < cur_dec_ind) { - CHECK_SIZE_CODE; - *e_code++ = ' '; - pos++; - } - if (ps.want_blank && e_code - s_code == startpos) - *e_code++ = ' '; - ps.want_blank = false; - } + } else + indent_declaration(dec_ind, tabs_to_var); + ps.dumped_decl_indent = true; + ps.want_blank = false; } } else { if (ps.want_blank) *e_code++ = ' '; ps.want_blank = false; - if (dec_ind && s_code != e_code) + if (dec_ind && s_code != e_code) { + *e_code = '\0'; dump_line(); + } dec_ind = 0; } } @@ -1002,7 +1001,7 @@ check_type: copy_id: if (ps.want_blank) *e_code++ = ' '; - if (troff && ps.its_a_keyword) { + if (troff && ps.keyword) { e_code = chfont(&bodyf, &keywordf, e_code); for (t_ptr = token; *t_ptr; ++t_ptr) { CHECK_SIZE_CODE; @@ -1039,12 +1038,12 @@ check_type: ps.want_blank = (s_code != e_code); /* only put blank after comma * if comma does not start the * line */ - if (ps.in_decl && is_procname == 0 && !ps.block_init) - while ((e_code - s_code) < (dec_ind - 1)) { - CHECK_SIZE_CODE; - *e_code++ = ' '; - } - + if (ps.in_decl && is_procname == 0 && !ps.block_init && + !ps.dumped_decl_indent) { + /* indent leading commas and not the actual identifiers */ + indent_declaration(dec_ind - 1, tabs_to_var); + ps.dumped_decl_indent = true; + } *e_code++ = ','; if (ps.p_l_follow == 0) { if (ps.block_init_level <= 0) @@ -1113,9 +1112,9 @@ check_type: while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) e_lab--; - if (e_lab - s_lab == com_end && bp_save == 0) { /* comment on - * preprocessor line */ - if (sc_end == 0) /* if this is the first comment, we + if (e_lab - s_lab == com_end && bp_save == NULL) { + /* comment on preprocessor line */ + if (sc_end == NULL) /* if this is the first comment, we * must set up the buffer */ sc_end = &(save_com[0]); else { @@ -1138,19 +1137,13 @@ check_type: * save_com */ *sc_end++ = ' '; /* add trailing blank, just in case */ buf_end = sc_end; - sc_end = 0; + sc_end = NULL; } *e_lab = '\0'; /* null terminate line */ ps.pcase = false; } - if (strncmp(s_lab, "#if", 3) == 0) { - if (blanklines_around_conditional_compilation) { - int c; - prefix_blankline_requested++; - while ((c = getc(input)) == '\n'); - ungetc(c, input); - } + if (strncmp(s_lab, "#if", 3) == 0) { /* also ifdef, ifndef */ if ((size_t)ifdef_level < nitems(state_stack)) { match_state[ifdef_level].tos = -1; state_stack[ifdef_level++] = ps; @@ -1158,40 +1151,54 @@ check_type: else diag2(1, "#if stack overflow"); } - else if (strncmp(s_lab, "#else", 5) == 0) + else if (strncmp(s_lab, "#el", 3) == 0) { /* else, elif */ if (ifdef_level <= 0) - diag2(1, "Unmatched #else"); + diag2(1, s_lab[3] == 'i' ? "Unmatched #elif" : "Unmatched #else"); else { match_state[ifdef_level - 1] = ps; ps = state_stack[ifdef_level - 1]; } + } else if (strncmp(s_lab, "#endif", 6) == 0) { if (ifdef_level <= 0) diag2(1, "Unmatched #endif"); - else { + else ifdef_level--; - -#ifdef undef - /* - * This match needs to be more intelligent before the - * message is useful - */ - if (match_state[ifdef_level].tos >= 0 - && bcmp(&ps, &match_state[ifdef_level], sizeof ps)) - diag2(0, "Syntactically inconsistent #ifdef alternatives"); -#endif + } else { + struct directives { + int size; + const char *string; } - if (blanklines_around_conditional_compilation) { - postfix_blankline_requested++; - n_real_blanklines = 0; + recognized[] = { + {7, "include"}, + {6, "define"}, + {5, "undef"}, + {4, "line"}, + {5, "error"}, + {6, "pragma"} + }; + int d = nitems(recognized); + while (--d >= 0) + if (strncmp(s_lab + 1, recognized[d].string, recognized[d].size) == 0) + break; + if (d < 0) { + diag2(1, "Unrecognized cpp directive"); + break; } } + if (blanklines_around_conditional_compilation) { + postfix_blankline_requested++; + n_real_blanklines = 0; + } + else { + postfix_blankline_requested = 0; + prefix_blankline_requested = 0; + } break; /* subsequent processing of the newline * character will cause the line to be printed */ case comment: /* we have gotten a / followed by * this is a biggie */ if (flushed_nl) { /* we should force a broken line here */ - flushed_nl = false; dump_line(); ps.want_blank = false; /* dont insert blank at line start */ force_nl = false; @@ -1231,7 +1238,7 @@ bakcopy(void) bakchn = creat(bakfile, 0600); if (bakchn < 0) err(1, "%s", bakfile); - while ((n = read(fileno(input), buff, sizeof buff)) != 0) + while ((n = read(fileno(input), buff, sizeof(buff))) > 0) if (write(bakchn, buff, n) != n) err(1, "%s", bakfile); if (n < 0) @@ -1250,3 +1257,33 @@ bakcopy(void) err(1, "%s", in_name); } } + +static void +indent_declaration(int cur_dec_ind, int tabs_to_var) +{ + int pos = e_code - s_code; + char *startpos = e_code; + + /* + * get the tab math right for indentations that are not multiples of 8 + */ + if ((ps.ind_level * ps.ind_size) % 8 != 0) { + pos += (ps.ind_level * ps.ind_size) % 8; + cur_dec_ind += (ps.ind_level * ps.ind_size) % 8; + } + if (tabs_to_var) + while ((pos & ~7) + 8 <= cur_dec_ind) { + CHECK_SIZE_CODE; + *e_code++ = '\t'; + pos = (pos & ~7) + 8; + } + while (pos < cur_dec_ind) { + CHECK_SIZE_CODE; + *e_code++ = ' '; + pos++; + } + if (e_code == startpos && ps.want_blank) { + *e_code++ = ' '; + ps.want_blank = false; + } +} diff --git a/usr.bin/indent/indent.h b/usr.bin/indent/indent.h index b1473a0..502a478 100644 --- a/usr.bin/indent/indent.h +++ b/usr.bin/indent/indent.h @@ -1,4 +1,4 @@ -/* +/*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2001 Jens Schweikhardt @@ -34,6 +34,7 @@ void addkey(char *, int); int compute_code_target(void); int compute_label_target(void); int count_spaces(int, char *); +int count_spaces_until(int, char *, char *); int lexi(void); void diag2(int, const char *); void diag3(int, const char *, int); diff --git a/usr.bin/indent/indent_codes.h b/usr.bin/indent/indent_codes.h index 45be777..369d0da 100644 --- a/usr.bin/indent/indent_codes.h +++ b/usr.bin/indent/indent_codes.h @@ -1,4 +1,4 @@ -/* +/*- * SPDX-License-Identifier: BSD-4-Clause * * Copyright (c) 1985 Sun Microsystems, Inc. diff --git a/usr.bin/indent/indent_globs.h b/usr.bin/indent/indent_globs.h index 910fc8d..95a89f1 100644 --- a/usr.bin/indent/indent_globs.h +++ b/usr.bin/indent/indent_globs.h @@ -1,4 +1,4 @@ -/* +/*- * SPDX-License-Identifier: BSD-4-Clause * * Copyright (c) 1985 Sun Microsystems, Inc. @@ -59,40 +59,46 @@ FILE *output; /* the output file */ #define CHECK_SIZE_CODE \ if (e_code >= l_code) { \ int nsize = l_code-s_code+400; \ + int code_len = e_code-s_code; \ codebuf = (char *) realloc(codebuf, nsize); \ if (codebuf == NULL) \ err(1, NULL); \ - e_code = codebuf + (e_code-s_code) + 1; \ + e_code = codebuf + code_len + 1; \ l_code = codebuf + nsize - 5; \ s_code = codebuf + 1; \ } #define CHECK_SIZE_COM \ if (e_com >= l_com) { \ int nsize = l_com-s_com+400; \ + int com_len = e_com - s_com; \ + int blank_pos = last_bl - s_com; \ combuf = (char *) realloc(combuf, nsize); \ if (combuf == NULL) \ err(1, NULL); \ - e_com = combuf + (e_com-s_com) + 1; \ + e_com = combuf + com_len + 1; \ + last_bl = combuf + blank_pos + 1; \ l_com = combuf + nsize - 5; \ s_com = combuf + 1; \ } #define CHECK_SIZE_LAB \ if (e_lab >= l_lab) { \ int nsize = l_lab-s_lab+400; \ + int label_len = e_lab - s_lab; \ labbuf = (char *) realloc(labbuf, nsize); \ if (labbuf == NULL) \ err(1, NULL); \ - e_lab = labbuf + (e_lab-s_lab) + 1; \ + e_lab = labbuf + label_len + 1; \ l_lab = labbuf + nsize - 5; \ s_lab = labbuf + 1; \ } #define CHECK_SIZE_TOKEN \ if (e_token >= l_token) { \ int nsize = l_token-s_token+400; \ + int token_len = e_token - s_token; \ tokenbuf = (char *) realloc(tokenbuf, nsize); \ if (tokenbuf == NULL) \ err(1, NULL); \ - e_token = tokenbuf + (e_token-s_token) + 1; \ + e_token = tokenbuf + token_len + 1; \ l_token = tokenbuf + nsize - 5; \ s_token = tokenbuf + 1; \ } @@ -227,7 +233,7 @@ struct fstate bodyf; /* major body font */ -#define STACKSIZE 150 +#define STACKSIZE 256 struct parser_state { int last_token; @@ -240,10 +246,10 @@ struct parser_state { * char should be lined up with the / in / followed by * */ int comment_delta, n_comment_delta; - int cast_mask; /* indicates which close parens close off - * casts */ - int sizeof_mask; /* indicates which close parens close off - * sizeof''s */ + int cast_mask; /* indicates which close parens potentially + * close off casts */ + int not_cast_mask; /* indicates which close parens definitely + * close off something else than casts */ int block_init; /* true iff inside a block initialization */ int block_init_level; /* The level of brace nesting in an * initialization */ @@ -313,8 +319,7 @@ struct parser_state { * specially */ int decl_indent; /* column to indent declared identifiers to */ int local_decl_indent; /* like decl_indent but for locals */ - int its_a_keyword; - int sizeof_keyword; + int keyword; /* the type of a keyword or 0 */ int dumped_decl_indent; float case_indent; /* The distance to indent case labels from the * switch statement */ diff --git a/usr.bin/indent/io.c b/usr.bin/indent/io.c index 66972c7..25e3867 100644 --- a/usr.bin/indent/io.c +++ b/usr.bin/indent/io.c @@ -1,4 +1,4 @@ -/* +/*- * SPDX-License-Identifier: BSD-4-Clause * * Copyright (c) 1985 Sun Microsystems, Inc. @@ -118,6 +118,7 @@ dump_line(void) } while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) e_lab--; + *e_lab = '\0'; cur_col = pad_output(1, compute_label_target()); if (s_lab[0] == '#' && (strncmp(s_lab, "#else", 5) == 0 || strncmp(s_lab, "#endif", 6) == 0)) { @@ -201,6 +202,7 @@ dump_line(void) break; case '\\': putc('\\', output); + /* add a backslash to escape the '\' */ default: putc(*follow, output); } @@ -225,8 +227,9 @@ dump_line(void) char *com_st = s_com; target += ps.comment_delta; - while (*com_st == '\t') - com_st++, target += 8; /* ? */ + while (*com_st == '\t') /* consider original indentation in + * case this is a box comment */ + com_st++, target += 8; while (target <= 0) if (*com_st == ' ') target++, com_st++; @@ -242,18 +245,9 @@ dump_line(void) } while (e_com > com_st && isspace(e_com[-1])) e_com--; - cur_col = pad_output(cur_col, target); - if (!ps.box_com) { - if (star_comment_cont && (com_st[1] != '*' || e_com <= com_st + 1)) { - if (com_st[1] == ' ' && com_st[0] == ' ' && e_com > com_st + 1) - com_st[1] = '*'; - else - fwrite(" * ", com_st[0] == '\t' ? 2 : com_st[0] == '*' ? 1 : 3, 1, output); - } - } + (void)pad_output(cur_col, target); fwrite(com_st, e_com - com_st, 1, output); ps.comment_delta = ps.n_comment_delta; - cur_col = count_spaces(cur_col, com_st); ++ps.com_lines; /* count lines with comments */ } } @@ -283,10 +277,11 @@ inhibit_newline: ps.dumped_decl_indent = 0; *(e_lab = s_lab) = '\0'; /* reset buffers */ *(e_code = s_code) = '\0'; - *(e_com = s_com) = '\0'; + *(e_com = s_com = combuf + 1) = '\0'; ps.ind_level = ps.i_l_follow; ps.paren_level = ps.p_l_follow; - paren_target = -ps.paren_indents[ps.paren_level - 1]; + if (ps.paren_level > 0) + paren_target = -ps.paren_indents[ps.paren_level - 1]; not_first_line = 1; } @@ -349,10 +344,10 @@ fill_buffer(void) int i; FILE *f = input; - if (bp_save != 0) { /* there is a partly filled input buffer left */ - buf_ptr = bp_save; /* dont read anything, just switch buffers */ + if (bp_save != NULL) { /* there is a partly filled input buffer left */ + buf_ptr = bp_save; /* do not read anything, just switch buffers */ buf_end = be_save; - bp_save = be_save = 0; + bp_save = be_save = NULL; if (buf_ptr < buf_end) return; /* only return if there is really something in * this buffer */ @@ -379,7 +374,7 @@ fill_buffer(void) } buf_ptr = in_buffer; buf_end = p; - if (p[-2] == '/' && p[-3] == '*') { + if (p - in_buffer > 2 && p[-2] == '/' && p[-3] == '*') { if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0) fill_buffer(); /* flush indent error message */ else { @@ -507,18 +502,15 @@ pad_output(int current, int target) * */ int -count_spaces(int current, char *buffer) +count_spaces_until(int cur, char *buffer, char *end) /* * this routine figures out where the character position will be after * printing the text in buffer starting at column "current" */ { char *buf; /* used to look thru buffer */ - int cur; /* current character counter */ - - cur = current; - for (buf = buffer; *buf != '\0'; ++buf) { + for (buf = buffer; *buf != '\0' && buf != end; ++buf) { switch (*buf) { case '\n': @@ -542,6 +534,12 @@ count_spaces(int current, char *buffer) return (cur); } +int +count_spaces(int cur, char *buffer) +{ + return (count_spaces_until(cur, buffer, NULL)); +} + void diag4(int level, const char *msg, int a, int b) { @@ -636,7 +634,7 @@ parsefont(struct fstate *f, const char *s0) const char *s = s0; int sizedelta = 0; - bzero(f, sizeof *f); + memset(f, '\0', sizeof(*f)); while (*s) { if (isdigit(*s)) f->size = f->size * 10 + *s - '0'; diff --git a/usr.bin/indent/lexi.c b/usr.bin/indent/lexi.c index baa66a9..7c6989c 100644 --- a/usr.bin/indent/lexi.c +++ b/usr.bin/indent/lexi.c @@ -1,4 +1,4 @@ -/* +/*- * SPDX-License-Identifier: BSD-4-Clause * * Copyright (c) 1985 Sun Microsystems, Inc. @@ -59,7 +59,9 @@ __FBSDID("$FreeBSD$"); #include "indent.h" #define alphanum 1 +#ifdef undef #define opchar 3 +#endif struct templ { const char *rwd; @@ -68,13 +70,13 @@ struct templ { struct templ specials[1000] = { - {"switch", 1}, - {"case", 2}, - {"break", 0}, + {"switch", 7}, + {"case", 8}, + {"break", 9}, {"struct", 3}, {"union", 3}, {"enum", 3}, - {"default", 2}, + {"default", 8}, {"int", 4}, {"char", 4}, {"float", 4}, @@ -90,14 +92,15 @@ struct templ specials[1000] = {"void", 4}, {"const", 4}, {"volatile", 4}, - {"goto", 0}, - {"return", 0}, + {"goto", 9}, + {"return", 9}, {"if", 5}, {"while", 5}, {"for", 5}, {"else", 6}, {"do", 6}, - {"sizeof", 7}, + {"sizeof", 2}, + {"offsetof", 1}, {0, 0} }; @@ -157,19 +160,47 @@ lexi(void) struct templ *p; if (isdigit(*buf_ptr) || (buf_ptr[0] == '.' && isdigit(buf_ptr[1]))) { + enum base { + BASE_2, BASE_8, BASE_10, BASE_16 + }; int seendot = 0, seenexp = 0, seensfx = 0; - if (*buf_ptr == '0' && - (buf_ptr[1] == 'x' || buf_ptr[1] == 'X')) { + enum base in_base = BASE_10; + + if (*buf_ptr == '0') { + if (buf_ptr[1] == 'b' || buf_ptr[1] == 'B') + in_base = BASE_2; + else if (buf_ptr[1] == 'x' || buf_ptr[1] == 'X') + in_base = BASE_16; + else if (isdigit(buf_ptr[1])) + in_base = BASE_8; + } + switch (in_base) { + case BASE_2: + *e_token++ = *buf_ptr++; + *e_token++ = *buf_ptr++; + while (*buf_ptr == '0' || *buf_ptr == '1') { + CHECK_SIZE_TOKEN; + *e_token++ = *buf_ptr++; + } + break; + case BASE_8: + *e_token++ = *buf_ptr++; + while (*buf_ptr >= '0' && *buf_ptr <= '8') { + CHECK_SIZE_TOKEN; + *e_token++ = *buf_ptr++; + } + break; + case BASE_16: *e_token++ = *buf_ptr++; *e_token++ = *buf_ptr++; while (isxdigit(*buf_ptr)) { CHECK_SIZE_TOKEN; *e_token++ = *buf_ptr++; } - } - else + break; + case BASE_10: while (1) { if (*buf_ptr == '.') { if (seendot) @@ -192,16 +223,16 @@ lexi(void) } } } + break; + } while (1) { - if (!(seensfx & 1) && - (*buf_ptr == 'U' || *buf_ptr == 'u')) { + if (!(seensfx & 1) && (*buf_ptr == 'U' || *buf_ptr == 'u')) { CHECK_SIZE_TOKEN; *e_token++ = *buf_ptr++; seensfx |= 1; continue; } - if (!(seensfx & 2) && - (*buf_ptr == 'L' || *buf_ptr == 'l')) { + if (!(seensfx & 2) && (strchr("fFlL", *buf_ptr) != NULL)) { CHECK_SIZE_TOKEN; if (buf_ptr[1] == buf_ptr[0]) *e_token++ = *buf_ptr++; @@ -239,8 +270,7 @@ lexi(void) if (++buf_ptr >= buf_end) fill_buffer(); } - ps.its_a_keyword = false; - ps.sizeof_keyword = false; + ps.keyword = 0; if (l_struct && !ps.p_l_follow) { /* if last token was 'struct' and we're not * in parentheses, then this token @@ -262,7 +292,7 @@ lexi(void) /* Check if we have an "_t" in the end */ if (q_len > 2 && (strcmp(q + q_len - 2, "_t") == 0)) { - ps.its_a_keyword = true; + ps.keyword = 4; /* a type name */ ps.last_u_d = true; goto found_auto_typedef; } @@ -271,7 +301,7 @@ lexi(void) /* * This loop will check if the token is a keyword. */ - for (p = specials; (j = p->rwd) != 0; p++) { + for (p = specials; (j = p->rwd) != NULL; p++) { const char *q = s_token; /* point at scanned token */ if (*j++ != *q++ || *j++ != *q++) continue; /* This test depends on the fact that @@ -287,12 +317,12 @@ lexi(void) } if (p->rwd) { /* we have a keyword */ found_keyword: - ps.its_a_keyword = true; + ps.keyword = p->rwcode; ps.last_u_d = true; switch (p->rwcode) { - case 1: /* it is a switch */ + case 7: /* it is a switch */ return (swstmt); - case 2: /* a case or default */ + case 8: /* a case or default */ return (casestmt); case 3: /* a "struct" */ @@ -306,8 +336,9 @@ lexi(void) case 4: /* one of the declaration keywords */ found_auto_typedef: if (ps.p_l_follow) { - ps.cast_mask |= (1 << ps.p_l_follow) & ~ps.sizeof_mask; - break; /* inside parens: cast, param list or sizeof */ + /* inside parens: cast, param list, offsetof or sizeof */ + ps.cast_mask |= (1 << ps.p_l_follow) & ~ps.not_cast_mask; + break; } last_code = decl; return (decl); @@ -318,8 +349,6 @@ lexi(void) case 6: /* do, else */ return (sp_nparen); - case 7: - ps.sizeof_keyword = true; default: /* all others are treated like any other * identifier */ return (ident); @@ -346,7 +375,7 @@ lexi(void) && (ps.last_token == rparen || ps.last_token == semicolon || ps.last_token == decl || ps.last_token == lbrace || ps.last_token == rbrace)) { - ps.its_a_keyword = true; + ps.keyword = 4; /* a type name */ ps.last_u_d = true; last_code = decl; return decl; @@ -610,6 +639,6 @@ addkey(char *key, int val) * ignored */ p->rwd = key; p->rwcode = val; - p[1].rwd = 0; + p[1].rwd = NULL; p[1].rwcode = 0; } diff --git a/usr.bin/indent/parse.c b/usr.bin/indent/parse.c index bf90060..c53b444 100644 --- a/usr.bin/indent/parse.c +++ b/usr.bin/indent/parse.c @@ -1,4 +1,4 @@ -/* +/*- * SPDX-License-Identifier: BSD-4-Clause * * Copyright (c) 1985 Sun Microsystems, Inc. @@ -44,6 +44,7 @@ static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/6/93"; #include __FBSDID("$FreeBSD$"); +#include #include #include "indent_globs.h" #include "indent_codes.h" @@ -95,7 +96,13 @@ parse(int tk) /* tk: the code for the construct scanned */ case ifstmt: /* scanned if (...) */ if (ps.p_stack[ps.tos] == elsehead && ps.else_if) /* "else if ..." */ - ps.i_l_follow = ps.il[ps.tos]; + /* + * Note that the stack pointer here is decremented, effectively + * reducing "else if" to "if". This saves a lot of stack space + * in case of a long "if-else-if ... else-if" sequence. + */ + ps.i_l_follow = ps.il[ps.tos--]; + /* the rest is the same as for dolit and forstmt */ case dolit: /* 'do' */ case forstmt: /* for (...) */ ps.p_stack[++ps.tos] = tk; @@ -167,7 +174,7 @@ parse(int tk) /* tk: the code for the construct scanned */ case rbrace: /* scanned a } */ /* stack should have or */ - if (ps.p_stack[ps.tos - 1] == lbrace) { + if (ps.tos > 0 && ps.p_stack[ps.tos - 1] == lbrace) { ps.ind_level = ps.i_l_follow = ps.il[--ps.tos]; ps.p_stack[ps.tos] = stmt; } @@ -202,6 +209,9 @@ parse(int tk) /* tk: the code for the construct scanned */ } /* end of switch */ + if (ps.tos >= STACKSIZE - 1) + errx(1, "Parser stack overflow"); + reduce(); /* see if any reduction can be done */ #ifdef debug @@ -299,7 +309,7 @@ reduce(void) case swstmt: /* */ case_ind = ps.cstk[ps.tos - 1]; - + /* FALLTHROUGH */ case decl: /* finish of a declaration */ case elsehead: /* < else> */ diff --git a/usr.bin/indent/pr_comment.c b/usr.bin/indent/pr_comment.c index e2169a0..9710b7a 100644 --- a/usr.bin/indent/pr_comment.c +++ b/usr.bin/indent/pr_comment.c @@ -1,4 +1,4 @@ -/* +/*- * SPDX-License-Identifier: BSD-4-Clause * * Copyright (c) 1985 Sun Microsystems, Inc. @@ -47,7 +47,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include "indent_globs.h" +#include "indent_codes.h" #include "indent.h" /* * NAME: @@ -89,33 +91,22 @@ pr_comment(void) char *last_bl; /* points to the last blank in the output * buffer */ char *t_ptr; /* used for moving string */ - int unix_comment; /* tri-state variable used to decide if it is - * a unix-style comment. 0 means only blanks - * since /+*, 1 means regular style comment, 2 - * means unix style comment */ int break_delim = comment_delimiter_on_blankline; int l_just_saw_decl = ps.just_saw_decl; - /* - * int ps.last_nl = 0; true iff the last significant thing - * weve seen is a newline - */ - int one_liner = 1; /* true iff this comment is a one-liner */ adj_max_col = max_col; ps.just_saw_decl = 0; - last_bl = 0; /* no blanks found so far */ + last_bl = NULL; /* no blanks found so far */ ps.box_com = false; /* at first, assume that we are not in * a boxed comment or some other * comment that should not be touched */ ++ps.out_coms; /* keep track of number of comments */ - unix_comment = 1; /* set flag to let us figure out if there is a - * unix-style comment ** DISABLED: use 0 to - * reenable this hack! */ /* Figure where to align and how to treat the comment */ if (ps.col_1 && !format_col1_comments) { /* if comment starts in column * 1 it should not be touched */ ps.box_com = true; + break_delim = false; ps.com_col = 1; } else { @@ -128,7 +119,7 @@ pr_comment(void) * be a block comment and is treated as a * box comment unless format_block_comments * is nonzero (the default). */ - break_delim = 0; + break_delim = false; } if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) { /* klg: check only if this line is blank */ @@ -143,7 +134,7 @@ pr_comment(void) } else { int target_col; - break_delim = 0; + break_delim = false; if (s_code != e_code) target_col = count_spaces(compute_code_target(), s_code); else { @@ -152,16 +143,23 @@ pr_comment(void) target_col = count_spaces(compute_label_target(), s_lab); } ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? ps.decl_com_ind : ps.com_ind; - if (ps.com_col < target_col) + if (ps.com_col <= target_col) ps.com_col = ((target_col + 7) & ~7) + 1; if (ps.com_col + 24 > adj_max_col) adj_max_col = ps.com_col + 24; } } if (ps.box_com) { - buf_ptr[-2] = 0; - ps.n_comment_delta = 1 - count_spaces(1, in_buffer); - buf_ptr[-2] = '/'; + /* + * Find out how much indentation there was originally, because that + * much will have to be ignored by pad_output() in dump_line(). This + * is a box comment, so nothing changes -- not even indentation. + * + * The comment we're about to read usually comes from in_buffer, + * unless it has been copied into save_com. + */ + char *start = buf_ptr >= save_com && buf_ptr < save_com + sc_size ? bp_save : buf_ptr; + ps.n_comment_delta = 1 - count_spaces_until(1, in_buffer, start - 2); } else { ps.n_comment_delta = 0; @@ -174,23 +172,39 @@ pr_comment(void) if (*buf_ptr != ' ' && !ps.box_com) *e_com++ = ' '; - *e_com = '\0'; - if (troff) { - now_col = 1; - adj_max_col = 80; + /* + * Don't put a break delimiter if this is a one-liner that won't wrap. + */ + if (break_delim) + for (t_ptr = buf_ptr; *t_ptr != '\0' && *t_ptr != '\n'; t_ptr++) { + if (t_ptr >= buf_end) + fill_buffer(); + if (t_ptr[0] == '*' && t_ptr[1] == '/') { + if (adj_max_col >= count_spaces_until(ps.com_col, buf_ptr, t_ptr + 2)) + break_delim = false; + break; + } + } + + if (break_delim) { + char *t = e_com; + e_com = s_com + 2; + *e_com = 0; + if (blanklines_before_blockcomments && ps.last_token != lbrace) + prefix_blankline_requested = 1; + dump_line(); + e_com = s_com = t; + if (!ps.box_com && star_comment_cont) + *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; } - else - now_col = count_spaces(ps.com_col, s_com); /* figure what column we - * would be in if we - * printed the comment - * now */ + + if (troff) + adj_max_col = 80; /* Start to copy the comment */ while (1) { /* this loop will go until the comment is * copied */ - if (*buf_ptr > 040 && *buf_ptr != '*') - ps.last_nl = 0; CHECK_SIZE_COM; switch (*buf_ptr) { /* this checks for various spcl cases */ case 014: /* check for a form feed */ @@ -198,11 +212,11 @@ pr_comment(void) ps.use_ff = true; /* fix so dump_line uses a form feed */ dump_line(); - last_bl = 0; - *e_com++ = ' '; - *e_com++ = '*'; - *e_com++ = ' '; - while (*++buf_ptr == ' ' || *buf_ptr == '\t'); + last_bl = NULL; + if (!ps.box_com && star_comment_cont) + *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; + while (*++buf_ptr == ' ' || *buf_ptr == '\t') + ; } else { if (++buf_ptr >= buf_end) @@ -214,69 +228,25 @@ pr_comment(void) case '\n': if (had_eof) { /* check for unexpected eof */ printf("Unterminated comment\n"); - *e_com = '\0'; dump_line(); return; } - one_liner = 0; + last_bl = NULL; if (ps.box_com || ps.last_nl) { /* if this is a boxed comment, * we dont ignore the newline */ - if (s_com == e_com) { - *e_com++ = ' '; + if (s_com == e_com) *e_com++ = ' '; - } - *e_com = '\0'; if (!ps.box_com && e_com - s_com > 3) { - if (break_delim == 1 && s_com[0] == '/' - && s_com[1] == '*' && s_com[2] == ' ') { - char *t = e_com; - break_delim = 2; - e_com = s_com + 2; - *e_com = 0; - if (blanklines_before_blockcomments) - prefix_blankline_requested = 1; - dump_line(); - e_com = t; - s_com[0] = s_com[1] = s_com[2] = ' '; - } dump_line(); - CHECK_SIZE_COM; - *e_com++ = ' '; - *e_com++ = ' '; + if (star_comment_cont) + *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; } dump_line(); - now_col = ps.com_col; + if (!ps.box_com && star_comment_cont) + *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; } else { ps.last_nl = 1; - if (unix_comment != 1) { /* we not are in unix_style - * comment */ - if (unix_comment == 0 && s_code == e_code) { - /* - * if it is a UNIX-style comment, ignore the - * requirement that previous line be blank for - * unindention - */ - ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1; - if (ps.com_col <= 1) - ps.com_col = 2; - } - unix_comment = 2; /* permanently remember that we are in - * this type of comment */ - dump_line(); - ++line_no; - now_col = ps.com_col; - *e_com++ = ' '; - /* - * fix so that the star at the start of the line will line - * up - */ - do /* flush leading white space */ - if (++buf_ptr >= buf_end) - fill_buffer(); - while (*buf_ptr == ' ' || *buf_ptr == '\t'); - break; - } if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t') last_bl = e_com - 1; /* @@ -287,7 +257,6 @@ pr_comment(void) last_bl = e_com; CHECK_SIZE_COM; *e_com++ = ' '; - ++now_col; } } ++line_no; /* keep track of input line number */ @@ -314,116 +283,65 @@ pr_comment(void) if (++buf_ptr >= buf_end) /* get to next char after * */ fill_buffer(); - if (unix_comment == 0) /* set flag to show we are not in - * unix-style comment */ - unix_comment = 1; - if (*buf_ptr == '/') { /* it is the end!!! */ end_of_comment: if (++buf_ptr >= buf_end) fill_buffer(); - - if (*(e_com - 1) != ' ' && !ps.box_com) { /* insure blank before - * end */ + CHECK_SIZE_COM; + if (break_delim) { + if (e_com > s_com + 3) { + dump_line(); + } + else + s_com = e_com; *e_com++ = ' '; - ++now_col; - } - if (break_delim == 1 && !one_liner && s_com[0] == '/' - && s_com[1] == '*' && s_com[2] == ' ') { - char *t = e_com; - break_delim = 2; - e_com = s_com + 2; - *e_com = 0; - if (blanklines_before_blockcomments) - prefix_blankline_requested = 1; - dump_line(); - e_com = t; - s_com[0] = s_com[1] = s_com[2] = ' '; } - if (break_delim == 2 && e_com > s_com + 3 - /* now_col > adj_max_col - 2 && !ps.box_com */ ) { - *e_com = '\0'; - dump_line(); - now_col = ps.com_col; - } - CHECK_SIZE_COM; - *e_com++ = '*'; - *e_com++ = '/'; - *e_com = '\0'; + if (e_com[-1] != ' ' && e_com[-1] != '\t' && !ps.box_com) + *e_com++ = ' '; /* ensure blank before end */ + *e_com++ = '*', *e_com++ = '/', *e_com = '\0'; ps.just_saw_decl = l_just_saw_decl; return; } - else { /* handle isolated '*' */ + else /* handle isolated '*' */ *e_com++ = '*'; - ++now_col; - } break; default: /* we have a random char */ - if (unix_comment == 0 && *buf_ptr != ' ' && *buf_ptr != '\t') - unix_comment = 1; /* we are not in unix-style comment */ - - *e_com = *buf_ptr++; - if (buf_ptr >= buf_end) - fill_buffer(); - - if (*e_com == '\t') /* keep track of column */ - now_col = ((now_col - 1) & tabmask) + tabsize + 1; - else if (*e_com == '\b') /* this is a backspace */ - --now_col; - else - ++now_col; - - if (*e_com == ' ' || *e_com == '\t') - last_bl = e_com; - /* remember we saw a blank */ - - ++e_com; - if (now_col > adj_max_col && !ps.box_com && unix_comment == 1 && e_com[-1] > ' ') { + now_col = count_spaces_until(ps.com_col, s_com, e_com); + do { + *e_com = *buf_ptr++; + if (buf_ptr >= buf_end) + fill_buffer(); + if (*e_com == ' ' || *e_com == '\t') + last_bl = e_com; /* remember we saw a blank */ + ++e_com; + now_col++; + } while (!memchr("*\n\r\b\t", *buf_ptr, 6) && + (now_col <= adj_max_col || !last_bl)); + ps.last_nl = false; + if (now_col > adj_max_col && !ps.box_com && e_com[-1] > ' ') { /* * the comment is too long, it must be broken up */ - if (break_delim == 1 && s_com[0] == '/' - && s_com[1] == '*' && s_com[2] == ' ') { - char *t = e_com; - break_delim = 2; - e_com = s_com + 2; - *e_com = 0; - if (blanklines_before_blockcomments) - prefix_blankline_requested = 1; + if (last_bl == NULL) { dump_line(); - e_com = t; - s_com[0] = s_com[1] = s_com[2] = ' '; - } - if (last_bl == 0) { /* we have seen no blanks */ - last_bl = e_com; /* fake it */ - *e_com++ = ' '; + if (!ps.box_com && star_comment_cont) + *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; + break; } - *e_com = '\0'; /* print what we have */ - *last_bl = '\0'; - while (last_bl > s_com && last_bl[-1] < 040) - *--last_bl = 0; + *e_com = '\0'; e_com = last_bl; dump_line(); - - *e_com++ = ' '; /* add blanks for continuation */ - *e_com++ = ' '; - *e_com++ = ' '; - - t_ptr = last_bl + 1; - last_bl = 0; - if (t_ptr >= e_com) { - while (*t_ptr == ' ' || *t_ptr == '\t') - t_ptr++; - while (*t_ptr != '\0') { /* move unprinted part of - * comment down in buffer */ - if (*t_ptr == ' ' || *t_ptr == '\t') - last_bl = e_com; - *e_com++ = *t_ptr++; - } - } - *e_com = '\0'; - now_col = count_spaces(ps.com_col, s_com); /* recompute current - * position */ + if (!ps.box_com && star_comment_cont) + *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; + for (t_ptr = last_bl + 1; *t_ptr == ' ' || *t_ptr == '\t'; + t_ptr++) + ; + last_bl = NULL; + while (*t_ptr != '\0') { + if (*t_ptr == ' ' || *t_ptr == '\t') + last_bl = e_com; + *e_com++ = *t_ptr++; + } } break; } diff --git a/usr.bin/indent/tests/Makefile b/usr.bin/indent/tests/Makefile new file mode 100644 index 0000000..01fa04a --- /dev/null +++ b/usr.bin/indent/tests/Makefile @@ -0,0 +1,45 @@ +# $FreeBSD$ + +PACKAGE= tests + +${PACKAGE}FILES+= binary.0 +${PACKAGE}FILES+= binary.0.stdout +${PACKAGE}FILES+= comments.0 +${PACKAGE}FILES+= comments.0.stdout +${PACKAGE}FILES+= declarations.0 +${PACKAGE}FILES+= declarations.0.stdout +${PACKAGE}FILES+= elsecomment.0 +${PACKAGE}FILES+= elsecomment.0.stdout +${PACKAGE}FILES+= elsecomment.0.pro +${PACKAGE}FILES+= float.0 +${PACKAGE}FILES+= float.0.stdout +${PACKAGE}FILES+= label.0 +${PACKAGE}FILES+= label.0.stdout +${PACKAGE}FILES+= label.0.pro +${PACKAGE}FILES+= list_head.0 +${PACKAGE}FILES+= list_head.0.stdout +${PACKAGE}FILES+= nsac.0 +${PACKAGE}FILES+= nsac.0.stdout +${PACKAGE}FILES+= nsac.0.pro +${PACKAGE}FILES+= offsetof.0 +${PACKAGE}FILES+= offsetof.0.stdout +${PACKAGE}FILES+= sac.0 +${PACKAGE}FILES+= sac.0.stdout +${PACKAGE}FILES+= sac.0.pro +${PACKAGE}FILES+= struct.0 +${PACKAGE}FILES+= struct.0.stdout +${PACKAGE}FILES+= surplusbad.0 +${PACKAGE}FILES+= surplusbad.0.stdout +${PACKAGE}FILES+= surplusbad.0.pro +${PACKAGE}FILES+= types_from_file.0 +${PACKAGE}FILES+= types_from_file.0.stdout +${PACKAGE}FILES+= types_from_file.0.list +${PACKAGE}FILES+= types_from_file.0.pro +${PACKAGE}FILES+= wchar.0 +${PACKAGE}FILES+= wchar.0.stdout + +ATF_TESTS_SH+= functional_test + +BINDIR= ${TESTSDIR} + +.include diff --git a/usr.bin/indent/tests/binary.0 b/usr.bin/indent/tests/binary.0 new file mode 100644 index 0000000..b2adc1f --- /dev/null +++ b/usr.bin/indent/tests/binary.0 @@ -0,0 +1,10 @@ +/* $FreeBSD$ */ +#define b00101010 -1 +void t(void) { + unsigned a[] = {0b00101010, 0x00005678, 02, 17U}; + float x[] = {.7f, 0.7f}; + unsigned long ul[] = {0b00001111UL, 0x01010101UL, 02UL, 17UL}; + + if (0 b00101010) + return; +} diff --git a/usr.bin/indent/tests/binary.0.stdout b/usr.bin/indent/tests/binary.0.stdout new file mode 100644 index 0000000..a883ed9 --- /dev/null +++ b/usr.bin/indent/tests/binary.0.stdout @@ -0,0 +1,12 @@ +/* $FreeBSD$ */ +#define b00101010 -1 +void +t(void) +{ + unsigned a[] = {0b00101010, 0x00005678, 02, 17U}; + float x[] = {.7f, 0.7f}; + unsigned long ul[] = {0b00001111UL, 0x01010101UL, 02UL, 17UL}; + + if (0 b00101010) + return; +} diff --git a/usr.bin/indent/tests/comments.0 b/usr.bin/indent/tests/comments.0 index e642bcc..567d234 100644 --- a/usr.bin/indent/tests/comments.0 +++ b/usr.bin/indent/tests/comments.0 @@ -1,4 +1,11 @@ /* $FreeBSD$ */ +typedef enum x { + aaaaaaaaaaaaaaaaaaaaaa = 1 << 0, /* test a */ + bbbbbbbbbbbbbbbbb = 1 << 1, /* test b */ + cccccccccccccc = 1 << 1, /* test c */ + dddddddddddddddddddddddddddddd = 1 << 2 /* test d */ +} x; + /* See r303597, r303598, r309219, and r309343 */ void t(void) { /* diff --git a/usr.bin/indent/tests/comments.0.pro b/usr.bin/indent/tests/comments.0.pro new file mode 100644 index 0000000..cac04fc --- /dev/null +++ b/usr.bin/indent/tests/comments.0.pro @@ -0,0 +1,2 @@ +/* $FreeBSD$ */ +-bbb diff --git a/usr.bin/indent/tests/comments.0.stdout b/usr.bin/indent/tests/comments.0.stdout index 62417bd..e176a57 100644 --- a/usr.bin/indent/tests/comments.0.stdout +++ b/usr.bin/indent/tests/comments.0.stdout @@ -1,4 +1,11 @@ /* $FreeBSD$ */ +typedef enum x { + aaaaaaaaaaaaaaaaaaaaaa = 1 << 0, /* test a */ + bbbbbbbbbbbbbbbbb = 1 << 1, /* test b */ + cccccccccccccc = 1 << 1, /* test c */ + dddddddddddddddddddddddddddddd = 1 << 2 /* test d */ +} x; + /* See r303597, r303598, r309219, and r309343 */ void t(void) diff --git a/usr.bin/indent/tests/elsecomment.0.pro b/usr.bin/indent/tests/elsecomment.0.pro new file mode 100644 index 0000000..892386f --- /dev/null +++ b/usr.bin/indent/tests/elsecomment.0.pro @@ -0,0 +1,2 @@ +/* $FreeBSD$ */ +-bl diff --git a/usr.bin/indent/tests/elsecomment.pro b/usr.bin/indent/tests/elsecomment.pro deleted file mode 100644 index 892386f..0000000 --- a/usr.bin/indent/tests/elsecomment.pro +++ /dev/null @@ -1,2 +0,0 @@ -/* $FreeBSD$ */ --bl diff --git a/usr.bin/indent/tests/functional_test.sh b/usr.bin/indent/tests/functional_test.sh new file mode 100755 index 0000000..e7b0039 --- /dev/null +++ b/usr.bin/indent/tests/functional_test.sh @@ -0,0 +1,90 @@ +# +# Copyright 2016 Dell EMC +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# $FreeBSD$ + +SRCDIR=$(atf_get_srcdir) + +check() +{ + local tc=${1}; shift + + local indent=$(atf_config_get usr.bin.indent.test_indent /usr/bin/indent) + + # All of the files need to be in the ATF sandbox in order for the tests + # to pass. + atf_check cp ${SRCDIR}/${tc}* . + + # Remove $FreeBSD$ RCS expansions because they get re-indented, which + # changes the output + local out_file="${tc}.stdout" + if [ -f "${out_file}" ]; then + parsed_file=output_file.parsed + + atf_check -o save:$parsed_file sed -e '/\$FreeBSD.*\$/d' \ + ${tc}.stdout + out_flag="-o file:$parsed_file" + fi + local profile_file="${tc}.pro" + if [ -f "${profile_file}" ]; then + profile_flag="-P${profile_file}" + else + # Make sure we don't implicitly use ~/.indent.pro from the test + # host, for determinism purposes. + profile_flag="-npro" + fi + sed -e '/\$FreeBSD.*\$/d' ${tc} > input_file.parsed + atf_check -s exit:${tc##*.} ${out_flag} ${indent} ${profile_flag} < input_file.parsed +} + +add_testcase() +{ + local tc=${1} + local tc_escaped word + + case "${tc%.*}" in + *-*) + local IFS="-" + for word in ${tc%.*}; do + tc_escaped="${tc_escaped:+${tc_escaped}_}${word}" + done + ;; + *) + tc_escaped=${tc%.*} + ;; + esac + + atf_test_case ${tc_escaped} + eval "${tc_escaped}_body() { check ${tc}; }" + atf_add_test_case ${tc_escaped} +} + +atf_init_test_cases() +{ + for path in $(find -Es "${SRCDIR}" -regex '.*\.[0-9]+$'); do + add_testcase ${path##*/} + done +} diff --git a/usr.bin/indent/tests/label.0.pro b/usr.bin/indent/tests/label.0.pro new file mode 100644 index 0000000..b5afc20 --- /dev/null +++ b/usr.bin/indent/tests/label.0.pro @@ -0,0 +1,2 @@ +/* $FreeBSD$ */ +-nut diff --git a/usr.bin/indent/tests/label.pro b/usr.bin/indent/tests/label.pro deleted file mode 100644 index b5afc20..0000000 --- a/usr.bin/indent/tests/label.pro +++ /dev/null @@ -1,2 +0,0 @@ -/* $FreeBSD$ */ --nut diff --git a/usr.bin/indent/tests/nsac.0.pro b/usr.bin/indent/tests/nsac.0.pro new file mode 100644 index 0000000..ce2e4fe --- /dev/null +++ b/usr.bin/indent/tests/nsac.0.pro @@ -0,0 +1,2 @@ +/* $FreeBSD$ */ +-nsac diff --git a/usr.bin/indent/tests/nsac.pro b/usr.bin/indent/tests/nsac.pro deleted file mode 100644 index ce2e4fe..0000000 --- a/usr.bin/indent/tests/nsac.pro +++ /dev/null @@ -1,2 +0,0 @@ -/* $FreeBSD$ */ --nsac diff --git a/usr.bin/indent/tests/sac.0.pro b/usr.bin/indent/tests/sac.0.pro new file mode 100644 index 0000000..ad5cf1a --- /dev/null +++ b/usr.bin/indent/tests/sac.0.pro @@ -0,0 +1,2 @@ +/* $FreeBSD$ */ +-sac diff --git a/usr.bin/indent/tests/sac.pro b/usr.bin/indent/tests/sac.pro deleted file mode 100644 index ad5cf1a..0000000 --- a/usr.bin/indent/tests/sac.pro +++ /dev/null @@ -1,2 +0,0 @@ -/* $FreeBSD$ */ --sac diff --git a/usr.bin/indent/tests/surplusbad.0.pro b/usr.bin/indent/tests/surplusbad.0.pro new file mode 100644 index 0000000..77c3a28 --- /dev/null +++ b/usr.bin/indent/tests/surplusbad.0.pro @@ -0,0 +1,2 @@ +/* $FreeBSD$ */ +-bad diff --git a/usr.bin/indent/tests/surplusbad.pro b/usr.bin/indent/tests/surplusbad.pro deleted file mode 100644 index 77c3a28..0000000 --- a/usr.bin/indent/tests/surplusbad.pro +++ /dev/null @@ -1,2 +0,0 @@ -/* $FreeBSD$ */ --bad diff --git a/usr.bin/indent/tests/types_from_file.0.list b/usr.bin/indent/tests/types_from_file.0.list new file mode 100644 index 0000000..5f73361 --- /dev/null +++ b/usr.bin/indent/tests/types_from_file.0.list @@ -0,0 +1,2 @@ +b +a \ No newline at end of file diff --git a/usr.bin/indent/tests/types_from_file.0.pro b/usr.bin/indent/tests/types_from_file.0.pro new file mode 100644 index 0000000..eeca804 --- /dev/null +++ b/usr.bin/indent/tests/types_from_file.0.pro @@ -0,0 +1,2 @@ +/* $FreeBSD$ */ +-Utypes_from_file.0.list diff --git a/usr.bin/indent/tests/types_from_file.list b/usr.bin/indent/tests/types_from_file.list deleted file mode 100644 index 5f73361..0000000 --- a/usr.bin/indent/tests/types_from_file.list +++ /dev/null @@ -1,2 +0,0 @@ -b -a \ No newline at end of file diff --git a/usr.bin/indent/tests/types_from_file.pro b/usr.bin/indent/tests/types_from_file.pro deleted file mode 100644 index 571b673..0000000 --- a/usr.bin/indent/tests/types_from_file.pro +++ /dev/null @@ -1,2 +0,0 @@ -/* $FreeBSD$ */ --Utypes_from_file.list -- cgit v1.1