Lines Matching +full:eq +full:- +full:level
3 # Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved.
4 # Copyright Siemens AG 2019-2022
11 # check-format.pl
12 # - check formatting of C source according to OpenSSL coding style
15 # check-format.pl [-l|--sloppy-len] [-l|--sloppy-bodylen]
16 # [-s|--sloppy-space] [-c|--sloppy-comment]
17 # [-m|--sloppy-macro] [-h|--sloppy-hang]
18 # [-e|--eol-comment] [-1|--1-stmt]
21 # run self-tests:
22 # util/check-format.pl util/check-format-test-positives.c
23 # util/check-format.pl util/check-format-test-negatives.c
31 # -l | --sloppy-len increase accepted max line length from 80 to 84
32 # -l | --sloppy-bodylen do not report function body length > 200
33 # -s | --sloppy-space do not report whitespace nits
34 # -c | --sloppy-comment do not report indentation of comments
35 # Otherwise for each multi-line comment the indentation of
41 # -m | --sloppy-macro allow missing extra indentation of macro bodies
42 # -h | --sloppy-hang when checking hanging indentation, do not report
44 # * same indentation as non-hanging indent level
45 # * indentation moved left (not beyond non-hanging indent)
47 # -e | --eol-comment report needless intermediate multiple consecutive spaces also before end-o…
48 # -1 | --1-stmt do more aggressive checks for { 1 stmt } - see below
50 # There are non-trivial false positives and negatives such as the following.
66 # Yet with the --1-stmt option false positives are preferred over negatives.
67 # False negatives occur if the braces are more than two non-blank lines apart.
70 # except when this is before end-of-line comments (unless the --eol-comment is given) and
75 # This pattern is recognized - and consequently extra space not reported -
76 # for a given line if in the non-blank line before or after (if existing)
77 # for each occurrence of " \S" (where \S means non-space) in the given line
80 # and false positives (in case of more complex multi-column alignment).
101 # command-line options
111 while ($ARGV[0] =~ m/^-(\w|-[\w\-]+)$/) {
113 if ($arg =~ m/^(l|-sloppy-len)$/) {
115 } elsif ($arg =~ m/^(b|-sloppy-bodylen)$/) {
117 } elsif ($arg =~ m/^(s|-sloppy-space)$/) {
119 } elsif ($arg =~ m/^(c|-sloppy-comment)$/) {
121 } elsif ($arg =~ m/^(m|-sloppy-macro)$/) {
123 } elsif ($arg =~ m/^(h|-sloppy-hang)$/) {
125 } elsif ($arg =~ m/^(e|-eol-comment)$/) {
127 } elsif ($arg =~ m/^(1|-1-stmt)$/) {
130 die("unknown option: -$arg");
135 … # whether the current input file is regarded to contain (positive/negative) self-tests
137 my $in_comment; # number of lines so far within multi-line comment, 0 if no comment, < 0…
138 my $leading_comment; # multi-line comment has no code before its beginning delimiter, if $in_…
139 my $formatted_comment; # multi-line comment beginning with "/*-", which indicates/allows specia…
146 my $preproc_offset; # offset to $block_indent within multi-line preprocessor directive, else…
147 my $in_macro_header; # number of open parentheses + 1 in (multi-line) header of #define, if $…
156 my $code_contents_before; # contents of previous non-comment non-preprocessor-directive line (with…
161 my $in_multiline_string; # line starts within multi-line string literal
162 my $count; # -1 or number of leading whitespace characters (except newline) in curr…
173 my $block_indent; # currently required normal indentation at block/statement level
178 my @nested_block_indents; # stack of indentations at block/statement level, needed due to hanging …
184 my $expr_indent; # resulting hanging indent within (multi-line) expressions including typ…
186 … of local declaration lines after block opening before normal statements, or -1 if no block opening
189 my $in_typedecl; # nesting level of typedef/struct/union/enum
218 $in_block_decls = -1;
322 sub parens_balance { # count balance of opening parentheses - closing parentheses
324 return $str =~ tr/\(// - $str =~ tr/\)//;
327 sub blind_nonspace { # blind non-space text of comment as @, preserving length and spaces
337 sub check_indent { # used for lines outside multi-line string literals
342 m/^\s*\/\*/ ? "intra-line comment" :
350 # allow indent 1 for labels - this cannot happen for leading ':'
353 if (@nested_conds_indents != 0 && substr($_, $count, 1) eq ":") {
354 … # leading ':' within stmt/expr/decl - this cannot happen for labels, leading '&&', or leading '||'
355 # allow special indent at level of corresponding "?"
356 ($alt_desc, $alt_indent) = ("leading ':'", @nested_conds_indents[-1]);
358 # allow extra indent offset leading '&&' or '||' - this cannot happen for leading ":"
361 …ndent < 0) { # implies @nested_symbols != 0 && @nested_symbols[0] eq "{" && @nested_indents[-1] < 0
362 … # allow normal stmt indentation level for hanging initializer/enum expressions after trailing '{'
366 …@nested_indents[-1] = $count == $stmt_indent ? $stmt_indent : -@nested_indents[-1]; # allow $stmt_…
367 $ref_indent = $expr_indent = @nested_indents[-1];
370 …# check consistency of indentation within multi-line comment (i.e., between its first, inner, and …
371 if ($in_comment != 0 && $in_comment != 1) { # in multi-line comment but not on its first line
374 report("indent = $count != $comment_indent within multi-line comment")
377 my $tweak = $in_comment == -2 ? 1 : 0;
378 … report("indent = ".($count + $tweak)." != $comment_indent at end of multi-line comment")
382 # do not check indentation of last line of non-leading multi-line comment
388 # $comment_indent will be checked by the below checks for end of multi-line comment
391 # else check indentation of entire-line comment or entire-line end of multi-line comment
393 …if (($in_comment == 0 || $in_comment == 1) # no comment, intra-line comment, or begin of multi-lin…
396 …report_flexibly($line_before, "entire-line comment indent = $count_before != $count (of following …
397 $contents_before) if !$sloppy_cmt && $count_before != -1 && $count_before != $count;
400 …if (($in_comment == 0 || $in_comment < 0) # (no comment,) intra-line comment or end of multi-line …
406 return if !eof; # defer check of entire-line comment to next line
409 # else check indentation of leading intra-line comment or end of multi-line comment
412 report("intra-line comment indent = $count != $ref_indent") if $in_comment == 0;
413 report("multi-line comment indent = $count != $ref_indent") if $in_comment < 0;
422 …# do not report indentation at normal indentation level while hanging expression indent would be r…
432 ($alt_desc eq ""
443 my $terminator_position = -1;
453 $i += length($1) + length($2) - 1;
456 return $i if $c eq ";" && (!$in_paren_expr || @nested_indents == 0);
460 if ($c eq "{") { # '{' in any context
462 … # cancel newly hanging_offset if opening brace '{' is after non-whitespace non-comment:
463 $hanging_offset -= INDENT_LEVEL if $hanging_offset > 0 && $head =~ m/[^\s\@]/;
473 ? $i + 1 + length($1) # actual indentation of following non-space non-comment
475 … : -($i + 1); # allow also $stmt_indent if '{' with only whitespace thereafter
477 … push @nested_conds_indents, $i if $c eq "?"; # remember special alternative indent for ':'
485 # # multi-line expr after 'case'
492 … @nested_symbols[-1] == $opening_c) { # for $c there was a corresponding $opening_c
495 pop @nested_conds_indents if $opening_c eq "?";
501 if ($c eq "}") { # '}' at block level but also inside stmt/expr/decl
514 … if $tail =~ m/^([^{]*)/ && $1 =~ m/[^\s\@;]/; # non-space non-';' before any '{'
519 return -1;
527 if ($symbol eq "{") { # repair stack of blocks
542 $self_test = $ARGV =~ m/check-format-test/;
549 if (m/(.*?)([\x00-\x09\x0B-\x1F\x7F-\xFF])/) {
551 report(($2 eq "\x09" ? "TAB" : $2 eq "\x0D" ? "CR " : $2 =~ m/[\x00-\x1F]/ ? "non-printable"
552 : "non-7bit char") . " at column $col") ;
558 # assign to $count the actual indentation level of the current line
569 # handle multi-line string literals to avoid confusion on starting/ending '"' and trailing '\'
573 $count = -1; # do not check indentation
575 report("multi-line string literal not terminated by '\"' and trailing '\' is missing")
583 s#('[^']*')#$1 =~ tr/'/@/cr#eg; # handle all intra-line character literals
584 s#("[^"]*")#$1 =~ tr/"/@/cr#eg; # handle all intra-line string literals
595 # do/prepare checks within multi-line comments
597 if ($in_comment > 0) { # this still includes the last line of multi-line comment
599 if ($any_symbol eq "*") {
600 …report("missing space or '*' after leading '*' in multi-line comment") if $cmt_text =~ m|^[^*\s/$s…
602 report("missing leading '*' in multi-line comment");
607 …# detect end of comment, must be within multi-line comment, check if it is preceded by non-whitesp…
616 … report("text before '*/' in multi-line comment") if ($head =~ m/[^*\s]/); # non-SPC before '*/'
617 $in_comment = -1; # indicate that multi-line comment ends on current line
619 … # make indentation of end of multi-line comment appear like of leading intra-line comment
621 $count--;
622 … $in_comment = -2; # indicate that multi-line comment ends on current line, with tweak
630 # detect begin of comment, check if it is followed by non-space text
632 if (my ($head, $opt_minus, $tail) = m|^(.*?)/\*(-?)(.*)$|) { # begin of comment: '/*'
638 report("unexpected '/*' inside multi-line comment");
640 report("unexpected '/*' inside intra-line comment") if $1 =~ /\/\*/;
645 } else { # begin of multi-line comment
647 report("text after '/*' in multi-line comment")
655 $formatted_comment = $opt_minus eq "-";
657 } elsif (($head, $tail) = m|^\{-(.*)$|) { # begin of Perl pragma: '{-'
660 if ($in_comment > 1) { # still inside multi-line comment (not at its begin or end)
672 # check for over-long lines,
673 # while allowing trailing (also multi-line) string literals to go past $max_length
678 # this allows over-long trailing string literals with beginning col before $max_length
683 # handle C++ / C99 - style end-of-line comments
685 report("'//' end-of-line comment"); # the '//' comment style is not allowed for C90
690 # at this point all non-space portions of any types of comments have been blinded as @
697 # blank these portions to prevent confusion with C-level 'if', 'else', etc.
701 $_ = blind_nonspace($_) if $preproc_directive eq "error"; # blind error message
703 report("preprocessor directive within multi-line directive");
709 if $preproc_directive =~ m/^(if|elif)$/ && m/^[\W0-9]+$/ && !$trailing_backslash;
710 $preproc_if_nesting-- if $preproc_directive =~ m/^(else|elif|endif)$/;
718 $ifdef__cplusplus = $preproc_directive eq "ifdef" && m/\s+__cplusplus\s*$/;
721 $count = -1; # do not check indentation of first line of preprocessor directive
726 # intra-line whitespace nits @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
733 $in_comment != 0 ? " in multi-line comment"
734 : " in intra-line comment" : "");
736 … split line contents into header containing leading spaces and the first non-space char, and the r…
738 … $in_comment != 0 ? "@" : ""; # '@' will match the blinded leading '*' in multi-line comment
740 …# do not check for extra SPC in leading spaces including any '#' (or '*' within multi-line comment)
750 my $head = shift; # leading spaces and the first non-space char
753 … # check if all extra SPC in $intra is used only for multi-line column alignment with $contents
755 for (my $col = 0; $col < length($intra) - 2; $col++) {
758 next if !$eol_cmt && $substr =~ m/^[@\s]+$/; # end-of-line comment
776 || ($intra_line =~ m/(\S)([\+\-\*\/\/%\&\|\^\!<>=]=)/
779 && !($1 =~ m/[\+\-\*\/\/%\&\|\^\!<>=]/)
782 $intra_line =~ s/(<<|>>|[\+\-\*\/\/%\&\|\^\!<>=])=/=/g;
784 $intra_line =~ s/[A-Z_]+/int/g if $trailing_backslash;
796 "$1$3$4".("$3$4$5$6$7" eq ";" || $3 ne "" || $7 ne "" ? "" : $5).";$6$7$8"/eg;
799 "$1$3".($3 eq ";" ? $5 : "")."$6"/eg;
802 …report("space before '$1'") if $intra_line =~ m/[\w)\]]\s+(\+\+|--)/; # postfix ++/-- with preced…
803 …report("space after '$1'") if $intra_line =~ m/(\+\+|--)\s+[a-zA-Z_(]/; # prefix ++/-- with follo…
805 …report("space before '$1'") if $intra_line =~ m/\s(\.|->)/; # '.' or '->' with precedin…
806 …report("space after '$1'") if $intra_line =~ m/(\.|->)\s/; # '.' or '->' with followin…
807 $intra_line =~ s/\-\>|\+\+|\-\-/@/g; # blind '->,', '++', and '--'
815 …ing space before binary '$2'") if $intra_line =~ m/([^\s{()\[e])([+\-])/; # '+'/'-' without prece…
816 …# ')' may be used for type casts or before "->", 'e' may be used for numerical literals such as "1…
821 …report("missing space after binary '$1'") if $intra_line=~m/[^{(\[]([*])[^\sa-zA-Z_(),*]/;# '*' w/…
823 …report("missing space after binary '$1'") if $intra_line=~m/([&])[^\sa-zA-Z_(]/; # '&' w/o follow…
825 …report("missing space after binary '$1'") if $intra_line=~m/[^{(\[]([+\-])[^\s\d(]/; # +/- w/o fo…
826 # TODO unary '+' and '-' must not be followed by SPC
839 …s/(\w*ASN1_[A-Z_]+END\w*([^(]|\(.*?\)|$))/$1;/g; # treat *ASN1_*END*(..) macro calls as if followe…
845 if ($in_stmt) { # expr/stmt/type decl/var def/fn hdr, i.e., not at block level
847 $in_block_decls = -1;
852 $hanging_symbol = @nested_symbols[-1];
853 $expr_indent = @nested_indents[-1];
858 $local_offset = -INDENT_LEVEL;
880 if (!$in_stmt) { # at block level, i.e., outside expr/stmt/type decl/var def/fn hdr
883 … # with non-whitespace non-'{' before
884 … report("code after '}'") unless $tail eq "" || $tail =~ m/(else|while|OSSL_TRACE_END)(\W|$)/;
887 my $body_len = $line - $line_body_start - 1;
892 if ($before ne "") { # non-whitespace non-'{' before '}'
895 $in_block_decls = -1;
896 $local_offset = $block_indent + $hanging_offset - INDENT_LEVEL;
899 $local_offset -= ($block_indent + $hanging_offset);
900 …# in effect $local_offset = -INDENT_LEVEL relative to $block_indent + $hanging_offset values before
909 $hanging_offset -= INDENT_LEVEL; # cancel newly hanging_offset
915 $local_offset = -INDENT_LEVEL;
918 $local_offset = -INDENT_LEVEL;
924 # potential adaptations of indent in first line of macro body in multi-line macro definition
930 … if ($count == $block_indent - $preproc_offset # body began with same indentation as preceding code
932 $block_indent -= $preproc_offset;
940 …check_indent() if $count >= 0; # not for start of preprocessor directive and not if multi-line str…
945 $in_comment == 0 && !m/^\s*\*?@/ && # not in a multi-line or intra-line comment
950 …)]))+?\s+[\*\(]*\w+(\s*(\)|\[[^\]]*\]))*\s*[;,=]/ # weak check for decl involving user-defined type
953 …report_flexibly($line - 1, "blank line within local decls, before", $contents) if $blank_line_befo…
957 $in_block_decls = -1 unless
959 || $in_comment != 0 || m/^\s*\*?@/; # in multi-line comment or an intra-line comment
963 $in_comment = 0 if $in_comment < 0; # multi-line comment has ended
967 my $outermost_level = $block_indent - $preproc_offset == 0;
969 report("more than one stmt") if !m/(^|\W)for(\W.*|$)/ && # no 'for' - TODO improve matching
976 # TODO extend detection from single-line to potentially multi-line statement
990 …report("single-letter name '$2'") if (m/(^|.*\W)([IO])(\W.*|$)/); # single-letter name 'I' or 'O' …
993 if (m/(['"]|([\+\-\*\/\/%\&\|\^<>]\s*)?\W[0-9]+L?|\WNULL)\s*([\!<>=]=|[<=>])([<>]?)/ &&
994 $2 eq "" && (($3 ne "<" && $3 ne "='" && $3 ne ">") || $4 eq ""));
1006 …$tmp =~ s/[\!<>=]=/@@/g; # blind (in-)equality symbols like '<=' as '@@' to prevent matching them …
1020 # to cope with multi-line expressions, do this also if !($tail =~ m/\{/)
1021 push @in_if_hanging_offsets, $hanging_offset if $mid eq "if";
1029 if ($mid eq "while" && @in_do_hanging_offsets != 0) {
1038 my $code_before = $head =~ m/[^\s\@}]/; # leading non-whitespace non-comment non-'}'
1040 …code after '$mid'" ) if $tail =~ m/[^\s\@{]/# trailing non-whitespace non-comment non-'{' (non-'\')
1041 … && !($mid eq "else" && $tail =~ m/[\s@]*if(\W|$)/);
1042 if ($mid eq "do") { # workarounds for code before 'do'
1051 push @in_do_hanging_offsets, $hanging_offset if $mid eq "do";
1052 if ($code_before && $mid eq "do") {
1053 $hanging_offset = length($head) - $block_indent;
1065 …&& ($2 eq "typedef" || !($3 =~ m/\s*\w++\s*(.)/ && $1 ne "{")) # 'struct'/'union'/'enum' <name> no…
1069 …$hanging_offset += INDENT_LEVEL if m/\*.*\(/; # '*' followed by '(' - seems consistent with Emacs …
1076 … # on end of non-if/while/for/switch (multi-line) expression (i.e., return/enum/assignment) and
1092 $hanging_offset -= INDENT_LEVEL;
1102 …$in_typedecl-- if $in_typedecl != 0 && @nested_in_typedecl == 0; # TODO handle multiple type decls…
1104 $terminator_position = length($_) - length($1) if $1;
1110 …# set hanging expression indent according to nested indents - TODO maybe do better in update_neste…
1113 for (my $i = -1; $i >= -@nested_symbols; $i--) {
1140 … $line_opening_brace = $line if $keyword_opening_brace eq "else" && $extended_1_stmt &&
1141 … # TODO prevent false positives for if/else where braces around single-statement branches
1144 !($keyword_opening_brace eq "else" && $line_opening_brace < $line_before2);
1146 … report("code after '{'") if $tail=~ m/[^\s\@]/ && # trailing non-whitespace non-comment (non-'\')
1199 # on begin of multi-line preprocessor directive, adapt indent
1202 if ($in_preproc == 1) { # start of multi-line preprocessor directive
1211 # post-processing at end of line @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1215 !m/^\s*#(\s*)(\w+)/ && # not single-line preprocessor directive
1216 $in_comment == 0 && !m/^\s*\*?@/; # not in a multi-line comment nor in an intra-line comment
1218 # on end of (possibly multi-line) preprocessor directive, adapt indent
1226 … report("leading ".($1 eq "" ? "blank" :"whitespace")." line") if $line == 1 && !$sloppy_SPC;
1229 my $linediff = $line - $line_before - 1;
1249 # post-processing at end of file @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1253 report(($1 eq "\n" ? "blank line" : $2 ne "" ? "'\\'" : "whitespace")." at EOF")
1256 # report unclosed expression-level nesting
1259 # sanity-check balance of block-level { ... } via final $block_indent at end of file
1262 … # sanity-check balance of #if ... #endif via final preprocessor directive indent at end of file
1271 my $num_other_reports = $num_reports - $num_indent_reports - $num_nesting_issues
1272 - $num_syntax_issues - $num_SPC_reports - $num_length_reports;