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
676 if ($off >= $len) {676 if ($off >= $len) {
677 last;677 last;
678 }678 }
679 if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
680 $level++;
681 $type = '#';
682 }
679 }683 }
680 $p = $c;684 $p = $c;
681 $c = substr($blk, $off, 1);685 $c = substr($blk, $off, 1);
@@ -738,6 +742,13 @@ sub ctx_statement_block { · 56 unmodified lines
738 last;742 last;
739 }743 }
740 }744 }
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 }
741 $off++;752 $off++;
742 }753 }
743 # We are truly at the end, so shuffle to the next line.754 # We are truly at the end, so shuffle to the next line.
@@ -1801,6 +1812,8 @@ sub process { · 1057 unmodified lines
1801 $stat =~ s/\n./\n /g;1812 $stat =~ s/\n./\n /g;
1802 $cond =~ s/\n./\n /g;1813 $cond =~ s/\n./\n /g;
1803 1814
1815#print "stat<$stat>\n";
1816
1804 # Find the real next line.1817 # Find the real next line.
1805 $realline_next = $line_nr_next;1818 $realline_next = $line_nr_next;
1806 if (defined $realline_next &&1819 if (defined $realline_next &&
@@ -2781,47 +2794,13 @@ sub process { · 974 unmodified lines
2781 my $cnt = $realcnt;2794 my $cnt = $realcnt;
2782 my ($off, $dstat, $dcond, $rest);2795 my ($off, $dstat, $dcond, $rest);
2783 my $ctx = '';2796 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
2798 ($dstat, $dcond, $ln, $cnt, $off) =2797 ($dstat, $dcond, $ln, $cnt, $off) =
2799 ctx_statement_block($linenr, $ln - $linenr + 1, 0);2798 ctx_statement_block($linenr, $realcnt, 0);
2799 $ctx = $dstat;
2800 #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";2800 #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
2801 #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";2801 #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
2802 2802
2803 # Extract the remainder of the define (if any) and2803 $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//;
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 }
2825 $dstat =~ s/$;//g;2804 $dstat =~ s/$;//g;
2826 $dstat =~ s/\\\n.//g;2805 $dstat =~ s/\\\n.//g;
2827 $dstat =~ s/^\s*//s;2806 $dstat =~ s/^\s*//s;
@@ -2847,23 +2826,32 @@ sub process { · 19 unmodified lines
2847 ^\"|\"$2826 ^\"|\"$
2848 }x;2827 }x;
2849 #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";2828 #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
2850 if ($rest ne '' && $rest ne ',') {2829 if ($dstat ne '' &&
2851 if ($rest !~ /while\s*\(/ &&2830 $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(),
2852 $dstat !~ /$exceptions/)2831 $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo();
2853 {2832 $dstat !~ /^(?:$Ident|-?$Constant)$/ && # 10 // foo()
2854 ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",2833 $dstat !~ /$exceptions/ &&
2855 "Macros with multiple statements should be enclosed in a do - while loop\n" . "$here\n$ctx\n");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";
2856 }2847 }
2857 2848
2858 } elsif ($ctx !~ /;/) {2849 if ($dstat =~ /;/) {
2859 if ($dstat ne '' &&2850 ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
2860 $dstat !~ /^(?:$Ident|-?$Constant)$/ &&2851 "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
2861 $dstat !~ /$exceptions/ &&2852 } else {
2862 $dstat !~ /^\.$Ident\s*=/ &&
2863 $dstat =~ /$Operators/)
2864 {
2865 ERROR("COMPLEX_MACRO",2853 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");
2867 }2855 }
2868 }2856 }
2869 }2857 }