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.
Showing the changes to scripts/checkpatch.pl (1 of 1 file). Show all
Unified · Split
| @@ -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) and | 2803 | $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 | } |