History

checkpatch: correctly track the end of preprocessor commands in context

When looking for a statement we currently run on through preprocessor commands. This means that a header file with just definitions is parsed over and over again combining all of the lines from the current line to the end of file leading to severe performance issues. Fix up context accumulation to track preprocessor commands and stop when reaching the end of them. At the same time vastly simplify the #define handling.

Andy Whitcroft committed 14 years ago

Commit f74bd191 parent 5f14d3b1 file · +39 −51Browse files

Showing the changes to scripts/checkpatch.pl (1 of 1 file). Show all

Unified · Split

scripts/checkpatch.pl+39−51
@@ -676,6 +676,10 @@ sub ctx_statement_block { · 675 unmodified lines
676676 if ($off >= $len) {
677677 last;
678678 }
679+ if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
680+ $level++;
681+ $type = '#';
682+ }
679683 }
680684 $p = $c;
681685 $c = substr($blk, $off, 1);
@@ -738,6 +742,13 @@ sub ctx_statement_block { · 56 unmodified lines
738742 last;
739743 }
740744 }
745+ # Preprocessor commands end at the newline unless escaped.
746+ if ($type eq '#' && $c eq "\n" && $p ne "\\") {
747+ $level--;
748+ $type = '';
749+ $off++;
750+ last;
751+ }
741752 $off++;
742753 }
743754 # We are truly at the end, so shuffle to the next line.
@@ -1801,6 +1812,8 @@ sub process { · 1057 unmodified lines
18011812 $stat =~ s/\n./\n /g;
18021813 $cond =~ s/\n./\n /g;
18031814
1815+#print "stat<$stat>\n";
1816+
18041817 # Find the real next line.
18051818 $realline_next = $line_nr_next;
18061819 if (defined $realline_next &&
@@ -2781,47 +2794,13 @@ sub process { · 974 unmodified lines
27812794 my $cnt = $realcnt;
27822795 my ($off, $dstat, $dcond, $rest);
27832796 my $ctx = '';
2784−
2785− my $args = defined($1);
2786−
2787− # Find the end of the macro and limit our statement
2788− # search to that.
2789− while ($cnt > 0 && defined $lines[$ln - 1] &&
2790− $lines[$ln - 1] =~ /^(?:-|..*\\$)/)
2791− {
2792− $ctx .= $rawlines[$ln - 1] . "\n";
2793− $cnt-- if ($lines[$ln - 1] !~ /^-/);
2794− $ln++;
2795− }
2796− $ctx .= $rawlines[$ln - 1];
2797−
27982797 ($dstat, $dcond, $ln, $cnt, $off) =
2799− ctx_statement_block($linenr, $ln - $linenr + 1, 0);
2798+ ctx_statement_block($linenr, $realcnt, 0);
2799+ $ctx = $dstat;
28002800 #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
28012801 #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
28022802
2803− # Extract the remainder of the define (if any) and
2804− # rip off surrounding spaces, and trailing \'s.
2805− $rest = '';
2806− while ($off != 0 || ($cnt > 0 && $rest =~ /\\\s*$/)) {
2807− #print "ADDING cnt<$cnt> $off <" . substr($lines[$ln - 1], $off) . "> rest<$rest>\n";
2808− if ($off != 0 || $lines[$ln - 1] !~ /^-/) {
2809− $rest .= substr($lines[$ln - 1], $off) . "\n";
2810− $cnt--;
2811− }
2812− $ln++;
2813− $off = 0;
2814− }
2815− $rest =~ s/\\\n.//g;
2816− $rest =~ s/^\s*//s;
2817− $rest =~ s/\s*$//s;
2818−
2819− # Clean up the original statement.
2820− if ($args) {
2821− substr($dstat, 0, length($dcond), '');
2822− } else {
2823− $dstat =~ s/^.\s*\#\s*define\s+$Ident\s*//;
2824− }
2803+ $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//;
28252804 $dstat =~ s/$;//g;
28262805 $dstat =~ s/\\\n.//g;
28272806 $dstat =~ s/^\s*//s;
@@ -2847,23 +2826,32 @@ sub process { · 19 unmodified lines
28472826 ^\"|\"$
28482827 }x;
28492828 #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
2850− if ($rest ne '' && $rest ne ',') {
2851− if ($rest !~ /while\s*\(/ &&
2852− $dstat !~ /$exceptions/)
2853− {
2854− ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
2855− "Macros with multiple statements should be enclosed in a do - while loop\n" . "$here\n$ctx\n");
2829+ if ($dstat ne '' &&
2830+ $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(),
2831+ $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo();
2832+ $dstat !~ /^(?:$Ident|-?$Constant)$/ && # 10 // foo()
2833+ $dstat !~ /$exceptions/ &&
2834+ $dstat !~ /^\.$Ident\s*=/ && # .foo =
2835+ $dstat !~ /^do\s*$Constant\s*while\s*$Constant;$/ && # do {...} while (...);
2836+ $dstat !~ /^for\s*$Constant$/ && # for (...)
2837+ $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar()
2838+ $dstat !~ /^do\s*{/ && # do {...
2839+ $dstat !~ /^\({/) # ({...
2840+ {
2841+ $ctx =~ s/\n*$//;
2842+ my $herectx = $here . "\n";
2843+ my $cnt = statement_rawlines($ctx);
2844+
2845+ for (my $n = 0; $n < $cnt; $n++) {
2846+ $herectx .= raw_line($linenr, $n) . "\n";
28562847 }
28572848
2858− } elsif ($ctx !~ /;/) {
2859− if ($dstat ne '' &&
2860− $dstat !~ /^(?:$Ident|-?$Constant)$/ &&
2861− $dstat !~ /$exceptions/ &&
2862− $dstat !~ /^\.$Ident\s*=/ &&
2863− $dstat =~ /$Operators/)
2864− {
2849+ if ($dstat =~ /;/) {
2850+ ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
2851+ "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
2852+ } else {
28652853 ERROR("COMPLEX_MACRO",
2866− "Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n");
2854+ "Macros with complex values should be enclosed in parenthesis\n" . "$herectx");
28672855 }
28682856 }
28692857 }