[PATCH 6/7] checkpatch: Make --ignore-cfg look recursively for the file

From: Knut Omang
Date: Thu Nov 16 2017 - 12:03:31 EST


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.omang@xxxxxxxxxx>
---
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