Commit 5b57980d authored by Joe Perches's avatar Joe Perches Committed by Linus Torvalds

checkpatch: improve runtime execution speed a little

checkpatch repeatedly uses a runtime minimum version check that validates
the minimum perl version required for a regex match by using a "$^V ge
5.10.0" runtime string match.

Only perform that minimum version test once and store the result to reduce
string matching time.

This reduces runtime execution time for patches or files with high line
counts.

An example runtime improvement:

new: $ time ./scripts/checkpatch.pl -f drivers/net/ethernet/intel/i40e/i40e_main.c > /dev/null

real	0m11.856s
user	0m11.831s
sys	0m0.025s

old: $ time ./scripts/checkpatch.pl -f drivers/net/ethernet/intel/i40e/i40e_main.c > /dev/null

real	0m13.330s
user	0m13.282s
sys	0m0.049s

Link: http://lkml.kernel.org/r/db21aa9703833bad65ab70cc4e8a78da5b399138.camel@perches.comSigned-off-by: default avatarJoe Perches <joe@perches.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 79682c0c
...@@ -240,11 +240,11 @@ $check_orig = $check; ...@@ -240,11 +240,11 @@ $check_orig = $check;
my $exit = 0; my $exit = 0;
my $perl_version_ok = 1;
if ($^V && $^V lt $minimum_perl_version) { if ($^V && $^V lt $minimum_perl_version) {
$perl_version_ok = 0;
printf "$P: requires at least perl version %vd\n", $minimum_perl_version; printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
if (!$ignore_perl_version) { exit(1) if (!$ignore_perl_version);
exit(1);
}
} }
#if no filenames are given, push '-' to read patch from stdin #if no filenames are given, push '-' to read patch from stdin
...@@ -1026,11 +1026,11 @@ if (!$quiet) { ...@@ -1026,11 +1026,11 @@ if (!$quiet) {
hash_show_words(\%use_type, "Used"); hash_show_words(\%use_type, "Used");
hash_show_words(\%ignore_type, "Ignored"); hash_show_words(\%ignore_type, "Ignored");
if ($^V lt 5.10.0) { if (!$perl_version_ok) {
print << "EOM" print << "EOM"
NOTE: perl $^V is not modern enough to detect all possible issues. NOTE: perl $^V is not modern enough to detect all possible issues.
An upgrade to at least perl v5.10.0 is suggested. An upgrade to at least perl $minimum_perl_version is suggested.
EOM EOM
} }
if ($exit) { if ($exit) {
...@@ -3079,7 +3079,7 @@ sub process { ...@@ -3079,7 +3079,7 @@ sub process {
} }
# check indentation starts on a tab stop # check indentation starts on a tab stop
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
$sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) { $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
my $indent = length($1); my $indent = length($1);
if ($indent % 8) { if ($indent % 8) {
...@@ -3092,7 +3092,7 @@ sub process { ...@@ -3092,7 +3092,7 @@ sub process {
} }
# check multi-line statement indentation matches previous line # check multi-line statement indentation matches previous line
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
$prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
$prevline =~ /^\+(\t*)(.*)$/; $prevline =~ /^\+(\t*)(.*)$/;
my $oldindent = $1; my $oldindent = $1;
...@@ -3967,7 +3967,7 @@ sub process { ...@@ -3967,7 +3967,7 @@ sub process {
# function brace can't be on same line, except for #defines of do while, # function brace can't be on same line, except for #defines of do while,
# or if closed on same line # or if closed on same line
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
$sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ && $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
$sline !~ /\#\s*define\b.*do\s*\{/ && $sline !~ /\#\s*define\b.*do\s*\{/ &&
$sline !~ /}/) { $sline !~ /}/) {
...@@ -4578,7 +4578,7 @@ sub process { ...@@ -4578,7 +4578,7 @@ sub process {
# check for unnecessary parentheses around comparisons in if uses # check for unnecessary parentheses around comparisons in if uses
# when !drivers/staging or command-line uses --strict # when !drivers/staging or command-line uses --strict
if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) && if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
$^V && $^V ge 5.10.0 && defined($stat) && $perl_version_ok && defined($stat) &&
$stat =~ /(^.\s*if\s*($balanced_parens))/) { $stat =~ /(^.\s*if\s*($balanced_parens))/) {
my $if_stat = $1; my $if_stat = $1;
my $test = substr($2, 1, -1); my $test = substr($2, 1, -1);
...@@ -4615,7 +4615,7 @@ sub process { ...@@ -4615,7 +4615,7 @@ sub process {
# return is not a function # return is not a function
if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
my $spacing = $1; my $spacing = $1;
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
$stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
my $value = $1; my $value = $1;
$value = deparenthesize($value); $value = deparenthesize($value);
...@@ -4642,7 +4642,7 @@ sub process { ...@@ -4642,7 +4642,7 @@ sub process {
} }
# if statements using unnecessary parentheses - ie: if ((foo == bar)) # if statements using unnecessary parentheses - ie: if ((foo == bar))
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
$line =~ /\bif\s*((?:\(\s*){2,})/) { $line =~ /\bif\s*((?:\(\s*){2,})/) {
my $openparens = $1; my $openparens = $1;
my $count = $openparens =~ tr@\(@\(@; my $count = $openparens =~ tr@\(@\(@;
...@@ -4659,7 +4659,7 @@ sub process { ...@@ -4659,7 +4659,7 @@ sub process {
# avoid cases like "foo + BAR < baz" # avoid cases like "foo + BAR < baz"
# only fix matches surrounded by parentheses to avoid incorrect # only fix matches surrounded by parentheses to avoid incorrect
# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" # conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
$line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
my $lead = $1; my $lead = $1;
my $const = $2; my $const = $2;
...@@ -5084,7 +5084,7 @@ sub process { ...@@ -5084,7 +5084,7 @@ sub process {
# do {} while (0) macro tests: # do {} while (0) macro tests:
# single-statement macros do not need to be enclosed in do while (0) loop, # single-statement macros do not need to be enclosed in do while (0) loop,
# macro should not end with a semicolon # macro should not end with a semicolon
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
$realfile !~ m@/vmlinux.lds.h$@ && $realfile !~ m@/vmlinux.lds.h$@ &&
$line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
my $ln = $linenr; my $ln = $linenr;
...@@ -5460,7 +5460,7 @@ sub process { ...@@ -5460,7 +5460,7 @@ sub process {
} }
# check for mask then right shift without a parentheses # check for mask then right shift without a parentheses
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
$line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
$4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
WARN("MASK_THEN_SHIFT", WARN("MASK_THEN_SHIFT",
...@@ -5468,7 +5468,7 @@ sub process { ...@@ -5468,7 +5468,7 @@ sub process {
} }
# check for pointer comparisons to NULL # check for pointer comparisons to NULL
if ($^V && $^V ge 5.10.0) { if ($perl_version_ok) {
while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
my $val = $1; my $val = $1;
my $equal = "!"; my $equal = "!";
...@@ -5740,7 +5740,7 @@ sub process { ...@@ -5740,7 +5740,7 @@ sub process {
} }
# Check for __attribute__ weak, or __weak declarations (may have link issues) # Check for __attribute__ weak, or __weak declarations (may have link issues)
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
$line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
$line =~ /\b__weak\b/)) { $line =~ /\b__weak\b/)) {
...@@ -5822,7 +5822,7 @@ sub process { ...@@ -5822,7 +5822,7 @@ sub process {
} }
# check for vsprintf extension %p<foo> misuses # check for vsprintf extension %p<foo> misuses
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
defined $stat && defined $stat &&
$stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
$1 !~ /^_*volatile_*$/) { $1 !~ /^_*volatile_*$/) {
...@@ -5869,7 +5869,7 @@ sub process { ...@@ -5869,7 +5869,7 @@ sub process {
} }
# Check for misused memsets # Check for misused memsets
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
defined $stat && defined $stat &&
$stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
...@@ -5887,7 +5887,7 @@ sub process { ...@@ -5887,7 +5887,7 @@ sub process {
} }
# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) # Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
# if ($^V && $^V ge 5.10.0 && # if ($perl_version_ok &&
# defined $stat && # defined $stat &&
# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { # $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
# if (WARN("PREFER_ETHER_ADDR_COPY", # if (WARN("PREFER_ETHER_ADDR_COPY",
...@@ -5898,7 +5898,7 @@ sub process { ...@@ -5898,7 +5898,7 @@ sub process {
# } # }
# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) # Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
# if ($^V && $^V ge 5.10.0 && # if ($perl_version_ok &&
# defined $stat && # defined $stat &&
# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { # $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
# WARN("PREFER_ETHER_ADDR_EQUAL", # WARN("PREFER_ETHER_ADDR_EQUAL",
...@@ -5907,7 +5907,7 @@ sub process { ...@@ -5907,7 +5907,7 @@ sub process {
# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr # check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr # check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
# if ($^V && $^V ge 5.10.0 && # if ($perl_version_ok &&
# defined $stat && # defined $stat &&
# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { # $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
# #
...@@ -5929,7 +5929,7 @@ sub process { ...@@ -5929,7 +5929,7 @@ sub process {
# } # }
# typecasts on min/max could be min_t/max_t # typecasts on min/max could be min_t/max_t
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
defined $stat && defined $stat &&
$stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
if (defined $2 || defined $7) { if (defined $2 || defined $7) {
...@@ -5953,7 +5953,7 @@ sub process { ...@@ -5953,7 +5953,7 @@ sub process {
} }
# check usleep_range arguments # check usleep_range arguments
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
defined $stat && defined $stat &&
$stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
my $min = $1; my $min = $1;
...@@ -5969,7 +5969,7 @@ sub process { ...@@ -5969,7 +5969,7 @@ sub process {
} }
# check for naked sscanf # check for naked sscanf
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
defined $stat && defined $stat &&
$line =~ /\bsscanf\b/ && $line =~ /\bsscanf\b/ &&
($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
...@@ -5983,7 +5983,7 @@ sub process { ...@@ -5983,7 +5983,7 @@ sub process {
} }
# check for simple sscanf that should be kstrto<foo> # check for simple sscanf that should be kstrto<foo>
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
defined $stat && defined $stat &&
$line =~ /\bsscanf\b/) { $line =~ /\bsscanf\b/) {
my $lc = $stat =~ tr@\n@@; my $lc = $stat =~ tr@\n@@;
...@@ -6055,7 +6055,7 @@ sub process { ...@@ -6055,7 +6055,7 @@ sub process {
} }
# check for function definitions # check for function definitions
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
defined $stat && defined $stat &&
$stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
$context_function = $1; $context_function = $1;
...@@ -6095,14 +6095,14 @@ sub process { ...@@ -6095,14 +6095,14 @@ sub process {
# alloc style # alloc style
# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) # p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
$line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
CHK("ALLOC_SIZEOF_STRUCT", CHK("ALLOC_SIZEOF_STRUCT",
"Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
} }
# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc # check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
defined $stat && defined $stat &&
$stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
my $oldfunc = $3; my $oldfunc = $3;
...@@ -6131,7 +6131,7 @@ sub process { ...@@ -6131,7 +6131,7 @@ sub process {
} }
# check for krealloc arg reuse # check for krealloc arg reuse
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
$line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) { $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) {
WARN("KREALLOC_ARG_REUSE", WARN("KREALLOC_ARG_REUSE",
"Reusing the krealloc arg is almost always a bug\n" . $herecurr); "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
...@@ -6200,7 +6200,7 @@ sub process { ...@@ -6200,7 +6200,7 @@ sub process {
} }
# check for switch/default statements without a break; # check for switch/default statements without a break;
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
defined $stat && defined $stat &&
$stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
my $cnt = statement_rawlines($stat); my $cnt = statement_rawlines($stat);
...@@ -6317,7 +6317,7 @@ sub process { ...@@ -6317,7 +6317,7 @@ sub process {
} }
# likely/unlikely comparisons similar to "(likely(foo) > 0)" # likely/unlikely comparisons similar to "(likely(foo) > 0)"
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
$line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
WARN("LIKELY_MISUSE", WARN("LIKELY_MISUSE",
"Using $1 should generally have parentheses around the comparison\n" . $herecurr); "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
...@@ -6360,7 +6360,7 @@ sub process { ...@@ -6360,7 +6360,7 @@ sub process {
# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO> # check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
# and whether or not function naming is typical and if # and whether or not function naming is typical and if
# DEVICE_ATTR permissions uses are unusual too # DEVICE_ATTR permissions uses are unusual too
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
defined $stat && defined $stat &&
$stat =~ /\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?\s*(\s*(?:${multi_mode_perms_string_search}|0[0-7]{3,3})\s*)\s*\)?\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/) { $stat =~ /\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?\s*(\s*(?:${multi_mode_perms_string_search}|0[0-7]{3,3})\s*)\s*\)?\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/) {
my $var = $1; my $var = $1;
...@@ -6420,7 +6420,7 @@ sub process { ...@@ -6420,7 +6420,7 @@ sub process {
# specific definition of not visible in sysfs. # specific definition of not visible in sysfs.
# o Ignore proc_create*(...) uses with a decimal 0 permission as that means # o Ignore proc_create*(...) uses with a decimal 0 permission as that means
# use the default permissions # use the default permissions
if ($^V && $^V ge 5.10.0 && if ($perl_version_ok &&
defined $stat && defined $stat &&
$line =~ /$mode_perms_search/) { $line =~ /$mode_perms_search/) {
foreach my $entry (@mode_permission_funcs) { foreach my $entry (@mode_permission_funcs) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment