The initial version of the logic for --ignore-cfg supported looking for the file in the current directory, and if not found, look in the directory of the source file.
With this change, in the case of a file name with no directory specification, and for an in-kernel file, checkpatch will iterate upwards in the directories above, looking for the same file until either hitting the top of the tree or finding a match. This should make the P={1,2} make target more useful for maintainers, as a start of functionality for checkpatch checking that can be globally enabled for a subsystem. Signed-off-by: Knut Omang <knut.om...@oracle.com> --- scripts/checkpatch.pl | 44 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index c17178e..a276eca 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2186,15 +2186,47 @@ sub pos_last_openparen { return length(expand_tabs(substr($line, 0, $last_openparen))) + 1; } + # Checkpatch suppression list configuration file support # # See Documentation/dev-tools/run-checkpatch.rst # -sub parse_ignore_cfg_file { - defined($ignore_cfg_file) || return 1; + +# Usage: find_ignore_cfg_file(filename,ignorefilename) +# If filename contains a directory, use it directly with no further attempts, +# If no directory is specified, whether relative or absolute, +# look for 'filename' in the following order until a match is found: +# 1) current dir, +# 2) the directory of the source file +# 3) if an in-source source-file (same source tree as this script) +# look in directories above for the first match. +# +sub find_ignore_cfg_file { my $path = shift(@_); + my $ipath = shift(@_); + my $ifile = basename($ipath); my $filename = basename($path); my $dir = dirname($path); + my $root = dirname($D); + ( -f $ipath ) && return ($filename, $ipath); + ( $ipath =~ m/\// ) && return ($filename,""); + + do { + $ipath = "$dir/$ifile"; + #print "*** Trying $ipath ***\n"; + ( -f $ipath ) && return ($filename, $ipath); + $dir = dirname($dir); + } while ( $dir =~ m/^$root/ && ! -f $ifile ); + return ($filename,""); +} + + +sub parse_ignore_cfg_file { + my $path = shift(@_); + my $filename; # The file to check + my $ifile; # The ignore file name + my $ignfile; # The ignore file handle + defined($ignore_cfg_file) || return 1; my %IgnoreCfgKeywords = ( 'except' => sub { my $type = shift(@_); grep( /^$filename$/, @_ ) && push(@ignore, $type); @@ -2202,11 +2234,11 @@ sub parse_ignore_cfg_file { 'pervasive' => sub { push(@ignore, @_); }, 'line_len' => sub { $max_line_length = shift(@_); } ); - my $ignfile; - ( -f $ignore_cfg_file ) || ( $ignore_cfg_file = "$dir/$ignore_cfg_file" ); - ( ! -f $ignore_cfg_file ) && return 0; - open($ignfile, '<', "$ignore_cfg_file") || return 0; + ($filename, $ifile) = find_ignore_cfg_file($path, $ignore_cfg_file); + ( $ifile eq "" ) && return 0; + open($ignfile, '<', "$ifile") || return 0; + #print "*** Found $ifile ***\n"; ($#_ >= 0) && die "$P: The --ignore-cfg option is only supported with one source file at a time!\n"; -- git-series 0.9.1